Beispiel #1
0
def authenticate(passwordFile: HtpasswdFile, credentials: Credentials) -> None:
    """Checks a name and password combination against a password file.

    Returns if authentication succeeds.
    Raises `UnauthorizedLogin` if the given user name and password
    combination is not accepted.

    The hashed version of the password will be updated with a new
    hash function if the current one is depricated.
    """

    name = credentials.name
    password = credentials.password

    try:
        checkPassword(password)
    except ValueError as ex:
        raise UnauthorizedLogin(ex) from ex

    # Have passlib check the password. When passed a None hash, it will
    # perform a dummy computation to keep the timing consistent.
    passwordFile.load_if_changed()
    correct, newHash = passwordFile.context.verify_and_update(
        password.encode(), passwordFile.get_hash(name))
    if not correct:
        raise UnauthorizedLogin('Authentication failed')

    if newHash is not None:
        # Replace hash with better algorithm or config.
        passwordFile.set_hash(name, newHash)
        writePasswordFile(passwordFile)
class HtpasswdAuthenticator(object):
    """
    Handles the user authentication for htpasswd files
    htpasswd is the location of the htpasswd to use
    """
    def __init__(self):
        #try to locate the server config and load it
        server_folder = os.path.join(os.path.expanduser("~"), '.conan_server')
        server_conf = os.path.join(server_folder, "server.conf")
        htpasswd_location = os.path.join(server_folder, "plugins",
                                         "authentication", ".htpasswd")
        if os.path.exists(server_conf):
            conf = ConfigParser()
            conf.read(server_conf)
            new_loc = conf.get("server", "htpasswd_file")
            if os.path.exists(new_loc):
                htpasswd_location = new_loc

        self.htpasswd = HtpasswdFile(htpasswd_location)

    def valid_user(self, username, plain_password):
        """
        username: Username to be authenticated
        plain_password: The password to authenticate with
        return: True if match False if don't
        """
        # Update
        self.htpasswd.load_if_changed()
        # Verify
        return username in self.htpasswd.users() and \
               self.htpasswd.check_password(username, plain_password)
Beispiel #3
0
 def authenticate(self, request):
     """Authenticate the provided request."""
     if (self.config.password_file is None
             or self.config.password_file == '.'):
         return True
     pwd_file = HtpasswdFile(self.config.password_file)
     pwd_file.load_if_changed()
     return pwd_file.check_password(*request.auth)
Beispiel #4
0
class TestAuthnz(object):
    def __init__(self,
                 htpasswd_file=".htpasswd",
                 perms_file=".repoperms",
                 keys_file=".rsakeys"):
        self.htpasswd = HtpasswdFile(htpasswd_file)
        self.perms_file = perms_file
        self.keys_file = keys_file

    def can_read(self, username, path_info):
        return self._check_access(username, path_info, "r")

    def can_write(self, username, path_info):
        return self._check_access(username, path_info, "w")

    def _check_access(self, username, path_info, level):
        if username is None:
            username = "******"

        if path_info['repository_fs_path'] is None:
            return False

        repo = os.path.basename(path_info['repository_fs_path'])

        config = SafeConfigParser()
        config.read(self.perms_file)

        if not config.has_option(repo, username):
            return False

        return level in config.get(repo, username)

    def check_password(self, username, password):
        self.htpasswd.load_if_changed()
        return self.htpasswd.check_password(username, password)

    def check_publickey(self, username, keyblob):
        with open(self.keys_file, 'rb') as f:
            for line in f:
                try:
                    user, key = line.split(':', 1)
                    if (username == user.strip() and
                        keyblob == keys.Key.fromString(data=key.strip()
                                                       ).blob()):
                        return True
                except:
                    log.err(None, "Loading key failed")
        return False
Beispiel #5
0
class TestAuthnz(object):
    def __init__(self,
                 htpasswd_file=".htpasswd",
                 perms_file=".repoperms",
                 keys_file=".rsakeys"):
        self.htpasswd = HtpasswdFile(htpasswd_file)
        self.perms_file = perms_file
        self.keys_file = keys_file

    def can_read(self, username, path_info):
        return self._check_access(username, path_info, "r")

    def can_write(self, username, path_info):
        return self._check_access(username, path_info, "w")

    def _check_access(self, username, path_info, level):
        if username is None:
            username = "******"

        if path_info['repository_fs_path'] is None:
            return False

        repo = os.path.basename(path_info['repository_fs_path'])

        config = SafeConfigParser()
        config.read(self.perms_file)

        if not config.has_option(repo, username):
            return False

        return level in config.get(repo, username)

    def check_password(self, username, password):
        self.htpasswd.load_if_changed()
        return self.htpasswd.check_password(username, password)

    def check_publickey(self, username, keyblob):
        with open(self.keys_file, 'rb') as f:
            for line in f:
                try:
                    user, key = line.split(':', 1)
                    if (username == user.strip() and keyblob
                            == keys.Key.fromString(data=key.strip()).blob()):
                        return True
                except:
                    log.err(None, "Loading key failed")
        return False
Beispiel #6
0
class HtpasswdUsers(Component):

    implements(IUserAuthenticator)
    implements(IUserTranslator)
    implements(IUserStore)

    def __init__(self):
        config = self.get_component_config()

        if 'file' not in config:
            raise InsufficientConfiguration(missing='file', component=self.get_component_name())

        self.htpasswd = HtpasswdFile(config['file'])

    def username_to_user(self, username):
        self.htpasswd.load_if_changed()
        if username in self.htpasswd.users():
            return HtpasswdUser(self, username, username=username, full_name=username)

    def userid_to_user(self, userid):
        if userid is None or userid == '*':
            warnings.warn("You should not call this directly. Use cydra.get_user()", DeprecationWarning, stacklevel=2)
            return self.compmgr.get_user(userid='*')

        self.htpasswd.load_if_changed()
        if userid in self.htpasswd.users():
            return HtpasswdUser(self, userid, username=userid, full_name=userid)
        else:
            # since the client was looking for a specific ID,
            # we return a dummy user object with empty data
            return User(self, userid, full_name='N/A')

    def groupid_to_group(self, groupid):
        pass

    def user_password(self, user, password):
        self.htpasswd.load_if_changed()
        return self.htpasswd.check_password(user.userid, password)

    def create_user(self, **kwargs):
        self.htpasswd.load_if_changed()

        userid = None
        if 'id' in kwargs:
            userid = kwargs['id']
        elif 'username' in kwargs:
            userid = kwargs['username']
        else:
            raise ValueError("No username/id specified")

        if userid in self.htpasswd.users():
            raise ValueError("User with this id already exists")
        else:
            self.htpasswd.set_password(userid, hashlib.sha1(os.urandom(8)).hexdigest())
            self.htpasswd.save()
            return userid
Beispiel #7
0
class HtpasswdUsers(Component):

    implements(IUserAuthenticator)
    implements(IUserTranslator)

    def __init__(self):
        config = self.get_component_config()

        if 'file' not in config:
            raise InsufficientConfiguration(missing='file', component=self.get_component_name())

        self.htpasswd = HtpasswdFile(config['file'])

    def username_to_user(self, username):
        self.htpasswd.load_if_changed()
        if username in self.htpasswd.users():
            return User(self.compmgr, username, username=username, full_name=username)


    def userid_to_user(self, userid):
        if userid is None or userid == '*':
            warnings.warn("You should not call this directly. Use cydra.get_user()", DeprecationWarning, stacklevel=2)
            return User(self.compmgr, '*', username='******', full_name='Guest')

        self.htpasswd.load_if_changed()
        if userid in self.htpasswd.users():
            return User(self.compmgr, userid, username=userid, full_name=userid)
        else:
            # since the client was looking for a specific ID,
            # we return a dummy user object with empty data
            return User(self.compmgr, userid, full_name='N/A')

    def groupid_to_group(self, groupid):
        pass

    def user_password(self, user, password):
        self.htpasswd.load_if_changed()
        return self.htpasswd.check_password(user.userid, password)