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