split out option parsing to config.c
[vpnc.git] / vpnc.c
blob4a1c814c86826a7d0572b8b5b63ecc1f78e50df6
1 /* IPSec VPN client compatible with Cisco equipment.
2 Copyright (C) 2002, 2003 Geoffrey Keating and Maurice Massar
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #define _GNU_SOURCE
20 #include <assert.h>
21 #include <unistd.h>
22 #include <sys/fcntl.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <time.h>
27 #include <stdlib.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <netdb.h>
31 #include <arpa/inet.h>
32 #include <poll.h>
33 #include <net/if.h>
34 #include <sys/ioctl.h>
35 #include <sys/utsname.h>
37 #include <gcrypt.h>
39 #include "sysdep.h"
40 #include "config.h"
41 #include "isakmp-pkt.h"
42 #include "math_group.h"
43 #include "dh.h"
44 #include "vpnc.h"
46 extern void vpnc_doit(unsigned long tous_spi,
47 const unsigned char *tous_key,
48 struct sockaddr_in *tous_dest,
49 unsigned long tothem_spi,
50 const unsigned char *tothem_key,
51 struct sockaddr_in *tothem_dest,
52 int tun_fd, int md_algo, int cry_algo,
53 uint8_t * kill_packet_p, size_t kill_packet_size_p,
54 struct sockaddr *kill_dest_p, const char *pidfile);
56 enum supp_algo_key {
57 SUPP_ALGO_NAME,
58 SUPP_ALGO_MY_ID,
59 SUPP_ALGO_IKE_SA,
60 SUPP_ALGO_IPSEC_SA
63 enum algo_group {
64 SUPP_ALGO_DH_GROUP,
65 SUPP_ALGO_HASH,
66 SUPP_ALGO_CRYPT
69 supported_algo_t supp_dh_group[] = {
70 {"nopfs", 0, 0, 0, 0},
71 {"dh1", OAKLEY_GRP_1, IKE_GROUP_MODP_768, IKE_GROUP_MODP_768, 0},
72 {"dh2", OAKLEY_GRP_2, IKE_GROUP_MODP_1024, IKE_GROUP_MODP_1024, 0},
73 {"dh5", OAKLEY_GRP_5, IKE_GROUP_MODP_1536, IKE_GROUP_MODP_1536, 0},
74 /*{ "dh7", OAKLEY_GRP_7, IKE_GROUP_EC2N_163K, IKE_GROUP_EC2N_163K, 0 } note: code missing */
75 {NULL, 0, 0, 0, 0}
78 supported_algo_t supp_hash[] = {
79 {"md5", GCRY_MD_MD5, IKE_HASH_MD5, IPSEC_AUTH_HMAC_MD5, 0},
80 {"sha1", GCRY_MD_SHA1, IKE_HASH_SHA, IPSEC_AUTH_HMAC_SHA, 0},
81 {NULL, 0, 0, 0, 0}
84 supported_algo_t supp_crypt[] = {
85 {"des", GCRY_CIPHER_DES, IKE_ENC_DES_CBC, ISAKMP_IPSEC_ESP_DES, 0}, /*note: working, but not recommended */
86 {"3des", GCRY_CIPHER_3DES, IKE_ENC_3DES_CBC, ISAKMP_IPSEC_ESP_3DES, 0},
87 {"aes128", GCRY_CIPHER_AES128, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 128},
88 {"aes192", GCRY_CIPHER_AES192, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 192},
89 {"aes256", GCRY_CIPHER_AES256, IKE_ENC_AES_CBC, ISAKMP_IPSEC_ESP_AES, 256},
90 {NULL, 0, 0, 0, 0}
93 const supported_algo_t *get_algo(enum algo_group what, enum supp_algo_key key, int id,
94 const char *name, int keylen)
96 supported_algo_t *sa = NULL;
97 int i = 0, val = 0;
98 const char *valname = NULL;
100 assert(what <= SUPP_ALGO_CRYPT);
101 assert(key <= SUPP_ALGO_IPSEC_SA);
103 switch (what) {
104 case SUPP_ALGO_DH_GROUP:
105 sa = supp_dh_group;
106 break;
107 case SUPP_ALGO_HASH:
108 sa = supp_hash;
109 break;
110 case SUPP_ALGO_CRYPT:
111 sa = supp_crypt;
112 break;
115 for (i = 0; sa[i].name != NULL; i++) {
116 switch (key) {
117 case SUPP_ALGO_NAME:
118 valname = sa[i].name;
119 break;
120 case SUPP_ALGO_MY_ID:
121 val = sa[i].my_id;
122 break;
123 case SUPP_ALGO_IKE_SA:
124 val = sa[i].ike_sa_id;
125 break;
126 case SUPP_ALGO_IPSEC_SA:
127 val = sa[i].ipsec_sa_id;
128 break;
130 if ((key == SUPP_ALGO_NAME) ? !strcasecmp(name, valname) : (val == id))
131 if (keylen == sa[i].keylen)
132 return sa + i;
135 return NULL;
138 const supported_algo_t *get_dh_group_ike(void)
140 return get_algo(SUPP_ALGO_DH_GROUP, SUPP_ALGO_NAME, 0, config[CONFIG_IKE_DH], 0);
142 const supported_algo_t *get_dh_group_ipsec(int server_setting)
144 const char *pfs_setting = config[CONFIG_IPSEC_PFS];
146 if (!strcmp(config[CONFIG_IPSEC_PFS], "server")) {
147 /* treat server_setting == -1 (unknown) as 0 */
148 pfs_setting = (server_setting == 1) ? "dh2" : "nopfs";
151 return get_algo(SUPP_ALGO_DH_GROUP, SUPP_ALGO_NAME, 0, pfs_setting, 0);
154 /* * */
156 static __inline__ int min(int a, int b)
158 return (a < b) ? a : b;
161 static int make_socket(uint16_t port)
163 int sock;
164 struct sockaddr_in name;
166 /* Create the socket. */
167 sock = socket(PF_INET, SOCK_DGRAM, 0);
168 if (sock < 0)
169 error(1, errno, "making socket");
171 /* Give the socket a name. */
172 name.sin_family = AF_INET;
173 name.sin_port = htons(port);
174 name.sin_addr.s_addr = htonl(INADDR_ANY);
175 if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0)
176 error(1, errno, "binding to port %d", port);
178 return sock;
181 static struct sockaddr *init_sockaddr(const char *hostname, uint16_t port)
183 struct hostent *hostinfo;
184 struct sockaddr_in *result;
186 result = malloc(sizeof(struct sockaddr_in));
187 if (result == NULL)
188 error(1, errno, "out of memory");
190 result->sin_family = AF_INET;
191 result->sin_port = htons(port);
192 if (inet_aton(hostname, &result->sin_addr) == 0) {
193 hostinfo = gethostbyname(hostname);
194 if (hostinfo == NULL)
195 error(1, 0, "unknown host `%s'\n", hostname);
196 result->sin_addr = *(struct in_addr *)hostinfo->h_addr;
198 return (struct sockaddr *)result;
201 int tun_fd = -1;
202 char tun_name[IFNAMSIZ];
204 static void setup_tunnel(void)
206 if (config[CONFIG_IF_NAME])
207 memcpy(tun_name, config[CONFIG_IF_NAME], strlen(config[CONFIG_IF_NAME]));
209 tun_fd = tun_open(tun_name);
210 DEBUG(2, printf("using interface %s\n", tun_name));
212 if (tun_fd == -1)
213 error(1, errno, "can't initialise tunnel interface");
216 static int sockfd = -1;
217 static struct sockaddr *dest_addr;
218 static int timeout = 5000; /* 5 seconds */
219 static uint8_t *resend_hash = NULL;
221 static int recv_ignore_dup(void *recvbuf, size_t recvbufsize, uint8_t reply_extype)
223 uint8_t *resend_check_hash;
224 int recvsize, hash_len;
225 struct sockaddr_in recvaddr;
226 socklen_t recvaddr_size = sizeof(recvaddr);
227 char ntop_buf[32];
229 recvsize = recvfrom(sockfd, recvbuf, recvbufsize, 0,
230 (struct sockaddr *)&recvaddr, &recvaddr_size);
231 if (recvsize == -1)
232 error(1, errno, "receiving packet");
233 if (recvsize > 0) {
234 if (recvaddr_size != sizeof(recvaddr)
235 || recvaddr.sin_family != dest_addr->sa_family
236 || recvaddr.sin_port != ((struct sockaddr_in *)dest_addr)->sin_port
237 || memcmp(&recvaddr.sin_addr,
238 &((struct sockaddr_in *)dest_addr)->sin_addr,
239 sizeof(struct in_addr)) != 0) {
240 error(0, 0, "got response from unknown host %s:%d",
241 inet_ntop(recvaddr.sin_family, &recvaddr.sin_addr,
242 ntop_buf, sizeof(ntop_buf)), ntohs(recvaddr.sin_port));
243 return -1;
246 hex_dump("exchange_type", ((uint8_t *) recvbuf) + ISAKMP_EXCHANGE_TYPE_O, UINT8);
247 if (reply_extype && (((uint8_t *) recvbuf)[ISAKMP_EXCHANGE_TYPE_O] != reply_extype)) {
248 DEBUG(2, printf("want extype %d, got %d, ignoring\n", reply_extype,
249 ((uint8_t *) recvbuf)[ISAKMP_EXCHANGE_TYPE_O]));
250 return -1;
253 hash_len = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
254 resend_check_hash = malloc(hash_len);
255 gcry_md_hash_buffer(GCRY_MD_SHA1, resend_check_hash, recvbuf, recvsize);
256 if (resend_hash && memcmp(resend_hash, resend_check_hash, hash_len) == 0) {
257 free(resend_check_hash);
258 return -1;
260 if (!resend_hash) {
261 resend_hash = resend_check_hash;
262 } else {
263 memcpy(resend_hash, resend_check_hash, hash_len);
264 free(resend_check_hash);
267 return recvsize;
270 /* Send TOSEND of size SENDSIZE to the socket. Then wait for a new packet,
271 resending TOSEND on timeout, and ignoring duplicate packets; the
272 new packet is put in RECVBUF of size RECVBUFSIZE and the actual size
273 of the new packet is returned. */
275 static ssize_t
276 sendrecv(void *recvbuf, size_t recvbufsize, void *tosend, size_t sendsize, uint8_t reply_extype)
278 struct pollfd pfd;
279 int tries = 0;
280 int recvsize;
281 time_t start = time(NULL);
282 time_t end;
284 pfd.fd = sockfd;
285 pfd.events = POLLIN;
286 tries = 0;
288 for (;;) {
289 int pollresult;
291 if (tosend != NULL)
292 if (sendto(sockfd, tosend, sendsize, 0,
293 dest_addr, sizeof(struct sockaddr_in)) != (int)sendsize)
294 error(1, errno, "can't send packet");
295 do {
296 pollresult = poll(&pfd, 1, timeout << tries);
297 } while (pollresult == -1 && errno == EINTR);
298 if (pollresult == -1)
299 error(1, errno, "can't poll socket");
300 if (pollresult != 0) {
301 recvsize = recv_ignore_dup(recvbuf, recvbufsize, reply_extype);
302 end = time(NULL);
303 if (recvsize != -1)
304 break;
305 continue;
307 if (tries > 5)
308 error(1, 0, "no response from target");
309 tries++;
312 /* Wait at least 2s for a response or 4 times the time it took
313 * last time. */
314 if (start == end)
315 timeout = 2000;
316 else
317 timeout = 4000 * (end - start);
319 return recvsize;
322 struct isakmp_attribute *make_transform_ike(int dh_group, int crypt, int hash, int keylen)
324 struct isakmp_attribute *a = NULL;
326 a = new_isakmp_attribute(IKE_ATTRIB_LIFE_DURATION, a);
327 a->af = isakmp_attr_lots;
328 a->u.lots.length = 4;
329 a->u.lots.data = xallocc(a->u.lots.length);
330 *((uint32_t *) a->u.lots.data) = htonl(2147483);
331 a = new_isakmp_attribute_16(IKE_ATTRIB_LIFE_TYPE, IKE_LIFE_TYPE_SECONDS, a);
332 a = new_isakmp_attribute_16(IKE_ATTRIB_GROUP_DESC, dh_group, a);
333 a = new_isakmp_attribute_16(IKE_ATTRIB_AUTH_METHOD, XAUTH_AUTH_XAUTHInitPreShared, a);
334 a = new_isakmp_attribute_16(IKE_ATTRIB_HASH, hash, a);
335 a = new_isakmp_attribute_16(IKE_ATTRIB_ENC, crypt, a);
336 if (keylen != 0)
337 a = new_isakmp_attribute_16(IKE_ATTRIB_KEY_LENGTH, keylen, a);
338 return a;
341 struct isakmp_payload *make_our_sa_ike(void)
343 struct isakmp_payload *r = new_isakmp_payload(ISAKMP_PAYLOAD_SA);
344 struct isakmp_payload *t = NULL, *tn;
345 struct isakmp_attribute *a;
346 int dh_grp = get_dh_group_ike()->ike_sa_id;
347 unsigned int crypt, hash, keylen;
348 int i;
350 r->u.sa.doi = ISAKMP_DOI_IPSEC;
351 r->u.sa.situation = ISAKMP_IPSEC_SIT_IDENTITY_ONLY;
352 r->u.sa.proposals = new_isakmp_payload(ISAKMP_PAYLOAD_P);
353 r->u.sa.proposals->u.p.prot_id = ISAKMP_IPSEC_PROTO_ISAKMP;
354 for (crypt = 0; supp_crypt[crypt].name != NULL; crypt++) {
355 if ((supp_crypt[crypt].my_id == GCRY_CIPHER_DES) && (opt_1des == 0))
356 continue;
357 keylen = supp_crypt[crypt].keylen;
358 for (hash = 0; supp_hash[hash].name != NULL; hash++) {
359 tn = t;
360 t = new_isakmp_payload(ISAKMP_PAYLOAD_T);
361 t->u.t.id = ISAKMP_IPSEC_KEY_IKE;
362 a = make_transform_ike(dh_grp, supp_crypt[crypt].ike_sa_id,
363 supp_hash[hash].ike_sa_id, keylen);
364 t->u.t.attributes = a;
365 t->next = tn;
368 for (i = 0, tn = t; tn; tn = tn->next)
369 tn->u.t.number = i++;
370 r->u.sa.proposals->u.p.transforms = t;
371 return r;
374 struct sa_block {
375 uint8_t i_cookie[ISAKMP_COOKIE_LENGTH];
376 uint8_t r_cookie[ISAKMP_COOKIE_LENGTH];
377 uint8_t *key;
378 int keylen;
379 uint8_t *initial_iv;
380 uint8_t *skeyid_a;
381 uint8_t *skeyid_d;
382 int cry_algo, ivlen;
383 int md_algo, md_len;
384 uint8_t current_iv_msgid[4];
385 uint8_t *current_iv;
386 uint8_t our_address[4], our_netmask[4];
387 uint32_t tous_esp_spi, tothem_esp_spi;
388 uint8_t *kill_packet;
389 size_t kill_packet_size;
390 int do_pfs;
393 void isakmp_crypt(struct sa_block *s, uint8_t * block, size_t blocklen, int enc)
395 unsigned char *new_iv;
396 gcry_cipher_hd_t cry_ctx;
398 if (blocklen < ISAKMP_PAYLOAD_O || ((blocklen - ISAKMP_PAYLOAD_O) % s->ivlen != 0))
399 abort();
401 if ((memcmp(block + ISAKMP_MESSAGE_ID_O, s->current_iv_msgid, 4) != 0) && (enc >= 0)) {
402 unsigned char *iv;
403 gcry_md_hd_t md_ctx;
405 gcry_md_open(&md_ctx, s->md_algo, 0);
406 gcry_md_write(md_ctx, s->initial_iv, s->ivlen);
407 gcry_md_write(md_ctx, block + ISAKMP_MESSAGE_ID_O, 4);
408 gcry_md_final(md_ctx);
409 iv = gcry_md_read(md_ctx, 0);
410 memcpy(s->current_iv, iv, s->ivlen);
411 memcpy(s->current_iv_msgid, block + ISAKMP_MESSAGE_ID_O, 4);
412 gcry_md_close(md_ctx);
415 new_iv = xallocc(s->ivlen);
416 gcry_cipher_open(&cry_ctx, s->cry_algo, GCRY_CIPHER_MODE_CBC, 0);
417 gcry_cipher_setkey(cry_ctx, s->key, s->keylen);
418 gcry_cipher_setiv(cry_ctx, s->current_iv, s->ivlen);
419 if (!enc) {
420 memcpy(new_iv, block + blocklen - s->ivlen, s->ivlen);
421 gcry_cipher_decrypt(cry_ctx, block + ISAKMP_PAYLOAD_O, blocklen - ISAKMP_PAYLOAD_O,
422 NULL, 0);
423 memcpy(s->current_iv, new_iv, s->ivlen);
424 } else { /* enc == -1 (no longer used) || enc == 1 */
425 gcry_cipher_encrypt(cry_ctx, block + ISAKMP_PAYLOAD_O, blocklen - ISAKMP_PAYLOAD_O,
426 NULL, 0);
427 if (enc > 0)
428 memcpy(s->current_iv, block + blocklen - s->ivlen, s->ivlen);
430 gcry_cipher_close(cry_ctx);
434 static uint8_t r_packet[2048];
435 static ssize_t r_length;
437 void do_phase_1(const char *key_id, const char *shared_key, struct sa_block *d)
439 unsigned char i_nonce[20];
440 struct group *dh_grp;
441 unsigned char *dh_public;
442 unsigned char *returned_hash;
443 static const uint8_t xauth_vid[] = XAUTH_VENDOR_ID;
444 static const uint8_t unity_vid[] = UNITY_VENDOR_ID;
445 static const uint8_t unknown_vid[] = UNKNOWN_VENDOR_ID;
446 #if 0
447 static const uint8_t dpd_vid[] = UNITY_VENDOR_ID;
448 static const uint8_t my_vid[] = {
449 0x35, 0x53, 0x07, 0x6c, 0x4f, 0x65, 0x12, 0x68, 0x02, 0x82, 0xf2, 0x15,
450 0x8a, 0xa8, 0xa0, 0x9e
452 #endif
454 struct isakmp_packet *p1;
456 DEBUG(2, printf("S4.1\n"));
457 gcry_randomize(d->i_cookie, ISAKMP_COOKIE_LENGTH, GCRY_STRONG_RANDOM);
458 d->do_pfs = -1;
459 if (d->i_cookie[0] == 0)
460 d->i_cookie[0] = 1;
461 hex_dump("i_cookie", d->i_cookie, ISAKMP_COOKIE_LENGTH);
462 gcry_randomize(i_nonce, sizeof(i_nonce), GCRY_STRONG_RANDOM);
463 hex_dump("i_nonce", i_nonce, sizeof(i_nonce));
464 DEBUG(2, printf("S4.2\n"));
465 /* Set up the Diffie-Hellman stuff. */
467 dh_grp = group_get(get_dh_group_ike()->my_id);
468 dh_public = xallocc(dh_getlen(dh_grp));
469 dh_create_exchange(dh_grp, dh_public);
470 hex_dump("dh_public", dh_public, dh_getlen(dh_grp));
473 DEBUG(2, printf("S4.3\n"));
474 /* Create the first packet. */
476 struct isakmp_payload *l;
477 uint8_t *pkt;
478 size_t pkt_len;
480 p1 = new_isakmp_packet();
481 memcpy(p1->i_cookie, d->i_cookie, ISAKMP_COOKIE_LENGTH);
482 p1->isakmp_version = ISAKMP_VERSION;
483 p1->exchange_type = ISAKMP_EXCHANGE_AGGRESSIVE;
484 p1->payload = l = make_our_sa_ike();
485 l->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_KE, dh_public, dh_getlen(dh_grp));
486 l->next->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_NONCE,
487 i_nonce, sizeof(i_nonce));
488 l = l->next->next;
489 l->next = new_isakmp_payload(ISAKMP_PAYLOAD_ID);
490 l = l->next;
491 l->u.id.type = ISAKMP_IPSEC_ID_KEY_ID;
492 l->u.id.protocol = IPPROTO_UDP;
493 l->u.id.port = 500; /*TODO: get local port */
494 l->u.id.length = strlen(key_id);
495 l->u.id.data = xallocc(l->u.id.length);
496 memcpy(l->u.id.data, key_id, strlen(key_id));
497 l->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_VID, xauth_vid, sizeof(xauth_vid));
498 l->next->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_VID,
499 unity_vid, sizeof(unity_vid));
500 #if 0
501 l->next->next->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_VID,
502 dpd_vid, sizeof(dpd_vid));
503 #endif
504 flatten_isakmp_packet(p1, &pkt, &pkt_len, 0);
506 /* Now, send that packet and receive a new one. */
507 r_length = sendrecv(r_packet, sizeof(r_packet), pkt, pkt_len, 0);
508 free(pkt);
510 DEBUG(2, printf("S4.4\n"));
511 /* Decode the recieved packet. */
513 struct isakmp_packet *r;
514 uint16_t reject;
515 struct isakmp_payload *rp;
516 struct isakmp_payload *nonce = NULL;
517 struct isakmp_payload *ke = NULL;
518 struct isakmp_payload *hash = NULL;
519 struct isakmp_payload *idp = NULL;
520 int seen_xauth_vid = 0;
521 unsigned char *skeyid;
522 gcry_md_hd_t skeyid_ctx;
524 reject = 0;
525 r = parse_isakmp_packet(r_packet, r_length, &reject);
527 /* Verify the correctness of the recieved packet. */
528 if (reject == 0 && memcmp(r->i_cookie, d->i_cookie, ISAKMP_COOKIE_LENGTH) != 0)
529 reject = ISAKMP_N_INVALID_COOKIE;
530 if (reject == 0)
531 memcpy(d->r_cookie, r->r_cookie, ISAKMP_COOKIE_LENGTH);
532 if (reject == 0 && r->exchange_type != ISAKMP_EXCHANGE_AGGRESSIVE)
533 reject = ISAKMP_N_INVALID_EXCHANGE_TYPE;
534 if (reject == 0 && r->flags != 0)
535 reject = ISAKMP_N_INVALID_FLAGS;
536 if (reject == 0 && r->message_id != 0)
537 reject = ISAKMP_N_INVALID_MESSAGE_ID;
538 if (reject != 0)
539 error(1, 0, "response was invalid [1]: %s", isakmp_notify_to_error(reject));
540 for (rp = r->payload; rp && reject == 0; rp = rp->next)
541 switch (rp->type) {
542 case ISAKMP_PAYLOAD_SA:
543 if (reject == 0 && rp->u.sa.doi != ISAKMP_DOI_IPSEC)
544 reject = ISAKMP_N_DOI_NOT_SUPPORTED;
545 if (reject == 0 &&
546 rp->u.sa.situation != ISAKMP_IPSEC_SIT_IDENTITY_ONLY)
547 reject = ISAKMP_N_SITUATION_NOT_SUPPORTED;
548 if (reject == 0 &&
549 (rp->u.sa.proposals == NULL
550 || rp->u.sa.proposals->next != NULL))
551 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
552 if (reject == 0 &&
553 rp->u.sa.proposals->u.p.prot_id !=
554 ISAKMP_IPSEC_PROTO_ISAKMP)
555 reject = ISAKMP_N_INVALID_PROTOCOL_ID;
556 if (reject == 0 && rp->u.sa.proposals->u.p.spi_size != 0)
557 reject = ISAKMP_N_INVALID_SPI;
558 if (reject == 0 &&
559 (rp->u.sa.proposals->u.p.transforms == NULL
560 || rp->u.sa.proposals->u.p.transforms->next !=
561 NULL))
562 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
563 if (reject == 0 &&
564 (rp->u.sa.proposals->u.p.transforms->u.t.id
565 != ISAKMP_IPSEC_KEY_IKE))
566 reject = ISAKMP_N_INVALID_TRANSFORM_ID;
567 if (reject == 0) {
568 struct isakmp_attribute *a
570 rp->u.sa.proposals->u.p.transforms->u.t.attributes;
571 int seen_enc = 0, seen_hash = 0, seen_auth = 0;
572 int seen_group = 0, seen_keylen = 0;
573 for (; a && reject == 0; a = a->next)
574 switch (a->type) {
575 case IKE_ATTRIB_GROUP_DESC:
576 if (a->af == isakmp_attr_16 &&
577 a->u.attr_16 ==
578 get_dh_group_ike()->ike_sa_id)
579 seen_group = 1;
580 else
581 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
582 break;
583 case IKE_ATTRIB_AUTH_METHOD:
584 if (a->af == isakmp_attr_16 &&
585 a->u.attr_16 ==
586 XAUTH_AUTH_XAUTHInitPreShared)
587 seen_auth = 1;
588 else
589 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
590 break;
591 case IKE_ATTRIB_HASH:
592 if (a->af == isakmp_attr_16)
593 seen_hash = a->u.attr_16;
594 else
595 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
596 break;
597 case IKE_ATTRIB_ENC:
598 if (a->af == isakmp_attr_16)
599 seen_enc = a->u.attr_16;
600 else
601 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
602 break;
603 case IKE_ATTRIB_KEY_LENGTH:
604 if (a->af == isakmp_attr_16)
605 seen_keylen = a->u.attr_16;
606 else
607 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
608 break;
609 case IKE_ATTRIB_LIFE_TYPE:
610 case IKE_ATTRIB_LIFE_DURATION:
611 break;
612 default:
613 DEBUG(1, printf
614 ("unknown attribute %d, arborting..\n",
615 a->type));
616 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
617 break;
619 if (!seen_group || !seen_auth || !seen_hash || !seen_enc)
620 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
622 if (get_algo(SUPP_ALGO_HASH, SUPP_ALGO_IKE_SA, seen_hash,
623 NULL, 0) == NULL)
624 reject = ISAKMP_N_NO_PROPOSAL_CHOSEN;
625 if (get_algo(SUPP_ALGO_CRYPT, SUPP_ALGO_IKE_SA, seen_enc,
626 NULL, seen_keylen) == NULL)
627 reject = ISAKMP_N_NO_PROPOSAL_CHOSEN;
629 if (reject == 0) {
630 d->cry_algo =
631 get_algo(SUPP_ALGO_CRYPT, SUPP_ALGO_IKE_SA,
632 seen_enc, NULL, seen_keylen)->my_id;
633 d->md_algo =
634 get_algo(SUPP_ALGO_HASH, SUPP_ALGO_IKE_SA,
635 seen_hash, NULL, 0)->my_id;
636 DEBUG(1, printf("IKE SA selected %s-%s\n",
637 get_algo(SUPP_ALGO_CRYPT,
638 SUPP_ALGO_IKE_SA, seen_enc,
639 NULL, seen_keylen)->name,
640 get_algo(SUPP_ALGO_HASH,
641 SUPP_ALGO_IKE_SA, seen_hash,
642 NULL, 0)->name));
645 break;
647 case ISAKMP_PAYLOAD_ID:
648 idp = rp;
649 break;
650 case ISAKMP_PAYLOAD_KE:
651 ke = rp;
652 break;
653 case ISAKMP_PAYLOAD_NONCE:
654 nonce = rp;
655 break;
656 case ISAKMP_PAYLOAD_HASH:
657 hash = rp;
658 break;
659 case ISAKMP_PAYLOAD_VID:
660 if (rp->u.vid.length == sizeof(xauth_vid)
661 && memcmp(rp->u.vid.data, xauth_vid,
662 sizeof(xauth_vid)) == 0)
663 seen_xauth_vid = 1;
664 break;
665 default:
666 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
667 break;
670 if (reject == 0) {
671 d->md_len = gcry_md_get_algo_dlen(d->md_algo);
672 gcry_cipher_algo_info(d->cry_algo, GCRYCTL_GET_BLKLEN, NULL, &(d->ivlen));
673 gcry_cipher_algo_info(d->cry_algo, GCRYCTL_GET_KEYLEN, NULL, &(d->keylen));
676 if (reject == 0 && (ke == NULL || ke->u.ke.length != dh_getlen(dh_grp)))
677 reject = ISAKMP_N_INVALID_KEY_INFORMATION;
678 if (reject == 0 && nonce == NULL)
679 reject = ISAKMP_N_INVALID_HASH_INFORMATION;
680 if (reject != 0)
681 error(1, 0, "response was invalid [2]: %s", isakmp_notify_to_error(reject));
682 if (reject == 0 && idp == NULL)
683 reject = ISAKMP_N_INVALID_ID_INFORMATION;
684 if (reject == 0 && (hash == NULL || hash->u.hash.length != d->md_len))
685 reject = ISAKMP_N_INVALID_HASH_INFORMATION;
686 if (reject != 0)
687 error(1, 0, "response was invalid [3]: %s", isakmp_notify_to_error(reject));
689 /* Generate SKEYID. */
691 gcry_md_open(&skeyid_ctx, d->md_algo, GCRY_MD_FLAG_HMAC);
692 gcry_md_setkey(skeyid_ctx, shared_key, strlen(shared_key));
693 gcry_md_write(skeyid_ctx, i_nonce, sizeof(i_nonce));
694 gcry_md_write(skeyid_ctx, nonce->u.nonce.data, nonce->u.nonce.length);
695 gcry_md_final(skeyid_ctx);
696 skeyid = gcry_md_read(skeyid_ctx, 0);
697 hex_dump("skeyid", skeyid, d->md_len);
700 /* Verify the hash. */
702 gcry_md_hd_t hm;
703 unsigned char *expected_hash;
704 uint8_t *sa_f, *idi_f, *idp_f;
705 size_t sa_size, idi_size, idp_size;
706 struct isakmp_payload *sa, *idi;
708 sa = p1->payload;
709 for (idi = sa; idi->type != ISAKMP_PAYLOAD_ID; idi = idi->next) ;
710 sa->next = NULL;
711 idi->next = NULL;
712 idp->next = NULL;
713 flatten_isakmp_payload(sa, &sa_f, &sa_size);
714 flatten_isakmp_payload(idi, &idi_f, &idi_size);
715 flatten_isakmp_payload(idp, &idp_f, &idp_size);
717 gcry_md_open(&hm, d->md_algo, GCRY_MD_FLAG_HMAC);
718 gcry_md_setkey(hm, skeyid, d->md_len);
719 gcry_md_write(hm, ke->u.ke.data, ke->u.ke.length);
720 gcry_md_write(hm, dh_public, dh_getlen(dh_grp));
721 gcry_md_write(hm, d->r_cookie, ISAKMP_COOKIE_LENGTH);
722 gcry_md_write(hm, d->i_cookie, ISAKMP_COOKIE_LENGTH);
723 gcry_md_write(hm, sa_f + 4, sa_size - 4);
724 gcry_md_write(hm, idp_f + 4, idp_size - 4);
725 gcry_md_final(hm);
726 expected_hash = gcry_md_read(hm, 0);
728 if (memcmp(expected_hash, hash->u.hash.data, d->md_len) != 0) {
729 error(1, 0, "hash comparison failed: %s\ncheck group password!",
730 isakmp_notify_to_error(ISAKMP_N_AUTHENTICATION_FAILED));
732 gcry_md_close(hm);
734 gcry_md_open(&hm, d->md_algo, GCRY_MD_FLAG_HMAC);
735 gcry_md_setkey(hm, skeyid, d->md_len);
736 gcry_md_write(hm, dh_public, dh_getlen(dh_grp));
737 gcry_md_write(hm, ke->u.ke.data, ke->u.ke.length);
738 gcry_md_write(hm, d->i_cookie, ISAKMP_COOKIE_LENGTH);
739 gcry_md_write(hm, d->r_cookie, ISAKMP_COOKIE_LENGTH);
740 gcry_md_write(hm, sa_f + 4, sa_size - 4);
741 gcry_md_write(hm, idi_f + 4, idi_size - 4);
742 gcry_md_final(hm);
743 returned_hash = xallocc(d->md_len);
744 memcpy(returned_hash, gcry_md_read(hm, 0), d->md_len);
745 gcry_md_close(hm);
746 hex_dump("returned_hash", returned_hash, d->md_len);
748 free(sa_f);
749 free(idi);
750 free(idp);
753 /* Determine all the SKEYID_x keys. */
755 gcry_md_hd_t hm;
756 int i;
757 static const unsigned char c012[3] = { 0, 1, 2 };
758 unsigned char *skeyid_e;
759 unsigned char *dh_shared_secret;
761 /* Determine the shared secret. */
762 dh_shared_secret = xallocc(dh_getlen(dh_grp));
763 dh_create_shared(dh_grp, dh_shared_secret, ke->u.ke.data);
764 hex_dump("dh_shared_secret", dh_shared_secret, dh_getlen(dh_grp));
766 gcry_md_open(&hm, d->md_algo, GCRY_MD_FLAG_HMAC);
767 gcry_md_setkey(hm, skeyid, d->md_len);
768 gcry_md_write(hm, dh_shared_secret, dh_getlen(dh_grp));
769 gcry_md_write(hm, d->i_cookie, ISAKMP_COOKIE_LENGTH);
770 gcry_md_write(hm, d->r_cookie, ISAKMP_COOKIE_LENGTH);
771 gcry_md_write(hm, c012 + 0, 1);
772 gcry_md_final(hm);
773 d->skeyid_d = xallocc(d->md_len);
774 memcpy(d->skeyid_d, gcry_md_read(hm, 0), d->md_len);
775 gcry_md_close(hm);
776 hex_dump("skeyid_d", d->skeyid_d, d->md_len);
778 gcry_md_open(&hm, d->md_algo, GCRY_MD_FLAG_HMAC);
779 gcry_md_setkey(hm, skeyid, d->md_len);
780 gcry_md_write(hm, d->skeyid_d, d->md_len);
781 gcry_md_write(hm, dh_shared_secret, dh_getlen(dh_grp));
782 gcry_md_write(hm, d->i_cookie, ISAKMP_COOKIE_LENGTH);
783 gcry_md_write(hm, d->r_cookie, ISAKMP_COOKIE_LENGTH);
784 gcry_md_write(hm, c012 + 1, 1);
785 gcry_md_final(hm);
786 d->skeyid_a = xallocc(d->md_len);
787 memcpy(d->skeyid_a, gcry_md_read(hm, 0), d->md_len);
788 gcry_md_close(hm);
789 hex_dump("skeyid_a", d->skeyid_a, d->md_len);
791 gcry_md_open(&hm, d->md_algo, GCRY_MD_FLAG_HMAC);
792 gcry_md_setkey(hm, skeyid, d->md_len);
793 gcry_md_write(hm, d->skeyid_a, d->md_len);
794 gcry_md_write(hm, dh_shared_secret, dh_getlen(dh_grp));
795 gcry_md_write(hm, d->i_cookie, ISAKMP_COOKIE_LENGTH);
796 gcry_md_write(hm, d->r_cookie, ISAKMP_COOKIE_LENGTH);
797 gcry_md_write(hm, c012 + 2, 1);
798 gcry_md_final(hm);
799 skeyid_e = xallocc(d->md_len);
800 memcpy(skeyid_e, gcry_md_read(hm, 0), d->md_len);
801 gcry_md_close(hm);
802 hex_dump("skeyid_e", skeyid_e, d->md_len);
804 memset(dh_shared_secret, 0, sizeof(dh_shared_secret));
806 /* Determine the IKE encryption key. */
807 d->key = xallocc(d->keylen);
809 if (d->keylen > d->md_len) {
810 for (i = 0; i * d->md_len < d->keylen; i++) {
811 gcry_md_open(&hm, d->md_algo, GCRY_MD_FLAG_HMAC);
812 gcry_md_setkey(hm, skeyid_e, d->md_len);
813 if (i == 0)
814 gcry_md_write(hm, "" /* &'\0' */ , 1);
815 else
816 gcry_md_write(hm, d->key + (i - 1) * d->md_len,
817 d->md_len);
818 gcry_md_final(hm);
819 memcpy(d->key + i * d->md_len, gcry_md_read(hm, 0),
820 min(d->md_len, d->keylen - i * d->md_len));
821 gcry_md_close(hm);
823 } else { /* keylen <= md_len */
824 memcpy(d->key, skeyid_e, d->keylen);
826 hex_dump("enc-key", d->key, d->keylen);
828 memset(skeyid_e, 0, d->md_len);
831 /* Determine the initial 3DES IV. */
833 gcry_md_hd_t hm;
835 assert(d->ivlen < d->md_len);
836 gcry_md_open(&hm, d->md_algo, 0);
837 gcry_md_write(hm, dh_public, dh_getlen(dh_grp));
838 gcry_md_write(hm, ke->u.ke.data, ke->u.ke.length);
839 gcry_md_final(hm);
840 d->current_iv = xallocc(d->ivlen);
841 memcpy(d->current_iv, gcry_md_read(hm, 0), d->ivlen);
842 gcry_md_close(hm);
843 hex_dump("current_iv", d->current_iv, d->ivlen);
844 memset(d->current_iv_msgid, 0, 4);
847 gcry_md_close(skeyid_ctx);
850 DEBUG(2, printf("S4.5\n"));
851 /* Send final phase 1 packet. */
853 struct isakmp_packet *p2;
854 uint8_t *p2kt;
855 size_t p2kt_len;
856 struct isakmp_payload *pl;
858 p2 = new_isakmp_packet();
859 memcpy(p2->i_cookie, d->i_cookie, ISAKMP_COOKIE_LENGTH);
860 memcpy(p2->r_cookie, d->r_cookie, ISAKMP_COOKIE_LENGTH);
861 p2->flags = ISAKMP_FLAG_E;
862 p2->isakmp_version = ISAKMP_VERSION;
863 p2->exchange_type = ISAKMP_EXCHANGE_AGGRESSIVE;
864 p2->payload = new_isakmp_data_payload(ISAKMP_PAYLOAD_HASH,
865 returned_hash, d->md_len);
866 p2->payload->next = pl = new_isakmp_payload(ISAKMP_PAYLOAD_N);
867 pl->u.n.doi = ISAKMP_DOI_IPSEC;
868 pl->u.n.protocol = ISAKMP_IPSEC_PROTO_ISAKMP;
869 pl->u.n.type = ISAKMP_N_IPSEC_INITIAL_CONTACT;
870 pl->u.n.spi_length = 2 * ISAKMP_COOKIE_LENGTH;
871 pl->u.n.spi = xallocc(2 * ISAKMP_COOKIE_LENGTH);
872 memcpy(pl->u.n.spi + ISAKMP_COOKIE_LENGTH * 0, d->i_cookie, ISAKMP_COOKIE_LENGTH);
873 memcpy(pl->u.n.spi + ISAKMP_COOKIE_LENGTH * 1, d->r_cookie, ISAKMP_COOKIE_LENGTH);
874 pl->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_VID,
875 unknown_vid, sizeof(unknown_vid));
876 pl->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_VID,
877 unity_vid, sizeof(unity_vid));
878 flatten_isakmp_packet(p2, &p2kt, &p2kt_len, d->ivlen);
879 free_isakmp_packet(p2);
880 isakmp_crypt(d, p2kt, p2kt_len, 1);
882 d->initial_iv = xallocc(d->ivlen);
883 memcpy(d->initial_iv, d->current_iv, d->ivlen);
884 hex_dump("initial_iv", d->initial_iv, d->ivlen);
886 /* Now, send that packet and receive a new one. */
887 r_length = sendrecv(r_packet, sizeof(r_packet), p2kt, p2kt_len, 0);
888 free(p2kt);
890 DEBUG(2, printf("S4.6\n"));
892 free(returned_hash);
895 static uint16_t
896 unpack_verify_phase2(struct sa_block *s,
897 uint8_t * r_packet,
898 size_t r_length, struct isakmp_packet **r_p, const uint8_t * nonce, size_t nonce_size)
900 struct isakmp_packet *r;
901 uint16_t reject = 0;
903 *r_p = NULL;
905 if (r_length < ISAKMP_PAYLOAD_O || ((r_length - ISAKMP_PAYLOAD_O) % s->ivlen != 0))
906 return ISAKMP_N_UNEQUAL_PAYLOAD_LENGTHS;
908 isakmp_crypt(s, r_packet, r_length, 0);
911 r = parse_isakmp_packet(r_packet, r_length, &reject);
912 if (reject != 0)
913 return reject;
916 /* Verify the basic stuff. */
917 if (memcmp(r->i_cookie, s->i_cookie, ISAKMP_COOKIE_LENGTH) != 0
918 || memcmp(r->r_cookie, s->r_cookie, ISAKMP_COOKIE_LENGTH) != 0)
919 return ISAKMP_N_INVALID_COOKIE;
920 if (r->flags != ISAKMP_FLAG_E)
921 return ISAKMP_N_INVALID_FLAGS;
924 size_t sz, spos;
925 gcry_md_hd_t hm;
926 unsigned char *expected_hash;
927 struct isakmp_payload *h = r->payload;
929 if (h == NULL || h->type != ISAKMP_PAYLOAD_HASH || h->u.hash.length != s->md_len)
930 return ISAKMP_N_INVALID_HASH_INFORMATION;
932 spos = (ISAKMP_PAYLOAD_O + (r_packet[ISAKMP_PAYLOAD_O + 2] << 8)
933 + r_packet[ISAKMP_PAYLOAD_O + 3]);
935 /* Compute the real length based on the payload lengths. */
936 for (sz = spos; r_packet[sz] != 0; sz += r_packet[sz + 2] << 8 | r_packet[sz + 3]) ;
937 sz += r_packet[sz + 2] << 8 | r_packet[sz + 3];
939 gcry_md_open(&hm, s->md_algo, GCRY_MD_FLAG_HMAC);
940 gcry_md_setkey(hm, s->skeyid_a, s->md_len);
941 gcry_md_write(hm, r_packet + ISAKMP_MESSAGE_ID_O, 4);
942 if (nonce)
943 gcry_md_write(hm, nonce, nonce_size);
944 gcry_md_write(hm, r_packet + spos, sz - spos);
945 gcry_md_final(hm);
946 expected_hash = gcry_md_read(hm, 0);
948 if (opt_debug >= 3) {
949 printf("hashlen: %d\n", s->md_len);
950 printf("u.hash.length: %d\n", h->u.hash.length);
951 hex_dump("expected_hash", expected_hash, s->md_len);
952 hex_dump("h->u.hash.data", h->u.hash.data, s->md_len);
955 reject = 0;
956 if (memcmp(h->u.hash.data, expected_hash, s->md_len) != 0)
957 reject = ISAKMP_N_AUTHENTICATION_FAILED;
958 gcry_md_close(hm);
959 #if 0
960 if (reject != 0)
961 return reject;
962 #endif
964 *r_p = r;
965 return 0;
968 static void
969 phase2_authpacket(struct sa_block *s, struct isakmp_payload *pl,
970 uint8_t exchange_type, uint32_t msgid,
971 uint8_t ** p_flat, size_t * p_size,
972 uint8_t * nonce_i, int ni_len, uint8_t * nonce_r, int nr_len)
974 struct isakmp_packet *p;
975 uint8_t *pl_flat;
976 size_t pl_size;
977 gcry_md_hd_t hm;
978 uint8_t msgid_sent[4];
980 /* Build up the packet. */
981 p = new_isakmp_packet();
982 memcpy(p->i_cookie, s->i_cookie, ISAKMP_COOKIE_LENGTH);
983 memcpy(p->r_cookie, s->r_cookie, ISAKMP_COOKIE_LENGTH);
984 p->flags = ISAKMP_FLAG_E;
985 p->isakmp_version = ISAKMP_VERSION;
986 p->exchange_type = exchange_type;
987 p->message_id = msgid;
988 p->payload = new_isakmp_payload(ISAKMP_PAYLOAD_HASH);
989 p->payload->next = pl;
990 p->payload->u.hash.length = s->md_len;
991 p->payload->u.hash.data = xallocc(s->md_len);
993 /* Set the MAC. */
994 gcry_md_open(&hm, s->md_algo, GCRY_MD_FLAG_HMAC);
995 gcry_md_setkey(hm, s->skeyid_a, s->md_len);
997 if (pl == NULL) {
998 DEBUG(3, printf("authing NULL package!\n"));
999 gcry_md_write(hm, "" /* \0 */ , 1);
1002 msgid_sent[0] = msgid >> 24;
1003 msgid_sent[1] = msgid >> 16;
1004 msgid_sent[2] = msgid >> 8;
1005 msgid_sent[3] = msgid;
1006 gcry_md_write(hm, msgid_sent, sizeof(msgid_sent));
1008 if (nonce_i != NULL)
1009 gcry_md_write(hm, nonce_i, ni_len);
1011 if (nonce_r != NULL)
1012 gcry_md_write(hm, nonce_r, nr_len);
1014 if (pl != NULL) {
1015 flatten_isakmp_payload(pl, &pl_flat, &pl_size);
1016 gcry_md_write(hm, pl_flat, pl_size);
1017 memset(pl_flat, 0, pl_size);
1018 free(pl_flat);
1021 gcry_md_final(hm);
1022 memcpy(p->payload->u.hash.data, gcry_md_read(hm, 0), s->md_len);
1023 gcry_md_close(hm);
1025 flatten_isakmp_packet(p, p_flat, p_size, s->ivlen);
1026 free_isakmp_packet(p);
1029 static void
1030 sendrecv_phase2(struct sa_block *s, struct isakmp_payload *pl,
1031 uint8_t exchange_type, uint32_t msgid, int sendonly, uint8_t reply_extype,
1032 uint8_t ** save_p_flat, size_t * save_p_size,
1033 uint8_t * nonce_i, int ni_len, uint8_t * nonce_r, int nr_len)
1035 uint8_t *p_flat;
1036 size_t p_size;
1038 if ((save_p_flat == NULL) || (*save_p_flat == NULL)) {
1039 phase2_authpacket(s, pl, exchange_type, msgid, &p_flat, &p_size,
1040 nonce_i, ni_len, nonce_r, nr_len);
1041 isakmp_crypt(s, p_flat, p_size, 1);
1042 } else {
1043 p_flat = *save_p_flat;
1044 p_size = *save_p_size;
1047 if (!sendonly)
1048 r_length = sendrecv(r_packet, sizeof(r_packet), p_flat, p_size, reply_extype);
1049 else {
1050 if (sendto(sockfd, p_flat, p_size, 0,
1051 dest_addr, sizeof(struct sockaddr_in)) != (int)p_size
1052 && sendonly == 1)
1053 error(1, errno, "can't send packet");
1055 if (save_p_flat == NULL) {
1056 free(p_flat);
1057 } else {
1058 *save_p_flat = p_flat;
1059 *save_p_size = p_size;
1063 static void phase2_fatal(struct sa_block *s, const char *msg, uint16_t id)
1065 struct isakmp_payload *pl;
1066 uint32_t msgid;
1068 DEBUG(1, printf("\n\n---!!!!!!!!! entering phase2_fatal !!!!!!!!!---\n\n\n"));
1069 gcry_randomize((uint8_t *) & msgid, sizeof(msgid), GCRY_WEAK_RANDOM);
1070 pl = new_isakmp_payload(ISAKMP_PAYLOAD_N);
1071 pl->u.n.doi = ISAKMP_DOI_IPSEC;
1072 pl->u.n.protocol = ISAKMP_IPSEC_PROTO_ISAKMP;
1073 pl->u.n.type = id;
1074 sendrecv_phase2(s, pl, ISAKMP_EXCHANGE_INFORMATIONAL, msgid, 2, 0, 0, 0, 0, 0, 0, 0);
1076 gcry_randomize((uint8_t *) & msgid, sizeof(msgid), GCRY_WEAK_RANDOM);
1077 pl = new_isakmp_payload(ISAKMP_PAYLOAD_D);
1078 pl->u.d.doi = ISAKMP_DOI_IPSEC;
1079 pl->u.d.protocol = ISAKMP_IPSEC_PROTO_ISAKMP;
1080 pl->u.d.spi_length = 2 * ISAKMP_COOKIE_LENGTH;
1081 pl->u.d.num_spi = 1;
1082 pl->u.d.spi = xallocc(1 * sizeof(uint8_t *));
1083 pl->u.d.spi[0] = xallocc(2 * ISAKMP_COOKIE_LENGTH);
1084 memcpy(pl->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 0, s->i_cookie, ISAKMP_COOKIE_LENGTH);
1085 memcpy(pl->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 1, s->r_cookie, ISAKMP_COOKIE_LENGTH);
1086 sendrecv_phase2(s, pl, ISAKMP_EXCHANGE_INFORMATIONAL, msgid, 2, 0, 0, 0, 0, 0, 0, 0);
1088 error(1, 0, msg, isakmp_notify_to_error(id));
1091 static int do_phase_2_xauth(struct sa_block *s)
1093 struct isakmp_packet *r;
1094 int loopcount;
1096 DEBUG(2, printf("S5.1\n"));
1097 /* This can go around for a while. */
1098 for (loopcount = 0;; loopcount++) {
1099 uint16_t reject;
1100 struct isakmp_payload *rp;
1101 struct isakmp_attribute *a, *ap, *reply_attr;
1102 char ntop_buf[32];
1103 int seen_answer = 0;
1105 DEBUG(2, printf("S5.2\n"));
1106 reject = unpack_verify_phase2(s, r_packet, r_length, &r, NULL, 0);
1107 if (reject == ISAKMP_N_PAYLOAD_MALFORMED) {
1108 r_length = sendrecv(r_packet, sizeof(r_packet), NULL, 0, 0);
1109 continue;
1112 /* check for notices */
1113 if (reject == 0 &&
1114 r->exchange_type == ISAKMP_EXCHANGE_INFORMATIONAL &&
1115 r->payload->next != NULL && r->payload->next->type == ISAKMP_PAYLOAD_N) {
1116 if (r->payload->next->u.n.type == ISAKMP_N_CISCO_LOAD_BALANCE) {
1117 /* load balancing notice ==> restart with new gw */
1118 if (r->payload->next->u.n.data_length != 4)
1119 error(1, 0, "malformed loadbalance target");
1120 memcpy(&((struct sockaddr_in *)dest_addr)->sin_addr,
1121 r->payload->next->u.n.data, 4);
1122 DEBUG(2, printf("got cisco loadbalancing notice, diverting to %s\n",
1123 inet_ntoa(((struct sockaddr_in *)dest_addr)->
1124 sin_addr)));
1125 return 1;
1127 if (r->payload->next->u.n.type == ISAKMP_N_IPSEC_RESPONDER_LIFETIME) {
1128 /* responder liftime notice ==> ignore */
1129 DEBUG(2, printf("got responder liftime notice, ignoring..\n"));
1130 r_length = sendrecv(r_packet, sizeof(r_packet), NULL, 0, 0);
1131 continue;
1135 DEBUG(2, printf("S5.3\n"));
1136 /* Check the transaction type is OK. */
1137 if (reject == 0 && r->exchange_type != ISAKMP_EXCHANGE_MODECFG_TRANSACTION)
1138 reject = ISAKMP_N_INVALID_EXCHANGE_TYPE;
1140 /* After the hash, expect an attribute block. */
1141 if (reject == 0
1142 && (r->payload->next == NULL
1143 || r->payload->next->next != NULL
1144 || r->payload->next->type != ISAKMP_PAYLOAD_MODECFG_ATTR))
1145 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
1147 if (reject == 0 && r->payload->next->u.modecfg.type == ISAKMP_MODECFG_CFG_SET)
1148 break;
1149 if (reject == 0 && r->payload->next->u.modecfg.type != ISAKMP_MODECFG_CFG_REQUEST)
1150 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
1152 if (reject != 0)
1153 phase2_fatal(s, "expected xauth packet; rejected: %s", reject);
1155 DEBUG(2, printf("S5.4\n"));
1156 a = r->payload->next->u.modecfg.attributes;
1157 /* First, print any messages, and verify that we understand the
1158 * conversation. */
1159 for (ap = a; ap && seen_answer == 0; ap = ap->next)
1160 if (ap->type == ISAKMP_XAUTH_ATTRIB_ANSWER)
1161 seen_answer = 1;
1163 for (ap = a; ap && reject == 0; ap = ap->next)
1164 switch (ap->type) {
1165 case ISAKMP_XAUTH_ATTRIB_TYPE:
1166 if (ap->af != isakmp_attr_16 || ap->u.attr_16 != 0)
1167 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1168 break;
1169 case ISAKMP_XAUTH_ATTRIB_USER_NAME:
1170 case ISAKMP_XAUTH_ATTRIB_USER_PASSWORD:
1171 case ISAKMP_XAUTH_ATTRIB_PASSCODE:
1172 case ISAKMP_XAUTH_ATTRIB_DOMAIN:
1173 case ISAKMP_XAUTH_ATTRIB_ANSWER:
1174 case ISAKMP_XAUTH_ATTRIB_CISCOEXT_VENDOR:
1175 break;
1176 case ISAKMP_XAUTH_ATTRIB_MESSAGE:
1177 if (opt_debug || seen_answer || config[CONFIG_XAUTH_INTERACTIVE]) {
1178 if (ap->af == isakmp_attr_16)
1179 printf("%c%c\n", ap->u.attr_16 >> 8, ap->u.attr_16);
1180 else
1181 printf("%.*s%s", ap->u.lots.length, ap->u.lots.data,
1182 ((ap->u.lots.data
1183 && ap->u.lots.data[ap->u.
1184 lots.length - 1] !=
1185 '\n')
1186 ? "\n" : ""));
1188 break;
1189 default:
1190 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1192 DEBUG(2, printf("S5.5\n"));
1193 if (reject != 0)
1194 phase2_fatal(s, "xauth packet unsupported: %s", reject);
1196 inet_ntop(dest_addr->sa_family,
1197 &((struct sockaddr_in *)dest_addr)->sin_addr, ntop_buf, sizeof(ntop_buf));
1199 /* Collect data from the user. */
1200 reply_attr = NULL;
1201 for (ap = a; ap && reject == 0; ap = ap->next)
1202 switch (ap->type) {
1203 case ISAKMP_XAUTH_ATTRIB_DOMAIN:
1205 struct isakmp_attribute *na;
1206 na = new_isakmp_attribute(ap->type, reply_attr);
1207 reply_attr = na;
1208 na->u.lots.length = strlen(config[CONFIG_DOMAIN]);
1209 if (na->u.lots.length == 0)
1210 error(1, 0,
1211 "server requested domain, but none set (use \"Domain ...\" in config or --domain");
1212 na->u.lots.data = xallocc(na->u.lots.length);
1213 memcpy(na->u.lots.data, config[CONFIG_DOMAIN],
1214 na->u.lots.length);
1215 break;
1217 case ISAKMP_XAUTH_ATTRIB_USER_NAME:
1219 struct isakmp_attribute *na;
1220 na = new_isakmp_attribute(ap->type, reply_attr);
1221 reply_attr = na;
1222 na->u.lots.length = strlen(config[CONFIG_XAUTH_USERNAME]);
1223 na->u.lots.data = xallocc(na->u.lots.length);
1224 memcpy(na->u.lots.data, config[CONFIG_XAUTH_USERNAME],
1225 na->u.lots.length);
1226 break;
1228 case ISAKMP_XAUTH_ATTRIB_ANSWER:
1230 char *line = NULL;
1231 size_t linelen = 0;
1232 ssize_t linesz;
1233 struct isakmp_attribute *na;
1235 if ((linesz = getline(&line, &linelen, stdin)) == -1)
1236 error(1, errno, "reading user input");
1237 if (line[linesz - 1] == '\n')
1238 linesz--;
1240 na = new_isakmp_attribute(ap->type, reply_attr);
1241 reply_attr = na;
1242 na->u.lots.length = linesz;
1243 na->u.lots.data = line;
1245 break;
1247 case ISAKMP_XAUTH_ATTRIB_USER_PASSWORD:
1248 case ISAKMP_XAUTH_ATTRIB_PASSCODE:
1250 struct isakmp_attribute *na;
1251 na = new_isakmp_attribute(ap->type, reply_attr);
1252 reply_attr = na;
1253 na->u.lots.length = strlen(config[CONFIG_XAUTH_PASSWORD]);
1254 na->u.lots.data = xallocc(na->u.lots.length);
1255 memcpy(na->u.lots.data, config[CONFIG_XAUTH_PASSWORD],
1256 na->u.lots.length);
1257 break;
1259 default:
1263 /* Send the response. */
1264 rp = new_isakmp_payload(ISAKMP_PAYLOAD_MODECFG_ATTR);
1265 rp->u.modecfg.type = ISAKMP_MODECFG_CFG_REPLY;
1266 rp->u.modecfg.id = r->payload->next->u.modecfg.id;
1267 rp->u.modecfg.attributes = reply_attr;
1268 sendrecv_phase2(s, rp, ISAKMP_EXCHANGE_MODECFG_TRANSACTION,
1269 r->message_id, 0, 0, 0, 0, 0, 0, 0, 0);
1271 free_isakmp_packet(r);
1274 DEBUG(2, printf("S5.6\n"));
1276 /* The final SET should have just one attribute. */
1277 uint16_t reject = 0;
1278 struct isakmp_attribute *a = r->payload->next->u.modecfg.attributes;
1279 uint16_t set_result;
1281 if (a == NULL
1282 || a->type != ISAKMP_XAUTH_ATTRIB_STATUS
1283 || a->af != isakmp_attr_16 || a->next != NULL) {
1284 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
1285 phase2_fatal(s, "xauth SET response rejected: %s", reject);
1287 set_result = a->u.attr_16;
1289 /* ACK the SET. */
1290 r->payload->next->u.modecfg.type = ISAKMP_MODECFG_CFG_ACK;
1291 sendrecv_phase2(s, r->payload->next, ISAKMP_EXCHANGE_MODECFG_TRANSACTION,
1292 r->message_id, 1, 0, 0, 0, 0, 0, 0, 0);
1293 r->payload->next = NULL;
1294 free_isakmp_packet(r);
1296 if (set_result == 0)
1297 error(2, 0, "authentication unsuccessful");
1299 DEBUG(2, printf("S5.7\n"));
1300 return 0;
1303 static void addenv(const void *name, const char *value)
1305 char *strbuf = NULL, *oldval;
1307 oldval = getenv(name);
1308 if (oldval != NULL) {
1309 strbuf = xallocc(strlen(oldval) + 1 + strlen(value) + 1);
1310 strcat(strbuf, oldval);
1311 strcat(strbuf, " ");
1312 strcat(strbuf, value);
1315 setenv(name, strbuf ? strbuf : value, 1);
1317 if (strbuf)
1318 free(strbuf);
1321 static void addenv_ipv4(const void *name, uint8_t * data)
1323 addenv(name, inet_ntoa(*((struct in_addr *)data)));
1326 static void do_phase_2_config(struct sa_block *s)
1328 struct isakmp_payload *rp;
1329 struct isakmp_attribute *a;
1330 struct isakmp_packet *r;
1331 struct utsname uts;
1332 uint32_t msgid;
1333 uint16_t reject;
1334 int seen_address = 0;
1335 char *strbuf;
1337 uname(&uts);
1339 gcry_randomize((uint8_t *) & msgid, sizeof(msgid), GCRY_WEAK_RANDOM);
1340 if (msgid == 0)
1341 msgid = 1;
1343 rp = new_isakmp_payload(ISAKMP_PAYLOAD_MODECFG_ATTR);
1344 rp->u.modecfg.type = ISAKMP_MODECFG_CFG_REQUEST;
1345 rp->u.modecfg.id = 20;
1346 a = NULL;
1348 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_APPLICATION_VERSION, a);
1349 a->u.lots.length = strlen(config[CONFIG_VERSION]);
1350 a->u.lots.data = xallocc(a->u.lots.length);
1351 memcpy(a->u.lots.data, config[CONFIG_VERSION], a->u.lots.length);
1353 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_DDNS_HOSTNAME, a);
1354 a->u.lots.length = strlen(uts.nodename);
1355 a->u.lots.data = xallocc(a->u.lots.length);
1356 memcpy(a->u.lots.data, uts.nodename, a->u.lots.length);
1358 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_BANNER, a);
1359 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_DO_PFS, a);
1360 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_DEF_DOMAIN, a);
1361 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_NBNS, a);
1362 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_DNS, a);
1363 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_NETMASK, a);
1364 a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_ADDRESS, a);
1366 rp->u.modecfg.attributes = a;
1367 sendrecv_phase2(s, rp, ISAKMP_EXCHANGE_MODECFG_TRANSACTION, msgid, 0, 0, 0, 0, 0, 0, 0, 0);
1369 reject = unpack_verify_phase2(s, r_packet, r_length, &r, NULL, 0);
1371 /* Check the transaction type & message ID are OK. */
1372 if (reject == 0 && r->message_id != msgid)
1373 reject = ISAKMP_N_INVALID_MESSAGE_ID;
1374 if (reject == 0 && r->exchange_type != ISAKMP_EXCHANGE_MODECFG_TRANSACTION)
1375 reject = ISAKMP_N_INVALID_EXCHANGE_TYPE;
1377 /* After the hash, expect an attribute block. */
1378 if (reject == 0
1379 && (r->payload->next == NULL
1380 || r->payload->next->next != NULL
1381 || r->payload->next->type != ISAKMP_PAYLOAD_MODECFG_ATTR
1382 #if 0
1383 || r->payload->next->u.modecfg.id != 20
1384 #endif
1385 || r->payload->next->u.modecfg.type != ISAKMP_MODECFG_CFG_REPLY))
1386 reject = ISAKMP_N_PAYLOAD_MALFORMED;
1388 if (reject != 0)
1389 phase2_fatal(s, "configuration response rejected: %s", reject);
1391 unsetenv("CISCO_BANNER");
1392 unsetenv("CISCO_DEF_DOMAIN");
1393 unsetenv("INTERNAL_IP4_NBNS");
1394 unsetenv("INTERNAL_IP4_DNS");
1395 unsetenv("INTERNAL_IP4_NETMASK");
1396 unsetenv("INTERNAL_IP4_ADDRESS");
1398 for (a = r->payload->next->u.modecfg.attributes; a && reject == 0; a = a->next)
1399 switch (a->type) {
1400 case ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_ADDRESS:
1401 if (a->af != isakmp_attr_lots || a->u.lots.length != 4)
1402 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1403 else {
1404 addenv_ipv4("INTERNAL_IP4_ADDRESS", a->u.lots.data);
1405 memcpy(s->our_address, a->u.lots.data, 4);
1407 seen_address = 1;
1408 break;
1410 case ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_NETMASK:
1411 if (a->af == isakmp_attr_lots && a->u.lots.length == 0) {
1412 DEBUG(2, printf("ignoring zero length netmask\n"));
1413 continue;
1415 if (a->af != isakmp_attr_lots || a->u.lots.length != 4)
1416 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1417 else
1418 addenv_ipv4("INTERNAL_IP4_NETMASK", a->u.lots.data);
1419 break;
1421 case ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_DNS:
1422 if (a->af != isakmp_attr_lots || a->u.lots.length != 4)
1423 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1424 else
1425 addenv_ipv4("INTERNAL_IP4_DNS", a->u.lots.data);
1426 break;
1428 case ISAKMP_MODECFG_ATTRIB_INTERNAL_IP4_NBNS:
1429 if (a->af != isakmp_attr_lots || a->u.lots.length != 4)
1430 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1431 else
1432 addenv_ipv4("INTERNAL_IP4_NBNS", a->u.lots.data);
1433 break;
1435 case ISAKMP_MODECFG_ATTRIB_CISCO_DEF_DOMAIN:
1436 if (a->af != isakmp_attr_lots) {
1437 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1438 break;
1440 strbuf = xallocc(a->u.lots.length + 1);
1441 memcpy(strbuf, a->u.lots.data, a->u.lots.length);
1442 addenv("CISCO_DEF_DOMAIN", strbuf);
1443 free(strbuf);
1444 break;
1446 case ISAKMP_MODECFG_ATTRIB_CISCO_BANNER:
1447 if (a->af != isakmp_attr_lots) {
1448 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1449 break;
1451 strbuf = xallocc(a->u.lots.length + 1);
1452 memcpy(strbuf, a->u.lots.data, a->u.lots.length);
1453 addenv("CISCO_BANNER", strbuf);
1454 free(strbuf);
1455 DEBUG(1, printf("Banner: "));
1456 DEBUG(1, fwrite(a->u.lots.data, a->u.lots.length, 1, stdout));
1457 DEBUG(1, printf("\n"));
1458 break;
1460 case ISAKMP_MODECFG_ATTRIB_APPLICATION_VERSION:
1461 DEBUG(2, printf("Remote Application Version: "));
1462 DEBUG(2, fwrite(a->u.lots.data, a->u.lots.length, 1, stdout));
1463 DEBUG(2, printf("\n"));
1464 break;
1466 case ISAKMP_MODECFG_ATTRIB_CISCO_DO_PFS:
1467 if (a->af != isakmp_attr_16)
1468 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1469 else {
1470 s->do_pfs = a->u.attr_16;
1471 DEBUG(2, printf("got pfs setting: %d\n", s->do_pfs));
1473 break;
1475 default:
1476 DEBUG(2, printf("unknown attriube %d / 0x%X\n", a->type, a->type));
1477 break;
1480 if (reject == 0 && !seen_address)
1481 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1483 if (reject != 0)
1484 phase2_fatal(s, "configuration response rejected: %s", reject);
1486 DEBUG(1, printf("got address %s\n", getenv("INTERNAL_IP4_ADDRESS")));
1489 void config_tunnel(const char *dev)
1491 setenv("TUNDEV", dev, 1);
1492 setenv("VPNGATEWAY", inet_ntoa(((struct sockaddr_in *)dest_addr)->sin_addr), 1);
1494 system(config[CONFIG_CONFIG_SCRIPT]);
1497 static uint8_t *gen_keymat(struct sa_block *s,
1498 uint8_t protocol, uint32_t spi,
1499 int md_algo, int crypt_algo,
1500 const uint8_t * dh_shared, size_t dh_size,
1501 const uint8_t * ni_data, size_t ni_size, const uint8_t * nr_data, size_t nr_size)
1503 gcry_md_hd_t hm;
1504 uint8_t *block;
1505 int i;
1506 int blksz;
1507 int cnt;
1509 int md_len = gcry_md_get_algo_dlen(md_algo);
1510 int cry_len;
1512 gcry_cipher_algo_info(crypt_algo, GCRYCTL_GET_KEYLEN, NULL, &cry_len);
1513 blksz = md_len + cry_len;
1514 cnt = (blksz + s->md_len - 1) / s->md_len;
1515 block = xallocc(cnt * s->md_len);
1516 DEBUG(3, printf("generating %d bytes keymat (cnt=%d)\n", blksz, cnt));
1517 if (cnt < 1)
1518 abort();
1520 for (i = 0; i < cnt; i++) {
1521 gcry_md_open(&hm, s->md_algo, GCRY_MD_FLAG_HMAC);
1522 gcry_md_setkey(hm, s->skeyid_d, s->md_len);
1523 if (i != 0)
1524 gcry_md_write(hm, block + (i - 1) * s->md_len, s->md_len);
1525 if (dh_shared != NULL)
1526 gcry_md_write(hm, dh_shared, dh_size);
1527 gcry_md_write(hm, &protocol, 1);
1528 gcry_md_write(hm, (uint8_t *) & spi, sizeof(spi));
1529 gcry_md_write(hm, ni_data, ni_size);
1530 gcry_md_write(hm, nr_data, nr_size);
1531 gcry_md_final(hm);
1532 memcpy(block + i * s->md_len, gcry_md_read(hm, 0), s->md_len);
1533 gcry_md_close(hm);
1535 return block;
1538 struct isakmp_attribute *make_transform_ipsec(int dh_group, int hash, int keylen)
1540 struct isakmp_attribute *a = NULL;
1542 a = new_isakmp_attribute(ISAKMP_IPSEC_ATTRIB_SA_LIFE_DURATION, a);
1543 a->af = isakmp_attr_lots;
1544 a->u.lots.length = 4;
1545 a->u.lots.data = xallocc(a->u.lots.length);
1546 *((uint32_t *) a->u.lots.data) = htonl(2147483);
1547 a = new_isakmp_attribute_16(ISAKMP_IPSEC_ATTRIB_SA_LIFE_TYPE, IPSEC_LIFE_SECONDS, a);
1549 if (dh_group)
1550 a = new_isakmp_attribute_16(ISAKMP_IPSEC_ATTRIB_GROUP_DESC, dh_group, a);
1551 a = new_isakmp_attribute_16(ISAKMP_IPSEC_ATTRIB_AUTH_ALG, hash, a);
1552 a = new_isakmp_attribute_16(ISAKMP_IPSEC_ATTRIB_ENCAP_MODE, IPSEC_ENCAP_TUNNEL, a);
1553 if (keylen != 0)
1554 a = new_isakmp_attribute_16(ISAKMP_IPSEC_ATTRIB_KEY_LENGTH, keylen, a);
1556 return a;
1559 struct isakmp_payload *make_our_sa_ipsec(struct sa_block *s)
1561 struct isakmp_payload *r = new_isakmp_payload(ISAKMP_PAYLOAD_SA);
1562 struct isakmp_payload *p = NULL, *pn;
1563 struct isakmp_attribute *a;
1564 int dh_grp = get_dh_group_ipsec(s->do_pfs)->ipsec_sa_id;
1565 unsigned int crypt, hash, keylen;
1566 int i;
1568 r = new_isakmp_payload(ISAKMP_PAYLOAD_SA);
1569 r->u.sa.doi = ISAKMP_DOI_IPSEC;
1570 r->u.sa.situation = ISAKMP_IPSEC_SIT_IDENTITY_ONLY;
1571 r->u.sa.proposals = new_isakmp_payload(ISAKMP_PAYLOAD_P);
1572 r->u.sa.proposals->u.p.spi_size = 4;
1573 r->u.sa.proposals->u.p.spi = xallocc(4);
1574 /* The sadb_sa_spi field is already in network order. */
1575 memcpy(r->u.sa.proposals->u.p.spi, &s->tous_esp_spi, 4);
1576 r->u.sa.proposals->u.p.prot_id = ISAKMP_IPSEC_PROTO_IPSEC_ESP;
1577 for (crypt = 0; supp_crypt[crypt].name != NULL; crypt++) {
1578 if ((supp_crypt[crypt].my_id == GCRY_CIPHER_DES) && (opt_1des == 0))
1579 continue;
1580 keylen = supp_crypt[crypt].keylen;
1581 for (hash = 0; supp_hash[hash].name != NULL; hash++) {
1582 pn = p;
1583 p = new_isakmp_payload(ISAKMP_PAYLOAD_P);
1584 p->u.p.spi_size = 4;
1585 p->u.p.spi = xallocc(4);
1586 /* The sadb_sa_spi field is already in network order. */
1587 memcpy(p->u.p.spi, &s->tous_esp_spi, 4);
1588 p->u.p.prot_id = ISAKMP_IPSEC_PROTO_IPSEC_ESP;
1589 p->u.p.transforms = new_isakmp_payload(ISAKMP_PAYLOAD_T);
1590 p->u.p.transforms->u.t.id = supp_crypt[crypt].ipsec_sa_id;
1591 a = make_transform_ipsec(dh_grp, supp_hash[hash].ipsec_sa_id, keylen);
1592 p->u.p.transforms->u.t.attributes = a;
1593 p->next = pn;
1596 for (i = 0, pn = p; pn; pn = pn->next)
1597 pn->u.p.number = i++;
1598 r->u.sa.proposals = p;
1599 return r;
1602 static void setup_link(struct sa_block *s)
1604 struct isakmp_payload *rp, *us, *ke = NULL, *them, *nonce_r = NULL;
1605 struct isakmp_packet *r;
1606 struct group *dh_grp = NULL;
1607 uint32_t msgid;
1608 uint16_t reject;
1609 uint8_t *p_flat = NULL, *realiv = NULL, realiv_msgid[4];
1610 size_t p_size = 0;
1611 uint8_t nonce[20], *dh_public = NULL;
1612 int ipsec_cry_algo = 0, ipsec_hash_algo = 0, i;
1614 DEBUG(2, printf("S7.1\n"));
1615 /* Set up the Diffie-Hellman stuff. */
1616 if (get_dh_group_ipsec(s->do_pfs)->my_id) {
1617 dh_grp = group_get(get_dh_group_ipsec(s->do_pfs)->my_id);
1618 DEBUG(3, printf("len = %d\n", dh_getlen(dh_grp)));
1619 dh_public = xallocc(dh_getlen(dh_grp));
1620 dh_create_exchange(dh_grp, dh_public);
1621 hex_dump("dh_public", dh_public, dh_getlen(dh_grp));
1624 gcry_randomize((uint8_t *) & s->tous_esp_spi, sizeof(s->tous_esp_spi), GCRY_WEAK_RANDOM);
1625 rp = make_our_sa_ipsec(s);
1626 gcry_randomize((uint8_t *) nonce, sizeof(nonce), GCRY_WEAK_RANDOM);
1627 rp->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_NONCE, nonce, sizeof(nonce));
1629 us = new_isakmp_payload(ISAKMP_PAYLOAD_ID);
1630 us->u.id.type = ISAKMP_IPSEC_ID_IPV4_ADDR;
1631 us->u.id.length = 4;
1632 us->u.id.data = xallocc(4);
1633 memcpy(us->u.id.data, s->our_address, sizeof(struct in_addr));
1634 them = new_isakmp_payload(ISAKMP_PAYLOAD_ID);
1635 them->u.id.type = ISAKMP_IPSEC_ID_IPV4_ADDR_SUBNET;
1636 them->u.id.length = 8;
1637 them->u.id.data = xallocc(8);
1638 memset(them->u.id.data, 0, 8);
1639 us->next = them;
1641 if (!dh_grp) {
1642 rp->next->next = us;
1643 } else {
1644 rp->next->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_KE,
1645 dh_public, dh_getlen(dh_grp));
1646 rp->next->next->next = us;
1649 gcry_randomize((uint8_t *) & msgid, sizeof(&msgid), GCRY_WEAK_RANDOM);
1650 if (msgid == 0)
1651 msgid = 1;
1653 DEBUG(2, printf("S7.2\n"));
1654 for (i = 0; i < 4; i++) {
1655 sendrecv_phase2(s, rp, ISAKMP_EXCHANGE_IKE_QUICK,
1656 msgid, 0, 0, &p_flat, &p_size, 0, 0, 0, 0);
1658 if (realiv == NULL) {
1659 realiv = xallocc(s->ivlen);
1660 memcpy(realiv, s->current_iv, s->ivlen);
1661 memcpy(realiv_msgid, s->current_iv_msgid, 4);
1664 DEBUG(2, printf("S7.3\n"));
1665 reject = unpack_verify_phase2(s, r_packet, r_length, &r, nonce, sizeof(nonce));
1667 DEBUG(2, printf("S7.4\n"));
1668 if (((reject == 0) || (reject == ISAKMP_N_AUTHENTICATION_FAILED))
1669 && r->exchange_type == ISAKMP_EXCHANGE_INFORMATIONAL) {
1670 /* handle notifie responder-lifetime (ignore) */
1671 /* (broken hash => ignore AUTHENTICATION_FAILED) */
1672 if (reject == 0 && r->payload->next->type != ISAKMP_PAYLOAD_N)
1673 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
1675 if (reject == 0
1676 && r->payload->next->u.n.type ==
1677 ISAKMP_N_IPSEC_RESPONDER_LIFETIME) {
1678 DEBUG(2, printf("ignoring responder-lifetime notify\n"));
1679 memcpy(s->current_iv, realiv, s->ivlen);
1680 memcpy(s->current_iv_msgid, realiv_msgid, 4);
1681 continue;
1685 /* Check the transaction type & message ID are OK. */
1686 if (reject == 0 && r->message_id != msgid)
1687 reject = ISAKMP_N_INVALID_MESSAGE_ID;
1689 if (reject == 0 && r->exchange_type != ISAKMP_EXCHANGE_IKE_QUICK)
1690 reject = ISAKMP_N_INVALID_EXCHANGE_TYPE;
1692 /* The SA payload must be second. */
1693 if (reject == 0 && r->payload->next->type != ISAKMP_PAYLOAD_SA)
1694 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
1696 if (p_flat)
1697 free(p_flat);
1698 if (realiv)
1699 free(realiv);
1700 break;
1703 DEBUG(2, printf("S7.5\n"));
1704 if (reject != 0)
1705 phase2_fatal(s, "quick mode response rejected: %s\ncheck pfs setting", reject);
1707 DEBUG(2, printf("S7.6\n"));
1708 for (rp = r->payload->next; rp && reject == 0; rp = rp->next)
1709 switch (rp->type) {
1710 case ISAKMP_PAYLOAD_SA:
1711 if (reject == 0 && rp->u.sa.doi != ISAKMP_DOI_IPSEC)
1712 reject = ISAKMP_N_DOI_NOT_SUPPORTED;
1713 if (reject == 0 && rp->u.sa.situation != ISAKMP_IPSEC_SIT_IDENTITY_ONLY)
1714 reject = ISAKMP_N_SITUATION_NOT_SUPPORTED;
1715 if (reject == 0 &&
1716 (rp->u.sa.proposals == NULL || rp->u.sa.proposals->next != NULL))
1717 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1718 if (reject == 0 &&
1719 rp->u.sa.proposals->u.p.prot_id != ISAKMP_IPSEC_PROTO_IPSEC_ESP)
1720 reject = ISAKMP_N_INVALID_PROTOCOL_ID;
1721 if (reject == 0 && rp->u.sa.proposals->u.p.spi_size != 4)
1722 reject = ISAKMP_N_INVALID_SPI;
1723 if (reject == 0 &&
1724 (rp->u.sa.proposals->u.p.transforms == NULL
1725 || rp->u.sa.proposals->u.p.transforms->next != NULL))
1726 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1727 if (reject == 0) {
1728 struct isakmp_attribute *a
1729 = rp->u.sa.proposals->u.p.transforms->u.t.attributes;
1730 int seen_enc = rp->u.sa.proposals->u.p.transforms->u.t.id;
1731 int seen_auth = 0, seen_encap = 0, seen_group = 0, seen_keylen = 0;
1733 memcpy(&s->tothem_esp_spi, rp->u.sa.proposals->u.p.spi, 4);
1735 for (; a && reject == 0; a = a->next)
1736 switch (a->type) {
1737 case ISAKMP_IPSEC_ATTRIB_AUTH_ALG:
1738 if (a->af == isakmp_attr_16)
1739 seen_auth = a->u.attr_16;
1740 else
1741 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1742 break;
1743 case ISAKMP_IPSEC_ATTRIB_ENCAP_MODE:
1744 if (a->af == isakmp_attr_16 &&
1745 a->u.attr_16 == IPSEC_ENCAP_TUNNEL)
1746 seen_encap = 1;
1747 else
1748 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1749 break;
1750 case ISAKMP_IPSEC_ATTRIB_GROUP_DESC:
1751 if (dh_grp &&
1752 a->af == isakmp_attr_16 &&
1753 a->u.attr_16 ==
1754 get_dh_group_ipsec(s->do_pfs)->ipsec_sa_id)
1755 seen_group = 1;
1756 else
1757 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1758 break;
1759 case ISAKMP_IPSEC_ATTRIB_KEY_LENGTH:
1760 if (a->af == isakmp_attr_16)
1761 seen_keylen = a->u.attr_16;
1762 else
1763 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1764 break;
1765 case ISAKMP_IPSEC_ATTRIB_SA_LIFE_TYPE:
1766 case ISAKMP_IPSEC_ATTRIB_SA_LIFE_DURATION:
1767 break;
1768 default:
1769 reject = ISAKMP_N_ATTRIBUTES_NOT_SUPPORTED;
1770 break;
1772 if (reject == 0 && (!seen_auth || !seen_encap ||
1773 (dh_grp && !seen_group)))
1774 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1776 if (reject == 0
1777 && get_algo(SUPP_ALGO_HASH, SUPP_ALGO_IPSEC_SA, seen_auth,
1778 NULL, 0) == NULL)
1779 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1780 if (reject == 0
1781 && get_algo(SUPP_ALGO_CRYPT, SUPP_ALGO_IPSEC_SA, seen_enc,
1782 NULL, seen_keylen) == NULL)
1783 reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX;
1785 if (reject == 0) {
1786 ipsec_cry_algo =
1787 get_algo(SUPP_ALGO_CRYPT, SUPP_ALGO_IPSEC_SA,
1788 seen_enc, NULL, seen_keylen)->my_id;
1789 ipsec_hash_algo =
1790 get_algo(SUPP_ALGO_HASH, SUPP_ALGO_IPSEC_SA,
1791 seen_auth, NULL, 0)->my_id;
1792 DEBUG(1, printf("IPSEC SA selected %s-%s\n",
1793 get_algo(SUPP_ALGO_CRYPT,
1794 SUPP_ALGO_IPSEC_SA, seen_enc, NULL,
1795 seen_keylen)->name,
1796 get_algo(SUPP_ALGO_HASH, SUPP_ALGO_IPSEC_SA,
1797 seen_auth, NULL, 0)->name));
1800 break;
1802 case ISAKMP_PAYLOAD_N:
1803 break;
1804 case ISAKMP_PAYLOAD_ID:
1805 break;
1806 case ISAKMP_PAYLOAD_KE:
1807 ke = rp;
1808 break;
1809 case ISAKMP_PAYLOAD_NONCE:
1810 nonce_r = rp;
1811 break;
1813 default:
1814 reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
1815 break;
1818 if (reject == 0 && nonce_r == NULL)
1819 reject = ISAKMP_N_INVALID_HASH_INFORMATION;
1820 if (reject == 0 && dh_grp && (ke == NULL || ke->u.ke.length != dh_getlen(dh_grp)))
1821 reject = ISAKMP_N_INVALID_KEY_INFORMATION;
1822 if (reject != 0)
1823 phase2_fatal(s, "quick mode response rejected [2]: %s", reject);
1825 /* send final packet */
1826 sendrecv_phase2(s, NULL, ISAKMP_EXCHANGE_IKE_QUICK,
1827 msgid, 1, 0, 0, 0, nonce, sizeof(nonce),
1828 nonce_r->u.nonce.data, nonce_r->u.nonce.length);
1830 DEBUG(2, printf("S7.7\n"));
1831 /* Create the delete payload, now that we have all the information. */
1833 struct isakmp_payload *d_isakmp, *d_ipsec;
1834 uint32_t del_msgid;
1836 gcry_randomize((uint8_t *) & del_msgid, sizeof(del_msgid), GCRY_WEAK_RANDOM);
1837 d_isakmp = new_isakmp_payload(ISAKMP_PAYLOAD_D);
1838 d_isakmp->u.d.doi = ISAKMP_DOI_IPSEC;
1839 d_isakmp->u.d.protocol = ISAKMP_IPSEC_PROTO_ISAKMP;
1840 d_isakmp->u.d.spi_length = 2 * ISAKMP_COOKIE_LENGTH;
1841 d_isakmp->u.d.num_spi = 1;
1842 d_isakmp->u.d.spi = xallocc(1 * sizeof(uint8_t *));
1843 d_isakmp->u.d.spi[0] = xallocc(2 * ISAKMP_COOKIE_LENGTH);
1844 memcpy(d_isakmp->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 0, s->i_cookie,
1845 ISAKMP_COOKIE_LENGTH);
1846 memcpy(d_isakmp->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 1, s->r_cookie,
1847 ISAKMP_COOKIE_LENGTH);
1848 d_ipsec = new_isakmp_payload(ISAKMP_PAYLOAD_D);
1849 d_ipsec->next = d_isakmp;
1850 d_ipsec->u.d.doi = ISAKMP_DOI_IPSEC;
1851 d_ipsec->u.d.protocol = ISAKMP_IPSEC_PROTO_IPSEC_ESP;
1852 d_ipsec->u.d.spi_length = 4;
1853 d_ipsec->u.d.num_spi = 2;
1854 d_ipsec->u.d.spi = xallocc(2 * sizeof(uint8_t *));
1855 d_ipsec->u.d.spi[0] = xallocc(d_ipsec->u.d.spi_length);
1856 memcpy(d_ipsec->u.d.spi[0], &s->tous_esp_spi, 4);
1857 d_ipsec->u.d.spi[1] = xallocc(d_ipsec->u.d.spi_length);
1858 memcpy(d_ipsec->u.d.spi[1], &s->tothem_esp_spi, 4);
1859 phase2_authpacket(s, d_ipsec, ISAKMP_EXCHANGE_INFORMATIONAL,
1860 del_msgid, &s->kill_packet, &s->kill_packet_size,
1861 nonce, sizeof(nonce), nonce_r->u.nonce.data, nonce_r->u.nonce.length);
1862 isakmp_crypt(s, s->kill_packet, s->kill_packet_size, 1);
1864 DEBUG(2, printf("S7.8\n"));
1866 /* Set up the interface here so it's ready when our acknowledgement
1867 * arrives. */
1868 config_tunnel(tun_name);
1869 DEBUG(2, printf("S7.9\n"));
1871 uint8_t *tous_keys, *tothem_keys;
1872 struct sockaddr_in tothem_dest;
1873 unsigned char *dh_shared_secret = NULL;
1875 if (dh_grp) {
1876 /* Determine the shared secret. */
1877 dh_shared_secret = xallocc(dh_getlen(dh_grp));
1878 dh_create_shared(dh_grp, dh_shared_secret, ke->u.ke.data);
1879 hex_dump("dh_shared_secret", dh_shared_secret, dh_getlen(dh_grp));
1881 tous_keys = gen_keymat(s, ISAKMP_IPSEC_PROTO_IPSEC_ESP, s->tous_esp_spi,
1882 ipsec_hash_algo, ipsec_cry_algo,
1883 dh_shared_secret, dh_grp ? dh_getlen(dh_grp) : 0,
1884 nonce, sizeof(nonce), nonce_r->u.nonce.data, nonce_r->u.nonce.length);
1885 memset(&tothem_dest, 0, sizeof(tothem_dest));
1886 tothem_dest.sin_family = AF_INET;
1887 memcpy(&tothem_dest.sin_addr, s->our_address, 4);
1888 tothem_keys = gen_keymat(s, ISAKMP_IPSEC_PROTO_IPSEC_ESP, s->tothem_esp_spi,
1889 ipsec_hash_algo, ipsec_cry_algo,
1890 dh_shared_secret, dh_grp ? dh_getlen(dh_grp) : 0,
1891 nonce, sizeof(nonce), nonce_r->u.nonce.data, nonce_r->u.nonce.length);
1892 DEBUG(2, printf("S7.10\n"));
1893 vpnc_doit(s->tous_esp_spi, tous_keys, &tothem_dest,
1894 s->tothem_esp_spi, tothem_keys, (struct sockaddr_in *)dest_addr,
1895 tun_fd, ipsec_hash_algo, ipsec_cry_algo,
1896 s->kill_packet, s->kill_packet_size, dest_addr, config[CONFIG_PID_FILE]);
1900 int main(int argc, char **argv)
1902 struct sa_block oursa;
1903 int do_load_balance;
1904 const uint8_t hex_test[] = { 0, 1, 2, 3 };
1906 test_pack_unpack();
1907 gcry_check_version("1.1.90");
1908 gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
1909 group_init();
1911 do_config(argc, argv);
1913 hex_dump("hex_test", hex_test, sizeof(hex_test));
1915 DEBUG(2, printf("S1\n"));
1916 dest_addr = init_sockaddr(config[CONFIG_IPSEC_GATEWAY], 500);
1917 DEBUG(2, printf("S2\n"));
1918 sockfd = make_socket(atoi(config[CONFIG_LOCAL_PORT]));
1919 DEBUG(2, printf("S3\n"));
1920 setup_tunnel();
1922 do {
1923 DEBUG(2, printf("S4\n"));
1924 memset(&oursa, '\0', sizeof(oursa));
1925 do_phase_1(config[CONFIG_IPSEC_ID], config[CONFIG_IPSEC_SECRET], &oursa);
1926 DEBUG(2, printf("S5\n"));
1927 do_load_balance = do_phase_2_xauth(&oursa);
1928 } while (do_load_balance);
1929 DEBUG(2, printf("S6\n"));
1930 do_phase_2_config(&oursa);
1931 DEBUG(2, printf("S7\n"));
1932 setup_link(&oursa);
1934 return 0;