diff svr-authpam.c @ 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 33d976eeb859
line wrap: on
line diff
--- 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