Loading ccserver/conf.py +80 −3 Original line number Diff line number Diff line Loading @@ -36,11 +36,14 @@ u'node' >>> ''' import hashlib import base64 import random import threading import logging import json import os import re from functools import wraps class CCConf(object): Loading @@ -55,6 +58,8 @@ class CCConf(object): 'tags': [], 'perms': None} RE_SALTPW = re.compile(r'{(?P<method>[A-Z]+)}(?P<password>.+)') def __init__(self, path_directory): self._path = path_directory self._lock = threading.Lock() Loading Loading @@ -115,6 +120,61 @@ class CCConf(object): return self._get_conf(login) def _unsaltify(self, string, digest_size): string = base64.decodestring(string) password = string[0:digest_size] salt = string[digest_size:] return password, salt def _get_randsalt(self, size=10): salt = '' for _ in xrange(size): salt += chr(random.randint(1, 255)) return salt def _auth_ssha(self, provided_passwd, configured_passwd=None): if configured_passwd is not None: salt = self._unsaltify(configured_passwd, 20)[1] else: salt = self._get_randsalt() digest = hashlib.sha1(str(provided_passwd) + salt).digest() return '{SSHA}%s' % base64.b64encode(digest + salt) def _auth_sha(self, configured_passwd, provided_passwd): digest = hashlib.sha1(str(provided_passwd)).digest() return '{SHA}%s' % base64.b64encode(digest) def _auth_smd5(self, configured_passwd, provided_passwd): if configured_passwd is not None: salt = self._unsaltify(configured_passwd, 16)[1] else: salt = self._get_randsalt() digest = hashlib.sha1(str(provided_passwd) + salt).digest() return '{SMD5}%s' % base64.b64encode(digest + salt) def _auth_md5(self, configured_passwd, provided_passwd): digest = hashlib.sha1(str(provided_passwd)).digest() return '{MD5}%s' % base64.b64encode(digest) def _auth_plain(self, configured_passwd, provided_passwd): return provided_passwd def _hash_password(self, password, method='ssha'): ''' Hash a password using given method and return it. :param password: the password to hash :param method: the hashing method :return: hashed password ''' meth = '_auth_%s' % method.lower() if hasattr(self, meth): auth = getattr(self, meth) return auth(password) else: raise CCConf.BadMethodError("Bad hashing method: '%s'" % method) def authentify(self, login, password): ''' Authentify the client providing its login and password. The function Loading @@ -127,13 +187,26 @@ class CCConf(object): ''' conf = self._get_conf(login) if conf['password'] == password: passwd_conf = conf['password'] is_valid = False m = CCConf.RE_SALTPW.match(passwd_conf) if m is None: is_valid = self._auth_plain(passwd_conf, password) else: meth = '_auth_%s' % m.group('method').lower() if hasattr(self, meth): auth = getattr(self, meth) is_valid = auth(password, m.group('password')) == passwd_conf else: logging.warning('Bad authentication method for %s: ' '%s' % (login, m.group('method'))) if is_valid: return conf['role'] else: return None @_writer def set_password(self, login, password): def set_password(self, login, password, method='ssha'): ''' Update the client's password in the configuration. Loading @@ -143,6 +216,7 @@ class CCConf(object): ''' conf = self._get_conf(login) password = self._hash_password(password, method) conf['password'] = password self._set_conf(login, conf) Loading Loading @@ -240,3 +314,6 @@ class CCConf(object): class AlreadyExistingAccount(Exception): pass class BadMethodError(Exception): pass Loading
ccserver/conf.py +80 −3 Original line number Diff line number Diff line Loading @@ -36,11 +36,14 @@ u'node' >>> ''' import hashlib import base64 import random import threading import logging import json import os import re from functools import wraps class CCConf(object): Loading @@ -55,6 +58,8 @@ class CCConf(object): 'tags': [], 'perms': None} RE_SALTPW = re.compile(r'{(?P<method>[A-Z]+)}(?P<password>.+)') def __init__(self, path_directory): self._path = path_directory self._lock = threading.Lock() Loading Loading @@ -115,6 +120,61 @@ class CCConf(object): return self._get_conf(login) def _unsaltify(self, string, digest_size): string = base64.decodestring(string) password = string[0:digest_size] salt = string[digest_size:] return password, salt def _get_randsalt(self, size=10): salt = '' for _ in xrange(size): salt += chr(random.randint(1, 255)) return salt def _auth_ssha(self, provided_passwd, configured_passwd=None): if configured_passwd is not None: salt = self._unsaltify(configured_passwd, 20)[1] else: salt = self._get_randsalt() digest = hashlib.sha1(str(provided_passwd) + salt).digest() return '{SSHA}%s' % base64.b64encode(digest + salt) def _auth_sha(self, configured_passwd, provided_passwd): digest = hashlib.sha1(str(provided_passwd)).digest() return '{SHA}%s' % base64.b64encode(digest) def _auth_smd5(self, configured_passwd, provided_passwd): if configured_passwd is not None: salt = self._unsaltify(configured_passwd, 16)[1] else: salt = self._get_randsalt() digest = hashlib.sha1(str(provided_passwd) + salt).digest() return '{SMD5}%s' % base64.b64encode(digest + salt) def _auth_md5(self, configured_passwd, provided_passwd): digest = hashlib.sha1(str(provided_passwd)).digest() return '{MD5}%s' % base64.b64encode(digest) def _auth_plain(self, configured_passwd, provided_passwd): return provided_passwd def _hash_password(self, password, method='ssha'): ''' Hash a password using given method and return it. :param password: the password to hash :param method: the hashing method :return: hashed password ''' meth = '_auth_%s' % method.lower() if hasattr(self, meth): auth = getattr(self, meth) return auth(password) else: raise CCConf.BadMethodError("Bad hashing method: '%s'" % method) def authentify(self, login, password): ''' Authentify the client providing its login and password. The function Loading @@ -127,13 +187,26 @@ class CCConf(object): ''' conf = self._get_conf(login) if conf['password'] == password: passwd_conf = conf['password'] is_valid = False m = CCConf.RE_SALTPW.match(passwd_conf) if m is None: is_valid = self._auth_plain(passwd_conf, password) else: meth = '_auth_%s' % m.group('method').lower() if hasattr(self, meth): auth = getattr(self, meth) is_valid = auth(password, m.group('password')) == passwd_conf else: logging.warning('Bad authentication method for %s: ' '%s' % (login, m.group('method'))) if is_valid: return conf['role'] else: return None @_writer def set_password(self, login, password): def set_password(self, login, password, method='ssha'): ''' Update the client's password in the configuration. Loading @@ -143,6 +216,7 @@ class CCConf(object): ''' conf = self._get_conf(login) password = self._hash_password(password, method) conf['password'] = password self._set_conf(login, conf) Loading Loading @@ -240,3 +314,6 @@ class CCConf(object): class AlreadyExistingAccount(Exception): pass class BadMethodError(Exception): pass