def secure_loads_deprecated(data, encryption_key, hash_key=None, compression_level=None): """loads signed data (deprecated because of incorrect padding)""" encryption_key = to_bytes(encryption_key) data = to_native(data) if ':' not in data: return None if not hash_key: hash_key = hashlib.sha1(encryption_key).hexdigest() signature, encrypted_data = data.split(':', 1) encrypted_data = to_bytes(encrypted_data) actual_signature = hmac.new(to_bytes(hash_key), encrypted_data, hashlib.md5).hexdigest() if not compare(signature, actual_signature): return None key = __pad_deprecated(encryption_key)[:32] encrypted_data = base64.urlsafe_b64decode(encrypted_data) IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] cipher, _ = AES_new(key, IV=IV) try: data = AES_dec(cipher, encrypted_data) data = data.rstrip(b' ') if compression_level: data = zlib.decompress(data) return pickle.loads(data) except Exception: return None
def secure_loads(data, encryption_key, hash_key=None, compression_level=None): """loads a signed data dump""" data = to_bytes(data) components = data.count(b':') if components == 1: return secure_loads_deprecated(data, encryption_key, hash_key, compression_level) if components != 2: return None version, signature, encrypted_data = data.split(b':', 2) if version != b'hmac256': return None encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = hashlib.sha256(encryption_key).digest() actual_signature = hmac.new(to_bytes(hash_key), encrypted_data, hashlib.sha256).hexdigest() if not compare(to_native(signature), actual_signature): return None encrypted_data = base64.urlsafe_b64decode(encrypted_data) IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] cipher, _ = AES_new(pad(encryption_key)[:32], IV=IV) try: data = unpad(AES_dec(cipher, encrypted_data)) if compression_level: data = zlib.decompress(data) return pickle.loads(data) except Exception: return None
def secure_loads(data, encryption_key, hash_key=None, compression_level=None): data = to_bytes(data) components = data.count(b':') if components == 1: return secure_loads_deprecated(data, encryption_key, hash_key, compression_level) if components != 2: return None version, signature, encrypted_data = data.split(b':', 2) if version != b'hmac256': return None encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = hashlib.sha256(encryption_key).digest() actual_signature = hmac.new(to_bytes(hash_key), encrypted_data, hashlib.sha256).hexdigest() if not compare(to_native(signature), actual_signature): return None encrypted_data = base64.urlsafe_b64decode(encrypted_data) IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] cipher, _ = AES_new(pad(encryption_key)[:32], IV=IV) try: data = unpad(AES_dec(cipher, encrypted_data)) if compression_level: data = zlib.decompress(data) return pickle.loads(data) except Exception as e: return None
def secure_loads_deprecated(data, encryption_key, hash_key=None, compression_level=None): encryption_key = to_bytes(encryption_key) data = to_native(data) if ':' not in data: return None if not hash_key: hash_key = sha1(encryption_key).hexdigest() signature, encrypted_data = data.split(':', 1) encrypted_data = to_bytes(encrypted_data) actual_signature = hmac.new(to_bytes(hash_key), encrypted_data, hashlib.md5).hexdigest() if not compare(signature, actual_signature): return None key = __pad_deprecated(encryption_key)[:32] encrypted_data = base64.urlsafe_b64decode(encrypted_data) IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] cipher, _ = AES_new(key, IV=IV) try: data = AES_dec(cipher, encrypted_data) data = data.rstrip(b' ') if compression_level: data = zlib.decompress(data) return pickle.loads(data) except Exception as e: return None
def websocket_send(url, message, hmac_key=None, group='default'): sig = hmac_key and hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() or '' params = urlencode( {'message': message, 'signature': sig, 'group': group}) f = urlopen(url, to_bytes(params)) data = f.read() f.close() return data
def websocket_send(url, message, hmac_key=None, group='default'): sig = hmac_key and hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() or '' params = urlencode({'message': message, 'signature': sig, 'group': group}) f = urlopen(url, to_bytes(params)) data = f.read() f.close() return data
def post(self): if hmac_key and not 'message' in self.request.arguments: self.send_error(401) if 'message' in self.request.arguments: message = self.request.arguments['message'][0] if hmac_key: signature = self.request.arguments['signature'][0] actual_signature = hmac.new(to_bytes(hmac_key), to_bytes(message), md5).hexdigest() if not gluon.utils.compare(to_native(signature), actual_signature): self.send_error(401) tokens[message] = None
def secure_dumps(data, encryption_key, hash_key=None, compression_level=None): dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) if compression_level: dump = zlib.compress(dump, compression_level) encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = hashlib.sha256(encryption_key).digest() cipher, IV = AES_new(pad(encryption_key)[:32]) encrypted_data = base64.urlsafe_b64encode(IV + AES_enc(cipher, pad(dump))) signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data, hashlib.sha256).hexdigest()) return b'hmac256:' + signature + b':' + encrypted_data
def post(self): if hmac_key and not 'message' in self.request.arguments: self.send_error(401) if 'message' in self.request.arguments: message = self.request.arguments['message'][0] if hmac_key: signature = self.request.arguments['signature'][0] actual_signature = hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() if not gluon.utils.compare(to_native(signature), actual_signature): self.send_error(401) tokens[message] = None
def secure_dumps(data, encryption_key, hash_key=None, compression_level=None): dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) if compression_level: dump = zlib.compress(dump, compression_level) encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = hashlib.sha256(encryption_key).digest() cipher, IV = AES_new(pad(encryption_key)[:32]) encrypted_data = base64.urlsafe_b64encode(IV + AES_enc(cipher, pad(dump))) signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data, hashlib.sha256).hexdigest()) return b"hmac256:" + signature + b":" + encrypted_data
def secure_dumps_deprecated(data, encryption_key, hash_key=None, compression_level=None): encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = sha1(encryption_key).hexdigest() dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) if compression_level: dump = zlib.compress(dump, compression_level) key = __pad_deprecated(encryption_key)[:32] cipher, IV = AES_new(key) encrypted_data = base64.urlsafe_b64encode(IV + AES_enc(cipher, pad(dump))) signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data, hashlib.md5).hexdigest()) return signature + b':' + encrypted_data
def secure_dumps(data, encryption_key, hash_key=None, compression_level=None): encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = sha1(encryption_key).hexdigest() dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) if compression_level: dump = zlib.compress(dump, compression_level) key = pad(encryption_key)[:32] cipher, IV = AES_new(key) encrypted_data = base64.urlsafe_b64encode(IV + cipher.encrypt(pad(dump))) signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data).hexdigest()) return signature + b':' + encrypted_data
def secure_dumps_deprecated(data, encryption_key, hash_key=None, compression_level=None): """dumps data with a signature (deprecated because of incorrect padding)""" encryption_key = to_bytes(encryption_key) if not hash_key: hash_key = hashlib.sha1(encryption_key).hexdigest() dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) if compression_level: dump = zlib.compress(dump, compression_level) key = __pad_deprecated(encryption_key)[:32] cipher, IV = AES_new(key) encrypted_data = base64.urlsafe_b64encode(IV + AES_enc(cipher, pad(dump))) signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data, hashlib.md5).hexdigest()) return signature + b':' + encrypted_data
def post(self): if hmac_key and not 'signature' in self.request.arguments: self.send_error(401) if 'message' in self.request.arguments: message = self.request.arguments['message'][0].decode(encoding='UTF-8') group = self.request.arguments.get('group', ['default'])[0].decode(encoding='UTF-8') print('%s:MESSAGE to %s:%s' % (time.time(), group, message)) if hmac_key: signature = self.request.arguments['signature'][0] actual_signature = hmac.new(to_bytes(hmac_key), to_bytes(message), md5).hexdigest() if not gluon.utils.compare(to_native(signature), actual_signature): self.send_error(401) for client in listeners.get(group, []): client.write_message(message)
def post(self): if hmac_key and not 'signature' in self.request.arguments: self.send_error(401) if 'message' in self.request.arguments: message = self.request.arguments['message'][0].decode(encoding='UTF-8') group = self.request.arguments.get('group', ['default'])[0].decode(encoding='UTF-8') print('%s:MESSAGE to %s:%s' % (time.time(), group, message)) if hmac_key: signature = self.request.arguments['signature'][0] actual_signature = hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() if not gluon.utils.compare(to_native(signature), actual_signature): self.send_error(401) for client in listeners.get(group, []): client.write_message(message)
def __init__(self, path): self.path = os.path.join(path, 'cron.master') if not os.path.exists(self.path): fileutils.write_file(self.path, to_bytes(''), 'wb') self.master = None self.now = time.time() self.logger = getLogger(logger_name)
def test_decode(self): T = languages.translator(self.langpath, self.http_accept_language) elem = SPAN(T("Complete")) self.assertEqual(elem.flatten(), "Complete") elem = SPAN(T("Cannot be empty", language="ru")) self.assertEqual(elem.xml(), to_bytes('<span>Пустое значение недопустимо</span>')) self.assertEqual(elem.flatten(), 'Пустое значение недопустимо')
def test_fpdf(self): """ Basic PDF test and sanity checks """ self.assertEqual( fpdf.FPDF_VERSION, pyfpdf.FPDF_VERSION, 'version mistmatch') self.assertEqual(fpdf.FPDF, pyfpdf.FPDF, 'class mistmatch') pdf = fpdf.FPDF() pdf.add_page() pdf.compress = False pdf.set_font('Arial', '', 14) pdf.ln(10) pdf.write(5, 'hello world') pdf_out = pdf.output('', 'S') self.assertTrue(to_bytes(fpdf.FPDF_VERSION) in pdf_out, 'version string') self.assertTrue(to_bytes('hello world') in pdf_out, 'sample message')
def test_fpdf(self): """ Basic PDF test and sanity checks """ self.assertEqual(fpdf.FPDF_VERSION, pyfpdf.FPDF_VERSION, 'version mistmatch') self.assertEqual(fpdf.FPDF, pyfpdf.FPDF, 'class mistmatch') pdf = fpdf.FPDF() pdf.add_page() pdf.compress = False pdf.set_font('Arial', '', 14) pdf.ln(10) pdf.write(5, 'hello world') pdf_out = pdf.output('', 'S') self.assertTrue( to_bytes(fpdf.FPDF_VERSION) in pdf_out, 'version string') self.assertTrue(to_bytes('hello world') in pdf_out, 'sample message')
def renew(self, clear_session=False): if clear_session: self.clear() request = current.request response = current.response session = response.session masterapp = response.session_masterapp cookies = request.cookies if response.session_storage_type == 'cookie': return # if the session goes in file if response.session_storage_type == 'file': self._close(response) uuid = web2py_uuid() response.session_id = '%s-%s' % (response.session_client, uuid) separate = (lambda s: s[-2:]) if session and response.session_id[2:3] == "/" else None if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': table = response.session_db_table # verify that session_id exists if response.session_file: self._close(response) if response.session_new: return # Get session data out of the database if response.session_id is None: return (record_id, sep, unique_key) = response.session_id.partition(':') if record_id.isdigit() and long(record_id) > 0: new_unique_key = web2py_uuid() row = table(record_id) if row and row[b'unique_key'] == to_bytes(unique_key): table._db(table.id == record_id).update(unique_key=new_unique_key) else: record_id = None if record_id: response.session_id = '%s:%s' % (record_id, new_unique_key) response.session_db_record_id = record_id response.session_db_unique_key = new_unique_key else: response.session_new = True
def simple_hash(text, key="", salt="", digest_alg="md5"): """Generate hash with the given text using the specified digest algorithm.""" text = to_bytes(text) key = to_bytes(key) salt = to_bytes(salt) if not digest_alg: raise RuntimeError("simple_hash with digest_alg=None") elif not isinstance(digest_alg, str): # manual approach h = digest_alg(text + key + salt) elif digest_alg.startswith("pbkdf2"): # latest and coolest! iterations, keylen, alg = digest_alg[7:-1].split(",") return to_native(pbkdf2_hex(text, salt, int(iterations), int(keylen), get_digest(alg))) elif key: # use hmac digest_alg = get_digest(digest_alg) h = hmac.new(key + salt, text, digest_alg) else: # compatible with third party systems h = get_digest(digest_alg)() h.update(text + salt) return h.hexdigest()
def simple_hash(text, key='', salt='', digest_alg='md5'): """Generate hash with the given text using the specified digest algorithm.""" text = to_bytes(text) key = to_bytes(key) salt = to_bytes(salt) if not digest_alg: raise RuntimeError("simple_hash with digest_alg=None") elif not isinstance(digest_alg, str): # manual approach h = digest_alg(text + key + salt) elif digest_alg.startswith('pbkdf2'): # latest and coolest! iterations, keylen, alg = digest_alg[7:-1].split(',') return to_native(pbkdf2_hex(text, salt, int(iterations), int(keylen), get_digest(alg))) elif key: # use hmac digest_alg = get_digest(digest_alg) h = hmac.new(key + salt, text, digest_alg) else: # compatible with third party systems h = get_digest(digest_alg)() h.update(text + salt) return h.hexdigest()
def __str__(self): # safely show an useful message to the user try: output = self.output if not isinstance(output, str, bytes, bytearray): output = str(output) if isinstance(output, unicodeT): output = to_bytes(output) except: output = "" return output
def to(self, responder, env=None): env = env or {} status = self.status headers = self.headers if status in defined_status: status = '%d %s' % (status, defined_status[status]) elif isinstance(status, int): status = '%d UNKNOWN ERROR' % status else: status = str(status) if not regex_status.match(status): status = '500 %s' % (defined_status[500]) headers.setdefault('Content-Type', 'text/html; charset=UTF-8') body = self.body if status[:1] == '4': if not body: body = status if isinstance(body, (str, bytes, bytearray)): if isinstance(body, unicodeT): body = to_bytes(body) # This must be done before len headers['Content-Length'] = len(body) rheaders = [] for k, v in iteritems(headers): if isinstance(v, list): rheaders += [(k, str(item)) for item in v] elif v is not None: rheaders.append((k, str(v))) responder(status, rheaders) if env.get('request_method', '') == 'HEAD': return [''] elif isinstance(body, (str, bytes, bytearray)): if isinstance(body, unicodeT): body = to_bytes(body) return [body] elif hasattr(body, '__iter__'): return body else: body = str(body) if isinstance(body, unicodeT): body = to_bytes(body) return [body]
def to(self, responder, env=None): env = env or {} status = self.status headers = self.headers if status in defined_status: status = '%d %s' % (status, defined_status[status]) elif isinstance(status, int): status = '%d UNKNOWN ERROR' % status else: status = str(status) if not regex_status.match(status): status = '500 %s' % (defined_status[500]) headers.setdefault('Content-Type', 'text/html; charset=UTF-8') body = self.body if status[:1] == '4': if not body: body = status if isinstance(body, (str, bytes, bytearray)): if isinstance(body, unicodeT): body = to_bytes(body) # This must be done before len headers['Content-Length'] = len(body) rheaders = [] for k, v in iteritems(headers): if isinstance(v, list): rheaders += [(k, str(item)) for item in v] elif v is not None: rheaders.append((k, str(v))) responder(status, rheaders) if env.get('request_method', '') == 'HEAD': return [to_bytes('')] elif isinstance(body, (str, bytes, bytearray)): if isinstance(body, unicodeT): body = to_bytes(body) return [body] elif hasattr(body, '__iter__'): return body else: body = str(body) if isinstance(body, unicodeT): body = to_bytes(body) return [body]
def secure_loads(data, encryption_key, hash_key=None, compression_level=None): encryption_key = to_bytes(encryption_key) data = to_native(data) if ':' not in data: return None if not hash_key: hash_key = sha1(encryption_key).hexdigest() signature, encrypted_data = data.split(':', 1) encrypted_data = to_bytes(encrypted_data) actual_signature = hmac.new(to_bytes(hash_key), encrypted_data).hexdigest() if not compare(signature, actual_signature): return None key = pad(encryption_key)[:32] encrypted_data = base64.urlsafe_b64decode(encrypted_data) IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] cipher, _ = AES_new(key, IV=IV) try: data = cipher.decrypt(encrypted_data) data = data.rstrip(b' ') if compression_level: data = zlib.decompress(data) return pickle.loads(data) except Exception as e: return None
def select(self): if self.op == 'eq' and self.field == 'id' and self.value: # means that someone wants to retrieve the key self.value key = self.keyprefix + ':' + str(self.value) if self.with_lock: acquire_lock(self.db.r_server, key + ':lock', self.value, 2) rtn = { to_native(k): v for k, v in self.db.r_server.hgetall(key).items() } if rtn: if self.unique_key: # make sure the id and unique_key are correct if rtn['unique_key'] == to_bytes(self.unique_key): rtn['update_record'] = self.update # update record support else: rtn = None return [Storage(self.db.convert_dict_string(rtn))] if rtn else [] elif self.op in ('ge', 'gt') and self.field == 'id' and self.value == 0: # means that someone wants the complete list rtn = [] id_idx = "%s:id_idx" % self.keyprefix # find all session keys of this app allkeys = self.db.r_server.smembers(id_idx) for sess in allkeys: val = self.db.r_server.hgetall(sess) if not val: if self.session_expiry: # clean up the idx, because the key expired self.db.r_server.srem(id_idx, sess) continue val = Storage(self.db.convert_dict_string(val)) # add a delete_record method (necessary for sessions2trash.py) val.delete_record = RecordDeleter(self.db, sess, self.keyprefix) rtn.append(val) return rtn else: raise Exception("Operation not supported")
def select(self): if self.op == 'eq' and self.field == 'id' and self.value: # means that someone wants to retrieve the key self.value key = self.keyprefix + ':' + str(self.value) if self.with_lock: acquire_lock(self.db.r_server, key + ':lock', self.value, 2) rtn = self.db.r_server.hgetall(key) if rtn: if self.unique_key: # make sure the id and unique_key are correct if rtn[b'unique_key'] == to_bytes(self.unique_key): rtn[b'update_record'] = self.update # update record support else: rtn = None return [Storage(rtn)] if rtn else [] elif self.op == 'ge' and self.field == 'id' and self.value == 0: # means that someone wants the complete list rtn = [] id_idx = "%s:id_idx" % self.keyprefix # find all session keys of this app allkeys = self.db.r_server.smembers(id_idx) for sess in allkeys: val = self.db.r_server.hgetall(sess) if not val: if self.session_expiry: # clean up the idx, because the key expired self.db.r_server.srem(id_idx, sess) continue val = Storage(val) # add a delete_record method (necessary for sessions2trash.py) val.delete_record = RecordDeleter( self.db, sess, self.keyprefix) rtn.append(val) return rtn else: raise Exception("Operation not supported")
def ldap_auth_aux(username, password, ldap_server=server, ldap_port=port, ldap_basedn=base_dn, ldap_mode=mode, ldap_binddn=bind_dn, ldap_bindpw=bind_pw, secure=secure, cert_path=cert_path, cert_file=cert_file, cacert_file=cacert_file, key_file=key_file, filterstr=filterstr, username_attrib=username_attrib, custom_scope=custom_scope, manage_user=manage_user, user_middlename_attrib=user_middlename_attrib, user_firstname_attrib=user_firstname_attrib, user_lastname_attrib=user_lastname_attrib, user_mail_attrib=user_mail_attrib, manage_groups=manage_groups, allowed_groups=allowed_groups, group_mapping=group_mapping, db=db): if password == '': # http://tools.ietf.org/html/rfc4513#section-5.1.2 logger.warning('blank password not allowed') return False logger.debug('mode: [%s] manage_user: [%s] custom_scope: [%s]' ' manage_groups: [%s]' % (str(mode), str(manage_user), str(custom_scope), str(manage_groups))) if manage_user: if user_middlename_attrib.count(':') > 0: (user_middlename_attrib, user_middlename_part) = user_middlename_attrib.split(':', 1) user_middlename_part = (int(user_middlename_part) - 1) else: user_firstname_part = None if user_firstname_attrib.count(':') > 0: (user_firstname_attrib, user_firstname_part) = user_firstname_attrib.split(':', 1) user_firstname_part = (int(user_firstname_part) - 1) else: user_firstname_part = None if user_lastname_attrib.count(':') > 0: (user_lastname_attrib, user_lastname_part) = user_lastname_attrib.split(':', 1) user_lastname_part = (int(user_lastname_part) - 1) else: user_lastname_part = None user_middlename_attrib = ldap.filter.escape_filter_chars( user_middlename_attrib) user_firstname_attrib = ldap.filter.escape_filter_chars( user_firstname_attrib) user_lastname_attrib = ldap.filter.escape_filter_chars( user_lastname_attrib) user_mail_attrib = ldap.filter.escape_filter_chars( user_mail_attrib) try: if allowed_groups: if not is_user_in_allowed_groups(username, password): return False con = init_ldap() if ldap_mode == 'ad': # Microsoft Active Directory if '@' not in username: domain = [] for x in ldap_basedn.split(','): if "DC=" in x.upper(): domain.append(x.split('=')[-1]) username = "******" % (username, '.'.join(domain)) username_bare = username.split("@")[0] con.set_option(ldap.OPT_PROTOCOL_VERSION, 3) # In cases where ForestDnsZones and DomainDnsZones are found, # result will look like the following: # ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones, # DC=domain,DC=com'] if ldap_binddn: # need to search directory with an admin account 1st con.simple_bind_s(ldap_binddn, ldap_bindpw) else: # credentials should be in the form of [email protected] con.simple_bind_s(username, password) # this will throw an index error if the account is not found # in the ldap_basedn requested_attrs = ['sAMAccountName'] if manage_user: requested_attrs.extend([ user_middlename_attrib, user_firstname_attrib, user_lastname_attrib, user_mail_attrib ]) result = con.search_ext_s( ldap_basedn, ldap.SCOPE_SUBTREE, "(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare), filterstr), requested_attrs)[0][1] if not isinstance(result, dict): # result should be a dict in the form # {'sAMAccountName': [username_bare]} logger.warning('User [%s] not found!' % username) return False if ldap_binddn: # We know the user exists & is in the correct OU # so now we just check the password con.simple_bind_s(username, password) username = username_bare if ldap_mode == 'domino': # Notes Domino if "@" in username: username = username.split("@")[0] con.simple_bind_s(username, password) if manage_user: # TODO: sorry I have no clue how to query attrs in domino result = { user_middlename_attrib: None, user_firstname_attrib: username, user_lastname_attrib: None, user_mail_attrib: None } if ldap_mode == 'cn': # OpenLDAP (CN) if ldap_binddn and ldap_bindpw: con.simple_bind_s(ldap_binddn, ldap_bindpw) dn = "cn=" + username + "," + ldap_basedn con.simple_bind_s(dn, password) if manage_user: result = con.search_s( dn, ldap.SCOPE_BASE, "(objectClass=*)", [ user_middlename_attrib, user_firstname_attrib, user_lastname_attrib, user_mail_attrib ])[0][1] if ldap_mode == 'uid': # OpenLDAP (UID) if ldap_binddn and ldap_bindpw: con.simple_bind_s(ldap_binddn, ldap_bindpw) dn = "uid=" + username + "," + ldap_basedn dn = con.search_s(ldap_basedn, ldap.SCOPE_SUBTREE, "(uid=%s)" % username, [''])[0][0] else: dn = "uid=" + username + "," + ldap_basedn con.simple_bind_s(dn, password) if manage_user: result = con.search_s( dn, ldap.SCOPE_BASE, "(objectClass=*)", [ user_middlename_attrib, user_firstname_attrib, user_lastname_attrib, user_mail_attrib ])[0][1] if ldap_mode == 'company': # no DNs or password needed to search directory dn = "" pw = "" # bind anonymously con.simple_bind_s(dn, pw) # search by e-mail address filter = '(&(mail=%s)(%s))' % ( ldap.filter.escape_filter_chars(username), filterstr) # find the uid attrs = ['uid'] if manage_user: attrs.extend([ user_middlename_attrib, user_firstname_attrib, user_lastname_attrib, user_mail_attrib ]) # perform the actual search company_search_result = con.search_s(ldap_basedn, ldap.SCOPE_SUBTREE, filter, attrs) dn = company_search_result[0][0] result = company_search_result[0][1] # perform the real authentication test con.simple_bind_s(dn, password) if ldap_mode == 'uid_r': # OpenLDAP (UID) with subtree search and multiple DNs if isinstance(ldap_basedn, list): basedns = ldap_basedn else: basedns = [ldap_basedn] filter = '(&(uid=%s)(%s))' % ( ldap.filter.escape_filter_chars(username), filterstr) found = False for basedn in basedns: try: result = con.search_s(basedn, ldap.SCOPE_SUBTREE, filter) if result: user_dn = result[0][0] # Check the password con.simple_bind_s(user_dn, password) found = True break except ldap.LDAPError as detail: (exc_type, exc_value) = sys.exc_info()[:2] logger.warning( "ldap_auth: searching %s for %s resulted in %s: %s\n" % (basedn, filter, exc_type, exc_value)) if not found: logger.warning('User [%s] not found!' % username) return False result = result[0][1] if ldap_mode == 'custom': # OpenLDAP (username_attrs) with subtree search and # multiple DNs if isinstance(ldap_basedn, list): basedns = ldap_basedn else: basedns = [ldap_basedn] filter = '(&(%s=%s)(%s))' % ( username_attrib, ldap.filter.escape_filter_chars(username), filterstr) if custom_scope == 'subtree': ldap_scope = ldap.SCOPE_SUBTREE elif custom_scope == 'base': ldap_scope = ldap.SCOPE_BASE elif custom_scope == 'onelevel': ldap_scope = ldap.SCOPE_ONELEVEL found = False for basedn in basedns: try: result = con.search_s(basedn, ldap_scope, filter) if result: user_dn = result[0][0] # Check the password con.simple_bind_s(user_dn, password) found = True break except ldap.LDAPError as detail: (exc_type, exc_value) = sys.exc_info()[:2] logger.warning( "ldap_auth: searching %s for %s resulted in %s: %s\n" % (basedn, filter, exc_type, exc_value)) if not found: logger.warning('User [%s] not found!' % username) return False result = result[0][1] if manage_user: logger.info('[%s] Manage user data' % str(username)) try: user_middlename = result[user_middlename_attrib][0] if user_middlename_part is not None: store_user_middlename = result[user_middlename_attrib][ 0].split(to_bytes(' '), 2)[user_middlename_part] else: store_user_middlename = user_middlename except (KeyError, IndexError) as e: store_user_middlename = None try: user_firstname = result[user_firstname_attrib][0] if user_firstname_part is not None: store_user_firstname = result[user_firstname_attrib][ 0].split(to_bytes(' '), 2)[user_firstname_part] else: store_user_firstname = user_firstname except (KeyError, IndexError) as e: store_user_firstname = None try: user_lastname = result[user_lastname_attrib][0] if user_lastname_part is not None: store_user_lastname = result[user_lastname_attrib][ 0].split(to_bytes(' '), 2)[user_lastname_part] else: store_user_lastname = user_lastname except (KeyError, IndexError) as e: store_user_lastname = None try: store_user_mail = result[user_mail_attrib][0] except KeyError as e: store_user_mail = None update_or_insert_values = { 'middle_name': store_user_middlename, 'first_name': store_user_firstname, 'last_name': store_user_lastname, 'email': store_user_mail, 'username': username } if '@' not in username: # user as username # ################ fields = ['first_name', 'last_name', 'email'] user_in_db = db(db.auth_user.username == username) elif '@' in username: # user as email # ############# fields = ['first_name', 'last_name'] user_in_db = db(db.auth_user.email == username) update_or_insert_values = dict( ((f, update_or_insert_values[f]) for f in fields)) if user_in_db.count() > 0: actual_values = user_in_db.select( *[db.auth_user[f] for f in fields]).first().as_dict() if update_or_insert_values != actual_values: # We don't update record if values are the same user_in_db.update(**update_or_insert_values) else: db.auth_user.insert(**update_or_insert_values) con.unbind() if manage_groups: if not do_manage_groups(username, password, group_mapping): return False return True except ldap.INVALID_CREDENTIALS as e: return False import traceback logger.warning('[%s] Error in ldap processing' % str(username)) logger.debug(traceback.format_exc()) except ldap.LDAPError as e: import traceback logger.warning('[%s] Error in ldap processing' % str(username)) logger.debug(traceback.format_exc()) return False except IndexError as ex: # for AD membership test import traceback logger.warning('[%s] Ldap result indexing error' % str(username)) logger.debug(traceback.format_exc()) return False
def md5_hash(text): """Generate an md5 hash with the given text.""" return md5(to_bytes(text)).hexdigest()
def md5_hash(text): """ Generates a md5 hash with the given text """ return md5(to_bytes(text)).hexdigest()
def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): hashfunc = hashfunc or sha1 hmac = hashlib.pbkdf2_hmac(hashfunc().name, to_bytes(data), to_bytes(salt), iterations, keylen) return binascii.hexlify(hmac)
def key_filter_in_windows(key): """ Windows doesn't allow \ / : * ? "< > | in filenames. To go around this encode the keys with base32. """ return to_native(base64.b32encode(to_bytes(key)))
def key_filter_out_windows(key): """ We need to decode the keys so regex based removal works. """ return to_native(base64.b32decode(to_bytes(key)))
def test_routes_args(self): ''' Test URL args parsing/generation ''' data = r'''routes_in = [ ('/robots.txt', '/welcome/static/robots.txt'), ('/favicon.ico', '/welcome/static/favicon.ico'), ('/admin$anything', '/admin$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /', '/app1/default'), ('.*:https?://(.*\\.)?domain1.com:$method /static/$anything', '/app1/static/$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /appadmin/$anything', '/app1/appadmin/$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /$anything', '/app1/default/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /', '/app2/default'), ('.*:https?://(.*\\.)?domain2.com:$method /static/$anything', '/app2/static/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /appadmin/$anything', '/app2/appadmin/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /$anything', '/app2/default/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /', '/app3/defcon3'), ('.*:https?://(.*\\.)?domain3.com:$method /static/$anything', '/app3/static/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /appadmin/$anything', '/app3/appadmin/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /$anything', '/app3/defcon3/$anything'), ('/', '/welcome/default'), ('/welcome/default/$anything', '/welcome/default/$anything'), ('/welcome/$anything', '/welcome/default/$anything'), ('/static/$anything', '/welcome/static/$anything'), ('/appadmin/$anything', '/welcome/appadmin/$anything'), ('/$anything', '/welcome/default/$anything'), ] routes_out = [ ('/welcome/static/$anything', '/static/$anything'), ('/welcome/appadmin/$anything', '/appadmin/$anything'), ('/welcome/default/$anything', '/$anything'), ('/app1/static/$anything', '/static/$anything'), ('/app1/appadmin/$anything', '/appadmin/$anything'), ('/app1/default/$anything', '/$anything'), ('/app2/static/$anything', '/static/$anything'), ('/app2/appadmin/$anything', '/appadmin/$anything'), ('/app2/default/$anything', '/$anything'), ('/app3/static/$anything', '/static/$anything'), ('/app3/appadmin/$anything', '/appadmin/$anything'), ('/app3/defcon3/$anything', '/$anything') ] ''' load(data=data) self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1'), "/welcome/default/f ['arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1/'), "/welcome/default/f ['arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//'), "/welcome/default/f ['arg1', '']") self.assertEqual( filter_url('http://domain.com/welcome/default/f//arg1'), "/welcome/default/f ['', 'arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1/arg2'), "/welcome/default/f ['arg1', 'arg2']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg2'), "/welcome/default/f ['arg1', '', 'arg2']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg3/'), "/welcome/default/f ['arg1', '', 'arg3']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg3//'), "/welcome/default/f ['arg1', '', 'arg3', '']") self.assertEqual( filter_url('http://domain.com/welcome/default/f', out=True), "/f") self.assertEqual(regex_filter_out('/welcome/default/f'), "/f") self.assertEqual(str(URL(a='welcome', c='default', f='f', args=None)), "/f") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['arg1'])), "/f/arg1") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['arg1', ''])), "/f/arg1//") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['arg1', '', 'arg3'])), "/f/arg1//arg3") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['ar g'])), "/f/ar%20g") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=['årg'])), "/f/%C3%A5rg") self.assertEqual(URL(a='welcome', c='default', f='fünc'), "/fünc") self.assertEqual(to_bytes(URL(a='welcome', c='default', f='fünc')), b"/f\xc3\xbcnc")
def cap_fun(s): return to_bytes(to_unicode(s).capitalize())
def title_fun(s): return to_bytes(to_unicode(s).title())
def upper_fun(s): return to_bytes(to_unicode(s).upper())
def post(self, url, data=None, cookies=None, headers=None, auth=None, method='auto', charset='utf-8'): self.url = self.app + url # if this POST form requires a postback do it if data and '_formname' in data and self.postbacks and \ self.history and self.history[-1][1] != self.url: # to bypass the web2py CSRF need to get formkey # before submitting the form self.get(url, cookies=cookies, headers=headers, auth=auth) # unless cookies are specified, recycle cookies if cookies is None: cookies = self.cookies cookies = cookies or {} headers = headers or {} args = [ urllib2.HTTPCookieProcessor(self.cookiejar), urllib2.HTTPHandler(debuglevel=0) ] # if required do basic auth if auth: auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(**auth) args.append(auth_handler) opener = urllib2.build_opener(*args) # copy headers from dict to list of key,value headers_list = [] for key, value in iteritems(self.default_headers): if not key in headers: headers[key] = value for key, value in iteritems(headers): if isinstance(value, (list, tuple)): for v in value: headers_list.append((key, v)) else: headers_list.append((key, value)) # move cookies to headers for key, value in iteritems(cookies): headers_list.append(('Cookie', '%s=%s' % (key, value))) # add headers to request for key, value in headers_list: opener.addheaders.append((key, str(value))) # assume everything is ok and make http request error = None try: if isinstance(data, str): self.method = 'POST' if method == 'auto' else method elif isinstance(data, dict): self.method = 'POST' if method == 'auto' else method # if there is only one form, set _formname automatically if not '_formname' in data and len(self.forms) == 1: data['_formname'] = next(iter( self.forms.keys())) # Use the first key # if there is no formkey but it is known, set it if '_formname' in data and not '_formkey' in data and \ data['_formname'] in self.forms: data['_formkey'] = self.forms[data['_formname']] # time the POST request data = urlencode(data, doseq=True) else: self.method = 'GET' if method == 'auto' else method data = None t0 = time.time() self.response = opener.open(self.url, to_bytes(data)) self.time = time.time() - t0 except urllib2.HTTPError as er: error = er # catch HTTP errors self.time = time.time() - t0 self.response = er if hasattr(self.response, 'getcode'): self.status = self.response.getcode() else: #python2.5 self.status = None self.text = self.response.read() if charset: if charset == 'auto': charset = self.response.headers.getparam('charset') self.text = to_native(self.text, charset) # In PY3 self.response.headers are case sensitive self.headers = dict() for h in self.response.headers: self.headers[h.lower()] = self.response.headers[h] # treat web2py tickets as special types of errors if error is not None: if 'web2py_error' in self.headers: raise RuntimeError(self.headers['web2py_error']) else: raise error self._parse_headers_in_cookies() # check is a new session id has been issued, symptom of broken session if self.session_regex is not None: for cookie, value in iteritems(self.cookies): match = self.session_regex.match(cookie) if match: name = match.group('name') if name in self.sessions and self.sessions[name] != value: print(RuntimeError('Changed session ID %s' % name)) self.sessions[name] = value # find all forms and formkeys in page if charset: self.forms = {} for match in FORM_REGEX.finditer(self.text): self.forms[match.group('formname')] = match.group('formkey') # log this request self.history.append((self.method, self.url, self.status, self.time))
def md5_hash(text): """Generate an md5 hash with the given text.""" return hashlib.md5(to_bytes(text)).hexdigest()
def test_routes_args(self): ''' Test URL args parsing/generation ''' data = r'''routes_in = [ ('/robots.txt', '/welcome/static/robots.txt'), ('/favicon.ico', '/welcome/static/favicon.ico'), ('/admin$anything', '/admin$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /', '/app1/default'), ('.*:https?://(.*\\.)?domain1.com:$method /static/$anything', '/app1/static/$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /appadmin/$anything', '/app1/appadmin/$anything'), ('.*:https?://(.*\\.)?domain1.com:$method /$anything', '/app1/default/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /', '/app2/default'), ('.*:https?://(.*\\.)?domain2.com:$method /static/$anything', '/app2/static/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /appadmin/$anything', '/app2/appadmin/$anything'), ('.*:https?://(.*\\.)?domain2.com:$method /$anything', '/app2/default/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /', '/app3/defcon3'), ('.*:https?://(.*\\.)?domain3.com:$method /static/$anything', '/app3/static/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /appadmin/$anything', '/app3/appadmin/$anything'), ('.*:https?://(.*\\.)?domain3.com:$method /$anything', '/app3/defcon3/$anything'), ('/', '/welcome/default'), ('/welcome/default/$anything', '/welcome/default/$anything'), ('/welcome/$anything', '/welcome/default/$anything'), ('/static/$anything', '/welcome/static/$anything'), ('/appadmin/$anything', '/welcome/appadmin/$anything'), ('/$anything', '/welcome/default/$anything'), ] routes_out = [ ('/welcome/static/$anything', '/static/$anything'), ('/welcome/appadmin/$anything', '/appadmin/$anything'), ('/welcome/default/$anything', '/$anything'), ('/app1/static/$anything', '/static/$anything'), ('/app1/appadmin/$anything', '/appadmin/$anything'), ('/app1/default/$anything', '/$anything'), ('/app2/static/$anything', '/static/$anything'), ('/app2/appadmin/$anything', '/appadmin/$anything'), ('/app2/default/$anything', '/$anything'), ('/app3/static/$anything', '/static/$anything'), ('/app3/appadmin/$anything', '/appadmin/$anything'), ('/app3/defcon3/$anything', '/$anything') ] ''' load(data=data) self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1'), "/welcome/default/f ['arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1/'), "/welcome/default/f ['arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//'), "/welcome/default/f ['arg1', '']") self.assertEqual( filter_url('http://domain.com/welcome/default/f//arg1'), "/welcome/default/f ['', 'arg1']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1/arg2'), "/welcome/default/f ['arg1', 'arg2']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg2'), "/welcome/default/f ['arg1', '', 'arg2']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg3/'), "/welcome/default/f ['arg1', '', 'arg3']") self.assertEqual( filter_url('http://domain.com/welcome/default/f/arg1//arg3//'), "/welcome/default/f ['arg1', '', 'arg3', '']") self.assertEqual( filter_url('http://domain.com/welcome/default/f', out=True), "/f") self.assertEqual(regex_filter_out('/welcome/default/f'), "/f") self.assertEqual( str(URL(a='welcome', c='default', f='f', args=None)), "/f") self.assertEqual(str( URL(a='welcome', c='default', f='f', args=['arg1'])), "/f/arg1") self.assertEqual(str(URL( a='welcome', c='default', f='f', args=['arg1', ''])), "/f/arg1//") self.assertEqual(str(URL(a='welcome', c='default', f='f', args=['arg1', '', 'arg3'])), "/f/arg1//arg3") self.assertEqual(str( URL(a='welcome', c='default', f='f', args=['ar g'])), "/f/ar%20g") self.assertEqual(str(URL( a='welcome', c='default', f='f', args=['årg'])), "/f/%C3%A5rg") self.assertEqual( URL(a='welcome', c='default', f='fünc'), "/fünc") self.assertEqual( to_bytes(URL(a='welcome', c='default', f='fünc')), b"/f\xc3\xbcnc")
def post(self, url, data=None, cookies=None, headers=None, auth=None, method='auto'): self.url = self.app + url # if this POST form requires a postback do it if data and '_formname' in data and self.postbacks and \ self.history and self.history[-1][1] != self.url: # to bypass the web2py CSRF need to get formkey # before submitting the form self.get(url, cookies=cookies, headers=headers, auth=auth) # unless cookies are specified, recycle cookies if cookies is None: cookies = self.cookies cookies = cookies or {} headers = headers or {} args = [ urllib2.HTTPCookieProcessor(self.cookiejar), urllib2.HTTPHandler(debuglevel=0) ] # if required do basic auth if auth: auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(**auth) args.append(auth_handler) opener = urllib2.build_opener(*args) # copy headers from dict to list of key,value headers_list = [] for key, value in iteritems(self.default_headers): if not key in headers: headers[key] = value for key, value in iteritems(headers): if isinstance(value, (list, tuple)): for v in value: headers_list.append((key, v)) else: headers_list.append((key, value)) # move cookies to headers for key, value in iteritems(cookies): headers_list.append(('Cookie', '%s=%s' % (key, value))) # add headers to request for key, value in headers_list: opener.addheaders.append((key, str(value))) # assume everything is ok and make http request error = None try: if isinstance(data, str): self.method = 'POST' if method=='auto' else method elif isinstance(data, dict): self.method = 'POST' if method=='auto' else method # if there is only one form, set _formname automatically if not '_formname' in data and len(self.forms) == 1: data['_formname'] = self.forms.keys()[0] # if there is no formkey but it is known, set it if '_formname' in data and not '_formkey' in data and \ data['_formname'] in self.forms: data['_formkey'] = self.forms[data['_formname']] # time the POST request data = urlencode(data, doseq=True) else: self.method = 'GET' if method=='auto' else method data = None t0 = time.time() self.response = opener.open(self.url, to_bytes(data)) self.time = time.time() - t0 except urllib2.HTTPError as er: error = er # catch HTTP errors self.time = time.time() - t0 self.response = er if hasattr(self.response, 'getcode'): self.status = self.response.getcode() else:#python2.5 self.status = None self.text = to_native(self.response.read()) # In PY3 self.response.headers are case sensitive self.headers = dict() for h in self.response.headers: self.headers[h.lower()] = self.response.headers[h] # treat web2py tickets as special types of errors if error is not None: if 'web2py_error' in self.headers: raise RuntimeError(self.headers['web2py_error']) else: raise error self._parse_headers_in_cookies() # check is a new session id has been issued, symptom of broken session if self.session_regex is not None: for cookie, value in iteritems(self.cookies): match = self.session_regex.match(cookie) if match: name = match.group('name') if name in self.sessions and self.sessions[name] != value: print(RuntimeError('Changed session ID %s' % name)) self.sessions[name] = value # find all forms and formkeys in page self.forms = {} for match in FORM_REGEX.finditer(to_native(self.text)): self.forms[match.group('formname')] = match.group('formkey') # log this request self.history.append((self.method, self.url, self.status, self.time))