IKEv1 XAuth: Added plugin support for XAuth, which allows us to have plugins to talk...
[strongswan.git] / src / libcharon / sa / authenticators / xauth / xauth_manager.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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 <utils/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 method type, vendor specific if vendor is set
31 */
32 xauth_type_t type;
33
34 /**
35 * vendor ID, 0 for default XAuth methods
36 */
37 u_int32_t vendor;
38
39 /**
40 * Role of the method returned by the constructor, XAUTH_SERVER or XAUTH_PEER
41 */
42 xauth_role_t role;
43
44 /**
45 * constructor function to create instance
46 */
47 xauth_constructor_t constructor;
48 };
49
50 /**
51 * private data of xauth_manager
52 */
53 struct private_xauth_manager_t {
54
55 /**
56 * public functions
57 */
58 xauth_manager_t public;
59
60 /**
61 * list of eap_entry_t's
62 */
63 linked_list_t *methods;
64
65 /**
66 * rwlock to lock methods
67 */
68 rwlock_t *lock;
69 };
70
71 METHOD(xauth_manager_t, add_method, void,
72 private_xauth_manager_t *this, xauth_type_t type, u_int32_t vendor,
73 xauth_role_t role, xauth_constructor_t constructor)
74 {
75 xauth_entry_t *entry = malloc_thing(xauth_entry_t);
76
77 entry->type = type;
78 entry->vendor = vendor;
79 entry->role = role;
80 entry->constructor = constructor;
81
82 this->lock->write_lock(this->lock);
83 this->methods->insert_last(this->methods, entry);
84 this->lock->unlock(this->lock);
85 }
86
87 METHOD(xauth_manager_t, remove_method, void,
88 private_xauth_manager_t *this, xauth_constructor_t constructor)
89 {
90 enumerator_t *enumerator;
91 xauth_entry_t *entry;
92
93 this->lock->write_lock(this->lock);
94 enumerator = this->methods->create_enumerator(this->methods);
95 while (enumerator->enumerate(enumerator, &entry))
96 {
97 if (constructor == entry->constructor)
98 {
99 this->methods->remove_at(this->methods, enumerator);
100 free(entry);
101 }
102 }
103 enumerator->destroy(enumerator);
104 this->lock->unlock(this->lock);
105 }
106
107 METHOD(xauth_manager_t, create_instance, xauth_method_t*,
108 private_xauth_manager_t *this, xauth_type_t type, u_int32_t vendor,
109 xauth_role_t role, identification_t *server, identification_t *peer)
110 {
111 enumerator_t *enumerator;
112 xauth_entry_t *entry;
113 xauth_method_t *method = NULL;
114
115 this->lock->read_lock(this->lock);
116 enumerator = this->methods->create_enumerator(this->methods);
117 while (enumerator->enumerate(enumerator, &entry))
118 {
119 if (type == entry->type && vendor == entry->vendor &&
120 role == entry->role)
121 {
122 method = entry->constructor(server, peer);
123 if (method)
124 {
125 break;
126 }
127 }
128 }
129 enumerator->destroy(enumerator);
130 this->lock->unlock(this->lock);
131 return method;
132 }
133
134 METHOD(xauth_manager_t, destroy, void,
135 private_xauth_manager_t *this)
136 {
137 this->methods->destroy_function(this->methods, free);
138 this->lock->destroy(this->lock);
139 free(this);
140 }
141
142 /*
143 * See header
144 */
145 xauth_manager_t *xauth_manager_create()
146 {
147 private_xauth_manager_t *this;
148
149 INIT(this,
150 .public = {
151 .add_method = _add_method,
152 .remove_method = _remove_method,
153 .create_instance = _create_instance,
154 .destroy = _destroy,
155 },
156 .methods = linked_list_create(),
157 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
158 );
159
160 return &this->public;
161 }