diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/CAS.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/CAS.pm index 16a724c3a6b14dc65238cc133d854ba7092da6b2..47dfd8908ea32df5b5576f2cf584643988bb66e3 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/CAS.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/CAS.pm @@ -198,8 +198,7 @@ sub extractFormInfo { $req->{urldc} = $login_url; $req->steps( [] ); $req->addCookie( - $self->p->genCookie( - $req, + $self->p->cookie( name => 'llngcasserver', value => $srv, secure => $self->conf->{securedCookie}, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Twitter.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Twitter.pm index 205a646680eddb1d59e4d73390836ce74773e798..6a71d682f8b53a3578ee8159731e124275e139cd 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Twitter.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Twitter.pm @@ -126,8 +126,7 @@ sub extractFormInfo { # 1.2 Store token key and secret in cookies (available 180s) $req->addCookie( - $self->p->genCookie( - $req, + $self->p->cookie( name => '_twitSec', value => $response->token_secret, max_age => 180, @@ -170,7 +169,7 @@ sub extractFormInfo { signature_method => 'HMAC-SHA1', verifier => $verifier, token => $request_token, - token_secret => $self->p->genCookie( $req, name => '_twitSec' ), + token_secret => $self->p->cookie( name => '_twitSec' ), timestamp => time, nonce => $nonce, ); @@ -211,8 +210,7 @@ sub extractFormInfo { # Clean temporaries cookies $req->addCookie( - $self->p->genCookie( - $req, + $self->cookie( name => '_twitSec', value => 0, expires => 'Wed, 21 Oct 2015 00:00:00 GMT' diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/JSON.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/JSON.pm index 87a92fa702f3e96dd178ceb90519064fef84b66b..81e8a9ab7f82bac024a6d55ccf670040f465bee4 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/JSON.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/JSON.pm @@ -184,7 +184,7 @@ sub getNotifBack { if ( $req->param('cancel') ) { $self->logger->debug('Cancel called -> remove ciphered cookie'); $req->addCookie( - $self->p->genCookie( + $self->p->genDomainCookie( $req, name => $self->conf->{cookieName}, value => 0, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/XML.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/XML.pm index b93b8aa31e26c6fc48532164c5a4254656daae46..65d4db15aae82620c24157c55a6be81d39c30a7f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/XML.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Notifications/XML.pm @@ -242,7 +242,7 @@ sub getNotifBack { if ( $req->param('cancel') ) { $self->logger->debug('Cancel called -> remove ciphered cookie'); $req->addCookie( - $self->p->genCookie( + $self->p->genDomainCookie( $req, name => $self->conf->{cookieName}, value => 0, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm index 59eac87bac65615a4b61c984994c66dce9670243..4d83ec3b06b4ef51f20d0c88443aae7e094b06c6 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Process.pm @@ -409,7 +409,7 @@ sub extractFormInfo { and $req->cookies->{ $self->conf->{cookieName} } ) { $req->addCookie( - $self->genCookie( + $self->genDomainCookie( $req, name => $self->conf->{cookieName}, value => 0, @@ -601,8 +601,8 @@ sub store { my $session = $self->getApacheSession( $req->id, hashStore => $req->data->{hashStore}, - force => $req->{force}, - info => $infos + force => $req->{force}, + info => $infos ); return PE_APACHESESSIONERROR unless $session; @@ -630,7 +630,7 @@ sub buildCookie { my ( $self, $req ) = @_; if ( $req->id ) { $req->addCookie( - $self->genCookie( + $self->genDomainCookie( $req, name => $self->conf->{cookieName}, value => $req->id, @@ -639,7 +639,7 @@ sub buildCookie { ); if ( $self->conf->{securedCookie} >= 2 ) { $req->addCookie( - $self->genCookie( + $self->genDomainCookie( $req, name => $self->conf->{cookieName} . "http", value => $req->{sessionInfo}->{_httpSession}, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 1174e1ef29fa563a68b43139dcebd8e9ebcf3494..02f294a59f4ee60014bc624384c45db673fab6cd 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -93,21 +93,41 @@ sub handler { # Save pdata if ( $sp or %{ $req->pdata } ) { - my %v = ( - name => $self->conf->{cookieName} . 'pdata', - secure => $self->conf->{securedCookie}, - ( - %{ $req->pdata } - ? ( value => uri_escape( JSON::to_json( $req->pdata ) ) ) - : ( value => '', expires => 'Wed, 21 Oct 2015 00:00:00 GMT' ) - ), - ( - $self->conf->{pdataDomain} - ? ( domain => $self->conf->{pdataDomain}, ) - : () - ), - ); - push @{ $res->[1] }, 'Set-Cookie', $self->genCookie( $req, %v ); + my %pdata_options = (); + $pdata_options{domain} = $self->conf->{pdataDomain} + if $self->conf->{pdataDomain}; + + if ( %{ $req->pdata } ) { + push @{ $res->[1] }, 'Set-Cookie', + $self->cookie( + name => $self->conf->{cookieName} . 'pdata', + secure => $self->conf->{securedCookie}, + value => uri_escape( JSON::to_json( $req->pdata ) ), + %pdata_options, + ); + + } + else { + push @{ $res->[1] }, 'Set-Cookie', + $self->cookie( + name => $self->conf->{cookieName} . 'pdata', + secure => $self->conf->{securedCookie}, + value => '', + expires => 'Wed, 21 Oct 2015 00:00:00 GMT', + %pdata_options, + ); + + # Avoid regressions with #3228 + push @{ $res->[1] }, 'Set-Cookie', + $self->genDomainCookie( + $req, + name => $self->conf->{cookieName} . 'pdata', + secure => $self->conf->{securedCookie}, + value => '', + expires => 'Wed, 21 Oct 2015 00:00:00 GMT', + %pdata_options, + ); + } } return $res; } @@ -240,7 +260,7 @@ sub processRefreshSession { # Avoid interferences when refresh is run on multiple sessions # in the same request - $req->sessionInfo({}); + $req->sessionInfo( {} ); $req->steps( [ 'getUser', @{ $self->betweenAuthAndData }, @@ -313,7 +333,7 @@ sub _unauthLogout { $self->logger->debug("Removing $self->{conf}->{cookieName} cookie"); $req->pdata( {} ); $req->addCookie( - $self->genCookie( + $self->genDomainCookie( $req, name => $self->conf->{cookieName}, secure => $self->conf->{securedCookie}, @@ -732,7 +752,7 @@ sub _deleteSession { # Create an obsolete cookie to remove it $req->addCookie( - $self->genCookie( + $self->genDomainCookie( $req, name => $self->conf->{cookieName} . 'http', value => 0, @@ -747,7 +767,7 @@ sub _deleteSession { # Create an obsolete cookie to remove it $req->addCookie( - $self->genCookie( + $self->genDomainCookie( $req, name => $self->conf->{cookieName}, value => 0, @@ -926,18 +946,23 @@ sub fullUrl { } # Generates a cookie header which can depend on the request +# If no domain was explicitely specified, use the default SSO domain +sub genDomainCookie { + my ( $self, $req, %h ) = @_; + + $h{domain} ||= $self->getCookieDomain($req); + return $self->cookie(%h); +} + +# DEPRECATED, #3228 sub genCookie { my ( $self, $req, %h ) = @_; - $h{path} ||= '/'; - $h{HttpOnly} //= $self->conf->{httpOnly}; - $h{max_age} //= $self->conf->{cookieExpiration} - if ( $self->conf->{cookieExpiration} ); - $h{SameSite} ||= $self->cookieSameSite; - $h{domain} ||= $self->getCookieDomain($req); - return $self->assemble_cookie(%h); + return $self->cookie(%h); } -# Deprecated method, does not handle dynamic portal URL +# Generate a cookie header +# If no domain was explicitely specified, only the portal will see +# this cookie sub cookie { my ( $self, %h ) = @_; $h{path} ||= '/'; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/RememberAuthChoice.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/RememberAuthChoice.pm index b864e27a74f8364ea903984a3233872e1f1ba949..0f5cab00f5377e6355ece62f4d67c3120a49fe63 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/RememberAuthChoice.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/RememberAuthChoice.pm @@ -76,8 +76,7 @@ sub storeRememberedAuthChoice { . " with authentication choice lmAuth=" . $lmAuth ); $req->addCookie( - $self->p->genCookie( - $req, + $self->p->cookie( name => $self->rememberCookieName, value => $lmAuth, max_age => $self->rememberCookieTimeout, @@ -94,7 +93,17 @@ sub storeRememberedAuthChoice { . $self->rememberCookieName ); $req->addCookie( - $self->p->genCookie( + $self->p->cookie( + name => $self->rememberCookieName, + value => 0, + expires => 'Wed, 21 Oct 2015 00:00:00 GMT', + secure => $self->conf->{securedCookie}, + ) + ); + + # Avoid regressions with #3228 + $req->addCookie( + $self->p->genDomainCookie( $req, name => $self->rememberCookieName, value => 0, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/TrustedBrowser.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/TrustedBrowser.pm index 1cf1ee710f9c2c7bd959fc415c4ef9aebc9272ec..6a9e716f7df514a74030ef45059f9fd10acc19c3 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/TrustedBrowser.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/TrustedBrowser.pm @@ -194,8 +194,7 @@ sub storeBrowser { # Cookie available 30 days by default $req->addCookie( - $self->p->genCookie( - $req, + $self->p->cookie( name => $self->cookieName, value => $ps->id, max_age => $self->timeout, @@ -404,7 +403,17 @@ sub removeCookie { my ( $self, $req ) = @_; $req->addCookie( - $self->p->genCookie( + $self->p->cookie( + name => $self->cookieName, + value => 0, + expires => 'Wed, 21 Oct 2015 00:00:00 GMT', + secure => $self->conf->{securedCookie}, + ) + ); + + # Avoid regressions with #3228 + $req->addCookie( + $self->p->genDomainCookie( $req, name => $self->cookieName, value => 0, diff --git a/lemonldap-ng-portal/t/01-Cookie-Domain.t b/lemonldap-ng-portal/t/01-Cookie-Domain.t index 502ba2f43c1d0515cd8e8d75b5d36e615662db46..da10a2c75e2b82a6a0363b136da5949f99e3abde 100644 --- a/lemonldap-ng-portal/t/01-Cookie-Domain.t +++ b/lemonldap-ng-portal/t/01-Cookie-Domain.t @@ -18,7 +18,7 @@ sub assertCookieValue { sub assertGenCookieValue { local $Test::Builder::Level = $Test::Builder::Level + 1; my ( $client, $req, $opts, $expected ) = @_; - my $result = $client->p->genCookie( $req, %$opts ); + my $result = $client->p->genDomainCookie( $req, %$opts ); my $str = join( ',', map { "$_=$opts->{$_}" } sort keys %$opts ); is( $result, $expected, "Correct cookie result for $str" ); } diff --git a/lemonldap-ng-portal/t/01-pdata.t b/lemonldap-ng-portal/t/01-pdata.t index 78f5217bdeb92845542b4283e861066670e9a89f..03762d46e812a8e83cc9343bc8f334da74ab2d92 100644 --- a/lemonldap-ng-portal/t/01-pdata.t +++ b/lemonldap-ng-portal/t/01-pdata.t @@ -3,14 +3,14 @@ use Test::More; use strict; use IO::String; use URI::Escape; +use Plack::Response; require 't/test-lib.pm'; my $res; my $tmp; -my $client = LLNG::Manager::Test->new( - { +my $client = LLNG::Manager::Test->new( { ini => { logLevel => 'error', customPlugins => 't::pdata', @@ -21,6 +21,14 @@ my $client = LLNG::Manager::Test->new( # Two simple access to see if pdata is set and restored ok( $res = $client->_get( '/', ), 'Simple access' ); $tmp = expectCookie( $res, 'lemonldappdata' ); + +unlike( + Plack::Response->new(@$res)->headers->header('Set-Cookie'), + qr/lemonldappdata=[^,]*domain=/, + "Domain not set in pdata cookie" +); +count(1); + ok( $tmp eq uri_escape('{"mytest":1}'), 'Pdata is {"mytest":1}' ) or explain( $tmp, uri_escape('{"mytest":1}') ); count(2); @@ -28,6 +36,12 @@ count(2); ok( $res = $client->_get( '/', cookie => 'lemonldappdata=' . $tmp, ), 'Second simple access' ); $tmp = expectCookie( $res, 'lemonldappdata' ); +unlike( + Plack::Response->new(@$res)->headers->header('Set-Cookie'), + qr/lemonldappdata=[^,]*domain=/, + "Domain not set in pdata cookie" +); +count(1); ok( $tmp eq uri_escape('{"mytest":2}'), 'Pdata is {"mytest":2}' ) or explain( $tmp, uri_escape('{"mytest":2}') ); count(2); diff --git a/lemonldap-ng-portal/t/64-StayConnected.t b/lemonldap-ng-portal/t/64-StayConnected.t index 6aeac8c470acfb64824155d9a1a2562ebd8519c8..a82975ec4ffac2e421a298d875934e070099ee19 100644 --- a/lemonldap-ng-portal/t/64-StayConnected.t +++ b/lemonldap-ng-portal/t/64-StayConnected.t @@ -2,11 +2,11 @@ use warnings; use Test::More; use strict; use IO::String; +use Plack::Response; require 't/test-lib.pm'; -my $client = LLNG::Manager::Test->new( - { +my $client = LLNG::Manager::Test->new( { ini => { logLevel => 'error', useSafeJail => 1, @@ -48,6 +48,11 @@ subtest "Register session, use it, then logout" => sub { my $id = expectCookie($res); expectRedirection( $res, 'http://auth.example.com/' ); my $cid = expectCookie( $res, 'llngpersistent' ); + unlike( + Plack::Response->new(@$res)->headers->header('Set-Cookie'), + qr/llngpersistent=[^,]*domain=/, + "Domain not set in stayconnected cookie" + ); ok( $res->[1]->[5] =~ /\bsecure\b/, ' Secure cookie found' ) or explain( $res->[1]->[5], 'Secure cookie found' ); @@ -115,6 +120,11 @@ subtest "Make sure connection ID is saved on first login too" => sub { my $id = expectCookie($res); expectRedirection( $res, 'http://auth.example.com/' ); my $cid = expectCookie( $res, 'llngpersistent' ); + unlike( + Plack::Response->new(@$res)->headers->header('Set-Cookie'), + qr/llngpersistent=[^,]*domain=/, + "Domain not set in stayconnected cookie" + ); ok( $res->[1]->[5] =~ /\bsecure\b/, ' Secure cookie found' ) or explain( $res->[1]->[5], 'Secure cookie found' );