diff -Naur libreswan-3.15-orig/programs/pluto/ikev1_xauth.c libreswan-3.15/programs/pluto/ikev1_xauth.c --- libreswan-3.15-orig/programs/pluto/ikev1_xauth.c 2015-08-24 16:52:43.000000000 -0400 +++ libreswan-3.15/programs/pluto/ikev1_xauth.c 2015-09-03 11:32:27.525000000 -0400 @@ -1001,81 +1001,6 @@ return STF_OK; } -#ifdef XAUTH_HAVE_PAM - -/** Do authentication via PAM (Plugable Authentication Modules) - * - * We try to authenticate the user in our own PAM session. - * - * @return bool success - */ -/* IN AN AUTH THREAD */ -static bool do_pam_authentication(void *varg) -{ - struct xauth_thread_arg *arg = varg; - int retval; - pam_handle_t *pamh = NULL; - struct pam_conv conv; - const char *what; - - /* This do-while structure is designed to allow a logical cascade - * without excessive indentation. No actual looping happens. - * Failure is handled by "break". - */ - do { - ipstr_buf ra; - - conv.conv = pam_conv; - conv.appdata_ptr = varg; - - what = "pam_start"; - retval = pam_start("pluto", arg->name, &conv, &pamh); - if (retval != PAM_SUCCESS) - break; - - DBG(DBG_CONTROL, DBG_log("pam_start SUCCESS")); - - /* Send the remote host address to PAM */ - what = "pam_set_item"; - retval = pam_set_item(pamh, PAM_RHOST, - ipstr(&arg->st->st_remoteaddr, &ra)); - if (retval != PAM_SUCCESS) - break; - - DBG(DBG_CONTROL, DBG_log("pam_set_item SUCCESS")); - - /* Two factor authentication - Check that the user is valid, - * and then check if they are permitted access - */ - what = "pam_authenticate"; - retval = pam_authenticate(pamh, PAM_SILENT); /* is user really user? */ - - if (retval != PAM_SUCCESS) - break; - - DBG(DBG_CONTROL, DBG_log("pam_authenticate SUCCESS")); - - what = "pam_acct_mgmt"; - retval = pam_acct_mgmt(pamh, 0); /* permitted access? */ - if (retval != PAM_SUCCESS) - break; - - /* success! */ - libreswan_log("XAUTH: PAM_SUCCESS"); - pam_end(pamh, PAM_SUCCESS); - return TRUE; - } while (FALSE); - - /* common failure code */ - - DBG(DBG_CONTROL, - DBG_log("%s failed with '%s", what, pam_strerror(pamh, retval))); - libreswan_log("XAUTH: %s failed with '%s'", what, pam_strerror(pamh, retval)); - pam_end(pamh, retval); - return FALSE; -} -#endif /* XAUTH_HAVE_PAM */ - /** Do authentication via /etc/ipsec.d/passwd file using MD5 passwords * * Structure is one entry per line. @@ -1256,6 +1181,43 @@ return win; } +/* IN AN AUTH THREAD */ +static bool ikev1_do_pam_authentication(const struct xauth_thread_arg *arg) +{ + struct state *st = arg->st; + libreswan_log("XAUTH: pam authentication being called to authenticate user %s", + arg->name); + struct pam_thread_arg parg; + ipstr_buf ra; + struct timeval start_time; + struct timeval served_time; + struct timeval served_delta; + bool results = FALSE; + + parg.name = arg->name; + parg.password = arg->password; + parg.c_name = arg->connname; + parg.ra = clone_str(ipstr(&st->st_remoteaddr, &ra), "st remote address"); + parg.st_serialno = st->st_serialno; + parg.c_instance_serial = st->st_connection->instance_serial; + parg.atype = "XAUTH"; + gettimeofday(&start_time, NULL); + results = do_pam_authentication(&parg); + gettimeofday(&served_time, NULL); + timersub(&served_time, &start_time, &served_delta); + DBG(DBG_CONTROL, DBG_log("XAUTH PAM helper thread call " + "state #%lu, %s[%lu] user=%s %s. " + "elapsed time %lu.%06lu", + parg.st_serialno, parg.c_name, + parg.c_instance_serial, parg.name, + results ? "SUCCESS" : "FAIL", + (unsigned long)served_delta.tv_sec, + (unsigned long)(served_delta.tv_usec * 1000000))); + + pfreeany(parg.ra); + return (results); +} + /* * Main authentication routine will then call the actual compiled-in * method to verify the user/password @@ -1330,10 +1292,7 @@ switch (st->st_connection->xauthby) { #ifdef XAUTH_HAVE_PAM case XAUTHBY_PAM: - libreswan_log( - "XAUTH: pam authentication being called to authenticate user %s", - arg->name); - results = do_pam_authentication(varg); + results = ikev1_do_pam_authentication(arg); break; #endif case XAUTHBY_FILE: diff -Naur libreswan-3.15-orig/programs/pluto/ikev2_parent.c libreswan-3.15/programs/pluto/ikev2_parent.c --- libreswan-3.15-orig/programs/pluto/ikev2_parent.c 2015-09-03 11:29:05.518000000 -0400 +++ libreswan-3.15/programs/pluto/ikev2_parent.c 2015-09-03 11:32:27.526000000 -0400 @@ -2417,7 +2417,7 @@ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcancelstate (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - p->pam_status = ikev2_do_pam_authentication(&p->pam); + p->pam_status = do_pam_authentication(&p->pam); gettimeofday(&p->done_time, NULL); timersub(&p->done_time, &p->start_time, &done_delta); @@ -2580,6 +2580,7 @@ p->pam.ra = clone_str(ipstr(&st->st_remoteaddr, &ra), "st remote address"); p->pam.c_instance_serial = st->st_connection->instance_serial; p->pam.st_serialno = st->st_serialno; + p->pam.atype = "IKEv2"; p->next = pluto_v2_pam_helpers; pluto_v2_pam_helpers = p; diff -Naur libreswan-3.15-orig/programs/pluto/pam_conv.c libreswan-3.15/programs/pluto/pam_conv.c --- libreswan-3.15-orig/programs/pluto/pam_conv.c 2015-08-24 16:52:43.000000000 -0400 +++ libreswan-3.15/programs/pluto/pam_conv.c 2015-09-03 11:32:27.526000000 -0400 @@ -10,7 +10,7 @@ * Copyright (C) 2012-2013 Paul Wouters * Copyright (C) 2012-2013 Philippe Vouters * Copyright (C) 2013 David McCullough - * Copyright (C) 2013 Antony Antony + * Copyright (C) 2013-2015 Antony Antony * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -109,15 +109,25 @@ return PAM_SUCCESS; } +static void log_pam_step(const struct pam_thread_arg *arg, const char *what, + const char *how) +{ + DBG(DBG_CONTROL, DBG_log("%s helper thread %s %s for " + "state #%lu, %s[%lu] user=%s.", + arg->atype, what, how, + arg->st_serialno, arg->c_name, + arg->c_instance_serial, arg->name)); + +} + /* * Do IKEv2 second authentication via PAM (Plugable Authentication Modules) * * @return bool success */ /* IN AN AUTH THREAD */ -bool ikev2_do_pam_authentication(void *varg) +bool do_pam_authentication(struct pam_thread_arg *arg) { - struct pam_thread_arg *arg = varg; int retval; pam_handle_t *pamh = NULL; struct pam_conv conv; @@ -129,22 +139,20 @@ */ do { conv.conv = pam_conv; - conv.appdata_ptr = varg; + conv.appdata_ptr = arg; what = "pam_start"; retval = pam_start("pluto", arg->name, &conv, &pamh); if (retval != PAM_SUCCESS) break; - - DBG(DBG_CONTROL, DBG_log("pam_start SUCCESS")); + log_pam_step(arg, what, "SUCCESS"); /* Send the remote host address to PAM */ what = "pam_set_item"; retval = pam_set_item(pamh, PAM_RHOST, arg->ra); if (retval != PAM_SUCCESS) break; - - DBG(DBG_CONTROL, DBG_log("pam_set_item SUCCESS")); + log_pam_step(arg, what, "SUCCESS"); /* Two factor authentication - Check that the user is valid, * and then check if they are permitted access @@ -154,16 +162,16 @@ if (retval != PAM_SUCCESS) break; + log_pam_step(arg, what, "SUCCESS"); - DBG(DBG_CONTROL, DBG_log("pam_authenticate SUCCESS")); - - what = "pam_acct_mgmt"; retval = pam_acct_mgmt(pamh, 0); /* permitted access? */ if (retval != PAM_SUCCESS) break; + what = "pam"; + log_pam_step(arg, what, "SUCCESS"); + /* success! */ - libreswan_log("IKEv2: PAM_SUCCESS"); pam_end(pamh, PAM_SUCCESS); return TRUE; } while (FALSE); diff -Naur libreswan-3.15-orig/programs/pluto/pam_conv.h libreswan-3.15/programs/pluto/pam_conv.h --- libreswan-3.15-orig/programs/pluto/pam_conv.h 2015-08-24 16:52:43.000000000 -0400 +++ libreswan-3.15/programs/pluto/pam_conv.h 2015-09-03 11:32:27.527000000 -0400 @@ -23,9 +23,10 @@ char *ra; so_serial_t st_serialno; unsigned long c_instance_serial; + char *atype; /* string XAUTH or IKEv2 */ }; -extern bool ikev2_do_pam_authentication(void *varg); +extern bool do_pam_authentication(struct pam_thread_arg *arg); int pam_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr);