auth shit and vaultpass XSD modifications
This commit is contained in:
parent
d551aeab24
commit
f4253736ba
@ -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/>
|
||||
|
@ -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
130
vaultpass/auth.py
Normal 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)
|
@ -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):
|
||||
|
@ -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.')
|
||||
|
Reference in New Issue
Block a user