[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 */
On Fri, 2004-07-09 at 04:55, dean gaudet wrote:
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 :)
It's done that way in CVS. CVS also sends local ip and protocol information.
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?
Oh, right, thanks. But I don't think it could be used to do anything bad. Maybe crash dovecot-auth in some circumstances, but it gets restarted automatically then. Fix is anyway: ot-0.99.10.6/src/auth/mech-plain.c --- dovecot-0.99.10.6-orig/src/auth/mech-plain.c 2003-05-18 15:26:28.000000000 +0300 +++ dovecot-0.99.10.6/src/auth/mech-plain.c 2004-07-09 13:47:01.000000000 +0300 @@ -41,7 +41,7 @@ } } - if (authenid == NULL) { + if (count != 2) { /* invalid input */ if (verbose) i_info("mech-plain: no username given");
+dovecot (0.99.10.6-3.dg1) unstable; urgency=low + + * hack a solution to pass PAM_RHOST the remote ip
Looks good.
participants (2)
-
dean gaudet
-
Timo Sirainen