def md5crypt(password, salt, magic='$1$'): # /* The password first, since that is what is most unknown */ /* Then our magic string */ /* Then the raw salt */ m = md5() m.update(password + magic + salt) # /* Then just as many characters of the MD5(pw,salt,pw) */ mixin = md5(password + salt + password).digest() for i in range(0, len(password)): m.update(mixin[i % 16]) # /* Then something really weird... */ # Also really broken, as far as I can tell. -m i = len(password) while i: if i & 1: m.update('\x00') else: m.update(password[0]) i >>= 1 final = m.digest() # /* and now, just to make sure things don't run too fast */ for i in range(1000): m2 = md5() if i & 1: m2.update(password) else: m2.update(final) if i % 3: m2.update(salt) if i % 7: m2.update(password) if i & 1: m2.update(final) else: m2.update(password) final = m2.digest() # This is the bit that uses to64() in the original code. itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' rearranged = '' for a, b, c in ((0, 6, 12), (1, 7, 13), (2, 8, 14), (3, 9, 15), (4, 10, 5)): v = ord(final[a]) << 16 | ord(final[b]) << 8 | ord(final[c]) for i in range(4): rearranged += itoa64[v & 0x3f]; v >>= 6 v = ord(final[11]) for i in range(2): rearranged += itoa64[v & 0x3f]; v >>= 6 return magic + salt + '$' + rearranged
def get_user_attribute(env, username=None, authenticated=1, attribute=None, value=None, db=None): """Return user attributes.""" ALL_COLS = ('sid', 'authenticated', 'name', 'value') columns = [] constraints = [] if username is not None: columns.append('sid') constraints.append(username) if authenticated is not None: columns.append('authenticated') constraints.append(authenticated) if attribute is not None: columns.append('name') constraints.append(attribute) if value is not None: columns.append('value') constraints.append(value) sel_columns = [col for col in ALL_COLS if col not in columns] if len(sel_columns) == 0: # No variable left, so only COUNTing is as a sensible task here. sel_stmt = 'COUNT(*)' else: if 'sid' not in sel_columns: sel_columns.append('sid') sel_stmt = ','.join(sel_columns) if len(columns) > 0: where_stmt = ''.join(['WHERE ', '=%s AND '.join(columns), '=%s']) else: where_stmt = '' sql = """ SELECT %s FROM session_attribute %s """ % (sel_stmt, where_stmt) sql_args = tuple(constraints) db = _get_db(env, db) cursor = db.cursor() cursor.execute(sql, sql_args) rows = cursor.fetchall() if rows is None: return {} res = {} for row in rows: if sel_stmt == 'COUNT(*)': return [row[0]] res_row = {} res_row.update(zip(sel_columns, row)) # Merge with constraints, that are constants for this SQL query. res_row.update(zip(columns, constraints)) account = res_row.pop('sid') authenticated = res_row.pop('authenticated') # Create single unique attribute ID. m = md5() m.update(''.join([account, str(authenticated), res_row.get('name')]).encode('utf-8')) row_id = m.hexdigest() if account in res: if authenticated in res[account]: res[account][authenticated].update({ res_row['name']: res_row['value'] }) res[account][authenticated]['id'].update({ res_row['name']: row_id }) else: res[account][authenticated] = { res_row['name']: res_row['value'], 'id': {res_row['name']: row_id} } # Create account ID for additional authentication state. m = md5() m.update(''.join([account, str(authenticated)]).encode('utf-8')) res[account]['id'][authenticated] = m.hexdigest() else: # Create account ID for authentication state. m = md5() m.update(''.join([account, str(authenticated)]).encode('utf-8')) res[account] = {authenticated: {res_row['name']: res_row['value'], 'id': {res_row['name']: row_id}}, 'id': {authenticated: m.hexdigest()}} return res
def md5crypt(password, salt, magic='$1$'): # /* The password first, since that is what is most unknown */ /* Then our magic string */ /* Then the raw salt */ m = md5() m.update(password + magic + salt) # /* Then just as many characters of the MD5(pw,salt,pw) */ mixin = md5(password + salt + password).digest() for i in range(0, len(password)): m.update(mixin[i % 16]) # /* Then something really weird... */ # Also really broken, as far as I can tell. -m i = len(password) while i: if i & 1: m.update('\x00') else: m.update(password[0]) i >>= 1 final = m.digest() # /* and now, just to make sure things don't run too fast */ for i in range(1000): m2 = md5() if i & 1: m2.update(password) else: m2.update(final) if i % 3: m2.update(salt) if i % 7: m2.update(password) if i & 1: m2.update(final) else: m2.update(password) final = m2.digest() # This is the bit that uses to64() in the original code. itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' rearranged = '' for a, b, c in ((0, 6, 12), (1, 7, 13), (2, 8, 14), (3, 9, 15), (4, 10, 5)): v = ord(final[a]) << 16 | ord(final[b]) << 8 | ord(final[c]) for i in range(4): rearranged += itoa64[v & 0x3f] v >>= 6 v = ord(final[11]) for i in range(2): rearranged += itoa64[v & 0x3f] v >>= 6 return magic + salt + '$' + rearranged
def htdigest(user, realm, password): p = ':'.join([user, realm, password]) return md5(p).hexdigest()
def get_user_attribute(env, username=None, authenticated=1, attribute=None, value=None, db=None): """Return user attributes.""" ALL_COLS = ('sid', 'authenticated', 'name', 'value') columns = [] constraints = [] if username is not None: columns.append('sid') constraints.append(username) if authenticated is not None: columns.append('authenticated') constraints.append(authenticated) if attribute is not None: columns.append('name') constraints.append(attribute) if value is not None: columns.append('value') constraints.append(value) sel_columns = [col for col in ALL_COLS if col not in columns] if len(sel_columns) == 0: # No variable left, so only COUNTing is as a sensible task here. sel_stmt = 'COUNT(*)' else: if 'sid' not in sel_columns: sel_columns.append('sid') sel_stmt = ','.join(sel_columns) if len(columns) > 0: where_stmt = ''.join(['WHERE ', '=%s AND '.join(columns), '=%s']) else: where_stmt = '' sql = """ SELECT %s FROM session_attribute %s """ % (sel_stmt, where_stmt) sql_args = tuple(constraints) db = _get_db(env, db) cursor = db.cursor() cursor.execute(sql, sql_args) rows = cursor.fetchall() if rows is None: return {} res = {} for row in rows: if sel_stmt == 'COUNT(*)': return [row[0]] res_row = {} res_row.update(zip(sel_columns, row)) # Merge with constraints, that are constants for this SQL query. res_row.update(zip(columns, constraints)) account = res_row.pop('sid') authenticated = res_row.pop('authenticated') # Create single unique attribute ID. m = md5() m.update(''.join([account, str(authenticated), res_row.get('name')]).encode('utf-8')) row_id = m.hexdigest() if account in res: if authenticated in res[account]: res[account][authenticated].update( {res_row['name']: res_row['value']}) res[account][authenticated]['id'].update( {res_row['name']: row_id}) else: res[account][authenticated] = { res_row['name']: res_row['value'], 'id': { res_row['name']: row_id } } # Create account ID for additional authentication state. m = md5() m.update(''.join([account, str(authenticated)]).encode('utf-8')) res[account]['id'][authenticated] = m.hexdigest() else: # Create account ID for authentication state. m = md5() m.update(''.join([account, str(authenticated)]).encode('utf-8')) res[account] = { authenticated: { res_row['name']: res_row['value'], 'id': { res_row['name']: row_id } }, 'id': { authenticated: m.hexdigest() } } return res