X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_dhx2_pam.c;h=5229d372433603b810ece221f427e92ed71079ee;hb=42eb54de3f6373cd394fbd6abfb86d85c8dde935;hp=48c407c72f7c412e0ab1d9c6d71c8813fa69fb42;hpb=d0f90628ecad684ef1b417471ea3f76292964b11;p=netatalk.git diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index 48c407c7..5229d372 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -1,6 +1,4 @@ /* - * $Id: uams_dhx2_pam.c,v 1.8 2009-10-15 11:39:48 didg 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. @@ -34,21 +32,21 @@ #include #include -#include "../afpd/globals.h" +#include /* Number of bits for p which we generate. Everybode out there uses 512, so we beet them */ #define PRIMEBITS 1024 /* hash a number to a 16-bit quantity */ -#define dhxhash(a) ((((unsigned long) (a) >> 8) ^ \ +#define dhxhash(a) ((((unsigned long) (a) >> 8) ^ \ (unsigned long) (a)) & 0xffff) /* Some parameters need be maintained across calls */ -static gcry_mpi_t p, Ra; +static gcry_mpi_t p, g, Ra; static gcry_mpi_t serverNonce; static char *K_MD5hash = NULL; static int K_hash_len; -static u_int16_t ID; +static uint16_t ID; /* The initialization vectors for CAST128 are fixed by Apple. */ static unsigned char dhx_c2siv[] = { 'L', 'W', 'a', 'l', 'l', 'a', 'c', 'e' }; @@ -64,7 +62,7 @@ static struct passwd *dhxpwd; /********************************************************* * Crypto helper func to generate p and g for use in DH. * libgcrypt doesn't provide one directly. - * Algorithm taken from GNUTLS:gnutls_dh_primes.c + * Algorithm taken from GNUTLS:gnutls_dh_primes.c *********************************************************/ /** @@ -72,78 +70,62 @@ static struct passwd *dhxpwd; * the Diffie-Hellman key exchange. * The bits value should be one of 768, 1024, 2048, 3072 or 4096. **/ - -static int -dh_params_generate (gcry_mpi_t *ret_p, gcry_mpi_t *ret_g, unsigned int bits) { +static int dh_params_generate (unsigned int bits) { int result, times = 0, qbits; - - gcry_mpi_t g = NULL, prime = NULL; gcry_mpi_t *factors = NULL; gcry_error_t err; /* Version check should be the very first call because it makes sure that important subsystems are intialized. */ if (!gcry_check_version (GCRYPT_VERSION)) { - LOG(log_info, logtype_uams, "PAM DHX2: libgcrypt versions mismatch. Need: %u", GCRYPT_VERSION); - result = AFPERR_MISC; - goto error; + LOG(log_error, logtype_uams, "PAM DHX2: libgcrypt versions mismatch. Need: %s", GCRYPT_VERSION); + result = AFPERR_MISC; + goto error; } if (bits < 256) - qbits = bits / 2; + qbits = bits / 2; else - qbits = (bits / 40) + 105; + qbits = (bits / 40) + 105; if (qbits & 1) /* better have an even number */ - qbits++; + qbits++; /* find a prime number of size bits. */ do { - if (times) { - gcry_mpi_release (prime); - gcry_prime_release_factors (factors); - } - err = gcry_prime_generate (&prime, bits, qbits, &factors, NULL, NULL, - GCRY_STRONG_RANDOM, GCRY_PRIME_FLAG_SPECIAL_FACTOR); - if (err != 0) { - result = AFPERR_MISC; - goto error; - } - err = gcry_prime_check (prime, 0); - times++; + if (times) { + gcry_mpi_release(p); + gcry_prime_release_factors (factors); + } + err = gcry_prime_generate(&p, bits, qbits, &factors, NULL, NULL, + GCRY_STRONG_RANDOM, GCRY_PRIME_FLAG_SPECIAL_FACTOR); + if (err != 0) { + result = AFPERR_MISC; + goto error; + } + err = gcry_prime_check(p, 0); + times++; } while (err != 0 && times < 10); - + if (err != 0) { - result = AFPERR_MISC; - goto error; + result = AFPERR_MISC; + goto error; } /* generate the group generator. */ - err = gcry_prime_group_generator (&g, prime, factors, NULL); + err = gcry_prime_group_generator(&g, p, factors, NULL); if (err != 0) { - result = AFPERR_MISC; - goto error; - } - - gcry_prime_release_factors (factors); - factors = NULL; - - if (ret_g) - *ret_g = g; - else - gcry_mpi_release (g); - if (ret_p) - *ret_p = prime; - else - gcry_mpi_release (prime); - + result = AFPERR_MISC; + goto error; + } + + gcry_prime_release_factors(factors); + return 0; error: - gcry_prime_release_factors (factors); - gcry_mpi_release (g); - gcry_mpi_release (prime); + gcry_prime_release_factors(factors); return result; } @@ -154,7 +136,11 @@ error: * echo off means password. */ static int PAM_conv (int num_msg, +#ifdef LINUX const struct pam_message **msg, +#else + struct pam_message **msg, +#endif struct pam_response **resp, void *appdata_ptr _U_) { int count = 0; @@ -254,33 +240,24 @@ static struct pam_conv PAM_conversation = { static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, - char *rbuf, size_t *rbuflen) + char *rbuf, size_t *rbuflen) { int ret; size_t nwritten; - gcry_mpi_t g, Ma; + gcry_mpi_t Ma; char *Ra_binary = NULL; + uint16_t uint16; *rbuflen = 0; - p = gcry_mpi_new(0); - g = gcry_mpi_new(0); Ra = gcry_mpi_new(0); Ma = gcry_mpi_new(0); - /* Generate p and g for DH */ - ret = dh_params_generate( &p, &g, PRIMEBITS); - if (ret != 0) { - LOG(log_info, logtype_uams, "DHX2: Couldn't generate p and g"); - ret = AFPERR_MISC; - goto error; - } - /* Generate our random number Ra. */ Ra_binary = calloc(1, PRIMEBITS/8); if (Ra_binary == NULL) { - ret = AFPERR_MISC; - goto error; + ret = AFPERR_MISC; + goto error; } gcry_randomize(Ra_binary, PRIMEBITS/8, GCRY_STRONG_RANDOM); gcry_mpi_scan(&Ra, GCRYMPI_FMT_USG, Ra_binary, PRIMEBITS/8, NULL); @@ -295,21 +272,24 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, /* Session ID first */ ID = dhxhash(obj); - *(u_int16_t *)rbuf = htons(ID); + uint16 = htons(ID); + memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; /* g is next */ gcry_mpi_print( GCRYMPI_FMT_USG, (unsigned char *)rbuf, 4, &nwritten, g); if (nwritten < 4) { - memmove( rbuf+4-nwritten, rbuf, nwritten); - memset( rbuf, 0, 4-nwritten); + memmove( rbuf+4-nwritten, rbuf, nwritten); + memset( rbuf, 0, 4-nwritten); } rbuf += 4; *rbuflen += 4; /* len = length of p = PRIMEBITS/8 */ - *(u_int16_t *)rbuf = htons((u_int16_t) PRIMEBITS/8); + + uint16 = htons((uint16_t) PRIMEBITS/8); + memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; @@ -321,17 +301,16 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, /* Ma */ gcry_mpi_print( GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS/8, &nwritten, Ma); if (nwritten < PRIMEBITS/8) { - memmove(rbuf + (PRIMEBITS/8) - nwritten, rbuf, nwritten); - memset(rbuf, 0, (PRIMEBITS/8) - nwritten); + memmove(rbuf + (PRIMEBITS/8) - nwritten, rbuf, nwritten); + memset(rbuf, 0, (PRIMEBITS/8) - nwritten); } rbuf += PRIMEBITS/8; *rbuflen += PRIMEBITS/8; ret = AFPERR_AUTHCONT; -error: /* We exit here anyway */ - /* We will only need p and Ra later, but mustn't forget to release it ! */ - gcry_mpi_release(g); +error: /* We exit here anyway */ + /* We will need Ra later, but mustn't forget to release it ! */ gcry_mpi_release(Ma); return ret; } @@ -343,7 +322,7 @@ static int login(void *obj, char *username, int ulen, struct passwd **uam_pwd _ { if (( dhxpwd = uam_getname(obj, username, ulen)) == NULL ) { LOG(log_info, logtype_uams, "DHX2: unknown username"); - return AFPERR_PARAM; + return AFPERR_NOTAUTH; } PAM_username = username; @@ -394,7 +373,7 @@ static int pam_login_ext(void *obj, char *uname, struct passwd **uam_pwd, { char *username; size_t len, ulen; - u_int16_t temp16; + uint16_t temp16; *rbuflen = 0; @@ -423,7 +402,6 @@ static int pam_login_ext(void *obj, char *uname, struct passwd **uam_pwd, } /* -------------------------------- */ - static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) { int ret; @@ -433,6 +411,7 @@ static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, siz char serverNonce_bin[16]; gcry_cipher_hd_t ctx; gcry_error_t ctxerror; + uint16_t uint16; *rbuflen = 0; @@ -443,9 +422,9 @@ static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, siz /* Packet size should be: Session ID + Ma + Encrypted client nonce */ if (ibuflen != 2 + PRIMEBITS/8 + 16) { - LOG(log_error, logtype_uams, "DHX2: Paket length not correct"); + LOG(log_error, logtype_uams, "DHX2: Paket length not correct"); ret = AFPERR_PARAM; - goto error_noctx; + goto error_noctx; } /* Skip session id */ @@ -461,20 +440,20 @@ static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, siz /* We need K in binary form in order to ... */ K_bin = calloc(1, PRIMEBITS/8); if (K_bin == NULL) { - ret = AFPERR_MISC; - goto error_noctx; + ret = AFPERR_MISC; + goto error_noctx; } gcry_mpi_print(GCRYMPI_FMT_USG, K_bin, PRIMEBITS/8, &nwritten, K); if (nwritten < PRIMEBITS/8) { - memmove(K_bin + PRIMEBITS/8 - nwritten, K_bin, nwritten); - memset(K_bin, 0, PRIMEBITS/8 - nwritten); + memmove(K_bin + PRIMEBITS/8 - nwritten, K_bin, nwritten); + memset(K_bin, 0, PRIMEBITS/8 - nwritten); } /* ... generate the MD5 hash of K. K_MD5hash is what we actually use ! */ K_MD5hash = calloc(1, K_hash_len = gcry_md_get_algo_dlen(GCRY_MD_MD5)); if (K_MD5hash == NULL) { - ret = AFPERR_MISC; - goto error_noctx; + ret = AFPERR_MISC; + goto error_noctx; } gcry_md_hash_buffer(GCRY_MD_MD5, K_MD5hash, K_bin, PRIMEBITS/8); free(K_bin); @@ -485,25 +464,25 @@ static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, siz /* Set up our encryption context. */ ctxerror = gcry_cipher_open( &ctx, GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC, 0); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { - ret = AFPERR_MISC; + ret = AFPERR_MISC; goto error_ctx; } /* Set key */ ctxerror = gcry_cipher_setkey(ctx, K_MD5hash, K_hash_len); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { - ret = AFPERR_MISC; + ret = AFPERR_MISC; goto error_ctx; } /* Set the initialization vector for client->server transfer. */ ctxerror = gcry_cipher_setiv(ctx, dhx_c2siv, sizeof(dhx_c2siv)); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { - ret = AFPERR_MISC; + ret = AFPERR_MISC; goto error_ctx; } /* Finally: decrypt client's md5_K(client nonce, C2SIV) inplace */ ctxerror = gcry_cipher_decrypt(ctx, ibuf, 16, NULL, 0); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { - ret = AFPERR_MISC; + ret = AFPERR_MISC; goto error_ctx; } /* Pull out clients nonce */ @@ -518,7 +497,8 @@ static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, siz /* ---- Start building reply packet ---- */ /* Session ID + 1 first */ - *(u_int16_t *)rbuf = htons(ID+1); + uint16 = htons(ID+1); + memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; @@ -530,14 +510,14 @@ static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, siz /* Set the initialization vector for server->client transfer. */ ctxerror = gcry_cipher_setiv(ctx, dhx_s2civ, sizeof(dhx_s2civ)); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { - ret = AFPERR_MISC; + ret = AFPERR_MISC; goto error_ctx; } /* Encrypt md5_K(clientNonce+1, serverNonce) inplace */ ctxerror = gcry_cipher_encrypt(ctx, rbuf, 32, NULL, 0); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { - ret = AFPERR_MISC; - goto error_ctx; + ret = AFPERR_MISC; + goto error_ctx; } rbuf += 32; *rbuflen += 32; @@ -555,21 +535,50 @@ exit: gcry_mpi_release(K); gcry_mpi_release(Mb); gcry_mpi_release(Ra); - gcry_mpi_release(p); gcry_mpi_release(clientNonce); return ret; } -static int logincont2(void *obj, struct passwd **uam_pwd, - char *ibuf, size_t ibuflen, - char *rbuf _U_, size_t *rbuflen) +/** + * Try to authenticate via PAM as "adminauthuser" + **/ +static int loginasroot(const char *adminauthuser, const char **hostname, int status) { - int ret; int PAM_error; - char *hostname = NULL; + + if ((PAM_error = pam_end(pamh, status)) != PAM_SUCCESS) + goto exit; + pamh = NULL; + + if ((PAM_error = pam_start("netatalk", adminauthuser, &PAM_conversation, &pamh)) != PAM_SUCCESS) { + LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", pam_strerror(pamh,PAM_error)); + goto exit; + } + + /* solaris craps out if PAM_TTY and PAM_RHOST aren't set. */ + pam_set_item(pamh, PAM_TTY, "afpd"); + pam_set_item(pamh, PAM_RHOST, *hostname); + if ((PAM_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS) + goto exit; + + LOG(log_warning, logtype_uams, "DHX2: Authenticated as \"%s\"", adminauthuser); + +exit: + return PAM_error; +} + +static int logincont2(void *obj_in, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf _U_, size_t *rbuflen) +{ + AFPObj *obj = obj_in; + int ret = AFPERR_MISC; + int PAM_error; + const char *hostname = NULL; gcry_mpi_t retServerNonce; gcry_cipher_hd_t ctx; gcry_error_t ctxerror; + char *utfpass = NULL; *rbuflen = 0; @@ -617,51 +626,63 @@ static int logincont2(void *obj, struct passwd **uam_pwd, gcry_mpi_scan(&retServerNonce, GCRYMPI_FMT_USG, ibuf, 16, NULL); gcry_mpi_sub_ui(retServerNonce, retServerNonce, 1); if ( gcry_mpi_cmp( serverNonce, retServerNonce) != 0) { - /* We're hacked! */ + /* We're hacked! */ ret = AFPERR_NOTAUTH; goto error_ctx; } ibuf += 16; - LOG(log_info, logtype_uams, "DHX2: logincont2 alive!"); - /* ---- Start authentication with PAM --- */ + /* The password is in legacy Mac encoding, convert it to host encoding */ + if (convert_string_allocate(CH_MAC, CH_UNIX, ibuf, -1, &utfpass) == (size_t)-1) { + LOG(log_error, logtype_uams, "DHX2: conversion error"); + goto error_ctx; + } + PAM_password = utfpass; + +#ifdef DEBUG + LOG(log_maxdebug, logtype_default, "DHX2: password: %s", PAM_password); +#endif + /* Set these things up for the conv function */ - PAM_password = ibuf; ret = AFPERR_NOTAUTH; PAM_error = pam_start("netatalk", PAM_username, &PAM_conversation, &pamh); if (PAM_error != PAM_SUCCESS) { - LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", - pam_strerror(pamh,PAM_error)); - goto error_ctx; + LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", pam_strerror(pamh,PAM_error)); + goto error_ctx; } /* solaris craps out if PAM_TTY and PAM_RHOST aren't set. */ pam_set_item(pamh, PAM_TTY, "afpd"); pam_set_item(pamh, PAM_RHOST, hostname); + pam_set_item(pamh, PAM_RUSER, PAM_username); + PAM_error = pam_authenticate(pamh, 0); if (PAM_error != PAM_SUCCESS) { - if (PAM_error == PAM_MAXTRIES) - ret = AFPERR_PWDEXPR; - LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", - pam_strerror(pamh, PAM_error)); - goto error_ctx; + if (PAM_error == PAM_MAXTRIES) + ret = AFPERR_PWDEXPR; + LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", pam_strerror(pamh, PAM_error)); + + if (!obj->options.adminauthuser) + goto error_ctx; + if (loginasroot(obj->options.adminauthuser, &hostname, PAM_error) != PAM_SUCCESS) { + goto error_ctx; + } } PAM_error = pam_acct_mgmt(pamh, 0); if (PAM_error != PAM_SUCCESS ) { - LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", - pam_strerror(pamh, PAM_error)); - if (PAM_error == PAM_NEW_AUTHTOK_REQD) /* password expired */ - ret = AFPERR_PWDEXPR; + LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); + if (PAM_error == PAM_NEW_AUTHTOK_REQD) /* password expired */ + ret = AFPERR_PWDEXPR; #ifdef PAM_AUTHTOKEN_REQD - else if (PAM_error == PAM_AUTHTOKEN_REQD) - ret = AFPERR_PWDCHNG; + else if (PAM_error == PAM_AUTHTOKEN_REQD) + ret = AFPERR_PWDCHNG; #endif - else - goto error_ctx; + goto error_ctx; } #ifndef PAM_CRED_ESTABLISH @@ -669,32 +690,34 @@ static int logincont2(void *obj, struct passwd **uam_pwd, #endif PAM_error = pam_setcred(pamh, PAM_CRED_ESTABLISH); if (PAM_error != PAM_SUCCESS) { - LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", - pam_strerror(pamh, PAM_error)); - goto error_ctx; + LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); + goto error_ctx; } PAM_error = pam_open_session(pamh, 0); if (PAM_error != PAM_SUCCESS) { - LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", - pam_strerror(pamh, PAM_error)); - goto error_ctx; + LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", + pam_strerror(pamh, PAM_error)); + goto error_ctx; } memset(ibuf, 0, 256); /* zero out the password */ + if (utfpass) + memset(utfpass, 0, strlen(utfpass)); *uam_pwd = dhxpwd; LOG(log_info, logtype_uams, "DHX2: PAM Auth OK!"); - if ( ret == AFPERR_PWDEXPR) - return ret; + ret = AFP_OK; error_ctx: gcry_cipher_close(ctx); error_noctx: + if (utfpass) free(utfpass); free(K_MD5hash); K_MD5hash=NULL; gcry_mpi_release(serverNonce); - gcry_mpi_release(retServerNonce); + gcry_mpi_release(retServerNonce); return ret; } @@ -702,11 +725,12 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) { - u_int16_t retID; + uint16_t retID; int ret; /* check for session id */ - retID = ntohs(*(u_int16_t *)ibuf); + memcpy(&retID, ibuf, sizeof(uint16_t)); + retID = ntohs(retID); if (retID == ID) ret = logincont1(obj, ibuf, ibuflen, rbuf, rbuflen); else if (retID == ID+1) @@ -730,7 +754,7 @@ static void pam_logout(void) { * --- Change pwd stuff --- */ static int changepw_1(void *obj, char *uname, - char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) + char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) { *rbuflen = 0; @@ -739,21 +763,21 @@ static int changepw_1(void *obj, char *uname, return( dhx2_setup(obj, ibuf, ibuflen, rbuf, rbuflen) ); } -static int changepw_2(void *obj, - char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) +static int changepw_2(void *obj, + char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) { return( logincont1(obj, ibuf, ibuflen, rbuf, rbuflen) ); } static int changepw_3(void *obj _U_, - char *ibuf, size_t ibuflen _U_, - char *rbuf _U_, size_t *rbuflen _U_) + char *ibuf, size_t ibuflen _U_, + char *rbuf _U_, size_t *rbuflen _U_) { int ret; int PAM_error; uid_t uid; pam_handle_t *lpamh; - char *hostname = NULL; + const char *hostname = NULL; gcry_mpi_t retServerNonce; gcry_cipher_hd_t ctx; gcry_error_t ctxerror; @@ -814,14 +838,14 @@ static int changepw_3(void *obj _U_, ibuf += 16; /* ---- Start pwd changing with PAM --- */ - ibuf[255] = '\0'; /* For safety */ + ibuf[255] = '\0'; /* For safety */ ibuf[511] = '\0'; /* check if new and old password are equal */ if (memcmp(ibuf, ibuf + 256, 255) == 0) { - LOG(log_info, logtype_uams, "DHX2 Chgpwd: new and old password are equal"); + LOG(log_info, logtype_uams, "DHX2 Chgpwd: new and old password are equal"); ret = AFPERR_PWDSAME; - goto error_ctx; + goto error_ctx; } /* Set these things up for the conv function. PAM_username was set in changepw_1 */ @@ -829,7 +853,7 @@ static int changepw_3(void *obj _U_, PAM_error = pam_start("netatalk", PAM_username, &PAM_conversation, &lpamh); if (PAM_error != PAM_SUCCESS) { LOG(log_info, logtype_uams, "DHX2 Chgpwd: PAM error in pam_start"); - ret = AFPERR_PARAM; + ret = AFPERR_PARAM; goto error_ctx; } pam_set_item(lpamh, PAM_TTY, "afpd"); @@ -839,21 +863,21 @@ static int changepw_3(void *obj _U_, seteuid(0); PAM_error = pam_authenticate(lpamh,0); if (PAM_error != PAM_SUCCESS) { - LOG(log_info, logtype_uams, "DHX2 Chgpwd: error authenticating with PAM"); - seteuid(uid); - pam_end(lpamh, PAM_error); - ret = AFPERR_NOTAUTH; - goto error_ctx; + LOG(log_info, logtype_uams, "DHX2 Chgpwd: error authenticating with PAM"); + seteuid(uid); + pam_end(lpamh, PAM_error); + ret = AFPERR_NOTAUTH; + goto error_ctx; } PAM_password = ibuf; PAM_error = pam_chauthtok(lpamh, 0); seteuid(uid); /* un-root ourselves. */ memset(ibuf, 0, 512); if (PAM_error != PAM_SUCCESS) { - LOG(log_info, logtype_uams, "DHX2 Chgpwd: error changing pw with PAM"); - pam_end(lpamh, PAM_error); - ret = AFPERR_ACCESS; - goto error_ctx; + LOG(log_info, logtype_uams, "DHX2 Chgpwd: error changing pw with PAM"); + pam_end(lpamh, PAM_error); + ret = AFPERR_ACCESS; + goto error_ctx; } pam_end(lpamh, 0); ret = AFP_OK; @@ -869,8 +893,8 @@ error_noctx: } static int dhx2_changepw(void *obj _U_, char *uname, - struct passwd *pwd _U_, char *ibuf, size_t ibuflen _U_, - char *rbuf _U_, size_t *rbuflen _U_) + struct passwd *pwd _U_, char *ibuf, size_t ibuflen _U_, + char *rbuf _U_, size_t *rbuflen _U_) { /* We use this to serialize the three incoming FPChangePassword calls */ static int dhx2_changepw_status = 1; @@ -879,22 +903,22 @@ static int dhx2_changepw(void *obj _U_, char *uname, switch (dhx2_changepw_status) { case 1: - ret = changepw_1( obj, uname, ibuf, ibuflen, rbuf, rbuflen); - if ( ret == AFPERR_AUTHCONT) - dhx2_changepw_status = 2; - break; + ret = changepw_1( obj, uname, ibuf, ibuflen, rbuf, rbuflen); + if ( ret == AFPERR_AUTHCONT) + dhx2_changepw_status = 2; + break; case 2: - ret = changepw_2( obj, ibuf, ibuflen, rbuf, rbuflen); + ret = changepw_2( obj, ibuf, ibuflen, rbuf, rbuflen); if ( ret == AFPERR_AUTHCONT) dhx2_changepw_status = 3; - else - dhx2_changepw_status = 1; - break; + else + dhx2_changepw_status = 1; + break; case 3: - ret = changepw_3( obj, ibuf, ibuflen, rbuf, rbuflen); - dhx2_changepw_status = 1; /* Whether is was succesfull or not: we - restart anyway !*/ - break; + ret = changepw_3( obj, ibuf, ibuflen, rbuf, rbuflen); + dhx2_changepw_status = 1; /* Whether is was succesfull or not: we + restart anyway !*/ + break; } return ret; } @@ -906,6 +930,14 @@ static int uam_setup(const char *path) return -1; if (uam_register(UAM_SERVER_CHANGEPW, path, "DHX2", dhx2_changepw) < 0) return -1; + + LOG(log_debug, logtype_uams, "DHX2: generating mersenne primes"); + /* Generate p and g for DH */ + if (dh_params_generate(PRIMEBITS) != 0) { + LOG(log_error, logtype_uams, "DHX2: Couldn't generate p and g"); + return -1; + } + return 0; } @@ -913,8 +945,12 @@ static void uam_cleanup(void) { uam_unregister(UAM_SERVER_LOGIN, "DHX2"); uam_unregister(UAM_SERVER_CHANGEPW, "DHX2"); -} + LOG(log_debug, logtype_uams, "DHX2: uam_cleanup"); + + gcry_mpi_release(p); + gcry_mpi_release(g); +} UAM_MODULE_EXPORT struct uam_export uams_dhx2 = { UAM_MODULE_SERVER, @@ -930,4 +966,3 @@ UAM_MODULE_EXPORT struct uam_export uams_dhx2_pam = { }; #endif /* USE_PAM && UAM_DHX2 */ -