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