Типа я (zilogic) wrote in changelog,
Типа я
zilogic
changelog

[livejournal] r19644: LJSUP-9428: Add sign to ljmastersession ...

Committer: amyshkin
LJSUP-9428: Add sign to ljmastersession cookie
U   trunk/cgi-bin/LJ/Session.pm
Modified: trunk/cgi-bin/LJ/Session.pm
===================================================================
--- trunk/cgi-bin/LJ/Session.pm	2011-08-09 03:48:27 UTC (rev 19643)
+++ trunk/cgi-bin/LJ/Session.pm	2011-08-09 03:54:27 UTC (rev 19644)
@@ -10,6 +10,7 @@
 use Digest::MD5;
 use Data::Dumper;
 use constant VERSION => 1;
+use constant MASTER_VERSION => 2;
 
 # NOTES
 #
@@ -254,11 +255,13 @@
 sub master_cookie_string {
     my $sess = shift;
 
-    my $ver = VERSION;
+    my $ver    = MASTER_VERSION;
+    my $sig    = master_signature($sess);
     my $cookie = "v$ver:" .
         "u$sess->{userid}:" .
         "s$sess->{sessid}:" .
-        "a$sess->{auth}";
+        "a$sess->{auth}:" .
+        "g$sig";
 
     if ($sess->{flags}) {
         $cookie .= ":f$sess->{flags}";
@@ -720,7 +723,7 @@
     my $old_cookie = delete $opts->{old_cookie} ? 1 : 0;
 
     delete $opts->{'redirect_ref'};  # we don't use this
-    croak("Unknown options") if %$opts;
+    croak("Unknown options: " . join(', ', keys(%$opts))) if %$opts;
 
     my $now = time();
 
@@ -732,7 +735,6 @@
   COOKIE:
     foreach my $sessdata (@cookies) {
         my ($cookie, $gen) = split(m!//!, $sessdata);
-
         my ($version, $userid, $sessid, $auth, $flags, $sig);
 
         my $dest = {
@@ -746,9 +748,10 @@
 
         my $bogus = 0;
         foreach my $var (split /:/, $cookie) {
-            if ($var =~ /^(\w)(.+)$/ && $dest->{$1}) {
+            if ( $var =~ /^(\w)(.+)$/ && $dest->{$1} ) {
                 ${$dest->{$1}} = $2;
-            } else {
+            }
+            else {
                 $bogus = 1;
             }
         }
@@ -765,12 +768,6 @@
             push @$errs, "$sessdata: $_[0]";
         };
 
-        # fail unless version matches current
-        unless ($version == VERSION) {
-            $err->("no ws auth");
-            next COOKIE;
-        }
-
         my $u = LJ::load_userid($userid);
         unless ($u) {
             $err->("user doesn't exist");
@@ -810,6 +807,25 @@
                 next COOKIE;
             }
         }
+
+        # current cookie version
+        if ( $version == MASTER_VERSION ) {
+            unless ( $sig eq master_signature($sess) ) {
+                $err->("wrong master cookie signature");
+                next COOKIE;
+            }
+        }
+        # prev cookie version
+        elsif ( $version == MASTER_VERSION - 1 ) {
+            # don't check signature
+            # it will work for a some time
+        }
+        # all other cookie must fail
+        else {
+            $err->("no ws auth");
+            next COOKIE;
+        }
+
         last COOKIE;
     }
 
@@ -961,6 +977,17 @@
     return "http://$host$uri$args_wq";
 }
 
+sub master_signature {
+    my ($sess) = @_;
+    my $u      = $sess->owner;
+    my $secret = $LJ::MASTER_COOKIE_SALT;
+
+    my $data = join("-", $sess->{auth}, $u->{userid}, $sess->{sessid});
+    my $sig  = hmac_sha1_hex($data, $secret);
+
+    return $sig;
+}
+
 sub domsess_signature {
     my ($time, $sess, $domcook) = @_;
 

Tags: livejournal, pm, zilogic
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments