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 <threading/mutex.h>
21 #include <tnc/tncif.h>
22 #include <tnc/tncifimv_names.h>
23 #include <tnc/tnccs/tnccs.h>
25 typedef struct private_tnccs_20_t private_tnccs_20_t
;
28 * Private data of a tnccs_20_t object.
30 struct private_tnccs_20_t
{
33 * Public tls_t interface.
38 * TNCC if TRUE, TNCS if FALSE
43 * Connection ID assigned to this TNCCS connection
45 TNC_ConnectionID connection_id
;
48 * Batch being constructed
53 * Mutex locking the batch in construction
58 * Set of IMV recommendations (TNC Server only)
60 recommendations_t
*recs
;
63 METHOD(tnccs_t
, send_message
, void,
64 private_tnccs_20_t
* this, TNC_BufferReference message
,
65 TNC_UInt32 message_len
,
66 TNC_MessageType message_type
)
68 chunk_t msg
= { message
, message_len
};
70 DBG1(DBG_TNC
, "TNCCS 2.0 send message");
71 this->mutex
->lock(this->mutex
);
72 this->batch
= chunk_cat("mc", this->batch
, msg
);
73 this->mutex
->unlock(this->mutex
);
76 METHOD(tls_t
, process
, status_t
,
77 private_tnccs_20_t
*this, void *buf
, size_t buflen
)
82 if (this->is_server
&& !this->connection_id
)
84 this->connection_id
= charon
->tnccs
->create_connection(charon
->tnccs
,
85 (tnccs_t
*)this, _send_message
, &this->recs
);
86 if (!this->connection_id
)
90 charon
->imvs
->notify_connection_change(charon
->imvs
,
91 this->connection_id
, TNC_CONNECTION_STATE_CREATE
);
93 DBG1(DBG_TNC
, "received TNCCS Batch (%u bytes) for Connection ID %u",
94 buflen
, this->connection_id
);
95 DBG3(DBG_TNC
, "%.*s", buflen
, buf
);
96 pos
= strchr(buf
, '|');
100 len
= buflen
- (pos
- (char*)buf
);
107 DBG1(DBG_TNC
, "received message '%.*s'", len
, pos
);
110 charon
->imvs
->receive_message(charon
->imvs
, this->connection_id
,
111 pos
, len
, 0x0080ab31);
112 charon
->imvs
->batch_ending(charon
->imvs
, this->connection_id
);
116 charon
->imcs
->receive_message(charon
->imcs
, this->connection_id
,
117 pos
, len
, 0x0080ab31);
118 charon
->imcs
->batch_ending(charon
->imcs
, this->connection_id
);
123 METHOD(tls_t
, build
, status_t
,
124 private_tnccs_20_t
*this, void *buf
, size_t *buflen
, size_t *msglen
)
126 char *msg
= this->is_server ?
"tncs->tncc 2.0|" : "tncc->tncs 2.0|";
129 this->mutex
->lock(this->mutex
);
130 this->batch
= chunk_cat("cm", chunk_create(msg
, strlen(msg
)), this->batch
);
131 this->mutex
->unlock(this->mutex
);
133 if (!this->is_server
&& !this->connection_id
)
135 this->connection_id
= charon
->tnccs
->create_connection(charon
->tnccs
,
136 (tnccs_t
*)this, _send_message
, NULL
);
137 if (!this->connection_id
)
141 charon
->imcs
->notify_connection_change(charon
->imcs
,
142 this->connection_id
, TNC_CONNECTION_STATE_CREATE
);
143 charon
->imcs
->notify_connection_change(charon
->imcs
,
144 this->connection_id
, TNC_CONNECTION_STATE_HANDSHAKE
);
145 charon
->imcs
->begin_handshake(charon
->imcs
, this->connection_id
);
148 this->mutex
->lock(this->mutex
);
149 len
= this->batch
.len
;
152 memcpy(buf
, this->batch
.ptr
, len
);
153 chunk_free(&this->batch
);
154 this->mutex
->unlock(this->mutex
);
156 DBG1(DBG_TNC
, "sending TNCCS Batch (%d bytes) for Connection ID %u",
157 len
, this->connection_id
);
158 DBG3(DBG_TNC
, "%.*s", len
, buf
);
163 METHOD(tls_t
, is_server
, bool,
164 private_tnccs_20_t
*this)
166 return this->is_server
;
169 METHOD(tls_t
, get_purpose
, tls_purpose_t
,
170 private_tnccs_20_t
*this)
172 return TLS_PURPOSE_EAP_TNC
;
175 METHOD(tls_t
, is_complete
, bool,
176 private_tnccs_20_t
*this)
178 TNC_IMV_Action_Recommendation rec
;
179 TNC_IMV_Evaluation_Result eval
;
181 if (this->recs
&& this->recs
->have_recommendation(this->recs
, &rec
, &eval
))
183 DBG2(DBG_TNC
, "Final recommendation '%N' and evaluation '%N'",
184 action_recommendation_names
, rec
, evaluation_result_names
, eval
);
186 return charon
->imvs
->enforce_recommendation(charon
->imvs
, rec
);
194 METHOD(tls_t
, get_eap_msk
, chunk_t
,
195 private_tnccs_20_t
*this)
200 METHOD(tls_t
, destroy
, void,
201 private_tnccs_20_t
*this)
203 charon
->tnccs
->remove_connection(charon
->tnccs
, this->connection_id
);
204 this->mutex
->destroy(this->mutex
);
205 free(this->batch
.ptr
);
212 tls_t
*tnccs_20_create(bool is_server
)
214 private_tnccs_20_t
*this;
220 .is_server
= _is_server
,
221 .get_purpose
= _get_purpose
,
222 .is_complete
= _is_complete
,
223 .get_eap_msk
= _get_eap_msk
,
226 .is_server
= is_server
,
227 .mutex
= mutex_create(MUTEX_TYPE_DEFAULT
),
230 return &this->public;