X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_dhx_passwd.c;h=8b772b6c449ef465f950f6a82ef9b330090d65c3;hb=80fe6e63eb8ec9a396b4383cb8210fd5ded6ad35;hp=9c41456beee4703e98f409fed10640161f4cc39a;hpb=0758c0ce03ae79bf94570bf8a37515f77dd89618;p=netatalk.git diff --git a/etc/uams/uams_dhx_passwd.c b/etc/uams/uams_dhx_passwd.c index 9c41456b..8b772b6c 100644 --- a/etc/uams/uams_dhx_passwd.c +++ b/etc/uams/uams_dhx_passwd.c @@ -1,6 +1,4 @@ /* - * $Id: uams_dhx_passwd.c,v 1.13 2001-10-24 16:25:24 srittau Exp $ - * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -10,23 +8,32 @@ #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 */ +#include +#include #include -#include +#include #ifdef SHADOWPW #include #endif /* SHADOWPW */ -#ifdef OPENSSL_DHX +#if defined(GNUTLS_DHX) +#include +#elif defined(OPENSSL_DHX) #include #include #include @@ -36,6 +43,7 @@ #include #endif /* OPENSSL_DHX */ +#include #include #include @@ -51,71 +59,58 @@ /* the secret key */ static CAST_KEY castkey; static struct passwd *dhxpwd; -static u_int8_t randbuf[16]; +static uint8_t randbuf[16]; #ifdef TRU64 #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, + uint8_t p[] = {0xBA, 0x28, 0x73, 0xDF, 0xB0, 0x60, 0x57, 0xD4, 0x3F, 0x20, 0x24, 0x74, 0x4C, 0xEE, 0xE7, 0x5B }; - u_int8_t g = 0x07; + uint8_t g = 0x07; #ifdef SHADOWPW struct spwd *sp; #endif /* SHADOWPW */ BIGNUM *bn, *gbn, *pbn; - u_int16_t sessid; - int len, i; - char *name; + uint16_t sessid; + 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 ); + if (( dhxpwd = uam_getname(obj, username, ulen)) == NULL ) { + return AFPERR_NOTAUTH; } - - 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; - } - - syslog( LOG_INFO, "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 ) { - syslog( LOG_INFO, "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 +120,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 +152,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 +164,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 +190,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 +202,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; + uint16_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; + uint16_t sessid; char *p; + int err = AFPERR_NOTAUTH; *rbuflen = 0; @@ -225,12 +293,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))) { @@ -270,8 +338,8 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, uam_afp_getcmdline( &ac, &av ); sprintf( hostname, "%s@%s", dhxpwd->pw_name, clientname ); - if( sia_validate_user( NULL, ac, av, hostname, dhxpwd->pw_name, - NULL, FALSE, NULL, rbuf ) != SIASUCCESS ) + if( uam_sia_validate_user( NULL, ac, av, hostname, dhxpwd->pw_name, + NULL, FALSE, NULL, rbuf ) != SIASUCCESS ) return AFPERR_NOTAUTH; memset( rbuf, 0, PASSWDLEN ); @@ -283,8 +351,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 +378,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 +398,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 +};