""
[strongswan.git] / Source / charon / configuration_manager.c
1 /**
2 * @file configuration.c
3 *
4 * @brief Configuration class used to store IKE_SA-configurations.
5 *
6 * Object of this type represents a configuration for an IKE_SA and its child_sa's.
7 *
8 */
9
10 /*
11 * Copyright (C) 2005 Jan Hutter, Martin Willi
12 * Hochschule fuer Technik Rapperswil
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 */
24
25 #include <stdlib.h>
26
27 #include "configuration_manager.h"
28
29 #include "types.h"
30 #include "utils/allocator.h"
31 #include "payloads/nonce_payload.h"
32 #include "payloads/proposal_substructure.h"
33 #include "payloads/ke_payload.h"
34 #include "payloads/transform_substructure.h"
35 #include "payloads/transform_attribute.h"
36
37 /**
38 * Private data of an configuration_t object
39 */
40 typedef struct private_configuration_manager_s private_configuration_manager_t;
41
42 struct private_configuration_manager_s {
43
44 /**
45 * Public part
46 */
47 configuration_manager_t public;
48
49 };
50
51 static status_t get_remote_host(private_configuration_manager_t *this, char *name, host_t **host)
52 {
53 /* some hard coded users for testing */
54 host_t *remote;
55 if (strcmp(name, "pinflb30") == 0) {
56 remote = host_create(AF_INET, "152.96.193.130", 500);
57 if (remote == NULL) {
58 return OUT_OF_RES;
59 }
60 *host = remote;
61 return SUCCESS;
62 }
63 else if (strcmp(name, "pinflb31") == 0) {
64 remote = host_create(AF_INET, "152.96.193.131", 500);
65 if (remote == NULL) {
66 return OUT_OF_RES;
67 }
68 *host = remote;
69 return SUCCESS;
70 }
71 return NOT_FOUND;
72 }
73
74 static status_t get_local_host(private_configuration_manager_t *this, char *name, host_t **host)
75 {
76 /* use default route for now */
77 host_t *local;
78 local = host_create(AF_INET, "0.0.0.0", 0);
79 if (local == NULL)
80 {
81 return OUT_OF_RES;
82 }
83 *host = local;
84 return SUCCESS;
85 }
86
87 static status_t get_proposals_for_host(private_configuration_manager_t *this, host_t *host, linked_list_iterator_t *iterator)
88 {
89 /* use a default proposal:
90 * - ENCR_AES_CBC 128Bit
91 * - PRF_HMAC_SHA1 128Bit
92 * - AUTH_HMAC_SHA1_96 96Bit
93 * - MODP_1024_BIT
94 */
95 proposal_substructure_t *proposal;
96 transform_substructure_t *transform;
97 transform_attribute_t *attribute;
98 status_t status;
99
100 proposal = proposal_substructure_create();
101 if (proposal == NULL)
102 {
103 return OUT_OF_RES;
104 }
105
106 /*
107 * Encryption Algorithm
108 */
109 transform = transform_substructure_create();
110 if (transform == NULL)
111 {
112 proposal->destroy(proposal);
113 return OUT_OF_RES;
114 }
115 status = proposal->add_transform_substructure(proposal, transform);
116 if (status != SUCCESS)
117 {
118 proposal->destroy(proposal);
119 return OUT_OF_RES;
120 }
121 transform->set_is_last_transform(transform, FALSE);
122 transform->set_transform_type(transform, ENCRYPTION_ALGORITHM);
123 transform->set_transform_id(transform, ENCR_AES_CBC);
124
125 attribute = transform_attribute_create();
126 if (attribute == NULL)
127 {
128 proposal->destroy(proposal);
129 return OUT_OF_RES;
130 }
131 status = transform->add_transform_attribute(transform, attribute);
132 if (status != SUCCESS)
133 {
134 proposal->destroy(proposal);
135 return OUT_OF_RES;
136 }
137 attribute->set_attribute_type(attribute, KEY_LENGTH);
138 attribute->set_value(attribute, 16);
139
140 /*
141 * Pseudo-random Function
142 */
143 transform = transform_substructure_create();
144 if (transform == NULL)
145 {
146 proposal->destroy(proposal);
147 return OUT_OF_RES;
148 }
149 status = proposal->add_transform_substructure(proposal, transform);
150 if (status != SUCCESS)
151 {
152 proposal->destroy(proposal);
153 return OUT_OF_RES;
154 }
155 transform->set_is_last_transform(transform, FALSE);
156 transform->set_transform_type(transform, PSEUDO_RANDOM_FUNCTION);
157 transform->set_transform_id(transform, PRF_HMAC_SHA1);
158
159 attribute = transform_attribute_create();
160 if (attribute == NULL)
161 {
162 proposal->destroy(proposal);
163 return OUT_OF_RES;
164 }
165 status = transform->add_transform_attribute(transform, attribute);
166 if (status != SUCCESS)
167 {
168 proposal->destroy(proposal);
169 return OUT_OF_RES;
170 }
171 attribute->set_attribute_type(attribute, KEY_LENGTH);
172 attribute->set_value(attribute, 16);
173
174
175 /*
176 * Integrity Algorithm
177 */
178 transform = transform_substructure_create();
179 if (transform == NULL)
180 {
181 proposal->destroy(proposal);
182 return OUT_OF_RES;
183 }
184 status = proposal->add_transform_substructure(proposal, transform);
185 if (status != SUCCESS)
186 {
187 proposal->destroy(proposal);
188 return OUT_OF_RES;
189 }
190 transform->set_is_last_transform(transform, FALSE);
191 transform->set_transform_type(transform, INTEGRITIY_ALGORITHM);
192 transform->set_transform_id(transform, AUTH_HMAC_SHA1_96);
193
194 attribute = transform_attribute_create();
195 if (attribute == NULL)
196 {
197 proposal->destroy(proposal);
198 return OUT_OF_RES;
199 }
200 status = transform->add_transform_attribute(transform, attribute);
201 if (status != SUCCESS)
202 {
203 proposal->destroy(proposal);
204 return OUT_OF_RES;
205 }
206 attribute->set_attribute_type(attribute, KEY_LENGTH);
207 attribute->set_value(attribute, 12);
208
209
210 /*
211 * Diffie-Hellman Group
212 */
213 transform = transform_substructure_create();
214 if (transform == NULL)
215 {
216 proposal->destroy(proposal);
217 return OUT_OF_RES;
218 }
219 status = proposal->add_transform_substructure(proposal, transform);
220 if (status != SUCCESS)
221 {
222 proposal->destroy(proposal);
223 return OUT_OF_RES;
224 }
225 transform->set_is_last_transform(transform, FALSE);
226 transform->set_transform_type(transform, DIFFIE_HELLMAN_GROUP);
227 transform->set_transform_id(transform, MODP_1024_BIT);
228
229 iterator->insert_after(iterator, (void*)proposal);
230
231 return SUCCESS;
232 }
233
234 static status_t select_proposals_for_host(private_configuration_manager_t *this, host_t *host, linked_list_iterator_t *in, linked_list_iterator_t *out)
235 {
236
237
238 return FAILED;
239 }
240
241
242 /**
243 * Implements function destroy of configuration_t.
244 * See #configuration_s.destroy for description.
245 */
246 static status_t destroy(private_configuration_manager_t *this)
247 {
248 allocator_free(this);
249 return SUCCESS;
250 }
251
252 /*
253 * Described in header-file
254 */
255 configuration_manager_t *configuration_manager_create()
256 {
257 private_configuration_manager_t *this = allocator_alloc_thing(private_configuration_manager_t);
258 if (this == NULL)
259 {
260 return NULL;
261 }
262
263 /* public functions */
264 this->public.destroy = (status_t(*)(configuration_manager_t*))destroy;
265 this->public.get_remote_host = (status_t(*)(configuration_manager_t*,char*,host_t**))get_remote_host;
266 this->public.get_local_host = (status_t(*)(configuration_manager_t*,char*,host_t**))get_local_host;
267 this->public.get_proposals_for_host = (status_t(*)(configuration_manager_t*,host_t*,linked_list_iterator_t*))get_proposals_for_host;
268 this->public.select_proposals_for_host = (status_t(*)(configuration_manager_t*,host_t*,linked_list_iterator_t*,linked_list_iterator_t*))select_proposals_for_host;
269
270
271 return (&this->public);
272 }