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,
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;
/**
* 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;
},
.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");
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;
* @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);
};
/**
/**
* 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_ @}*/
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)
{
/* 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;