def __init__(self, e_alg=None, key=None, h_alg=None, iv=None): if e_alg is None: self.e_alg = self.AES_ALG[0] else: self.e_alg = e_alg assert self.e_alg in self.AES_ALG, "The encryption alg %s do not exist. Use one of the follwing encryption " \ "alg: %s" % (self.alg, self.AES_ALG) typ, bits, cmode = self.e_alg.split("_") if key is None: self.key = os.urandom(int(bits) >> 3) else: self.key = key assert len(self.key) == int(bits) >> 3, "The key must consist of %d bytes." % int(bits) >> 3 if h_alg is None: self.h_alg = "sha256" else: self.h_alg = h_alg if iv is None: self.iv = Random.new().read(AES.block_size) else: self.iv = iv assert len(self.iv) == AES.block_size, "The initialization vector must be %d size." % AES.block_size h_alg_ok = False approved_hash_alg = "" for tmp_h_alg in hashlib.algorithms: if self.h_alg == tmp_h_alg: h_alg_ok = True approved_hash_alg += tmp_h_alg + "," assert h_alg_ok, "The hash alg %s do not exist. Use one of the following alg: %s" % (self.h_alg, approved_hash_alg) self.aes = AESCipher(key=self.key, iv=self.iv)
def __init__(self, srv, mako_template, template_lookup, pwd, return_to): """ :param srv: The server instance :param mako_template: Which Mako template to use :param pwd: Username/password dictionary like database :param return_to: Where to send the user after authentication :return: """ UserAuthnMethod.__init__(self, srv) self.mako_template = mako_template self.template_lookup = template_lookup self.passwd = pwd self.return_to = return_to self.active = {} self.query_param = "upm_answer" self.aes = AESCipher(self.srv.symkey.encode(), srv.iv)
def __init__(self, srv, mako_template, template_lookup, pwd, return_to): """ :param srv: The server instance :param mako_template: Which Mako template to use :param pwd: Username/password dictionary like database :param return_to: Where to send the user after authentication :return: """ UserAuthnMethod.__init__(self, srv) self.mako_template = mako_template self.template_lookup = template_lookup self.passwd = pwd self.return_to = return_to self.active = {} self.query_param = "upm_answer" self.aes = AESCipher(self.srv.symkey, srv.iv)
class UsernamePasswordMako(UserAuthnMethod): """Do user authentication using the normal username password form using Mako as template system""" cookie_name = "userpassmako" def __init__(self, srv, mako_template, template_lookup, pwd, return_to): """ :param srv: The server instance :param mako_template: Which Mako template to use :param pwd: Username/password dictionary like database :param return_to: Where to send the user after authentication :return: """ UserAuthnMethod.__init__(self, srv) self.mako_template = mako_template self.template_lookup = template_lookup self.passwd = pwd self.return_to = return_to self.active = {} self.query_param = "upm_answer" self.aes = AESCipher(self.srv.symkey, srv.iv) def __call__(self, cookie=None, policy_url=None, logo_url=None, query="", **kwargs): """ Put up the login form """ if cookie: headers = [cookie] else: headers = [] resp = Response(headers=headers) argv = {"login": "", "password": "", "action": "verify", "policy_url": policy_url, "logo_url": logo_url, "query": query} logger.info("do_authentication argv: %s" % argv) mte = self.template_lookup.get_template(self.mako_template) resp.message = mte.render(**argv) return resp def _verify(self, pwd, user): assert pwd == self.passwd[user] def verify(self, request, **kwargs): """ Verifies that the given username and password was correct :param request: Either the query part of a URL a urlencoded body of a HTTP message or a parse such. :param kwargs: Catch whatever else is sent. :return: redirect back to where ever the base applications wants the user after authentication. """ logger.debug("verify(%s)" % request) if isinstance(request, basestring): _dict = parse_qs(request) elif isinstance(request, dict): _dict = request else: raise ValueError("Wrong type of input") logger.debug("dict: %s" % _dict) logger.debug("passwd: %s" % self.passwd) # verify username and password try: self._verify(_dict["password"][0], _dict["login"][0]) timestamp = str(int(time.mktime(time.gmtime()))) info = self.aes.encrypt("::".join([_dict["login"][0], timestamp])) self.active[info] = timestamp cookie = make_cookie(self.cookie_name, info, self.srv.seed) return_to = create_return_url(self.return_to, _dict["query"][0], **{self.query_param: "true"}) resp = Redirect(return_to, headers=[cookie]) except (AssertionError, KeyError): resp = Unauthorized("Unknown user or wrong password") return resp def authenticated_as(self, cookie=None, **kwargs): if cookie is None: return None else: logger.debug("kwargs: %s" % kwargs) try: info, timestamp = parse_cookie(self.cookie_name, self.srv.seed, cookie) if self.active[info] == timestamp: uid, _ts = self.aes.decrypt(info).split("::") if timestamp == _ts: return {"uid": uid} except Exception: pass return None def done(self, areq): try: _ = areq[self.query_param] return False except KeyError: return True
class TargetIdHandler(object): AES_ALG = ["aes_128_cbc", "aes_128_cfb", "aes_128_ecb", "aes_192_cbc", "aes_192_cfb", "aes_192_ecb", "aes_256_cbc", "aes_256_cfb", "aes_256_ecb"] def __init__(self, e_alg=None, key=None, h_alg=None, iv=None): if e_alg is None: self.e_alg = self.AES_ALG[0] else: self.e_alg = e_alg assert self.e_alg in self.AES_ALG, "The encryption alg %s do not exist. Use one of the follwing encryption " \ "alg: %s" % (self.alg, self.AES_ALG) typ, bits, cmode = self.e_alg.split("_") if key is None: self.key = os.urandom(int(bits) >> 3) else: self.key = key assert len(self.key) == int(bits) >> 3, "The key must consist of %d bytes." % int(bits) >> 3 if h_alg is None: self.h_alg = "sha256" else: self.h_alg = h_alg if iv is None: self.iv = Random.new().read(AES.block_size) else: self.iv = iv assert len(self.iv) == AES.block_size, "The initialization vector must be %d size." % AES.block_size h_alg_ok = False approved_hash_alg = "" for tmp_h_alg in hashlib.algorithms: if self.h_alg == tmp_h_alg: h_alg_ok = True approved_hash_alg += tmp_h_alg + "," assert h_alg_ok, "The hash alg %s do not exist. Use one of the following alg: %s" % (self.h_alg, approved_hash_alg) self.aes = AESCipher(key=self.key, iv=self.iv) def get_new_iv(self): return Random.new().read(AES.block_size) def tid2_json(self, tid1, sp_entityid): tid2_dict = { "tid1": tid1, "sp_entityid": sp_entityid, "uuid": uuid4().urn } return json.dumps(tid2_dict) def tid2_dict(self, tid2_json): return json.loads(tid2_json) def tid2_encrypt(self, tid1, sp_entityid, iv=None): tid2 = self.tid2_json(tid1, sp_entityid) tid2_encrypt = self.aes.encrypt(msg=tid2, alg=self.e_alg, iv=None) return tid2_encrypt def tid2_decrypt(self, tid2_encrypted, iv=None): tid2_json = self.aes.decrypt(tid2_encrypted, alg=self.e_alg, iv=None) return self.tid2_dict(tid2_json) def tid2_hash(self, tid1, sp_entityid): tid2 = self.tid2_json(tid1, sp_entityid) hash_func = getattr(hashlib, self.h_alg) return hash_func(tid2).hexdigest() def uid_hash(self, tid1): hash_func = getattr(hashlib, self.h_alg) return hash_func(tid1).hexdigest()
class UsernamePasswordMako(UserAuthnMethod): """Do user authentication using the normal username password form using Mako as template system""" cookie_name = "userpassmako" def __init__(self, srv, mako_template, template_lookup, pwd, return_to): """ :param srv: The server instance :param mako_template: Which Mako template to use :param pwd: Username/password dictionary like database :param return_to: Where to send the user after authentication :return: """ UserAuthnMethod.__init__(self, srv) self.mako_template = mako_template self.template_lookup = template_lookup self.passwd = pwd self.return_to = return_to self.active = {} self.query_param = "upm_answer" self.aes = AESCipher(self.srv.symkey.encode(), srv.iv) def __call__(self, cookie=None, policy_url=None, logo_url=None, query="", **kwargs): """ Put up the login form """ if cookie: headers = [cookie] else: headers = [] resp = Response(headers=headers) argv = { "login": "", "password": "", "action": "verify", "policy_url": policy_url, "logo_url": logo_url, "query": query } logger.info("do_authentication argv: %s" % argv) mte = self.template_lookup.get_template(self.mako_template) resp.message = mte.render(**argv) return resp def _verify(self, pwd, user): if not is_equal(pwd, self.passwd[user]): raise ValueError("Wrong password") def verify(self, request, **kwargs): """ Verifies that the given username and password was correct :param request: Either the query part of a URL a urlencoded body of a HTTP message or a parse such. :param kwargs: Catch whatever else is sent. :return: redirect back to where ever the base applications wants the user after authentication. """ #logger.debug("verify(%s)" % request) if isinstance(request, six.string_types): _dict = parse_qs(request) elif isinstance(request, dict): _dict = request else: raise ValueError("Wrong type of input") # verify username and password try: self._verify(_dict["password"][0], _dict["login"][0]) timestamp = str(int(time.mktime(time.gmtime()))) msg = "::".join([_dict["login"][0], timestamp]) info = self.aes.encrypt(msg.encode()) self.active[info] = timestamp cookie = make_cookie(self.cookie_name, info, self.srv.seed) return_to = create_return_url(self.return_to, _dict["query"][0], **{self.query_param: "true"}) resp = Redirect(return_to, headers=[cookie]) except (ValueError, KeyError): resp = Unauthorized("Unknown user or wrong password") return resp def authenticated_as(self, cookie=None, **kwargs): if cookie is None: return None else: logger.debug("kwargs: %s" % kwargs) try: info, timestamp = parse_cookie(self.cookie_name, self.srv.seed, cookie) if self.active[info] == timestamp: msg = self.aes.decrypt(info).decode() uid, _ts = msg.split("::") if timestamp == _ts: return {"uid": uid} except Exception: pass return None def done(self, areq): try: _ = areq[self.query_param] return False except KeyError: return True