* Debian upgrade for jquery management
* SQL injection protection for DBI * Regexp to control user field * Missing parameters in _Struct.pm * Bad errors management in Uploader
This commit is contained in:
parent
29b8c86848
commit
4d47d92749
|
@ -75,7 +75,7 @@ install: build
|
|||
find $(CURDIR)/debian/tmp -type f -regex '.*/jquery-[0-9].*\.js' -delete
|
||||
find $(CURDIR)/debian/tmp -type f -name jquery.js -delete
|
||||
rm -f $(CURDIR)/debian/tmp$(LMSHAREDIR)*-skins/*/jquery.js
|
||||
perl -i -pe 's#(["'"'"'])\S*?jquery(-\d[\.\w\-]*?)?.js#$$1/javascript/jquery/jquery.js#' \
|
||||
perl -i -pe 's#src=(["'"'"']).*?jquery(-\d[\.\w\-]*?)?.js#src=$$1/javascript/jquery/jquery.js#i' \
|
||||
$(CURDIR)/debian/tmp/examples/manager/*.pl \
|
||||
$(CURDIR)/debian/tmp$(LMSHAREDIR)manager-skins/default/*.tpl \
|
||||
$(CURDIR)/debian/tmp$(LMSHAREDIR)portal-skins/pastel/*.tpl
|
||||
|
|
|
@ -43,7 +43,7 @@ sub confUpload {
|
|||
my $newConf = { cfgNum => $self->{cfgNum} };
|
||||
|
||||
# Loading returned parameters
|
||||
my $res;
|
||||
my $errors = {};
|
||||
foreach ( @{ $result->getChildrenByTagName('element') } ) {
|
||||
my ( $id, $name, $value ) = (
|
||||
$_->getAttribute('id'),
|
||||
|
@ -63,7 +63,7 @@ sub confUpload {
|
|||
my ( $res, $m );
|
||||
|
||||
if ( !defined($test) ) {
|
||||
$res->{errors}->{$name} =
|
||||
$errors->{errors}->{$name} =
|
||||
"Key $name: Lemonldap::NG::Manager error, see Apache's logs";
|
||||
$self->lmLog(
|
||||
"Unknown configuration key $id (name: $name, value: $value)",
|
||||
|
@ -78,27 +78,27 @@ sub confUpload {
|
|||
if ( $test->{keyTest} ) {
|
||||
( $res, $m ) = $self->applyTest( $test->{keyTest}, $name );
|
||||
unless ($res) {
|
||||
$res->{errors}->{$name} = $m || $test->{keyMsgFail};
|
||||
$errors->{errors}->{$name} = $m || $test->{keyMsgFail};
|
||||
next;
|
||||
}
|
||||
}
|
||||
if ( $test->{test} ) {
|
||||
( $res, $m ) = $self->applyTest( $test->{test}, $value );
|
||||
unless ($res) {
|
||||
$res->{errors}->{$name} = $m || $test->{msgFail};
|
||||
$errors->{errors}->{$name} = $m || $test->{msgFail};
|
||||
next;
|
||||
}
|
||||
}
|
||||
if ( $test->{warnKeyTest} ) {
|
||||
( $res, $m ) = $self->applyTest( $test->{warnKeyTest}, $name );
|
||||
unless ($res) {
|
||||
$res->{warnings}->{$name} = $m || $test->{keyMsgWarn};
|
||||
$errors->{warnings}->{$name} = $m || $test->{keyMsgWarn};
|
||||
}
|
||||
}
|
||||
if ( $test->{warnTest} ) {
|
||||
( $res, $m ) = $self->applyTest( $test->{warnTest}, $value );
|
||||
unless ($res) {
|
||||
$res->{warnings}->{$name} = $m || $test->{keyMsgWarn};
|
||||
$errors->{warnings}->{$name} = $m || $test->{keyMsgWarn};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,12 +124,13 @@ sub confUpload {
|
|||
}
|
||||
}
|
||||
|
||||
#print STDERR Dumper( $newConf, $res );
|
||||
$res->{result}->{cfgNum} = $self->confObj->saveConf($newConf)
|
||||
unless ( $res->{errors} );
|
||||
#print STDERR Dumper( $newConf, $errors );
|
||||
#print STDERR Dumper($errors);
|
||||
$errors->{result}->{cfgNum} = $self->confObj->saveConf($newConf)
|
||||
unless ( $errors->{errors} );
|
||||
my $buf = '{';
|
||||
my $i = 0;
|
||||
while ( my ( $type, $h ) = each %$res ) {
|
||||
while ( my ( $type, $h ) = each %$errors ) {
|
||||
$buf .= ',' if ($i);
|
||||
$buf .= "'$type':{";
|
||||
$buf .= join( ',', map { "'$_':'$h->{$_}'" } keys %$h );
|
||||
|
|
|
@ -52,13 +52,13 @@ sub struct {
|
|||
_nodes => [
|
||||
qw(portal authentication userDB syslog whatToTrace singleSession singleIP singleUserByIP)
|
||||
],
|
||||
_help => 'authParams',
|
||||
authentication => 'text:/authentication',
|
||||
portal => 'text:/portal',
|
||||
userDB => 'text:/userDB',
|
||||
syslog => 'int:/syslog',
|
||||
_help => 'authParams',
|
||||
authentication => 'text:/authentication',
|
||||
portal => 'text:/portal',
|
||||
userDB => 'text:/userDB',
|
||||
syslog => 'int:/syslog',
|
||||
useXForwardedForIP => 'int:/useXForwardedForIP',
|
||||
whatToTrace => 'text:/whatToTrace:whatToTrace:text',
|
||||
whatToTrace => 'text:/whatToTrace:whatToTrace:text',
|
||||
singleSession => 'int:/singleSession',
|
||||
singleIP => 'int:/singleIP',
|
||||
singleUserByIP => 'int:/singleUserByIP',
|
||||
|
@ -66,7 +66,7 @@ sub struct {
|
|||
cookieParams => {
|
||||
_nodes =>
|
||||
[qw(cookieName domain securedCookie cookieExpiration)],
|
||||
_help => 'cookies',
|
||||
_help => 'cookies',
|
||||
cookieName => 'text:/cookieName:cookieName:text',
|
||||
domain => 'text:/domain:domain:text',
|
||||
securedCookie =>
|
||||
|
@ -104,19 +104,19 @@ sub struct {
|
|||
},
|
||||
advancedParams => {
|
||||
_nodes => [
|
||||
qw(Soap exportedAttr storePassword trustedDomains status https protection notifications passwordManagement)
|
||||
qw(Soap exportedAttr storePassword trustedDomains status https notifications passwordManagement userControl)
|
||||
],
|
||||
Soap => 'int:/Soap',
|
||||
Soap => 'int:/Soap',
|
||||
https => 'int:/https',
|
||||
exportedAttr => 'text:/exportedAttr',
|
||||
exportedAttr => 'text:/exportedAttr',
|
||||
storePassword => 'int:/storePassword',
|
||||
notifications => {
|
||||
_nodes => [
|
||||
qw(notification notificationStorage notificationStorageOptions)
|
||||
],
|
||||
_help => 'notifications',
|
||||
_help => 'notifications',
|
||||
notification => 'int:/notification',
|
||||
notificationStorage => 'text:/notificationStorage',
|
||||
notificationStorage => 'text:/notificationStorage',
|
||||
notificationStorageOptions => {
|
||||
_nodes => ['hash:/notificationStorageOptions'],
|
||||
_js => 'hashRoot'
|
||||
|
@ -135,13 +135,19 @@ sub struct {
|
|||
},
|
||||
trustedDomains => 'text:/trustedDomains',
|
||||
status => 'int:/status',
|
||||
protection => 'int:/protection',
|
||||
userControl => 'text:/userControl:userControl:text',
|
||||
}
|
||||
},
|
||||
groups =>
|
||||
{ _nodes => ['hash:/groups:groups:btext'], _js => 'hashRoot', _help => 'default', },
|
||||
virtualHosts =>
|
||||
{ _nodes => ['nhash:/locationRules:virtualHosts:none'], _upload => ['/exportedHeaders'], _help => 'default', },
|
||||
groups => {
|
||||
_nodes => ['hash:/groups:groups:btext'],
|
||||
_js => 'hashRoot',
|
||||
_help => 'default',
|
||||
},
|
||||
virtualHosts => {
|
||||
_nodes => ['nhash:/locationRules:virtualHosts:none'],
|
||||
_upload => ['/exportedHeaders'],
|
||||
_help => 'default',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -158,8 +164,25 @@ sub testStruct {
|
|||
return ( $@ ? ( 0, $@ ) : 1 );
|
||||
};
|
||||
my $boolean = { test => qr/^(?:0|1)?$/, msgFail => 'Value must be 0 or 1' };
|
||||
my $pcre = sub {
|
||||
my $r = shift;
|
||||
my $q;
|
||||
eval { $q = qr/$r/ };
|
||||
return ( $@ ? ( 0, $@ ) : 1 );
|
||||
};
|
||||
my $testNotDefined = { test => sub { 1 }, msgFail => 'Ok' };
|
||||
return {
|
||||
authentication => {
|
||||
mailFrom => $testNotDefined,
|
||||
trustedDomains => $testNotDefined,
|
||||
exportedAttr => $testNotDefined,
|
||||
mailSubject => $testNotDefined,
|
||||
randomPasswordRegexp => $testNotDefined,
|
||||
passwordDB => $testNotDefined,
|
||||
mailBody => $testNotDefined,
|
||||
SMTPServer => $testNotDefined,
|
||||
cookieExpiration => $testNotDefined,
|
||||
notificationStorage => $testNotDefined,
|
||||
authentication => {
|
||||
test => qr/^[a-zA-Z][\w\:]*$/,
|
||||
msgFail => 'Bad module name',
|
||||
},
|
||||
|
@ -175,7 +198,7 @@ sub testStruct {
|
|||
test => qr/^https?:\/\/\S+$/,
|
||||
msgFail => 'Bad portal value',
|
||||
},
|
||||
cda => $boolean,
|
||||
cda => $boolean,
|
||||
cookieName => {
|
||||
test => qr/^[a-zA-Z]\w*$/,
|
||||
msgFail => 'Bad cookie name',
|
||||
|
@ -224,7 +247,7 @@ sub testStruct {
|
|||
test => qr/^(?:\w+=.*,\w+=.*)?$/,
|
||||
msgFail => 'Bad LDAP dn',
|
||||
},
|
||||
managerPassword => {},
|
||||
managerPassword => {},
|
||||
notificationStorage => {
|
||||
test => qr/^[\w:]+$/,
|
||||
msgFail => 'Bad module name',
|
||||
|
@ -233,7 +256,7 @@ sub testStruct {
|
|||
keyTest => qr/^\w+$/,
|
||||
keyMsgFail => 'Bad parameter',
|
||||
},
|
||||
groups => {
|
||||
groups => {
|
||||
keyTest => qr/^\w[\w-]*$/,
|
||||
keyMsgFail => 'Bad group name',
|
||||
test => $perlExpr,
|
||||
|
@ -263,13 +286,8 @@ sub testStruct {
|
|||
keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
|
||||
msgFail => 'Bad virtual host name',
|
||||
'*' => {
|
||||
keyTest => sub {
|
||||
my $r = shift;
|
||||
my $q;
|
||||
eval { $q = qr/$r/ };
|
||||
return ( $@ ? ( 0, $@ ) : 1 );
|
||||
},
|
||||
test => sub {
|
||||
keyTest => $pcre,
|
||||
test => sub {
|
||||
my $e = shift;
|
||||
return 1 if ( $e eq 'accept' or $e eq 'deny' );
|
||||
if ( $e =~ s/^logout(?:_(?:app|sso|app_sso))?\s*// ) {
|
||||
|
@ -291,9 +309,9 @@ sub testStruct {
|
|||
},
|
||||
},
|
||||
exportedHeaders => {
|
||||
keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
|
||||
msgFail => 'Bad virtual host name',
|
||||
'*' => {
|
||||
keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
|
||||
keyMsgFail => 'Bad virtual host name',
|
||||
'*' => {
|
||||
keyTest => qr/^\w([\w\-]*\w)?$/,
|
||||
keyMsgFail => 'Bad header name',
|
||||
test => $perlExpr,
|
||||
|
@ -304,10 +322,10 @@ sub testStruct {
|
|||
},
|
||||
},
|
||||
},
|
||||
syslog => $boolean,
|
||||
Soap => $boolean,
|
||||
syslog => $boolean,
|
||||
Soap => $boolean,
|
||||
storePassword => $boolean,
|
||||
notification => $boolean,
|
||||
notification => $boolean,
|
||||
status => $boolean,
|
||||
https => $boolean,
|
||||
protection => {
|
||||
|
@ -318,6 +336,10 @@ sub testStruct {
|
|||
singleSession => $boolean,
|
||||
singleIP => $boolean,
|
||||
singleUserByIP => $boolean,
|
||||
userControl => {
|
||||
test => $pcre,
|
||||
msgFail => 'Bad regular expression',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -325,15 +347,17 @@ sub testStruct {
|
|||
#@return Hashref of default values
|
||||
sub defaultConf {
|
||||
return {
|
||||
authentication => 'LDAP',
|
||||
userDB => 'LDAP',
|
||||
ldapServer => 'localhost',
|
||||
globalStorage => 'Apache::Session::File',
|
||||
authentication => 'LDAP',
|
||||
userDB => 'LDAP',
|
||||
ldapServer => 'localhost',
|
||||
globalStorage => 'Apache::Session::File',
|
||||
globalStorageOptions => {
|
||||
'Directory' => '/var/lib/lemonldap-ng/sessions/',
|
||||
'Directory' => '/var/lib/lemonldap-ng/sessions/',
|
||||
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
|
||||
},
|
||||
timeout => 7200,
|
||||
timeout => 7200,
|
||||
userControl => '^[\w\.\-@]+$',
|
||||
notificationStorage => 'File',
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ sub en {
|
|||
sessionStorage => 'Sessions Storage',
|
||||
timeout => 'Sessions timeout',
|
||||
userDB => 'Users database type',
|
||||
userControl => 'Username control',
|
||||
virtualHosts => 'Virtual Hosts',
|
||||
whatToTrace => "Attribute to use in Apache's logs",
|
||||
};
|
||||
|
@ -105,6 +106,7 @@ sub fr {
|
|||
sessionStorage => 'Stockage des sessions',
|
||||
timeout => 'Durée de vie des sessions',
|
||||
userDB => "Type de base de données d'utilisateurs",
|
||||
userControl => "Contrôle du nom d'utilisateur",
|
||||
virtualHosts => 'Hôtes virtuels',
|
||||
whatToTrace => "Donnée à inscrire dans les journaux d'Apache",
|
||||
};
|
||||
|
|
|
@ -47,7 +47,9 @@ sub authenticate {
|
|||
my $loginCol = $self->{dbiAuthLoginCol};
|
||||
my $passwordCol = $self->{dbiAuthPasswordCol};
|
||||
my $user = $self->{user};
|
||||
my $password;
|
||||
my $password = $self->{password};
|
||||
$user =~ s/'/''/g;
|
||||
$password =~ s/'/''/g;
|
||||
|
||||
# Manage password hash
|
||||
if ( $self->{dbiAuthPasswordHash} =~ /^(md5|sha|sha1)$/i ) {
|
||||
|
@ -55,24 +57,30 @@ sub authenticate {
|
|||
"Using " . uc( $self->{dbiAuthPasswordHash} ) . " to hash password",
|
||||
'debug'
|
||||
);
|
||||
$password =
|
||||
uc( $self->{dbiAuthPasswordHash} ) . "('" . $self->{password} . "')";
|
||||
$password = uc( $self->{dbiAuthPasswordHash} ) . "('$password')";
|
||||
}
|
||||
else {
|
||||
$self->lmLog( "No valid password hash, using clear text for password",
|
||||
'debug' );
|
||||
$password = "'" . $self->{password} . "'";
|
||||
$password = "'$password'";
|
||||
}
|
||||
|
||||
my $sth = $dbh->prepare(
|
||||
my @rows = ();
|
||||
eval {
|
||||
my $sth = $dbh->prepare(
|
||||
"SELECT $loginCol FROM $table WHERE $loginCol='$user' AND $passwordCol=$password"
|
||||
);
|
||||
);
|
||||
|
||||
$sth->execute();
|
||||
$sth->execute();
|
||||
|
||||
my @rows = $sth->fetchrow_array();
|
||||
@rows = $sth->fetchrow_array();
|
||||
};
|
||||
if ($@) {
|
||||
$self->lmLog( "DBI error: $@", 'error' );
|
||||
return PE_ERROR;
|
||||
}
|
||||
|
||||
if ( $#rows eq 0 ) {
|
||||
if ( @rows == 1 ) {
|
||||
$self->lmLog( "One row returned by SQL query", 'debug' );
|
||||
return PE_OK;
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ use constant {
|
|||
PE_BADURL => 37,
|
||||
PE_NOSCHEME => 38,
|
||||
PE_BADOLDPASSWORD => 39,
|
||||
PE_MALFORMEDUSER => 40,
|
||||
};
|
||||
|
||||
# EXPORTER PARAMETERS
|
||||
|
@ -91,7 +92,7 @@ our @EXPORT =
|
|||
PE_PP_PASSWORD_TOO_SHORT PE_PP_PASSWORD_TOO_YOUNG
|
||||
PE_PP_PASSWORD_IN_HISTORY PE_PP_GRACE PE_PP_EXP_WARNING
|
||||
PE_PASSWORD_MISMATCH PE_PASSWORD_OK PE_NOTIFICATION PE_BADURL
|
||||
PE_NOSCHEME PE_BADOLDPASSWORD);
|
||||
PE_NOSCHEME PE_BADOLDPASSWORD PE_MALFORMEDUSER);
|
||||
our %EXPORT_TAGS = ( 'all' => [ @EXPORT, 'import' ], );
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
|
|
|
@ -30,6 +30,33 @@ sub userDBInit {
|
|||
# Do nothing
|
||||
# @return Lemonldap::NG::Portal constant
|
||||
sub getUser {
|
||||
my $self = shift;
|
||||
|
||||
# Connect
|
||||
my $dbh =
|
||||
$self->dbh( $self->{dbiUserChain}, $self->{dbiUserUser},
|
||||
$self->{dbiUserPassword} );
|
||||
return PE_ERROR unless $dbh;
|
||||
|
||||
my $table = $self->{dbiUserTable};
|
||||
my $pivot = $self->{userPivot};
|
||||
my $user = $self->{user};
|
||||
$user =~ s/'/''/g;
|
||||
|
||||
eval {
|
||||
my $sth = $dbh->prepare("SELECT * FROM $table WHERE $pivot='$user'");
|
||||
$sth->execute();
|
||||
|
||||
unless ( $self->{entry} = $sth->fetchrow_hashref() ) {
|
||||
$self->lmLog( "User $user not found", 'notice' );
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
};
|
||||
if ($@) {
|
||||
$self->lmLog( "DBI error: $@", 'error' );
|
||||
return PE_ERROR;
|
||||
}
|
||||
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
|
@ -44,27 +71,9 @@ sub setSessionInfo {
|
|||
unless ( $self->{exportedVars}
|
||||
and ref( $self->{exportedVars} ) eq 'HASH' );
|
||||
|
||||
# Connect
|
||||
my $dbh =
|
||||
$self->dbh( $self->{dbiUserChain}, $self->{dbiUserUser},
|
||||
$self->{dbiUserPassword} );
|
||||
return PE_ERROR unless $dbh;
|
||||
|
||||
my $table = $self->{dbiUserTable};
|
||||
my $pivot = $self->{userPivot};
|
||||
|
||||
my $sth = $dbh->prepare(
|
||||
"SELECT * FROM $table WHERE $pivot='" . $self->{user} . "'" );
|
||||
|
||||
$sth->execute();
|
||||
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
|
||||
foreach ( keys %{ $self->{exportedVars} } ) {
|
||||
if ( exists $result->{ $self->{exportedVars}->{$_} } ) {
|
||||
$self->{sessionInfo}->{$_} =
|
||||
$result->{ $self->{exportedVars}->{$_} };
|
||||
}
|
||||
while ( my ( $var, $attr ) = each %{ $self->{exportedVars} } ) {
|
||||
$self->{sessionInfo}->{$var} = $self->{entry}->{$attr}
|
||||
if ( defined $self->{entry}->{$attr} );
|
||||
}
|
||||
|
||||
PE_OK;
|
||||
|
|
|
@ -27,15 +27,17 @@ sub extractFormInfo {
|
|||
return PE_FORMEMPTY
|
||||
unless (
|
||||
(
|
||||
( $self->{'user'} = $self->param('user') )
|
||||
&& ( ( $self->{'password'} = $self->param('password') )
|
||||
|| ( $self->{'newpassword'} = $self->param('newpassword') ) )
|
||||
( $self->{user} = $self->param('user') )
|
||||
&& ( ( $self->{password} = $self->param('password') )
|
||||
|| ( $self->{newpassword} = $self->param('newpassword') ) )
|
||||
)
|
||||
|| ( $self->{'mail'} = $self->param('mail') )
|
||||
|| ( $self->{mail} = $self->param('mail') )
|
||||
);
|
||||
$self->{'oldpassword'} = $self->param('oldpassword');
|
||||
$self->{'confirmpassword'} = $self->param('confirmpassword');
|
||||
$self->{'timezone'} = $self->param('timezone');
|
||||
$self->{oldpassword} = $self->param('oldpassword');
|
||||
$self->{confirmpassword} = $self->param('confirmpassword');
|
||||
$self->{timezone} = $self->param('timezone');
|
||||
$self->{userControl} ||= '^[\w\.\-@]+$';
|
||||
return PE_MALFORMEDUSER unless ( $self->{user} =~ /$self->{userControl}/o );
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ sub error_fr {
|
|||
'Mauvaise URL',
|
||||
'Aucun schéma disponible',
|
||||
'Ancien mot de passe invalide',
|
||||
"Nom d'utilisateur incorrect",
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -175,6 +176,7 @@ sub error_en {
|
|||
'Bad URL',
|
||||
'No scheme available',
|
||||
'Bad old password',
|
||||
'Bad username',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -224,5 +226,6 @@ sub error_ro {
|
|||
'Rea URL',
|
||||
'No scheme available',
|
||||
'Bad old password',
|
||||
'Bad username',
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user