moved AUTH_LIFETIME handling in its own task (cleaner separation, proper payload...
[strongswan.git] / src / charon / sa / tasks / ike_auth_lifetime.c
1 /**
2 * @file ike_auth_lifetime.c
3 *
4 * @brief Implementation of the ike_auth_lifetime task.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 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_auth_lifetime.h"
24
25 #include <daemon.h>
26 #include <encoding/payloads/notify_payload.h>
27
28
29 typedef struct private_ike_auth_lifetime_t private_ike_auth_lifetime_t;
30
31 /**
32 * Private members of a ike_auth_lifetime_t task.
33 */
34 struct private_ike_auth_lifetime_t {
35
36 /**
37 * Public methods and task_t interface.
38 */
39 ike_auth_lifetime_t public;
40
41 /**
42 * Assigned IKE_SA.
43 */
44 ike_sa_t *ike_sa;
45 };
46
47 /**
48 * add the AUTH_LIFETIME notify to the message
49 */
50 static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *message)
51 {
52 chunk_t chunk;
53 u_int32_t lifetime;
54
55 lifetime = this->ike_sa->get_statistic(this->ike_sa, STAT_REAUTH_TIME);
56 if (lifetime)
57 {
58 chunk = chunk_from_thing(lifetime);
59 *(u_int32_t*)chunk.ptr = htonl(lifetime);
60 message->add_notify(message, FALSE, AUTH_LIFETIME, chunk);
61 }
62 }
63
64 /**
65 * read notifys from message and evaluate them
66 */
67 static void process_payloads(private_ike_auth_lifetime_t *this, message_t *message)
68 {
69 iterator_t *iterator;
70 payload_t *payload;
71 notify_payload_t *notify;
72
73 iterator = message->get_payload_iterator(message);
74 while (iterator->iterate(iterator, (void**)&payload))
75 {
76 if (payload->get_type(payload) == NOTIFY)
77 {
78 notify = (notify_payload_t*)payload;
79 switch (notify->get_notify_type(notify))
80 {
81 case AUTH_LIFETIME:
82 {
83 chunk_t data = notify->get_notification_data(notify);
84 u_int32_t lifetime = ntohl(*(u_int32_t*)data.ptr);
85 this->ike_sa->set_auth_lifetime(this->ike_sa, lifetime);
86 break;
87 }
88 default:
89 break;
90 }
91 }
92 }
93 iterator->destroy(iterator);
94 }
95
96 /**
97 * Implementation of task_t.process for initiator
98 */
99 static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message)
100 {
101 if (message->get_exchange_type(message) == INFORMATIONAL)
102 {
103 add_auth_lifetime(this, message);
104 return SUCCESS;
105 }
106 return NEED_MORE;
107 }
108
109 /**
110 * Implementation of task_t.process for responder
111 */
112 static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message)
113 {
114 if (message->get_exchange_type(message) == INFORMATIONAL)
115 {
116 process_payloads(this, message);
117 return SUCCESS;
118 }
119 return NEED_MORE;
120 }
121
122 /**
123 * Implementation of task_t.build for responder
124 */
125 static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message)
126 {
127 if (message->get_exchange_type(message) == IKE_AUTH &&
128 message->get_payload(message, SECURITY_ASSOCIATION))
129 {
130 add_auth_lifetime(this, message);
131 return SUCCESS;
132 }
133 return NEED_MORE;
134 }
135
136 /**
137 * Implementation of task_t.process for initiator
138 */
139 static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message)
140 {
141 if (message->get_exchange_type(message) == IKE_AUTH &&
142 message->get_payload(message, SECURITY_ASSOCIATION))
143 {
144 process_payloads(this, message);
145 return SUCCESS;
146 }
147 return NEED_MORE;
148 }
149
150 /**
151 * Implementation of task_t.get_type
152 */
153 static task_type_t get_type(private_ike_auth_lifetime_t *this)
154 {
155 return IKE_AUTH_LIFETIME;
156 }
157
158 /**
159 * Implementation of task_t.migrate
160 */
161 static void migrate(private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa)
162 {
163 this->ike_sa = ike_sa;
164 }
165
166 /**
167 * Implementation of task_t.destroy
168 */
169 static void destroy(private_ike_auth_lifetime_t *this)
170 {
171 free(this);
172 }
173
174 /*
175 * Described in header.
176 */
177 ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator)
178 {
179 private_ike_auth_lifetime_t *this = malloc_thing(private_ike_auth_lifetime_t);
180
181 this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
182 this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
183 this->public.task.destroy = (void(*)(task_t*))destroy;
184
185 if (initiator)
186 {
187 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
188 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
189 }
190 else
191 {
192 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
193 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
194 }
195
196 this->ike_sa = ike_sa;
197
198 return &this->public;
199 }
200