4 * @brief Implementation of receiver_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30 #include <network/socket.h>
31 #include <network/packet.h>
32 #include <processing/job_queue.h>
33 #include <processing/jobs/job.h>
34 #include <processing/jobs/process_message_job.h>
36 /** length of the full cookie, including time (u_int32_t + SHA1()) */
37 #define COOKIE_LENGTH 24
38 /** lifetime of a cookie, in seconds */
39 #define COOKIE_LIFETIME 10
40 /** how many times to reuse the secret */
41 #define COOKIE_REUSE 10000
42 /** require cookies after half open IKE_SAs */
43 #define COOKIE_TRESHOLD 10
44 /** how many half open IKE_SAs per peer before blocking */
45 #define BLOCK_TRESHOLD 5
46 /** length of the secret to use for cookie calculation */
47 #define SECRET_LENGTH 16
49 typedef struct private_receiver_t private_receiver_t
;
52 * Private data of a receiver_t object.
54 struct private_receiver_t
{
56 * Public part of a receiver_t object.
63 pthread_t assigned_thread
;
66 * current secret to use for cookie calculation
68 char secret
[SECRET_LENGTH
];
71 * previous secret used to verify older cookies
73 char secret_old
[SECRET_LENGTH
];
76 * how many times we have used "secret" so far
78 u_int32_t secret_used
;
81 * time we did the cookie switch
83 u_int32_t secret_switch
;
86 * time offset to use, hides our system time
88 u_int32_t secret_offset
;
91 * the randomizer to use for secret generation
93 randomizer_t
*randomizer
;
96 * hasher to use for cookie calculation
102 * send a notify back to the sender
104 static void send_notify(message_t
*request
, notify_type_t type
, chunk_t data
)
106 if (request
->get_request(request
) &&
107 request
->get_exchange_type(request
) == IKE_SA_INIT
)
112 ike_sa_id_t
*ike_sa_id
;
114 response
= message_create();
115 dst
= request
->get_source(request
);
116 src
= request
->get_destination(request
);
117 response
->set_source(response
, src
->clone(src
));
118 response
->set_destination(response
, dst
->clone(dst
));
119 response
->set_exchange_type(response
, request
->get_exchange_type(request
));
120 response
->set_request(response
, FALSE
);
121 response
->set_message_id(response
, 0);
122 ike_sa_id
= request
->get_ike_sa_id(request
);
123 ike_sa_id
->switch_initiator(ike_sa_id
);
124 response
->set_ike_sa_id(response
, ike_sa_id
);
125 response
->add_notify(response
, FALSE
, type
, data
);
126 if (response
->generate(response
, NULL
, NULL
, &packet
) == SUCCESS
)
128 charon
->sender
->send(charon
->sender
, packet
);
129 response
->destroy(response
);
137 static chunk_t
cookie_build(private_receiver_t
*this, message_t
*message
,
138 u_int32_t t
, chunk_t secret
)
140 u_int64_t spi
= message
->get_initiator_spi(message
);
141 host_t
*ip
= message
->get_source(message
);
142 chunk_t input
, hash
= chunk_alloca(this->hasher
->get_hash_size(this->hasher
));
144 /* COOKIE = t | sha1( IPi | SPIi | t | secret ) */
145 input
= chunk_cata("cccc", ip
->get_address(ip
), chunk_from_thing(spi
),
146 chunk_from_thing(t
), secret
);
147 this->hasher
->get_hash(this->hasher
, input
, hash
.ptr
);
148 return chunk_cat("cc", chunk_from_thing(t
), hash
);
152 * verify a received cookie
154 static bool cookie_verify(private_receiver_t
*this, message_t
*message
,
162 t
= *(u_int32_t
*)cookie
.ptr
;
164 if (cookie
.len
!= COOKIE_LENGTH
||
165 t
< now
- this->secret_offset
- COOKIE_LIFETIME
)
167 DBG2(DBG_NET
, "received cookie lifetime expired, rejecting");
171 /* check if cookie is derived from old_secret */
172 if (t
+ this->secret_offset
> this->secret_switch
)
174 secret
= chunk_from_thing(this->secret
);
178 secret
= chunk_from_thing(this->secret_old
);
181 /* compare own calculation against received */
182 reference
= cookie_build(this, message
, t
, secret
);
183 if (chunk_equals(reference
, cookie
))
185 chunk_free(&reference
);
188 chunk_free(&reference
);
193 * check if cookies are required, and if so, a valid cookie is included
195 static bool cookie_required(private_receiver_t
*this, message_t
*message
)
199 if (charon
->ike_sa_manager
->get_half_open_count(charon
->ike_sa_manager
,
200 NULL
) >= COOKIE_TRESHOLD
)
202 /* check for a cookie. We don't use our parser here and do it
203 * quick and dirty for performance reasons.
204 * we assume to cookie is the first payload (which is a MUST), and
205 * the cookies SPI length is zero. */
206 packet_t
*packet
= message
->get_packet(message
);
207 chunk_t data
= packet
->get_data(packet
);
209 IKE_HEADER_LENGTH
+ NOTIFY_PAYLOAD_HEADER_LENGTH
+ COOKIE_LENGTH
||
210 *(data
.ptr
+ 16) != NOTIFY
||
211 *(u_int16_t
*)(data
.ptr
+ IKE_HEADER_LENGTH
+ 6) != htons(COOKIE
))
213 /* no cookie found */
218 data
.ptr
+= IKE_HEADER_LENGTH
+ NOTIFY_PAYLOAD_HEADER_LENGTH
;
219 data
.len
= COOKIE_LENGTH
;
220 if (!cookie_verify(this, message
, data
))
222 DBG2(DBG_NET
, "found cookie, but content invalid");
226 packet
->destroy(packet
);
232 * check if peer has to many half open IKE_SAs
234 static bool peer_to_aggressive(private_receiver_t
*this, message_t
*message
)
236 if (charon
->ike_sa_manager
->get_half_open_count(charon
->ike_sa_manager
,
237 message
->get_source(message
)) >= BLOCK_TRESHOLD
)
245 * Implementation of receiver_t.receive_packets.
247 static void receive_packets(private_receiver_t
*this)
253 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
254 DBG1(DBG_NET
, "receiver thread running, thread_ID: %06u",
255 (int)pthread_self());
257 charon
->drop_capabilities(charon
, TRUE
);
261 /* read in a packet */
262 if (charon
->socket
->receive(charon
->socket
, &packet
) != SUCCESS
)
264 DBG2(DBG_NET
, "receiving from socket failed!");
265 /* try again after a delay */
270 /* parse message header */
271 message
= message_create_from_packet(packet
);
272 if (message
->parse_header(message
) != SUCCESS
)
274 DBG1(DBG_NET
, "received invalid IKE header from %H, ignored",
275 packet
->get_source(packet
));
276 message
->destroy(message
);
280 /* check IKE major version */
281 if (message
->get_major_version(message
) != IKE_MAJOR_VERSION
)
283 DBG1(DBG_NET
, "received unsupported IKE version %d.%d from %H, "
284 "sending INVALID_MAJOR_VERSION", message
->get_major_version(message
),
285 message
->get_minor_version(message
), packet
->get_source(packet
));
286 send_notify(message
, INVALID_MAJOR_VERSION
, chunk_empty
);
287 message
->destroy(message
);
291 if (message
->get_request(message
) &&
292 message
->get_exchange_type(message
) == IKE_SA_INIT
)
294 /* check for cookies */
295 if (cookie_required(this, message
))
297 u_int32_t now
= time(NULL
);
298 chunk_t cookie
= cookie_build(this, message
, now
- this->secret_offset
,
299 chunk_from_thing(this->secret
));
301 DBG2(DBG_NET
, "received packet from: %#H to %#H",
302 message
->get_source(message
),
303 message
->get_destination(message
));
304 DBG2(DBG_NET
, "sending COOKIE notify to %H",
305 message
->get_source(message
));
306 send_notify(message
, COOKIE
, cookie
);
308 if (++this->secret_used
> COOKIE_REUSE
)
310 /* create new cookie */
311 DBG1(DBG_NET
, "generating new cookie secret after %d uses",
313 memcpy(this->secret_old
, this->secret
, SECRET_LENGTH
);
314 this->randomizer
->get_pseudo_random_bytes(this->randomizer
,
315 SECRET_LENGTH
, this->secret
);
316 this->secret_switch
= now
;
317 this->secret_used
= 0;
319 message
->destroy(message
);
323 /* check if peer has not too many IKE_SAs half open */
324 if (peer_to_aggressive(this, message
))
326 DBG1(DBG_NET
, "ignoring IKE_SA setup from %H, "
327 "peer to aggressive", message
->get_source(message
));
328 message
->destroy(message
);
332 job
= (job_t
*)process_message_job_create(message
);
333 charon
->job_queue
->add(charon
->job_queue
, job
);
338 * Implementation of receiver_t.destroy.
340 static void destroy(private_receiver_t
*this)
342 pthread_cancel(this->assigned_thread
);
343 pthread_join(this->assigned_thread
, NULL
);
344 this->randomizer
->destroy(this->randomizer
);
345 this->hasher
->destroy(this->hasher
);
350 * Described in header.
352 receiver_t
*receiver_create()
354 private_receiver_t
*this = malloc_thing(private_receiver_t
);
355 u_int32_t now
= time(NULL
);
357 this->public.destroy
= (void(*)(receiver_t
*)) destroy
;
359 this->randomizer
= randomizer_create();
360 this->hasher
= hasher_create(HASH_SHA1
);
361 this->secret_switch
= now
;
362 this->secret_offset
= random() % now
;
363 this->secret_used
= 0;
364 this->randomizer
->get_pseudo_random_bytes(this->randomizer
, SECRET_LENGTH
,
366 memcpy(this->secret_old
, this->secret
, SECRET_LENGTH
);
368 if (pthread_create(&this->assigned_thread
, NULL
,
369 (void*)receive_packets
, this) != 0)
372 charon
->kill(charon
, "unable to create receiver thread");
375 return &this->public;