X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_dhx_pam.c;h=b3bd931052c54b424cd328579be35f67531b7813;hb=b35812db1e932c31154b7da72c564dabe95fd03d;hp=0a23bc426104e1498e7060ab736274411f0ece50;hpb=7c5e4c078d8b28c7f9e7920c2ecebb4dcd3ed41e;p=netatalk.git diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 0a23bc42..b3bd9310 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -1,5 +1,5 @@ /* - * $Id: uams_dhx_pam.c,v 1.19 2001-11-20 17:07:18 srittau Exp $ + * $Id: uams_dhx_pam.c,v 1.33 2010-03-30 10:25:49 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -14,23 +14,32 @@ #include #include #include -#include +#include #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_H */ #include - +#ifdef HAVE_SECURITY_PAM_APPL_H #include +#endif +#ifdef HAVE_PAM_PAM_APPL_H +#include +#endif -#ifdef OPENSSL_DHX + +#if defined(GNUTLS_DHX) +#include +#elif defined(OPENSSL_DHX) #include #include #include +#include #else /* OPENSSL_DHX */ #include #include #include +#include #endif /* OPENSSL_DHX */ #include @@ -73,7 +82,7 @@ static char *PAM_password; static int PAM_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, - void *appdata_ptr) { + void *appdata_ptr _U_) { int count = 0; struct pam_response *reply; @@ -83,7 +92,7 @@ static int PAM_conv (int num_msg, if (num_msg < 1) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM DHX Conversation Err -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM DHX Conversation Err -- %s", strerror(errno)); /* Log Entry */ return PAM_CONV_ERR; @@ -94,7 +103,7 @@ static int PAM_conv (int num_msg, if (!reply) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM DHX Conversation Err -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM DHX Conversation Err -- %s", strerror(errno)); /* Log Entry */ return PAM_CONV_ERR; @@ -107,7 +116,7 @@ static int PAM_conv (int num_msg, case PAM_PROMPT_ECHO_ON: if (!(string = COPY_STRING(PAM_username))) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: username failure -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: username failure -- %s", strerror(errno)); /* Log Entry */ goto pam_fail_conv; @@ -116,7 +125,7 @@ static int PAM_conv (int num_msg, case PAM_PROMPT_ECHO_OFF: if (!(string = COPY_STRING(PAM_password))) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: passwd failure: --: %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: passwd failure: --: %s", strerror(errno)); /* Log Entry */ goto pam_fail_conv; @@ -131,7 +140,7 @@ static int PAM_conv (int num_msg, case PAM_ERROR_MSG: default: /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Binary_Prompt -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Binary_Prompt -- %s", strerror(errno)); /* Log Entry */ goto pam_fail_conv; @@ -146,8 +155,7 @@ static int PAM_conv (int num_msg, *resp = reply; /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM Success -- %s", - strerror(errno)); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM Success"); /* Log Entry */ return PAM_SUCCESS; @@ -164,7 +172,7 @@ pam_fail_conv: } free(reply); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM DHX Conversation Err -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM DHX Conversation Err -- %s", strerror(errno)); /* Log Entry */ return PAM_CONV_ERR; @@ -176,24 +184,18 @@ static struct pam_conv PAM_conversation = { }; -static int dhx_setup(void *obj, char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { u_int16_t sessid; - int i; + size_t i; BIGNUM *bn, *gbn, *pbn; DH *dh; - /* TODO: seed dhx_setup properly... this is a hack */ -#ifdef sun - /* *SEVERE* hack... fix */ - RAND_load_file("/var/adm/messages", KEYSIZE); -#endif /* sun */ - /* get the client's public key */ if (!(bn = BN_bin2bn(ibuf, KEYSIZE, NULL))) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM No Public Key -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM No Public Key -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -203,7 +205,7 @@ static int dhx_setup(void *obj, char *ibuf, int ibuflen, if (!(gbn = BN_bin2bn(&g, sizeof(g), NULL))) { BN_clear_free(bn); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM No Primes: GBN -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM No Primes: GBN -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -213,7 +215,7 @@ static int dhx_setup(void *obj, char *ibuf, int ibuflen, BN_free(gbn); BN_clear_free(bn); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM No Primes: PBN -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM No Primes: PBN -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -225,7 +227,7 @@ static int dhx_setup(void *obj, char *ibuf, int ibuflen, BN_free(gbn); BN_clear_free(bn); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM DH was equal to DH_New... Go figure... -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM DH was equal to DH_New... Go figure... -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -234,12 +236,22 @@ static int dhx_setup(void *obj, char *ibuf, int ibuflen, /* generate key and make sure that we have enough space */ dh->p = pbn; dh->g = gbn; - if (!DH_generate_key(dh) || (BN_num_bytes(dh->pub_key) > KEYSIZE)) { - /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Err Generating Key -- Not enough Space? -- %s", - strerror(errno)); - /* Log Entry */ - goto pam_fail; + if (DH_generate_key(dh) == 0) { + unsigned long dherror; + char errbuf[256]; + + ERR_load_crypto_strings(); + dherror = ERR_get_error(); + ERR_error_string_n(dherror, errbuf, 256); + + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Err Generating Key (OpenSSL error code: %u, %s)", dherror, errbuf); + + ERR_free_strings(); + goto pam_fail; + } + if (BN_num_bytes(dh->pub_key) > KEYSIZE) { + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Err Generating Key -- Not enough Space? -- %s", strerror(errno)); + goto pam_fail; } /* figure out the key. store the key in rbuf for now. */ @@ -265,7 +277,7 @@ static int dhx_setup(void *obj, char *ibuf, int ibuflen, &i) < 0) { *rbuflen = 0; /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Buffer Encryption Err. -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Buffer Encryption Err. -- %s", strerror(errno)); /* Log Entry */ goto pam_fail; @@ -278,7 +290,7 @@ static int dhx_setup(void *obj, char *ibuf, int ibuflen, (void *) &buf, NULL) < 0) { *rbuflen = 0; /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Signature Retieval Failure -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Signature Retieval Failure -- %s", strerror(errno)); /* Log Entry */ goto pam_fail; @@ -300,68 +312,105 @@ pam_fail: BN_free(bn); DH_free(dh); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Fail - Cast Encryption -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Fail - Cast Encryption -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; } +/* -------------------------------- */ +static int login(void *obj, char *username, int ulen, struct passwd **uam_pwd _U_, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + if (( dhxpwd = uam_getname(obj, username, ulen)) == NULL ) { + LOG(log_info, logtype_uams, "uams_dhx_pam.c: unknown username [%s]", username); + return AFPERR_NOTAUTH; + } + + PAM_username = username; + LOG(log_info, logtype_uams, "dhx login: %s", username); + return dhx_setup(obj, ibuf, ibuflen, rbuf, rbuflen); +} +/* -------------------------------- */ /* dhx login: things are done in a slightly bizarre order to avoid * having to clean things up if there's an error. */ static int pam_login(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) { - char *buf; - int len, i; + char *username; + size_t len, ulen; *rbuflen = 0; /* grab some of the options */ - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, (void *) &buf, - &i) < 0) { - /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: uam_afpserver_option didn't meet uam_option_username -- %s", + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, (void *) &username, &ulen) < 0) { + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: uam_afpserver_option didn't meet uam_option_username -- %s", strerror(errno)); - /* Log Entry */ - return AFPERR_PARAM; + return AFPERR_PARAM; } len = (unsigned char) *ibuf++; - if ( len > i ) { - /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Signature Retieval Failure -- %s", + if ( len > ulen ) { + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Signature Retieval Failure -- %s", strerror(errno)); - /* Log Entry */ - return( AFPERR_PARAM ); + return AFPERR_PARAM; } - memcpy(buf, ibuf, len ); + memcpy(username, ibuf, len ); ibuf += len; - buf[ len ] = '\0'; + username[ len ] = '\0'; + if ((unsigned long) ibuf & 1) /* pad to even boundary */ ++ibuf; - if (( dhxpwd = uam_getname(buf, i)) == NULL ) { - /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: User entered a null value -- %s", + return (login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + +/* ----------------------------- */ +static int pam_login_ext(void *obj, char *uname, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + int len, ulen; + u_int16_t temp16; + + *rbuflen = 0; + + /* grab some of the options */ + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, (void *) &username, &ulen) < 0) { + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: uam_afpserver_option didn't meet uam_option_username -- %s", + strerror(errno)); + return AFPERR_PARAM; + } + + if (*uname != 3) + return AFPERR_PARAM; + uname++; + memcpy(&temp16, uname, sizeof(temp16)); + len = ntohs(temp16); + + if ( !len || len > ulen ) { + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Signature Retrieval Failure -- %s", strerror(errno)); - /* Log Entry */ return AFPERR_PARAM; } + memcpy(username, uname +2, len ); + username[ len ] = '\0'; - PAM_username = buf; - syslog( LOG_INFO, "dhx login: %s", buf); - return dhx_setup(obj, ibuf, ibuflen, rbuf, rbuflen); + return (login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); } +/* -------------------------------- */ static int pam_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) { - char *hostname; + const char *hostname; BIGNUM *bn1, *bn2, *bn3; u_int16_t sessid; int err, PAM_error; @@ -372,7 +421,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, memcpy(&sessid, ibuf, sizeof(sessid)); if (sessid != dhxhash(obj)) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM Session ID - DHXHash Mismatch -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM Session ID - DHXHash Mismatch -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -382,7 +431,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, if (uam_afpserver_option(obj, UAM_OPTION_CLIENTNAME, (void *) &hostname, NULL) < 0) { - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: unable to retrieve client hostname"); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: unable to retrieve client hostname"); hostname = NULL; } @@ -431,8 +480,8 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, &pamh); if (PAM_error != PAM_SUCCESS) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM_Error: %s -- %s", - pam_strerror(pamh,PAM_error), strerror(errno)); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM_Error: %s", + pam_strerror(pamh,PAM_error)); /* Log Entry */ goto logincont_err; } @@ -445,25 +494,26 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, if (PAM_error == PAM_MAXTRIES) err = AFPERR_PWDEXPR; /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM_Error: %s -- %s", - pam_strerror(pamh, PAM_error), strerror(errno)); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); /* Log Entry */ goto logincont_err; } PAM_error = pam_acct_mgmt(pamh, 0); - if (PAM_error != PAM_SUCCESS) { - if (PAM_error == PAM_ACCT_EXPIRED) + if (PAM_error != PAM_SUCCESS ) { + /* Log Entry */ + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); + /* Log Entry */ + if (PAM_error == PAM_NEW_AUTHTOK_REQD) /* password expired */ err = AFPERR_PWDEXPR; #ifdef PAM_AUTHTOKEN_REQD else if (PAM_error == PAM_AUTHTOKEN_REQD) err = AFPERR_PWDCHNG; #endif - /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM_Error: %s -- %s", - pam_strerror(pamh, PAM_error), strerror(errno)); - /* Log Entry */ - goto logincont_err; + else + goto logincont_err; } #ifndef PAM_CRED_ESTABLISH @@ -472,8 +522,8 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, PAM_error = pam_setcred(pamh, PAM_CRED_ESTABLISH); if (PAM_error != PAM_SUCCESS) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM_Error: %s -- %s", - pam_strerror(pamh, PAM_error), strerror(errno)); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); /* Log Entry */ goto logincont_err; } @@ -481,8 +531,8 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, PAM_error = pam_open_session(pamh, 0); if (PAM_error != PAM_SUCCESS) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM_Error: %s -- %s", - pam_strerror(pamh, PAM_error), strerror(errno)); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); /* Log Entry */ goto logincont_err; } @@ -490,8 +540,10 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, memset(rbuf, 0, PASSWDLEN); /* zero out the password */ *uam_pwd = dhxpwd; /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: PAM Auth OK!"); + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: PAM Auth OK!"); /* Log Entry */ + if ( err == AFPERR_PWDEXPR) + return err; return AFP_OK; logincont_err: @@ -502,7 +554,7 @@ logincont_err: } /* logout */ -static void pam_logout() { +static void pam_logout(void) { pam_close_session(pamh, 0); pam_end(pamh, 0); pamh = NULL; @@ -512,8 +564,8 @@ static void pam_logout() { /* change pw for dhx needs a couple passes to get everything all * right. basically, it's like the login/logincont sequence */ static int pam_changepw(void *obj, char *username, - struct passwd *pwd, char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + struct passwd *pwd _U_, char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) { BIGNUM *bn1, *bn2, *bn3; @@ -523,6 +575,10 @@ static int pam_changepw(void *obj, char *username, u_int16_t sessid; int PAM_error; + if (ibuflen < sizeof(sessid)) { + return AFPERR_PARAM; + } + /* grab the id */ memcpy(&sessid, ibuf, sizeof(sessid)); ibuf += sizeof(sessid); @@ -539,7 +595,7 @@ static int pam_changepw(void *obj, char *username, /* check out the session id */ if (sessid != dhxhash(obj)) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Session ID not Equal to DHX Hash -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Session ID not Equal to DHX Hash -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -549,7 +605,7 @@ static int pam_changepw(void *obj, char *username, if (uam_afpserver_option(obj, UAM_OPTION_HOSTNAME, (void *) &hostname, NULL) < 0) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Hostname Null?? -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Hostname Null?? -- %s", strerror(errno)); /* Log Entry */ return AFPERR_MISC; @@ -564,7 +620,7 @@ static int pam_changepw(void *obj, char *username, * get sent back an incremented random number. */ if (!(bn1 = BN_bin2bn(ibuf, KEYSIZE, NULL))) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Random Number Not the same or not incremented-- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Random Number Not the same or not incremented-- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -573,7 +629,7 @@ static int pam_changepw(void *obj, char *username, if (!(bn2 = BN_bin2bn(randbuf, sizeof(randbuf), NULL))) { BN_free(bn1); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Random Number Not the same or not incremented -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Random Number Not the same or not incremented -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -587,7 +643,7 @@ static int pam_changepw(void *obj, char *username, BN_free(bn2); BN_free(bn1); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Random Number did not Zero -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Random Number did not Zero -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -602,7 +658,7 @@ static int pam_changepw(void *obj, char *username, if (!BN_is_one(bn3)) { BN_free(bn3); /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: After Random Number not Zero, is it one more? -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: After Random Number not Zero, is it one more? -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -620,7 +676,7 @@ static int pam_changepw(void *obj, char *username, &lpamh); if (PAM_error != PAM_SUCCESS) { /* Log Entry */ - syslog(LOG_INFO, "uams_dhx_pam.c :PAM: Needless to say, PAM_error is != to PAM_SUCCESS -- %s", + LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Needless to say, PAM_error is != to PAM_SUCCESS -- %s", strerror(errno)); /* Log Entry */ return AFPERR_PARAM; @@ -661,8 +717,8 @@ static int pam_changepw(void *obj, char *username, static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "DHCAST128", pam_login, - pam_logincont, pam_logout) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHCAST128", pam_login, + pam_logincont, pam_logout, pam_login_ext) < 0) return -1; if (uam_register(UAM_SERVER_CHANGEPW, path, "DHCAST128",