* 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:
Xavier Guimard 2009-12-19 08:57:59 +00:00
parent 29b8c86848
commit 4d47d92749
9 changed files with 139 additions and 89 deletions

View File

@ -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

View File

@ -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 );

View File

@ -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',
};
}

View 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",
};

View File

@ -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;
}

View File

@ -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'} } );

View File

@ -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;

View File

@ -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;
}

View File

@ -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',
];
}