Hello,

Nicholas Marriott schrieb am 02.07.2011 um 23:11:49 +0100:
> Hi
> 
> I don't think you need to strsep out the style yourself, a NULL style to
> auth_userokay will look for it after a : itself.
> 
> Otherwise this reads fine to me.
> 
> 
> On Mon, Jun 27, 2011 at 07:30:53PM +0200, Nils Anspach wrote:
> > Hello list,
> > 
> > attached is a patch for popa3d(8) to use BSD authentication.
> > 
> > Currently, to authenticate users, popa3d(8) encrypts the user-provided
> > password via crypt(3) and then compares the hash with the passwd field
> > from master.passwd(5).  This method however does not work if users are
> > authenticated by other means when logging into the machine (e.g. via
> > login_ldap(8)).  The attached patch allows for such authentication
> > styles.
> > 
> > Nils
> > Index: auth_passwd.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/popa3d/auth_passwd.c,v
> > retrieving revision 1.2
> > diff -u -r1.2 auth_passwd.c
> > --- auth_passwd.c   21 Sep 2001 20:22:06 -0000      1.2
> > +++ auth_passwd.c   27 Jun 2011 16:48:21 -0000
> > @@ -6,7 +6,7 @@
> >  
> >  #include "params.h"
> >  
> > -#if AUTH_PASSWD && !VIRTUAL_ONLY
> > +#if BSD_AUTH && !VIRTUAL_ONLY
> >  
> >  #define _XOPEN_SOURCE 4
> >  #define _XOPEN_SOURCE_EXTENDED
> > @@ -16,8 +16,10 @@
> >  #include <string.h>
> >  #include <pwd.h>
> >  #include <sys/types.h>
> > +#include <login_cap.h>
> > +#include <bsd_auth.h>
> >  
> > -struct passwd *auth_userpass(char *user, char *pass, int *known)
> > +struct passwd *auth_userpass(char *user, char *style, char *pass, int 
> > *known)
> >  {
> >     struct passwd *pw, *result;
> >  
> > @@ -25,11 +27,7 @@
> >     endpwent();
> >     result = NULL;
> >  
> > -   if (!pw || !*pw->pw_passwd ||
> > -       *pw->pw_passwd == '*' || *pw->pw_passwd == '!')
> > -           crypt(pass, AUTH_DUMMY_SALT);
> > -   else
> > -   if (!strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd))
> > +   if (pw && auth_userokay(user, style, BSD_AUTH_TYPE, pass))
> >             result = pw;
> >  
> >     if (pw)
> > Index: params.h
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/popa3d/params.h,v
> > retrieving revision 1.9
> > diff -u -r1.9 params.h
> > --- params.h        16 Dec 2009 20:42:26 -0000      1.9
> > +++ params.h        27 Jun 2011 16:48:22 -0000
> > @@ -142,15 +142,23 @@
> >  /*
> >   * Choose the password authentication method your system uses:
> >   *
> > - * AUTH_PASSWD             Use getpwnam(3) only, for *BSD or readable 
> > passwd;
> > - *
> > - * Note that there's no built-in password aging support.
> > + * BSD_AUTH                Use BSD Authentication.
> > + * 
> >   */
> > -#define AUTH_PASSWD                        1
> > +#define BSD_AUTH                   1
> > +
> > +#if BSD_AUTH
> > +
> > +/*
> > + * BSD Authentication type
> > + */
> > +#define BSD_AUTH_TYPE                      "auth-popa3d"
> > +
> > +#endif
> >  
> >  #endif
> >  
> > -#if POP_VIRTUAL || AUTH_PASSWD
> > +#if POP_VIRTUAL
> >  
> >  /*
> >   * A salt used to waste some CPU time on dummy crypt(3) calls and make
> > Index: pop_root.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/popa3d/pop_root.c,v
> > retrieving revision 1.5
> > diff -u -r1.5 pop_root.c
> > --- pop_root.c      3 May 2005 05:44:35 -0000       1.5
> > +++ pop_root.c      27 Jun 2011 16:48:22 -0000
> > @@ -9,7 +9,7 @@
> >   * startup.c               if supporting command line options (POP_OPTIONS)
> >   * standalone.c            if not running via an inetd clone 
> > (POP_STANDALONE)
> >   * virtual.c               if supporting virtual domains (POP_VIRTUAL)
> > - * auth_passwd.c   if using passwd or *BSD (AUTH_PASSWD && !VIRTUAL_ONLY)
> > + * auth_passwd.c   if using BSD Auth. (BSD_AUTH && !VIRTUAL_ONLY)
> >   */
> >  
> >  #include <unistd.h>
> > @@ -34,7 +34,7 @@
> >  #endif
> >  
> >  #if !VIRTUAL_ONLY
> > -extern struct passwd *auth_userpass(char *user, char *pass, int *known);
> > +extern struct passwd *auth_userpass(char *user, char *style, char *pass, 
> > int *known);
> >  #endif
> >  
> >  /* POP_USER's pw_uid and pw_gid, other fields may not be valid */
> > @@ -110,6 +110,9 @@
> >  {
> >     static char auth[AUTH_BUFFER_SIZE + 2];
> >     char *pass;
> > +#if BSD_AUTH
> > +   char *style;
> > +#endif
> >     struct passwd *pw;
> >  
> >     known = 0;
> > @@ -130,8 +133,15 @@
> >             return AUTH_NONE;
> >     }
> >  
> > +#if BSD_AUTH
> > +   style = auth;
> > +   pass = &style[strlen(style) + 1];
> > +   user = strsep(&style, ":");
> > +#else
> >     user = auth;
> >     pass = &user[strlen(user) + 1];
> > +#endif
> > +   if (!*pass) return AUTH_FAILED;
> >  
> >     pw = NULL;
> >  #if POP_VIRTUAL
> > @@ -145,13 +155,17 @@
> >             memset(pass, 0, strlen(pass));
> >             return AUTH_FAILED;
> >     }
> > +#elif BSD_AUTH
> > +   if (!pw && !(pw = auth_userpass(user, style, pass, &known))) {
> > +           memset(pass, 0, strlen(pass));
> > +           return AUTH_FAILED;
> > +   }
> >  #else
> > -   if (!pw && !(pw = auth_userpass(user, pass, &known))) {
> > +   if (!pw) {
> >             memset(pass, 0, strlen(pass));
> >             return AUTH_FAILED;
> >     }
> >  #endif
> > -   if (!*pass) return AUTH_FAILED;
> >     memset(pass, 0, strlen(pass));
> >     if (!*user) return AUTH_FAILED;
> >  
> > Index: popa3d.8
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/popa3d/popa3d.8,v
> > retrieving revision 1.14
> > diff -u -r1.14 popa3d.8
> > --- popa3d.8        31 May 2007 19:20:27 -0000      1.14
> > +++ popa3d.8        27 Jun 2011 16:48:22 -0000
> > @@ -102,6 +102,12 @@
> >  .Pp
> >  .Dl pop3 stream tcp nowait root /usr/libexec/tcpd /usr/sbin/popa3d
> >  .Pp
> > +.Nm
> > +uses BSD Authentication with authentication type
> > +.Dq auth-popa3d
> > +for the given username and password ; see
> > +.Xr login.conf 5 .
> > +.Pp
> >  For access to a mailbox through the POP3 service, the username must
> >  be in the password database.
> >  Additionally,
> > @@ -165,6 +171,7 @@
> >  .Sh SEE ALSO
> >  .Xr hosts_access 5 ,
> >  .Xr inetd 8 ,
> > +.Xr login.conf 5 ,
> >  .Xr sendmail 8 ,
> >  .Xr tcpd 8
> >  .Pp

popa3d(8) wants to log known, but non-authenticated users too, so it
needs the username (without the :style part), and in case of successful
authentication it needs some data from the passwd structure, too.  So,
simply auth_userokay'ing is not enough.

In the following diff, the strsep part is put into auth_userpass.  Might
be more appropriate.

Comments? Suggestions?

Nils
Index: auth_passwd.c
===================================================================
RCS file: /cvs/src/usr.sbin/popa3d/auth_passwd.c,v
retrieving revision 1.2
diff -u -r1.2 auth_passwd.c
--- auth_passwd.c       21 Sep 2001 20:22:06 -0000      1.2
+++ auth_passwd.c       4 Jul 2011 21:30:48 -0000
@@ -1,12 +1,12 @@
 /* $OpenBSD: auth_passwd.c,v 1.2 2001/09/21 20:22:06 camield Exp $ */
 
 /*
- * The /etc/passwd authentication routine.
+ * The BSD authentication routine.
  */
 
 #include "params.h"
 
-#if AUTH_PASSWD && !VIRTUAL_ONLY
+#if BSD_AUTH && !VIRTUAL_ONLY
 
 #define _XOPEN_SOURCE 4
 #define _XOPEN_SOURCE_EXTENDED
@@ -16,24 +16,29 @@
 #include <string.h>
 #include <pwd.h>
 #include <sys/types.h>
+#include <login_cap.h>
+#include <bsd_auth.h>
 
 struct passwd *auth_userpass(char *user, char *pass, int *known)
 {
+       char *name; 
        struct passwd *pw, *result;
 
-       *known = (pw = getpwnam(user)) != NULL;
-       endpwent();
+       pw = NULL;
        result = NULL;
 
-       if (!pw || !*pw->pw_passwd ||
-           *pw->pw_passwd == '*' || *pw->pw_passwd == '!')
-               crypt(pass, AUTH_DUMMY_SALT);
-       else
-       if (!strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd))
+       if (name = strsep(&user, ":")) {
+               *known = (pw = getpwnam(name)) != NULL;
+               endpwent();
+       }
+
+       if (pw && auth_userokay(name, user, BSD_AUTH_TYPE, pass))
                result = pw;
 
        if (pw)
                memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
+
+       user = name;
 
        return result;
 }
Index: params.h
===================================================================
RCS file: /cvs/src/usr.sbin/popa3d/params.h,v
retrieving revision 1.9
diff -u -r1.9 params.h
--- params.h    16 Dec 2009 20:42:26 -0000      1.9
+++ params.h    4 Jul 2011 21:30:48 -0000
@@ -142,15 +142,23 @@
 /*
  * Choose the password authentication method your system uses:
  *
- * AUTH_PASSWD         Use getpwnam(3) only, for *BSD or readable passwd;
- *
- * Note that there's no built-in password aging support.
+ * BSD_AUTH            Use BSD Authentication.
+ * 
  */
-#define AUTH_PASSWD                    1
+#define BSD_AUTH                       1
+
+#if BSD_AUTH
+
+/*
+ * BSD Authentication type
+ */
+#define BSD_AUTH_TYPE                  "auth-popa3d"
+
+#endif
 
 #endif
 
-#if POP_VIRTUAL || AUTH_PASSWD
+#if POP_VIRTUAL
 
 /*
  * A salt used to waste some CPU time on dummy crypt(3) calls and make
Index: pop_root.c
===================================================================
RCS file: /cvs/src/usr.sbin/popa3d/pop_root.c,v
retrieving revision 1.5
diff -u -r1.5 pop_root.c
--- pop_root.c  3 May 2005 05:44:35 -0000       1.5
+++ pop_root.c  4 Jul 2011 21:30:48 -0000
@@ -9,7 +9,7 @@
  * startup.c           if supporting command line options (POP_OPTIONS)
  * standalone.c                if not running via an inetd clone 
(POP_STANDALONE)
  * virtual.c           if supporting virtual domains (POP_VIRTUAL)
- * auth_passwd.c       if using passwd or *BSD (AUTH_PASSWD && !VIRTUAL_ONLY)
+ * auth_passwd.c       if using BSD Auth. (BSD_AUTH && !VIRTUAL_ONLY)
  */
 
 #include <unistd.h>
@@ -133,6 +133,8 @@
        user = auth;
        pass = &user[strlen(user) + 1];
 
+       if (!*pass) return AUTH_FAILED;
+
        pw = NULL;
 #if POP_VIRTUAL
        if (!(pw = virtual_userpass(user, pass, &known)) && virtual_domain) {
@@ -145,13 +147,17 @@
                memset(pass, 0, strlen(pass));
                return AUTH_FAILED;
        }
-#else
+#elif BSD_AUTH
        if (!pw && !(pw = auth_userpass(user, pass, &known))) {
                memset(pass, 0, strlen(pass));
                return AUTH_FAILED;
        }
+#else
+       if (!pw) {
+               memset(pass, 0, strlen(pass));
+               return AUTH_FAILED;
+       }
 #endif
-       if (!*pass) return AUTH_FAILED;
        memset(pass, 0, strlen(pass));
        if (!*user) return AUTH_FAILED;
 
Index: popa3d.8
===================================================================
RCS file: /cvs/src/usr.sbin/popa3d/popa3d.8,v
retrieving revision 1.14
diff -u -r1.14 popa3d.8
--- popa3d.8    31 May 2007 19:20:27 -0000      1.14
+++ popa3d.8    4 Jul 2011 21:30:48 -0000
@@ -102,6 +102,12 @@
 .Pp
 .Dl pop3 stream tcp nowait root /usr/libexec/tcpd /usr/sbin/popa3d
 .Pp
+.Nm
+uses BSD Authentication with authentication type
+.Dq auth-popa3d
+for the given username and password ; see
+.Xr login.conf 5 .
+.Pp
 For access to a mailbox through the POP3 service, the username must
 be in the password database.
 Additionally,
@@ -165,6 +171,7 @@
 .Sh SEE ALSO
 .Xr hosts_access 5 ,
 .Xr inetd 8 ,
+.Xr login.conf 5 ,
 .Xr sendmail 8 ,
 .Xr tcpd 8
 .Pp

Reply via email to