Skip to content

Commit

Permalink
[auth/netapi/salt-api] trust X-Remote-User in salt-api
Browse files Browse the repository at this point in the history
Add a way to get an unauthenticated token when we've set
the salt-api to trust a frontal to be doing the authentication
(related to saltstack#24793)
  • Loading branch information
arthurzenika committed Jun 25, 2015
1 parent d71d75e commit 5f16cab
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 7 deletions.
29 changes: 23 additions & 6 deletions salt/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,24 @@ def get_groups(self, load):
except Exception:
return None

def mk_token(self, load):
def mk_unauth_token(self, load):
'''
Get an unauthenticated token (for example when authentication is
taken care of by a frontal sur as nginx or apache that proxies
to salt-api). Use with caution.
'''
# TODO check config allows this
return self.mk_token(load, auth=False)


def mk_token(self, load, auth=True):
'''
Run time_auth and create a token. Return False or the token
'''
ret = self.time_auth(load)
if ret is False:
return {}
if auth: # and config.get (allow token with no auth, or pick from rest_cherrypy:trust_remote_user = True
ret = self.time_auth(load)
if ret is False:
return {}
fstr = '{0}.auth'.format(load['eauth'])
hash_type = getattr(hashlib, self.opts.get('hash_type', 'md5'))
tok = str(hash_type(os.urandom(512)).hexdigest())
Expand Down Expand Up @@ -407,11 +418,17 @@ def token_cli(self, eauth, load):
os.umask(oldmask)
return tdata

def mk_token(self, load):
def mk_unauth_token(self, load):
return self.mk_token(load, auth=False)

def mk_token(self, load, auth=True):
'''
Request a token from the master
'''
load['cmd'] = 'mk_token'
if auth: # TODO more checks
load['cmd'] = 'mk_token'
else:
load['cmd'] = 'mk_unauth_token'
tdata = self._send_token_request(load)
return tdata

Expand Down
28 changes: 28 additions & 0 deletions salt/auth/kerberos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
'''
Provide authentication using Kerberos by trusting webapp.
This is a placeholder auth module that does not authenticate with kerberos
.. versionadded:: TODO
'''

from __future__ import absolute_import
import logging

log = logging.getLogger(__name__)


def auth(username, **kwargs):
'''
Refuse authentication always. This gives the opportunity to use
the Remote User mecanism in salt-api
This prevents a local user from bypassing authorisation
TOOD : link to documentation about how to enable X-Remote-User in salt-api
'''
log.debug('returning False for kerberos trusted auth')
return False

3 changes: 3 additions & 0 deletions salt/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -2096,6 +2096,9 @@ def wheel(self, clear_load):
args=exc.args,
message=str(exc)))

def mk_unauth_token(self, clear_load):
return self.loadauth.mk_unauth_token(clear_load)

def mk_token(self, clear_load):
'''
Create and return an authentication token, the clear load needs to
Expand Down
20 changes: 19 additions & 1 deletion salt/netapi/rest_cherrypy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@
root_prefix : ``/``
A URL path to the main entry point for the application. This is useful
for serving multiple applications from the same URL.
authorized_ips
A list of IPs to restrict the authorized IPs that can connect to your
salt-api
trust_remote_user: ``False``
Puts the salt-api in "trust" mode, where it will trust the remote header
set by the frontal which handles the authentication. This is a common
pattern in web applications, see
`django documentation <https://docs.djangoproject.com/en/1.8/howto/auth-remote-user/>`_
about this. USE WITH CAUTION. This requires to make sure the frontal
is doing the authentication and that you are only listenning to localhost
and that no users ca request salt-api directly (for example from the
server it is running on). Also set authorized_ips to 127.0.0.1.
.. _rest_cherrypy-auth:
Expand Down Expand Up @@ -1415,7 +1427,13 @@ def POST(self, **kwargs):
else:
creds = cherrypy.serving.request.lowstate

token = self.auth.mk_token(creds)
auth=True
logger.debug('HEADER {0}'.format(cherrypy.serving.request.headers))
if cherrypy.config.get('saltopts', {}).get('rest_cherrypy', {}).get('trust_remote_user', False):
if cherrypy.serving.request.headers.get('X-Remote-User', '') == creds['username']:
logger.debug('X-Remote-User is {0}, trusting frontal'.format(creds['username']))
auth = False
token = self.auth.mk_token(creds, auth=auth)
if 'token' not in token:
raise cherrypy.HTTPError(401,
'Could not authenticate using provided credentials')
Expand Down

0 comments on commit 5f16cab

Please sign in to comment.