From 7ce50d19fcdfd82e88a6c542f665aedbd8bef447 Mon Sep 17 00:00:00 2001 From: philipp Date: Fri, 10 May 2019 22:14:51 +0000 Subject: [PATCH] Move password_is_correct to auth module. git-svn-id: http://www.winterrodeln.org/svn/wradmin/trunk@2813 7aebc617-e5e2-0310-91dc-80fb5f6d2477 --- wradmin/auth/__init__.py | 32 ++++++++++++++ wradmin/lib/mediawiki.py | 93 ---------------------------------------- 2 files changed, 32 insertions(+), 93 deletions(-) create mode 100644 wradmin/auth/__init__.py delete mode 100644 wradmin/lib/mediawiki.py diff --git a/wradmin/auth/__init__.py b/wradmin/auth/__init__.py new file mode 100644 index 0000000..1292b99 --- /dev/null +++ b/wradmin/auth/__init__.py @@ -0,0 +1,32 @@ +from authkit.users import md5, AuthKitError + + +def password_is_correct(password_plain, password_db): + """Returns true if a plain text password corresponds to the hash of the password as stored in the MediaWiki db. + + :param password_plain: plain text password, e.g. 'abc' + :param password_db: complete password line as stored in the database, e.g. ':pbkdf2:sha256:10000:128:EXgVGhc2mAs710feKvkiaw==:J5fYth9pg/R2d0F8bSsYfTR8SBpTBNIcdv/DgJ0tOPC1rtajl2Dr0RLqOozLb8O0XpDhtv4a3JJd/M0b58WebfNWAcdJBJI9nNeC0EYYD7OCYZGVAaRhiYtK4m53KZBBL6x/k2j4RjHPT1NmgV8Fr1DPqBNOlOHxUIh5z5oslM4=' + """ + if not password_db.startswith(':'): + raise AuthKitError("Password entry in the database does have an unexpected format (does not start with ':').") + pwd_parts = password_db[1:].split(':') + pwd_type = pwd_parts[0] + if pwd_type == 'B': + # legacy + # example: password_db == ':B:d25b2886:41e46c952790b1b442aac4f24f7ea7a8' + # pwd_parts == ['B', 'd25b2886', '41e46c952790b1b442aac4f24f7ea7a8'] + if len(pwd_parts) != 3: + raise AuthKitError("Password entry in the database does have an unexpected format (too few ':').") + salt, pwd_md5 = tuple(pwd_parts[1:3]) # salt = 'd25b2886'; pwd_md5 = '41e46c952790b1b442aac4f24f7ea7a8' + # log.info("user: '%s'; md5 of salt+' '+entered_pwd: '%s'; md5-part of DB-pwd: %s" % (username, md5(salt + '-' + md5(password)), pwd_md5)) + return md5(salt + '-' + md5(password_plain)) == pwd_md5 + elif pwd_type == 'pbkdf2': + if len(pwd_parts) != 6: + raise AuthKitError("Password entry in the database does have an unexpected format (too few ':').") + _, algorithm, rounds, num_bit, salt, pwd_hash = pwd_parts + from base64 import b64decode, b64encode + from hashlib import pbkdf2_hmac + salt = b64decode(salt) + hash = pbkdf2_hmac(algorithm, password_plain, salt, int(rounds), int(num_bit)) + hash = b64encode(hash) + return hash == pwd_hash diff --git a/wradmin/lib/mediawiki.py b/wradmin/lib/mediawiki.py deleted file mode 100644 index c083305..0000000 --- a/wradmin/lib/mediawiki.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/python3.4 -# $Id$ -"""MediaWiki communication functions""" -import datetime -import re - -from authkit.users import UsersReadOnly, md5, AuthKitError -import formencode, formencode.national - -import logging -log = logging.getLogger(__name__) - -import wradmin.model as model - - -# User management -# --------------- - -class MediaWikiUsers(UsersReadOnly): - def __init__(self, data=None, encrypt=None): - UsersReadOnly.__init__(self, data, encrypt) - - # Initialize class fields - self.usernames = [] - self.passwords = {} - self.roles = {} - self.groups = {} - self.user_ids = {} # MediaWiki user_id field of the database - self.real_names = {} # Real names of the users - self.emails = {} # E-Mail addresses of the users - - # Query database - con = model.meta.engine.connect() - sql = "SELECT user_id, user_name, user_real_name, user_password, user_email FROM user, user_groups WHERE ug_user=user_id AND ug_group='beauftragte'" - result = con.execute(sql) - for row in result: - user_id, username, real_name, password, email = row - username = username.lower() - role = [] - group = None - - self.usernames.append(username) - self.passwords[username] = password - self.roles[username] = role - self.groups[username] = group - self.user_ids[username] = user_id - self.real_names[username] = real_name - self.emails[username] = email - con.close() - log.info("%d users loaded from the MediaWiki database" % len(self.usernames)) - - @staticmethod - def password_is_correct(password_plain, password_db): - """Returns true if a plain text password corresponds to the hash of the password as stored in the MediaWiki db. - - :param password_plain: plain text password, e.g. 'abc' - :param password_db: complete password line as stored in the database, e.g. ':pbkdf2:sha256:10000:128:EXgVGhc2mAs710feKvkiaw==:J5fYth9pg/R2d0F8bSsYfTR8SBpTBNIcdv/DgJ0tOPC1rtajl2Dr0RLqOozLb8O0XpDhtv4a3JJd/M0b58WebfNWAcdJBJI9nNeC0EYYD7OCYZGVAaRhiYtK4m53KZBBL6x/k2j4RjHPT1NmgV8Fr1DPqBNOlOHxUIh5z5oslM4=' - """ - if not password_db.startswith(':'): - raise AuthKitError("Password entry in the database does have an unexpected format (does not start with ':').") - pwd_parts = password_db[1:].split(':') - pwd_type = pwd_parts[0] - if pwd_type == 'B': - # legacy - # example: password_db == ':B:d25b2886:41e46c952790b1b442aac4f24f7ea7a8' - # pwd_parts == ['B', 'd25b2886', '41e46c952790b1b442aac4f24f7ea7a8'] - if len(pwd_parts) != 3: - raise AuthKitError("Password entry in the database does have an unexpected format (too few ':').") - salt, pwd_md5 = tuple(pwd_parts[1:3]) # salt = 'd25b2886'; pwd_md5 = '41e46c952790b1b442aac4f24f7ea7a8' - # log.info("user: '%s'; md5 of salt+' '+entered_pwd: '%s'; md5-part of DB-pwd: %s" % (username, md5(salt + '-' + md5(password)), pwd_md5)) - return md5(salt + '-' + md5(password_plain)) == pwd_md5 - elif pwd_type == 'pbkdf2': - if len(pwd_parts) != 6: - raise AuthKitError("Password entry in the database does have an unexpected format (too few ':').") - _, algorithm, rounds, num_bit, salt, pwd_hash = pwd_parts - from base64 import b64decode, b64encode - from hashlib import pbkdf2_hmac - salt = b64decode(salt) - hash = pbkdf2_hmac(algorithm, password_plain, salt, int(rounds), int(num_bit)) - hash = b64encode(hash) - return hash == pwd_hash - - - def user_has_password(self, username, password): - """ - Passwords are case sensitive. - Returns ``True`` if the user has the password specified, ``False`` otherwise. - Raises an exception if the user doesn't exist. - - See http://www.winterrodeln.org/trac/wiki/MediaWikiAuthorization - """ - password_db = self.user_password(username) - return self.password_is_correct(password, password_db) -- 2.39.5