Add Auth::PAM (#closes: #1196)
This commit is contained in:
parent
625ea22266
commit
a07e92759c
|
@ -148,6 +148,8 @@ sub defaultValues {
|
|||
'openIdSreg_fullname' => 'cn',
|
||||
'openIdSreg_nickname' => 'uid',
|
||||
'openIdSreg_timezone' => '_timezone',
|
||||
'pamAuthnLevel' => 2,
|
||||
'pamService' => 'login',
|
||||
'passwordDB' => 'Demo',
|
||||
'portal' => 'http://auth.example.com/',
|
||||
'portalAntiFrame' => 1,
|
||||
|
|
|
@ -42,6 +42,7 @@ our $authParameters = {
|
|||
nullParams => [qw(nullAuthnLevel)],
|
||||
oidcParams => [qw(oidcAuthnLevel oidcRPCallbackGetParam oidcRPStateTimeout)],
|
||||
openidParams => [qw(openIdAuthnLevel openIdExportedVars openIdSecret openIdIDPList)],
|
||||
pamParams => [qw(pamService pamAuthnLevel)],
|
||||
proxyParams => [qw(proxyAuthService proxySessionService remoteCookieName proxyAuthnLevel proxyUseSoap)],
|
||||
radiusParams => [qw(radiusAuthnLevel radiusSecret radiusServer)],
|
||||
remoteParams => [qw(remotePortal remoteCookieName remoteGlobalStorage remoteGlobalStorageOptions)],
|
||||
|
|
|
@ -27,7 +27,7 @@ sub types {
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval "$s $val";
|
||||
my $err = join(
|
||||
|
@ -308,6 +308,10 @@ sub attributes {
|
|||
'k' => 'LDAP',
|
||||
'v' => 'LDAP'
|
||||
},
|
||||
{
|
||||
'k' => 'PAM',
|
||||
'v' => 'PAM'
|
||||
},
|
||||
{
|
||||
'k' => 'Null',
|
||||
'v' => 'None'
|
||||
|
@ -498,6 +502,10 @@ sub attributes {
|
|||
'k' => 'LDAP',
|
||||
'v' => 'LDAP'
|
||||
},
|
||||
{
|
||||
'k' => 'PAM',
|
||||
'v' => 'PAM'
|
||||
},
|
||||
{
|
||||
'k' => 'Radius',
|
||||
'v' => 'Radius'
|
||||
|
@ -707,6 +715,10 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'k' => 'LDAP',
|
||||
'v' => 'LDAP'
|
||||
},
|
||||
{
|
||||
'k' => 'PAM',
|
||||
'v' => 'PAM'
|
||||
},
|
||||
{
|
||||
'k' => 'Radius',
|
||||
'v' => 'Radius'
|
||||
|
@ -927,7 +939,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval $s;
|
||||
my $err = join(
|
||||
|
@ -996,7 +1008,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval "$s $val";
|
||||
my $err = join(
|
||||
|
@ -1019,7 +1031,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval "$s $val";
|
||||
my $err = join(
|
||||
|
@ -1331,7 +1343,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval $s;
|
||||
my $err = join(
|
||||
|
@ -1368,7 +1380,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval "$s $val";
|
||||
my $err = join(
|
||||
|
@ -1862,6 +1874,14 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
'default' => '_timezone',
|
||||
'type' => 'lmAttrOrMacro'
|
||||
},
|
||||
'pamAuthnLevel' => {
|
||||
'default' => 2,
|
||||
'type' => 'int'
|
||||
},
|
||||
'pamService' => {
|
||||
'default' => 'login',
|
||||
'type' => 'text'
|
||||
},
|
||||
'passwordDB' => {
|
||||
'default' => 'Demo',
|
||||
'select' => [
|
||||
|
@ -2018,7 +2038,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval "$s $val";
|
||||
my $err = join(
|
||||
|
|
|
@ -1756,6 +1756,7 @@ sub attributes {
|
|||
{ k => 'Facebook', v => 'Facebook' },
|
||||
{ k => 'Google', v => 'Google' },
|
||||
{ k => 'LDAP', v => 'LDAP' },
|
||||
{ k => 'PAM', v => 'PAM' },
|
||||
{ k => 'Radius', v => 'Radius' },
|
||||
{ k => 'REST', v => 'REST' },
|
||||
{ k => 'SSL', v => 'SSL' },
|
||||
|
@ -2020,6 +2021,18 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
keyMsgFail => '__badCasProxyId__',
|
||||
},
|
||||
|
||||
# PAM
|
||||
pamAuthnLevel => {
|
||||
type => 'int',
|
||||
default => 2,
|
||||
documentation => 'PAM authentication level',
|
||||
},
|
||||
pamService => {
|
||||
type => 'text',
|
||||
default => 'login',
|
||||
documentation => 'PAM service',
|
||||
},
|
||||
|
||||
# Radius
|
||||
radiusAuthnLevel => {
|
||||
type => 'int',
|
||||
|
@ -2219,6 +2232,7 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
{ k => 'Facebook', v => 'Facebook' },
|
||||
{ k => 'Google', v => 'Google' },
|
||||
{ k => 'LDAP', v => 'LDAP' },
|
||||
{ k => 'PAM', v => 'PAM' },
|
||||
{ k => 'Null', v => 'None' },
|
||||
{ k => 'OpenID', v => 'OpenID' },
|
||||
{ k => 'OpenIDConnect', v => 'OpenID Connect' },
|
||||
|
@ -2281,6 +2295,7 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
{ k => 'Facebook', v => 'Facebook' },
|
||||
{ k => 'Google', v => 'Google' },
|
||||
{ k => 'LDAP', v => 'LDAP' },
|
||||
{ k => 'PAM', v => 'PAM' },
|
||||
{ k => 'Radius', v => 'Radius' },
|
||||
{ k => 'REST', v => 'REST' },
|
||||
{ k => 'SSL', v => 'SSL' },
|
||||
|
|
|
@ -287,6 +287,12 @@ sub tree {
|
|||
'proxyUseSoap'
|
||||
]
|
||||
},
|
||||
{
|
||||
title => 'pamParams',
|
||||
help => 'authpam.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [ 'pamService', 'pamAuthnLevel', ]
|
||||
},
|
||||
{
|
||||
title => 'radiusParams',
|
||||
help => 'authradius.html',
|
||||
|
|
|
@ -509,6 +509,9 @@
|
|||
"OpenIDConnect_OP": "Provider key",
|
||||
"OptionalTitle": "Optional title",
|
||||
"overPrm": "Overloaded parameters",
|
||||
"pamAuthnLevel": "Authentication level",
|
||||
"pamParams": "PAM parameters",
|
||||
"pamService": "PAM service",
|
||||
"password": "Password",
|
||||
"passwordDB": "Password module",
|
||||
"passwordManagement": "Password management",
|
||||
|
|
|
@ -509,6 +509,9 @@
|
|||
"OpenIDConnect_OP": "Clef du fournisseur",
|
||||
"OptionalTitle": "Titre optionnel",
|
||||
"overPrm": "Paramètres surchargés",
|
||||
"pamAuthnLevel": "Niveau d'authentification",
|
||||
"pamParams": "Paramètres PAM",
|
||||
"pamService": "Service PAM",
|
||||
"password": "Mot-de-passe",
|
||||
"passwordDB": "Module de mot de passe",
|
||||
"passwordManagement": "Gestion des mots de passe",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -23,6 +23,7 @@ lib/Lemonldap/NG/Portal/Auth/LDAP.pm
|
|||
lib/Lemonldap/NG/Portal/Auth/Null.pm
|
||||
lib/Lemonldap/NG/Portal/Auth/OpenID.pm
|
||||
lib/Lemonldap/NG/Portal/Auth/OpenIDConnect.pm
|
||||
lib/Lemonldap/NG/Portal/Auth/PAM.pm
|
||||
lib/Lemonldap/NG/Portal/Auth/Proxy.pm
|
||||
lib/Lemonldap/NG/Portal/Auth/Radius.pm
|
||||
lib/Lemonldap/NG/Portal/Auth/Remote.pm
|
||||
|
|
86
lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/PAM.pm
Normal file
86
lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/PAM.pm
Normal file
|
@ -0,0 +1,86 @@
|
|||
package Lemonldap::NG::Portal::Auth::PAM;
|
||||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Authen::PAM;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
PE_OK
|
||||
);
|
||||
|
||||
extends qw(Lemonldap::NG::Portal::Auth::_WebForm);
|
||||
|
||||
our $VERSION = '2.0.0';
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
has service => (
|
||||
is => 'rw',
|
||||
default => sub {
|
||||
return $_[0]->{conf}->{pamService} || 'login';
|
||||
}
|
||||
);
|
||||
|
||||
# RUNNING METHODS
|
||||
|
||||
sub authenticate {
|
||||
my ( $self, $req ) = @_;
|
||||
no strict 'subs';
|
||||
|
||||
# Handler to dial with Authen::PAM
|
||||
my $handler = sub {
|
||||
my @response = ();
|
||||
|
||||
while (@_) {
|
||||
my $code = shift;
|
||||
my $msg = shift;
|
||||
my $res;
|
||||
|
||||
if ( $code == PAM_PROMPT_ECHO_ON ) {
|
||||
$res = $req->user;
|
||||
}
|
||||
|
||||
elsif ( $code == PAM_PROMPT_ECHO_OFF ) {
|
||||
$res = $req->datas->{password};
|
||||
}
|
||||
|
||||
push( @response, PAM_SUCCESS, $res );
|
||||
}
|
||||
|
||||
return ( @response, PAM_SUCCESS );
|
||||
};
|
||||
|
||||
# Launch PAM service
|
||||
my $pam = Authen::PAM->new( $self->service, $req->user, $handler );
|
||||
unless ( ref $pam ) {
|
||||
$self->logger->error(
|
||||
'PAM failed: ' . Authen::PAM->pam_strerror($pam) );
|
||||
return PE_ERROR;
|
||||
}
|
||||
|
||||
# Check for authentication and authorization
|
||||
foreach my $sub (qw(pam_authenticate pam_acct_mgmt)) {
|
||||
my $res = $pam->$sub;
|
||||
unless ( $res == PAM_SUCCESS ) {
|
||||
$self->userLogger->warn( "PAM failed to authenticate $req->{user}: "
|
||||
. $pam->pam_strerror($res) );
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
}
|
||||
$self->userLogger->notice("Good PAM authentication for $req->{user}");
|
||||
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
sub setAuthSessionInfo {
|
||||
my ( $self, $req ) = @_;
|
||||
$req->sessionInfo->{authenticationLevel} = $self->conf->{pamAuthnLevel};
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
sub authLogout {
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user