implemented check_and_build_recommendation()
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 10 Jan 2011 05:46:17 +0000 (06:46 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 11 Jan 2011 00:17:40 +0000 (01:17 +0100)
src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h
src/libcharon/plugins/tnccs_11/tnccs_11.c

index ad1ed36..76ad7e0 100644 (file)
@@ -40,14 +40,14 @@ struct private_tnccs_reason_strings_msg_t {
        xmlNodePtr node;
 
        /**
-        * Reason Language
+        * Reason String
         */
-       char* language;
+       chunk_t reason;
 
        /**
-        * Reason String
+        * Reason Language
         */
-       char* reason;
+       chunk_t language;
 };
 
 METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
@@ -65,13 +65,13 @@ METHOD(tnccs_msg_t, get_node, xmlNodePtr,
 METHOD(tnccs_msg_t, destroy, void,
        private_tnccs_reason_strings_msg_t *this)
 {
-       free(this->language);
-       free(this->reason);
+       free(this->reason.ptr);
+       free(this->language.ptr);
        free(this);
 }
 
-METHOD(tnccs_reason_strings_msg_t, get_reason, char*,
-       private_tnccs_reason_strings_msg_t *this, char **language)
+METHOD(tnccs_reason_strings_msg_t, get_reason, chunk_t,
+       private_tnccs_reason_strings_msg_t *this, chunk_t *language)
 {
        *language = this->language;
 
@@ -105,7 +105,7 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
 /**
  * See header
  */
-tnccs_msg_t *tnccs_reason_strings_msg_create(char *language, char *reason)
+tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language)
 {
        private_tnccs_reason_strings_msg_t *this;
        xmlNodePtr n, n2, n3;
@@ -121,10 +121,14 @@ tnccs_msg_t *tnccs_reason_strings_msg_create(char *language, char *reason)
                },
                .type = TNCCS_MSG_REASON_STRINGS,
                .node =  xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
-               .language = strdup(language),
-               .reason = strdup(reason),
+               .reason = chunk_create_clone(malloc(reason.len + 1), reason),
+               .language = chunk_create_clone(malloc(language.len + 1), language),
        );
 
+       /* add NULL termination for XML string representation */
+       this->reason.ptr[this->reason.len] = '\0';
+       this->language.ptr[this->language.len] = '\0';
+
        /* add the message type number in hex */
        n = xmlNewNode(NULL, BAD_CAST "Type");
        xmlNodeSetContent(n, BAD_CAST "00000004");
@@ -134,13 +138,11 @@ tnccs_msg_t *tnccs_reason_strings_msg_create(char *language, char *reason)
        xmlAddChild(this->node, n);
 
        n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
-       xmlNodeSetContent(n2, BAD_CAST language);
-       xmlAddChild(n, n2);
 
     /* could add multiple reasons here, if we had them */
     n3 = xmlNewNode(NULL, BAD_CAST "ReasonString");
-    xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST language);
-    xmlNodeSetContent(n3, BAD_CAST reason);
+    xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST this->language.ptr);
+    xmlNodeSetContent(n3, BAD_CAST this->reason.ptr);
     xmlAddChild(n2, n3);
 
        return &this->public.tnccs_msg_interface;
index 9057477..5b4dec3 100644 (file)
@@ -41,7 +41,7 @@ struct tnccs_reason_strings_msg_t {
         * @param language              reason language
         * @return                              reason string
         */
-       char* (*get_reason)(tnccs_reason_strings_msg_t *this, char **language);
+       chunk_t (*get_reason)(tnccs_reason_strings_msg_t *this, chunk_t *language);
 };
 
 /**
@@ -56,9 +56,9 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
 /**
  * Create a TNCCS-ReasonStrings message from parameters
  *
- * @param language                     reason language
  * @param reason                       reason string
+ * @param language                     reason language
  */
-tnccs_msg_t *tnccs_reason_strings_msg_create(char *language, char *reason);
+tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language);
 
 #endif /** TNCCS_REASON_STRINGS_MSG_H_ @}*/
index a10aa26..9d3989b 100644 (file)
@@ -285,6 +285,43 @@ METHOD(tls_t, process, status_t,
        return NEED_MORE;
 }
 
+/**
+ *  Add a recommendation message if a final recommendation is available
+ */
+static void check_and_build_recommendation(private_tnccs_11_t *this)
+{
+       TNC_IMV_Action_Recommendation rec;
+       TNC_IMV_Evaluation_Result eval;
+       TNC_IMVID id;
+       chunk_t reason, language;
+       enumerator_t *enumerator;
+       tnccs_msg_t *msg;
+
+       if (!this->recs->have_recommendation(this->recs, &rec, &eval))
+       {
+               charon->imvs->solicit_recommendation(charon->imvs, this->connection_id);
+       }
+       if (this->recs->have_recommendation(this->recs, &rec, &eval))
+       {
+               if (!this->batch)
+               {
+                       this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
+               }
+
+               msg = tnccs_recommendation_msg_create(rec);
+               this->batch->add_msg(this->batch, msg);
+
+               /* currently we just send the first Reason String */
+               enumerator = this->recs->create_reason_enumerator(this->recs);
+               if (enumerator->enumerate(enumerator, &id, &reason, &language))
+               {
+                       msg = tnccs_reason_strings_msg_create(reason, language);
+                       this->batch->add_msg(this->batch, msg);
+               }
+               enumerator->destroy(enumerator);
+       }
+}
+
 METHOD(tls_t, build, status_t,
        private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
 {
@@ -322,6 +359,11 @@ METHOD(tls_t, build, status_t,
        /* Do not allow any asynchronous IMCs or IMVs to add additional messages */
        this->mutex->lock(this->mutex);
 
+       if (this->is_server && (!this->batch || this->fatal_error))
+       {
+               check_and_build_recommendation(this);
+       }
+
        if (this->batch)
        {
                chunk_t data;