IKEv1 XAuth: XAuthInitPreShared working for XAuth initiator (Main Mode responder...
authorClavister OpenSource <opensource@clavister.com>
Thu, 24 Nov 2011 10:46:02 +0000 (11:46 +0100)
committerClavister OpenSource <opensource@clavister.com>
Tue, 20 Mar 2012 16:30:52 +0000 (17:30 +0100)
src/libcharon/sa/tasks/xauth_request.c

index 14ee75a..09ddb90 100644 (file)
@@ -7,6 +7,11 @@
 
 typedef struct private_xauth_request_t private_xauth_request_t;
 
+enum {
+       XAUTH_STATUS_FAIL = 0,
+       XAUTH_STATUS_OK = 1,
+};
+
 /**
  * Private members of a xauth_request_t task.
  */
@@ -36,6 +41,29 @@ struct private_xauth_request_t {
         * list of attributes requested and its handler, entry_t
         */
        linked_list_t *requested;
+
+       /**
+        * The user name
+        */
+       chunk_t user_name;
+
+       /**
+        * The user pass
+        */
+       chunk_t user_pass;
+
+       /**
+        * The current state of the task
+        */
+       enum {
+               TASK_XAUTH_INIT,
+               TASK_XAUTH_PASS_DONE,
+       } state;
+
+       /**
+        * The status of the XAuth request
+        */
+       status_t status;
 };
 
 /**
@@ -48,28 +76,35 @@ typedef struct {
        attribute_handler_t *handler;
 } entry_t;
 
-/**
- * Scan for configuration payloads and attributes
- */
-static void process_payloads(private_xauth_request_t *this, message_t *message)
-{
-}
-
 METHOD(task_t, build_i, status_t,
        private_xauth_request_t *this, message_t *message)
 {
        cp_payload_t *cp;
        chunk_t chunk = chunk_empty;
 
-       DBG1(DBG_IKE, "BUILDING XAUTH REQUEST PACKET");
-       /* TODO1: Create ATTR payload */
-       cp = cp_payload_create(CONFIGURATION_V1);
-       cp->add_attribute(cp, configuration_attribute_create_chunk(
-                               CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, chunk));
-       cp->add_attribute(cp, configuration_attribute_create_chunk(
-                               CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, chunk));
+       switch(this->state)
+       {
+               case TASK_XAUTH_INIT:
+                       cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
+                       cp->add_attribute(cp, configuration_attribute_create_chunk(
+                                               CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, chunk));
+                       cp->add_attribute(cp, configuration_attribute_create_chunk(
+                                               CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, chunk));
+                       break;
+               case TASK_XAUTH_PASS_DONE:
+                       cp = cp_payload_create_type(CONFIGURATION_V1, CFG_SET);
+                       cp->add_attribute(cp, configuration_attribute_create_value(
+                                               XAUTH_STATUS,
+                                               (this->status == FAILED ? XAUTH_STATUS_FAIL : XAUTH_STATUS_OK)));
+                       break;
+               default:
+                       return FAILED;
+
+       }
+       /* Add the payloads into the message */
        message->add_payload(message, (payload_t *)cp);
 
+
        return NEED_MORE;
 }
 
@@ -88,7 +123,77 @@ METHOD(task_t, build_r, status_t,
 METHOD(task_t, process_i, status_t,
        private_xauth_request_t *this, message_t *message)
 {
-       return NEED_MORE;
+       cp_payload_t *cp_payload;
+       enumerator_t *enumerator;
+       configuration_attribute_t *ca;
+       chunk_t status_chunk = chunk_empty;
+
+       cp_payload = (cp_payload_t *)message->get_payload(message, CONFIGURATION_V1);
+       enumerator = cp_payload->create_attribute_enumerator(cp_payload);
+       while (enumerator->enumerate(enumerator, &ca))
+       {
+               switch(ca->get_type(ca))
+               {
+                       case XAUTH_USER_NAME:
+                               this->user_name = ca->get_chunk(ca);
+                               break;
+                       case XAUTH_USER_PASSWORD:
+                               this->user_pass = ca->get_chunk(ca);
+                               break;
+                       case XAUTH_STATUS:
+                               status_chunk = ca->get_chunk(ca);
+                               break;
+                       default:
+                               DBG3(DBG_IKE, "Unknown config attribute type %d, ignored", ca->get_type(ca));
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       switch(this->state)
+       {
+               case TASK_XAUTH_INIT:
+
+                       if(cp_payload->get_type(cp_payload) != CFG_REPLY)
+                       {
+                               DBG1(DBG_IKE, "ERROR: ConfigMode payload is not a reply");
+                               return FAILED;
+                       }
+
+                       this->state = TASK_XAUTH_PASS_DONE;
+                       if((this->user_name.len == 0) || (this->user_pass.len == 0))
+                       {
+                               DBG1(DBG_IKE, "ERROR: Did not get user name or user pass, aborting");
+                               this->status = FAILED;
+                               /* We should close out the XAuth negotiation cleanly by sending a "failed" message */
+                               return NEED_MORE;
+                       }
+
+                       /* TODO-IKEv1: Do actual user/pass verification */
+//                     if(!chunk_compare(this->user_name, this->user_pass))
+//                     {
+//                             this->status = FAILED;
+//                             DBG1(DBG_IKE, "ERROR: user/pass verification failure");
+                               /* We should close out the XAuth negotiation cleanly by sending a "failed" message */
+//                             return NEED_MORE;
+//                     }
+
+                       this->status = SUCCESS;
+                       return NEED_MORE;
+               case TASK_XAUTH_PASS_DONE:
+                       if(cp_payload->get_type(cp_payload) != CFG_ACK)
+                       {
+                               DBG1(DBG_IKE, "ERROR: ConfigMode payload is not a status ack");
+                               return FAILED;
+                       }
+                       if(status_chunk.len != 0)
+                       {
+                               DBG1(DBG_IKE, "Status payload of an ack had data, hmm....");
+                       }
+
+                       DBG1(DBG_IKE, "Done with XAUTH!!!");
+                       return this->status;
+       }
+       return FAILED;
 }
 
 METHOD(task_t, get_type, task_type_t,
@@ -134,6 +239,9 @@ xauth_request_t *xauth_request_create(ike_sa_t *ike_sa, bool initiator)
                .initiator = initiator,
                .ike_sa = ike_sa,
                .requested = linked_list_create(),
+               .user_name = chunk_empty,
+               .user_pass = chunk_empty,
+               .state = TASK_XAUTH_INIT,
        );
 
        if (initiator)