diff --git a/docs/README.adoc b/docs/README.adoc index 97cc3f1..a69231a 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -48,7 +48,7 @@ for how default values/behaviour are determined.] This element is a container fo Vault server. This consists of: ... A single `uri` element.footnote:optelem[] It should be the same as the **base** URL for your Vault server. The default (if not specified) is to first check for a **`VAULT_SERVER`** environment variable and, if not found, to use -`http://localhost:8000/`. +`http://localhost:8200/`. ... An unseal directive, which can be used to (attempt to) automatically unseal the server if it is sealed. This isn't required, but can assist in automatic operation. One of either:footnote:optelem[] @@ -72,7 +72,7 @@ Let's look at an example configuration. xsi:schemaLocation="https://git.square-r00t.net/VaultPass/ http://schema.xml.r00t2.io/projects/vaultpass.xsd"> - http://localhost:8000/ + http://localhost:8200/ YOUR_UNSEAL_SHARD @@ -82,7 +82,7 @@ Let's look at an example configuration. ---- -In the above, we can see that it would use the vault server at `http://localhost:8000/` using whatever token is either +In the above, we can see that it would use the vault server at `http://localhost:8200/` using whatever token is either in the **`VAULT_TOKEN`** environment variable or, if empty, the `~/.vault-token` file. Because an unseal shard was provided, it will be able to attempt to automatically unseal the Vault (assuming its shard will complete the threshold needed). @@ -266,7 +266,7 @@ Let's look at an example of GPG-encrypted elements. xsi:schemaLocation="https://git.square-r00t.net/VaultPass/ http://schema.xml.r00t2.io/projects/vaultpass.xsd"> - http://localhost:8000/ + http://localhost:8200/ ~/.private/vaultpass/unseal.asc ~/.private/vaultpass/auth.gpg diff --git a/example.vaultpass.xml b/example.vaultpass.xml index 6158c5d..19a71ab 100644 --- a/example.vaultpass.xml +++ b/example.vaultpass.xml @@ -3,8 +3,8 @@ xmlns="https://git.square-r00t.net/VaultPass/" xsi:schemaLocation="https://git.square-r00t.net/VaultPass/ http://schema.xml.r00t2.io/projects/vaultpass.xsd"> - - http://localhost:8000/ + + http://localhost:8200/ WU9VUiBVTlNFQUwgU0hBUkQgSEVSRQo= diff --git a/vaultpass/__init__.py b/vaultpass/__init__.py index ee1ae1c..8f50b4c 100644 --- a/vaultpass/__init__.py +++ b/vaultpass/__init__.py @@ -1,12 +1,12 @@ import logging +import os ## +from . import logger +_logger = logging.getLogger('VaultPass') from . import auth from . import clipboard from . import config -from . import logger - - -_logger = logging.getLogger('VaultPass') +from . import mounts class PassMan(object): @@ -18,19 +18,50 @@ class PassMan(object): self.cfg = config.getConfig(cfg) self._getURI() self.getClient() + self._checkSeal() + + def _checkSeal(self): + _logger.debug('Checking and attempting unseal if necessary and possible.') + if not self.client.sys.is_sealed(): + _logger.debug('Unsealing unnecessary; Vault is already unsealed.') + return(None) + shard = self.cfg.xml.find('unseal') + if shard is None: + _logger.debug('Vault is sealed but no key shard was provided.') + _logger.error('Vault is sealed') + raise RuntimeError('Vault is sealed') + self.client.sys.submit_unseal_key(shard.text) + if self.client.sys.is_sealed: + _logger.debug(('Vault is sealed and either our unseal shard is incorrect or it is not enough to meet the ' + 'unseal shard threshold.')) + _logger.error('Unable to unseal') + raise RuntimeError('Unable to unseal') + return(None) def _getURI(self): - uri = self.cfg.xml.find('uri') + uri = self.cfg.xml.find('.//uri') if uri is None: - uri = 'http://localhost:8000/' - pass + _logger.debug('No server URI specified; checking ${VAULT_ADDR}') + _uri = os.environ.get('VAULT_ADDR') + if not _uri: + _logger.debug('No ${VAULT_ADDR}; using default of http://localhost:8200/') + uri = 'http://localhost:8200/' + else: + uri = _uri + else: + uri = uri.text + self.uri = uri + _logger.debug('Set URI to {0}'.format(self.uri)) + return(None) def getClient(self): - # This may need to be re-tooled in the future. - auth_xml = self.cfg.xml.find('auth') + auth_xml = self.cfg.xml.find('.//auth') if auth_xml is None: + _logger.debug('No auth section was found in the configuration file.') + _logger.error('Could not find authentication') raise RuntimeError('Could not find authentication') authmethod_xml = auth_xml.getchildren()[0] + _logger.debug('Attempting to auto-detect the authentication method...') for a in dir(auth): if a.startswith('_'): continue @@ -42,10 +73,15 @@ class PassMan(object): continue self.auth = c(self.uri, authmethod_xml) + _logger.debug('Found auth method: {0}'.format(self.auth.name)) break if not self.auth: - _logger.error('Invalid auth configuration') _logger.debug('Auth specified ({0}) was not found or is not supported'.format(authmethod_xml.tag)) + _logger.error('Invalid auth configuration') raise RuntimeError('Invalid auth configuration') self.client = self.auth.client + if not self.client.sys.is_initialized(): + _logger.debug('Vault instance is not initialized. Please initialize (and configure, if necessary) first.') + _logger.error('Not initialized') + raise RuntimeError('Not initialized') return(None) diff --git a/vaultpass/mounts.py b/vaultpass/mounts.py new file mode 100644 index 0000000..c36e3f0 --- /dev/null +++ b/vaultpass/mounts.py @@ -0,0 +1,13 @@ +class MountHandler(object): + def __init__(self, client, mounts_xml = None): + self.client = client + self.mounts = {} + + def getSysMounts(self): + pass + + def print(self): + pass + + def search(self): + pass