]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libcharon / plugins / eap_sim_file / eap_sim_file_triplets.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "eap_sim_file_triplets.h"
18
19 #include <stdio.h>
20 #include <errno.h>
21
22 #include <daemon.h>
23 #include <collections/linked_list.h>
24 #include <threading/mutex.h>
25 #include <simaka_manager.h>
26
27 typedef struct private_eap_sim_file_triplets_t private_eap_sim_file_triplets_t;
28
29 /**
30 * Private data of an eap_sim_file_triplets_t object.
31 */
32 struct private_eap_sim_file_triplets_t {
33
34 /**
35 * Public eap_sim_file_triplets_t interface.
36 */
37 eap_sim_file_triplets_t public;
38
39 /**
40 * List of triplets, as triplet_t
41 */
42 linked_list_t *triplets;
43
44 /**
45 * mutex to lock triplets list
46 */
47 mutex_t *mutex;
48 };
49
50 /**
51 * A single triplet
52 */
53 typedef struct {
54 identification_t *imsi;
55 char rand[SIM_RAND_LEN];
56 char sres[SIM_SRES_LEN];
57 char kc[SIM_KC_LEN];
58 } triplet_t;
59
60 /**
61 * Destroy a triplet
62 */
63 static void triplet_destroy(triplet_t *this)
64 {
65 DESTROY_IF(this->imsi);
66 free(this);
67 }
68
69 /**
70 * triplet enumerator
71 */
72 typedef struct {
73 /** implements enumerator */
74 enumerator_t public;
75 /** inner enumerator */
76 enumerator_t *inner;
77 /** current enumerating triplet */
78 triplet_t *current;
79 /** back ptr */
80 private_eap_sim_file_triplets_t *this;
81 } triplet_enumerator_t;
82
83 METHOD(enumerator_t, enumerator_destroy, void,
84 triplet_enumerator_t *e)
85 {
86 if (e->current)
87 {
88 /* We assume that the current element is used on invocation if destroy.
89 * We move that triplet to the end to avoid handout of the same triplet
90 * next time. */
91 e->this->triplets->remove_at(e->this->triplets, e->inner);
92 e->this->triplets->insert_last(e->this->triplets, e->current);
93 }
94 e->inner->destroy(e->inner);
95 e->this->mutex->unlock(e->this->mutex);
96 free(e);
97 }
98
99 METHOD(enumerator_t, enumerator_enumerate, bool,
100 triplet_enumerator_t *e, va_list args)
101 {
102 identification_t **imsi;
103 triplet_t *triplet;
104 char **rand, **sres, **kc;
105
106 VA_ARGS_VGET(args, imsi, rand, sres, kc);
107
108 if (e->inner->enumerate(e->inner, &triplet))
109 {
110 e->current = triplet;
111 *imsi = triplet->imsi;
112 *rand = triplet->rand;
113 *sres = triplet->sres;
114 *kc = triplet->kc;
115 return TRUE;
116 }
117 e->current = NULL;
118 return FALSE;
119 }
120
121 METHOD(eap_sim_file_triplets_t, create_enumerator, enumerator_t*,
122 private_eap_sim_file_triplets_t *this)
123 {
124 triplet_enumerator_t *enumerator;
125
126 this->mutex->lock(this->mutex);
127 INIT(enumerator,
128 .public = {
129 .enumerate = enumerator_enumerate_default,
130 .venumerate = _enumerator_enumerate,
131 .destroy = _enumerator_destroy,
132 },
133 .inner = this->triplets->create_enumerator(this->triplets),
134 .this = this,
135 );
136 return &enumerator->public;
137 }
138
139 /**
140 * convert to token into the array
141 */
142 static void parse_token(char *to, char *from, size_t len)
143 {
144 chunk_t chunk;
145
146 chunk = chunk_create(from, min(strlen(from), len * 2));
147 chunk = chunk_from_hex(chunk, NULL);
148 memset(to, 0, len);
149 memcpy(to + len - chunk.len, chunk.ptr, chunk.len);
150 free(chunk.ptr);
151 }
152
153 /**
154 * Read the triplets from the file
155 */
156 static bool read_triplets(private_eap_sim_file_triplets_t *this, char *path)
157 {
158 char line[512];
159 FILE *file;
160 int i, nr = 0;
161
162 file = fopen(path, "r");
163 if (file == NULL)
164 {
165 DBG1(DBG_CFG, "opening triplet file %s failed: %s",
166 path, strerror(errno));
167 return FALSE;
168 }
169
170 /* read line by line */
171 while (fgets(line, sizeof(line), file))
172 {
173 triplet_t *triplet;
174 enumerator_t *enumerator;
175 char *token;
176
177 nr++;
178 /* skip comments, empty lines */
179 switch (line[0])
180 {
181 case '\n':
182 case '\r':
183 case '#':
184 case '\0':
185 continue;
186 default:
187 break;
188 }
189 triplet = malloc_thing(triplet_t);
190 memset(triplet, 0, sizeof(triplet_t));
191
192 i = 0;
193 enumerator = enumerator_create_token(line, ",", " \n\r#");
194 while (enumerator->enumerate(enumerator, &token))
195 {
196 switch (i++)
197 {
198 case 0: /* IMSI */
199 triplet->imsi = identification_create_from_string(token);
200 continue;
201 case 1: /* rand */
202 parse_token(triplet->rand, token, SIM_RAND_LEN);
203 continue;
204 case 2: /* sres */
205 parse_token(triplet->sres, token, SIM_SRES_LEN);
206 continue;
207 case 3: /* kc */
208 parse_token(triplet->kc, token, SIM_KC_LEN);
209 continue;
210 default:
211 break;;
212 }
213 break;
214 }
215 enumerator->destroy(enumerator);
216 if (i < 4)
217 {
218 DBG1(DBG_CFG, "error in triplet file, line %d", nr);
219 triplet_destroy(triplet);
220 continue;
221 }
222
223 DBG2(DBG_CFG, "triplet: imsi %Y\nrand %b\nsres %b\nkc %b",
224 triplet->imsi, triplet->rand, SIM_RAND_LEN,
225 triplet->sres, SIM_SRES_LEN, triplet->kc, SIM_KC_LEN);
226
227 this->triplets->insert_last(this->triplets, triplet);
228 }
229 fclose(file);
230
231 DBG1(DBG_CFG, "read %d triplets from %s",
232 this->triplets->get_count(this->triplets), path);
233 return TRUE;
234 }
235
236 METHOD(eap_sim_file_triplets_t, destroy, void,
237 private_eap_sim_file_triplets_t *this)
238 {
239 this->triplets->destroy_function(this->triplets, (void*)triplet_destroy);
240 this->mutex->destroy(this->mutex);
241 free(this);
242 }
243
244 /**
245 * See header
246 */
247 eap_sim_file_triplets_t *eap_sim_file_triplets_create(char *file)
248 {
249 private_eap_sim_file_triplets_t *this;
250
251 INIT(this,
252 .public = {
253 .create_enumerator = _create_enumerator,
254 .destroy = _destroy,
255 },
256 .triplets = linked_list_create(),
257 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
258 );
259
260 if (!read_triplets(this, file))
261 {
262 destroy(this);
263 return NULL;
264 }
265 return &this->public;
266 }
267