2 * Copyright (C) 2010 Sansar Choinyanbuu
3 * HSR Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 #include <tnc/tncif.h>
21 #include <tnc/tncifimv_names.h>
22 #include <tnc/tnccs/tnccs.h>
24 typedef struct recommendation_entry_t recommendation_entry_t
;
25 typedef struct private_tnccs_20_t private_tnccs_20_t
;
28 * Recommendation entry
30 struct recommendation_entry_t
{
38 * Action Recommendation provided by IMV instance
40 TNC_IMV_Action_Recommendation rec
;
43 * Evaluation Result provided by IMV instance
45 TNC_IMV_Evaluation_Result eval
;
49 * Private data of a tnccs_20_t object.
51 struct private_tnccs_20_t
{
54 * Public tls_t interface.
59 * TNCC if TRUE, TNCS if FALSE
64 * Connection ID assigned to this TNCCS connection
66 TNC_ConnectionID connection_id
;
69 * Batch being constructed
74 * Action Recommendations and Evaluations Results provided by IMVs
76 linked_list_t
*recommendations
;
79 METHOD(tnccs_t
, send_message
, void,
80 private_tnccs_20_t
* this, TNC_BufferReference message
,
81 TNC_UInt32 message_len
,
82 TNC_MessageType message_type
)
84 chunk_t msg
= { message
, message_len
},
87 DBG1(DBG_TNC
, "TNCCS 2.0 send message");
88 this->batch
= chunk_cat("mc", batch
, msg
);
91 METHOD(tnccs_t
, provide_recommendation
, void,
92 private_tnccs_20_t
* this, TNC_IMVID id
,
93 TNC_IMV_Action_Recommendation rec
,
94 TNC_IMV_Evaluation_Result eval
)
96 enumerator_t
*enumerator
;
97 recommendation_entry_t
*entry
;
100 DBG2(DBG_TNC
, "IMV %u provides recommendation '%N' and evaluation '%N'",
101 id
, action_recommendation_names
, rec
, evaluation_result_names
, eval
);
103 enumerator
= this->recommendations
->create_enumerator(this->recommendations
);
104 while (enumerator
->enumerate(enumerator
, &entry
))
112 enumerator
->destroy(enumerator
);
116 entry
= malloc_thing(recommendation_entry_t
);
118 this->recommendations
->insert_last(this->recommendations
, entry
);
121 /* Assign provided action recommendation and evaluation result */
126 METHOD(tls_t
, process
, status_t
,
127 private_tnccs_20_t
*this, void *buf
, size_t buflen
)
132 if (this->is_server
&& !this->connection_id
)
134 this->connection_id
= charon
->tnccs
->create_connection(charon
->tnccs
,
136 _send_message
, _provide_recommendation
);
137 charon
->imvs
->notify_connection_change(charon
->imvs
,
138 this->connection_id
, TNC_CONNECTION_STATE_CREATE
);
140 DBG1(DBG_TNC
, "received TNCCS Batch (%u bytes) for Connection ID %u",
141 buflen
, this->connection_id
);
142 DBG3(DBG_TNC
, "%.*s", buflen
, buf
);
143 pos
= strchr(buf
, '|');
147 len
= buflen
- ((char*)buf
- pos
);
156 charon
->imvs
->receive_message(charon
->imvs
, this->connection_id
,
157 pos
, len
, 0x0080ab31);
158 charon
->imvs
->batch_ending(charon
->imvs
, this->connection_id
);
162 charon
->imcs
->receive_message(charon
->imcs
, this->connection_id
,
163 pos
, len
, 0x0080ab31);
164 charon
->imcs
->batch_ending(charon
->imcs
, this->connection_id
);
169 METHOD(tls_t
, build
, status_t
,
170 private_tnccs_20_t
*this, void *buf
, size_t *buflen
, size_t *msglen
)
172 char *msg
= this->is_server ?
"tncs->tncc 2.0|" : "tncc->tncs 2.0|";
175 this->batch
= chunk_cat("cm", chunk_create(msg
, strlen(msg
)), this->batch
);
177 if (!this->is_server
&& !this->connection_id
)
179 this->connection_id
= charon
->tnccs
->create_connection(charon
->tnccs
,
180 (tnccs_t
*)this, _send_message
, NULL
);
181 charon
->imcs
->notify_connection_change(charon
->imcs
,
182 this->connection_id
, TNC_CONNECTION_STATE_CREATE
);
183 charon
->imcs
->notify_connection_change(charon
->imcs
,
184 this->connection_id
, TNC_CONNECTION_STATE_HANDSHAKE
);
185 charon
->imcs
->begin_handshake(charon
->imcs
, this->connection_id
);
188 len
= this->batch
.len
;
191 memcpy(buf
, this->batch
.ptr
, len
);
193 DBG1(DBG_TNC
, "sending TNCCS Batch (%d bytes) for Connection ID %u",
194 len
, this->connection_id
);
195 DBG3(DBG_TNC
, "%.*s", len
, buf
);
196 chunk_free(&this->batch
);
201 METHOD(tls_t
, is_server
, bool,
202 private_tnccs_20_t
*this)
204 return this->is_server
;
207 METHOD(tls_t
, get_purpose
, tls_purpose_t
,
208 private_tnccs_20_t
*this)
210 return TLS_PURPOSE_EAP_TNC
;
213 METHOD(tls_t
, is_complete
, bool,
214 private_tnccs_20_t
*this)
219 METHOD(tls_t
, get_eap_msk
, chunk_t
,
220 private_tnccs_20_t
*this)
225 METHOD(tls_t
, destroy
, void,
226 private_tnccs_20_t
*this)
228 charon
->tnccs
->remove_connection(charon
->tnccs
, this->connection_id
);
229 this->recommendations
->destroy_function(this->recommendations
, free
);
230 free(this->batch
.ptr
);
237 tls_t
*tnccs_20_create(bool is_server
)
239 private_tnccs_20_t
*this;
245 .is_server
= _is_server
,
246 .get_purpose
= _get_purpose
,
247 .is_complete
= _is_complete
,
248 .get_eap_msk
= _get_eap_msk
,
251 .is_server
= is_server
,
252 .recommendations
= linked_list_create(),
255 return &this->public;