implemented server-initiated phase2 of EAP-TTLS authentication
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 16 Aug 2010 16:30:29 +0000 (18:30 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 16 Aug 2010 16:30:41 +0000 (18:30 +0200)
src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
src/libcharon/plugins/eap_ttls/eap_ttls_server.c

index b47ed93..b675d9a 100644 (file)
@@ -133,22 +133,30 @@ METHOD(tls_application_t, process, status_t,
                return FAILED;
        }
 
-       if (this->method->process(this->method, in, &this->out) == NEED_MORE)
-       {
-               in->destroy(in);
-               return NEED_MORE;
-       }
+       status = this->method->process(this->method, in, &this->out);
+       in->destroy(in);
 
-       if (vendor)
-       {
-               DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed", type, vendor);
-       }
-       else
+       switch (status)
        {
-               DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
-       }
-       in->destroy(in);
-       return FAILED;
+               case SUCCESS:
+                       this->method->destroy(this->method);
+                       this->method = NULL;
+                       /* fall through to NEED_MORE since response must be sent */
+               case NEED_MORE:
+                       return NEED_MORE;
+               case FAILED:
+               default:
+                       if (vendor)
+                       {
+                               DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed",
+                                                          type, vendor);
+                       }
+                       else
+                       {
+                               DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+                       }
+                       return FAILED;
+       }               
 }
 
 METHOD(tls_application_t, build, status_t,
index 45fc794..8401f85 100644 (file)
@@ -201,12 +201,23 @@ METHOD(tls_application_t, process, status_t,
                        DBG1(DBG_IKE, "%N phase2 authentication of '%Y' with %N successful",
                                                        eap_type_names, EAP_TTLS, this->peer,
                                                        eap_type_names, type);
+                       this->method->destroy(this->method);
+                       this->method = NULL;
                        break;
                case NEED_MORE:
                        break;
                case FAILED:
                default:
-                       DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+                       if (vendor)
+                       {
+                               DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed",
+                                                          type, vendor);
+                       }
+                       else
+                       {
+                               DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+                       }
+                       return FAILED;
        }               
        return status;
 }
@@ -219,6 +230,24 @@ METHOD(tls_application_t, build, status_t,
        eap_type_t type;
        u_int32_t vendor;
 
+       if (this->method == NULL && this->start_phase2 &&
+               lib->settings->get_bool(lib->settings,
+                               "charon.plugins.eap-ttls.phase2_piggyback", FALSE))
+       {
+               /* generate an EAP Identity request which will be piggybacked right
+                * onto the TLS Finished message thus initiating EAP-TTLS phase2
+                */
+               this->method = charon->eap->create_instance(charon->eap, EAP_IDENTITY,
+                                                                0,     EAP_SERVER, this->server, this->peer);
+               if (this->method == NULL)
+               {
+                       DBG1(DBG_IKE, "EAP_IDENTITY method not available");
+                       return FAILED;
+               }
+               this->method->initiate(this->method, &this->out);
+               this->start_phase2 = FALSE;
+       }
+
        if (this->out)
        {
                code = this->out->get_code(this->out);