~ubuntu-branches/ubuntu/oneiric/strongswan/oneiric

« back to all changes in this revision

Viewing changes to src/charon/config/auth_cfg.c

  • Committer: Bazaar Package Importer
  • Author(s): Rene Mayrhofer
  • Date: 2009-04-18 20:28:51 UTC
  • mfrom: (1.1.9 upstream) (2.1.15 karmic)
  • Revision ID: james.westby@ubuntu.com-20090418202851-ep722qhmzvpxh6yj
Tags: 4.3.2-1
Urgency high because of security issue and FTBFS.
* New upstream release, fixes security bug.
* Fix padlock handling for i386 in debian/rules.
  Closes: #525652 (FTBFS on i386)
* Acknowledge NMUs by security team.
  Closes: #533837, #531612
* Add "Conflicts: strongswan (< 4.2.12-1)" to libstrongswan, 
  strongswan-starter, strongswan-ikev1, and strongswan-ikev2 to force
  update of the strongswan package on installation and avoid conflicts
  caused by package restructuring.
  Closes: #526037: strongswan-ikev2 and strongswan: error when trying to 
                   install together
  Closes: #526486: strongswan and libstrongswan: error when trying to 
                   install together
  Closes: #526487: strongswan-ikev1 and strongswan: error when trying to 
                   install together
  Closes: #526488: strongswan-starter and strongswan: error when trying to 
                   install together
* Debconf templates and debian/control reviewed by the debian-l10n-
  english team as part of the Smith review project. Closes: #528073
* Debconf translation updates:
  Closes: #525234: [INTL:ja] Update po-debconf template translation (ja.po) 
  Closes: #528323: [INTL:sv] po-debconf file for strongswan 
  Closes: #528370: [INTL:vi] Vietnamese debconf templates translation update 
  Closes: #529027: [INTL:pt] Updated Portuguese translation for debconf messages
  Closes: #529071: [INTL:fr] French debconf templates translation update 
  Closes: #529592: nb translation of debconf PO for strongSWAN 
  Closes: #529638: [INTL:ru] Russian debconf templates translation 
  Closes: #529661: Updated Czech translation of strongswan debconf messages 
  Closes: #529742: [INTL:eu] strongswan debconf basque translation 
  Closes: #530273: [INTL:fi] Finnish translation of the debconf templates
  Closes: #529063: [INTL:gl] strongswan 4.2.14-2 debconf translation update

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007-2009 Martin Willi
 
3
 * Copyright (C) 2008 Tobias Brunner
 
4
 * Hochschule fuer Technik Rapperswil
 
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 "auth_cfg.h"
 
18
 
 
19
#include <daemon.h>
 
20
#include <utils/linked_list.h>
 
21
#include <utils/identification.h>
 
22
#include <credentials/certificates/certificate.h>
 
23
 
 
24
ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
 
25
        "RULE_IDENTITY",
 
26
        "RULE_AUTH_CLASS",
 
27
        "RULE_EAP_IDENTITY",
 
28
        "RULE_EAP_TYPE",
 
29
        "RULE_EAP_VENDOR",
 
30
        "RULE_CA_CERT",
 
31
        "RULE_IM_CERT",
 
32
        "RULE_SUBJECT_CERT",
 
33
        "RULE_CRL_VALIDATION",
 
34
        "RULE_OCSP_VALIDATION",
 
35
        "RULE_AC_GROUP",
 
36
        "HELPER_IM_CERT",
 
37
        "HELPER_SUBJECT_CERT",
 
38
        "HELPER_IM_HASH_URL",
 
39
        "HELPER_SUBJECT_HASH_URL",
 
40
);
 
41
 
 
42
typedef struct private_auth_cfg_t private_auth_cfg_t;
 
43
 
 
44
/**
 
45
 * private data of item_set
 
46
 */
 
47
struct private_auth_cfg_t {
 
48
        
 
49
        /**
 
50
         * public functions
 
51
         */
 
52
        auth_cfg_t public;
 
53
        
 
54
        /**
 
55
         * list of entry_t
 
56
         */
 
57
        linked_list_t *entries;
 
58
};
 
59
 
 
60
typedef struct entry_t entry_t;
 
61
 
 
62
struct entry_t {
 
63
        /** rule type */
 
64
        auth_rule_t type;
 
65
        /** associated value */
 
66
        void *value;
 
67
};
 
68
 
 
69
/**
 
70
 * enumerator for auth_cfg_t.create_enumerator()
 
71
 */
 
72
typedef struct {
 
73
        /** implements enumerator_t */
 
74
        enumerator_t public;
 
75
        /** inner enumerator from linked_list_t */
 
76
        enumerator_t *inner;
 
77
        /** current entry */
 
78
        entry_t *current;
 
79
} entry_enumerator_t;
 
80
 
 
81
/**
 
82
 * enumerate function for item_enumerator_t
 
83
 */
 
84
static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
 
85
{
 
86
        entry_t *entry;
 
87
        
 
88
        if (this->inner->enumerate(this->inner, &entry))
 
89
        {
 
90
                this->current = entry;
 
91
                *type = entry->type;
 
92
                *value = entry->value;
 
93
                return TRUE;
 
94
        }
 
95
        return FALSE;
 
96
}
 
97
 
 
98
/**
 
99
 * destroy function for item_enumerator_t
 
100
 */
 
101
static void entry_enumerator_destroy(entry_enumerator_t *this)
 
102
{
 
103
        this->inner->destroy(this->inner);
 
104
        free(this);
 
105
}
 
106
 
 
107
/**
 
108
 * Implementation of auth_cfg_t.create_enumerator.
 
109
 */
 
110
static enumerator_t* create_enumerator(private_auth_cfg_t *this)
 
111
{
 
112
        entry_enumerator_t *enumerator;
 
113
        
 
114
        enumerator = malloc_thing(entry_enumerator_t);
 
115
        enumerator->inner = this->entries->create_enumerator(this->entries);
 
116
        enumerator->public.enumerate = (void*)enumerate;
 
117
        enumerator->public.destroy = (void*)entry_enumerator_destroy;
 
118
        enumerator->current = NULL;
 
119
        return &enumerator->public;
 
120
}
 
121
 
 
122
/**
 
123
 * Destroy the value associated with an entry
 
124
 */
 
125
static void destroy_entry_value(entry_t *entry)
 
126
{
 
127
        switch (entry->type)
 
128
        {
 
129
                case AUTH_RULE_IDENTITY:
 
130
                case AUTH_RULE_EAP_IDENTITY:
 
131
                case AUTH_RULE_AC_GROUP:
 
132
                {
 
133
                        identification_t *id = (identification_t*)entry->value;
 
134
                        id->destroy(id);
 
135
                        break;
 
136
                }
 
137
                case AUTH_RULE_CA_CERT:
 
138
                case AUTH_RULE_IM_CERT:
 
139
                case AUTH_RULE_SUBJECT_CERT:
 
140
                case AUTH_HELPER_IM_CERT:
 
141
                case AUTH_HELPER_SUBJECT_CERT:
 
142
                {
 
143
                        certificate_t *cert = (certificate_t*)entry->value;
 
144
                        cert->destroy(cert);
 
145
                        break;
 
146
                }
 
147
                case AUTH_HELPER_IM_HASH_URL:
 
148
                case AUTH_HELPER_SUBJECT_HASH_URL:
 
149
                {
 
150
                        free(entry->value);
 
151
                        break;
 
152
                }
 
153
                case AUTH_RULE_AUTH_CLASS:
 
154
                case AUTH_RULE_EAP_TYPE:
 
155
                case AUTH_RULE_EAP_VENDOR:
 
156
                case AUTH_RULE_CRL_VALIDATION:
 
157
                case AUTH_RULE_OCSP_VALIDATION:
 
158
                        break;
 
159
        }
 
160
}
 
161
 
 
162
/**
 
163
 * Implementation of auth_cfg_t.replace.
 
164
 */
 
165
static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
 
166
                                        auth_rule_t type, ...)
 
167
{
 
168
        if (enumerator->current)
 
169
        {
 
170
                va_list args;
 
171
                
 
172
                va_start(args, type);
 
173
                
 
174
                destroy_entry_value(enumerator->current);
 
175
                enumerator->current->type = type;
 
176
                switch (type)
 
177
                {
 
178
                        case AUTH_RULE_AUTH_CLASS:
 
179
                        case AUTH_RULE_EAP_TYPE:
 
180
                        case AUTH_RULE_EAP_VENDOR:
 
181
                        case AUTH_RULE_CRL_VALIDATION:
 
182
                        case AUTH_RULE_OCSP_VALIDATION:
 
183
                                /* integer type */
 
184
                                enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
 
185
                                break;
 
186
                        case AUTH_RULE_IDENTITY:
 
187
                        case AUTH_RULE_EAP_IDENTITY:
 
188
                        case AUTH_RULE_AC_GROUP:
 
189
                        case AUTH_RULE_CA_CERT:
 
190
                        case AUTH_RULE_IM_CERT:
 
191
                        case AUTH_RULE_SUBJECT_CERT:
 
192
                        case AUTH_HELPER_IM_CERT:
 
193
                        case AUTH_HELPER_SUBJECT_CERT:
 
194
                        case AUTH_HELPER_IM_HASH_URL:
 
195
                        case AUTH_HELPER_SUBJECT_HASH_URL:
 
196
                                /* pointer type */
 
197
                                enumerator->current->value = va_arg(args, void*);
 
198
                                break;
 
199
                }
 
200
                va_end(args);
 
201
        }
 
202
}
 
203
 
 
204
/**
 
205
 * Implementation of auth_cfg_t.get.
 
206
 */
 
207
static void* get(private_auth_cfg_t *this, auth_rule_t type)
 
208
{
 
209
        enumerator_t *enumerator;
 
210
        void *current_value, *best_value = NULL;
 
211
        auth_rule_t current_type;
 
212
        bool found = FALSE;
 
213
        
 
214
        enumerator = create_enumerator(this);
 
215
        while (enumerator->enumerate(enumerator, &current_type, &current_value))
 
216
        {
 
217
                if (type == current_type)
 
218
                {
 
219
                        if (type == AUTH_RULE_CRL_VALIDATION ||
 
220
                                type == AUTH_RULE_OCSP_VALIDATION)
 
221
                        {       /* for CRL/OCSP validation, always get() the highest value */
 
222
                                if (!found || current_value > best_value)
 
223
                                {
 
224
                                        best_value = current_value;
 
225
                                }
 
226
                                found = TRUE;
 
227
                                continue;
 
228
                        }
 
229
                        best_value = current_value;
 
230
                        found = TRUE;
 
231
                        break;
 
232
                }
 
233
        }
 
234
        enumerator->destroy(enumerator);
 
235
        if (found)
 
236
        {
 
237
                return best_value;
 
238
        }
 
239
        switch (type)
 
240
        {
 
241
                /* use some sane defaults if we don't find an entry */
 
242
                case AUTH_RULE_AUTH_CLASS:
 
243
                        return (void*)AUTH_CLASS_ANY;
 
244
                case AUTH_RULE_EAP_TYPE:
 
245
                        return (void*)EAP_NAK;
 
246
                case AUTH_RULE_EAP_VENDOR:
 
247
                        return (void*)0;
 
248
                case AUTH_RULE_CRL_VALIDATION:
 
249
                case AUTH_RULE_OCSP_VALIDATION:
 
250
                        return (void*)VALIDATION_FAILED;
 
251
                case AUTH_RULE_IDENTITY:
 
252
                case AUTH_RULE_EAP_IDENTITY:
 
253
                case AUTH_RULE_AC_GROUP:
 
254
                case AUTH_RULE_CA_CERT:
 
255
                case AUTH_RULE_IM_CERT:
 
256
                case AUTH_RULE_SUBJECT_CERT:
 
257
                case AUTH_HELPER_IM_CERT:
 
258
                case AUTH_HELPER_SUBJECT_CERT:
 
259
                case AUTH_HELPER_IM_HASH_URL:
 
260
                case AUTH_HELPER_SUBJECT_HASH_URL:
 
261
                default:
 
262
                        return NULL;
 
263
        }
 
264
}
 
265
 
 
266
/**
 
267
 * Implementation of auth_cfg_t.add.
 
268
 */
 
269
static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
 
270
{
 
271
        entry_t *entry = malloc_thing(entry_t);
 
272
        va_list args;
 
273
        
 
274
        va_start(args, type);
 
275
        entry->type = type;
 
276
        switch (type)
 
277
        {
 
278
                case AUTH_RULE_AUTH_CLASS:
 
279
                case AUTH_RULE_EAP_TYPE:
 
280
                case AUTH_RULE_EAP_VENDOR:
 
281
                case AUTH_RULE_CRL_VALIDATION:
 
282
                case AUTH_RULE_OCSP_VALIDATION:
 
283
                        /* integer type */
 
284
                        entry->value = (void*)(uintptr_t)va_arg(args, u_int);
 
285
                        break;
 
286
                case AUTH_RULE_IDENTITY:
 
287
                case AUTH_RULE_EAP_IDENTITY:
 
288
                case AUTH_RULE_AC_GROUP:
 
289
                case AUTH_RULE_CA_CERT:
 
290
                case AUTH_RULE_IM_CERT:
 
291
                case AUTH_RULE_SUBJECT_CERT:
 
292
                case AUTH_HELPER_IM_CERT:
 
293
                case AUTH_HELPER_SUBJECT_CERT:
 
294
                case AUTH_HELPER_IM_HASH_URL:
 
295
                case AUTH_HELPER_SUBJECT_HASH_URL:
 
296
                        /* pointer type */
 
297
                        entry->value = va_arg(args, void*);
 
298
                        break;
 
299
        }
 
300
        va_end(args);
 
301
        this->entries->insert_last(this->entries, entry);
 
302
}
 
303
 
 
304
/**
 
305
 * Implementation of auth_cfg_t.complies.
 
306
 */
 
307
static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
 
308
                                         bool log_error)
 
309
{
 
310
        enumerator_t *e1, *e2;
 
311
        bool success = TRUE;
 
312
        auth_rule_t t1, t2;
 
313
        void *value;
 
314
        
 
315
        e1 = constraints->create_enumerator(constraints);
 
316
        while (e1->enumerate(e1, &t1, &value))
 
317
        {
 
318
                switch (t1)
 
319
                {
 
320
                        case AUTH_RULE_CA_CERT:
 
321
                        case AUTH_RULE_IM_CERT:
 
322
                        {
 
323
                                certificate_t *c1, *c2;
 
324
                                
 
325
                                c1 = (certificate_t*)value;
 
326
                                
 
327
                                success = FALSE;
 
328
                                e2 = create_enumerator(this);
 
329
                                while (e2->enumerate(e2, &t2, &c2))
 
330
                                {
 
331
                                        if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
 
332
                                                c1->equals(c1, c2))
 
333
                                        {
 
334
                                                success = TRUE;
 
335
                                        }
 
336
                                }
 
337
                                e2->destroy(e2);
 
338
                                if (!success && log_error)
 
339
                                {
 
340
                                        DBG1(DBG_CFG, "constraint check failed: peer not "
 
341
                                                 "authenticated by CA '%Y'.", c1->get_subject(c1));
 
342
                                }
 
343
                                break;
 
344
                        }
 
345
                        case AUTH_RULE_SUBJECT_CERT:
 
346
                        {
 
347
                                certificate_t *c1, *c2;
 
348
                                
 
349
                                c1 = (certificate_t*)value;
 
350
                                c2 = get(this, AUTH_RULE_SUBJECT_CERT);
 
351
                                if (!c2 || !c1->equals(c1, c2))
 
352
                                {
 
353
                                        success = FALSE;
 
354
                                        if (log_error)
 
355
                                        {
 
356
                                                DBG1(DBG_CFG, "constraint check failed: peer not "
 
357
                                                         "authenticated with peer cert '%Y'.",
 
358
                                                         c1->get_subject(c1));
 
359
                                        }
 
360
                                }
 
361
                                break;
 
362
                        }
 
363
                        case AUTH_RULE_CRL_VALIDATION:
 
364
                        case AUTH_RULE_OCSP_VALIDATION:
 
365
                        {
 
366
                                cert_validation_t validated, required;
 
367
                                
 
368
                                required = (uintptr_t)value;
 
369
                                validated = (uintptr_t)get(this, t1);
 
370
                                switch (required)
 
371
                                {
 
372
                                        case VALIDATION_FAILED:
 
373
                                                /* no constraint */
 
374
                                                break;
 
375
                                        case VALIDATION_SKIPPED:
 
376
                                                if (validated == VALIDATION_SKIPPED)
 
377
                                                {
 
378
                                                        break;
 
379
                                                }
 
380
                                                /* FALL */
 
381
                                        case VALIDATION_GOOD:
 
382
                                                if (validated == VALIDATION_GOOD)
 
383
                                                {
 
384
                                                        break;
 
385
                                                }
 
386
                                                /* FALL */
 
387
                                        default:
 
388
                                                success = FALSE;
 
389
                                                if (log_error)
 
390
                                                {
 
391
                                                        DBG1(DBG_CFG, "constraint check failed: %N is %N, "
 
392
                                                                 "but requires at least %N", auth_rule_names,
 
393
                                                                 t1, cert_validation_names, validated,
 
394
                                                                 cert_validation_names, required);
 
395
                                                }
 
396
                                                break;
 
397
                                }
 
398
                                break;
 
399
                        }
 
400
                        case AUTH_RULE_IDENTITY:
 
401
                        case AUTH_RULE_EAP_IDENTITY:
 
402
                        {
 
403
                                identification_t *id1, *id2;
 
404
                                
 
405
                                id1 = (identification_t*)value;
 
406
                                id2 = get(this, t1);
 
407
                                if (!id2 || !id2->matches(id2, id1))
 
408
                                {
 
409
                                        success = FALSE;
 
410
                                        if (log_error)
 
411
                                        {
 
412
                                                DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
 
413
                                                         " required ", t1 == AUTH_RULE_IDENTITY ? "" :
 
414
                                                         "EAP ", id1);
 
415
                                        }
 
416
                                }
 
417
                                break;
 
418
                        }
 
419
                        case AUTH_RULE_AUTH_CLASS:
 
420
                        {
 
421
                                if ((uintptr_t)value != AUTH_CLASS_ANY &&
 
422
                                        (uintptr_t)value != (uintptr_t)get(this, t1))
 
423
                                {
 
424
                                        success = FALSE;
 
425
                                        if (log_error)
 
426
                                        {
 
427
                                                DBG1(DBG_CFG, "constraint requires %N authentication, "
 
428
                                                         "but %N was used", auth_class_names, (uintptr_t)value,
 
429
                                                         auth_class_names, (uintptr_t)get(this, t1));
 
430
                                        }
 
431
                                }
 
432
                                break;
 
433
                        }
 
434
                        case AUTH_RULE_EAP_TYPE:
 
435
                        {
 
436
                                if ((uintptr_t)value != (uintptr_t)get(this, t1))
 
437
                                {
 
438
                                        success = FALSE;
 
439
                                        if (log_error)
 
440
                                        {
 
441
                                                DBG1(DBG_CFG, "constraint requires %N, "
 
442
                                                         "but %N was used", eap_type_names, (uintptr_t)value,
 
443
                                                         eap_type_names,  (uintptr_t)get(this, t1));
 
444
                                        }
 
445
                                }
 
446
                                break;
 
447
                        }
 
448
                        case AUTH_RULE_EAP_VENDOR:
 
449
                        {
 
450
                                if ((uintptr_t)value != (uintptr_t)get(this, t1))
 
451
                                {
 
452
                                        success = FALSE;
 
453
                                        if (log_error)
 
454
                                        {
 
455
                                                DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
 
456
                                                         "but %d was used", (uintptr_t)value,
 
457
                                                         (uintptr_t)get(this, t1));
 
458
                                        }
 
459
                                }
 
460
                                break;
 
461
                        }
 
462
                        case AUTH_RULE_AC_GROUP:
 
463
                        {
 
464
                                success = FALSE;
 
465
                                if (log_error)
 
466
                                {
 
467
                                        DBG1(DBG_CFG, "constraint check %N not implemented!",
 
468
                                                 auth_rule_names, t1);
 
469
                                }
 
470
                                break;
 
471
                        }
 
472
                        case AUTH_HELPER_IM_CERT:
 
473
                        case AUTH_HELPER_SUBJECT_CERT:
 
474
                        case AUTH_HELPER_IM_HASH_URL:
 
475
                        case AUTH_HELPER_SUBJECT_HASH_URL:
 
476
                                /* skip helpers */
 
477
                                continue;
 
478
                }
 
479
                if (!success)
 
480
                {
 
481
                        break;
 
482
                }
 
483
        }
 
484
        e1->destroy(e1);
 
485
        return success;
 
486
}
 
487
 
 
488
/**
 
489
 * Implementation of auth_cfg_t.merge.
 
490
 */
 
491
static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
 
492
{
 
493
        if (!other)
 
494
        {       /* nothing to merge */
 
495
                return;
 
496
        }
 
497
        if (copy)
 
498
        {
 
499
                enumerator_t *enumerator;
 
500
                auth_rule_t type;
 
501
                void *value;
 
502
                
 
503
                enumerator = create_enumerator(other);
 
504
                while (enumerator->enumerate(enumerator, &type, &value))
 
505
                {
 
506
                        switch (type)
 
507
                        {
 
508
                                case AUTH_RULE_CA_CERT:
 
509
                                case AUTH_RULE_IM_CERT:
 
510
                                case AUTH_RULE_SUBJECT_CERT:
 
511
                                case AUTH_HELPER_IM_CERT:
 
512
                                case AUTH_HELPER_SUBJECT_CERT:
 
513
                                {
 
514
                                        certificate_t *cert = (certificate_t*)value;
 
515
                                        
 
516
                                        add(this, type, cert->get_ref(cert));
 
517
                                        break;
 
518
                                }
 
519
                                case AUTH_RULE_CRL_VALIDATION:
 
520
                                case AUTH_RULE_OCSP_VALIDATION:
 
521
                                case AUTH_RULE_AUTH_CLASS:
 
522
                                case AUTH_RULE_EAP_TYPE:
 
523
                                case AUTH_RULE_EAP_VENDOR:
 
524
                                {
 
525
                                        add(this, type, (uintptr_t)value);
 
526
                                        break;
 
527
                                }
 
528
                                case AUTH_RULE_IDENTITY:
 
529
                                case AUTH_RULE_EAP_IDENTITY:
 
530
                                case AUTH_RULE_AC_GROUP:
 
531
                                {
 
532
                                        identification_t *id = (identification_t*)value;
 
533
                                        
 
534
                                        add(this, type, id->clone(id));
 
535
                                        break;
 
536
                                }
 
537
                                case AUTH_HELPER_IM_HASH_URL:
 
538
                                case AUTH_HELPER_SUBJECT_HASH_URL:
 
539
                                {
 
540
                                        add(this, type, strdup((char*)value));
 
541
                                        break;
 
542
                                }
 
543
                        }
 
544
                }
 
545
                enumerator->destroy(enumerator);
 
546
        }
 
547
        else
 
548
        {
 
549
                entry_t *entry;
 
550
                
 
551
                while (other->entries->remove_first(other->entries,
 
552
                                                                                        (void**)&entry) == SUCCESS)
 
553
                {
 
554
                        this->entries->insert_last(this->entries, entry);
 
555
                }
 
556
        }
 
557
}
 
558
 
 
559
/**
 
560
 * Implementation of auth_cfg_t.equals.
 
561
 */
 
562
static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
 
563
{
 
564
        enumerator_t *e1, *e2;
 
565
        entry_t *i1, *i2;
 
566
        bool equal = TRUE, found;
 
567
        
 
568
        if (this->entries->get_count(this->entries) !=
 
569
                other->entries->get_count(other->entries))
 
570
        {
 
571
                return FALSE;
 
572
        }
 
573
        e1 = this->entries->create_enumerator(this->entries);
 
574
        while (e1->enumerate(e1, &i1))
 
575
        {
 
576
                found = FALSE;
 
577
                e2 = other->entries->create_enumerator(other->entries);
 
578
                while (e2->enumerate(e2, &i2))
 
579
                {
 
580
                        if (i1->type == i2->type)
 
581
                        {
 
582
                                switch (i1->type)
 
583
                                {
 
584
                                        case AUTH_RULE_AUTH_CLASS:
 
585
                                        case AUTH_RULE_EAP_TYPE:
 
586
                                        case AUTH_RULE_EAP_VENDOR:
 
587
                                        case AUTH_RULE_CRL_VALIDATION:
 
588
                                        case AUTH_RULE_OCSP_VALIDATION:
 
589
                                        {
 
590
                                                if (i1->value == i2->value)
 
591
                                                {
 
592
                                                        found = TRUE;
 
593
                                                        break;
 
594
                                                }
 
595
                                                continue;
 
596
                                        }
 
597
                                        case AUTH_RULE_CA_CERT:
 
598
                                        case AUTH_RULE_IM_CERT:
 
599
                                        case AUTH_RULE_SUBJECT_CERT:
 
600
                                        case AUTH_HELPER_IM_CERT:
 
601
                                        case AUTH_HELPER_SUBJECT_CERT:
 
602
                                        {
 
603
                                                certificate_t *c1, *c2;
 
604
                                                
 
605
                                                c1 = (certificate_t*)i1->value;
 
606
                                                c2 = (certificate_t*)i2->value;
 
607
                                                
 
608
                                                if (c1->equals(c1, c2))
 
609
                                                {
 
610
                                                        found = TRUE;
 
611
                                                        break;
 
612
                                                }
 
613
                                                continue;
 
614
                                        }
 
615
                                        case AUTH_RULE_IDENTITY:
 
616
                                        case AUTH_RULE_EAP_IDENTITY:
 
617
                                        case AUTH_RULE_AC_GROUP:
 
618
                                        {
 
619
                                                identification_t *id1, *id2;
 
620
                                                
 
621
                                                id1 = (identification_t*)i1->value;
 
622
                                                id2 = (identification_t*)i2->value;
 
623
                                                
 
624
                                                if (id1->equals(id1, id2))
 
625
                                                {
 
626
                                                        found = TRUE;
 
627
                                                        break;
 
628
                                                }
 
629
                                                continue;
 
630
                                        }
 
631
                                        case AUTH_HELPER_IM_HASH_URL:
 
632
                                        case AUTH_HELPER_SUBJECT_HASH_URL:
 
633
                                        {
 
634
                                                if (streq(i1->value, i2->value))
 
635
                                                {
 
636
                                                        found = TRUE;
 
637
                                                        break;
 
638
                                                }
 
639
                                                continue;
 
640
                                        }
 
641
                                }
 
642
                                break;
 
643
                        }
 
644
                }
 
645
                e2->destroy(e2);
 
646
                if (!found)
 
647
                {
 
648
                        equal = FALSE;
 
649
                        break;
 
650
                }
 
651
        }
 
652
        e1->destroy(e1);
 
653
        return equal;
 
654
}
 
655
 
 
656
/**
 
657
 * Implementation of auth_cfg_t.purge
 
658
 */
 
659
static void purge(private_auth_cfg_t *this, bool keep_ca)
 
660
{
 
661
        entry_t *entry;
 
662
        linked_list_t *cas;
 
663
        
 
664
        cas = linked_list_create();
 
665
        while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
 
666
        {
 
667
                if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
 
668
                {
 
669
                        cas->insert_first(cas, entry);
 
670
                }
 
671
                else
 
672
                {
 
673
                        destroy_entry_value(entry);
 
674
                        free(entry);
 
675
                }
 
676
        }
 
677
        while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
 
678
        {
 
679
                this->entries->insert_first(this->entries, entry);
 
680
        }
 
681
        cas->destroy(cas);
 
682
}
 
683
 
 
684
/**
 
685
 * Implementation of auth_cfg_t.clone
 
686
 */
 
687
static auth_cfg_t* clone_(private_auth_cfg_t *this)
 
688
{
 
689
        enumerator_t *enumerator;
 
690
        auth_cfg_t *clone;
 
691
        entry_t *entry;
 
692
        
 
693
        clone = auth_cfg_create();
 
694
        enumerator = this->entries->create_enumerator(this->entries);
 
695
        while (enumerator->enumerate(enumerator, &entry))
 
696
        {
 
697
                switch (entry->type)
 
698
                {
 
699
                        case AUTH_RULE_IDENTITY:
 
700
                        case AUTH_RULE_EAP_IDENTITY:
 
701
                        case AUTH_RULE_AC_GROUP:
 
702
                        {
 
703
                                identification_t *id = (identification_t*)entry->value;
 
704
                                clone->add(clone, entry->type, id->clone(id));
 
705
                                break;
 
706
                        }
 
707
                        case AUTH_RULE_CA_CERT:
 
708
                        case AUTH_RULE_IM_CERT:
 
709
                        case AUTH_RULE_SUBJECT_CERT:
 
710
                        case AUTH_HELPER_IM_CERT:
 
711
                        case AUTH_HELPER_SUBJECT_CERT:
 
712
                        {
 
713
                                certificate_t *cert = (certificate_t*)entry->value;
 
714
                                clone->add(clone, entry->type, cert->get_ref(cert));
 
715
                                break;
 
716
                        }
 
717
                        case AUTH_HELPER_IM_HASH_URL:
 
718
                        case AUTH_HELPER_SUBJECT_HASH_URL:
 
719
                        {
 
720
                                clone->add(clone, entry->type, strdup(entry->value));
 
721
                                break;
 
722
                        }
 
723
                        case AUTH_RULE_AUTH_CLASS:
 
724
                        case AUTH_RULE_EAP_TYPE:
 
725
                        case AUTH_RULE_EAP_VENDOR:
 
726
                        case AUTH_RULE_CRL_VALIDATION:
 
727
                        case AUTH_RULE_OCSP_VALIDATION:
 
728
                                clone->add(clone, entry->type, (uintptr_t)entry->value);
 
729
                                break;
 
730
                }
 
731
        }
 
732
        enumerator->destroy(enumerator);
 
733
        return clone;
 
734
}
 
735
 
 
736
/**
 
737
 * Implementation of auth_cfg_t.destroy
 
738
 */
 
739
static void destroy(private_auth_cfg_t *this)
 
740
{
 
741
        purge(this, FALSE);
 
742
        this->entries->destroy(this->entries);
 
743
        free(this);
 
744
}
 
745
 
 
746
/*
 
747
 * see header file
 
748
 */
 
749
auth_cfg_t *auth_cfg_create()
 
750
{
 
751
        private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
 
752
        
 
753
        this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
 
754
        this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
 
755
        this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
 
756
        this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
 
757
        this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
 
758
        this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
 
759
        this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
 
760
        this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
 
761
        this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
 
762
        this->public.destroy = (void(*)(auth_cfg_t*))destroy;
 
763
        
 
764
        this->entries = linked_list_create();
 
765
        
 
766
        return &this->public;
 
767
}
 
768