/*
- * $Id: uams_dhx2_pam.c,v 1.12 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)
* All Rights Reserved. See COPYRIGHT.
#include <atalk/afp.h>
#include <atalk/uam.h>
-#include "../afpd/globals.h"
+#include <atalk/globals.h>
/* 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' };
/*********************************************************
* 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
*********************************************************/
/**
* 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;
}
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;
}
* 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;
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);
/* 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;
/* 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;
}
{
char *username;
size_t len, ulen;
- u_int16_t temp16;
+ uint16_t temp16;
*rbuflen = 0;
}
/* -------------------------------- */
-
static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
int ret;
char serverNonce_bin[16];
gcry_cipher_hd_t ctx;
gcry_error_t ctxerror;
+ uint16_t uint16;
*rbuflen = 0;
/* 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 */
/* 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);
/* 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 */
/* ---- 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;
/* 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;
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;
+
+ 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;
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;
}
/* ---- 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
#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;
}
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)
* --- 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;
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;
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 */
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");
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;
}
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;
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;
}
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
{
if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHX2", pam_login,
pam_logincont, pam_logout, pam_login_ext) < 0)
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;
}
{
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,
};
#endif /* USE_PAM && UAM_DHX2 */
-