Make sure that xauth-noauth is not used accidentally
[strongswan.git] / src / libcharon / sa / xauth / xauth_manager.c
1 /*
2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
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 #include "xauth_manager.h"
17
18 #include <collections/linked_list.h>
19 #include <threading/rwlock.h>
20
21 typedef struct private_xauth_manager_t private_xauth_manager_t;
22 typedef struct xauth_entry_t xauth_entry_t;
23
24 /**
25 * XAuth constructor entry
26 */
27 struct xauth_entry_t {
28
29 /**
30 * Xauth backend name
31 */
32 char *name;
33
34 /**
35 * Role of the method, XAUTH_SERVER or XAUTH_PEER
36 */
37 xauth_role_t role;
38
39 /**
40 * constructor function to create instance
41 */
42 xauth_constructor_t constructor;
43 };
44
45 /**
46 * private data of xauth_manager
47 */
48 struct private_xauth_manager_t {
49
50 /**
51 * public functions
52 */
53 xauth_manager_t public;
54
55 /**
56 * list of eap_entry_t's
57 */
58 linked_list_t *methods;
59
60 /**
61 * rwlock to lock methods
62 */
63 rwlock_t *lock;
64 };
65
66 METHOD(xauth_manager_t, add_method, void,
67 private_xauth_manager_t *this, char *name, xauth_role_t role,
68 xauth_constructor_t constructor)
69 {
70 xauth_entry_t *entry;
71
72 INIT(entry,
73 .name = name,
74 .role = role,
75 .constructor = constructor,
76 );
77
78 this->lock->write_lock(this->lock);
79 this->methods->insert_last(this->methods, entry);
80 this->lock->unlock(this->lock);
81 }
82
83 METHOD(xauth_manager_t, remove_method, void,
84 private_xauth_manager_t *this, xauth_constructor_t constructor)
85 {
86 enumerator_t *enumerator;
87 xauth_entry_t *entry;
88
89 this->lock->write_lock(this->lock);
90 enumerator = this->methods->create_enumerator(this->methods);
91 while (enumerator->enumerate(enumerator, &entry))
92 {
93 if (constructor == entry->constructor)
94 {
95 this->methods->remove_at(this->methods, enumerator);
96 free(entry);
97 }
98 }
99 enumerator->destroy(enumerator);
100 this->lock->unlock(this->lock);
101 }
102
103 METHOD(xauth_manager_t, create_instance, xauth_method_t*,
104 private_xauth_manager_t *this, char *name, xauth_role_t role,
105 identification_t *server, identification_t *peer)
106 {
107 enumerator_t *enumerator;
108 xauth_entry_t *entry;
109 xauth_method_t *method = NULL;
110
111 this->lock->read_lock(this->lock);
112 enumerator = this->methods->create_enumerator(this->methods);
113 while (enumerator->enumerate(enumerator, &entry))
114 {
115 if (!name && streq(entry->name, "noauth"))
116 { /* xauth-noauth has to be configured explicitly */
117 continue;
118 }
119 if (role == entry->role && (!name || streq(name, entry->name)))
120 {
121 method = entry->constructor(server, peer);
122 if (method)
123 {
124 break;
125 }
126 }
127 }
128 enumerator->destroy(enumerator);
129 this->lock->unlock(this->lock);
130 return method;
131 }
132
133 METHOD(xauth_manager_t, destroy, void,
134 private_xauth_manager_t *this)
135 {
136 this->methods->destroy_function(this->methods, free);
137 this->lock->destroy(this->lock);
138 free(this);
139 }
140
141 /*
142 * See header
143 */
144 xauth_manager_t *xauth_manager_create()
145 {
146 private_xauth_manager_t *this;
147
148 INIT(this,
149 .public = {
150 .add_method = _add_method,
151 .remove_method = _remove_method,
152 .create_instance = _create_instance,
153 .destroy = _destroy,
154 },
155 .methods = linked_list_create(),
156 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
157 );
158
159 return &this->public;
160 }