changeset 121:9337c9f9a607 private-rez

PAM improvements
author Matt Johnston <matt@ucc.asn.au>
date Tue, 14 Sep 2004 12:51:16 +0000
parents 3394a7cb30cd
children cb7ef2f63bf0
files options.h svr-auth.c svr-authpam.c svr-runopts.c
diffstat 4 files changed, 44 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- 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
 
--- 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;
 	}
--- 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
--- 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;