{"thread":{"id":"11282","subject":"[PATCH] Authentication support for pserver","startedAt":"2007-12-14T04:08:51Z","lastAt":"2010-05-15T15:07:54Z","messageCount":25,"participants":["Ævar Arnfjörð Bjarmason","Junio C Hamano","Shawn O. Pearce","Martin Langhoff"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"63079","messageId":"87wsrhex4c.fsf@cpan.org","threadId":"11282","inReplyTo":null,"subject":"[PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avar@cpan.org","sentAt":"2007-12-14T04:08:51Z","receivedAt":"2007-12-14T04:08:51Z","isPatch":true,"sender":{"key":"avar@cpan.org","avatar":"https://gravatar.com/avatar/26a9abd89a6d76e77bbb1d1b6a5fc4714a6060dbf7862544cec4540305c9d9da?d=mp&s=160"},"body":"I've patched git-cvsserver so that it supports pserver authentication as\nopposed to only anonymous access. The patch itself works but I haven't\nupdated the relevant documentation or test cases and won't be able to do\nso until after the weekend so I'm submitting what I have for review on\nthe list.\n\nThe pserver user/password database is stored in the config file for each\nrepository because I didn't know where else to put it, for example:\n\navar@oe:/tmp/fleh$ cat /tmp/git-test.git/config \n[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = true\n\n[gitcvs]\n    enabled = 1\n\n[gitcvs.users]\n    avar = foobar\n    whee = whoo\n\nThe user can then login/checkout and do other operations with the\nuser/password set in the config file:\n\navar@oe:/tmp/fleh$ cvs -d:pserver:whee:whoo@localhost/tmp/git-test.git login\nLogging in to :pserver:whee@localhost:2401/tmp/git-test.git\navar@oe:/tmp/fleh$ cvs -d:pserver:whee:oops@localhost/tmp/git-test.git login\nLogging in to :pserver:whee@localhost:2401/tmp/git-test.git\nThe password supplied for user whee was incorrect\ncvs login: authorization failed: server localhost rejected access to\n    /tmp/git-test.git for user whee\n\n$ cvs -d:pserver:whee:whoo@localhost/tmp/git-test.git co master\ncvs checkout: Updating master\nU master/.emacs\n[...]\n\n\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex ecded3b..851383b 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -150,12 +150,32 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -273,7 +293,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1176,12 +1196,6 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n-    {\n-        print \"error 1 pserver access cannot commit\\n\";\n-        exit;\n-    }\n-\n     if ( -e $state->{CVSROOT} . \"/index\" )\n     {\n         $log->warn(\"file 'index' already exists in the git repository\");\n@@ -2107,6 +2121,41 @@ sub kopts_from_path\n     }\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same format has been used since\n+    # CVS was spawned\n+    $str =~ s/^(.)//;\n+    die \"invalid password format $1\" unless $1 eq 'A';\n+\n+    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n+\n+    return $str;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n"},{"id":"63088","messageId":"7vd4t9x2lw.fsf@gitster.siamese.dyndns.org","threadId":"11282","inReplyTo":"87wsrhex4c.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-14T05:32:59Z","receivedAt":"2007-12-14T05:32:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n\n> +    unless ($user eq 'anonymous') {\n> +        # Trying to authenticate a user\n> +        if (not exists $cfg->{gitcvs}->{users}) {\n> +            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n> +            print \"I HATE YOU\\n\";\n> +            exit 1;\n> +        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n> +            print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n> +            print \"I HATE YOU\\n\";\n> +            exit 1;\n> +        } else {\n> +            my $descrambled_password = descramble($password);\n> +            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n> +            if ($descrambled_password ne $cleartext_password) {\n> +                print \"E The password supplied for user $user was incorrect\\n\";\n> +                print \"I HATE YOU\\n\";\n> +                exit 1;\n> +            }\n\nI do not know what the real pserver does but by sending these E lines in\nthe latter two different forms back to the client you are leaking\nsensitive information, which is probably not what you want (the first\none is Ok, though.  It would help the server administrator to notice\nmisconfiguration, and until it is corrected nobody would be able to log\nin anyway).\n\nAdmittedly, the pserver password scrambling is not a real security, but\nif we were paranoid, we would probably be even adding random delay in\n\"no user found\" case and \"password does not match\" case, so that the\nclient cannot even tell from the response latency if a username exists\nat the server.\n\n> @@ -1176,12 +1196,6 @@ sub req_ci\n>  \n>      $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n>  \n> -    if ( $state->{method} eq 'pserver')\n> -    {\n> -        print \"error 1 pserver access cannot commit\\n\";\n> -        exit;\n> -    }\n> -\n\nIs this correct?  You are still allowing anonymous pserver access, so\nshouldn't you check if this was an anonymous access or authenticated one\nand refuse access like before for anonymous people?\n\n> +    my ($str) = @_;\n> +\n> +    # This should never happen, the same format has been used since\n> +    # CVS was spawned\n> +    $str =~ s/^(.)//;\n> +    die \"invalid password format $1\" unless $1 eq 'A';\n\nI do not quite understand what \"spawn\" means in this sentence.\n"},{"id":"63089","messageId":"20071214054427.GE14735@spearce.org","threadId":"11282","inReplyTo":"7vd4t9x2lw.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-12-14T05:44:27Z","receivedAt":"2007-12-14T05:44:27Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n> > +\n> > +    # This should never happen, the same format has been used since\n> > +    # CVS was spawned\n> > +    $str =~ s/^(.)//;\n> > +    die \"invalid password format $1\" unless $1 eq 'A';\n> \n> I do not quite understand what \"spawn\" means in this sentence.\n\nspawned: since it came from the depths of hell and cursed all\n         developers, until the day Git was born.  :-)\n\n-- \nShawn.\n"},{"id":"63112","messageId":"87mysdepeh.fsf@cpan.org","threadId":"11282","inReplyTo":"7vd4t9x2lw.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avar@cpan.org","sentAt":"2007-12-14T06:55:34Z","receivedAt":"2007-12-14T06:55:34Z","isPatch":true,"sender":{"key":"avar@cpan.org","avatar":"https://gravatar.com/avatar/26a9abd89a6d76e77bbb1d1b6a5fc4714a6060dbf7862544cec4540305c9d9da?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n>\n>> +    unless ($user eq 'anonymous') {\n>> +        # Trying to authenticate a user\n>> +        if (not exists $cfg->{gitcvs}->{users}) {\n>> +            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n>> +            print \"I HATE YOU\\n\";\n>> +            exit 1;\n>> +        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n>> +            print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n>> +            print \"I HATE YOU\\n\";\n>> +            exit 1;\n>> +        } else {\n>> +            my $descrambled_password = descramble($password);\n>> +            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n>> +            if ($descrambled_password ne $cleartext_password) {\n>> +                print \"E The password supplied for user $user was incorrect\\n\";\n>> +                print \"I HATE YOU\\n\";\n>> +                exit 1;\n>> +            }\n>\n> I do not know what the real pserver does but by sending these E lines in\n> the latter two different forms back to the client you are leaking\n> sensitive information, which is probably not what you want (the first\n> one is Ok, though.  It would help the server administrator to notice\n> misconfiguration, and until it is corrected nobody would be able to log\n> in anyway).\n\nI've commented out those two error messages, it now doesn't provide that\ninfo.\n\n> Admittedly, the pserver password scrambling is not a real security, but\n> if we were paranoid, we would probably be even adding random delay in\n> \"no user found\" case and \"password does not match\" case, so that the\n> client cannot even tell from the response latency if a username exists\n> at the server.\n>\n>> @@ -1176,12 +1196,6 @@ sub req_ci\n>>  \n>>      $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n>>  \n>> -    if ( $state->{method} eq 'pserver')\n>> -    {\n>> -        print \"error 1 pserver access cannot commit\\n\";\n>> -        exit;\n>> -    }\n>> -\n>\n> Is this correct?  You are still allowing anonymous pserver access, so\n> shouldn't you check if this was an anonymous access or authenticated one\n> and refuse access like before for anonymous people?\n\nNo it's not, oops. Fixed.\n\n>> +    my ($str) = @_;\n>> +\n>> +    # This should never happen, the same format has been used since\n>> +    # CVS was spawned\n>> +    $str =~ s/^(.)//;\n>> +    die \"invalid password format $1\" unless $1 eq 'A';\n>\n> I do not quite understand what \"spawn\" means in this sentence.\n\nShawn O. Pearce put it best but I've changed the comment to be more\nreadable to someone without a odd sense of humor:)\n\n\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex 258a62f..5ca84fc 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -69,9 +69,6 @@ plugin. Most functionality works fine with both of these clients.\n LIMITATIONS\n -----------\n \n-Currently cvsserver works over SSH connections for read/write clients, and\n-over pserver for anonymous CVS access.\n-\n CVS clients cannot tag, branch or perform GIT merges.\n \n git-cvsserver maps GIT branches to CVS modules. This is very different\n@@ -81,7 +78,7 @@ one or more directories.\n INSTALLATION\n ------------\n \n-1. If you are going to offer anonymous CVS access via pserver, add a line in\n+1. If you are going to offer CVS access via pserver, add a line in\n    /etc/inetd.conf like\n +\n --\n@@ -98,6 +95,22 @@ looks like\n    cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n \n ------\n+\n+Only anonymous access is provided by pserve by default. To commit you\n+will have to create pserver accounts, simply add a [gitcvs.users]\n+section to the repositories you want to access, for example:\n+\n+------\n+   \n+   [gitcvs.users]\n+        someuser = somepassword\n+        otheruser = otherpassword\n+   \n+------\n+Then provide your password via the pserver method, for example:\n+------\n+   cvs -d:pserver:someuser:somepassword@server/path/repo.git co <HEAD_name>\n+------\n No special setup is needed for SSH access, other than having GIT tools\n in the PATH. If you have clients that do not accept the CVS_SERVER\n environment variable, you can rename git-cvsserver to cvs.\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex ecded3b..9541049 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -150,12 +150,35 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                #print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n+    # For checking whether the user is anonymous on commit\n+    $state->{user} = $user;\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -273,7 +296,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1176,9 +1199,9 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n+    if ($state->{method} eq 'pserver' and $state->{user} eq 'anonymous')\n     {\n-        print \"error 1 pserver access cannot commit\\n\";\n+        print \"error 1 anonymous user cannot commit via pserver\\n\";\n         exit;\n     }\n \n@@ -2107,6 +2130,41 @@ sub kopts_from_path\n     }\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same password format (A) bas been\n+    # used by CVS since the beginnin of time\n+    $str =~ s/^(.)//;\n+    die \"invalid password format $1\" unless $1 eq 'A';\n+\n+    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n+\n+    return $str;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n"},{"id":"63122","messageId":"7vir31u210.fsf@gitster.siamese.dyndns.org","threadId":"11282","inReplyTo":"87mysdepeh.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-14T08:13:47Z","receivedAt":"2007-12-14T08:13:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n\n> diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\n> index 258a62f..5ca84fc 100644\n> --- a/Documentation/git-cvsserver.txt\n> +++ b/Documentation/git-cvsserver.txt\n\nLooks good.  I'll queue only so that I won't lose it and wait for Acks\nfrom Mart[iy]ns.  Please sign off your patch.\n\nThanks.\n"},{"id":"63207","messageId":"877ijhm1b5.fsf@cpan.org","threadId":"11282","inReplyTo":"7vir31u210.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avar@cpan.org","sentAt":"2007-12-14T21:08:46Z","receivedAt":"2007-12-14T21:08:46Z","isPatch":true,"sender":{"key":"avar@cpan.org","avatar":"https://gravatar.com/avatar/26a9abd89a6d76e77bbb1d1b6a5fc4714a6060dbf7862544cec4540305c9d9da?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Looks good.  I'll queue only so that I won't lose it and wait for Acks\n> from Mart[iy]ns.  Please sign off your patch.\n\nWill this do?\n\n\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n Documentation/git-cvsserver.txt |   21 +++++++++--\n git-cvsserver.perl              |   74 ++++++++++++++++++++++++++++++++++----\n 2 files changed, 83 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex 258a62f..5ca84fc 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -69,9 +69,6 @@ plugin. Most functionality works fine with both of these clients.\n LIMITATIONS\n -----------\n \n-Currently cvsserver works over SSH connections for read/write clients, and\n-over pserver for anonymous CVS access.\n-\n CVS clients cannot tag, branch or perform GIT merges.\n \n git-cvsserver maps GIT branches to CVS modules. This is very different\n@@ -81,7 +78,7 @@ one or more directories.\n INSTALLATION\n ------------\n \n-1. If you are going to offer anonymous CVS access via pserver, add a line in\n+1. If you are going to offer CVS access via pserver, add a line in\n    /etc/inetd.conf like\n +\n --\n@@ -98,6 +95,22 @@ looks like\n    cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n \n ------\n+\n+Only anonymous access is provided by pserve by default. To commit you\n+will have to create pserver accounts, simply add a [gitcvs.users]\n+section to the repositories you want to access, for example:\n+\n+------\n+   \n+   [gitcvs.users]\n+        someuser = somepassword\n+        otheruser = otherpassword\n+   \n+------\n+Then provide your password via the pserver method, for example:\n+------\n+   cvs -d:pserver:someuser:somepassword@server/path/repo.git co <HEAD_name>\n+------\n No special setup is needed for SSH access, other than having GIT tools\n in the PATH. If you have clients that do not accept the CVS_SERVER\n environment variable, you can rename git-cvsserver to cvs.\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex ecded3b..6f08bed 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -150,12 +150,35 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                #print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n+    # For checking whether the user is anonymous on commit\n+    $state->{user} = $user;\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -273,7 +296,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1176,9 +1199,9 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n+    if ($state->{method} eq 'pserver' and $state->{user} eq 'anonymous')\n     {\n-        print \"error 1 pserver access cannot commit\\n\";\n+        print \"error 1 anonymous user cannot commit via pserver\\n\";\n         exit;\n     }\n \n@@ -2107,6 +2130,41 @@ sub kopts_from_path\n     }\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same password format (A) bas been\n+    # used by CVS since the beginning of time\n+    $str =~ s/^(.)//;\n+    die \"invalid password format $1\" unless $1 eq 'A';\n+\n+    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n+\n+    return $str;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n-- \n1.5.3.6.gea559\n\n"},{"id":"63579","messageId":"46a038f90712180141x2f27e6cei5ef53339fd3f90dc@mail.gmail.com","threadId":"11282","inReplyTo":"877ijhm1b5.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2007-12-18T09:41:03Z","receivedAt":"2007-12-18T09:41:03Z","isPatch":true,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On Dec 15, 2007 10:08 AM, Ævar Arnfjörð Bjarmason <avar@cpan.org> wrote:\n> > Looks good.  I'll queue only so that I won't lose it and wait for Acks\n> > from Mart[iy]ns.  Please sign off your patch.\n\nI have been mulling a bit about this change. Seems correct from a code\nflow POV. But anon pserver support was added with a lot of\ntrepidation. Authenticated, write-enabled pserver support fills me\nwith dread ;-)\n\nA few things that come to mind\n\n - git/config is very likely to be readable if the site is served via\nother means, like dumb http protocol, or git+ssh. So even if the\npassword scrambling is mickey-mouse. it might make sense to force the\npassword data to live elsewhere.\n\n - umasks/file permissions will probably be handled by the underlying\ngit tools and core.sharedrepository, since we no longer update refs\n\"manually\". So after a bit of thinking, this should not be an issue.\n\n - I still worry about running cvsserver with an acct that has write\nprivileges. With anon, all we need write access is the sqlite db, and\nthat's not even based on user input. And it can be relocated elsewhere\nvia git/config.\n\nSo, wondering about input validation and related matters re-read most\nof cvsserver. The only suspicious bit I find is a caller to\ntransmitfile @ lines 1117, where the 2nd parameter doesn't come from\ntempfile() - if a nasty filename sneaked in, we could (perhaps) be in\nfor a surprise. We do that for diff header prettyness - we could use\n--label / -L instead. Will try and prep a patch for that tomorrow if\nnoone beats me to it (bedtime in nz!).\n\nHmmm. Does \"worried ACK\" count as an ACK? Can we add big fat warnings\nalong the lines of \"run this in a locked down environment, pretty\nplease\"?\n\ncheers,\n\n\n\nm\n"},{"id":"63667","messageId":"46a038f90712181239g3c6fe69bs822fd689d4628b5@mail.gmail.com","threadId":"11282","inReplyTo":"46a038f90712180141x2f27e6cei5ef53339fd3f90dc@mail.gmail.com","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2007-12-18T20:39:20Z","receivedAt":"2007-12-18T20:39:20Z","isPatch":true,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On Dec 18, 2007 10:41 PM, Martin Langhoff <martin.langhoff@gmail.com> wrote:\n>  - git/config is very likely to be readable if the site is served via\n> other means, like dumb http protocol, or git+ssh. So even if the\n> password scrambling is mickey-mouse. it might make sense to force the\n> password data to live elsewhere.\n\nOn this aspect, I see no reason why we wouldn't have the passwords\ncrypt()ed or SHA1'd. Perl includes crypt() in the default\ndistribution, so it wouldn't add any dependency.\n\nThe protocol may be ROT13'ing the passwords, but we don't have to\ndouble-ROT13 them in our storage format ;-)\n\ncheers,\n\n\nmartin\n"},{"id":"63676","messageId":"51dd1af80712181310q38255593t989be64799be2e0e@mail.gmail.com","threadId":"11282","inReplyTo":"46a038f90712181238p7529a02bmde21c89956a3f641@mail.gmail.com","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2007-12-18T21:10:28Z","receivedAt":"2007-12-18T21:10:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Dec 18, 2007 8:38 PM, Martin Langhoff <martin.langhoff@gmail.com> wrote:\n> On Dec 18, 2007 10:41 PM, Martin Langhoff <martin.langhoff@gmail.com> wrote:\n> >  - git/config is very likely to be readable if the site is served via\n> > other means, like dumb http protocol, or git+ssh. So even if the\n> > password scrambling is mickey-mouse. it might make sense to force the\n> > password data to live elsewhere.\n>\n> On this aspect, I see no reason why we wouldn't have the passwords\n> crypt()ed or SHA1'd. Perl includes crypt() in the default\n> distribution, so it wouldn't add any dependency.\n\nIt also includes Digest::SHA in the default distribution as of today:)\n\nI could add another option for allowing users to choose their password\nstorage, e.g.:\n\n[gitcvs]\n    password_storage = plaintext # or sha1, crypt, ...\n"},{"id":"63681","messageId":"7vmys7y99s.fsf@gitster.siamese.dyndns.org","threadId":"11282","inReplyTo":"51dd1af80712181310q38255593t989be64799be2e0e@mail.gmail.com","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-18T21:37:19Z","receivedAt":"2007-12-18T21:37:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Ævar Arnfjörð Bjarmason\"  <avarab@gmail.com> writes:\n\n>> On this aspect, I see no reason why we wouldn't have the passwords\n>> crypt()ed or SHA1'd. Perl includes crypt() in the default\n>> distribution, so it wouldn't add any dependency.\n>\n> It also includes Digest::SHA in the default distribution as of today:)\n>\n> I could add another option for allowing users to choose their password\n> storage, e.g.:\n>\n> [gitcvs]\n>     password_storage = plaintext # or sha1, crypt, ...\n\nI personally feel that selectable password storage format is going\noverboard.  Pick a reasonable one and use it everywhere.\n\nUsing some form of crypt is a good idea but then we would need a\nseparate mode of operation to gitcvs to generate user password.\n\n\t$ gitcvs adduser junio\n        Password: ******\n        Retype password: ******\n\tAdded user 'junio' to .git/config\n\t$ exit\n\nI personally do not care about deluser or change-password subcommands,\nas you can always go directly to .git/config to remove the user and\nrecreate anew, but adding them might be nice finishing touches.\n\n\t$ gitcvs password junio\n        New password: ******\n        Retype password: ******\n\tChanged password for user 'junio' in .git/config        \n\t$ gitcvs deluser junio\n        Are you sure you want to remove user 'junio' [y/N]? Y\n\tRemoved user 'junio' from .git/config\n\t$ exit\n"},{"id":"71302","messageId":"86r6ens6k5.fsf@cpan.org","threadId":"11282","inReplyTo":"46a038f90712180141x2f27e6cei5ef53339fd3f90dc@mail.gmail.com","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avar@cpan.org","sentAt":"2008-03-07T00:48:10Z","receivedAt":"2008-03-07T00:48:10Z","isPatch":true,"sender":{"key":"avar@cpan.org","avatar":"https://gravatar.com/avatar/26a9abd89a6d76e77bbb1d1b6a5fc4714a6060dbf7862544cec4540305c9d9da?d=mp&s=160"},"body":"\"Martin Langhoff\" <martin.langhoff@gmail.com> writes:\n\n> On Dec 15, 2007 10:08 AM, Ævar Arnfjörð Bjarmason <avar@cpan.org> wrote:\n>> > Looks good.  I'll queue only so that I won't lose it and wait for Acks\n>> > from Mart[iy]ns.  Please sign off your patch.\n>\n> I have been mulling a bit about this change. Seems correct from a code\n> flow POV. But anon pserver support was added with a lot of\n> trepidation. Authenticated, write-enabled pserver support fills me\n> with dread ;-)\n>\n> A few things that come to mind\n>\n>  - git/config is very likely to be readable if the site is served via\n> other means, like dumb http protocol, or git+ssh. So even if the\n> password scrambling is mickey-mouse. it might make sense to force the\n> password data to live elsewhere.\n>\n>  - umasks/file permissions will probably be handled by the underlying\n> git tools and core.sharedrepository, since we no longer update refs\n> \"manually\". So after a bit of thinking, this should not be an issue.\n>\n>  - I still worry about running cvsserver with an acct that has write\n> privileges. With anon, all we need write access is the sqlite db, and\n> that's not even based on user input. And it can be relocated elsewhere\n> via git/config.\n>\n> So, wondering about input validation and related matters re-read most\n> of cvsserver. The only suspicious bit I find is a caller to\n> transmitfile @ lines 1117, where the 2nd parameter doesn't come from\n> tempfile() - if a nasty filename sneaked in, we could (perhaps) be in\n> for a surprise. We do that for diff header prettyness - we could use\n> --label / -L instead. Will try and prep a patch for that tomorrow if\n> noone beats me to it (bedtime in nz!).\n>\n> Hmmm. Does \"worried ACK\" count as an ACK? Can we add big fat warnings\n> along the lines of \"run this in a locked down environment, pretty\n> please\"?\n\nBetter late than never, here's a more complete and hopefully final patch\nto add authentication support to CVS. Thanks to Sam Vilain for\ncontributing and kicking me into action.\n\nNow you specify a user:password authentication database in the [gitcvs]\nsection. The passwords are crypt()-ed and can be produced by htpasswd,\nexample config file:\n    \n    [gitcvs]\n        enabled = 1\n        authdb = /tmp/authdb.htpasswd\n    \nThe patch can be pulled from git://git.nix.is/avar/git\n\nIt's also produced below:\n\n\n\n>From 5900732b52c3a693bfb36c0bf56e3c5eb83ef65e Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 14 Dec 2007 08:08:46 +0000\nSubject: [PATCH] git-cvsserver: authentication support for pserver\nMIME-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit\n\nAllow git-cvsserver to use authentication over pserver mode.  The\npserver user/password database is stored in the config file for each\nrepository.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\nWorriedly-Acked-by: Martin Langhoff <martin.langhoff@gmail.com>\n---\n Documentation/git-cvsserver.txt |   21 +++++++++--\n git-cvsserver.perl              |   74 ++++++++++++++++++++++++++++++++++----\n 2 files changed, 83 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex d3e9993..98183d4 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -69,9 +69,6 @@ plugin. Most functionality works fine with both of these clients.\n LIMITATIONS\n -----------\n \n-Currently cvsserver works over SSH connections for read/write clients, and\n-over pserver for anonymous CVS access.\n-\n CVS clients cannot tag, branch or perform GIT merges.\n \n git-cvsserver maps GIT branches to CVS modules. This is very different\n@@ -81,7 +78,7 @@ one or more directories.\n INSTALLATION\n ------------\n \n-1. If you are going to offer anonymous CVS access via pserver, add a line in\n+1. If you are going to offer CVS access via pserver, add a line in\n    /etc/inetd.conf like\n +\n --\n@@ -98,6 +95,22 @@ looks like\n    cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n \n ------\n+\n+Only anonymous access is provided by pserve by default. To commit you\n+will have to create pserver accounts, simply add a [gitcvs.users]\n+section to the repositories you want to access, for example:\n+\n+------\n+   \n+   [gitcvs.users]\n+        someuser = somepassword\n+        otheruser = otherpassword\n+   \n+------\n+Then provide your password via the pserver method, for example:\n+------\n+   cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n+------\n No special setup is needed for SSH access, other than having GIT tools\n in the PATH. If you have clients that do not accept the CVS_SERVER\n environment variable, you can rename git-cvsserver to cvs.\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex afe3d0b..9bc2ff5 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -150,12 +150,35 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                #print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n+    # For checking whether the user is anonymous on commit\n+    $state->{user} = $user;\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -273,7 +296,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1176,9 +1199,9 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n+    if ($state->{method} eq 'pserver' and $state->{user} eq 'anonymous')\n     {\n-        print \"error 1 pserver access cannot commit\\n\";\n+        print \"error 1 anonymous user cannot commit via pserver\\n\";\n         exit;\n     }\n \n@@ -2107,6 +2130,41 @@ sub kopts_from_path\n     }\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same password format (A) bas been\n+    # used by CVS since the beginning of time\n+    $str =~ s/^(.)//;\n+    die \"invalid password format $1\" unless $1 eq 'A';\n+\n+    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n+\n+    return $str;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From f59c255ed14c5b80d5328f94f6934461cfe454da Mon Sep 17 00:00:00 2001\nFrom: Sam Vilain <sam.vilain@catalyst.net.nz>\nDate: Fri, 7 Mar 2008 11:03:14 +1300\nSubject: [PATCH] git-cvsserver: use a password file cvsserver pserver\n\nIf a git repository is shared via HTTP, the config file is typically\nvisible.  Use an external file instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n Documentation/git-cvsserver.txt |   21 ++++++++++++++++-----\n git-cvsserver.perl              |   27 ++++++++++++++-------------\n 2 files changed, 30 insertions(+), 18 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex 98183d4..c642f12 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -97,16 +97,27 @@ looks like\n ------\n \n Only anonymous access is provided by pserve by default. To commit you\n-will have to create pserver accounts, simply add a [gitcvs.users]\n-section to the repositories you want to access, for example:\n+will have to create pserver accounts, simply add a gitcvs.authdb\n+setting in the config file of the repositories you want the cvsserver\n+to allow writes to, for example:\n \n ------\n    \n-   [gitcvs.users]\n-        someuser = somepassword\n-        otheruser = otherpassword\n+   [gitcvs]\n+        authdb = /etc/cvsserver/passwd\n    \n ------\n+The format of these files is username followed by the crypted password,\n+for example:\n+\n+------\n+   myuser:$1Oyx5r9mdGZ2\n+   myuser:$1$BA)@$vbnMJMDym7tA32AamXrm./\n+------\n+You can use the 'htpasswd' facility that comes with Apache to make these\n+files, but Apache's MD5 crypt method differs from the one used by most C\n+library's crypt() function, so don't use the -m option.\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 9bc2ff5..e54cbcd 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -156,24 +156,25 @@ if ($state->{method} eq 'pserver') {\n \n     unless ($user eq 'anonymous') {\n         # Trying to authenticate a user\n-        if (not exists $cfg->{gitcvs}->{users}) {\n-            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+        if (not exists $cfg->{gitcvs}->{authdb}) {\n+            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n-            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+        }\n+\tmy $auth_ok;\n+\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n+\twhile(<PASSWD>) {\n+\t    if (m{^\\Q$user\\E:(.*)}) {\n+\t\tif (crypt($user, $1) eq $1) {\n+\t\t    $auth_ok = 1;\n+\t\t}\n+\t    };\n+\t}\n+\tunless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } else {\n-            my $descrambled_password = descramble($password);\n-            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n-            if ($descrambled_password ne $cleartext_password) {\n-                #print \"E The password supplied for user $user was incorrect\\n\";\n-                print \"I HATE YOU\\n\";\n-                exit 1;\n-            }\n-            # else fall through to LOVE\n         }\n+        # else fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From e8b69f313888900447f45ac3a8dceb38bd5c261e Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Thu, 6 Mar 2008 23:43:13 +0000\nSubject: [PATCH] Indent the last commit to fit with the rest of the code.\n\nUse lexical filehandles instead of global globs\n\nClose the filehandle after the password database has been read\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n git-cvsserver.perl |   23 +++++++++++++----------\n 1 files changed, 13 insertions(+), 10 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex e54cbcd..f956ac9 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -161,16 +161,19 @@ if ($state->{method} eq 'pserver') {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-\tmy $auth_ok;\n-\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n-\twhile(<PASSWD>) {\n-\t    if (m{^\\Q$user\\E:(.*)}) {\n-\t\tif (crypt($user, $1) eq $1) {\n-\t\t    $auth_ok = 1;\n-\t\t}\n-\t    };\n-\t}\n-\tunless ($auth_ok) {\n+\n+        my $auth_ok;\n+        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n+        while (<$passwd>) {\n+            if (m{^\\Q$user\\E:(.*)}) {\n+                if (crypt($user, $1) eq $1) {\n+                    $auth_ok = 1;\n+                }\n+            };\n+        }\n+        close $passwd;\n+\n+        unless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From 90d3468556b46fc649a9408af42ff24ed2e50455 Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 7 Mar 2008 00:06:52 +0000\nSubject: [PATCH] Produce an error if the user tries to supply a password for anonymous\n\nClarify the error message produced when there's no [gitcvs.authdb]\n\nProduce an E error if the authdb doesn't exist instead of spewing $!\nto the user\n\ndo crypt($user, descramble($pass)) eq $hash; crypt($user, $hash) eq\n$hash would accept any password\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n git-cvsserver.perl |   28 +++++++++++++++++++++++-----\n 1 files changed, 23 insertions(+), 5 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex f956ac9..aa0299e 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -154,19 +154,36 @@ if ($state->{method} eq 'pserver') {\n     $line = <STDIN>; chomp $line;\n     my $password = $line;\n \n-    unless ($user eq 'anonymous') {\n+    if ($user eq 'anonymous') {\n+        # \"A\" will be 1 byte, use length instead in case the\n+        # encryption method ever changes (yeah, right!)\n+        if (length($password) > 1 ) {\n+            print \"E Don't supply a password for the `anonymous' user\\n\";\n+            print \"I HATE YOU\\n\";\n+        }\n+\n+        # Fall through to LOVE\n+    } else {\n         # Trying to authenticate a user\n         if (not exists $cfg->{gitcvs}->{authdb}) {\n-            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n+            print \"E the repo config file needs a [gitcvs] section with an 'authdb' parameter set to the filename of the authentication database\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        }\n+\n+        my $authdb = $cfg->{gitcvs}->{authdb};\n+\n+        unless (-e $authdb) {\n+            print \"E The authentication database specified in [gitcvs.authdb] does not exist\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n \n         my $auth_ok;\n-        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n+        open my $passwd, \"<\", $authdb or die $!;\n         while (<$passwd>) {\n             if (m{^\\Q$user\\E:(.*)}) {\n-                if (crypt($user, $1) eq $1) {\n+                if (crypt($user, descramble($password)) eq $1) {\n                     $auth_ok = 1;\n                 }\n             };\n@@ -177,7 +194,8 @@ if ($state->{method} eq 'pserver') {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-        # else fall through to LOVE\n+\n+        # Fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From a55dfa2667da1473199ee70ca6cfd53094001119 Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 7 Mar 2008 00:09:14 +0000\nSubject: [PATCH] document a perl snippet to produce passwords for those that don't have htpasswd\n\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n Documentation/git-cvsserver.txt |    5 +++++\n 1 files changed, 5 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex c642f12..d410a11 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -118,6 +118,11 @@ You can use the 'htpasswd' facility that comes with Apache to make these\n files, but Apache's MD5 crypt method differs from the one used by most C\n library's crypt() function, so don't use the -m option.\n \n+Alternatively you can produce the password with perl's crypt() operator:\n+-----\n+   perl -e 'my ($user, $pass) = @ARGV; printf \"%s:%s\\n\", $user, crypt($user, $pass)' $USER password\n+-----\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n-- \n1.5.3.rc3.120.g68d422\n\n"},{"id":"71355","messageId":"86iqzyse9u.fsf@cpan.org","threadId":"11282","inReplyTo":"86r6ens6k5.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avar@cpan.org","sentAt":"2008-03-07T16:13:49Z","receivedAt":"2008-03-07T16:13:49Z","isPatch":true,"sender":{"key":"avar@cpan.org","avatar":"https://gravatar.com/avatar/26a9abd89a6d76e77bbb1d1b6a5fc4714a6060dbf7862544cec4540305c9d9da?d=mp&s=160"},"body":"avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n\n> Better late than never, here's a more complete and hopefully final patch\n> to add authentication support to CVS. Thanks to Sam Vilain for\n> contributing and kicking me into action.\n>\n> Now you specify a user:password authentication database in the [gitcvs]\n> section. The passwords are crypt()-ed and can be produced by htpasswd,\n> example config file:\n>     \n>     [gitcvs]\n>         enabled = 1\n>         authdb = /tmp/authdb.htpasswd\n>     \n> The patch can be pulled from git://git.nix.is/avar/git\n>\n> It's also produced below:\n\nThe patch needed a small fix, I didn't exit(1) after an error\ncondition[1]. This can also be got at git://git.nix.is/avar/git and is\nproduced in full below:\n\n\n\n>From 5900732b52c3a693bfb36c0bf56e3c5eb83ef65e Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 14 Dec 2007 08:08:46 +0000\nSubject: [PATCH] git-cvsserver: authentication support for pserver\nMIME-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit\n\nAllow git-cvsserver to use authentication over pserver mode.  The\npserver user/password database is stored in the config file for each\nrepository.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\nWorriedly-Acked-by: Martin Langhoff <martin.langhoff@gmail.com>\n---\n Documentation/git-cvsserver.txt |   21 +++++++++--\n git-cvsserver.perl              |   74 ++++++++++++++++++++++++++++++++++----\n 2 files changed, 83 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex d3e9993..98183d4 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -69,9 +69,6 @@ plugin. Most functionality works fine with both of these clients.\n LIMITATIONS\n -----------\n \n-Currently cvsserver works over SSH connections for read/write clients, and\n-over pserver for anonymous CVS access.\n-\n CVS clients cannot tag, branch or perform GIT merges.\n \n git-cvsserver maps GIT branches to CVS modules. This is very different\n@@ -81,7 +78,7 @@ one or more directories.\n INSTALLATION\n ------------\n \n-1. If you are going to offer anonymous CVS access via pserver, add a line in\n+1. If you are going to offer CVS access via pserver, add a line in\n    /etc/inetd.conf like\n +\n --\n@@ -98,6 +95,22 @@ looks like\n    cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n \n ------\n+\n+Only anonymous access is provided by pserve by default. To commit you\n+will have to create pserver accounts, simply add a [gitcvs.users]\n+section to the repositories you want to access, for example:\n+\n+------\n+   \n+   [gitcvs.users]\n+        someuser = somepassword\n+        otheruser = otherpassword\n+   \n+------\n+Then provide your password via the pserver method, for example:\n+------\n+   cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n+------\n No special setup is needed for SSH access, other than having GIT tools\n in the PATH. If you have clients that do not accept the CVS_SERVER\n environment variable, you can rename git-cvsserver to cvs.\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex afe3d0b..9bc2ff5 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -150,12 +150,35 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                #print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n+    # For checking whether the user is anonymous on commit\n+    $state->{user} = $user;\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -273,7 +296,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1176,9 +1199,9 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n+    if ($state->{method} eq 'pserver' and $state->{user} eq 'anonymous')\n     {\n-        print \"error 1 pserver access cannot commit\\n\";\n+        print \"error 1 anonymous user cannot commit via pserver\\n\";\n         exit;\n     }\n \n@@ -2107,6 +2130,41 @@ sub kopts_from_path\n     }\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same password format (A) bas been\n+    # used by CVS since the beginning of time\n+    $str =~ s/^(.)//;\n+    die \"invalid password format $1\" unless $1 eq 'A';\n+\n+    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n+\n+    return $str;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From f59c255ed14c5b80d5328f94f6934461cfe454da Mon Sep 17 00:00:00 2001\nFrom: Sam Vilain <sam.vilain@catalyst.net.nz>\nDate: Fri, 7 Mar 2008 11:03:14 +1300\nSubject: [PATCH] git-cvsserver: use a password file cvsserver pserver\n\nIf a git repository is shared via HTTP, the config file is typically\nvisible.  Use an external file instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n Documentation/git-cvsserver.txt |   21 ++++++++++++++++-----\n git-cvsserver.perl              |   27 ++++++++++++++-------------\n 2 files changed, 30 insertions(+), 18 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex 98183d4..c642f12 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -97,16 +97,27 @@ looks like\n ------\n \n Only anonymous access is provided by pserve by default. To commit you\n-will have to create pserver accounts, simply add a [gitcvs.users]\n-section to the repositories you want to access, for example:\n+will have to create pserver accounts, simply add a gitcvs.authdb\n+setting in the config file of the repositories you want the cvsserver\n+to allow writes to, for example:\n \n ------\n    \n-   [gitcvs.users]\n-        someuser = somepassword\n-        otheruser = otherpassword\n+   [gitcvs]\n+        authdb = /etc/cvsserver/passwd\n    \n ------\n+The format of these files is username followed by the crypted password,\n+for example:\n+\n+------\n+   myuser:$1Oyx5r9mdGZ2\n+   myuser:$1$BA)@$vbnMJMDym7tA32AamXrm./\n+------\n+You can use the 'htpasswd' facility that comes with Apache to make these\n+files, but Apache's MD5 crypt method differs from the one used by most C\n+library's crypt() function, so don't use the -m option.\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 9bc2ff5..e54cbcd 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -156,24 +156,25 @@ if ($state->{method} eq 'pserver') {\n \n     unless ($user eq 'anonymous') {\n         # Trying to authenticate a user\n-        if (not exists $cfg->{gitcvs}->{users}) {\n-            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+        if (not exists $cfg->{gitcvs}->{authdb}) {\n+            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n-            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+        }\n+\tmy $auth_ok;\n+\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n+\twhile(<PASSWD>) {\n+\t    if (m{^\\Q$user\\E:(.*)}) {\n+\t\tif (crypt($user, $1) eq $1) {\n+\t\t    $auth_ok = 1;\n+\t\t}\n+\t    };\n+\t}\n+\tunless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } else {\n-            my $descrambled_password = descramble($password);\n-            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n-            if ($descrambled_password ne $cleartext_password) {\n-                #print \"E The password supplied for user $user was incorrect\\n\";\n-                print \"I HATE YOU\\n\";\n-                exit 1;\n-            }\n-            # else fall through to LOVE\n         }\n+        # else fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From e8b69f313888900447f45ac3a8dceb38bd5c261e Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Thu, 6 Mar 2008 23:43:13 +0000\nSubject: [PATCH] Indent the last commit to fit with the rest of the code.\n\nUse lexical filehandles instead of global globs\n\nClose the filehandle after the password database has been read\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n git-cvsserver.perl |   23 +++++++++++++----------\n 1 files changed, 13 insertions(+), 10 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex e54cbcd..f956ac9 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -161,16 +161,19 @@ if ($state->{method} eq 'pserver') {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-\tmy $auth_ok;\n-\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n-\twhile(<PASSWD>) {\n-\t    if (m{^\\Q$user\\E:(.*)}) {\n-\t\tif (crypt($user, $1) eq $1) {\n-\t\t    $auth_ok = 1;\n-\t\t}\n-\t    };\n-\t}\n-\tunless ($auth_ok) {\n+\n+        my $auth_ok;\n+        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n+        while (<$passwd>) {\n+            if (m{^\\Q$user\\E:(.*)}) {\n+                if (crypt($user, $1) eq $1) {\n+                    $auth_ok = 1;\n+                }\n+            };\n+        }\n+        close $passwd;\n+\n+        unless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From 90d3468556b46fc649a9408af42ff24ed2e50455 Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 7 Mar 2008 00:06:52 +0000\nSubject: [PATCH] Produce an error if the user tries to supply a password for anonymous\n\nClarify the error message produced when there's no [gitcvs.authdb]\n\nProduce an E error if the authdb doesn't exist instead of spewing $!\nto the user\n\ndo crypt($user, descramble($pass)) eq $hash; crypt($user, $hash) eq\n$hash would accept any password\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n git-cvsserver.perl |   28 +++++++++++++++++++++++-----\n 1 files changed, 23 insertions(+), 5 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex f956ac9..aa0299e 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -154,19 +154,36 @@ if ($state->{method} eq 'pserver') {\n     $line = <STDIN>; chomp $line;\n     my $password = $line;\n \n-    unless ($user eq 'anonymous') {\n+    if ($user eq 'anonymous') {\n+        # \"A\" will be 1 byte, use length instead in case the\n+        # encryption method ever changes (yeah, right!)\n+        if (length($password) > 1 ) {\n+            print \"E Don't supply a password for the `anonymous' user\\n\";\n+            print \"I HATE YOU\\n\";\n+        }\n+\n+        # Fall through to LOVE\n+    } else {\n         # Trying to authenticate a user\n         if (not exists $cfg->{gitcvs}->{authdb}) {\n-            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n+            print \"E the repo config file needs a [gitcvs] section with an 'authdb' parameter set to the filename of the authentication database\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        }\n+\n+        my $authdb = $cfg->{gitcvs}->{authdb};\n+\n+        unless (-e $authdb) {\n+            print \"E The authentication database specified in [gitcvs.authdb] does not exist\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n \n         my $auth_ok;\n-        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n+        open my $passwd, \"<\", $authdb or die $!;\n         while (<$passwd>) {\n             if (m{^\\Q$user\\E:(.*)}) {\n-                if (crypt($user, $1) eq $1) {\n+                if (crypt($user, descramble($password)) eq $1) {\n                     $auth_ok = 1;\n                 }\n             };\n@@ -177,7 +194,8 @@ if ($state->{method} eq 'pserver') {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-        # else fall through to LOVE\n+\n+        # Fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From a55dfa2667da1473199ee70ca6cfd53094001119 Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 7 Mar 2008 00:09:14 +0000\nSubject: [PATCH] document a perl snippet to produce passwords for those that don't have htpasswd\n\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n Documentation/git-cvsserver.txt |    5 +++++\n 1 files changed, 5 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex c642f12..d410a11 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -118,6 +118,11 @@ You can use the 'htpasswd' facility that comes with Apache to make these\n files, but Apache's MD5 crypt method differs from the one used by most C\n library's crypt() function, so don't use the -m option.\n \n+Alternatively you can produce the password with perl's crypt() operator:\n+-----\n+   perl -e 'my ($user, $pass) = @ARGV; printf \"%s:%s\\n\", $user, crypt($user, $pass)' $USER password\n+-----\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n-- \n1.5.3.rc3.120.g68d422\n\n\n>From 60f893bd9fe329bd5cf8ec513d10ec00e85feb2c Mon Sep 17 00:00:00 2001\nFrom: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\nDate: Fri, 7 Mar 2008 16:06:31 +0000\nSubject: [PATCH] exit after producing the error about anonymous having a password\n\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n---\n git-cvsserver.perl |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex aa0299e..da48ebd 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -160,6 +160,7 @@ if ($state->{method} eq 'pserver') {\n         if (length($password) > 1 ) {\n             print \"E Don't supply a password for the `anonymous' user\\n\";\n             print \"I HATE YOU\\n\";\n+            exit 1;\n         }\n \n         # Fall through to LOVE\n-- \n1.5.3.rc3.120.g68d422\n\n\n\n\n1. http://git.nix.is/?p=avar/git;a=commitdiff;h=60f893bd9fe329bd5cf8ec513d10ec00e85feb2c\n"},{"id":"80340","messageId":"861w2tjpev.fsf@cpan.org","threadId":"11282","inReplyTo":"86iqzyse9u.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avar@cpan.org","sentAt":"2008-06-19T17:38:32Z","receivedAt":"2008-06-19T17:38:32Z","isPatch":true,"sender":{"key":"avar@cpan.org","avatar":"https://gravatar.com/avatar/26a9abd89a6d76e77bbb1d1b6a5fc4714a6060dbf7862544cec4540305c9d9da?d=mp&s=160"},"body":"avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n\n> avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n>\n>> Better late than never, here's a more complete and hopefully final patch\n>> to add authentication support to CVS. Thanks to Sam Vilain for\n>> contributing and kicking me into action.\n>>\n>> Now you specify a user:password authentication database in the [gitcvs]\n>> section. The passwords are crypt()-ed and can be produced by htpasswd,\n>> example config file:\n>>     \n>>     [gitcvs]\n>>         enabled = 1\n>>         authdb = /tmp/authdb.htpasswd\n>>     \n>> The patch can be pulled from git://git.nix.is/avar/git\n>>\n>> It's also produced below:\n>\n> The patch needed a small fix, I didn't exit(1) after an error\n> condition[1]. This can also be got at git://git.nix.is/avar/git and is\n> produced in full below:\n>\n>\n> From 5900732b52c3a693bfb36c0bf56e3c5eb83ef65e Mon Sep 17 00:00:00 2001\n> From: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\n> Date: Fri, 14 Dec 2007 08:08:46 +0000\n> Subject: [PATCH] git-cvsserver: authentication support for pserver\n> MIME-Version: 1.0\n> Content-Type: text/plain; charset=utf-8\n> Content-Transfer-Encoding: 8bit\n>\n> Allow git-cvsserver to use authentication over pserver mode.  The\n> pserver user/password database is stored in the config file for each\n> repository.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n> Worriedly-Acked-by: Martin Langhoff <martin.langhoff@gmail.com>\n> ---\n>  Documentation/git-cvsserver.txt |   21 +++++++++--\n>  git-cvsserver.perl              |   74 ++++++++++++++++++++++++++++++++++----\n>  2 files changed, 83 insertions(+), 12 deletions(-)\n>\n> diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\n> index d3e9993..98183d4 100644\n> --- a/Documentation/git-cvsserver.txt\n> +++ b/Documentation/git-cvsserver.txt\n> @@ -69,9 +69,6 @@ plugin. Most functionality works fine with both of these clients.\n>  LIMITATIONS\n>  -----------\n>  \n> -Currently cvsserver works over SSH connections for read/write clients, and\n> -over pserver for anonymous CVS access.\n> -\n>  CVS clients cannot tag, branch or perform GIT merges.\n>  \n>  git-cvsserver maps GIT branches to CVS modules. This is very different\n> @@ -81,7 +78,7 @@ one or more directories.\n>  INSTALLATION\n>  ------------\n>  \n> -1. If you are going to offer anonymous CVS access via pserver, add a line in\n> +1. If you are going to offer CVS access via pserver, add a line in\n>     /etc/inetd.conf like\n>  +\n>  --\n> @@ -98,6 +95,22 @@ looks like\n>     cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n>  \n>  ------\n> +\n> +Only anonymous access is provided by pserve by default. To commit you\n> +will have to create pserver accounts, simply add a [gitcvs.users]\n> +section to the repositories you want to access, for example:\n> +\n> +------\n> +   \n> +   [gitcvs.users]\n> +        someuser = somepassword\n> +        otheruser = otherpassword\n> +   \n> +------\n> +Then provide your password via the pserver method, for example:\n> +------\n> +   cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n> +------\n>  No special setup is needed for SSH access, other than having GIT tools\n>  in the PATH. If you have clients that do not accept the CVS_SERVER\n>  environment variable, you can rename git-cvsserver to cvs.\n> diff --git a/git-cvsserver.perl b/git-cvsserver.perl\n> index afe3d0b..9bc2ff5 100755\n> --- a/git-cvsserver.perl\n> +++ b/git-cvsserver.perl\n> @@ -150,12 +150,35 @@ if ($state->{method} eq 'pserver') {\n>         exit 1;\n>      }\n>      $line = <STDIN>; chomp $line;\n> -    unless ($line eq 'anonymous') {\n> -       print \"E Only anonymous user allowed via pserver\\n\";\n> -       print \"I HATE YOU\\n\";\n> -       exit 1;\n> +    my $user = $line;\n> +    $line = <STDIN>; chomp $line;\n> +    my $password = $line;\n> +\n> +    unless ($user eq 'anonymous') {\n> +        # Trying to authenticate a user\n> +        if (not exists $cfg->{gitcvs}->{users}) {\n> +            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n> +            print \"I HATE YOU\\n\";\n> +            exit 1;\n> +        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n> +            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n> +            print \"I HATE YOU\\n\";\n> +            exit 1;\n> +        } else {\n> +            my $descrambled_password = descramble($password);\n> +            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n> +            if ($descrambled_password ne $cleartext_password) {\n> +                #print \"E The password supplied for user $user was incorrect\\n\";\n> +                print \"I HATE YOU\\n\";\n> +                exit 1;\n> +            }\n> +            # else fall through to LOVE\n> +        }\n>      }\n> -    $line = <STDIN>; chomp $line;    # validate the password?\n> +\n> +    # For checking whether the user is anonymous on commit\n> +    $state->{user} = $user;\n> +\n>      $line = <STDIN>; chomp $line;\n>      unless ($line eq \"END $request REQUEST\") {\n>         die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n> @@ -273,7 +296,7 @@ sub req_Root\n>      }\n>      foreach my $line ( @gitvars )\n>      {\n> -        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n> +        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n>          unless ($2) {\n>              $cfg->{$1}{$3} = $4;\n>          } else {\n> @@ -1176,9 +1199,9 @@ sub req_ci\n>  \n>      $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n>  \n> -    if ( $state->{method} eq 'pserver')\n> +    if ($state->{method} eq 'pserver' and $state->{user} eq 'anonymous')\n>      {\n> -        print \"error 1 pserver access cannot commit\\n\";\n> +        print \"error 1 anonymous user cannot commit via pserver\\n\";\n>          exit;\n>      }\n>  \n> @@ -2107,6 +2130,41 @@ sub kopts_from_path\n>      }\n>  }\n>  \n> +\n> +sub descramble\n> +{\n> +    # This table is from src/scramble.c in the CVS source\n> +    my @SHIFTS = (\n> +        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n> +        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n> +        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n> +        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n> +        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n> +        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n> +        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n> +        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n> +        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n> +        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n> +        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n> +        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n> +        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n> +        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n> +        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n> +        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n> +    );\n> +    my ($str) = @_;\n> +\n> +    # This should never happen, the same password format (A) bas been\n> +    # used by CVS since the beginning of time\n> +    $str =~ s/^(.)//;\n> +    die \"invalid password format $1\" unless $1 eq 'A';\n> +\n> +    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n> +\n> +    return $str;\n> +}\n> +\n> +\n>  package GITCVS::log;\n>  \n>  ####\n> -- \n> 1.5.3.rc3.120.g68d422\n>\n>\n> From f59c255ed14c5b80d5328f94f6934461cfe454da Mon Sep 17 00:00:00 2001\n> From: Sam Vilain <sam.vilain@catalyst.net.nz>\n> Date: Fri, 7 Mar 2008 11:03:14 +1300\n> Subject: [PATCH] git-cvsserver: use a password file cvsserver pserver\n>\n> If a git repository is shared via HTTP, the config file is typically\n> visible.  Use an external file instead.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n> ---\n>  Documentation/git-cvsserver.txt |   21 ++++++++++++++++-----\n>  git-cvsserver.perl              |   27 ++++++++++++++-------------\n>  2 files changed, 30 insertions(+), 18 deletions(-)\n>\n> diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\n> index 98183d4..c642f12 100644\n> --- a/Documentation/git-cvsserver.txt\n> +++ b/Documentation/git-cvsserver.txt\n> @@ -97,16 +97,27 @@ looks like\n>  ------\n>  \n>  Only anonymous access is provided by pserve by default. To commit you\n> -will have to create pserver accounts, simply add a [gitcvs.users]\n> -section to the repositories you want to access, for example:\n> +will have to create pserver accounts, simply add a gitcvs.authdb\n> +setting in the config file of the repositories you want the cvsserver\n> +to allow writes to, for example:\n>  \n>  ------\n>     \n> -   [gitcvs.users]\n> -        someuser = somepassword\n> -        otheruser = otherpassword\n> +   [gitcvs]\n> +        authdb = /etc/cvsserver/passwd\n>     \n>  ------\n> +The format of these files is username followed by the crypted password,\n> +for example:\n> +\n> +------\n> +   myuser:$1Oyx5r9mdGZ2\n> +   myuser:$1$BA)@$vbnMJMDym7tA32AamXrm./\n> +------\n> +You can use the 'htpasswd' facility that comes with Apache to make these\n> +files, but Apache's MD5 crypt method differs from the one used by most C\n> +library's crypt() function, so don't use the -m option.\n> +\n>  Then provide your password via the pserver method, for example:\n>  ------\n>     cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n> diff --git a/git-cvsserver.perl b/git-cvsserver.perl\n> index 9bc2ff5..e54cbcd 100755\n> --- a/git-cvsserver.perl\n> +++ b/git-cvsserver.perl\n> @@ -156,24 +156,25 @@ if ($state->{method} eq 'pserver') {\n>  \n>      unless ($user eq 'anonymous') {\n>          # Trying to authenticate a user\n> -        if (not exists $cfg->{gitcvs}->{users}) {\n> -            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n> +        if (not exists $cfg->{gitcvs}->{authdb}) {\n> +            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n>              print \"I HATE YOU\\n\";\n>              exit 1;\n> -        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n> -            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n> +        }\n> +\tmy $auth_ok;\n> +\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n> +\twhile(<PASSWD>) {\n> +\t    if (m{^\\Q$user\\E:(.*)}) {\n> +\t\tif (crypt($user, $1) eq $1) {\n> +\t\t    $auth_ok = 1;\n> +\t\t}\n> +\t    };\n> +\t}\n> +\tunless ($auth_ok) {\n>              print \"I HATE YOU\\n\";\n>              exit 1;\n> -        } else {\n> -            my $descrambled_password = descramble($password);\n> -            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n> -            if ($descrambled_password ne $cleartext_password) {\n> -                #print \"E The password supplied for user $user was incorrect\\n\";\n> -                print \"I HATE YOU\\n\";\n> -                exit 1;\n> -            }\n> -            # else fall through to LOVE\n>          }\n> +        # else fall through to LOVE\n>      }\n>  \n>      # For checking whether the user is anonymous on commit\n> -- \n> 1.5.3.rc3.120.g68d422\n>\n>\n> From e8b69f313888900447f45ac3a8dceb38bd5c261e Mon Sep 17 00:00:00 2001\n> From: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\n> Date: Thu, 6 Mar 2008 23:43:13 +0000\n> Subject: [PATCH] Indent the last commit to fit with the rest of the code.\n>\n> Use lexical filehandles instead of global globs\n>\n> Close the filehandle after the password database has been read\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n> ---\n>  git-cvsserver.perl |   23 +++++++++++++----------\n>  1 files changed, 13 insertions(+), 10 deletions(-)\n>\n> diff --git a/git-cvsserver.perl b/git-cvsserver.perl\n> index e54cbcd..f956ac9 100755\n> --- a/git-cvsserver.perl\n> +++ b/git-cvsserver.perl\n> @@ -161,16 +161,19 @@ if ($state->{method} eq 'pserver') {\n>              print \"I HATE YOU\\n\";\n>              exit 1;\n>          }\n> -\tmy $auth_ok;\n> -\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n> -\twhile(<PASSWD>) {\n> -\t    if (m{^\\Q$user\\E:(.*)}) {\n> -\t\tif (crypt($user, $1) eq $1) {\n> -\t\t    $auth_ok = 1;\n> -\t\t}\n> -\t    };\n> -\t}\n> -\tunless ($auth_ok) {\n> +\n> +        my $auth_ok;\n> +        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n> +        while (<$passwd>) {\n> +            if (m{^\\Q$user\\E:(.*)}) {\n> +                if (crypt($user, $1) eq $1) {\n> +                    $auth_ok = 1;\n> +                }\n> +            };\n> +        }\n> +        close $passwd;\n> +\n> +        unless ($auth_ok) {\n>              print \"I HATE YOU\\n\";\n>              exit 1;\n>          }\n> -- \n> 1.5.3.rc3.120.g68d422\n>\n>\n> From 90d3468556b46fc649a9408af42ff24ed2e50455 Mon Sep 17 00:00:00 2001\n> From: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\n> Date: Fri, 7 Mar 2008 00:06:52 +0000\n> Subject: [PATCH] Produce an error if the user tries to supply a password for anonymous\n>\n> Clarify the error message produced when there's no [gitcvs.authdb]\n>\n> Produce an E error if the authdb doesn't exist instead of spewing $!\n> to the user\n>\n> do crypt($user, descramble($pass)) eq $hash; crypt($user, $hash) eq\n> $hash would accept any password\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n> ---\n>  git-cvsserver.perl |   28 +++++++++++++++++++++++-----\n>  1 files changed, 23 insertions(+), 5 deletions(-)\n>\n> diff --git a/git-cvsserver.perl b/git-cvsserver.perl\n> index f956ac9..aa0299e 100755\n> --- a/git-cvsserver.perl\n> +++ b/git-cvsserver.perl\n> @@ -154,19 +154,36 @@ if ($state->{method} eq 'pserver') {\n>      $line = <STDIN>; chomp $line;\n>      my $password = $line;\n>  \n> -    unless ($user eq 'anonymous') {\n> +    if ($user eq 'anonymous') {\n> +        # \"A\" will be 1 byte, use length instead in case the\n> +        # encryption method ever changes (yeah, right!)\n> +        if (length($password) > 1 ) {\n> +            print \"E Don't supply a password for the `anonymous' user\\n\";\n> +            print \"I HATE YOU\\n\";\n> +        }\n> +\n> +        # Fall through to LOVE\n> +    } else {\n>          # Trying to authenticate a user\n>          if (not exists $cfg->{gitcvs}->{authdb}) {\n> -            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n> +            print \"E the repo config file needs a [gitcvs] section with an 'authdb' parameter set to the filename of the authentication database\\n\";\n> +            print \"I HATE YOU\\n\";\n> +            exit 1;\n> +        }\n> +\n> +        my $authdb = $cfg->{gitcvs}->{authdb};\n> +\n> +        unless (-e $authdb) {\n> +            print \"E The authentication database specified in [gitcvs.authdb] does not exist\\n\";\n>              print \"I HATE YOU\\n\";\n>              exit 1;\n>          }\n>  \n>          my $auth_ok;\n> -        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n> +        open my $passwd, \"<\", $authdb or die $!;\n>          while (<$passwd>) {\n>              if (m{^\\Q$user\\E:(.*)}) {\n> -                if (crypt($user, $1) eq $1) {\n> +                if (crypt($user, descramble($password)) eq $1) {\n>                      $auth_ok = 1;\n>                  }\n>              };\n> @@ -177,7 +194,8 @@ if ($state->{method} eq 'pserver') {\n>              print \"I HATE YOU\\n\";\n>              exit 1;\n>          }\n> -        # else fall through to LOVE\n> +\n> +        # Fall through to LOVE\n>      }\n>  \n>      # For checking whether the user is anonymous on commit\n> -- \n> 1.5.3.rc3.120.g68d422\n>\n>\n> From a55dfa2667da1473199ee70ca6cfd53094001119 Mon Sep 17 00:00:00 2001\n> From: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\n> Date: Fri, 7 Mar 2008 00:09:14 +0000\n> Subject: [PATCH] document a perl snippet to produce passwords for those that don't have htpasswd\n>\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n> ---\n>  Documentation/git-cvsserver.txt |    5 +++++\n>  1 files changed, 5 insertions(+), 0 deletions(-)\n>\n> diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\n> index c642f12..d410a11 100644\n> --- a/Documentation/git-cvsserver.txt\n> +++ b/Documentation/git-cvsserver.txt\n> @@ -118,6 +118,11 @@ You can use the 'htpasswd' facility that comes with Apache to make these\n>  files, but Apache's MD5 crypt method differs from the one used by most C\n>  library's crypt() function, so don't use the -m option.\n>  \n> +Alternatively you can produce the password with perl's crypt() operator:\n> +-----\n> +   perl -e 'my ($user, $pass) = @ARGV; printf \"%s:%s\\n\", $user, crypt($user, $pass)' $USER password\n> +-----\n> +\n>  Then provide your password via the pserver method, for example:\n>  ------\n>     cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n> -- \n> 1.5.3.rc3.120.g68d422\n>\n>\n> From 60f893bd9fe329bd5cf8ec513d10ec00e85feb2c Mon Sep 17 00:00:00 2001\n> From: =?utf-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= <avar@cpan.org>\n> Date: Fri, 7 Mar 2008 16:06:31 +0000\n> Subject: [PATCH] exit after producing the error about anonymous having a password\n>\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>\n> ---\n>  git-cvsserver.perl |    1 +\n>  1 files changed, 1 insertions(+), 0 deletions(-)\n>\n> diff --git a/git-cvsserver.perl b/git-cvsserver.perl\n> index aa0299e..da48ebd 100755\n> --- a/git-cvsserver.perl\n> +++ b/git-cvsserver.perl\n> @@ -160,6 +160,7 @@ if ($state->{method} eq 'pserver') {\n>          if (length($password) > 1 ) {\n>              print \"E Don't supply a password for the `anonymous' user\\n\";\n>              print \"I HATE YOU\\n\";\n> +            exit 1;\n>          }\n>  \n>          # Fall through to LOVE\n> -- \n> 1.5.3.rc3.120.g68d422\n>\n>\n>\n> 1. http://git.nix.is/?p=avar/git;a=commitdiff;h=60f893bd9fe329bd5cf8ec513d10ec00e85feb2c\n\nIt has been over 3 months since I submitted this patch without anyone\nacting on it. In absence of comment from the Mart[yi]ns could this\nplease applied anyway?\n"},{"id":"80352","messageId":"46a038f90806191200n237633u80f0be736e8d227b@mail.gmail.com","threadId":"11282","inReplyTo":"861w2tjpev.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2008-06-19T19:00:03Z","receivedAt":"2008-06-19T19:00:03Z","isPatch":true,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On Thu, Jun 19, 2008 at 1:38 PM, Ævar Arnfjörð Bjarmason <avar@cpan.org> wrote:\n>> 1. http://git.nix.is/?p=avar/git;a=commitdiff;h=60f893bd9fe329bd5cf8ec513d10ec00e85feb2c\n>\n> It has been over 3 months since I submitted this patch without anyone\n> acting on it. In absence of comment from the Mart[yi]ns could this\n> please applied anyway?\n\nSorry. My opinion on this is a mild ACK on the technical front, and a\nbit of a frown (\"do we really want to offer this?\"). Specifically, my\nconcern goes beyond what you can do against a pserver service - git\nhooks can be targeted with this. \"Warning: as safe as telnet\" ;-)\n\ncheers,\n\n\n\nm\n-- \n martin.langhoff@gmail.com\n martin@laptop.org -- School Server Architect\n - ask interesting questions\n - don't get distracted with shiny stuff - working code first\n - http://wiki.laptop.org/go/User:Martinlanghoff\n"},{"id":"80357","messageId":"7vd4mdten7.fsf@gitster.siamese.dyndns.org","threadId":"11282","inReplyTo":"46a038f90806191200n237633u80f0be736e8d227b@mail.gmail.com","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-19T19:21:00Z","receivedAt":"2008-06-19T19:21:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Martin Langhoff\" <martin.langhoff@gmail.com> writes:\n\n> On Thu, Jun 19, 2008 at 1:38 PM, Ævar Arnfjörð Bjarmason <avar@cpan.org> wrote:\n>>> 1. http://git.nix.is/?p=avar/git;a=commitdiff;h=60f893bd9fe329bd5cf8ec513d10ec00e85feb2c\n>>\n>> It has been over 3 months since I submitted this patch without anyone\n>> acting on it. In absence of comment from the Mart[yi]ns could this\n>> please applied anyway?\n>\n> Sorry. My opinion on this is a mild ACK on the technical front, and a\n> bit of a frown (\"do we really want to offer this?\"). Specifically, my\n> concern goes beyond what you can do against a pserver service - git\n> hooks can be targeted with this. \"Warning: as safe as telnet\" ;-)\n\n\"As safe as telnet\" is Ok as long as it is strictly optional.  What I\nwould primarily be worried about is if this change is a no-op for existing\nusers, when they chose not to enable the new feature.\n"},{"id":"80361","messageId":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","threadId":"11282","inReplyTo":"861w2tjpev.fsf@cpan.org","subject":"Re: [PATCH] Authentication support for pserver","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-19T20:14:35Z","receivedAt":"2008-06-19T20:14:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"avar@cpan.org (Ævar Arnfjörð Bjarmason) writes:\n\n> ...\n> It has been over 3 months since I submitted this patch without anyone\n> acting on it. In absence of comment from the Mart[yi]ns could this\n> please applied anyway?\n\nCan you send a patch that can be applied (cf. Documentation/SubmittingPatches)?\n"},{"id":"141709","messageId":"1273891564-7523-1-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 0/6] git-cvsserver: password support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:45:58Z","receivedAt":"2010-05-15T02:45:58Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This series adds optional pserver authentication support to\ngit-cvsserver. It's useful in legacy environments that rely on pserver\nauthentication support, and for various reasons can't easily switch to\nssh-based authentication.\n\nThis series was originally submitted in 2007/2008[1] and approved by\nJunio[2], it stalled because I didn't follow up[3] on sending it in an\napplyable format until now.\n\nChanges since the series was originally submitted:\n\n  - There's now a test for pserver authentication support\n\n  - Fixed the commit message of a few commits & squashed some commits.\n\n  - It now complies with Documentation/SubmittingPatches. I.e. has\n    signed-off-by lines.\n\n  - Changed my E-Mail address in the commits.\n\n1. http://lists-archives.org/git/640574-authentication-support-for-pserver.html \n2. http://lists-archives.org/git/640617-authentication-support-for-pserver.html \n3. http://article.gmane.org/gmane.comp.version-control.git/85521/\n\nSam Vilain (1):\n  git-cvsserver: use a password file cvsserver pserver\n\nÆvar Arnfjörð Bjarmason (5):\n  git-cvsserver: authentication support for pserver\n  git-cvsserver: indent & clean up authdb code\n  git-cvsserver: Improved error handling for pserver\n  git-cvsserver: document making a password without htpasswd\n  git-cvsserver: test for pserver authentication support\n\n Documentation/git-cvsserver.txt |   37 +++++++++++++--\n git-cvsserver.perl              |   97 +++++++++++++++++++++++++++++++++++---\n t/t9400-git-cvsserver-server.sh |   16 ++++++-\n 3 files changed, 137 insertions(+), 13 deletions(-)\n"},{"id":"141711","messageId":"1273891564-7523-2-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 1/6] git-cvsserver: authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:45:59Z","receivedAt":"2010-05-15T02:45:59Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Allow git-cvsserver to use authentication over pserver mode.  The\npserver user/password database is stored in the config file for each\nrepository.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nWorriedly-Acked-by: Martin Langhoff <martin.langhoff@gmail.com>\n---\n Documentation/git-cvsserver.txt |   21 +++++++++--\n git-cvsserver.perl              |   74 ++++++++++++++++++++++++++++++++++----\n 2 files changed, 83 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex dbb053e..f4e1339 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -72,9 +72,6 @@ plugin. Most functionality works fine with both of these clients.\n LIMITATIONS\n -----------\n \n-Currently cvsserver works over SSH connections for read/write clients, and\n-over pserver for anonymous CVS access.\n-\n CVS clients cannot tag, branch or perform GIT merges.\n \n 'git-cvsserver' maps GIT branches to CVS modules. This is very different\n@@ -84,7 +81,7 @@ one or more directories.\n INSTALLATION\n ------------\n \n-1. If you are going to offer anonymous CVS access via pserver, add a line in\n+1. If you are going to offer CVS access via pserver, add a line in\n    /etc/inetd.conf like\n +\n --\n@@ -101,6 +98,22 @@ looks like\n    cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n \n ------\n+\n+Only anonymous access is provided by pserve by default. To commit you\n+will have to create pserver accounts, simply add a [gitcvs.users]\n+section to the repositories you want to access, for example:\n+\n+------\n+   \n+   [gitcvs.users]\n+        someuser = somepassword\n+        otheruser = otherpassword\n+   \n+------\n+Then provide your password via the pserver method, for example:\n+------\n+   cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n+------\n No special setup is needed for SSH access, other than having GIT tools\n in the PATH. If you have clients that do not accept the CVS_SERVER\n environment variable, you can rename 'git-cvsserver' to `cvs`.\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 13751db..d9a26cb 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -183,12 +183,35 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                #print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n+    # For checking whether the user is anonymous on commit\n+    $state->{user} = $user;\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -314,7 +337,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1271,9 +1294,9 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n+    if ( $state->{method} eq 'pserver' and $state->{user} eq 'anonymous' )\n     {\n-        print \"error 1 pserver access cannot commit\\n\";\n+        print \"error 1 anonymous user cannot commit via pserver\\n\";\n         cleanupWorkTree();\n         exit;\n     }\n@@ -2586,6 +2609,41 @@ sub cvs_author\n     $author;\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same password format (A) bas been\n+    # used by CVS since the beginning of time\n+    $str =~ s/^(.)//;\n+    die \"invalid password format $1\" unless $1 eq 'A';\n+\n+    $str =~ s/(.)/chr $SHIFTS[ord $1]/ge;\n+\n+    return $str;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n-- \n1.7.1.84.gd92f8\n"},{"id":"141710","messageId":"1273891564-7523-3-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 2/6] git-cvsserver: use a password file cvsserver pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:46:00Z","receivedAt":"2010-05-15T02:46:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"From: Sam Vilain <sam.vilain@catalyst.net.nz>\n\nIf a git repository is shared via HTTP, the config file is typically\nvisible.  Use an external file instead.\n---\n Documentation/git-cvsserver.txt |   21 ++++++++++++++++-----\n git-cvsserver.perl              |   27 ++++++++++++++-------------\n 2 files changed, 30 insertions(+), 18 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex f4e1339..bc2da8c 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -100,16 +100,27 @@ looks like\n ------\n \n Only anonymous access is provided by pserve by default. To commit you\n-will have to create pserver accounts, simply add a [gitcvs.users]\n-section to the repositories you want to access, for example:\n+will have to create pserver accounts, simply add a gitcvs.authdb\n+setting in the config file of the repositories you want the cvsserver\n+to allow writes to, for example:\n \n ------\n    \n-   [gitcvs.users]\n-        someuser = somepassword\n-        otheruser = otherpassword\n+   [gitcvs]\n+        authdb = /etc/cvsserver/passwd\n    \n ------\n+The format of these files is username followed by the crypted password,\n+for example:\n+\n+------\n+   myuser:$1Oyx5r9mdGZ2\n+   myuser:$1$BA)@$vbnMJMDym7tA32AamXrm./\n+------\n+You can use the 'htpasswd' facility that comes with Apache to make these\n+files, but Apache's MD5 crypt method differs from the one used by most C\n+library's crypt() function, so don't use the -m option.\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex d9a26cb..ca02fba 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -189,24 +189,25 @@ if ($state->{method} eq 'pserver') {\n \n     unless ($user eq 'anonymous') {\n         # Trying to authenticate a user\n-        if (not exists $cfg->{gitcvs}->{users}) {\n-            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+        if (not exists $cfg->{gitcvs}->{authdb}) {\n+            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n-            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+        }\n+\tmy $auth_ok;\n+\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n+\twhile(<PASSWD>) {\n+\t    if (m{^\\Q$user\\E:(.*)}) {\n+\t\tif (crypt($user, $1) eq $1) {\n+\t\t    $auth_ok = 1;\n+\t\t}\n+\t    };\n+\t}\n+\tunless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } else {\n-            my $descrambled_password = descramble($password);\n-            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n-            if ($descrambled_password ne $cleartext_password) {\n-                #print \"E The password supplied for user $user was incorrect\\n\";\n-                print \"I HATE YOU\\n\";\n-                exit 1;\n-            }\n-            # else fall through to LOVE\n         }\n+        # else fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n-- \n1.7.1.84.gd92f8\n"},{"id":"141714","messageId":"1273891564-7523-4-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 3/6] git-cvsserver: indent & clean up authdb code","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:46:01Z","receivedAt":"2010-05-15T02:46:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":" - Indent the last commit to fit with the rest of the code.\n\n - Use lexical filehandles instead of global globs\n\n - Close the filehandle after the password database has been read.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n git-cvsserver.perl |   23 +++++++++++++----------\n 1 files changed, 13 insertions(+), 10 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex ca02fba..9f63c56 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -194,16 +194,19 @@ if ($state->{method} eq 'pserver') {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-\tmy $auth_ok;\n-\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n-\twhile(<PASSWD>) {\n-\t    if (m{^\\Q$user\\E:(.*)}) {\n-\t\tif (crypt($user, $1) eq $1) {\n-\t\t    $auth_ok = 1;\n-\t\t}\n-\t    };\n-\t}\n-\tunless ($auth_ok) {\n+\n+        my $auth_ok;\n+        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n+        while (<$passwd>) {\n+            if (m{^\\Q$user\\E:(.*)}) {\n+                if (crypt($user, $1) eq $1) {\n+                    $auth_ok = 1;\n+                }\n+            };\n+        }\n+        close $passwd;\n+\n+        unless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-- \n1.7.1.84.gd92f8\n"},{"id":"141715","messageId":"1273891564-7523-5-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 4/6] git-cvsserver: Improved error handling for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:46:02Z","receivedAt":"2010-05-15T02:46:02Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"  - Produce an error if the user tries to supply a password for anonymous\n\n  - Clarify the error message produced when there's no [gitcvs.authdb]\n\n  - Produce an E error if the authdb doesn't exist instead of spewing\n    $! to the user\n\n  - do crypt($user, descramble($pass)) eq $hash; crypt($user, $hash)\n    eq $hash would accept any password\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n git-cvsserver.perl |   29 ++++++++++++++++++++++++-----\n 1 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 9f63c56..813df76 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -187,19 +187,37 @@ if ($state->{method} eq 'pserver') {\n     $line = <STDIN>; chomp $line;\n     my $password = $line;\n \n-    unless ($user eq 'anonymous') {\n+    if ($user eq 'anonymous') {\n+        # \"A\" will be 1 byte, use length instead in case the\n+        # encryption method ever changes (yeah, right!)\n+        if (length($password) > 1 ) {\n+            print \"E Don't supply a password for the `anonymous' user\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        }\n+\n+        # Fall through to LOVE\n+    } else {\n         # Trying to authenticate a user\n         if (not exists $cfg->{gitcvs}->{authdb}) {\n-            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n+            print \"E the repo config file needs a [gitcvs] section with an 'authdb' parameter set to the filename of the authentication database\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        }\n+\n+        my $authdb = $cfg->{gitcvs}->{authdb};\n+\n+        unless (-e $authdb) {\n+            print \"E The authentication database specified in [gitcvs.authdb] does not exist\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n \n         my $auth_ok;\n-        open my $passwd, \"<\", $cfg->{gitcvs}->{authdb} or die $!;\n+        open my $passwd, \"<\", $authdb or die $!;\n         while (<$passwd>) {\n             if (m{^\\Q$user\\E:(.*)}) {\n-                if (crypt($user, $1) eq $1) {\n+                if (crypt($user, descramble($password)) eq $1) {\n                     $auth_ok = 1;\n                 }\n             };\n@@ -210,7 +228,8 @@ if ($state->{method} eq 'pserver') {\n             print \"I HATE YOU\\n\";\n             exit 1;\n         }\n-        # else fall through to LOVE\n+\n+        # Fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n-- \n1.7.1.84.gd92f8\n"},{"id":"141713","messageId":"1273891564-7523-6-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 5/6] git-cvsserver: document making a password without htpasswd","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:46:03Z","receivedAt":"2010-05-15T02:46:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This perl snippet is useful for quickly making a password without\nhtpasswd(1).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-cvsserver.txt |    5 +++++\n 1 files changed, 5 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex bc2da8c..5825787 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -121,6 +121,11 @@ You can use the 'htpasswd' facility that comes with Apache to make these\n files, but Apache's MD5 crypt method differs from the one used by most C\n library's crypt() function, so don't use the -m option.\n \n+Alternatively you can produce the password with perl's crypt() operator:\n+-----\n+   perl -e 'my ($user, $pass) = @ARGV; printf \"%s:%s\\n\", $user, crypt($user, $pass)' $USER password\n+-----\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n-- \n1.7.1.84.gd92f8\n"},{"id":"141712","messageId":"1273891564-7523-7-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"7v3an9tc5w.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 6/6] git-cvsserver: test for pserver authentication support","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T02:46:04Z","receivedAt":"2010-05-15T02:46:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t9400-git-cvsserver-server.sh |   16 +++++++++++++++-\n 1 files changed, 15 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh\nindex daef2d6..437e9b8 100755\n--- a/t/t9400-git-cvsserver-server.sh\n+++ b/t/t9400-git-cvsserver-server.sh\n@@ -48,7 +48,9 @@ test_expect_success 'setup' '\n   git pull secondroot master &&\n   git clone -q --bare \"$WORKDIR/.git\" \"$SERVERDIR\" >/dev/null 2>&1 &&\n   GIT_DIR=\"$SERVERDIR\" git config --bool gitcvs.enabled true &&\n-  GIT_DIR=\"$SERVERDIR\" git config gitcvs.logfile \"$SERVERDIR/gitcvs.log\"\n+  GIT_DIR=\"$SERVERDIR\" git config gitcvs.logfile \"$SERVERDIR/gitcvs.log\" &&\n+  GIT_DIR=\"$SERVERDIR\" git config gitcvs.authdb \"$SERVERDIR/auth.db\" &&\n+  echo cvsuser:cvGVEarMLnhlA > \"$SERVERDIR/auth.db\"\n '\n \n # note that cvs doesn't accept absolute pathnames\n@@ -94,6 +96,14 @@ git\n END VERIFICATION REQUEST\n EOF\n \n+cat >login-git-ok <<EOF\n+BEGIN VERIFICATION REQUEST\n+$SERVERDIR\n+cvsuser\n+Ah<Z:yZZ30 e\n+END VERIFICATION REQUEST\n+EOF\n+\n test_expect_success 'pserver authentication' \\\n   'cat request-anonymous | git-cvsserver pserver >log 2>&1 &&\n    sed -ne \\$p log | grep \"^I LOVE YOU\\$\"'\n@@ -107,6 +117,10 @@ test_expect_success 'pserver authentication failure (non-anonymous user)' \\\n    fi &&\n    sed -ne \\$p log | grep \"^I HATE YOU\\$\"'\n \n+test_expect_success 'pserver authentication success (non-anonymous user with password)' \\\n+  'cat login-git-ok | git-cvsserver pserver >log 2>&1 &&\n+   sed -ne \\$p log | grep \"^I LOVE YOU\\$\"'\n+\n test_expect_success 'pserver authentication (login)' \\\n   'cat login-anonymous | git-cvsserver pserver >log 2>&1 &&\n    sed -ne \\$p log | grep \"^I LOVE YOU\\$\"'\n-- \n1.7.1.84.gd92f8\n"},{"id":"141735","messageId":"1273936006-22357-1-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"1273891564-7523-2-git-send-email-avarab@gmail.com","subject":"[PATCH 1/6 v2] git-cvsserver: authentication support for pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T15:06:46Z","receivedAt":"2010-05-15T15:06:46Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Allow git-cvsserver to use authentication over pserver mode.  The\npserver user/password database is stored in the config file for each\nrepository.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nWorriedly-Acked-by: Martin Langhoff <martin.langhoff@gmail.com>\n---\nThe descramble() method was potentially broken if anyone had fed it a\nnon-bytestring. Now it uses unpack() instead of regexes.\n\n Documentation/git-cvsserver.txt |   21 +++++++++--\n git-cvsserver.perl              |   73 ++++++++++++++++++++++++++++++++++----\n 2 files changed, 82 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex dbb053e..f4e1339 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -72,9 +72,6 @@ plugin. Most functionality works fine with both of these clients.\n LIMITATIONS\n -----------\n \n-Currently cvsserver works over SSH connections for read/write clients, and\n-over pserver for anonymous CVS access.\n-\n CVS clients cannot tag, branch or perform GIT merges.\n \n 'git-cvsserver' maps GIT branches to CVS modules. This is very different\n@@ -84,7 +81,7 @@ one or more directories.\n INSTALLATION\n ------------\n \n-1. If you are going to offer anonymous CVS access via pserver, add a line in\n+1. If you are going to offer CVS access via pserver, add a line in\n    /etc/inetd.conf like\n +\n --\n@@ -101,6 +98,22 @@ looks like\n    cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver\n \n ------\n+\n+Only anonymous access is provided by pserve by default. To commit you\n+will have to create pserver accounts, simply add a [gitcvs.users]\n+section to the repositories you want to access, for example:\n+\n+------\n+   \n+   [gitcvs.users]\n+        someuser = somepassword\n+        otheruser = otherpassword\n+   \n+------\n+Then provide your password via the pserver method, for example:\n+------\n+   cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\n+------\n No special setup is needed for SSH access, other than having GIT tools\n in the PATH. If you have clients that do not accept the CVS_SERVER\n environment variable, you can rename 'git-cvsserver' to `cvs`.\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 13751db..7097419 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -183,12 +183,35 @@ if ($state->{method} eq 'pserver') {\n        exit 1;\n     }\n     $line = <STDIN>; chomp $line;\n-    unless ($line eq 'anonymous') {\n-       print \"E Only anonymous user allowed via pserver\\n\";\n-       print \"I HATE YOU\\n\";\n-       exit 1;\n+    my $user = $line;\n+    $line = <STDIN>; chomp $line;\n+    my $password = $line;\n+\n+    unless ($user eq 'anonymous') {\n+        # Trying to authenticate a user\n+        if (not exists $cfg->{gitcvs}->{users}) {\n+            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n+            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+            print \"I HATE YOU\\n\";\n+            exit 1;\n+        } else {\n+            my $descrambled_password = descramble($password);\n+            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n+            if ($descrambled_password ne $cleartext_password) {\n+                #print \"E The password supplied for user $user was incorrect\\n\";\n+                print \"I HATE YOU\\n\";\n+                exit 1;\n+            }\n+            # else fall through to LOVE\n+        }\n     }\n-    $line = <STDIN>; chomp $line;    # validate the password?\n+\n+    # For checking whether the user is anonymous on commit\n+    $state->{user} = $user;\n+\n     $line = <STDIN>; chomp $line;\n     unless ($line eq \"END $request REQUEST\") {\n        die \"E Do not understand $line -- expecting END $request REQUEST\\n\";\n@@ -314,7 +337,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n@@ -1271,9 +1294,9 @@ sub req_ci\n \n     $log->info(\"req_ci : \" . ( defined($data) ? $data : \"[NULL]\" ));\n \n-    if ( $state->{method} eq 'pserver')\n+    if ( $state->{method} eq 'pserver' and $state->{user} eq 'anonymous' )\n     {\n-        print \"error 1 pserver access cannot commit\\n\";\n+        print \"error 1 anonymous user cannot commit via pserver\\n\";\n         cleanupWorkTree();\n         exit;\n     }\n@@ -2586,6 +2609,40 @@ sub cvs_author\n     $author;\n }\n \n+\n+sub descramble\n+{\n+    # This table is from src/scramble.c in the CVS source\n+    my @SHIFTS = (\n+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n+        114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,\n+        111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,\n+        41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,\n+        125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,\n+        36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,\n+        58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,\n+        225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,\n+        199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,\n+        174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,\n+        207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,\n+        192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,\n+        227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,\n+        182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,\n+        243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152\n+    );\n+    my ($str) = @_;\n+\n+    # This should never happen, the same password format (A) bas been\n+    # used by CVS since the beginning of time\n+    die \"invalid password format $1\" unless substr($str, 0, 1) eq 'A';\n+\n+    my @str = unpack \"C*\", substr($str, 1);\n+    my $ret = join '', map { chr $SHIFTS[$_] } @str;\n+    return $ret;\n+}\n+\n+\n package GITCVS::log;\n \n ####\n-- \n1.7.1.84.gd92f8\n"},{"id":"141736","messageId":"1273936074-22401-1-git-send-email-avarab@gmail.com","threadId":"11282","inReplyTo":"1273891564-7523-3-git-send-email-avarab@gmail.com","subject":"[PATCH 2/6 v2] git-cvsserver: use a password file cvsserver pserver","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T15:07:54Z","receivedAt":"2010-05-15T15:07:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"From: Sam Vilain <sam.vilain@catalyst.net.nz>\n\nIf a git repository is shared via HTTP, the config file is typically\nvisible.  Use an external file instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\nThis patch was missing a removal of the gitcvs.users config key\nintroduced in the last patch.\n\n Documentation/git-cvsserver.txt |   21 ++++++++++++++++-----\n git-cvsserver.perl              |   29 +++++++++++++++--------------\n 2 files changed, 31 insertions(+), 19 deletions(-)\n\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex f4e1339..bc2da8c 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -100,16 +100,27 @@ looks like\n ------\n \n Only anonymous access is provided by pserve by default. To commit you\n-will have to create pserver accounts, simply add a [gitcvs.users]\n-section to the repositories you want to access, for example:\n+will have to create pserver accounts, simply add a gitcvs.authdb\n+setting in the config file of the repositories you want the cvsserver\n+to allow writes to, for example:\n \n ------\n    \n-   [gitcvs.users]\n-        someuser = somepassword\n-        otheruser = otherpassword\n+   [gitcvs]\n+        authdb = /etc/cvsserver/passwd\n    \n ------\n+The format of these files is username followed by the crypted password,\n+for example:\n+\n+------\n+   myuser:$1Oyx5r9mdGZ2\n+   myuser:$1$BA)@$vbnMJMDym7tA32AamXrm./\n+------\n+You can use the 'htpasswd' facility that comes with Apache to make these\n+files, but Apache's MD5 crypt method differs from the one used by most C\n+library's crypt() function, so don't use the -m option.\n+\n Then provide your password via the pserver method, for example:\n ------\n    cvs -d:pserver:someuser:somepassword <at> server/path/repo.git co <HEAD_name>\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 7097419..8b97fb8 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -189,24 +189,25 @@ if ($state->{method} eq 'pserver') {\n \n     unless ($user eq 'anonymous') {\n         # Trying to authenticate a user\n-        if (not exists $cfg->{gitcvs}->{users}) {\n-            print \"E the repo config file needs a [gitcvs.users] section with user/password key-value pairs\\n\";\n+        if (not exists $cfg->{gitcvs}->{authdb}) {\n+            print \"E the repo config file needs a [gitcvs.authdb] section with a filename\\n\";\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } elsif (exists $cfg->{gitcvs}->{users} and not exists $cfg->{gitcvs}->{users}->{$user}) {\n-            #print \"E the repo config file has a [gitcvs.users] section but the user $user is not defined in it\\n\";\n+        }\n+\tmy $auth_ok;\n+\topen PASSWD, \"<$cfg->{gitcvs}->{authdb}\" or die $!;\n+\twhile(<PASSWD>) {\n+\t    if (m{^\\Q$user\\E:(.*)}) {\n+\t\tif (crypt($user, $1) eq $1) {\n+\t\t    $auth_ok = 1;\n+\t\t}\n+\t    };\n+\t}\n+\tunless ($auth_ok) {\n             print \"I HATE YOU\\n\";\n             exit 1;\n-        } else {\n-            my $descrambled_password = descramble($password);\n-            my $cleartext_password = $cfg->{gitcvs}->{users}->{$user};\n-            if ($descrambled_password ne $cleartext_password) {\n-                #print \"E The password supplied for user $user was incorrect\\n\";\n-                print \"I HATE YOU\\n\";\n-                exit 1;\n-            }\n-            # else fall through to LOVE\n         }\n+        # else fall through to LOVE\n     }\n \n     # For checking whether the user is anonymous on commit\n@@ -337,7 +338,7 @@ sub req_Root\n     }\n     foreach my $line ( @gitvars )\n     {\n-        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver|users)\\.)?([\\w-]+)=(.*)$/ );\n+        next unless ( $line =~ /^(gitcvs)\\.(?:(ext|pserver)\\.)?([\\w-]+)=(.*)$/ );\n         unless ($2) {\n             $cfg->{$1}{$3} = $4;\n         } else {\n-- \n1.7.1.84.gd92f8\n"}]}