1 /*
2 * fiked - a fake IKE PSK+XAUTH daemon based on vpnc
3 * Copyright (C) 2005, Daniel Roethlisberger <daniel@roe.ch>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see http://www.gnu.org/copyleft/
17 *
18 * $Id: peer_ctx.c 103 2005-12-18 16:28:08Z roe $
19 */
20
21 #include "peer_ctx.h"
22 #include "mem.h"
23 #include "vpnc/math_group.h"
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <stdio.h>
31
32 /* message_iv */
33
message_iv_get(uint32_t id,message_iv ** head)34 message_iv * message_iv_get(uint32_t id, message_iv **head)
35 {
36 message_iv *found = NULL;
37 for(message_iv *p = *head; p && !found; p = p->next) {
38 if(p->id == id)
39 found = p;
40 }
41
42 if(!found) {
43 mem_allocate(&found, sizeof(message_iv));
44 memset(found, 0, sizeof(message_iv));
45 found->id = id;
46 found->next = *head;
47 *head = found;
48 }
49
50 return found;
51 }
52
message_iv_free(message_iv * msg_iv)53 void message_iv_free(message_iv *msg_iv)
54 {
55 if(msg_iv->next) {
56 message_iv_free(msg_iv->next);
57 msg_iv->next = NULL;
58 }
59 mem_free(&msg_iv->iv);
60 free(msg_iv);
61 }
62
63
64 /* peer_ctx */
65
peer_ctx_get(datagram * dgm,config * cfg,peer_ctx ** head)66 peer_ctx * peer_ctx_get(datagram *dgm, config *cfg, peer_ctx **head)
67 {
68 peer_ctx *found = NULL;
69 for(peer_ctx *p = *head; p && !found; p = p->next) {
70 if(p->peer_addr.sin_addr.s_addr == dgm->peer_addr.sin_addr.s_addr &&
71 p->peer_addr.sin_port == dgm->peer_addr.sin_port)
72 found = p;
73 }
74
75 if(!found) {
76 mem_allocate(&found, sizeof(peer_ctx));
77 memset(found, 0, sizeof(peer_ctx));
78 found->peer_addr = dgm->peer_addr;
79 found->next = *head;
80 found->state = STATE_NEW;
81 found->cfg = cfg;
82 *head = found;
83 }
84
85 return found;
86 }
87
peer_ctx_clear(peer_ctx * ctx)88 void peer_ctx_clear(peer_ctx *ctx)
89 {
90 mem_free(&ctx->ipsec_id);
91 mem_free(&ctx->ipsec_secret);
92 mem_free(&ctx->xauth_username);
93 mem_free(&ctx->xauth_password);
94
95 mem_free(&ctx->key);
96 mem_free(&ctx->iv0);
97 if(ctx->msg_iv) {
98 message_iv_free(ctx->msg_iv);
99 ctx->msg_iv = NULL;
100 }
101
102 if(ctx->dh_group) {
103 group_free(ctx->dh_group);
104 ctx->dh_group = NULL;
105 }
106
107 mem_free(&ctx->dh_i_public);
108 mem_free(&ctx->dh_r_public);
109 mem_free(&ctx->dh_secret);
110
111 mem_free(&ctx->skeyid);
112 mem_free(&ctx->skeyid_e);
113 mem_free(&ctx->skeyid_a);
114 mem_free(&ctx->skeyid_d);
115
116 mem_free(&ctx->i_sa);
117 mem_free(&ctx->i_id);
118 mem_free(&ctx->r_id);
119 mem_free(&ctx->i_nonce);
120 mem_free(&ctx->r_nonce);
121 mem_free(&ctx->i_hash);
122 mem_free(&ctx->r_hash);
123 }
124
peer_ctx_reset(peer_ctx * ctx)125 void peer_ctx_reset(peer_ctx *ctx)
126 {
127 peer_ctx_clear(ctx);
128 memset((uint8_t *)&ctx->state, 0,
129 (uint8_t *)ctx - (uint8_t *)&ctx->state + sizeof(peer_ctx));
130 ctx->state = STATE_NEW;
131 }
132
peer_ctx_free(peer_ctx * ctx)133 void peer_ctx_free(peer_ctx *ctx)
134 {
135 if(ctx->next) {
136 peer_ctx_free(ctx->next);
137 ctx->next = NULL;
138 }
139 mem_free(&ctx->last_dgm_hash); /* only free on free_peer_ctx */
140 peer_ctx_clear(ctx);
141 free(ctx);
142 }
143