changeset 239:23daf2fae33a

*security subsytem bugfixes *HttpResponse: cookies which values are set to undefined will be deleted from browser
author sergey
date Tue, 16 Oct 2012 20:14:11 +0400
parents b8c724f6de36
children abc7c26bf615
files Lib/IMPL/Security/Auth/Simple.pm Lib/IMPL/Web/Handler/SecureCookie.pm Lib/IMPL/Web/HttpResponse.pm Lib/IMPL/Web/Security.pm
diffstat 4 files changed, 82 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/Security/Auth/Simple.pm	Tue Oct 16 01:33:06 2012 +0400
+++ b/Lib/IMPL/Security/Auth/Simple.pm	Tue Oct 16 20:14:11 2012 +0400
@@ -62,7 +62,7 @@
             $this->_stage(STAGE_DONE);
         }
         return (AUTH_SUCCESS, undef);
-    } elsee {
+    } else {
         return (AUTH_FAIL, undef);
     }
 }
--- a/Lib/IMPL/Web/Handler/SecureCookie.pm	Tue Oct 16 01:33:06 2012 +0400
+++ b/Lib/IMPL/Web/Handler/SecureCookie.pm	Tue Oct 16 20:14:11 2012 +0400
@@ -43,7 +43,7 @@
         
     my $sid = $action->cookie('sid',qr/(\w+)/); 
     my $cookie = $action->cookie('sdata',qr/(\w+)/);
-    my $sign = $action->cookie('sign',qw/(\w+)/); 
+    my $sign = $action->cookie('sign',qw/(\w+)/);
     
     if (
         $sid and
@@ -58,15 +58,16 @@
     ) {
         # TODO: add a DefferedProxy to deffer a request to a data source
         if ( $context = $this->_manager->GetSession($sid) ) {
-        
             if ( eval { $context->auth->isa(AuthSimple) } ) {
                 my ($result,$challenge) = $context->auth->DoAuth($cookie);
-                
-                $action->_manager->SaveSession($context);
-                
+ 
+                $context->authority($this);
+
                 if ($result == AUTH_FAIL) {
                     $context = undef;
                 }
+            } else {
+            	undef $context;
             }
         }
         
@@ -83,27 +84,46 @@
 }
 
 sub InitSession {
-    my ($this,$user,$auth,$roles) = @_;
+    my ($this,$user,$roles,$auth,$challenge) = @_;
     
-    my $sid = GenSSID();
-    my $cookie = GenSSID();
+    my ($status,$answer) = $auth->DoAuth($challenge);
+    
+    die OperationException->new("This provider doesn't support multiround auth")
+        if ($status == AUTH_INCOMPLETE || $answer);
     
-    $this->_cookies({
-        sid => $sid,
-        sdata => $cookie
-    });
+    if ($status == AUTH_SUCCESS) {
+	    my $sid = GenSSID();
+	    my $cookie = GenSSID();
+	    
+	    $this->_cookies({
+	        sid => $sid,
+	        sdata => $cookie
+	    });
+	    
+	    my $context = $this->_manager->CreateSession(
+	        sessionId => $sid,
+	        principal => $user,
+	        auth => AuthSimple->Create(password => $cookie),
+	        authority => $this,
+	        rolesAssigned => $roles
+	    );
+	    
+	    $context->Apply();
+	    
+	    $this->_manager->SaveSession($context);
+    }
+    
+    return $status;
+}
 
-    my $context = $this->_manager->CreateSession(
-        sessionId => $sid,
-        principal => $user,
-        auth => AuthSimple->Create(password => $cookie),
-        authority => $this,
-        assignedRoles => $roles
-    );
-    
-    $context->Apply();
-    
-    return $context;
+sub CloseSession {
+	my ($this) = @_;
+	if(my $session = SecurityContext->current) {
+        $this->_cookies({
+	        sid => undef,
+	        sdata => undef
+        })	
+	}
 }
 
 sub WriteResponse {
@@ -111,7 +131,7 @@
     
     if (my $data = $this->_cookies) {
 
-        my $sign = md5_hex(
+        my $sign = $data->{sid} && md5_hex(
             $this->salt,
             $data->{sid},
             $data->{sdata},
--- a/Lib/IMPL/Web/HttpResponse.pm	Tue Oct 16 01:33:06 2012 +0400
+++ b/Lib/IMPL/Web/HttpResponse.pm	Tue Oct 16 20:14:11 2012 +0400
@@ -61,7 +61,12 @@
 
 #used to map a pair name valie to a valid cookie object
 sub _createCookie {
-    return UNIVERSAL::isa($_[1], 'CGI::Cookie') ? $_[1] : CGI::Cookie->new(-name => $_[0], -value => $_[1] );
+    return UNIVERSAL::isa($_[1], 'CGI::Cookie')
+        ? $_[1]
+        : ( defined $_[1]
+            ? CGI::Cookie->new(-name => $_[0], -value => $_[1] )
+            : CGI::Cookie->new(-name => $_[0], -expires => '-1d', -value => '')
+        );
 }
 
 sub InternalError {
--- a/Lib/IMPL/Web/Security.pm	Tue Oct 16 01:33:06 2012 +0400
+++ b/Lib/IMPL/Web/Security.pm	Tue Oct 16 20:14:11 2012 +0400
@@ -13,7 +13,9 @@
 use constant {
     ERR_NO_SUCH_USER => -1,
     ERR_NO_SEC_DATA => -2,
-    ERR_AUTH_FAIL => -3
+    ERR_NO_AUTHORITY => -3,
+    ERR_NO_SEC_CONTEXT => -4,
+    ERR_AUTH_FAIL => -5
 };
 
 sub AuthUser {
@@ -24,7 +26,7 @@
             status => AUTH_FAIL,
             code => ERR_NO_SUCH_USER
         };
-    
+
     my $auth;
     if ( my $secData = $user->GetSecData($package) ) {
         $auth = $package->new($secData);
@@ -36,10 +38,21 @@
         };
     }
     
+    return {
+    	status => AUTH_FAIL,
+    	code => ERR_NO_SEC_CONTEXT
+    } unless SecurityContext->current;
+    
+    return {
+    	status => AUTH_FAIL,
+    	code => ERR_NO_AUTHORITY
+    } unless SecurityContext->current->authority;
+
     my $status = SecurityContext->current->authority->InitSession(
         $user,
+        [$user->roles],
         $auth,
-        [$user->roles]
+        $challenge
     );
     
     return {
@@ -49,6 +62,17 @@
     };
 }
 
+sub Logout {
+	my ($this) = @_;
+	
+	my $session = SecurityContext->current;
+	if($session && $session->authority) {
+		$session->authority->CloseSession($session);
+		
+		$this->CloseSession($session);
+	}
+}
+
 sub FindUserByName {
     die NotImplementedException->new();
 }
@@ -65,6 +89,10 @@
     die NotImplementedException->new();
 }
 
+sub CloseSession {
+	die NotImplementedException->new();
+}
+
 1;
 
 __END__