Пример #1
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password_encrypted = self.encrypt(password.encode("utf-8"))
        # encode with base64
        password_base64 = base64.encodestring(password_encrypted).decode()

        # ensure the file exists
        self._ensure_file_path()

        # load the keyring from the disk
        config = configparser.RawConfigParser()
        config.read(self.file_path)

        # update the keyring with the password
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, username, password_base64)

        # save the keyring back to the file
        config_file = open(self.file_path, "w")
        try:
            config.write(config_file)
        finally:
            config_file.close()
Пример #2
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        self._relocate_file()
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password_encrypted = self.encrypt(password.encode('utf-8'))
        # load the password from the disk
        config = ConfigParser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path)

        # encode with base64
        password_base64 = base64.encodestring(password_encrypted).decode()
        # write the modification
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, username, password_base64)
        # ensure the storage path exists
        if not os.path.isdir(os.path.dirname(self.file_path)):
            os.makedirs(os.path.dirname(self.file_path))
        config_file = open(self.file_path,'w')
        config.write(config_file)
Пример #3
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password_encrypted = self.encrypt(password.encode('utf-8'))
        # encode with base64
        password_base64 = base64.encodestring(password_encrypted).decode()

        # ensure the file exists
        self._ensure_file_path()

        # load the keyring from the disk
        config = configparser.RawConfigParser()
        config.read(self.file_path)

        # update the keyring with the password
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, username, password_base64)

        # save the keyring back to the file
        with open(self.file_path, 'w') as config_file:
            config.write(config_file)
Пример #4
0
    def get_password(self, service, username):
        """
        Read the password from the file.
        """
        assoc = self._generate_assoc(service, username)
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # load the passwords from the file
        config = configparser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path)

        # fetch the password
        try:
            password_base64 = config.get(service, username).encode()
            # decode with base64
            password_encrypted = decodebytes(password_base64)
            # decrypt the password with associated data
            try:
                password = self.decrypt(password_encrypted, assoc).decode('utf-8')
            except ValueError:
                # decrypt the password without associated data
                password = self.decrypt(password_encrypted).decode('utf-8')
        except (configparser.NoOptionError, configparser.NoSectionError):
            password = None
        return password
Пример #5
0
    def test_scheme(self):
        self.assertTrue(self.keyring.scheme is not None)

        # generate keyring
        self.keyring.set_password('system', 'user', 'password')
        config = self.get_config()
        krsetting = escape_for_ini('keyring-setting')
        scheme = escape_for_ini('scheme')
        defscheme = '[Argon2] AES128.GCM'

        # default scheme match
        if self.keyring.aesmode == 'GCM':
            self.assertTrue(config.get(krsetting, scheme) == defscheme)

        # invalid AES mode
        config.set(krsetting, scheme, defscheme.replace('GCM', 'XXX'))
        with pytest.raises(ValueError):
            self.keyring._check_scheme(config)

        # compatibility with former scheme format
        config.set(krsetting, scheme, 'PyCryptodome ' + defscheme)
        self.assertTrue(self.keyring._check_scheme(config) == None)

        # test with invalid KDF
        config.set(krsetting, scheme, defscheme.replace('Argon2', 'PBKDF2'))
        with pytest.raises(ValueError):
            self.keyring._check_scheme(config)

        # a missing scheme is valid
        config.remove_option(krsetting, scheme)
        self.save_config(config)
        self.assertTrue(self.keyring._check_file() == True)

        with pytest.raises(AttributeError):
            self.keyring._check_scheme(config)
Пример #6
0
    def _check_scheme(self, config):
        """
        check for a valid scheme

        raise AttributeError if missing
        raise ValueError if not valid
        """
        try:
            scheme = config.get(
                escape_for_ini('keyring-setting'),
                escape_for_ini('scheme'),
            )
        except (configparser.NoSectionError, configparser.NoOptionError):
            raise AttributeError("Encryption scheme missing")

        # extract AES mode
        aesmode = scheme[-3:]
        if aesmode not in self._get_mode():
            raise ValueError("Encryption scheme invalid: %s" % (aesmode))

        # setup AES mode
        self.aesmode = aesmode

        # remove pointless crypto module name
        if scheme.startswith('PyCryptodome '):
            scheme = scheme[13:]

        # check other scheme properties
        if scheme != self.scheme:
            raise ValueError("Encryption scheme mismatch "
                             "(exp.: %s, found: %s)" % (self.scheme, scheme))
    def delete_password(self, service, username):
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        try:
            self.config.remove_option(service, username)
        except configparser.NoSectionError:
            raise errors.PasswordDeleteError('Password not found')
        config_file = UnicodeWriterAdapter(self._open('w'))
        self.config.write(config_file)
        config_file.close()
Пример #8
0
    def delete_password(self, service, username):
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        try:
            self.config.remove_option(service, username)
        except configparser.NoSectionError:
            raise errors.PasswordDeleteError('Password not found')
        config_file = UnicodeWriterAdapter(self._open('w'))
        self.config.write(config_file)
        config_file.close()
Пример #9
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        assoc = (escape_for_ini(service) + '\0' +
                 escape_for_ini(username)).encode()
        # encrypt the password
        password_encrypted = self.encrypt(password.encode('utf-8'), assoc)
        # encode with base64 and add line break to untangle config file
        password_base64 = '\n' + encodebytes(password_encrypted).decode()

        self._write_config_value(service, username, password_base64)
Пример #10
0
 def _check_file(self):
     """
     Check if the file exists and has the expected password reference.
     """
     if not os.path.exists(self.file_path):
         return False
     self._migrate()
     config = configparser.RawConfigParser()
     config.read(self.file_path)
     try:
         config.get(escape_for_ini("keyring-setting"), escape_for_ini("password reference"))
     except (configparser.NoSectionError, configparser.NoOptionError):
         return False
     return True
Пример #11
0
    def _check_version(self, config):
        """
        check for a valid version
        an existing scheme implies an existing version as well

        return True, if version is valid, and False otherwise
        """
        try:
            self.file_version = config.get(
                    escape_for_ini('keyring-setting'),
                    escape_for_ini('version'),
            )
        except (configparser.NoSectionError, configparser.NoOptionError):
            return False
        return True
Пример #12
0
    def _check_version(self, config):
        """
        check for a valid version
        an existing scheme implies an existing version as well

        return True, if version is valid, and False otherwise
        """
        try:
            self.file_version = config.get(
                escape_for_ini('keyring-setting'),
                escape_for_ini('version'),
            )
        except (configparser.NoSectionError, configparser.NoOptionError):
            return False
        return True
Пример #13
0
 def delete_password(self, service, username):
     """Delete the password for the username of the service.
     """
     service = escape_for_ini(service)
     username = escape_for_ini(username)
     config = configparser.RawConfigParser()
     if os.path.exists(self.file_path):
         config.read(self.file_path)
     try:
         if not config.remove_option(service, username):
             raise PasswordDeleteError("Password not found")
     except configparser.NoSectionError:
         raise PasswordDeleteError("Password not found")
     # update the file
     with open(self.file_path, 'w') as config_file:
         config.write(config_file)
Пример #14
0
    def get_password(self, service, username):
        """Read the password from the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # fetch the password
        try:
            password_base64 = self.config.get(service, username).encode()
            # decode with base64
            password_encrypted = base64.decodestring(password_base64)
            # decrypted the password
            password = self.decrypt(password_encrypted).decode('utf-8')
        except (configparser.NoOptionError, configparser.NoSectionError):
            password = None
        return password
    def get_password(self, service, username):
        """Read the password from the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # fetch the password
        try:
            password_base64 = self.config.get(service, username).encode()
            # decode with base64
            password_encrypted = base64.decodestring(password_base64)
            # decrypted the password
            password = self.decrypt(password_encrypted).decode('utf-8')
        except (configparser.NoOptionError, configparser.NoSectionError):
            password = None
        return password
Пример #16
0
 def _check_file(self):
     """
     Check if the file exists and has the expected password reference.
     """
     if not os.path.exists(self.file_path):
         return False
     self._migrate()
     config = configparser.RawConfigParser()
     config.read(self.file_path)
     try:
         config.get(
             escape_for_ini('keyring-setting'),
             escape_for_ini('password reference'),
         )
     except (configparser.NoSectionError, configparser.NoOptionError):
         return False
     return True
Пример #17
0
    def get_password(self, service, username):
        """Read the password from the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # load the passwords from the file
        config = configparser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path, encoding='utf-8')

        # fetch the password
        try:
            password = config.get(service, username)
        except (configparser.NoOptionError, configparser.NoSectionError):
            password = None
        
        return password
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password = password or ''
        password_encrypted = self.encrypt(password.encode('utf-8'))

        # encode with base64
        password_base64 = base64.encodestring(password_encrypted).decode()
        # write the modification
        if not self.config.has_section(service):
            self.config.add_section(service)
        self.config.set(service, username, password_base64)
        config_file = UnicodeWriterAdapter(self._open('w'))
        self.config.write(config_file)
        config_file.close()
Пример #19
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password = password or ''
        password_encrypted = self.encrypt(password.encode('utf-8'))

        # encode with base64
        password_base64 = base64.encodestring(password_encrypted).decode()
        # write the modification
        if not self.config.has_section(service):
            self.config.add_section(service)
        self.config.set(service, username, password_base64)
        config_file = UnicodeWriterAdapter(self._open('w'))
        self.config.write(config_file)
        config_file.close()
Пример #20
0
    def _write_config_value(self, service, key, value):
        # ensure the file exists
        self._ensure_file_path()

        # load the keyring from the disk
        config = configparser.RawConfigParser()
        config.read(self.file_path)

        service = escape_for_ini(service)
        key = escape_for_ini(key)

        # update the keyring with the password
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, key, value)

        # save the keyring back to the file
        with open(self.file_path, 'w') as config_file:
            config.write(config_file)
Пример #21
0
    def test_version(self):
        # version exists
        self.assertTrue(self.keyring.version is not None)
        if not hasattr(self.keyring, '_check_version'):
            return

        # generate keyring
        self.keyring.set_password('system', 'user', 'password')
        config = self.get_config()

        # default version valid
        self.assertTrue(self.keyring._check_version(config) == True)

        krsetting = escape_for_ini('keyring-setting')
        version = escape_for_ini('version')

        # invalid, if version is missing
        config.remove_option(krsetting, version)
        self.save_config(config)
        self.assertTrue(self.keyring._check_version(config) == False)
Пример #22
0
    def test_version(self):
        # version exists
        self.assertTrue(self.keyring.version is not None)
        if not hasattr(self.keyring, '_check_version'):
            return

        # generate keyring
        self.keyring.set_password('system', 'user', 'password')
        config = self.get_config()

        # default version valid
        self.assertTrue(self.keyring._check_version(config) == True)

        krsetting = escape_for_ini('keyring-setting')
        version = escape_for_ini('version')

        # invalid, if version is missing
        config.remove_option(krsetting, version)
        self.save_config(config)
        self.assertTrue(self.keyring._check_version(config) == False)
Пример #23
0
 def delete_password(self, service, username):
     """Delete the password for the username of the service.
     """
     service = escape_for_ini(service)
     config = configparser.RawConfigParser()
     if os.path.exists(self.file_path):
         config.read(self.file_path)
     if not config.remove_section(service):
         raise PasswordDeleteError("Password not found")
     # update the file
     config_file = open(self.file_path, "w")
     config.write(config_file)
Пример #24
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password_encrypted = self.encrypt(password)
        # load the password from the disk
        config = ConfigParser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path)

        # encode with base64
        password_base64 = password_encrypted.encode("base64")
        # write the modification
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, username, password_base64)
        config_file = open(self.file_path,'w')
        config.write(config_file)
Пример #25
0
    def get_password(self, service, username):
        """Read the password from the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # load the passwords from the file
        config = ConfigParser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path)

        # fetch the password
        try:
            password_base64 = config.get(service, username)
            # decode with base64
            password_encrypted = password_base64.decode("base64")
            # decrypted the password
            password = self.decrypt(password_encrypted)
        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
            password = None
        return password
Пример #26
0
 def test_file(self):
     if not hasattr(self.keyring, '_check_file'):
         return
     # keyring file doesn't exist yet
     self.assertTrue(self.keyring._check_file() == False)
     # generate keyring
     self.keyring.set_password('system', 'user', 'password')
     # valid keyring file exist now
     self.assertTrue(self.keyring._check_file() == True)
     # lock keyring
     self.keyring._lock()
     # fetch password from keyring
     self.assertTrue(self.keyring.get_password('system', 'user') == 'password')
     # test missing password reference
     config = self.get_config()
     krsetting = escape_for_ini('keyring-setting')
     pwref = escape_for_ini('password reference')
     #pwrefval = config.get(krsetting, pwref)
     config.remove_option(krsetting, pwref)
     self.save_config(config)
     self.assertTrue(self.keyring._check_file() == False)
Пример #27
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # encrypt the password
        password_encrypted = self.encrypt(password)
        # load the password from the disk
        config = ConfigParser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path)

        # encode with base64
        password_base64 = password_encrypted.encode("base64")
        # write the modification
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, username, password_base64)
        config_file = open(self.file_path, 'w')
        config.write(config_file)
Пример #28
0
    def get_password(self, service, username):
        """Read the password from the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # load the passwords from the file
        config = ConfigParser.RawConfigParser()
        if os.path.exists(self.file_path):
            config.read(self.file_path)

        # fetch the password
        try:
            password_base64 = config.get(service, username)
            # decode with base64
            password_encrypted = password_base64.decode("base64")
            # decrypted the password
            password = self.decrypt(password_encrypted)
        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
            password = None
        return password
Пример #29
0
    def test_scheme(self):
        # scheme exists
        self.assertTrue(self.keyring.scheme is not None)
        if not hasattr(self.keyring, '_check_file'):
            return

        # keyring file doesn't exist yet
        self.assertTrue(self.keyring._check_file() == False)
        # generate keyring
        self.keyring.set_password('system', 'user', 'password')
        config = self.get_config()
        krsetting = escape_for_ini('keyring-setting')
        scheme = escape_for_ini('scheme')
        defscheme = '[PBKDF2] AES256.CFB'

        # default scheme match
        self.assertTrue(config.get(krsetting, scheme) == defscheme)

        # invalid AES mode
        config.set(krsetting, scheme, defscheme.replace('CFB', 'XXX'))
        with pytest.raises(ValueError):
            self.keyring._check_scheme(config)

         # compatibility with former scheme format
        config.set(krsetting, scheme, 'PyCrypto ' + defscheme)
        self.assertTrue(self.keyring._check_scheme(config) == None)

        # test with invalid KDF
        config.set(krsetting, scheme, defscheme.replace('PBKDF2', 'scrypt'))
        with pytest.raises(ValueError):
            self.keyring._check_scheme(config)

        # a missing scheme is valid
        config.remove_option(krsetting, scheme)
        self.save_config(config)
        self.assertTrue(self.keyring._check_file() == True)

        with pytest.raises(AttributeError):
            self.keyring._check_scheme(config)
Пример #30
0
    def _check_scheme(self, config):
        """
        check for a valid scheme

        raise ValueError otherwise
        raise AttributeError if missing
        """
        try:
            scheme = config.get(
                escape_for_ini('keyring-setting'),
                escape_for_ini('scheme'),
            )
        except (configparser.NoSectionError, configparser.NoOptionError):
            raise AttributeError("Encryption scheme missing")

        # remove pointless crypto module name
        if scheme.startswith('PyCrypto '):
            scheme = scheme[9:]

        if scheme != self.scheme:
            raise ValueError("Encryption scheme mismatch "
                             "(exp.: %s, found: %s)" % (self.scheme, scheme))
Пример #31
0
    def _check_scheme(self, config):
        """
        check for a valid scheme

        raise ValueError otherwise
        raise AttributeError if missing
        """
        try:
            scheme = config.get(
                escape_for_ini('keyring-setting'),
                escape_for_ini('scheme'),
            )
        except (configparser.NoSectionError, configparser.NoOptionError):
            raise AttributeError("Encryption scheme missing")

        # remove pointless crypto module name
        if scheme.startswith('PyCrypto '):
            scheme = scheme[9:]

        if scheme != self.scheme:
            raise ValueError("Encryption scheme mismatch "
                             "(exp.: %s, found: %s)" % (self.scheme, scheme))
Пример #32
0
 def _check_file(self):
     """
     Check if the file exists and has the expected password reference.
     """
     if not os.path.exists(self.file_path):
         return False
     self._migrate()
     config = configparser.RawConfigParser()
     config.read(self.file_path)
     try:
         config.get(
             escape_for_ini('keyring-setting'),
             escape_for_ini('password reference'),
         )
     except (configparser.NoSectionError, configparser.NoOptionError):
         return False
     try:
         self._check_scheme(config)
     except AttributeError:
         # accept a missing scheme
         return True
     return self._check_version(config)
Пример #33
0
 def test_file(self):
     if not hasattr(self.keyring, '_check_file'):
         return
     # keyring file doesn't exist yet
     self.assertTrue(self.keyring._check_file() == False)
     # generate keyring
     self.keyring.set_password('system', 'user', 'password')
     # valid keyring file exist now
     self.assertTrue(self.keyring._check_file() == True)
     # lock keyring
     self.keyring._lock()
     # fetch password from keyring
     self.assertTrue(
         self.keyring.get_password('system', 'user') == 'password')
     # test missing password reference
     config = self.get_config()
     krsetting = escape_for_ini('keyring-setting')
     pwref = escape_for_ini('password reference')
     #pwrefval = config.get(krsetting, pwref)
     config.remove_option(krsetting, pwref)
     self.save_config(config)
     self.assertTrue(self.keyring._check_file() == False)
Пример #34
0
    def test_scheme(self):
        # scheme exists
        self.assertTrue(self.keyring.scheme is not None)
        if not hasattr(self.keyring, '_check_file'):
            return

        # keyring file doesn't exist yet
        self.assertTrue(self.keyring._check_file() == False)
        # generate keyring
        self.keyring.set_password('system', 'user', 'password')
        config = self.get_config()
        krsetting = escape_for_ini('keyring-setting')
        scheme = escape_for_ini('scheme')
        defscheme = '[PBKDF2] AES256.CFB'

        # default scheme match
        self.assertTrue(config.get(krsetting, scheme) == defscheme)

        # invalid AES mode
        config.set(krsetting, scheme, defscheme.replace('CFB', 'XXX'))
        with pytest.raises(ValueError):
            self.keyring._check_scheme(config)

        # compatibility with former scheme format
        config.set(krsetting, scheme, 'PyCrypto ' + defscheme)
        self.assertTrue(self.keyring._check_scheme(config) == None)

        # test with invalid KDF
        config.set(krsetting, scheme, defscheme.replace('PBKDF2', 'scrypt'))
        with pytest.raises(ValueError):
            self.keyring._check_scheme(config)

        # a missing scheme is valid
        config.remove_option(krsetting, scheme)
        self.save_config(config)
        self.assertTrue(self.keyring._check_file() == True)

        with pytest.raises(AttributeError):
            self.keyring._check_scheme(config)
Пример #35
0
    def set_password(self, service, username, password):
        """Write the password in the file.
        """
        service = escape_for_ini(service)
        username = escape_for_ini(username)

        # ensure the file exists
        self._ensure_file_path()

        # load the keyring from the disk
        config = configparser.RawConfigParser()
        config.read(self.file_path)

        # update the keyring with the password
        if not config.has_section(service):
            config.add_section(service)
        config.set(service, username, password)

        # save the keyring back to the file
        config_file = codecs.open(self.file_path, 'w', 'utf-8')
        try:
            config.write(config_file)
        finally:
            config_file.close()
Пример #36
0
 def _generate_assoc(self, service, username):
     """Generate tamper resistant bytestring of associated data
     """
     return (escape_for_ini(service) + '\0' +
             escape_for_ini(username)).encode()