]>
jfr.im git - irc/quakenet/qwebirc.git/blob - qwebirc/engines/authgateengine.py
1 from twisted
.web
import resource
, server
, static
2 import config
, urlparse
, urllib
, hashlib
, re
3 import qwebirc
.util
.rijndael
, qwebirc
.util
.ciphers
6 authgate
= config
.AUTHGATEPROVIDER
.twisted
9 class AuthgateEngine(resource
.Resource
):
12 def __init__(self
, prefix
):
13 self
.__prefix
= prefix
14 self
.__hit
= qwebirc
.util
.HitCounter()
16 def deleteCookie(self
, request
, key
):
17 request
.addCookie(key
, "", path
="/", expires
="Sat, 29 Jun 1996 01:44:48 GMT")
19 def render_GET(self
, request
):
20 if request
.args
.get("logout"):
21 self
.deleteCookie(request
, "user")
23 a
= authgate(request
, config
.AUTHGATEDOMAIN
)
25 ticket
= a
.login_required(accepting
=lambda x
: True)
26 except a
.redirect_exception
, e
:
29 # only used for informational purposes, the backend stores this seperately
30 # so if the user changes it just their front end will be messed up!
31 request
.addCookie("user", ticket
.username
, path
="/")
33 qt
= ticket
.get("qticket")
35 getSessionData(request
)["qticket"] = decodeQTicket(qt
)
38 location
= request
.getCookie("redirect")
42 self
.deleteCookie(request
, "redirect")
43 _
, _
, path
, params
, query
, _
= urlparse
.urlparse(urllib
.unquote(location
))
44 location
= urlparse
.urlunparse(("", "", path
, params
, query
, ""))
46 request
.redirect(location
)
49 return server
.NOT_DONE_YET
52 def adminEngine(self
):
53 return dict(Logins
=((self
.__hit
,),))
55 def decodeQTicket(qticket
, p
=re
.compile("\x00*$"), cipher
=qwebirc
.util
.rijndael
.rijndael(hashlib
.sha256(config
.QTICKETKEY
).digest()[:16])):
58 if l
< BLOCK_SIZE
* 2 or l
% BLOCK_SIZE
!= 0:
59 raise Exception("Bad qticket.")
61 iv
, data
= data
[:16], data
[16:]
62 cbc
= qwebirc
.util
.ciphers
.CBC(cipher
, iv
)
64 # technically this is a flawed padding algorithm as it allows chopping at BLOCK_SIZE, we don't
65 # care about that though!
66 b
= range(0, l
-BLOCK_SIZE
, BLOCK_SIZE
)
67 for i
, v
in enumerate(b
):
68 q
= cbc
.decrypt(data
[v
:v
+BLOCK_SIZE
])
70 yield re
.sub(p
, "", q
)
73 return "".join(decrypt(qticket
))
75 def getSessionData(request
):
76 return authgate
.get_session_data(request
)
78 def login_optional(request
):
79 return authgate(request
, config
.AUTHGATEDOMAIN
).login_optional()