2 * Copyright (C) 2012 Andreas Steffen
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
16 #include "tnc_pdp_connections.h"
18 #include <collections/linked_list.h>
19 #include <utils/debug.h>
21 typedef struct private_tnc_pdp_connections_t private_tnc_pdp_connections_t
;
22 typedef struct entry_t entry_t
;
25 * Private data of tnc_pdp_connections_t
27 struct private_tnc_pdp_connections_t
{
30 * Implements tnc_pdp_connections_t interface
32 tnc_pdp_connections_t
public;
35 * List of TNC PEP RADIUS Connections
41 * Data entry for a TNC PEP RADIUS connection
46 * NAS identifier of PEP
51 * User name of TNC Client
61 * IKE SA used for bus communication
67 * Free the memory allocated to a data entry
69 static void free_entry(entry_t
*this)
71 this->method
->destroy(this->method
);
72 this->ike_sa
->destroy(this->ike_sa
);
73 free(this->nas_id
.ptr
);
74 free(this->user_name
.ptr
);
79 * Find a matching data entry
81 static bool equals_entry( entry_t
*this, chunk_t nas_id
, chunk_t user_name
)
83 bool no_nas_id
= !this->nas_id
.ptr
&& !nas_id
.ptr
;
85 return (chunk_equals(this->nas_id
, nas_id
) || no_nas_id
) &&
86 chunk_equals(this->user_name
, user_name
);
90 * Find a matching data entry
92 static void dbg_nas_user(chunk_t nas_id
, chunk_t user_name
, bool not, char *op
)
96 DBG1(DBG_CFG
, "%s RADIUS connection for user '%.*s' NAS '%.*s'",
97 not ? "could not find" : op
, (int)user_name
.len
,
98 user_name
.ptr
, (int)nas_id
.len
, nas_id
.ptr
);
102 DBG1(DBG_CFG
, "%s RADIUS connection for user '%.*s'",
103 not ? "could not find" : op
, (int)user_name
.len
,
108 METHOD(tnc_pdp_connections_t
, add
, void,
109 private_tnc_pdp_connections_t
*this, chunk_t nas_id
, chunk_t user_name
,
110 identification_t
*peer
, eap_method_t
*method
)
112 enumerator_t
*enumerator
;
114 ike_sa_id_t
*ike_sa_id
;
118 ike_sa_id
= ike_sa_id_create(IKEV2_MAJOR_VERSION
, 0, 0, FALSE
);
119 ike_sa
= ike_sa_create(ike_sa_id
, FALSE
, IKEV2
);
120 ike_sa_id
->destroy(ike_sa_id
);
121 ike_sa
->set_other_id(ike_sa
, peer
);
123 enumerator
= this->list
->create_enumerator(this->list
);
124 while (enumerator
->enumerate(enumerator
, &entry
))
126 if (equals_entry(entry
, nas_id
, user_name
))
129 entry
->method
->destroy(entry
->method
);
130 entry
->ike_sa
->destroy(entry
->ike_sa
);
131 DBG1(DBG_CFG
, "removed stale RADIUS connection");
132 entry
->method
= method
;
133 entry
->ike_sa
= ike_sa
;
137 enumerator
->destroy(enumerator
);
141 entry
= malloc_thing(entry_t
);
142 entry
->nas_id
= chunk_clone(nas_id
);
143 entry
->user_name
= chunk_clone(user_name
);
144 entry
->method
= method
;
145 entry
->ike_sa
= ike_sa
;
146 this->list
->insert_last(this->list
, entry
);
148 dbg_nas_user(nas_id
, user_name
, FALSE
, "created");
151 METHOD(tnc_pdp_connections_t
, remove_
, void,
152 private_tnc_pdp_connections_t
*this, chunk_t nas_id
, chunk_t user_name
)
154 enumerator_t
*enumerator
;
157 enumerator
= this->list
->create_enumerator(this->list
);
158 while (enumerator
->enumerate(enumerator
, &entry
))
160 if (equals_entry(entry
, nas_id
, user_name
))
163 this->list
->remove_at(this->list
, enumerator
);
164 dbg_nas_user(nas_id
, user_name
, FALSE
, "removed");
168 enumerator
->destroy(enumerator
);
171 METHOD(tnc_pdp_connections_t
, get_state
, eap_method_t
*,
172 private_tnc_pdp_connections_t
*this, chunk_t nas_id
, chunk_t user_name
,
175 enumerator_t
*enumerator
;
177 eap_method_t
*found
= NULL
;
179 enumerator
= this->list
->create_enumerator(this->list
);
180 while (enumerator
->enumerate(enumerator
, &entry
))
182 if (equals_entry(entry
, nas_id
, user_name
))
184 found
= entry
->method
;
185 *ike_sa
= entry
->ike_sa
;
189 enumerator
->destroy(enumerator
);
191 dbg_nas_user(nas_id
, user_name
, !found
, "found");
195 METHOD(tnc_pdp_connections_t
, destroy
, void,
196 private_tnc_pdp_connections_t
*this)
198 this->list
->destroy_function(this->list
, (void*)free_entry
);
205 tnc_pdp_connections_t
*tnc_pdp_connections_create(void)
207 private_tnc_pdp_connections_t
*this;
213 .get_state
= _get_state
,
216 .list
= linked_list_create(),
219 return &this->public;