[PATCH] Notify clients of PAM error messages

Martin Donnelly martin.donnelly at ge.com
Thu May 2 18:44:10 WST 2013


This patch adds support for relaying PAM_ERROR_MSG to clients. This
is useful when PAM_ERROR_MSG returns meaningful information, an
example of this is when pam_nologin is being used and '/etc/nologin'
contains a message for clients attempting to connect.

-Martin
-------------- next part --------------
diff -ubNr dropbear-2013.58.orig/auth.h dropbear-2013.58/auth.h
--- dropbear-2013.58.orig/auth.h	2013-04-18 15:58:14.000000000 +0100
+++ dropbear-2013.58/auth.h	2013-04-30 17:37:33.317480220 +0100
@@ -36,6 +36,7 @@
 void recv_msg_userauth_request();
 void send_msg_userauth_failure(int partial, int incrfail);
 void send_msg_userauth_success();
+void send_msg_userauth_banner(buffer **msg);
 void svr_auth_password();
 void svr_auth_pubkey();
 void svr_auth_pam();
diff -ubNr dropbear-2013.58.orig/common-session.c dropbear-2013.58/common-session.c
--- dropbear-2013.58.orig/common-session.c	2013-04-18 15:58:14.000000000 +0100
+++ dropbear-2013.58/common-session.c	2013-05-01 15:55:20.687368142 +0100
@@ -122,6 +122,8 @@
 
 	ses.allowprivport = 0;
 
+	ses.pam_err = NULL;
+
 	TRACE(("leave session_init"))
 }
 
diff -ubNr dropbear-2013.58.orig/session.h dropbear-2013.58/session.h
--- dropbear-2013.58.orig/session.h	2013-04-18 15:58:14.000000000 +0100
+++ dropbear-2013.58/session.h	2013-05-02 11:32:32.610072021 +0100
@@ -197,6 +197,8 @@
 	 * really belong here, but nowhere else fits nicely */
 	int allowprivport;
 
+	/* buffer for storing PAM error messages */
+	buffer * pam_err;
 };
 
 struct serversession {
diff -ubNr dropbear-2013.58.orig/svr-auth.c dropbear-2013.58/svr-auth.c
--- dropbear-2013.58.orig/svr-auth.c	2013-04-18 15:58:14.000000000 +0100
+++ dropbear-2013.58/svr-auth.c	2013-05-01 17:36:28.249791834 +0100
@@ -37,7 +37,6 @@
 
 static void authclear();
 static int checkusername(unsigned char *username, unsigned int userlen);
-static void send_msg_userauth_banner();
 
 /* initialise the first time for a session, resetting all parameters */
 void svr_authinitialise() {
@@ -82,10 +81,10 @@
 
 /* Send a banner message if specified to the client. The client might
  * ignore this, but possibly serves as a legal "no trespassing" sign */
-static void send_msg_userauth_banner() {
+void send_msg_userauth_banner(buffer **banner) {
 
 	TRACE(("enter send_msg_userauth_banner"))
-	if (svr_opts.banner == NULL) {
+	if ((banner == NULL) || (*banner == NULL)) {
 		TRACE(("leave send_msg_userauth_banner: banner is NULL"))
 		return;
 	}
@@ -93,13 +92,13 @@
 	CHECKCLEARTOWRITE();
 
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_BANNER);
-	buf_putstring(ses.writepayload, buf_getptr(svr_opts.banner,
-				svr_opts.banner->len), svr_opts.banner->len);
+	buf_putstring(ses.writepayload, buf_getptr(*banner,
+				(*banner)->len), (*banner)->len);
 	buf_putstring(ses.writepayload, "en", 2);
 
 	encrypt_packet();
-	buf_free(svr_opts.banner);
-	svr_opts.banner = NULL;
+	buf_free(*banner);
+	*banner = NULL;
 
 	TRACE(("leave send_msg_userauth_banner"))
 }
@@ -121,7 +120,7 @@
 
 	/* send the banner if it exists, it will only exist once */
 	if (svr_opts.banner) {
-		send_msg_userauth_banner();
+		send_msg_userauth_banner(&svr_opts.banner);
 	}
 
 	
diff -ubNr dropbear-2013.58.orig/svr-authpam.c dropbear-2013.58/svr-authpam.c
--- dropbear-2013.58.orig/svr-authpam.c	2013-04-18 15:58:14.000000000 +0100
+++ dropbear-2013.58/svr-authpam.c	2013-05-01 15:18:38.603729862 +0100
@@ -142,6 +142,22 @@
 			(*respp) = resp;
 			break;
 
+		case PAM_ERROR_MSG:
+
+			if (msg_len > 0) {
+				ses.pam_err  = buf_new(msg_len + 4);
+				buf_setpos(ses.pam_err, 0);
+				buf_putbytes(ses.pam_err, "\r\n", 2);
+				buf_putbytes(ses.pam_err, (*msg)->msg, msg_len);
+				buf_putbytes(ses.pam_err, "\r\n", 2);
+				buf_setpos(ses.pam_err, 0);
+
+				send_msg_userauth_banner(&ses.pam_err);
+			}
+
+			rc = PAM_AUTH_ERR;
+			break;
+
 		default:
 			TRACE(("Unknown message type"))
 			rc = PAM_CONV_ERR;


More information about the Dropbear mailing list