diff --git a/rhodecode/__init__.py b/rhodecode/__init__.py --- a/rhodecode/__init__.py +++ b/rhodecode/__init__.py @@ -25,11 +25,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. - +import platform VERSION = (1, 2, 0, 'beta') __version__ = '.'.join((str(each) for each in VERSION[:4])) __dbversion__ = 3 #defines current db version for migrations +__platform__ = platform.system() try: from rhodecode.lib.utils import get_current_revision @@ -48,5 +49,5 @@ def get_version(): BACKENDS = { 'hg': 'Mercurial repository', - #'git': 'Git repository', + #'git': 'Git repository', } diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py --- a/rhodecode/lib/auth.py +++ b/rhodecode/lib/auth.py @@ -24,11 +24,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. -import bcrypt import random import logging import traceback import hashlib + from tempfile import _RandomNameSequence from decorator import decorator @@ -36,6 +36,14 @@ from pylons import config, session, url, from pylons.controllers.util import abort, redirect from pylons.i18n.translation import _ +from rhodecode import __platform__ + +if __platform__ == 'Windows': + from hashlib import sha256 +if __platform__ in ('Linux', 'Darwin'): + import bcrypt + + from rhodecode.lib.exceptions import LdapPasswordError, LdapUsernameError from rhodecode.lib.utils import get_repo_slug from rhodecode.lib.auth_ldap import AuthLdap @@ -72,13 +80,49 @@ class PasswordGenerator(object): self.passwd = ''.join([random.choice(type) for _ in xrange(len)]) return self.passwd +class RhodeCodeCrypto(object): + + @classmethod + def hash_string(cls, str_): + """ + Cryptographic function used for password hashing based on pybcrypt + or pycrypto in windows + + :param password: password to hash + """ + if __platform__ == 'Windows': + return sha256(str_).hexdigest() + elif __platform__ in ('Linux', 'Darwin'): + return bcrypt.hashpw(str_, bcrypt.gensalt(10)) + else: + raise Exception('Unknown or unsupoprted platform %s' % __platform__) + + @classmethod + def hash_check(cls, password, hashed): + """ + Checks matching password with it's hashed value, runs different + implementation based on platform it runs on + + :param password: password + :param hashed: password in hashed form + """ + + if __platform__ == 'Windows': + return sha256(password).hexdigest() == hashed + elif __platform__ in ('Linux', 'Darwin'): + return bcrypt.hashpw(password, hashed) == hashed + else: + raise Exception('Unknown or unsupoprted platform %s' % __platform__) + + + + def get_crypt_password(password): - """Cryptographic function used for password hashing based on pybcrypt - - :param password: password to hash - """ - return bcrypt.hashpw(password, bcrypt.gensalt(10)) + return RhodeCodeCrypto.hash_string(password) + +def check_password(password, hashed): + return RhodeCodeCrypto.hash_check(password, hashed) def generate_api_key(username, salt=None): if salt is None: @@ -86,9 +130,6 @@ def generate_api_key(username, salt=None return hashlib.sha1(username + salt).hexdigest() -def check_password(password, hashed): - return bcrypt.hashpw(password, hashed) == hashed - def authfunc(environ, username, password): """Dummy authentication function used in Mercurial/Git/ and access control, diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ import sys from rhodecode import get_version +from rhodecode import __platform__ py_version = sys.version_info @@ -13,7 +14,6 @@ requirements = [ "mercurial>=1.7.5", "whoosh>=1.3.4", "celery>=2.2.4", - "py-bcrypt", "babel", ] @@ -29,6 +29,10 @@ if py_version < (2, 6): requirements.append("simplejson") requirements.append("pysqlite") +if __platform__ in ('Linux', 'Darwin'): + requirements.append("py-bcrypt") + + #additional files from project that goes somewhere in the filesystem #relative to sys.prefix data_files = []