bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PATCH


From: Mathias Herberts
Subject: Re: PATCH
Date: Thu, 23 Oct 2003 20:54:44 +0000
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021130

Ok, here it is then.

My patch modifies src/server.c:check_repository_password so it can check a user password using an external authentication process. I basically wrote that so I could authenticate my CVS users against our corporate Active Directory.

The patch relies on a special syntax of the password field in CVSROOT/passwd. If the password starts with an at sign '@' then everything following the '@' up to the ':' is considered a path to an authentication program. As the salt used by crypt(3) cannot contain '@' we can still use regular encrypted passwords.

If the password field is a path to an authentication program AND there is a sysuser field on the line then we call the program with three parameters: repository username password. If the exit status of the program is 0 the authentication is considered successful, otherwise it is considered to have failed. The sysuser field is mandatory for my patch because the users authenticated this way have a high probability of not existing as system accounts on the server machine (at least it was the case for my use of AD).

There is a security issue related to the cleartext password being fed as a parameter to the authentication program, and thus possibly appearing on a process listing. This is something that was bareable for my set up.

The call to the authentication program is done via system(3) with stdout and stderr being redirected to /dev/null, whether or not this would work on a Windows server is something I do not know.

The patch included is against 1.11.6, it applies verbatim to 1.11.9 with a two lines offset.

Please provide any feedback you think is necessary.

Thanks for your job on CVS.

Regards,

Mathias.

Larry Jones wrote:
Mathias Herberts writes:

I created a patch for CVS to allow for external authentication, I do not know where to send my patch. Could you please provide me with a pointer to the right place to submit it.


Right here: address@hidden

-Larry Jones

Sheesh.  Who can fathom the feminine mind? -- Calvin
--- src/server.c.orig   Thu May  1 22:38:16 2003
+++ src/server.c        Thu Oct 23 17:20:25 2003
@@ -5265,6 +5265,7 @@
 check_repository_password (username, password, repository, host_user_ptr)
      char *username, *password, *repository, **host_user_ptr;
 {
+    int extauth = 0;
     int retval = 0;
     FILE *fp;
     char *filename;
@@ -5370,12 +5371,70 @@
            host_user_tmp = strtok (NULL, ":");
        }
 
+       /*
+        * We have an existing system user portion, check the
+        * password field to see if it is a reference to an
+        * external authentication program, such references are
+        * of the form: @/PATH/TO/AUTH/PROGRAM
+        */
+
+       if (host_user_tmp != NULL && found_password != NULL)
+       {
+         if (found_password[0] == '@')
+         {
+           int res;
+           int len;
+           char * cmdbuf;
+           
+           /*
+            * The password field is a reference to an external
+            * authentication program, call it with arguments
+            *
+            * repository username password
+            */
+
+           /*
+            * Allocate memory for cmdbuf, size is that
+            * of found_password - 1 (for the program path),
+            *  + repository
+            *  + username
+            *  + password
+            *  + 3 white spaces
+            *  + terminating null.
+            */
+
+           len = strlen (found_password)
+             + strlen (repository)
+             + strlen (username)
+             + strlen (password)
+             + strlen (">/dev/null 2>&1")
+             + 4; /* white spaces */
+
+           cmdbuf = (char *) malloc (len);
+
+           if (cmdbuf != (char *) NULL)
+           {
+             snprintf (cmdbuf, len, "%s %s %s %s >/dev/null 2>&1", 
found_password + 1, repository, username, password);
+
+             res = system (cmdbuf);
+
+             if (res == 0)
+             {
+               extauth = 1;
+             }
+
+             free (cmdbuf);
+           }
+         }
+       }
+
        /* Of course, maybe there was no system user portion... */
        if (host_user_tmp == NULL)
            host_user_tmp = username;
 
        /* Verify blank passwords directly, otherwise use crypt(). */
-       if ((found_password == NULL)
+       if ((extauth == 1)
+           || (found_password == NULL)
            || ((strcmp (found_password, crypt (password, found_password))
                 == 0)))
        {

reply via email to

[Prev in Thread] Current Thread [Next in Thread]