]> jfr.im git - irc/quakenet/qwebirc.git/blobdiff - qwebirc/engines/ajaxengine.py
Fix several login bugs, add bouncer auth mode.
[irc/quakenet/qwebirc.git] / qwebirc / engines / ajaxengine.py
index 5fab9cf4c4f00c95d4cce6869be941e4211c141f..a7acb464e6ee8bec3b9a8b1c2ce180d7dd3930bb 100644 (file)
@@ -2,11 +2,11 @@ from twisted.web import resource, server, static, error as http_error
 from twisted.names import client
 from twisted.internet import reactor, error
 from authgateengine import login_optional, getSessionData
-import simplejson, md5, sys, os, time, config, weakref, traceback
+import simplejson, md5, sys, os, time, config, qwebirc.config_options as config_options, traceback, socket
 import qwebirc.ircclient as ircclient
 from adminengine import AdminEngineAction
 from qwebirc.util import HitCounter
-
+import qwebirc.dns as qdns
 Sessions = {}
 
 def get_session_id():
@@ -52,6 +52,7 @@ class IRCSession:
     self.id = id
     self.subscriptions = []
     self.buffer = []
+    self.buflen = 0
     self.throttle = 0
     self.schedule = None
     self.closed = False
@@ -106,7 +107,8 @@ class IRCSession:
 
     encdata = simplejson.dumps(self.buffer)
     self.buffer = []
-    
+    self.buflen = 0
+
     newsubs = []
     for x in self.subscriptions:
       if x.write(encdata):
@@ -117,13 +119,14 @@ class IRCSession:
       cleanupSession(self.id)
 
   def event(self, data):
-    bufferlen = sum(map(len, self.buffer))
-    if bufferlen + len(data) > config.MAXBUFLEN:
+    newbuflen = self.buflen + len(data)
+    if newbuflen > config.MAXBUFLEN:
       self.buffer = []
       self.client.error("Buffer overflow.")
       return
 
     self.buffer.append(data)
+    self.buflen = newbuflen
     self.flush()
     
   def push(self, data):
@@ -137,6 +140,10 @@ class IRCSession:
 
     reactor.callLater(5, cleanupSession, self.id)
 
+# DANGER! Breach of encapsulation!
+def connect_notice(line):
+  return "c", "NOTICE", "", ("AUTH", "*** (qwebirc) %s" % line)
+
 class Channel:
   def __init__(self, request):
     self.request = request
@@ -173,9 +180,6 @@ class AJAXEngine(resource.Resource):
         
     raise PassthruException, http_error.NoResource().render(request)
 
-  #def render_GET(self, request):
-    #return self.render_POST(request)
-  
   def newConnection(self, request):
     ticket = login_optional(request)
     
@@ -186,8 +190,10 @@ class AJAXEngine(resource.Resource):
       raise AJAXException, "Nickname not supplied."
     nick = ircclient.irc_decode(nick[0])
 
-    ident, realname = "webchat", config.REALNAME
-    
+    password = request.args.get("password")
+    if password is not None:
+      password = ircclient.irc_decode(password[0])
+      
     for i in xrange(10):
       id = get_session_id()
       if not Sessions.get(id):
@@ -205,10 +211,35 @@ class AJAXEngine(resource.Resource):
       msg_mask = service_mask.split("!")[0] + "@" + service_mask.split("@", 1)[1]
       perform = ["PRIVMSG %s :TICKETAUTH %s" % (msg_mask, qticket)]
 
+    ident, realname = config.IDENT, config.REALNAME
+    if ident is config_options.IDENT_HEX or ident is None: # latter is legacy
+      ident = socket.inet_aton(ip).encode("hex")
+    elif ident is config_options.IDENT_NICKNAME:
+      ident = nick
+
     self.__connect_hit()
-    client = ircclient.createIRC(session, nick=nick, ident=ident, ip=ip, realname=realname, perform=perform)
-    session.client = client
-    
+
+    def proceed(hostname):
+      kwargs = dict(nick=nick, ident=ident, ip=ip, realname=realname, perform=perform, hostname=hostname)
+      if password is not None:
+        kwargs["password"] = password
+        
+      client = ircclient.createIRC(session, **kwargs)
+      session.client = client
+
+    if not hasattr(config, "WEBIRC_MODE") or config.WEBIRC_MODE == "hmac":
+      proceed(None)
+    elif config.WEBIRC_MODE != "hmac":
+      notice = lambda x: session.event(connect_notice(x))
+      notice("Looking up your hostname...")
+      def callback(hostname):
+        notice("Found your hostname.")
+        proceed(hostname)
+      def errback(failure):
+        notice("Couldn't look up your hostname!")
+        proceed(ip)
+      qdns.lookupAndVerifyPTR(ip, timeout=[config.DNS_TIMEOUT]).addCallbacks(callback, errback)
+
     Sessions[id] = session
     
     return id
@@ -271,4 +302,4 @@ class AJAXEngine(resource.Resource):
     }
     
   COMMANDS = dict(p=push, n=newConnection, s=subscribe)
-  
\ No newline at end of file
+