# HG changeset patch # User Matt Johnston # Date 1095166276 0 # Node ID 9337c9f9a607ed51a74b73c6ee678f6a8437c54e # Parent 3394a7cb30cd6c0699c621c93ea64a33bc27bfb1 PAM improvements diff -r 3394a7cb30cd -r 9337c9f9a607 options.h --- a/options.h Sun Sep 12 05:52:36 2004 +0000 +++ b/options.h Tue Sep 14 12:51:16 2004 +0000 @@ -110,12 +110,18 @@ #define MOTD_FILENAME "/etc/motd" #endif -/* Authentication types to enable, at least one required. +/* Authentication Types - at least one required. RFC Draft requires pubkey auth, and recommends password */ + +/* PAM auth is quite simple, and only works for PAM modules which just do a + * simple "Login: " "Password: " (or something like that - if your module is + * similar but not quite like that, edit the strings in svr-authpam.c). + * Basically, it's useful for systems like OS X where standard password crypts + * don't work, but there's and interface via a PAM module. You'll need to + * configure with --enable-pam as well, since it's off by default. And you + * should only enable either PASSWORD _or_ PAM auth, not both. */ + /*#define ENABLE_SVR_PASSWORD_AUTH*/ -/* Only set PAM auth if you aren't using SVR_PASSWORD_AUTH. Also, you'll need - * to make sure PAM libraries etc are installed. To the client, PAM auth looks - * just like password auth. */ #define ENABLE_SVR_PAM_AUTH #define ENABLE_SVR_PUBKEY_AUTH diff -r 3394a7cb30cd -r 9337c9f9a607 svr-auth.c --- a/svr-auth.c Sun Sep 12 05:52:36 2004 +0000 +++ b/svr-auth.c Tue Sep 14 12:51:16 2004 +0000 @@ -55,7 +55,7 @@ #ifdef ENABLE_SVR_PUBKEY_AUTH ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; #endif -#if defined(ENABLE_SVR_PUBKEY_AUTH) || defined(ENABLE_SVR_PAM_AUTH) +#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) if (!svr_opts.noauthpass) { ses.authstate.authtypes |= AUTH_TYPE_PASSWORD; } diff -r 3394a7cb30cd -r 9337c9f9a607 svr-authpam.c --- a/svr-authpam.c Sun Sep 12 05:52:36 2004 +0000 +++ b/svr-authpam.c Tue Sep 14 12:51:16 2004 +0000 @@ -1,7 +1,8 @@ /* - * Dropbear - a SSH2 server + * Dropbear SSH * - * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) 2004 Martin Carlsson + * Portions (c) 2004 Matt Johnston * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -/* Validates a user password */ +/* Validates a user password using PAM */ #include "includes.h" #include "session.h" @@ -51,9 +52,19 @@ int rc = PAM_SUCCESS; struct pam_response* resp = NULL; struct UserDataS* userDatap = (struct UserDataS*) appdata_ptr; + const char* message = (*msg)->msg; TRACE(("enter pamConvFunc")); + + if (num_msg != 1) { + /* If you're getting here - Dropbear probably can't support your pam + * modules. This whole file is a bit of a hack around lack of + * asynchronocity in PAM anyway */ + dropbear_log(LOG_INFO, "pamConvFunc() called with >1 messages: not supported."); + return PAM_CONV_ERR; + } + TRACE(("msg_style is %d", (*msg)->msg_style)); if (message) { TRACE(("message is '%s'", message)); @@ -71,11 +82,14 @@ break; } - /* XXX leak */ + /* This looks leaky, but the PAM module-writer docs + * assure us that the caller will free it... */ resp = (struct pam_response*) m_malloc(sizeof(struct pam_response)); - /* XXX leak */ - resp->resp = (char*) m_strdup(userDatap->passwd); - resp->resp_retcode = 0; + memset(resp, 0, sizeof(struct pam_response)); + + /* Safe to just use the direct pointer (no strdup) since + * it shouldn't be getting munged at all */ + resp->resp = userDatap->passwd; (*respp) = resp; break; @@ -90,24 +104,18 @@ break; } - /* XXX leak */ + /* This looks leaky, but the PAM module-writer docs + * assure us that the caller will free it... */ resp = (struct pam_response*) m_malloc(sizeof(struct pam_response)); - /* XXX leak */ - resp->resp = (char*) m_strdup(userDatap->user); + memset(resp, 0, sizeof(struct pam_response)); + + /* Safe to just use the direct pointer (no strdup) since + * it shouldn't be getting munged at all */ + resp->resp = userDatap->user; TRACE(("userDatap->user='%s'", userDatap->user)); - - resp->resp_retcode = 0; (*respp) = resp; break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - case PAM_RADIO_TYPE: - case PAM_BINARY_PROMPT: - TRACE(("Unhandled message type")); - rc = PAM_CONV_ERR; - break; - default: TRACE(("Unknown message type")); rc = PAM_CONV_ERR; @@ -120,7 +128,9 @@ } /* Process a password auth request, sending success or failure messages as - * appropriate. To the client it looks like it's doing normal password auth (as opposed to keyboard-interactive or something), so the pam module has to be fairly standard (ie just "what's your username, what's your password, OK"). + * appropriate. To the client it looks like it's doing normal password auth (as + * opposed to keyboard-interactive or something), so the pam module has to be + * fairly standard (ie just "what's your username, what's your password, OK"). * * Keyboard interactive would be a lot nicer, but since PAM is synchronous, it * gets very messy trying to send the interactive challenges, and read the diff -r 3394a7cb30cd -r 9337c9f9a607 svr-runopts.c --- a/svr-runopts.c Sun Sep 12 05:52:36 2004 +0000 +++ b/svr-runopts.c Tue Sep 14 12:51:16 2004 +0000 @@ -59,7 +59,7 @@ "-m Don't display the motd on login\n" #endif "-w Disallow root logins\n" -#ifdef ENABLE_SVR_PASSWORD_AUTH +#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) "-s Disable password logins\n" "-g Disable password logins for root\n" #endif @@ -183,7 +183,7 @@ case 'w': svr_opts.norootlogin = 1; break; -#ifdef ENABLE_SVR_PASSWORD_AUTH +#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) case 's': svr_opts.noauthpass = 1; break;