From 6a58d3ebb9fc536ba8c16a374787077f21b94c89 Mon Sep 17 00:00:00 2001 From: "wurblzap%gmail.com" <> Date: Fri, 3 Aug 2007 03:38:37 +0000 Subject: Bug 380187 – Bugzilla should support RADIUS authentication. Patch by Marc Schumann ; r=mkanat, a=mkanat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bugzilla/Auth/Verify/RADIUS.pm | 64 ++++++++++++++++ Bugzilla/Config/Auth.pm | 4 +- Bugzilla/Config/Common.pm | 34 ++++++--- Bugzilla/Config/RADIUS.pm | 60 +++++++++++++++ Bugzilla/Install/Requirements.pm | 6 ++ docs/xml/installation.xml | 87 ++++++++++++++++++++-- js/params.js | 61 +++++++++++++++ skins/standard/params.css | 6 ++ template/en/default/admin/params/auth.html.tmpl | 22 ++++-- template/en/default/admin/params/common.html.tmpl | 54 ++++++++++++++ .../en/default/admin/params/editparams.html.tmpl | 1 + template/en/default/admin/params/radius.html.tmpl | 55 ++++++++++++++ template/en/default/filterexceptions.pl | 4 + template/en/default/global/code-error.html.tmpl | 3 + 14 files changed, 437 insertions(+), 24 deletions(-) create mode 100755 Bugzilla/Auth/Verify/RADIUS.pm create mode 100755 Bugzilla/Config/RADIUS.pm create mode 100755 js/params.js create mode 100755 template/en/default/admin/params/radius.html.tmpl diff --git a/Bugzilla/Auth/Verify/RADIUS.pm b/Bugzilla/Auth/Verify/RADIUS.pm new file mode 100755 index 000000000..da36c3bd1 --- /dev/null +++ b/Bugzilla/Auth/Verify/RADIUS.pm @@ -0,0 +1,64 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Marc Schumann. +# Portions created by Marc Schumann are Copyright (c) 2007 Marc Schumann. +# All rights reserved. +# +# Contributor(s): Marc Schumann + +package Bugzilla::Auth::Verify::RADIUS; +use strict; +use base qw(Bugzilla::Auth::Verify); + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Util; + +use Authen::Radius; + +use constant admin_can_create_account => 0; +use constant user_can_create_account => 0; + +sub check_credentials { + my ($self, $params) = @_; + my $dbh = Bugzilla->dbh; + my $address_suffix = Bugzilla->params->{'RADIUS_email_suffix'}; + my $username = $params->{username}; + + # If we're using RADIUS_email_suffix, we may need to cut it off from + # the login name. + if ($address_suffix) { + $username =~ s/\Q$address_suffix\E$//i; + } + + # Create RADIUS object. + my $radius = + new Authen::Radius(Host => Bugzilla->params->{'RADIUS_server'}, + Secret => Bugzilla->params->{'RADIUS_secret'}) + || return { failure => AUTH_ERROR, error => 'radius_preparation_error', + details => {errstr => Authen::Radius::strerror() } }; + + # Check the password. + $radius->check_pwd($username, $params->{password}, + Bugzilla->params->{'RADIUS_NAS_IP'} || undef) + || return { failure => AUTH_LOGINFAILED }; + + # Build the user account's e-mail address. + $params->{bz_username} = $username . $address_suffix; + + return $params; +} + +1; diff --git a/Bugzilla/Config/Auth.pm b/Bugzilla/Config/Auth.pm index 65ebc1b79..cbd94617a 100644 --- a/Bugzilla/Config/Auth.pm +++ b/Bugzilla/Config/Auth.pm @@ -76,8 +76,8 @@ sub get_param_list { { name => 'user_verify_class', - type => 's', - choices => [ 'DB', 'LDAP', 'DB,LDAP', 'LDAP,DB' ], + type => 'o', + choices => [ 'DB', 'RADIUS', 'LDAP' ], default => 'DB', checker => \&check_user_verify_class }, diff --git a/Bugzilla/Config/Common.pm b/Bugzilla/Config/Common.pm index 188ef0c90..14406019d 100644 --- a/Bugzilla/Config/Common.pm +++ b/Bugzilla/Config/Common.pm @@ -27,6 +27,7 @@ # Joseph Heenan # Erik Stambaugh # Frédéric Buclin +# Marc Schumann # package Bugzilla::Config::Common; @@ -64,8 +65,8 @@ sub check_multi { return ""; } - elsif ($param->{'type'} eq "m") { - foreach my $chkParam (@$value) { + elsif ($param->{'type'} eq 'm' || $param->{'type'} eq 'o') { + foreach my $chkParam (split(',', $value)) { unless (scalar(grep {$_ eq $chkParam} (@{$param->{'choices'}}))) { return "Invalid choice '$chkParam' for multi-select list param '$param->{'name'}'"; } @@ -268,18 +269,27 @@ sub check_user_verify_class { # So don't do that. my ($list, $entry) = @_; + $list || return 'You need to specify at least one authentication mechanism'; for my $class (split /,\s*/, $list) { my $res = check_multi($class, $entry); return $res if $res; if ($class eq 'DB') { # No params - } elsif ($class eq 'LDAP') { + } + elsif ($class eq 'RADIUS') { + eval "require Authen::Radius"; + return "Error requiring Authen::Radius: '$@'" if $@; + return "RADIUS servername (RADIUS_server) is missing" unless Bugzilla->params->{"RADIUS_server"}; + return "RADIUS_secret is empty" unless Bugzilla->params->{"RADIUS_secret"}; + } + elsif ($class eq 'LDAP') { eval "require Net::LDAP"; return "Error requiring Net::LDAP: '$@'" if $@; - return "LDAP servername is missing" unless Bugzilla->params->{"LDAPserver"}; + return "LDAP servername (LDAPserver) is missing" unless Bugzilla->params->{"LDAPserver"}; return "LDAPBaseDN is empty" unless Bugzilla->params->{"LDAPBaseDN"}; - } else { - return "Unknown user_verify_class '$class' in check_user_verify_class"; + } + else { + return "Unknown user_verify_class '$class' in check_user_verify_class"; } } return ""; @@ -363,9 +373,8 @@ sub check_timezone { # b -- A boolean value (either 1 or 0) # m -- A list of values, with many selectable (shows up as a select box) # To specify the list of values, make the 'choices' key be an array -# reference of the valid choices. The 'default' key should be an array -# reference for the list of selected values (which must appear in the -# first anonymous array), i.e.: +# reference of the valid choices. The 'default' key should be a string +# with a list of selected values (as a comma-separated list), i.e.: # { # name => 'multiselect', # desc => 'A list of options, choose many', @@ -381,6 +390,11 @@ sub check_timezone { # &check_multi should always be used as the param verification function # for list (single and multiple) parameter types. # +# o -- A list of values, orderable, and with many selectable (shows up as a +# JavaScript-enhanced select box if JavaScript is enabled, and a text +# entry field if not) +# Set up in the same way as type m. +# # s -- A list of values, with one selectable (shows up as a select box) # To specify the list of values, make the 'choices' key be an array # reference of the valid choices. The 'default' key should be one of @@ -422,7 +436,7 @@ All parameter checking functions are called with two parameters: =item C -Checks that a multi-valued parameter (ie type C or type C) satisfies +Checks that a multi-valued parameter (ie types C, C or C) satisfies its contraints. =item C diff --git a/Bugzilla/Config/RADIUS.pm b/Bugzilla/Config/RADIUS.pm new file mode 100755 index 000000000..6701d6f08 --- /dev/null +++ b/Bugzilla/Config/RADIUS.pm @@ -0,0 +1,60 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Marc Schumann. +# Portions created by Marc Schumann are Copyright (c) 2007 Marc Schumann. +# All rights reserved. +# +# Contributor(s): Marc Schumann +# + +package Bugzilla::Config::RADIUS; + +use strict; + +use Bugzilla::Config::Common; + +$Bugzilla::Config::RADIUS::sortkey = "09"; + +sub get_param_list { + my $class = shift; + my @param_list = ( + { + name => 'RADIUS_server', + type => 't', + default => '' + }, + + { + name => 'RADIUS_secret', + type => 't', + default => '' + }, + + { + name => 'RADIUS_NAS_IP', + type => 't', + default => '' + }, + + { + name => 'RADIUS_email_suffix', + type => 't', + default => '' + }, + ); + return @param_list; +} + +1; diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm index 7cc51a5e6..321f90f8d 100644 --- a/Bugzilla/Install/Requirements.pm +++ b/Bugzilla/Install/Requirements.pm @@ -169,6 +169,12 @@ sub OPTIONAL_MODULES { version => 0, feature => 'LDAP Authentication' }, + { + package => 'RadiusPerl', + module => 'Authen::Radius', + version => 0, + feature => 'RADIUS Authentication' + }, { package => 'SOAP-Lite', module => 'SOAP::Lite', diff --git a/docs/xml/installation.xml b/docs/xml/installation.xml index 0f859bbf0..337c1b431 100644 --- a/docs/xml/installation.xml +++ b/docs/xml/installation.xml @@ -1,5 +1,5 @@ - + Installing Bugzilla @@ -418,6 +418,13 @@ + + + Authen::Radius + (&min-authen-radius-ver;) for RADIUS Authentication + + + SOAP::Lite @@ -1506,6 +1513,72 @@ c:\perl\bin\perl.exe -xc:\bugzilla -wT "%s" %s +
+ RADIUS Authentication + + RADIUS authentication is a module for Bugzilla's plugin + authentication architecture. + Most caveats that apply to LDAP authentication apply to RADIUS + authentication as well. + + + Parameters required to use RADIUS Authentication: + + + + user_verify_class + + If you want to list RADIUS here, + make sure to have set up the other parameters listed below. + Unless you have other (working) authentication methods listed as + well, you may otherwise not be able to log back in to Bugzilla once + you log out. + If this happens to you, you will need to manually edit + data/params and set user_verify_class to + DB. + + + + + + RADIUS_server + + This parameter should be set to the name (and optionally the + port) of your RADIUS server. + + + + + + RADIUS_secret + + This parameter should be set to the RADIUS server's secret. + + + + + + RADIUS_email_suffix + + Bugzilla needs an e-mail address for each user account. + Therefore, it needs to determine the e-mail address corresponding + to a RADIUS user. + Bugzilla offers only a simple way to do this: it can concatenate + a suffix to the RADIUS user name to convert it into an e-mail + address. + You can specify this suffix in the RADIUS_email_suffix parameter. + + If this simple solution does not work for you, you'll + probably need to modify + Bugzilla/Auth/Verify/RADIUS.pm to match your + requirements. + + + + + +
+
LDAP Authentication @@ -1553,12 +1626,12 @@ c:\perl\bin\perl.exe -xc:\bugzilla -wT "%s" %s user_verify_class - This parameter should be set to LDAP - only if you will be using an LDAP directory - for authentication. If you set this param to LDAP but - fail to set up the other parameters listed below you will not be - able to log back in to Bugzilla one you log out. If this happens - to you, you will need to manually edit + If you want to list LDAP here, + make sure to have set up the other parameters listed below. + Unless you have other (working) authentication methods listed as + well, you may otherwise not be able to log back in to Bugzilla once + you log out. + If this happens to you, you will need to manually edit data/params and set user_verify_class to DB. diff --git a/js/params.js b/js/params.js new file mode 100755 index 000000000..453740799 --- /dev/null +++ b/js/params.js @@ -0,0 +1,61 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * The Initial Developer of the Original Code is Marc Schumann. + * Portions created by Marc Schumann are Copyright (c) 2007 Marc Schumann. + * All rights reserved. + * + * Contributor(s): Marc Schumann + */ + +function sortedList_moveItem(paramName, direction, separator) { + var select = document.getElementById('select_' + paramName); + var inputField = document.getElementById('input_' + paramName); + var currentIndex = select.selectedIndex; + var newIndex = currentIndex + direction; + var optionCurrentIndex; + var optionNewIndex; + + /* Return if no selection */ + if (currentIndex < 0) return; + /* Return if trying to move upward out of list */ + if (newIndex < 0) return; + /* Return if trying to move downward out of list */ + if (newIndex >= select.length) return; + + /* Move selection */ + optionNewIndex = select.options[newIndex]; + optionCurrentIndex = select.options[currentIndex]; + /* Because some browsers don't accept the same option object twice in a + * selection list, we need to put a blank option here first */ + select.options[newIndex] = new Option(); + select.options[currentIndex] = optionNewIndex; + select.options[newIndex] = optionCurrentIndex; + select.selectedIndex = newIndex; + populateInputField(select, inputField, separator); +} + +function populateInputField(select, inputField, separator) { + var i; + var stringRepresentation = ''; + + for (i = 0; i < select.length; i++) { + if (select.options[i].value == separator) { + break; + } + if (stringRepresentation != '') { + stringRepresentation += ','; + } + stringRepresentation += select.options[i].value; + } + inputField.value = stringRepresentation; +} diff --git a/skins/standard/params.css b/skins/standard/params.css index 8d34d0e05..4eec75261 100644 --- a/skins/standard/params.css +++ b/skins/standard/params.css @@ -48,6 +48,12 @@ dd { margin-bottom: 1.5em; } +.sortlist_separator { + font-weight: bold; + font-size: 80%; + background-color: #dddddd; +} + .contribute { border: 1px dotted black; padding: .5em; diff --git a/template/en/default/admin/params/auth.html.tmpl b/template/en/default/admin/params/auth.html.tmpl index 040190699..2e52426bf 100644 --- a/template/en/default/admin/params/auth.html.tmpl +++ b/template/en/default/admin/params/auth.html.tmpl @@ -18,6 +18,7 @@ # # Contributor(s): Dave Miller # Frédéric Buclin + # Marc Schumann #%] [% title = "User Authentication" @@ -67,12 +68,23 @@ ${terms.Bugzilla}'s built-in authentication. This is the most common choice. +
RADIUS
+
+ RADIUS authentication using a RADIUS server. + This method is experimental; please see the + $terms.Bugzilla documentation for more information. + Using this method requires + additional + parameters to be set. +
LDAP
- LDAP authentication using an LDAP server. This method is - experimental; please see the $terms.Bugzilla documentation for more - information. Using this method requires additional parameters - to be set above. + LDAP authentication using an LDAP server. + This method is experimental; please see the + $terms.Bugzilla documentation for more information. + Using this method requires + additional + parameters to be set.
", @@ -121,4 +133,4 @@ "to be created. If this parameter is left blank, no users " _ "will be permitted to create their own accounts and all accounts " _ "will have to be created by an administrator." } -%] \ No newline at end of file +%] diff --git a/template/en/default/admin/params/common.html.tmpl b/template/en/default/admin/params/common.html.tmpl index 34cd1d39c..4e2b8f821 100644 --- a/template/en/default/admin/params/common.html.tmpl +++ b/template/en/default/admin/params/common.html.tmpl @@ -17,11 +17,14 @@ # Rights Reserved. # # Contributor(s): Frédéric Buclin + # Marc Schumann #%] [%# INTERFACE: # panel: hash representing the current panel. #%] +[% sortlist_separator = '---' %] +
[% FOREACH param = panel.param_list %]
[% param.name FILTER html %]
@@ -53,6 +56,57 @@ [% END %] + [% ELSIF param.type == "o" %] + +
+ + [% boxSize = 7 %] + [% boxSize = 3 + param.choices.size IF param.choices.size < 7 %] + [% plist = Param(param.name).split(',') %] + + [% ELSIF param.type == "s" %]