diff -urN authlib/Makefile.in authlib/Makefile.in --- authlib/Makefile.in Thu Aug 8 12:47:55 2002 +++ authlib/Makefile.in Tue Dec 3 17:52:07 2002 @@ -301,7 +301,7 @@ authvchkpw_SOURCES = mod.h modauthvchkpw.c authvchkpw_DEPENDENCIES = libauthmod.a libauth.a @MD5LIB@ @SHA1LIB@ -authvchkpw_LDADD = libauthmod.a libauth.a ../numlib/libnumlib.a @MD5LIB@ @SHA1LIB@ @VPOPMAILLIBS@ @LIBM@ $(CRYPTLIBS) +authvchkpw_LDADD = libauthmod.a libauth.a ../numlib/libnumlib.a @HMACLIB@ @MD5LIB@ @SHA1LIB@ @VPOPMAILLIBS@ @LIBM@ $(CRYPTLIBS) authcram_SOURCES = mod.h modauthcram.c authcram_DEPENDENCIES = libauthmod.a libauth.a @HMACLIB@ ../userdb/libuserdb.a \ diff -urN authlib/authvchkpw.c authlib/authvchkpw.c --- authlib/authvchkpw.c Thu Jul 26 06:29:34 2001 +++ authlib/authvchkpw.c Tue Dec 3 17:52:07 2002 @@ -64,8 +64,8 @@ return (0); } -char *auth_vchkpw(const char *service, const char *authtype, char *authdata, - int issession, +static char *auth_vchkpw_login(const char *service, const char *authtype, + char *authdata, int issession, void (*callback_func)(struct authinfo *, void *), void *callback_arg) { char *user, *pass; @@ -100,6 +100,155 @@ putenv("MAILDIR="); return (ci.userret); +} + +#if HAVE_HMACLIB + +#include "../libhmac/hmac.h" +#include "cramlib.h" + +struct vchkpw_cram_callback_info { + struct hmac_hashinfo *h; + char *user; + char *challenge; + char *response; + char *userret; + int issession; + void (*callback_func)(struct authinfo *, void *); + void *callback_arg; + }; + +static int callback_cram(struct authinfo *a, void *vp) +{ +struct vchkpw_cram_callback_info *cci=(struct vchkpw_cram_callback_info *)vp; +unsigned char *hashbuf; +unsigned char *p; +unsigned i; +static const char hex[]="0123456789abcdef"; +int rc; + + if (!a->clearpasswd) + return (-1); + + /* + hmac->hh_L*2 will be the size of the binary hash. + + hmac->hh_L*4+1 will therefore be size of the binary hash, + as a hexadecimal string. + */ + + if ((hashbuf=malloc(cci->h->hh_L*6+1)) == 0) + return (1); + + hmac_hashkey(cci->h, a->clearpasswd, strlen(a->clearpasswd), + hashbuf, hashbuf+cci->h->hh_L); + + p=hashbuf+cci->h->hh_L*2; + + for (i=0; ih->hh_L*2; i++) + { + char c; + + c = hex[ (hashbuf[i] >> 4) & 0x0F]; + *p++=c; + + c = hex[ hashbuf[i] & 0x0F]; + *p++=c; + + *p=0; + } + + rc=auth_verify_cram(cci->h, cci->challenge, cci->response, + (const char *)hashbuf+cci->h->hh_L*2); + free(hashbuf); + + if (rc) return (rc); + + if ((cci->userret=strdup(a->address)) == 0) + { + perror("malloc"); + return (1); + } + + if (cci->callback_func) + (*cci->callback_func)(a, cci->callback_arg); + else + { + authsuccess(a->homedir, a->sysusername, a->sysuserid, + &a->sysgroupid, + a->address, + a->quota); + + if (a->maildir && a->maildir[0]) + { + static char *maildir=0; + + if (maildir) free(maildir); + maildir=malloc(sizeof("MAILDIR=")+strlen(a->maildir)); + if (!maildir) + { + perror("malloc"); + exit(1); + } + strcat(strcpy(maildir, "MAILDIR="), a->maildir); + putenv(maildir); + } + else + { + putenv("MAILDIR="); + } + } + + return (0); +} + +static char *auth_vchkpw_cram(const char *service, + const char *authtype, char *authdata, int issession, + void (*callback_func)(struct authinfo *, void *), void *callback_arg) +{ +struct vchkpw_cram_callback_info cci; +int rc; + + if (auth_get_cram(authtype, authdata, + &cci.h, &cci.user, &cci.challenge, &cci.response)) + return (0); + + cci.issession=issession; + cci.callback_func=callback_func; + cci.callback_arg=callback_arg; + + rc=auth_vchkpw_pre(cci.user, service, &callback_cram, &cci); + + if (rc < 0) + { + errno=EPERM; + return (0); + } + if (rc > 0) + { + errno=EACCES; + return (0); + } + return (cci.userret); +} +#endif + +char *auth_vchkpw(const char *service, const char *authtype, char *authdata, + int issession, + void (*callback_func)(struct authinfo *, void *), void *callback_arg) +{ + if (strcmp(authtype, AUTHTYPE_LOGIN) == 0) + return (auth_vchkpw_login(service, authtype, authdata, + issession, callback_func, callback_arg)); + +#if HAVE_HMACLIB + return (auth_vchkpw_cram(service, authtype, authdata, issession, + callback_func, callback_arg)); +#else + errno=EPERM; + return (0); +#endif + } static void authvchkpwclose() diff -urN authlib/preauthvchkpw.c authlib/preauthvchkpw.c --- authlib/preauthvchkpw.c Sat Feb 2 14:07:33 2002 +++ authlib/preauthvchkpw.c Tue Dec 3 17:54:19 2002 @@ -96,12 +96,15 @@ } } +/* auth.sysusername=vpw->pw_name; */ auth.sysuserid=&uid; auth.sysgroupid=gid; auth.homedir=vpw->pw_dir; auth.address=userid; auth.fullname=vpw->pw_gecos; + auth.quota=vpw->pw_shell; auth.passwd=vpw->pw_passwd; + auth.clearpasswd=vpw->pw_clear_passwd; return ((*callback)(&auth, arg)); }