Commit 17e351df authored by Xavier Guimard's avatar Xavier Guimard

Merge branch 'v2.0'

parents 7703b993 c77317fe
...@@ -61,10 +61,10 @@ server { ...@@ -61,10 +61,10 @@ server {
# Set manually your headers # Set manually your headers
#auth_request_set $authuser $upstream_http_auth_user; #auth_request_set $authuser $upstream_http_auth_user;
#proxy_set_header Auth-User $authuser; #proxy_set_header Auth-User $authuser;
# OR in the correspondinc block # OR in the corresponding block
#fastcgi_param HTTP_AUTH_USER $authuser; #fastcgi_param HTTP_AUTH_USER $authuser;
# Then (if LUA not supported), change cookie header to hide LLNG cookie # Then (if LUA is not supported), change cookie header to hide LLNG cookie
#auth_request_set $lmcookie $upstream_http_cookie; #auth_request_set $lmcookie $upstream_http_cookie;
#proxy_set_header Cookie: $lmcookie; #proxy_set_header Cookie: $lmcookie;
# OR in the corresponding block # OR in the corresponding block
......
...@@ -14,6 +14,7 @@ Build-Depends-Indep: libapache-session-perl, ...@@ -14,6 +14,7 @@ Build-Depends-Indep: libapache-session-perl,
libconvert-pem-perl, libconvert-pem-perl,
libcrypt-openssl-rsa-perl, libcrypt-openssl-rsa-perl,
libcrypt-openssl-x509-perl, libcrypt-openssl-x509-perl,
libcrypt-urandom-perl,
libcrypt-rijndael-perl, libcrypt-rijndael-perl,
libdbd-sqlite3-perl, libdbd-sqlite3-perl,
libdbi-perl, libdbi-perl,
...@@ -195,6 +196,7 @@ Depends: ${misc:Depends}, ...@@ -195,6 +196,7 @@ Depends: ${misc:Depends},
libconfig-inifiles-perl, libconfig-inifiles-perl,
libcrypt-openssl-rsa-perl, libcrypt-openssl-rsa-perl,
libcrypt-openssl-x509-perl, libcrypt-openssl-x509-perl,
libcrypt-urandom-perl,
libcrypt-rijndael-perl, libcrypt-rijndael-perl,
libhtml-template-perl, libhtml-template-perl,
libjson-perl, libjson-perl,
......
...@@ -2,15 +2,21 @@ ...@@ -2,15 +2,21 @@
/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */ /* http://docs.angularjs.org/guide/dev_guide.e2e-testing */
describe('02 Lemonldap::NG Manager', function() { describe('02 Lemonldap::NG Manger', function() {
describe('Menu', function() {
describe('translation', function() {
it('should translate in english and french', function() { it('should translate in english and french', function() {
var tests = { var tests = {
"en": "General Parameters", "en": "General Parameters",
"fr": "Paramètres généraux" "fr": "Paramètres généraux"
}; };
// // Login attempt
// browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
// browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//input[@name='password']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
// browser.get('/');
var els = element.all(by.css('[ng-click="getLanguage(lang)"]')); var els = element.all(by.css('[ng-click="getLanguage(lang)"]'));
expect(els.count()).toEqual(14); expect(els.count()).toEqual(14);
els.each(function(el) { els.each(function(el) {
...@@ -26,5 +32,14 @@ describe('02 Lemonldap::NG Manager', function() { ...@@ -26,5 +32,14 @@ describe('02 Lemonldap::NG Manager', function() {
}); });
}); });
}); });
it('Should display Menu -> Links', function() {
element(by.id("mainlangmenu")).click();
browser.sleep(500);
var links = element.all(by.repeater('menulink in menulinks'));
expect(links.count()).toEqual(4);
expect(links.get(0).getText()).toEqual('Retour au portail');
expect(links.get(1).getText()).toEqual('Déconnexion');
});
}); });
}); });
...@@ -11,12 +11,13 @@ describe('40 Lemonldap::NG Manager', function() { ...@@ -11,12 +11,13 @@ describe('40 Lemonldap::NG Manager', function() {
}); });
describe('40 Lemonldap::NG Session explorer', function() { describe('40 Lemonldap::NG Sessions explorer', function() {
var session, ip; var session, ip;
it('Should display at least my session', function() { it('Should display at least my session', function() {
browser.get('/sessions.html'); browser.get('/sessions.html');
expect(element.all(by.xpath("//a[@href='sessions.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
var t = element.all(by.repeater('node in data track by node.id')); var t = element.all(by.repeater('node in data track by node.id'));
expect(t.count()).toBeGreaterThan(0); expect(t.count()).toBeGreaterThan(0);
element(by.id("a-d")).click(); element(by.id("a-d")).click();
......
'use strict';
describe('50 Lemonldap::NG Manager', function() {
it('should display 2FA Sessions explorer', function() {
//// Login attempt
// browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
// browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//input[@name='password']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
browser.get('/');
var links = element.all(by.repeater('l in links'));
expect(links.count()).toEqual(4);
expect(element.all(by.xpath("//a[@href='2ndfa.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
element.all(by.xpath("//a[@href='2ndfa.html']")).first().click();
});
});
describe('50 Lemonldap::NG 2FA Sessions explorer', function() {
it('Should display at least my persistent session', function() {
browser.get('/2ndfa.html');
expect(element(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA ');
expect(element.all(by.css("input[type=checkbox]")).count()).toEqual(3);
expect(element.all(by.css("input[type=text]")).count()).toEqual(1);
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.id("a-d")).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.id("s-5efe8af397fc3577e05b483aca964f1b")).click();
browser.sleep(500);
});
it('Should display Dwho session', function() {
expect(element(by.tagName('h1')).getText()).toEqual('Contenu de la session 5efe8af397fc3577e05b483aca964f1b');
var titles = element.all(by.tagName('h2'));
expect(titles.get(0).getText()).toEqual('Dates');
expect(titles.get(1).getText()).toEqual("Seconds Facteurs d'Authentification");
var nodes = element.all(by.className('glyphicon-minus-sign'));
expect(nodes.count()).toEqual(3);
nodes.get(0).click();
expect(element.all(by.className('glyphicon-minus-sign')).count()).toEqual(2);
});
it('Should filter persistent sessions', function() {
element(by.css('input[ng-model="U2FCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.css('input[ng-model="UBKCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.css('input[ng-model="TOTPCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(0);
expect(element.all(by.className('label-warning')).get(0).getText()).toEqual('Aucune donnée à afficher');
element(by.css('input[ng-model="TOTPCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.css('input[ng-model="searchString"]')).clear().sendKeys('dw');
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
expect(element(by.id("a-dw")));
browser.sleep(500);
element(by.css('input[ng-model="searchString"]')).clear().sendKeys('dwho');
expect(element(by.id("a-dwho")));
browser.sleep(500);
element(by.css('input[ng-model="searchString"]')).clear().sendKeys('a');
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(0);
expect(element.all(by.className('label-warning')).get(0).getText()).toEqual('Aucune donnée à afficher');
browser.sleep(500);
element(by.className('glyphicon-search')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
browser.sleep(500);
});
});
...@@ -99,21 +99,25 @@ describe('0 Lemonldap::NG', function() { ...@@ -99,21 +99,25 @@ describe('0 Lemonldap::NG', function() {
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="WebSSO Manager"]')).click(); browser.driver.findElement(by.css('[alt="WebSSO Manager"]')).click();
expect(element.all(by.xpath("//a[@href='manager.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000); browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="currentConfiguration"]')).getText()).toEqual('Configuration actuelle'); expect(browser.driver.findElement(by.css('[trspan="currentConfiguration"]')).getText()).toEqual('Configuration actuelle');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="Sessions explorer"]')).click(); browser.driver.findElement(by.css('[alt="Sessions explorer"]')).click();
expect(element.all(by.xpath("//a[@href='sessions.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000); browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="session_s"]')).getText()).toEqual('session(s)'); expect(browser.driver.findElement(by.css('[trspan="session_s"]')).getText()).toEqual('session(s)');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="Notifications explorer"]')).click(); browser.driver.findElement(by.css('[alt="Notifications explorer"]')).click();
expect(element(by.xpath("//a[@href='notifications.html']")).getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000); browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="noDatas"]')).getText()).toEqual('Aucune donnée à afficher'); expect(browser.driver.findElement(by.css('[trspan="noDatas"]')).getText()).toEqual('Aucune donnée à afficher');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="2FA Sessions explorer"]')).click(); browser.driver.findElement(by.css('[alt="2FA Sessions explorer"]')).click();
expect(element.all(by.xpath("//a[@href='2ndfa.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000); browser.sleep(1000);
expect(browser.driver.findElement(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA '); expect(browser.driver.findElement(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA ');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
......
...@@ -33,6 +33,7 @@ WriteMakefile( ...@@ -33,6 +33,7 @@ WriteMakefile(
'Apache::Session::Browseable' => 0, 'Apache::Session::Browseable' => 0,
'Convert::Base32' => 0, 'Convert::Base32' => 0,
'Cookie::Baker::XS' => 0, 'Cookie::Baker::XS' => 0,
'Crypt::URandom' => 0,
'DBI' => 0, 'DBI' => 0,
'Net::LDAP' => 0, 'Net::LDAP' => 0,
'SOAP::Lite' => 0, 'SOAP::Lite' => 0,
......
...@@ -9,9 +9,10 @@ ...@@ -9,9 +9,10 @@
package Lemonldap::NG::Common::Apache::Session::Generate::SHA256; package Lemonldap::NG::Common::Apache::Session::Generate::SHA256;
use strict; use strict;
use Crypt::URandom;
use Digest::SHA qw(sha256 sha256_hex sha256_base64); use Digest::SHA qw(sha256 sha256_hex sha256_base64);
our $VERSION = '2.0.0'; our $VERSION = '2.0.2';
sub generate { sub generate {
my $session = shift; my $session = shift;
...@@ -23,7 +24,9 @@ sub generate { ...@@ -23,7 +24,9 @@ sub generate {
$session->{data}->{_session_id} = substr( $session->{data}->{_session_id} = substr(
Digest::SHA::sha256_hex( Digest::SHA::sha256_hex(
Digest::SHA::sha256_hex( time() . {} . rand() . $$ ) Digest::SHA::sha256_hex(
time() . {} . Crypt::URandom::urandom($length) . $$
)
), ),
0, $length 0, $length
); );
......
...@@ -5,10 +5,11 @@ package Lemonldap::NG::Common::TOTP; ...@@ -5,10 +5,11 @@ package Lemonldap::NG::Common::TOTP;
use strict; use strict;
use Mouse; use Mouse;
use Convert::Base32 'decode_base32'; use Convert::Base32 qw(decode_base32 encode_base32);
use Crypt::URandom;
use Digest::HMAC_SHA1 'hmac_sha1_hex'; use Digest::HMAC_SHA1 'hmac_sha1_hex';
our $VERSION = '2.0.0'; our $VERSION = '2.0.2';
# Verify that TOTP $code matches with $secret # Verify that TOTP $code matches with $secret
sub verifyCode { sub verifyCode {
...@@ -47,8 +48,7 @@ sub _code { ...@@ -47,8 +48,7 @@ sub _code {
# Simply generate new base32 secret # Simply generate new base32 secret
sub newSecret { sub newSecret {
my ($self) = @_; my ($self) = @_;
my @chars = ( 'a' .. 'z', 2 .. 7 ); return encode_base32( Crypt::URandom::urandom(20) );
return join( '', @chars[ map { int( rand(32) ) } 1 .. 32 ] );
} }
1; 1;
...@@ -66,7 +66,7 @@ sub logLevelInit { ...@@ -66,7 +66,7 @@ sub logLevelInit {
# adapt server signature # adapt server signature
sub serverSignatureInit { sub serverSignatureInit {
my $class = shift; my $class = shift;
require Lemonldap::NG::Handler; require Lemonldap::NG::Handler::Main;
my $version = $Lemonldap::NG::Handler::VERSION; my $version = $Lemonldap::NG::Handler::VERSION;
$class->setServerSignature("Lemonldap::NG/$version"); $class->setServerSignature("Lemonldap::NG/$version");
} }
......
...@@ -44,17 +44,17 @@ sub getStatus { ...@@ -44,17 +44,17 @@ sub getStatus {
if ( $ENV{LLNGSTATUSHOST} ) { if ( $ENV{LLNGSTATUSHOST} ) {
require IO::Socket::INET; require IO::Socket::INET;
foreach ( 64322 .. 64331 ) { foreach ( 64322 .. 64331 ) {
if ( $statusOut = if ( $statusOut
IO::Socket::INET->new( Proto => 'udp', LocalPort => $_ ) ) = IO::Socket::INET->new( Proto => 'udp', LocalPort => $_ ) )
{ {
$args = $args = ' host='
' host=' . ( $ENV{LLNGSTATUSCLIENT} || 'localhost' ) . ":$_"; . ( $ENV{LLNGSTATUSCLIENT} || 'localhost' ) . ":$_";
last; last;
} }
} }
return $class->abort( $req, return $class->abort( $req,
"$class: status page can not be displayed, unable to open socket" ) "$class: status page can not be displayed, unable to open socket"
unless ($statusOut); ) unless ($statusOut);
} }
return $class->abort( $req, "$class: status page can not be displayed" ) return $class->abort( $req, "$class: status page can not be displayed" )
unless ( $statusPipe and $statusOut ); unless ( $statusPipe and $statusOut );
...@@ -243,8 +243,8 @@ sub lmLog { ...@@ -243,8 +243,8 @@ sub lmLog {
sub checkMaintenanceMode { sub checkMaintenanceMode {
my ( $class, $req ) = @_; my ( $class, $req ) = @_;
my $vhost = $class->resolveAlias($req); my $vhost = $class->resolveAlias($req);
my $_maintenance = my $_maintenance
( defined $class->tsv->{maintenance}->{$vhost} ) = ( defined $class->tsv->{maintenance}->{$vhost} )
? $class->tsv->{maintenance}->{$vhost} ? $class->tsv->{maintenance}->{$vhost}
: $class->tsv->{maintenance}->{_}; : $class->tsv->{maintenance}->{_};
...@@ -272,8 +272,8 @@ sub grant { ...@@ -272,8 +272,8 @@ sub grant {
} }
} }
for ( for (
my $i = 0 ; my $i = 0;
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 ) ; $i < ( $class->tsv->{locationCount}->{$vhost} || 0 );
$i++ $i++
) )
{ {
...@@ -341,8 +341,12 @@ sub hideCookie { ...@@ -341,8 +341,12 @@ sub hideCookie {
my ( $class, $req ) = @_; my ( $class, $req ) = @_;
$class->logger->debug("removing cookie"); $class->logger->debug("removing cookie");
my $cookie = $req->env->{HTTP_COOKIE}; my $cookie = $req->env->{HTTP_COOKIE};
$class->logger->debug("Cookies -> $cookie");
my $cn = $class->tsv->{cookieName}; my $cn = $class->tsv->{cookieName};
$cookie =~ s/$cn(http)?=[^,;]*[,;\s]*//og; $class->logger->debug("CookieName -> $cn");
$cookie =~ s/\b$cn(http)?=[^,;]*[,;\s]*//og;
$class->logger->debug("newCookies -> $cookie");
if ($cookie) { if ($cookie) {
$class->set_header_in( $req, 'Cookie' => $cookie ); $class->set_header_in( $req, 'Cookie' => $cookie );
} }
...@@ -405,8 +409,8 @@ sub fetchId { ...@@ -405,8 +409,8 @@ sub fetchId {
: $class->tsv->{https}->{_} : $class->tsv->{https}->{_}
); );
my $cn = $class->tsv->{cookieName}; my $cn = $class->tsv->{cookieName};
my $value = my $value
$lookForHttpCookie = $lookForHttpCookie
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 ) ? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 ); : ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
...@@ -437,8 +441,8 @@ sub retrieveSession { ...@@ -437,8 +441,8 @@ sub retrieveSession {
# (15 seconds) # (15 seconds)
if ( defined $class->data->{_session_id} if ( defined $class->data->{_session_id}
and $id eq $class->data->{_session_id} and $id eq $class->data->{_session_id}
and ( $now - $class->dataUpdate < $class->tsv->{handlerInternalCache} ) and
) ( $now - $class->dataUpdate < $class->tsv->{handlerInternalCache} ) )
{ {
$class->logger->debug("Get session $id from Handler internal cache"); $class->logger->debug("Get session $id from Handler internal cache");
return $class->data; return $class->data;
...@@ -447,8 +451,7 @@ sub retrieveSession { ...@@ -447,8 +451,7 @@ sub retrieveSession {
# 2. Get the session from cache or backend # 2. Get the session from cache or backend
my $session = $req->data->{session} = ( my $session = $req->data->{session} = (
Lemonldap::NG::Common::Session->new( Lemonldap::NG::Common::Session->new(
{ { storageModule => $class->tsv->{sessionStorageModule},
storageModule => $class->tsv->{sessionStorageModule},
storageModuleOptions => $class->tsv->{sessionStorageOptions}, storageModuleOptions => $class->tsv->{sessionStorageOptions},
cacheModule => $class->tsv->{sessionCacheModule}, cacheModule => $class->tsv->{sessionCacheModule},
cacheModuleOptions => $class->tsv->{sessionCacheOptions}, cacheModuleOptions => $class->tsv->{sessionCacheOptions},
...@@ -465,11 +468,12 @@ sub retrieveSession { ...@@ -465,11 +468,12 @@ sub retrieveSession {
# Verify that session is valid # Verify that session is valid
$class->logger->error( $class->logger->error(
"_utime is not defined. This should not happen. Check if it is well transmitted to handler" "_utime is not defined. This should not happen. Check if it is well transmitted to handler"
) unless $session->data->{_utime}; ) unless $session->data->{_utime};
$class->logger->debug("Check session validity from Handler"); $class->logger->debug("Check session validity from Handler");
$class->logger->debug( "Session timeout -> " . $class->tsv->{timeout} ); $class->logger->debug(
"Session timeout -> " . $class->tsv->{timeout} );
$class->logger->debug( "Session timeoutActivity -> " $class->logger->debug( "Session timeoutActivity -> "
. $class->tsv->{timeoutActivity} . $class->tsv->{timeoutActivity}
. "s" ) . "s" )
...@@ -489,8 +493,7 @@ sub retrieveSession { ...@@ -489,8 +493,7 @@ sub retrieveSession {
my $ttl = $class->tsv->{timeout} - $now + $session->data->{_utime}; my $ttl = $class->tsv->{timeout} - $now + $session->data->{_utime};
$class->logger->debug( "Session TTL = " . $ttl ); $class->logger->debug( "Session TTL = " . $ttl );
if ( if ($now - $session->data->{_utime} > $class->tsv->{timeout}
$now - $session->data->{_utime} > $class->tsv->{timeout}
or ( $class->tsv->{timeoutActivity} or ( $class->tsv->{timeoutActivity}
and $session->data->{_lastSeen} and $session->data->{_lastSeen}
and $delta > $class->tsv->{timeoutActivity} ) and $delta > $class->tsv->{timeoutActivity} )
...@@ -504,10 +507,9 @@ sub retrieveSession { ...@@ -504,10 +507,9 @@ sub retrieveSession {
} }
# Update the session to notify activity, if necessary # Update the session to notify activity, if necessary
if ( if ($class->tsv->{timeoutActivity}
$class->tsv->{timeoutActivity} and ( $now - $session->data->{_lastSeen}
and ( $now - $session->data->{_lastSeen} > > $class->tsv->{timeoutActivityInterval} )
$class->tsv->{timeoutActivityInterval} )
) )
{ {
$req->data->{session}->update( { '_lastSeen' => $now } ); $req->data->{session}->update( { '_lastSeen' => $now } );
...@@ -546,8 +548,8 @@ sub _buildUrl { ...@@ -546,8 +548,8 @@ sub _buildUrl {
? $class->tsv->{https}->{$vhost} ? $class->tsv->{https}->{$vhost}
: $class->tsv->{https}->{_} : $class->tsv->{https}->{_}
); );
my $portString = my $portString
$class->tsv->{port}->{$vhost} = $class->tsv->{port}->{$vhost}
|| $class->tsv->{port}->{_} || $class->tsv->{port}->{_}
|| $req->{env}->{SERVER_PORT}; || $req->{env}->{SERVER_PORT};
$portString = ( $portString = (
...@@ -569,8 +571,8 @@ sub isUnprotected { ...@@ -569,8 +571,8 @@ sub isUnprotected {
my ( $class, $req, $uri ) = @_; my ( $class, $req, $uri ) = @_;
my $vhost = $class->resolveAlias($req); my $vhost = $class->resolveAlias($req);
for ( for (
my $i = 0 ; my $i = 0;
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 ) ; $i < ( $class->tsv->{locationCount}->{$vhost} || 0 );
$i++ $i++
) )
{ {
...@@ -589,8 +591,8 @@ sub sendHeaders { ...@@ -589,8 +591,8 @@ sub sendHeaders {
if ( defined $class->tsv->{forgeHeaders}->{$vhost} ) { if ( defined $class->tsv->{forgeHeaders}->{$vhost} ) {
# Log headers in debug mode # Log headers in debug mode
my %headers = my %headers
$class->tsv->{forgeHeaders}->{$vhost}->( $req, $session ); = $class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
foreach my $h ( sort keys %headers ) { foreach my $h ( sort keys %headers ) {
if ( defined( my $v = $headers{$h} ) ) { if ( defined( my $v = $headers{$h} ) ) {
$class->logger->debug("Send header $h with value $v"); $class->logger->debug("Send header $h with value $v");
...@@ -695,8 +697,8 @@ sub postOutputFilter { ...@@ -695,8 +697,8 @@ sub postOutputFilter {
$class->logger->debug("Filling a html form with fake data"); $class->logger->debug("Filling a html form with fake data");
$class->unset_header_in( $req, "Accept-Encoding" ); $class->unset_header_in( $req, "Accept-Encoding" );
my %postdata = my %postdata = $class->tsv->{outputPostData}->{$vhost}->{$uri}
$class->tsv->{outputPostData}->{$vhost}->{$uri}->( $req, $session ); ->( $req, $session );
my $formParams = $class->tsv->{postFormParams}->{$vhost}->{$uri}; my $formParams = $class->tsv->{postFormParams}->{$vhost}->{$uri};
my $js = $class->postJavascript( $req, \%postdata, $formParams ); my $js = $class->postJavascript( $req, \%postdata, $formParams );
$class->addToHtmlHead( $req, $js ); $class->addToHtmlHead( $req, $js );
...@@ -713,8 +715,8 @@ sub postInputFilter { ...@@ -713,8 +715,8 @@ sub postInputFilter {
if ( defined( $class->tsv->{inputPostData}->{$vhost}->{$uri} ) ) { if ( defined( $class->tsv->{inputPostData}->{$vhost}->{$uri} ) ) {
$class->logger->debug("Replacing fake data with real form data"); $class->logger->debug("Replacing fake data with real form data");
my %data = my %data = $class->tsv->{inputPostData}->{$vhost}->{$uri}
$class->tsv->{inputPostData}->{$vhost}->{$uri}->( $req, $session ); ->( $req, $session );
foreach ( keys %data ) { foreach ( keys %data ) {
$data{$_} = uri_escape( $data{$_} ); $data{$_} = uri_escape( $data{$_} );
} }
...@@ -734,18 +736,19 @@ sub postJavascript { ...@@ -734,18 +736,19 @@ sub postJavascript {
foreach my $name ( keys %$data ) { foreach my $name ( keys %$data ) {
use bytes; use bytes;
my $value = "x" x bytes::length( $data->{$name} ); my $value = "x" x bytes::length( $data->{$name} );
$filler .= $filler
"form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n"; .= "form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
} }
my $submitter = my $submitter
$formParams->{buttonSelector} eq "none" ? "" = $formParams->{buttonSelector} eq "none" ? ""
: $formParams->{buttonSelector} : $formParams->{buttonSelector}
? "form.find('$formParams->{buttonSelector}').click();\n" ? "form.find('$formParams->{buttonSelector}').click();\n"
: "form.submit();\n"; : "form.submit();\n";
my $jqueryUrl = $formParams->{jqueryUrl} || ""; my $jqueryUrl = $formParams->{jqueryUrl} || "";
$jqueryUrl = &{ $class->tsv->{portal} } . "skins/common/js/jquery-1.10.2.js" $jqueryUrl
= &{ $class->tsv->{portal} } . "skins/common/js/jquery-1.10.2.js"
if ( $jqueryUrl eq "default" ); if ( $jqueryUrl eq "default" );
$jqueryUrl = "<script type='text/javascript' src='$jqueryUrl'></script>\n" $jqueryUrl = "<script type='text/javascript' src='$jqueryUrl'></script>\n"
if ($jqueryUrl); if ($jqueryUrl);
......
...@@ -67,8 +67,11 @@ sub handler { ...@@ -67,8 +67,11 @@ sub handler {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
my $hdrs = $req->{respHeaders}; my $hdrs = $req->{respHeaders};
$req->{respHeaders} = []; $req->{respHeaders} = [];
my $cookie = $req->env->{HTTP_COOKIE};
my $cn = $self->Lemonldap::NG::Handler::Main::tsv->{cookieName};
$cookie =~ s/\b$cn(http)?=[^,;]*[,;\s]*//og;
my @convertedHdrs = my @convertedHdrs =
( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) ); ( 'Content-Length' => 0, Cookie => ( $cookie // '' ) );
my $i = 0; my $i = 0;
while ( my $k = shift @$hdrs ) { while ( my $k = shift @$hdrs ) {
my $v = shift @$hdrs; my $v = shift @$hdrs;
......
package Lemonldap::NG::Manager::Cli; package Lemonldap::NG::Manager::Cli;
use strict; use strict;
use Crypt::URandom;
use Mouse; use Mouse;
use Data::Dumper; use Data::Dumper;
use Lemonldap::NG::Common::Conf::ReConstants; use Lemonldap::NG::Common::Conf::ReConstants;
...@@ -254,8 +255,9 @@ sub _save { ...@@ -254,8 +255,9 @@ sub _save {
$new->{cfgDate} = time; $new->{cfgDate} = time;
$new->{cfgVersion} = $VERSION; $new->{cfgVersion} = $VERSION;
$new->{cfgLog} = ''; $new->{cfgLog} = '';
$new->{key} ||= $new->{key} ||= join( '',
join( '', map { chr( int( rand(94) ) + 33 ) } ( 1 .. 16 ) ); map { chr( int( ord( Crypt::URandom::urandom(1) ) * 94 / 256 ) + 33 ) }
( 1 .. 16 ) );
my $s = $self->mgr->confAcc->saveConf( $new, %$saveParams ); my $s = $self->mgr->confAcc->saveConf( $new, %$saveParams );
if ( $s > 0 ) { if ( $s > 0 ) {
......
...@@ -20,6 +20,7 @@ package Lemonldap::NG::Manager::Conf::Parser; ...@@ -20,6 +20,7 @@ package Lemonldap::NG::Manager::Conf::Parser;