diff --git a/example.vaultpass.xml b/example.vaultpass.xml index 19a71ab..9935265 100644 --- a/example.vaultpass.xml +++ b/example.vaultpass.xml @@ -10,4 +10,12 @@ WU9VUiBVTlNFQUwgU0hBUkQgSEVSRQo= ~/.vaultcreds.xml.gpg + + + + secrets_legacy + secrets + cubbyhole + diff --git a/vaultpass/__init__.py b/vaultpass/__init__.py index 8f50b4c..7625c39 100644 --- a/vaultpass/__init__.py +++ b/vaultpass/__init__.py @@ -13,12 +13,14 @@ class PassMan(object): client = None auth = None uri = None + mount = None def __init__(self, cfg = '~/.config/vaultpass.xml'): self.cfg = config.getConfig(cfg) self._getURI() self.getClient() self._checkSeal() + self._getMount() def _checkSeal(self): _logger.debug('Checking and attempting unseal if necessary and possible.') @@ -38,6 +40,10 @@ class PassMan(object): raise RuntimeError('Unable to unseal') return(None) + def _getMount(self): + # TODO: mounts xml? + self.mount = mounts.MountHandler(self.client) + def _getURI(self): uri = self.cfg.xml.find('.//uri') if uri is None: diff --git a/vaultpass/auth.py b/vaultpass/auth.py index 8c63001..076e89c 100644 --- a/vaultpass/auth.py +++ b/vaultpass/auth.py @@ -21,6 +21,7 @@ class _AuthBase(object): _logger.debug('Could not authenticate to {0} using {1}.'.format(self.uri, self.name)) _logger.error('Could not authenticate') raise RuntimeError('Could not authenticate') + return(None) def getClient(self): pass # Dummy/placeholder func. @@ -40,14 +41,18 @@ class _BasicAuthBase(_AuthBase): self.setCreds() def setCreds(self): - self.username = self.xml.find('username').text - self.password = self.xml.find('password').text - _mntpt = self.xml.find('mountPoint') + self.username = self.xml.find('.//username').text + _logger.debug('Set username: {0}'.format(self.username)) + self.password = self.xml.find('.//password').text + _logger.debug('Set password: {0}'.format(self.password)) + _mntpt = self.xml.find('.//mountPoint') if _mntpt is not None: self.mount = _mntpt.text else: self.mount = self.default_mountpoint + _logger.debug('Set mountpoint: {0}'.format(self.mount)) self.client = hvac.Client(url = self.uri) + _logger.info('Initialized client.') return(None) @@ -62,10 +67,14 @@ class AppRole(_AuthBase): self.getClient() def getClient(self): - self.role = self.xml.find('role').text - self.secret = self.xml.find('secret').text + self.role = self.xml.find('.//role').text + _logger.debug('Set role: {0}'.format(self.role)) + self.secret = self.xml.find('.//secret').text + _logger.debug('Set secret: {0}'.format(self.secret)) self.client = hvac.Client(url = self.uri) + _logger.info('Initialized client.') self.client.auth_approle(self.role, secret_id = self.secret) + _logger.debug('Attempted to authenticate client.') self.authCheck() return(None) @@ -82,6 +91,7 @@ class LDAP(_BasicAuthBase): self.client.auth.ldap.login(username = self.username, password = self.password, mount_point = self.mount) + _logger.debug('Attempted to authenticate client.') self.authCheck() return(None) @@ -141,8 +151,11 @@ class Token(_AuthBase): self.token = self._getEnv(e) else: self.token = self._getFile(a) + _logger.debug('Set token: {0}'.format(self.token)) self.client = hvac.Client(url = self.uri) + _logger.info('Initialized client.') self.client.token = self.token + _logger.debug('Applied token.') self.authCheck() return(None) @@ -156,8 +169,14 @@ class UserPass(_BasicAuthBase): self.getClient() def getClient(self): - self.client.auth.userpass.login(username = self.username, - password = self.password, - mount_point = self.mount) + resp = self.client.auth.userpass.login(username = self.username, + password = self.password, + mount_point = self.mount) + _logger.debug('Attempted to authenticate client.') + try: + self.client.token = resp['auth']['client_token'] + except KeyError: + # Auth failed. We'll let authCheck() handle the error. + pass self.authCheck() return(None) diff --git a/vaultpass/mounts.py b/vaultpass/mounts.py index c36e3f0..d7ba8e0 100644 --- a/vaultpass/mounts.py +++ b/vaultpass/mounts.py @@ -1,10 +1,37 @@ +import logging +import re +import warnings +## +import hvac.exceptions + + +_logger = logging.getLogger() +_mount_re = re.compile(r'^(?P.*)/') + + class MountHandler(object): + internal_mounts = ('identity', 'sys') + def __init__(self, client, mounts_xml = None): self.client = client - self.mounts = {} + self.xml = mounts_xml + self.mounts = [] def getSysMounts(self): - pass + try: + for mount, mount_info in self.client.sys.list_mounted_secrets_engines()['data'].items(): + r = _mount_re.search(mount) + if r: + mount = r.group('mount') + if mount in self.internal_mounts: + continue + self.mounts.append(mount) + _logger.debug('Added mountpoint to mounts list: {0}'.format(mount)) + except hvac.exceptions.Forbidden: + _logger.warning('Client does not have permission to read /sys/mounts.') + # TODO: xml parsing + + return(None) def print(self): pass