[Swan] SUCCESS Re: NEW PROBLEM Re: IKEv2 PAM auth failure - how it's done properly?
Paul Wouters
paul at nohats.ca
Tue Jan 25 05:24:06 EET 2022
On Mon, 24 Jan 2022, Mirsad Goran Todorovac wrote:
> I can publish a patch diff. I have really made very small modifications. A couple of lines.
> I would also want to map certificate subject lines to unix usernames, put the user into utmp and display the connected user with `w`
> or `who` commands. But I'm not sure how it's done yet.
Attached is what I had gobbled together to pull IDs from certificates inside pam_url for IKEv2.
> Maybe I should think of forking pam_url and supplying a Debian .deb package, since only .rpm exists in the wild?
I don't think it is well maintained or active upstream?
> pam-authenticate is a very practical method of access control. I would like to clear the doubts that it decreased the security of
> IKEv2 VPN, and that it is unprofessional, because pam_url calls a cgi-bin script in .php over a TLSv1.3 connection.
It still beats 10 round trips of EAPTLS on Windows :)
Paul
-------------- next part --------------
diff -Naur pam_url-0.3.3-orig/examples/pam_url.conf pam_url-0.3.3/examples/pam_url.conf
--- pam_url-0.3.3-orig/examples/pam_url.conf 2013-11-18 17:04:54.000000000 -0500
+++ pam_url-0.3.3/examples/pam_url.conf 2017-09-23 13:07:07.760000000 -0400
@@ -6,10 +6,10 @@
{
url = "https://totp.example.com/"; # URI to fetch
returncode = "OK"; # The remote script/cgi should return a 200 http code and this string as its only results
- userfield = "user"; # userfield name to send
- passwdfield = "token"; # passwdfield name to send
- extradata = "&do=login"; # extra data to send
- prompt = "Token: "; # password prompt
+ userfield = "username"; # userfield name to send
+ passwdfield = "password"; # passwdfield name to send
+ extradata = "&clientIP"; # extra data to send
+ prompt = "password: "; # password prompt
};
ssl:
diff -Naur pam_url-0.3.3-orig/pam_url.c pam_url-0.3.3/pam_url.c
--- pam_url-0.3.3-orig/pam_url.c 2013-11-18 17:04:54.000000000 -0500
+++ pam_url-0.3.3/pam_url.c 2017-09-23 13:16:40.141000000 -0400
@@ -18,7 +18,6 @@
{
char* p = NULL;
const char *prompt;
- int prompt_len = 0;
if(config_lookup_string(&config, "pam_url.settings.prompt", &prompt) == CONFIG_FALSE)
prompt = DEF_PROMPT;
@@ -199,7 +198,23 @@
if( NULL == (eh = curl_easy_init() ) )
goto curl_error;
- char *safe_user = curl_easy_escape(eh, opts.user, 0);
+ /* 512 matches libreswan's IDTOA_BUF */
+ char *user_start;
+ char *user_end;
+ char *username = malloc(512);
+ strncpy(username, opts.user, 512);
+ user_start = strstr(username, "CN=");
+ if(user_start != NULL) {
+ user_start = user_start + sizeof("CN=") - 1;
+ user_end = strstr(user_start, "@");
+ if(user_end != NULL)
+ user_end[0] = '\0';
+ else
+ user_start = username;
+ } else
+ user_start = username;
+
+ char *safe_user = curl_easy_escape(eh, user_start, 0);
if( safe_user == NULL )
goto curl_error;
@@ -228,15 +243,19 @@
if( safe_passwd == NULL )
goto curl_error;
- ret = asprintf(&post, "%s=%s&%s=%s&mode=%s%s", opts.user_field,
+ const char *clientIP;
+ if (PAM_SUCCESS != pam_get_item(pamh, PAM_RHOST, (const void **)&clientIP))
+ debug(pamh, "Could not get PAM_RHOST from pam.");
+ else
+ debug(pamh, "PAM_RHOST retrieved from pam.");
+
+ ret = asprintf(&post, "%s=%s&%s=%s%s%s", opts.user_field,
safe_user,
opts.passwd_field,
safe_passwd,
- opts.mode,
- opts.extra_field);
-
- curl_free(safe_passwd);
- curl_free(safe_user);
+ /* opts.mode, */
+ opts.extra_field,
+ clientIP);
if (ret == -1)
// If this happens, the contents of post are undefined, we could
@@ -255,9 +274,10 @@
if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_DEBUGFUNCTION, curl_debug) )
goto curl_error;
}
-
+/*
if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_POSTFIELDS, post) )
goto curl_error;
+*/
if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_USERAGENT, USER_AGENT) )
goto curl_error;
@@ -265,7 +285,16 @@
if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, curl_wf) )
goto curl_error;
- if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_URL, opts.url) )
+ char *newurl, *baseurl;
+ baseurl = malloc(strlen(opts.url));
+ strncpy(baseurl, opts.url, strlen(opts.url));
+ /* baseurl[strlen(opts.url)-1] = '\0'; */
+ ret = asprintf(&newurl,"%s?%s",opts.url, post);
+ free(baseurl);
+ if (ret == -1)
+ goto curl_error;
+
+ if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_URL, newurl) )
goto curl_error;
if( CURLE_OK != curl_easy_setopt(eh, CURLOPT_SSLCERT, opts.ssl_cert) )
@@ -312,11 +341,20 @@
goto curl_error;
// No errors
+ free(username);
+ curl_free(safe_user);
+ curl_free(safe_passwd);
curl_easy_cleanup(eh);
free(post);
return PAM_SUCCESS;
curl_error:
+ if(username != NULL)
+ free(username);
+ if(safe_user != NULL)
+ curl_free(safe_user);
+ if(safe_passwd != NULL)
+ curl_free(safe_passwd);
if (eh != NULL)
curl_easy_cleanup(eh);
if (post != NULL)
@@ -333,8 +371,7 @@
return PAM_AUTH_ERR;
}
- if( strlen(opts.ret_code) == recvbuf_size &&
- 0 == strncmp(opts.ret_code, recvbuf, recvbuf_size) )
+ if (strstr(recvbuf, opts.ret_code) != NULL)
{
return PAM_SUCCESS;
}
More information about the Swan
mailing list