Annotation of embedaddon/strongswan/src/libimcv/plugins/imv_hcd/imv_hcd_agent.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2015 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
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>.
9: *
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
13: * for more details.
14: */
15:
16: #define _GNU_SOURCE
17: #include <stdio.h>
18:
19: #include "imv_hcd_agent.h"
20: #include "imv_hcd_state.h"
21:
22: #include <imcv.h>
23: #include <imv/imv_agent.h>
24: #include <imv/imv_msg.h>
25: #include <generic/generic_attr_bool.h>
26: #include <generic/generic_attr_chunk.h>
27: #include <generic/generic_attr_string.h>
28: #include <ietf/ietf_attr.h>
29: #include <ietf/ietf_attr_attr_request.h>
30: #include <ietf/ietf_attr_fwd_enabled.h>
31: #include <pwg/pwg_attr.h>
32: #include <pwg/pwg_attr_vendor_smi_code.h>
33: #include "tcg/seg/tcg_seg_attr_max_size.h"
34: #include "tcg/seg/tcg_seg_attr_seg_env.h"
35:
36: #include <tncif_names.h>
37: #include <tncif_pa_subtypes.h>
38:
39: #include <pen/pen.h>
40: #include <utils/debug.h>
41:
42: #define HCD_MAX_ATTR_SIZE 10000000
43:
44: typedef struct private_imv_hcd_agent_t private_imv_hcd_agent_t;
45:
46: /* Subscribed PA-TNC message subtypes */
47: static pen_type_t msg_types[] = {
48: { PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM },
49: { PEN_PWG, PA_SUBTYPE_PWG_HCD_SYSTEM },
50: { PEN_PWG, PA_SUBTYPE_PWG_HCD_CONSOLE },
51: { PEN_PWG, PA_SUBTYPE_PWG_HCD_MARKER },
52: { PEN_PWG, PA_SUBTYPE_PWG_HCD_FINISHER },
53: { PEN_PWG, PA_SUBTYPE_PWG_HCD_INTERFACE },
54: { PEN_PWG, PA_SUBTYPE_PWG_HCD_SCANNER }
55: };
56:
57: static imv_hcd_attr_t attr_type_to_flag(pwg_attr_t attr_type)
58: {
59: switch (attr_type)
60: {
61: case PWG_HCD_DEFAULT_PWD_ENABLED:
62: return IMV_HCD_ATTR_DEFAULT_PWD_ENABLED;
63: case PWG_HCD_FIREWALL_SETTING:
64: return IMV_HCD_ATTR_FIREWALL_SETTING;
65: case PWG_HCD_FORWARDING_ENABLED:
66: return IMV_HCD_ATTR_FORWARDING_ENABLED;
67: case PWG_HCD_MACHINE_TYPE_MODEL:
68: return IMV_HCD_ATTR_MACHINE_TYPE_MODEL;
69: case PWG_HCD_PSTN_FAX_ENABLED:
70: return IMV_HCD_ATTR_PSTN_FAX_ENABLED;
71: case PWG_HCD_TIME_SOURCE:
72: return IMV_HCD_ATTR_TIME_SOURCE;
73: case PWG_HCD_USER_APP_ENABLED:
74: return IMV_HCD_ATTR_USER_APP_ENABLED;
75: case PWG_HCD_USER_APP_PERSIST_ENABLED:
76: return IMV_HCD_ATTR_USER_APP_PERSIST_ENABLED;
77: case PWG_HCD_VENDOR_NAME:
78: return IMV_HCD_ATTR_VENDOR_NAME;
79: case PWG_HCD_VENDOR_SMI_CODE:
80: return IMV_HCD_ATTR_VENDOR_SMI_CODE;
81: case PWG_HCD_CERTIFICATION_STATE:
82: return IMV_HCD_ATTR_CERTIFICATION_STATE;
83: case PWG_HCD_CONFIGURATION_STATE:
84: return IMV_HCD_ATTR_CONFIGURATION_STATE;
85: case PWG_HCD_ATTRS_NATURAL_LANG:
86: return IMV_HCD_ATTR_NATURAL_LANG;
87: case PWG_HCD_FIRMWARE_NAME:
88: return IMV_HCD_ATTR_FIRMWARE_NAME;
89: case PWG_HCD_RESIDENT_APP_NAME:
90: return IMV_HCD_ATTR_RESIDENT_APP_NAME;
91: case PWG_HCD_USER_APP_NAME:
92: return IMV_HCD_ATTR_USER_APP_NAME;
93: default:
94: return IMV_HCD_ATTR_NONE;
95: }
96: }
97:
98: /**
99: * Private data of an imv_hcd_agent_t object.
100: */
101: struct private_imv_hcd_agent_t {
102:
103: /**
104: * Public members of imv_hcd_agent_t
105: */
106: imv_agent_if_t public;
107:
108: /**
109: * IMV agent responsible for generic functions
110: */
111: imv_agent_t *agent;
112:
113: };
114:
115: METHOD(imv_agent_if_t, bind_functions, TNC_Result,
116: private_imv_hcd_agent_t *this, TNC_TNCS_BindFunctionPointer bind_function)
117: {
118: return this->agent->bind_functions(this->agent, bind_function);
119: }
120:
121: METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
122: private_imv_hcd_agent_t *this, TNC_ConnectionID id,
123: TNC_ConnectionState new_state)
124: {
125: TNC_IMV_Action_Recommendation rec;
126: imv_state_t *state;
127: imv_session_t *session;
128:
129: switch (new_state)
130: {
131: case TNC_CONNECTION_STATE_CREATE:
132: state = imv_hcd_state_create(id);
133: return this->agent->create_state(this->agent, state);
134: case TNC_CONNECTION_STATE_DELETE:
135: return this->agent->delete_state(this->agent, id);
136: case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
137: case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
138: case TNC_CONNECTION_STATE_ACCESS_NONE:
139: if (this->agent->get_state(this->agent, id, &state) && imcv_db)
140: {
141: session = state->get_session(state);
142:
143: if (session->get_policy_started(session))
144: {
145: switch (new_state)
146: {
147: case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
148: rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
149: break;
150: case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
151: rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
152: break;
153: case TNC_CONNECTION_STATE_ACCESS_NONE:
154: default:
155: rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
156: }
157: imcv_db->add_recommendation(imcv_db, session, rec);
158: if (!imcv_db->policy_script(imcv_db, session, FALSE))
159: {
160: DBG1(DBG_IMV, "error in policy script stop");
161: }
162: }
163: }
164: /* fall through to default state */
165: default:
166: return this->agent->change_state(this->agent, id, new_state, NULL);
167: }
168: }
169:
170: /**
171: * Process a received message
172: */
173: static TNC_Result receive_msg(private_imv_hcd_agent_t *this, imv_state_t *state,
174: imv_msg_t *in_msg)
175: {
176: imv_msg_t *out_msg;
177: imv_hcd_state_t *hcd_state;
178: pa_tnc_attr_t *attr;
179: enum_name_t *pa_subtype_names;
180: pen_type_t type, msg_type;
181: TNC_Result result;
182: bool fatal_error = FALSE, assessment = FALSE;
183: enumerator_t *enumerator;
184:
185: hcd_state = (imv_hcd_state_t*)state;
186:
187: /* generate an outgoing PA-TNC message - we might need it */
188: out_msg = imv_msg_create_as_reply(in_msg);
189:
190: /* parse received PA-TNC message and handle local and remote errors */
191: result = in_msg->receive(in_msg,out_msg, &fatal_error);
192: if (result != TNC_RESULT_SUCCESS)
193: {
194: out_msg->destroy(out_msg);
195: return result;
196: }
197: msg_type = in_msg->get_msg_type(in_msg);
198: pa_subtype_names = get_pa_subtype_names(msg_type.vendor_id);
199: DBG2(DBG_IMV, "received attributes for PA subtype %N/%N",
200: pen_names, msg_type.vendor_id, pa_subtype_names, msg_type.type);
201:
202: /* set current subtype */
203: if (msg_type.vendor_id == PEN_IETF)
204: {
205: hcd_state->set_subtype(hcd_state, PA_SUBTYPE_PWG_HCD_SYSTEM);
206: }
207: else
208: {
209: hcd_state->set_subtype(hcd_state, msg_type.type);
210: }
211:
212: /* analyze PA-TNC attributes */
213: enumerator = in_msg->create_attribute_enumerator(in_msg);
214: while (enumerator->enumerate(enumerator, &attr))
215: {
216: type = attr->get_type(attr);
217:
218: if (type.vendor_id == PEN_IETF)
219: {
220: switch (type.type)
221: {
222: case IETF_ATTR_FORWARDING_ENABLED:
223: {
224: ietf_attr_fwd_enabled_t *attr_cast;
225: os_fwd_status_t fwd_status;
226:
227: attr_cast = (ietf_attr_fwd_enabled_t*)attr;
228: fwd_status = attr_cast->get_status(attr_cast);
229: DBG2(DBG_IMV, " %N: %N", ietf_attr_names, type.type,
230: os_fwd_status_names, fwd_status);
231: state->set_action_flags(state,
232: IMV_HCD_ATTR_FORWARDING_ENABLED);
233: break;
234: }
235: case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
236: {
237: generic_attr_bool_t *attr_cast;
238: bool status;
239:
240: attr_cast = (generic_attr_bool_t*)attr;
241: status = attr_cast->get_status(attr_cast);
242: DBG2(DBG_IMV, " %N: %s", ietf_attr_names, type.type,
243: status ? "yes" : "no");
244: state->set_action_flags(state,
245: IMV_HCD_ATTR_DEFAULT_PWD_ENABLED);
246: break;
247: }
248: default:
249: break;
250: }
251: }
252: else if (type.vendor_id == PEN_PWG)
253: {
254: state->set_action_flags(state, attr_type_to_flag(type.type));
255:
256: switch (type.type)
257: {
258: case PWG_HCD_ATTRS_NATURAL_LANG:
259: case PWG_HCD_MACHINE_TYPE_MODEL:
260: case PWG_HCD_VENDOR_NAME:
261: case PWG_HCD_TIME_SOURCE:
262: case PWG_HCD_FIRMWARE_NAME:
263: case PWG_HCD_FIRMWARE_STRING_VERSION:
264: case PWG_HCD_RESIDENT_APP_NAME:
265: case PWG_HCD_RESIDENT_APP_STRING_VERSION:
266: case PWG_HCD_USER_APP_NAME:
267: case PWG_HCD_USER_APP_STRING_VERSION:
268: {
269: chunk_t value;
270:
271: value = attr->get_value(attr);
272: DBG2(DBG_IMV, " %N: %.*s", pwg_attr_names, type.type,
273: value.len, value.ptr);
274: break;
275: }
276: case PWG_HCD_FIRMWARE_PATCHES:
277: case PWG_HCD_RESIDENT_APP_PATCHES:
278: case PWG_HCD_USER_APP_PATCHES:
279: {
280: chunk_t value;
281: size_t len;
282:
283: value = attr->get_value(attr);
284: len = value.len;
285:
286: /* remove any trailing LF from patches string */
287: if (len && (value.ptr[len - 1] == '\n'))
288: {
289: len--;
290: }
291: DBG2(DBG_IMV, " %N:%s%.*s", pwg_attr_names, type.type,
292: len ? "\n" : " ", len, value.ptr);
293: break;
294: }
295: case PWG_HCD_FIRMWARE_VERSION:
296: case PWG_HCD_RESIDENT_APP_VERSION:
297: case PWG_HCD_USER_APP_VERSION:
298: {
299: chunk_t value;
300:
301: value = attr->get_value(attr);
302: DBG2(DBG_IMV, " %N: %#B", pwg_attr_names, type.type, &value);
303: break;
304: }
305: case PWG_HCD_CERTIFICATION_STATE:
306: case PWG_HCD_CONFIGURATION_STATE:
307: {
308: chunk_t value;
309:
310: value = attr->get_value(attr);
311: DBG2(DBG_IMV, " %N: %B", pwg_attr_names, type.type, &value);
312: break;
313: }
314: case PWG_HCD_DEFAULT_PWD_ENABLED:
315: case PWG_HCD_PSTN_FAX_ENABLED:
316: case PWG_HCD_USER_APP_ENABLED:
317: case PWG_HCD_USER_APP_PERSIST_ENABLED:
318: {
319: generic_attr_bool_t *attr_cast;
320: bool status;
321:
322: attr_cast = (generic_attr_bool_t*)attr;
323: status = attr_cast->get_status(attr_cast);
324: DBG2(DBG_IMV, " %N: %s", pwg_attr_names, type.type,
325: status ? "yes" : "no");
326:
327: if (type.type == PWG_HCD_USER_APP_ENABLED && !status)
328: {
329: /* do not request user applications */
330: hcd_state->set_user_app_disabled(hcd_state);
331: }
332: break;
333: }
334: case PWG_HCD_FORWARDING_ENABLED:
335: {
336: ietf_attr_fwd_enabled_t *attr_cast;
337: os_fwd_status_t fwd_status;
338:
339: attr_cast = (ietf_attr_fwd_enabled_t*)attr;
340: fwd_status = attr_cast->get_status(attr_cast);
341: DBG2(DBG_IMV, " %N: %N", pwg_attr_names, type.type,
342: os_fwd_status_names, fwd_status);
343: break;
344: }
345:
346: case PWG_HCD_VENDOR_SMI_CODE:
347: {
348: pwg_attr_vendor_smi_code_t *attr_cast;
349: uint32_t smi_code;
350:
351: attr_cast = (pwg_attr_vendor_smi_code_t*)attr;
352: smi_code = attr_cast->get_vendor_smi_code(attr_cast);
353: DBG2(DBG_IMV, " %N: 0x%06x (%u)", pwg_attr_names, type.type,
354: smi_code, smi_code);
355: break;
356: }
357: default:
358: break;
359: }
360: }
361: }
362: enumerator->destroy(enumerator);
363:
364: if (fatal_error)
365: {
366: state->set_recommendation(state,
367: TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
368: TNC_IMV_EVALUATION_RESULT_ERROR);
369: assessment = TRUE;
370: }
371:
372: if (assessment)
373: {
374: hcd_state->set_handshake_state(hcd_state, IMV_HCD_STATE_END);
375: result = out_msg->send_assessment(out_msg);
376: if (result == TNC_RESULT_SUCCESS)
377: {
378: result = this->agent->provide_recommendation(this->agent, state);
379: }
380: }
381: else
382: {
383: /* send PA-TNC message with the EXCL flag set */
384: result = out_msg->send(out_msg, TRUE);
385: }
386: out_msg->destroy(out_msg);
387:
388: return result;
389: }
390:
391: METHOD(imv_agent_if_t, receive_message, TNC_Result,
392: private_imv_hcd_agent_t *this, TNC_ConnectionID id,
393: TNC_MessageType msg_type, chunk_t msg)
394: {
395: imv_state_t *state;
396: imv_msg_t *in_msg;
397: TNC_Result result;
398:
399: if (!this->agent->get_state(this->agent, id, &state))
400: {
401: return TNC_RESULT_FATAL;
402: }
403: in_msg = imv_msg_create_from_data(this->agent, state, id, msg_type, msg);
404: result = receive_msg(this, state, in_msg);
405: in_msg->destroy(in_msg);
406:
407: return result;
408: }
409:
410: METHOD(imv_agent_if_t, receive_message_long, TNC_Result,
411: private_imv_hcd_agent_t *this, TNC_ConnectionID id,
412: TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id,
413: TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype, chunk_t msg)
414: {
415: imv_state_t *state;
416: imv_msg_t *in_msg;
417: TNC_Result result;
418:
419: if (!this->agent->get_state(this->agent, id, &state))
420: {
421: return TNC_RESULT_FATAL;
422: }
423: in_msg = imv_msg_create_from_long_data(this->agent, state, id,
424: src_imc_id, dst_imv_id, msg_vid, msg_subtype, msg);
425: result = receive_msg(this, state, in_msg);
426: in_msg->destroy(in_msg);
427:
428: return result;
429:
430: }
431:
432: /**
433: * Build an IETF Attribute Request attribute for missing attributes
434: */
435: static pa_tnc_attr_t* build_attr_request(uint32_t received)
436: {
437: pa_tnc_attr_t *attr;
438: ietf_attr_attr_request_t *attr_cast;
439:
440: attr = ietf_attr_attr_request_create(PEN_RESERVED, 0);
441: attr_cast = (ietf_attr_attr_request_t*)attr;
442:
443: if (!(received & IMV_HCD_ATTR_NATURAL_LANG))
444: {
445: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_ATTRS_NATURAL_LANG);
446: }
447: if (!(received & IMV_HCD_ATTR_DEFAULT_PWD_ENABLED))
448: {
449: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_DEFAULT_PWD_ENABLED);
450: }
451: if (!(received & IMV_HCD_ATTR_FIREWALL_SETTING))
452: {
453: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_FIREWALL_SETTING);
454: }
455: if (!(received & IMV_HCD_ATTR_FIRMWARE_NAME))
456: {
457: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_FIRMWARE_NAME);
458: }
459: if (!(received & IMV_HCD_ATTR_FORWARDING_ENABLED))
460: {
461: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_FORWARDING_ENABLED);
462: }
463: if (!(received & IMV_HCD_ATTR_MACHINE_TYPE_MODEL))
464: {
465: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_MACHINE_TYPE_MODEL);
466: }
467: if (!(received & IMV_HCD_ATTR_PSTN_FAX_ENABLED))
468: {
469: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_PSTN_FAX_ENABLED);
470: }
471: if (!(received & IMV_HCD_ATTR_RESIDENT_APP_NAME))
472: {
473: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_RESIDENT_APP_NAME);
474: }
475: if (!(received & IMV_HCD_ATTR_TIME_SOURCE))
476: {
477: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_TIME_SOURCE);
478: }
479: if (!(received & IMV_HCD_ATTR_USER_APP_ENABLED))
480: {
481: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_USER_APP_ENABLED);
482: }
483: if (!(received & IMV_HCD_ATTR_USER_APP_PERSIST_ENABLED))
484: {
485: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_USER_APP_PERSIST_ENABLED);
486: }
487: if (!(received & IMV_HCD_ATTR_USER_APP_NAME))
488: {
489: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_USER_APP_NAME);
490: }
491: if (!(received & IMV_HCD_ATTR_VENDOR_NAME))
492: {
493: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_VENDOR_NAME);
494: }
495: if (!(received & IMV_HCD_ATTR_VENDOR_SMI_CODE))
496: {
497: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_VENDOR_SMI_CODE);
498: }
499: if (!(received & IMV_HCD_ATTR_CERTIFICATION_STATE))
500: {
501: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_CERTIFICATION_STATE);
502: }
503: if (!(received & IMV_HCD_ATTR_CONFIGURATION_STATE))
504: {
505: attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_CONFIGURATION_STATE);
506: }
507: return attr;
508: }
509:
510: METHOD(imv_agent_if_t, batch_ending, TNC_Result,
511: private_imv_hcd_agent_t *this, TNC_ConnectionID id)
512: {
513: imv_msg_t *out_msg;
514: imv_state_t *state;
515: imv_hcd_state_t *hcd_state;
516: imv_hcd_handshake_state_t handshake_state;
517: pa_tnc_attr_t *attr;
518: TNC_IMVID imv_id;
519: TNC_Result result = TNC_RESULT_SUCCESS;
520:
521: if (!this->agent->get_state(this->agent, id, &state))
522: {
523: return TNC_RESULT_FATAL;
524: }
525: hcd_state = (imv_hcd_state_t*)state;
526: handshake_state = hcd_state->get_handshake_state(hcd_state);
527: imv_id = this->agent->get_id(this->agent);
528:
529: if (handshake_state == IMV_HCD_STATE_END)
530: {
531: return TNC_RESULT_SUCCESS;
532: }
533:
534: if (handshake_state == IMV_HCD_STATE_INIT)
535: {
536: size_t max_attr_size = HCD_MAX_ATTR_SIZE;
537: size_t max_seg_size;
538: seg_contract_t *contract;
539: seg_contract_manager_t *contracts;
540: char buf[BUF_LEN];
541: uint32_t received;
542: int i;
543:
544: /* Determine maximum PA-TNC attribute segment size */
545: max_seg_size = state->get_max_msg_len(state)
546: - PA_TNC_HEADER_SIZE
547: - PA_TNC_ATTR_HEADER_SIZE
548: - TCG_SEG_ATTR_SEG_ENV_HEADER
549: - PA_TNC_ATTR_HEADER_SIZE
550: - TCG_SEG_ATTR_MAX_SIZE_SIZE;
551: contracts = state->get_contracts(state);
552:
553: for (i = 1; i < countof(msg_types); i++)
554: {
555: out_msg = imv_msg_create(this->agent, state, id, imv_id,
556: TNC_IMCID_ANY, msg_types[i]);
557:
558: /* Announce support of PA-TNC segmentation to IMC */
559: contract = seg_contract_create(msg_types[i], max_attr_size,
560: max_seg_size, TRUE, imv_id, FALSE);
561: contract->get_info_string(contract, buf, BUF_LEN, TRUE);
562: DBG2(DBG_IMV, "%s", buf);
563: contracts->add_contract(contracts, contract);
564: attr = tcg_seg_attr_max_size_create(max_attr_size, max_seg_size,
565: TRUE);
566: out_msg->add_attribute(out_msg, attr);
567:
568: hcd_state->set_subtype(hcd_state, msg_types[i].type);
569: received = state->get_action_flags(state);
570:
571: if ((received & IMV_HCD_ATTR_MUST) != IMV_HCD_ATTR_MUST)
572: {
573: /* create attribute request for missing mandatory attributes */
574: out_msg->add_attribute(out_msg, build_attr_request(received));
575: }
576: result = out_msg->send(out_msg, FALSE);
577: out_msg->destroy(out_msg);
578:
579: if (result != TNC_RESULT_SUCCESS)
580: {
581: break;
582: }
583: }
584: hcd_state->set_handshake_state(hcd_state, IMV_HCD_STATE_ATTR_REQ);
585: }
586:
587: return result;
588: }
589:
590: METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result,
591: private_imv_hcd_agent_t *this, TNC_ConnectionID id)
592: {
593: imv_state_t *state;
594: imv_hcd_state_t* hcd_state;
595: imv_hcd_handshake_state_t handshake_state;
596: enum_name_t *pa_subtype_names;
597: bool missing = FALSE;
598: uint32_t received;
599: int i;
600:
601: if (!this->agent->get_state(this->agent, id, &state))
602: {
603: return TNC_RESULT_FATAL;
604: }
605: hcd_state = (imv_hcd_state_t*)state;
606: handshake_state = hcd_state->get_handshake_state(hcd_state);
607:
608: if (handshake_state == IMV_HCD_STATE_ATTR_REQ)
609: {
610: pa_subtype_names = get_pa_subtype_names(PEN_PWG);
611:
612: for (i = 1; i < countof(msg_types); i++)
613: {
614: hcd_state->set_subtype(hcd_state, msg_types[i].type);
615: received = state->get_action_flags(state);
616: if ((received & IMV_HCD_ATTR_MUST) != IMV_HCD_ATTR_MUST)
617: {
618: DBG1(DBG_IMV, "missing attributes for PA subtype %N/%N",
619: pen_names, PEN_PWG, pa_subtype_names, msg_types[i].type);
620: missing = TRUE;
621: }
622: }
623:
624: if (missing)
625: {
626: state->set_recommendation(state,
627: TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS ,
628: TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
629: }
630: else
631: {
632: state->set_recommendation(state,
633: TNC_IMV_ACTION_RECOMMENDATION_ALLOW ,
634: TNC_IMV_EVALUATION_RESULT_COMPLIANT);
635: }
636: }
637: hcd_state->set_handshake_state(hcd_state, IMV_HCD_STATE_END);
638:
639: return this->agent->provide_recommendation(this->agent, state);
640: }
641:
642: METHOD(imv_agent_if_t, destroy, void,
643: private_imv_hcd_agent_t *this)
644: {
645: DESTROY_IF(this->agent);
646: free(this);
647: }
648:
649: /**
650: * Described in header.
651: */
652: imv_agent_if_t *imv_hcd_agent_create(const char *name, TNC_IMVID id,
653: TNC_Version *actual_version)
654: {
655: private_imv_hcd_agent_t *this;
656: imv_agent_t *agent;
657:
658: agent = imv_agent_create(name, msg_types, countof(msg_types), id,
659: actual_version);
660: if (!agent)
661: {
662: return NULL;
663: }
664:
665: INIT(this,
666: .public = {
667: .bind_functions = _bind_functions,
668: .notify_connection_change = _notify_connection_change,
669: .receive_message = _receive_message,
670: .receive_message_long = _receive_message_long,
671: .batch_ending = _batch_ending,
672: .solicit_recommendation = _solicit_recommendation,
673: .destroy = _destroy,
674: },
675: .agent = agent,
676: );
677:
678: return &this->public;
679: }
680:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>