Mac OS X EAP-TLS with wrong usename kills freeradius when check_cert_cn is set
Hi, We are building freeradius server to authenticate WLAN users with EAP-TLS and EAP-PEAP. EAP-PEAP works great with all tested operating systems, but Mac OS X 802.1X client with EAP-TLS kills freeradius if check_cert_cn is set on and Mac OS X user sends user name which does not match with certificate's common name. Operating system version is 10.4.8 and it runs on Macbook. If Window XP user sets different outer identity than cert's common name freeradius works ok (user gets rejected). We have tested following freeradius server versions on following platforms Freeradius 1.1.1 / SUN Os 5.8 Freeradius 1.1.3 (FC6's rpm) / FC6 Freeradius 1.1.4 (build from source)/ FC6 Freeradius snapshot 20070118 (build from source) / FC6 Freeradius 1.1.4 (build from source) / CentOS 4.4 FC and Centos are using distros default openssl libs etc. Heres some log and debug from CentOS with freerad 1.1.4 http://cc.oulu.fi/~mraisane/tmp/radiusd.txt Any ideas, fixes or workarounds?
Miika Räisänen wrote:
We are building freeradius server to authenticate WLAN users with EAP-TLS and EAP-PEAP. EAP-PEAP works great with all tested operating systems, but Mac OS X 802.1X client with EAP-TLS kills freeradius if check_cert_cn is set on and Mac OS X user sends user name which does not match with certificate's common name. Operating system version is 10.4.8 and it runs on Macbook.
I've heard something similar before, and I haven't been able to figure out why it happens.
We have tested following freeradius server versions on following platforms Freeradius 1.1.1 / SUN Os 5.8 Freeradius 1.1.3 (FC6's rpm) / FC6 Freeradius 1.1.4 (build from source)/ FC6 Freeradius snapshot 20070118 (build from source) / FC6 Freeradius 1.1.4 (build from source) / CentOS 4.4
That says it's common code, at least.
Any ideas, fixes or workarounds?
If you can get a core dump, that would help a lot. See doc/bugs Or, if you can run the server under "valgrind" for testing, it should print out what's going wrong. Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog
On 1/19/07, Alan DeKok <aland@deployingradius.com> wrote:
Miika Räisänen wrote:
We are building freeradius server to authenticate WLAN users with EAP-TLS and EAP-PEAP. EAP-PEAP works great with all tested operating systems, but Mac OS X 802.1X client with EAP-TLS kills freeradius if check_cert_cn is set on and Mac OS X user sends user name which does not match with certificate's common name. Operating system version is 10.4.8 and it runs on Macbook.
I've heard something similar before, and I haven't been able to figure out why it happens.
We have tested following freeradius server versions on following platforms Freeradius 1.1.1 / SUN Os 5.8 Freeradius 1.1.3 (FC6's rpm) / FC6 Freeradius 1.1.4 (build from source)/ FC6 Freeradius snapshot 20070118 (build from source) / FC6 Freeradius 1.1.4 (build from source) / CentOS 4.4
That says it's common code, at least.
Any ideas, fixes or workarounds?
If you can get a core dump, that would help a lot. See doc/bugs
Or, if you can run the server under "valgrind" for testing, it should print out what's going wrong.
Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog
Heres coredump gdb logfile http://cc.oulu.fi/~mraisane/tmp/gdb-radiusd.log and valgrind logfile http://cc.oulu.fi/~mraisane/tmp/radiusd.valgrind.7386 from freerad 1.1.4 on CentOS.
Miika Räisänen wrote:
Heres coredump gdb logfile http://cc.oulu.fi/~mraisane/tmp/gdb-radiusd.log
Well, that's pretty clear: #0 0x00e97899 in cbtls_verify (ok=1, ctx=0xbff1e330) at rlm_eap_tls.c:257 ... handler = (EAP_HANDLER *) 0x1 That's not a valid pointer. It looks like the handler is being freed somewhere. Try the following patch, and run the server in debugging mode. It won't fix the problem, but it might help track down where/why the server is freeing an EAP session that's still in the middle of doing SSL. Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog ? eap.patch ? radeapclient Index: eap.h =================================================================== RCS file: /source/radiusd/src/modules/rlm_eap/eap.h,v retrieving revision 1.27.4.1 diff -u -r1.27.4.1 eap.h --- eap.h 6 Feb 2006 16:23:50 -0000 1.27.4.1 +++ eap.h 19 Jan 2007 16:12:50 -0000 @@ -121,6 +121,7 @@ int status; int stage; + int in_ssl; } EAP_HANDLER; /* Index: mem.c =================================================================== RCS file: /source/radiusd/src/modules/rlm_eap/mem.c,v retrieving revision 1.14.4.2 diff -u -r1.14.4.2 mem.c --- mem.c 9 May 2006 20:59:23 -0000 1.14.4.2 +++ mem.c 19 Jan 2007 16:12:51 -0000 @@ -139,6 +139,8 @@ handler->opaque = NULL; handler->free_opaque = NULL; + if (handler->in_ssl) DEBUG2("This will crash the server!"); + free(handler); } Index: libeap/tls.c =================================================================== RCS file: /source/radiusd/src/modules/rlm_eap/libeap/tls.c,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 tls.c --- libeap/tls.c 27 Apr 2006 18:53:23 -0000 1.1.2.3 +++ libeap/tls.c 19 Jan 2007 16:12:51 -0000 @@ -267,8 +267,15 @@ void session_close(tls_session_t *ssn) { - if(ssn->ssl) + if(ssn->ssl) { + EAP_HANDLER *handler; + + handler = (EAP_HANDLER *)SSL_get_ex_data(ssn->ssl, 0); + if (handler) handler->in_ssl = 0; + SSL_free(ssn->ssl); + } + #if 0 /* * WARNING: SSL_free seems to decrement the reference counts already, Index: types/rlm_eap_tls/rlm_eap_tls.c =================================================================== RCS file: /source/radiusd/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c,v retrieving revision 1.21.4.12 diff -u -r1.21.4.12 rlm_eap_tls.c --- types/rlm_eap_tls/rlm_eap_tls.c 29 Nov 2006 22:59:48 -0000 1.21.4.12 +++ types/rlm_eap_tls/rlm_eap_tls.c 19 Jan 2007 16:12:55 -0000 @@ -615,6 +615,7 @@ * this index should be global. */ SSL_set_ex_data(ssn->ssl, 0, (void *)handler); + handler->in_ssl = 1; SSL_set_ex_data(ssn->ssl, 1, (void *)inst->conf); ssn->length_flag = inst->conf->include_length;
On 1/19/07, Alan DeKok <aland@deployingradius.com> wrote:
Miika Räisänen wrote:
Heres coredump gdb logfile http://cc.oulu.fi/~mraisane/tmp/gdb-radiusd.log
Well, that's pretty clear:
#0 0x00e97899 in cbtls_verify (ok=1, ctx=0xbff1e330) at rlm_eap_tls.c:257 ... handler = (EAP_HANDLER *) 0x1
That's not a valid pointer. It looks like the handler is being freed somewhere.
Try the following patch, and run the server in debugging mode. It won't fix the problem, but it might help track down where/why the server is freeing an EAP session that's still in the middle of doing SSL.
Alan DeKok.
Ok, patch applied and heres log files: radiusd run: http://cc.oulu.fi/~mraisane/tmp/radiusd.1st-patch.log and gdb after core dump: http://cc.oulu.fi/~mraisane/tmp/gdb-radiusd.1st-patch.log
Miika Räisänen wrote:
Ok, patch applied and heres log files:
The patch hasn't helped (that's expected), but I think I now have more information about how to fix the problem. I'll try to come up with a patch that should fix the problem. Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog
Miika Räisänen wrote:
and gdb after core dump: http://cc.oulu.fi/~mraisane/tmp/gdb-radiusd.1st-patch.log
Please try the following patch. I believe it will fix the problem. If so, I'll commit it to CVS. Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog ? eap.patch ? radeapclient Index: libeap/tls.c =================================================================== RCS file: /source/radiusd/src/modules/rlm_eap/libeap/tls.c,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 tls.c --- libeap/tls.c 27 Apr 2006 18:53:23 -0000 1.1.2.3 +++ libeap/tls.c 24 Jan 2007 09:00:27 -0000 @@ -92,7 +92,7 @@ /* * Print out some text describing the error. */ -static void int_ssl_check(SSL *s, int ret, const char *text) +static int int_ssl_check(SSL *s, int ret, const char *text) { int e; @@ -117,7 +117,7 @@ case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_ZERO_RETURN: - return; + break; /* * These seem to be indications of a genuine @@ -127,14 +127,12 @@ case SSL_ERROR_SYSCALL: radlog(L_ERR, "rlm_eap_tls: %s failed in a system call (%d), TLS session fails.", text, ret); - SSL_set_app_data(s, (char *)1); - return; + return 0; case SSL_ERROR_SSL: radlog(L_ERR, "rlm_eap_tls: %s failed inside of TLS (%d), TLS session fails.", text, ret); - SSL_set_app_data(s, (char *)1); - return; + return 0; default: /* @@ -144,8 +142,10 @@ * the code needs updating here. */ radlog(L_ERR, "rlm_eap_tls: FATAL SSL error ..... %d\n", e); - break; + return 0; } + + return 1; } /* @@ -170,8 +170,8 @@ sizeof(ssn->clean_out.data)); if (err > 0) { ssn->clean_out.used = err; - } else { - int_ssl_check(ssn->ssl, err, "SSL_read"); + } else if (!int_ssl_check(ssn->ssl, err, "SSL_read")) { + return 0; } /* Some Extra STATE information for easy debugging */
On 1/24/07, Alan DeKok <aland@deployingradius.com> wrote:
Miika Räisänen wrote:
and gdb after core dump: http://cc.oulu.fi/~mraisane/tmp/gdb-radiusd.1st-patch.log
Please try the following patch. I believe it will fix the problem.
If so, I'll commit it to CVS.
Alan DeKok.
It worked. Thanks.
Hi, while trying to reproduce the segfault and eventually looking into the diagnostic patch Alan provided I came across something which might be contributing (also freeradius should not segfault nevertheless). When feeding a freeradius-1.1.3 (linux) an "forged" Acces-Request with bogus user name and ask it to check_cert_cn it detects the mismatch, etc. just like in your example and sends out a fatal tls alert. My test client wpa_supplicant (also linux) picks that up, recognizes the failure and essentially stops that run to authenticate and sends an tls alert ACK inside the next Access-Request. freeradius recognizes it and only then sends an Access-Reject without much further processing. After some timeout the supplicant tries anew. That would be the first Access-Request freeradius sees again from it. As its still wrongly configured the above repeats...no segfault (see attached debug log, a bit bloated as I use basically that setup for other tests too) Whereas I noticed in your debug log that immediately after the tls alert message from freeradius your client sends (keeping on with authentication?) an EAP-Message containing a CertificateVerify tls message (sort of manually decoding) EAP-Message = 0x0205002f0d800000002515030100207a99997bc8a6c68c3a5c5770c8b46fdd7b8848b6850dc4ea57d1d0e0434ae4c8 for reasons I do not understand. It's that message that leads to the segfault in cbtls_verify. As said above some strangely (wrongfully?) behaving client shouldn't be able to crash the authentication server but it looks curious. Perhaps someone might find that information helpful. regards K. Hoercher
participants (3)
-
Alan DeKok -
K. Hoercher -
Miika Räisänen