auth shit and vaultpass XSD modifications

This commit is contained in:
brent s. 2020-03-27 14:43:43 -04:00
parent d551aeab24
commit f4253736ba
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
5 changed files with 180 additions and 7 deletions

View File

@ -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=">
<uri>https://localhost:8000/</uri>
<auth>
<token/>

View File

@ -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)

130
vaultpass/auth.py Normal file
View File

@ -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)

View File

@ -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):

View File

@ -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.')