X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fuams%2Fuams_dhx2_pam.c;h=8e79b450d4c802e9e6e516c598c2ced645270476;hp=b95e1587f7e81dc56fcaf1fd9039ac3bfb5a90f4;hb=130d356c840ea83c31c4724c8ae92660360eb07b;hpb=f1c0e462cdfe8d19a14bb4e296ed005e3f14bd56 diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index b95e1587..8e79b450 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -46,7 +46,7 @@ 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' }; @@ -136,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; @@ -242,6 +246,7 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, size_t nwritten; gcry_mpi_t Ma; char *Ra_binary = NULL; + uint16_t uint16; *rbuflen = 0; @@ -267,7 +272,8 @@ 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; @@ -281,7 +287,9 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, *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; @@ -365,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; @@ -403,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; @@ -488,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; @@ -529,16 +539,46 @@ exit: return ret; } -static int logincont2(void *obj, struct passwd **uam_pwd, +/** + * Try to authenticate via PAM as "adminauthuser" + **/ +static int loginasroot(const char *adminauthuser, const char **hostname, int status) +{ + 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) { - int ret; + 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; @@ -594,27 +634,42 @@ static int logincont2(void *obj, struct passwd **uam_pwd, /* ---- 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)); + 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; + 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); @@ -627,8 +682,7 @@ static int logincont2(void *obj, struct passwd **uam_pwd, else if (PAM_error == PAM_AUTHTOKEN_REQD) ret = AFPERR_PWDCHNG; #endif - else - goto error_ctx; + goto error_ctx; } #ifndef PAM_CRED_ESTABLISH @@ -649,15 +703,17 @@ static int logincont2(void *obj, struct passwd **uam_pwd, } 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); @@ -669,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) @@ -866,7 +923,7 @@ static int dhx2_changepw(void *obj _U_, char *uname, 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) @@ -874,9 +931,6 @@ static int uam_setup(const char *path) if (uam_register(UAM_SERVER_CHANGEPW, path, "DHX2", dhx2_changepw) < 0) return -1; - p = gcry_mpi_new(0); - g = gcry_mpi_new(0); - LOG(log_debug, logtype_uams, "DHX2: generating mersenne primes"); /* Generate p and g for DH */ if (dh_params_generate(PRIMEBITS) != 0) { @@ -892,11 +946,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, UAM_MODULE_VERSION,