# -*- coding: utf-8 -*-
"""The path specification key chain.
The key chain is used to manage credentials for path specifications. E.g.
BitLocker Drive Encryption (BDE) encrypted volumes can require a credential
(e.g. password) to access the unencrypted data (unlock).
"""
from dfvfs.credentials import manager
[docs]
class KeyChain(object):
"""Key chain."""
[docs]
def __init__(self):
"""Initializes a key chain."""
super(KeyChain, self).__init__()
self._credentials_per_path_spec = {}
[docs]
def Empty(self):
"""Empties the key chain."""
self._credentials_per_path_spec = {}
[docs]
def GetCredential(self, path_spec, identifier):
"""Retrieves a specific credential from the key chain.
Args:
path_spec (PathSpec): path specification.
identifier (str): credential identifier.
Returns:
object: credential or None if the credential for the path specification
is not set.
"""
credentials = self._credentials_per_path_spec.get(path_spec.comparable, {})
return credentials.get(identifier, None)
[docs]
def GetCredentials(self, path_spec):
"""Retrieves all credentials for the path specification.
Args:
path_spec (PathSpec): path specification.
Returns:
dict[str,object]: credentials for the path specification.
"""
return self._credentials_per_path_spec.get(path_spec.comparable, {})
[docs]
def SetCredential(self, path_spec, identifier, data):
"""Sets a specific credential for the path specification.
Args:
path_spec (PathSpec): path specification.
identifier (str): credential identifier.
data (object): credential data.
Raises:
KeyError: if the credential is not supported by the path specification
type.
"""
supported_credentials = manager.CredentialsManager.GetCredentials(path_spec)
if identifier not in supported_credentials.CREDENTIALS:
raise KeyError((
f'Unsuppored credential: {identifier:s} for path specification '
f'type: {path_spec.type_indicator:s}'))
credentials = self._credentials_per_path_spec.get(path_spec.comparable, {})
credentials[identifier] = data
self._credentials_per_path_spec[path_spec.comparable] = credentials