diff --git a/example.vaultpass.xml b/example.vaultpass.xml
index cd7c524..bf302fc 100644
--- a/example.vaultpass.xml
+++ b/example.vaultpass.xml
@@ -3,7 +3,7 @@
xmlns="https://git.square-r00t.net/VaultPass/"
xsi:schemaLocation="https://git.square-r00t.net/VaultPass/ http://schema.xml.r00t2.io/projects/vaultpass.xsd"
autoUnseal="true"
- unsealShard="YOUR_UNSEAL_HERE">
+ unsealShard="WU9VUiBVTlNFQUwgU0hBUkQgSEVSRQo=">
https://localhost:8000/
diff --git a/vaultpass/__init__.py b/vaultpass/__init__.py
index e0ab1a9..6ecba3b 100644
--- a/vaultpass/__init__.py
+++ b/vaultpass/__init__.py
@@ -1,11 +1,50 @@
-import warnings
-##
-import hvac
+import logging
##
+from . import auth
from . import clipboard
from . import config
+from . import logger
+
+
+_logger = logging.getLogger('VaultPass')
class PassMan(object):
- def __init__(self):
+ client = None
+ auth = None
+ uri = None
+
+ def __init__(self, cfg = '~/.config/vaultpass.xml'):
+ self.cfg = config.getConfig(cfg)
+ self.cfg.main()
+ self._getURI()
+ self.getClient()
+
+ def _getURI(self):
+ uri = self.cfg.xml.find('uri')
+ if uri is None:
+ uri = 'http://localhost:8000/'
pass
+
+ def getClient(self):
+ # This may need to be re-tooled in the future.
+ auth_xml = self.cfg.xml.find('auth')
+ authmethod_xml = auth_xml.getchildren()[0]\
+ for a in dir(auth):
+ if a.startswith('_'):
+ continue
+ c = getattr(auth, a)
+ if not c:
+ continue
+ confname = getattr(c, 'config_name')
+ if not confname or confname != authmethod_xml.tag:
+ continue
+ self.auth = c(self.uri,
+ authmethod_xml)
+ 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))
+ raise RuntimeError('Invalid auth configuration')
+ self.client = self.auth.client
+ return(None)
diff --git a/vaultpass/auth.py b/vaultpass/auth.py
new file mode 100644
index 0000000..d522985
--- /dev/null
+++ b/vaultpass/auth.py
@@ -0,0 +1,130 @@
+import logging
+import os
+##
+import hvac
+
+
+_logger = logging.getLogger()
+
+
+class _AuthBase(object):
+ name = '_AuthBase'
+ client = None
+
+ def __init__(self, uri, auth_xml, *args, **kwargs):
+ self.uri = uri
+ self.xml = auth_xml
+ _logger.debug('Intialized instance of {0}'.format(self.name))
+
+ def authCheck(self):
+ if not self.client.is_authenticated():
+ _logger.debug('Could not authenticate to {0} using {1}.'.format(self.uri, self.name))
+ _logger.error('Could not authenticate')
+ raise RuntimeError('Could not authenticate')
+
+ def getClient(self):
+ pass # Dummy/placeholder func.
+ return(None)
+
+
+class AppRole(_AuthBase):
+ name = 'AppRole'
+ config_name = 'appRole'
+ role = None
+ secret = None
+
+ def __init__(self, uri, auth_xml, *args, **kwargs):
+ super().__init__(uri, auth_xml, *args, **kwargs)
+ self.getClient()
+
+ def getClient(self):
+ self.role = self.xml.find('role').text
+ self.secret = self.xml.find('secret').text
+ self.client = hvac.Client(url = self.uri)
+ self.client.auth_approle(self.role, secret_id = self.secret)
+ self.authCheck()
+ return(None)
+
+
+class LDAP(_AuthBase):
+ name = 'LDAP'
+ config_name = 'ldap'
+ username = None
+ password = None
+ mount = None
+
+ def __init__(self, uri, auth_xml, *args, **kwargs):
+ super().__init__(uri, auth_xml, *args, **kwargs)
+ self.getClient()
+
+ def getClient(self):
+ self.username = self.xml.find('username').text
+ self.password = self.xml.find('password').text
+ _mntpt = self.xml.find('mountPoint')
+ if _mntpt is not None:
+ self.mount = _mntpt.text
+ else:
+ self.mount = 'ldap'
+ self.client = hvac.Client(url = self.uri)
+ self.client.auth.ldap.login(username = self.username,
+ password = self.password,
+ mount_point = self.mount)
+ self.authCheck()
+ return(None)
+
+
+class Token(_AuthBase):
+ name = 'Token'
+ config_name = 'token'
+ token = None
+
+ def __init__(self, uri, auth_xml, *args, **kwargs):
+ super().__init__(uri, auth_xml, *args, **kwargs)
+ self.getClient()
+
+ def _getEnv(self, env_var):
+ var = os.environ.get(env_var)
+ if not var:
+ _logger.debug(('Environment variable {0} was specified as containing the token '
+ 'but it is empty').format(env_var))
+ _logger.error('Env var not populated')
+ raise RuntimeError('Env var not populated')
+ return(var)
+
+ def _getFile(self, fpath):
+ fpath = os.path.abspath(os.path.expanduser(fpath))
+ with open(fpath, 'r') as fh:
+ contents = fh.read().strip()
+ return(contents)
+
+ def getClient(self):
+ _token = self.xml.text
+ if _token is not None:
+ self.token = _token
+ else:
+ # First we check the attrib.
+ a = self.xml.attrib.get('source')
+ if not a:
+ _exhausted = False
+ # try, in order, env var and then ~/.vault-token
+ while not _exhausted:
+ try:
+ self._getEnv('VAULT_TOKEN')
+ break
+ except Exception as e:
+ pass
+ try:
+ self._getFile('~/.vault-token')
+ except Exception as e:
+ _exhausted = True
+ if not self.token:
+ _logger.debug(('Unable to automatically determine token from '
+ 'environment variable or filesystem defaults'))
+ _logger.error('Cannot determine token')
+ raise RuntimeError('Cannot determine token')
+ else:
+ if a.startswith('env:'):
+ e = a.split(':', 1)
+ self.token = self._getEnv(e)
+ else:
+ self.token = self._getFile(a)
diff --git a/vaultpass/config.py b/vaultpass/config.py
index 80c7d7d..7b0efa1 100644
--- a/vaultpass/config.py
+++ b/vaultpass/config.py
@@ -8,7 +8,7 @@ from lxml import etree
# TODO: change filehandler of logger? https://stackoverflow.com/a/47447444
-_logger = logging.getLogger('config:{0}'.format(__name__))
+_logger = logging.getLogger()
class Config(object):
diff --git a/vaultpass/logger.py b/vaultpass/logger.py
index 580864b..1ee6523 100644
--- a/vaultpass/logger.py
+++ b/vaultpass/logger.py
@@ -17,6 +17,10 @@ def prepLogfile(path = logfile):
path = os.path.abspath(os.path.expanduser(path))
# Set up the permissions beforehand.
os.makedirs(os.path.dirname(logfile), exist_ok = True, mode = 0o0700)
+ if not os.path.isfile(path):
+ # "Touch" it so the next command doesn't fail.
+ with open(path, 'w') as fh:
+ fh.write('')
os.chmod(logfile, 0o0600)
return(path)
@@ -49,6 +53,6 @@ h.setFormatter(logging.Formatter(style = '{',
_cfg_args['handlers'].append(h)
logging.basicConfig(**_cfg_args)
-logger = logging.getLogger()
+logger = logging.getLogger('VaultPass')
logger.info('Logging initialized.')