From: dean gaudet <dean-list-dovecot@arctic.org>
Date: 9. heinŠkuuta 2004 04:55:22 GMT+03:00
To: dovecot@dovecot.org
Subject: [Dovecot] passing remote ip to pam

to improve forensic log info i want to set the PAM_RHOST value to the
remote ip (which pam logs as rhost=foo in failure messages).  i didn't
look to see if anything has been done in this way on CVS because i'm still
on 0.99.10.6.

below is a bit of a hack.  in some sense the remote_ip might make more
sense in the AUTH_LOGIN_REQUEST_NEW packet rather than the continue
packet... but that looked like i'd have to change more code :)

btw -- is there anything which stops mech_plain_auth_continue from doing a
somewhat unbounded pstrdup if you send "a\0b" for the auth string?

-dean

diff -rpu dovecot-0.99.10.6.deborig/debian/changelog dovecot-0.99.10.6/debian/changelog
--- dovecot-0.99.10.6.deborig/debian/changelog	2004-07-08 18:11:55.000000000 -0700
+++ dovecot-0.99.10.6/debian/changelog	2004-07-08 18:34:40.000000000 -0700
@@ -1,3 +1,9 @@
+dovecot (0.99.10.6-3.dg1) unstable; urgency=low
+
+  * hack a solution to pass PAM_RHOST the remote ip
+
+ -- dean gaudet <dean@arctic.org>  Thu,  8 Jul 2004 18:34:26 -0700
+
 dovecot (0.99.10.6-3) unstable; urgency=low

   * Patched so dovecot follows symlinks to directories again.
diff -rpu dovecot-0.99.10.6.deborig/src/auth/auth-login-interface.h dovecot-0.99.10.6/src/auth/auth-login-interface.h
--- dovecot-0.99.10.6.deborig/src/auth/auth-login-interface.h	2003-05-18 05:26:28.000000000 -0700
+++ dovecot-0.99.10.6/src/auth/auth-login-interface.h	2004-07-08 18:32:22.000000000 -0700
@@ -1,6 +1,8 @@
 #ifndef __AUTH_LOGIN_INTERFACE_H
 #define __AUTH_LOGIN_INTERFACE_H

+#include "network.h"
+
 /* max. size for auth_login_request_continue.data[] */
 #define AUTH_LOGIN_MAX_REQUEST_DATA_SIZE 4096

@@ -57,6 +59,8 @@ struct auth_login_request_continue {
 	enum auth_login_request_type type; /* AUTH_LOGIN_REQUEST_CONTINUE */
 	unsigned int id;

+	struct ip_addr remote_ip;
+
 	size_t data_size;
 	/* unsigned char data[]; */
 };
diff -rpu dovecot-0.99.10.6.deborig/src/auth/mech-plain.c dovecot-0.99.10.6/src/auth/mech-plain.c
--- dovecot-0.99.10.6.deborig/src/auth/mech-plain.c	2003-05-18 05:26:28.000000000 -0700
+++ dovecot-0.99.10.6/src/auth/mech-plain.c	2004-07-08 18:25:14.000000000 -0700
@@ -21,6 +21,7 @@ mech_plain_auth_continue(struct auth_req
 	size_t i, count, len;

 	auth_request->callback = callback;
+	auth_request->remote_ip = request->remote_ip;

 	/* authorization ID \0 authentication ID \0 pass.
 	   we'll ignore authorization ID for now. */
diff -rpu dovecot-0.99.10.6.deborig/src/auth/mech.h dovecot-0.99.10.6/src/auth/mech.h
--- dovecot-0.99.10.6.deborig/src/auth/mech.h	2003-05-18 05:26:28.000000000 -0700
+++ dovecot-0.99.10.6/src/auth/mech.h	2004-07-08 18:31:42.000000000 -0700
@@ -1,6 +1,7 @@
 #ifndef __MECH_H
 #define __MECH_H

+#include "network.h"
 #include "auth-login-interface.h"

 struct login_connection;
@@ -11,6 +12,7 @@ typedef void mech_callback_t(struct auth
 struct auth_request {
 	pool_t pool;
 	char *user;
+	struct ip_addr remote_ip;

 	struct login_connection *conn;
 	unsigned int id;
diff -rpu dovecot-0.99.10.6.deborig/src/auth/passdb-pam.c dovecot-0.99.10.6/src/auth/passdb-pam.c
--- dovecot-0.99.10.6.deborig/src/auth/passdb-pam.c	2003-11-08 06:17:51.000000000 -0800
+++ dovecot-0.99.10.6/src/auth/passdb-pam.c	2004-07-08 18:32:52.000000000 -0700
@@ -166,13 +166,23 @@ static int pam_userpass_conv(int num_msg
 	return PAM_SUCCESS;
 }

-static int pam_auth(pam_handle_t *pamh, const char *user, const char **error)
+static int pam_auth(pam_handle_t *pamh, const char *user,
+		const struct ip_addr *remote_ip, const char **error)
 {
 	void *item;
 	int status;
+	const char *addr;

 	*error = NULL;

+	if ((addr = net_ip2addr(remote_ip))
+		&& (status = pam_set_item(pamh, PAM_RHOST, addr))
+			!= PAM_SUCCESS) {
+		*error = t_strdup_printf("pam_set_item(PAM_RHOST, %s) failed: %s",
+					 addr, pam_strerror(pamh, status));
+		return status;
+	}
+
 	if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
 		*error = t_strdup_printf("pam_authenticate(%s) failed: %s",
 					 user, pam_strerror(pamh, status));
@@ -205,7 +215,8 @@ static int pam_auth(pam_handle_t *pamh,

 static void
 pam_verify_plain_child(const char *service, const char *user,
-		       const char *password, int fd)
+		       const char *password, const struct ip_addr *remote_ip,
+		       int fd)
 {
 	pam_handle_t *pamh;
 	struct pam_userpass userpass;
@@ -228,7 +239,7 @@ pam_verify_plain_child(const char *servi
 		str = t_strdup_printf("pam_start(%s) failed: %s",
 				      user, pam_strerror(pamh, status));
 	} else {
-		status = pam_auth(pamh, user, &str);
+		status = pam_auth(pamh, user, remote_ip, &str);
 		if ((status2 = pam_end(pamh, status)) == PAM_SUCCESS) {
 			/* FIXME: check for PASSDB_RESULT_UNKNOWN_USER
 			   somehow? */
@@ -353,7 +364,7 @@ pam_verify_plain(struct auth_request *re

 	if (pid == 0) {
 		(void)close(fd[0]);
-		pam_verify_plain_child(service, request->user, password, fd[1]);
+		pam_verify_plain_child(service, request->user, password, &request->remote_ip, fd[1]);
 		_exit(0);
 	}

diff -rpu dovecot-0.99.10.6.deborig/src/imap-login/client-authenticate.c dovecot-0.99.10.6/src/imap-login/client-authenticate.c
--- dovecot-0.99.10.6.deborig/src/imap-login/client-authenticate.c	2003-11-24 11:50:55.000000000 -0800
+++ dovecot-0.99.10.6/src/imap-login/client-authenticate.c	2004-07-08 18:21:19.000000000 -0700
@@ -140,7 +140,7 @@ static void login_callback(struct auth_r
 	case 0:
 		/* continue */
 		ptr = buffer_get_data(client->plain_login, &size);
-		auth_continue_request(request, ptr, size);
+		auth_continue_request(request, ptr, size, &client->common.ip);

 		buffer_set_used_size(client->plain_login, 0);
 		break;
@@ -270,7 +270,8 @@ static void client_auth_input(void *cont
 	} else {
 		auth_continue_request(client->common.auth_request,
 				      buffer_get_data(buf, NULL),
-				      buffer_get_used_size(buf));
+				      buffer_get_used_size(buf),
+				      &client->common.ip);
 	}

 	/* clear sensitive data */
diff -rpu dovecot-0.99.10.6.deborig/src/login-common/auth-connection.c dovecot-0.99.10.6/src/login-common/auth-connection.c
--- dovecot-0.99.10.6.deborig/src/login-common/auth-connection.c	2003-05-26 08:27:13.000000000 -0700
+++ dovecot-0.99.10.6/src/login-common/auth-connection.c	2004-07-08 18:33:38.000000000 -0700
@@ -335,13 +335,21 @@ int auth_init_request(enum auth_mech mec
 }

 void auth_continue_request(struct auth_request *request,
-			   const unsigned char *data, size_t data_size)
+			   const unsigned char *data, size_t data_size,
+			   const struct ip_addr *remote_ip)
 {
 	struct auth_login_request_continue auth_request;

 	/* send continued request to auth */
 	auth_request.type = AUTH_LOGIN_REQUEST_CONTINUE;
 	auth_request.id = request->id;
+	if (remote_ip) {
+		auth_request.remote_ip = *remote_ip;
+	}
+	else {
+		memset(&auth_request.remote_ip,
+			0, sizeof(auth_request.remote_ip));
+	}
 	auth_request.data_size = data_size;

 	if (o_stream_send(request->conn->output, &auth_request,
diff -rpu dovecot-0.99.10.6.deborig/src/login-common/auth-connection.h dovecot-0.99.10.6/src/login-common/auth-connection.h
--- dovecot-0.99.10.6.deborig/src/login-common/auth-connection.h	2003-02-09 23:56:23.000000000 -0800
+++ dovecot-0.99.10.6/src/login-common/auth-connection.h	2004-07-08 18:20:58.000000000 -0700
@@ -48,7 +48,8 @@ int auth_init_request(enum auth_mech mec
 		      const char **error);

 void auth_continue_request(struct auth_request *request,
-			   const unsigned char *data, size_t data_size);
+			   const unsigned char *data, size_t data_size,
+			   const struct ip_addr *remote_ip);

 void auth_abort_request(struct auth_request *request);

diff -rpu dovecot-0.99.10.6.deborig/src/pop3-login/client-authenticate.c dovecot-0.99.10.6/src/pop3-login/client-authenticate.c
--- dovecot-0.99.10.6.deborig/src/pop3-login/client-authenticate.c	2003-11-24 11:52:09.000000000 -0800
+++ dovecot-0.99.10.6/src/pop3-login/client-authenticate.c	2004-07-08 18:21:32.000000000 -0700
@@ -141,7 +141,7 @@ static void login_callback(struct auth_r

 	case 0:
 		ptr = buffer_get_data(client->plain_login, &size);
-		auth_continue_request(request, ptr, size);
+		auth_continue_request(request, ptr, size, &client->common.ip);

 		buffer_set_used_size(client->plain_login, 0);
 		break;
@@ -259,7 +259,8 @@ static void client_auth_input(void *cont
 	} else {
 		auth_continue_request(client->common.auth_request,
 				      buffer_get_data(buf, NULL),
-				      buffer_get_used_size(buf));
+				      buffer_get_used_size(buf),
+				      &client->common.ip);
 	}

 	/* clear sensitive data */
