1 # Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
3 from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
5 from ipsilon.util.plugin import PluginObject
6 from ipsilon.util.user import UserSession
7 from ipsilon.util import config as pconfig
8 from string import Template
12 # Translate PAM errors into more human-digestible values and eventually
15 "Authentication token is no longer valid; new one required":
16 "Password is expired",
17 "Authentication failure":
18 "Authentication failure",
22 class Form(LoginFormBase):
24 def POST(self, *args, **kwargs):
28 if not user.is_anonymous:
29 return self.lm.auth_successful(self.trans, user.name, 'password')
31 error = cherrypy.request.wsgi_environ.get(
32 'EXTERNAL_AUTH_ERROR',
33 'Unknown error using external authentication'
35 error = PAM_AUTH_ERRORS.get(error, error)
36 cherrypy.log.error("Error: %s" % error)
37 return self.lm.auth_failed(self.trans, error)
40 class LoginManager(LoginManagerBase):
42 def __init__(self, *args, **kwargs):
43 super(LoginManager, self).__init__(*args, **kwargs)
47 self.service_name = 'form'
48 self.description = """
49 Form based login Manager. Relies on mod_intercept_form_submit plugin for
50 actual authentication. """
55 'Text used to ask for the username at login time.',
59 'Text used to ask for the password at login time.',
63 'Text used to guide the user at login time.',
64 'Insert your Username and Password and then submit.')
69 return self.get_config_value('help text')
72 def username_text(self):
73 return self.get_config_value('username text')
76 def password_text(self):
77 return self.get_config_value('password text')
79 def get_tree(self, site):
80 self.page = Form(site, self, 'login/form')
85 LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
86 LoadModule authnz_pam_module modules/mod_authnz_pam.so
88 <Location /${instance}/login/form>
89 InterceptFormPAMService ${service}
90 InterceptFormLogin login_name
91 InterceptFormPassword login_password
92 # InterceptFormLoginSkip admin
93 # InterceptFormClearRemoteUserForSkipped on
94 InterceptFormPasswordRedact on
99 class Installer(LoginManagerInstaller):
101 def __init__(self, *pargs):
102 super(Installer, self).__init__()
106 def install_args(self, group):
107 group.add_argument('--form', choices=['yes', 'no'], default='no',
108 help='Configure External Form authentication')
109 group.add_argument('--form-service', action='store', default='remote',
110 help='PAM service name to use for authentication')
112 def configure(self, opts, changes):
113 if opts['form'] != 'yes':
116 confopts = {'instance': opts['instance'],
117 'service': opts['form_service']}
119 tmpl = Template(CONF_TEMPLATE)
120 hunk = tmpl.substitute(**confopts)
121 with open(opts['httpd_conf'], 'a') as httpd_conf:
122 httpd_conf.write(hunk)
124 # Add configuration data to database
125 po = PluginObject(*self.pargs)
128 po.wipe_config_values()
130 # Update global config to add login plugin
132 po.save_enabled_state()
134 # for selinux enabled platforms, ignore if it fails just report
136 subprocess.call(['/usr/sbin/setsebool', '-P',
137 'httpd_mod_auth_pam=on'])
138 except Exception: # pylint: disable=broad-except