-#!/usr/bin/python
-#
# Copyright (C) 2014 Simo Sorce <simo@redhat.com>
#
# see file 'COPYING' for use and warranty information
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from ipsilon.login.common import LoginPageBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
+from ipsilon.login.common import LoginPageBase, LoginManagerBase, \
+ LoginManagerInstaller
from ipsilon.util.plugin import PluginObject
+from ipsilon.util.user import UserSession
from string import Template
import cherrypy
import os
class KrbAuth(LoginPageBase):
def root(self, *args, **kwargs):
+ trans = self.get_valid_transaction('login', **kwargs)
# If we can get here, we must be authenticated and remote_user
# was set. Check the session has a user set already or error.
- if self.user and self.user.name:
- userdata = {'krb_principal_name': self.user.name}
- return self.lm.auth_successful(self.user.name, userdata)
+ us = UserSession()
+ us.remote_login()
+ self.user = us.get_user()
+ if not self.user.is_anonymous:
+ principal = cherrypy.request.wsgi_environ.get('GSS_NAME', None)
+ if principal:
+ userdata = {'krb_principal_name': principal}
+ else:
+ userdata = {'krb_principal_name': self.user.name}
+ return self.lm.auth_successful(trans, self.user.name,
+ 'krb', userdata)
else:
- return self.lm.auth_failed()
+ return self.lm.auth_failed(trans)
class KrbError(LoginPageBase):
def root(self, *args, **kwargs):
cherrypy.log.error('REQUEST: %s' % cherrypy.request.headers)
- # If we have no negotiate header return whatever mod_auth_kerb
+ # If we have no negotiate header return whatever mod_auth_gssapi
# generated and wait for the next request
- if not 'WWW-Authenticate' in cherrypy.request.headers:
+ if 'WWW-Authenticate' not in cherrypy.request.headers:
cherrypy.response.status = 401
- if self.lm.next_login:
- return self.lm.next_login.page.root(*args, **kwargs)
+ next_login = self.lm.next_login()
+ if next_login:
+ return next_login.page.root(*args, **kwargs)
conturl = '%s/login' % self.basepath
return self._template('login/krb.html',
cont=conturl)
# If we get here, negotiate failed
- return self.lm.auth_failed()
+ trans = self.get_valid_transaction('login', **kwargs)
+ return self.lm.auth_failed(trans)
class LoginManager(LoginManagerBase):
self.path = 'krb/negotiate'
self.page = None
self.description = """
-Kereros Negotiate authentication plugin. Relies on the mod_auth_kerb apache
-plugin for actual authentication. """
+Kerberos Negotiate authentication plugin. Relies on the mod_auth_gssapi
+apache plugin for actual authentication. """
+ self.new_config(self.name)
def get_tree(self, site):
self.page = Krb(site, self)
self.page.__dict__['negotiate'] = KrbAuth(site, self)
self.page.__dict__['unauthorized'] = KrbError(site, self)
+ self.page.__dict__['failed'] = KrbError(site, self)
return self.page
CONF_TEMPLATE = """
-<Location /idp/login/krb/negotiate>
- AuthType Kerberos
- AuthName "Kerberos Login"
- KrbMethodNegotiate on
- KrbMethodK5Passwd off
- KrbServiceName HTTP
- $realms
+<Location /${instance}/login/krb/negotiate>
+ AuthType GSSAPI
+ AuthName "GSSAPI Single Sign On Login"
$keytab
- KrbSaveCredentials off
- KrbConstrainedDelegation off
- # KrbLocalUserMapping On
+ GssapiSSLonly $gssapisslonly
+ GssapiLocalName on
Require valid-user
- ErrorDocument 401 /idp/login/krb/unauthorized
+ ErrorDocument 401 /${instance}/login/krb/unauthorized
+ ErrorDocument 500 /${instance}/login/krb/failed
</Location>
"""
-class Installer(object):
+class Installer(LoginManagerInstaller):
- def __init__(self):
+ def __init__(self, *pargs):
+ super(Installer, self).__init__()
self.name = 'krb'
- self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--krb', choices=['yes', 'no'], default='no',
help='Configure Kerberos authentication')
- group.add_argument('--krb-realms',
- help='Allowed Kerberos Auth Realms')
group.add_argument('--krb-httpd-keytab',
default='/etc/httpd/conf/http.keytab',
help='Kerberos keytab location for HTTPD')
if opts['krb'] != 'yes':
return
- keytab = ' # Krb5KeyTab - No Keytab provided'
- if opts['krb_httpd_keytab'] is None:
- if os.path.exists('/etc/httpd/conf/http.keytab'):
- keytab = ' Krb5KeyTab /etc/httpd/conf/http.keytab'
+ confopts = {'instance': opts['instance']}
+
+ if os.path.exists(opts['krb_httpd_keytab']):
+ confopts['keytab'] = 'GssapiCredStore keytab:%s' % (
+ opts['krb_httpd_keytab'])
else:
- if os.path.exists(opts['krb_httpd_keytab']):
- keytab = ' Krb5KeyTab %s' % opts['krb_httpd_keytab']
- else:
- raise Exception('Keytab not found')
+ raise Exception('Keytab not found')
- if opts['krb_realms'] is None:
- realms = ' # KrbAuthRealms - Any trusted realm is allowed'
+ if opts['secure'] == 'no':
+ confopts['gssapisslonly'] = 'Off'
else:
- realms = ' KrbAuthRealms %s' % opts['krb_realms']
+ confopts['gssapisslonly'] = 'On'
tmpl = Template(CONF_TEMPLATE)
- hunk = tmpl.substitute(keytab=keytab, realms=realms)
+ hunk = tmpl.substitute(**confopts) # pylint: disable=star-args
with open(opts['httpd_conf'], 'a') as httpd_conf:
httpd_conf.write(hunk)
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'krb'
po.wipe_data()
# Update global config, put 'krb' always first
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.insert(0, 'krb')
- globalconf['order'] = ','.join(order)
- po.set_config(globalconf)
- po.save_plugin_config(FACILITY)
+ ph = self.pargs[0]
+ ph.refresh_enabled()
+ if 'krb' not in ph.enabled:
+ enabled = []
+ enabled.extend(ph.enabled)
+ enabled.insert(0, 'krb')
+ ph.save_enabled(enabled)