]>
Commit | Line | Data |
---|---|---|
c7dd2a7b MW |
1 | /** |
2 | * @file ike_sa_established.c | |
3 | * | |
df3c59d0 | 4 | * @brief Implementation of ike_sa_established_t. |
c7dd2a7b MW |
5 | * |
6 | */ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify it | |
13 | * under the terms of the GNU General Public License as published by the | |
14 | * Free Software Foundation; either version 2 of the License, or (at your | |
15 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, but | |
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
19 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
20 | * for more details. | |
21 | */ | |
22 | ||
23 | #include "ike_sa_established.h" | |
24 | ||
9c781c15 | 25 | #include <daemon.h> |
e9c0ca15 | 26 | #include <encoding/payloads/delete_payload.h> |
c7dd2a7b | 27 | |
5796aa16 MW |
28 | |
29 | typedef struct private_ike_sa_established_t private_ike_sa_established_t; | |
30 | ||
c7dd2a7b MW |
31 | /** |
32 | * Private data of a ike_sa_established_t object. | |
c7dd2a7b | 33 | */ |
5796aa16 | 34 | struct private_ike_sa_established_t { |
c7dd2a7b MW |
35 | /** |
36 | * methods of the state_t interface | |
37 | */ | |
38 | ike_sa_established_t public; | |
39 | ||
40 | /** | |
e9c0ca15 | 41 | * Assigned IKE_SA. |
c7dd2a7b MW |
42 | */ |
43 | protected_ike_sa_t *ike_sa; | |
44 | ||
e9c0ca15 JH |
45 | /** |
46 | * Assigned logger. Use logger of IKE_SA. | |
47 | */ | |
48 | logger_t *logger; | |
49 | ||
e9c0ca15 JH |
50 | /** |
51 | * Process a notify payload | |
52 | * | |
53 | * @param this calling object | |
54 | * @param notify_payload notify payload | |
55 | * @param response response message of type INFORMATIONAL | |
56 | * | |
57 | * - SUCCESS | |
58 | * - FAILED | |
59 | * - DELETE_ME | |
60 | */ | |
61 | status_t (*process_notify_payload) (private_ike_sa_established_t *this, notify_payload_t *notify_payload,message_t *response); | |
c7dd2a7b MW |
62 | }; |
63 | ||
64 | /** | |
65 | * Implements state_t.get_state | |
66 | */ | |
aad398a7 | 67 | static status_t process_message(private_ike_sa_established_t *this, message_t *message) |
c7dd2a7b | 68 | { |
e9c0ca15 | 69 | delete_payload_t *delete_request = NULL; |
c00f1ece | 70 | ike_sa_id_t *ike_sa_id; |
e9c0ca15 JH |
71 | iterator_t *payloads; |
72 | message_t *response; | |
73 | crypter_t *crypter; | |
74 | signer_t *signer; | |
75 | status_t status; | |
76 | ||
77 | if (message->get_exchange_type(message) != INFORMATIONAL) | |
78 | { | |
79 | this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_sa_established", | |
80 | mapping_find(exchange_type_m,message->get_exchange_type(message))); | |
81 | return FAILED; | |
82 | } | |
83 | ||
84 | if (!message->get_request(message)) | |
85 | { | |
86 | this->logger->log(this->logger, ERROR | LEVEL1, "INFORMATIONAL responses not handled in state ike_sa_established"); | |
87 | return FAILED; | |
88 | } | |
89 | ||
c00f1ece JH |
90 | ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public)); |
91 | ||
e9c0ca15 | 92 | /* get signer for verification and crypter for decryption */ |
c00f1ece JH |
93 | if (!ike_sa_id->is_initiator(ike_sa_id)) |
94 | { | |
95 | crypter = this->ike_sa->get_crypter_initiator(this->ike_sa); | |
96 | signer = this->ike_sa->get_signer_initiator(this->ike_sa); | |
97 | } | |
98 | else | |
99 | { | |
100 | crypter = this->ike_sa->get_crypter_responder(this->ike_sa); | |
101 | signer = this->ike_sa->get_signer_responder(this->ike_sa); | |
102 | } | |
e9c0ca15 JH |
103 | |
104 | /* parse incoming message */ | |
105 | status = message->parse_body(message, crypter, signer); | |
106 | if (status != SUCCESS) | |
107 | { | |
108 | this->logger->log(this->logger, AUDIT, "INFORMATIONAL request decryption failed. Ignoring message"); | |
109 | return status; | |
110 | } | |
111 | ||
112 | /* build empty INFORMATIONAL message */ | |
113 | this->ike_sa->build_message(this->ike_sa, INFORMATIONAL, FALSE, &response); | |
114 | ||
115 | payloads = message->get_payload_iterator(message); | |
116 | ||
117 | while (payloads->has_next(payloads)) | |
118 | { | |
119 | payload_t *payload; | |
120 | payloads->current(payloads, (void**)&payload); | |
121 | ||
122 | switch (payload->get_type(payload)) | |
123 | { | |
124 | case NOTIFY: | |
125 | { | |
126 | notify_payload_t *notify_payload = (notify_payload_t *) payload; | |
127 | /* handle the notify directly, abort if no further processing required */ | |
128 | status = this->process_notify_payload(this, notify_payload,response); | |
129 | if (status != SUCCESS) | |
130 | { | |
131 | payloads->destroy(payloads); | |
132 | response->destroy(response); | |
133 | return status; | |
134 | } | |
135 | } | |
136 | case DELETE: | |
137 | { | |
138 | delete_request = (delete_payload_t *) payload; | |
b1953ccd | 139 | break; |
e9c0ca15 JH |
140 | } |
141 | default: | |
142 | { | |
143 | this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)", | |
144 | mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload)); | |
145 | break; | |
146 | } | |
147 | } | |
148 | } | |
149 | /* iterator can be destroyed */ | |
150 | payloads->destroy(payloads); | |
151 | ||
152 | if (delete_request) | |
b1953ccd | 153 | { |
dec59822 | 154 | if (delete_request->get_protocol_id(delete_request) == PROTO_IKE) |
e9c0ca15 | 155 | { |
b1953ccd | 156 | this->logger->log(this->logger, AUDIT, "DELETE request for IKE_SA received"); |
e9c0ca15 | 157 | response->destroy(response); |
b1953ccd MW |
158 | return DELETE_ME; |
159 | } | |
160 | else | |
161 | { | |
162 | this->logger->log(this->logger, AUDIT, "DELETE request for CHILD_SA received. Ignored"); | |
163 | response->destroy(response); | |
164 | return SUCCESS; | |
e9c0ca15 JH |
165 | } |
166 | } | |
167 | ||
e9c0ca15 JH |
168 | status = this->ike_sa->send_response(this->ike_sa, response); |
169 | /* message can now be sent (must not be destroyed) */ | |
170 | if (status != SUCCESS) | |
171 | { | |
172 | this->logger->log(this->logger, AUDIT, "Unable to send INFORMATIONAL reply"); | |
173 | response->destroy(response); | |
174 | return FAILED; | |
175 | } | |
176 | ||
177 | return SUCCESS; | |
178 | } | |
179 | ||
c7dd2a7b | 180 | /** |
e9c0ca15 JH |
181 | * Implementation of private_ike_sa_established_t.process_notify_payload; |
182 | */ | |
183 | static status_t process_notify_payload (private_ike_sa_established_t *this, notify_payload_t *notify_payload, message_t *response) | |
184 | { | |
185 | notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload); | |
186 | ||
187 | this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s for protocol %s", | |
188 | mapping_find(notify_message_type_m, notify_message_type), | |
189 | mapping_find(protocol_id_m, notify_payload->get_protocol_id(notify_payload))); | |
190 | ||
191 | switch (notify_message_type) | |
192 | { | |
193 | default: | |
194 | { | |
195 | this->logger->log(this->logger, AUDIT, "INFORMATIONAL request contained an unknown notify (%d), ignored.", notify_message_type); | |
196 | } | |
197 | } | |
198 | ||
199 | ||
200 | return SUCCESS; | |
201 | } | |
202 | ||
203 | /** | |
204 | * Implementation of state_t.get_state. | |
c7dd2a7b MW |
205 | */ |
206 | static ike_sa_state_t get_state(private_ike_sa_established_t *this) | |
207 | { | |
208 | return IKE_SA_ESTABLISHED; | |
209 | } | |
210 | ||
211 | /** | |
e9c0ca15 | 212 | * Implementation of state_t.get_state |
c7dd2a7b | 213 | */ |
d048df5c | 214 | static void destroy(private_ike_sa_established_t *this) |
c7dd2a7b | 215 | { |
5113680f | 216 | free(this); |
c7dd2a7b MW |
217 | } |
218 | ||
219 | /* | |
220 | * Described in header. | |
221 | */ | |
222 | ike_sa_established_t *ike_sa_established_create(protected_ike_sa_t *ike_sa) | |
223 | { | |
5113680f | 224 | private_ike_sa_established_t *this = malloc_thing(private_ike_sa_established_t); |
c7dd2a7b MW |
225 | |
226 | /* interface functions */ | |
aad398a7 | 227 | this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message; |
c7dd2a7b | 228 | this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state; |
d048df5c | 229 | this->public.state_interface.destroy = (void (*) (state_t *)) destroy; |
c7dd2a7b | 230 | |
e9c0ca15 JH |
231 | /* private functions */ |
232 | this->process_notify_payload = process_notify_payload; | |
e9c0ca15 | 233 | |
c7dd2a7b MW |
234 | /* private data */ |
235 | this->ike_sa = ike_sa; | |
5113680f | 236 | this->logger = logger_manager->get_logger(logger_manager, IKE_SA); |
c7dd2a7b MW |
237 | |
238 | return &(this->public); | |
239 | } |