X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_dhx_passwd.c;h=bc91aca60cf80599fd7f069a7658b0b2424d8985;hb=57bbe088b549eb7b0189c90ad7e733b113ffcf28;hp=2a28f99f9c8b31fa0879a959004684b37a3dbccb;hpb=eaf59ab61214a746387fd0b1deb4b0f587069780;p=netatalk.git diff --git a/etc/uams/uams_dhx_passwd.c b/etc/uams/uams_dhx_passwd.c index 2a28f99f..bc91aca6 100644 --- a/etc/uams/uams_dhx_passwd.c +++ b/etc/uams/uams_dhx_passwd.c @@ -1,5 +1,5 @@ /* - * $Id: uams_dhx_passwd.c,v 1.15 2002-02-13 16:44:59 srittau Exp $ + * $Id: uams_dhx_passwd.c,v 1.29 2010-03-30 12:44:35 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -10,23 +10,35 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#ifdef NETBSD +#define _XOPEN_SOURCE 500 /* for crypt() */ +#endif +#ifdef FREEBSD +#define _XOPEN_SOURCE /* for crypt() */ +#endif + #include #include #include #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_H */ -#ifndef NO_CRYPT_H +#ifdef HAVE_CRYPT_H #include -#endif /* ! NO_CRYPT_H */ +#endif /* ! HAVE_CRYPT_H */ +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif #include -#include - #ifdef SHADOWPW #include #endif /* SHADOWPW */ - -#ifdef OPENSSL_DHX +#if defined(GNUTLS_DHX) +#include +#elif defined(OPENSSL_DHX) #include #include #include @@ -36,6 +48,7 @@ #include #endif /* OPENSSL_DHX */ +#include #include #include @@ -57,13 +70,13 @@ static u_int8_t randbuf[16]; #include #include -static char *clientname; +static const char *clientname; #endif /* TRU64 */ /* dhx passwd */ -static int passwd_login(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int pwd_login(void *obj, char *username, int ulen, struct passwd **uam_pwd _U_, + char *ibuf, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { unsigned char iv[] = "CJalbert"; u_int8_t p[] = {0xBA, 0x28, 0x73, 0xDF, 0xB0, 0x60, 0x57, 0xD4, @@ -74,48 +87,35 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, #endif /* SHADOWPW */ BIGNUM *bn, *gbn, *pbn; u_int16_t sessid; - int len, i; - char *name; + size_t i; DH *dh; #ifdef TRU64 - static const char rnd_seed[] = "string to make the random number generator think it has entropy"; - RAND_seed(rnd_seed, sizeof rnd_seed); + int rnd_seed[256]; + for (i = 0; i < 256; i++) + rnd_seed[i] = random(); + RAND_seed(rnd_seed, sizeof(rnd_seed)); #endif /* TRU64 */ *rbuflen = 0; - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, (void *) &name, &i) < 0) - return AFPERR_PARAM; - #ifdef TRU64 if( uam_afpserver_option( obj, UAM_OPTION_CLIENTNAME, (void *) &clientname, NULL ) < 0 ) return AFPERR_PARAM; #endif /* TRU64 */ - len = (unsigned char) *ibuf++; - if ( len + 1 > i ) { - return( AFPERR_PARAM ); - } - - memcpy(name, ibuf, len ); - ibuf += len; - name[ len ] = '\0'; - if ((unsigned long) ibuf & 1) /* padding */ - ++ibuf; - - if (( dhxpwd = uam_getname(name, i)) == NULL ) { - return AFPERR_PARAM; + if (( dhxpwd = uam_getname(obj, username, ulen)) == NULL ) { + return AFPERR_NOTAUTH; } - - LOG(log_info, logtype_default, "dhx login: %s", name); + + LOG(log_info, logtype_uams, "dhx login: %s", username); if (uam_checkuser(dhxpwd) < 0) return AFPERR_NOTAUTH; #ifdef SHADOWPW if (( sp = getspnam( dhxpwd->pw_name )) == NULL ) { - LOG(log_info, logtype_default, "no shadow passwd entry for %s", name); + LOG(log_info, logtype_uams, "no shadow passwd entry for %s", username); return AFPERR_NOTAUTH; } dhxpwd->pw_passwd = sp->sp_pwdp; @@ -125,7 +125,7 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, return AFPERR_NOTAUTH; /* get the client's public key */ - if (!(bn = BN_bin2bn(ibuf, KEYSIZE, NULL))) { + if (!(bn = BN_bin2bn((unsigned char *)ibuf, KEYSIZE, NULL))) { return AFPERR_PARAM; } @@ -157,10 +157,10 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, } /* figure out the key. use rbuf as a temporary buffer. */ - i = DH_compute_key(rbuf, bn, dh); + i = DH_compute_key((unsigned char *)rbuf, bn, dh); /* set the key */ - CAST_set_key(&castkey, i, rbuf); + CAST_set_key(&castkey, i, (unsigned char *)rbuf); /* session id. it's just a hashed version of the object pointer. */ sessid = dhxhash(obj); @@ -169,7 +169,7 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, *rbuflen += sizeof(sessid); /* send our public key */ - BN_bn2bin(dh->pub_key, rbuf); + BN_bn2bin(dh->pub_key, (unsigned char *)rbuf); rbuf += KEYSIZE; *rbuflen += KEYSIZE; @@ -195,7 +195,7 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, #endif /* 0 */ /* encrypt using cast */ - CAST_cbc_encrypt(rbuf, rbuf, CRYPTBUFLEN, &castkey, iv, CAST_ENCRYPT); + CAST_cbc_encrypt((unsigned char *)rbuf, (unsigned char *)rbuf, CRYPTBUFLEN, &castkey, iv, CAST_ENCRYPT); *rbuflen += CRYPTBUFLEN; BN_free(bn); DH_free(dh); @@ -207,14 +207,87 @@ passwd_fail: return AFPERR_PARAM; } +/* cleartxt login */ +static int passwd_login(void *obj, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + size_t len, ulen; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (ibuflen < 2) { + return( AFPERR_PARAM ); + } + + len = (unsigned char) *ibuf++; + ibuflen--; + if (!len || len > ibuflen || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, ibuf, len ); + ibuf += len; + ibuflen -=len; + username[ len ] = '\0'; + + if ((unsigned long) ibuf & 1) { /* pad character */ + ++ibuf; + ibuflen--; + } + return (pwd_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); + +} + +/* cleartxt login ext + * uname format : + byte 3 + 2 bytes len (network order) + len bytes utf8 name +*/ +static int passwd_login_ext(void *obj, char *uname, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + size_t len, ulen; + u_int16_t temp16; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (*uname != 3) + return AFPERR_PARAM; + uname++; + memcpy(&temp16, uname, sizeof(temp16)); + len = ntohs(temp16); + if (!len || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, uname +2, len ); + username[ len ] = '\0'; + return (pwd_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + static int passwd_logincont(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *ibuf, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { +#ifdef SHADOWPW + struct spwd *sp; +#endif /* SHADOWPW */ unsigned char iv[] = "LWallace"; BIGNUM *bn1, *bn2, *bn3; u_int16_t sessid; char *p; + int err = AFPERR_NOTAUTH; *rbuflen = 0; @@ -225,12 +298,12 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, ibuf += sizeof(sessid); /* use rbuf as scratch space */ - CAST_cbc_encrypt(ibuf, rbuf, CRYPT2BUFLEN, &castkey, + CAST_cbc_encrypt((unsigned char *)ibuf, (unsigned char *)rbuf, CRYPT2BUFLEN, &castkey, iv, CAST_DECRYPT); /* check to make sure that the random number is the same. we * get sent back an incremented random number. */ - if (!(bn1 = BN_bin2bn(rbuf, KEYSIZE, NULL))) + if (!(bn1 = BN_bin2bn((unsigned char *)rbuf, KEYSIZE, NULL))) return AFPERR_PARAM; if (!(bn2 = BN_bin2bn(randbuf, sizeof(randbuf), NULL))) { @@ -283,8 +356,25 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, memset(rbuf, 0, PASSWDLEN); if ( strcmp( p, dhxpwd->pw_passwd ) == 0 ) { *uam_pwd = dhxpwd; - return AFP_OK; + err = AFP_OK; + } +#ifdef SHADOWPW + if (( sp = getspnam( dhxpwd->pw_name )) == NULL ) { + LOG(log_info, logtype_uams, "no shadow passwd entry for %s", dhxpwd->pw_name); + return (AFPERR_NOTAUTH); + } + + /* check for expired password */ + if (sp && sp->sp_max != -1 && sp->sp_lstchg) { + time_t now = time(NULL) / (60*60*24); + int32_t expire_days = sp->sp_lstchg - now + sp->sp_max; + if ( expire_days < 0 ) { + LOG(log_info, logtype_uams, "password for user %s expired", dhxpwd->pw_name); + err = AFPERR_PWDEXPR; + } } +#endif /* SHADOWPW */ + return err; #endif /* TRU64 */ return AFPERR_NOTAUTH; @@ -293,8 +383,8 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "DHCAST128", - passwd_login, passwd_logincont, NULL) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHCAST128", + passwd_login, passwd_logincont, NULL, passwd_login_ext) < 0) return -1; /*uam_register(UAM_SERVER_PRINTAUTH, path, "DHCAST128", passwd_printer);*/ @@ -313,3 +403,9 @@ UAM_MODULE_EXPORT struct uam_export uams_dhx = { UAM_MODULE_VERSION, uam_setup, uam_cleanup }; + +UAM_MODULE_EXPORT struct uam_export uams_dhx_passwd = { + UAM_MODULE_SERVER, + UAM_MODULE_VERSION, + uam_setup, uam_cleanup +};