|
Lines 60-74
Link Here
|
| 60 |
static uint8_t r_packet[2048]; |
60 |
static uint8_t r_packet[2048]; |
| 61 |
static ssize_t r_length; |
61 |
static ssize_t r_length; |
| 62 |
|
62 |
|
| 63 |
extern void vpnc_doit(unsigned long tous_spi, |
63 |
extern int vpnc_doit(unsigned long tous_spi, |
| 64 |
const unsigned char *tous_key, |
64 |
const unsigned char *tous_key, |
| 65 |
struct sockaddr_in *tous_dest, |
65 |
struct sockaddr_in *tous_dest, |
| 66 |
unsigned long tothem_spi, |
66 |
unsigned long tothem_spi, |
| 67 |
const unsigned char *tothem_key, |
67 |
const unsigned char *tothem_key, |
| 68 |
struct sockaddr_in *tothem_dest, |
68 |
struct sockaddr_in *tothem_dest, |
| 69 |
int tun_fd, int md_algo, int cry_algo, |
69 |
int tun_fd, int md_algo, int cry_algo, |
| 70 |
uint8_t * kill_packet_p, size_t kill_packet_size_p, |
|
|
| 71 |
struct sockaddr *kill_dest_p, |
| 72 |
uint16_t encap_mode, int isakmp_fd, |
70 |
uint16_t encap_mode, int isakmp_fd, |
| 73 |
const char *pidfile); |
71 |
const char *pidfile); |
| 74 |
|
72 |
|
|
Lines 332-337
Link Here
|
| 332 |
time_t start = time(NULL); |
330 |
time_t start = time(NULL); |
| 333 |
time_t end = 0; |
331 |
time_t end = 0; |
| 334 |
void *realtosend; |
332 |
void *realtosend; |
|
|
333 |
static uint32_t zero; |
| 335 |
|
334 |
|
| 336 |
pfd.fd = sockfd; |
335 |
pfd.fd = sockfd; |
| 337 |
pfd.events = POLLIN; |
336 |
pfd.events = POLLIN; |
|
Lines 365-372
Link Here
|
| 365 |
if (pollresult != 0) { |
364 |
if (pollresult != 0) { |
| 366 |
recvsize = recv_ignore_dup(recvbuf, recvbufsize); |
365 |
recvsize = recv_ignore_dup(recvbuf, recvbufsize); |
| 367 |
end = time(NULL); |
366 |
end = time(NULL); |
| 368 |
if (recvsize != -1) |
367 |
if (recvsize != -1) { |
| 369 |
break; |
368 |
if (encap_mode == IPSEC_ENCAP_TUNNEL || |
|
|
369 |
memcmp(recvbuf, &zero, sizeof(zero)) == 0) |
| 370 |
/* this hack drops ESP packets on NATed connections |
| 371 |
during rekeying, but it shouldn't matter much */ |
| 372 |
break; |
| 373 |
} |
| 370 |
continue; |
374 |
continue; |
| 371 |
} |
375 |
} |
| 372 |
|
376 |
|
|
Lines 383-389
Link Here
|
| 383 |
|
387 |
|
| 384 |
if (encap_mode != IPSEC_ENCAP_TUNNEL) { |
388 |
if (encap_mode != IPSEC_ENCAP_TUNNEL) { |
| 385 |
recvsize -= 4; /* 4 bytes non-esp marker */ |
389 |
recvsize -= 4; /* 4 bytes non-esp marker */ |
| 386 |
memcpy(recvbuf, recvbuf+4, recvsize); |
390 |
memmove(recvbuf, recvbuf+4, recvsize); |
| 387 |
} |
391 |
} |
| 388 |
|
392 |
|
| 389 |
/* Wait at least 2s for a response or 4 times the time it took |
393 |
/* Wait at least 2s for a response or 4 times the time it took |
|
Lines 396-401
Link Here
|
| 396 |
return recvsize; |
400 |
return recvsize; |
| 397 |
} |
401 |
} |
| 398 |
|
402 |
|
|
|
403 |
static void |
| 404 |
flushrecv(void) |
| 405 |
{ |
| 406 |
struct pollfd pfd; |
| 407 |
int recvsize = -1; |
| 408 |
struct sockaddr_in recvaddr; |
| 409 |
socklen_t recvaddr_size = sizeof(recvaddr); |
| 410 |
uint8_t r_packet[2048]; |
| 411 |
|
| 412 |
pfd.fd = sockfd; |
| 413 |
pfd.events = POLLIN; |
| 414 |
|
| 415 |
for (;;) { |
| 416 |
int pollresult; |
| 417 |
|
| 418 |
pollresult = poll(&pfd, 1, 0); |
| 419 |
|
| 420 |
if (pollresult <= 0) |
| 421 |
return; |
| 422 |
|
| 423 |
recvsize = recvfrom(sockfd, r_packet, sizeof(r_packet), 0, |
| 424 |
(struct sockaddr *)&recvaddr, &recvaddr_size); |
| 425 |
} |
| 426 |
} |
| 427 |
|
| 399 |
int isakmp_crypt(struct sa_block *s, uint8_t * block, size_t blocklen, int enc) |
428 |
int isakmp_crypt(struct sa_block *s, uint8_t * block, size_t blocklen, int enc) |
| 400 |
{ |
429 |
{ |
| 401 |
unsigned char *new_iv, *iv = NULL; |
430 |
unsigned char *new_iv, *iv = NULL; |
|
Lines 1882-1888
Link Here
|
| 1882 |
return r; |
1911 |
return r; |
| 1883 |
} |
1912 |
} |
| 1884 |
|
1913 |
|
| 1885 |
static void setup_link(struct sa_block *s) |
1914 |
static int setup_link(struct sa_block *s) |
| 1886 |
{ |
1915 |
{ |
| 1887 |
struct isakmp_payload *rp, *us, *ke = NULL, *them, *nonce_r = NULL; |
1916 |
struct isakmp_payload *rp, *us, *ke = NULL, *them, *nonce_r = NULL; |
| 1888 |
struct isakmp_packet *r; |
1917 |
struct isakmp_packet *r; |
|
Lines 1893-1898
Link Here
|
| 1893 |
size_t p_size = 0; |
1922 |
size_t p_size = 0; |
| 1894 |
uint8_t nonce[20], *dh_public = NULL; |
1923 |
uint8_t nonce[20], *dh_public = NULL; |
| 1895 |
int ipsec_cry_algo = 0, ipsec_hash_algo = 0, i; |
1924 |
int ipsec_cry_algo = 0, ipsec_hash_algo = 0, i; |
|
|
1925 |
static int rekey = 0; |
| 1926 |
static int tunnelfd = -1; |
| 1896 |
|
1927 |
|
| 1897 |
DEBUG(2, printf("S7.1\n")); |
1928 |
DEBUG(2, printf("S7.1\n")); |
| 1898 |
/* Set up the Diffie-Hellman stuff. */ |
1929 |
/* Set up the Diffie-Hellman stuff. */ |
|
Lines 1934-1939
Link Here
|
| 1934 |
msgid = 1; |
1965 |
msgid = 1; |
| 1935 |
|
1966 |
|
| 1936 |
DEBUG(2, printf("S7.2\n")); |
1967 |
DEBUG(2, printf("S7.2\n")); |
|
|
1968 |
|
| 1969 |
if(rekey) { |
| 1970 |
flushrecv(); |
| 1971 |
} |
| 1972 |
|
| 1937 |
for (i = 0; i < 4; i++) { |
1973 |
for (i = 0; i < 4; i++) { |
| 1938 |
sendrecv_phase2(s, rp, ISAKMP_EXCHANGE_IKE_QUICK, |
1974 |
sendrecv_phase2(s, rp, ISAKMP_EXCHANGE_IKE_QUICK, |
| 1939 |
msgid, 0, &p_flat, &p_size, 0, 0, 0, 0); |
1975 |
msgid, 0, &p_flat, &p_size, 0, 0, 0, 0); |
|
Lines 1946-1957
Link Here
|
| 1946 |
|
1982 |
|
| 1947 |
DEBUG(2, printf("S7.3\n")); |
1983 |
DEBUG(2, printf("S7.3\n")); |
| 1948 |
reject = unpack_verify_phase2(s, r_packet, r_length, &r, nonce, sizeof(nonce)); |
1984 |
reject = unpack_verify_phase2(s, r_packet, r_length, &r, nonce, sizeof(nonce)); |
|
|
1985 |
if (reject != 0 && reject != ISAKMP_N_AUTHENTICATION_FAILED) { |
| 1986 |
DEBUG(2, printf("ignoring bad packet, retrying\n")); |
| 1987 |
r_length = sendrecv(r_packet, sizeof(*r_packet), NULL, 0, 0); |
| 1988 |
continue; |
| 1989 |
} |
| 1949 |
|
1990 |
|
| 1950 |
DEBUG(2, printf("S7.4\n")); |
1991 |
DEBUG(2, printf("S7.4\n")); |
| 1951 |
if (((reject == 0) || (reject == ISAKMP_N_AUTHENTICATION_FAILED)) |
1992 |
if (((reject == 0) || (reject == ISAKMP_N_AUTHENTICATION_FAILED)) |
| 1952 |
&& r->exchange_type == ISAKMP_EXCHANGE_INFORMATIONAL) { |
1993 |
&& r->exchange_type == ISAKMP_EXCHANGE_INFORMATIONAL) { |
| 1953 |
/* handle notifie responder-lifetime (ignore) */ |
1994 |
/* handle notifie responder-lifetime (ignore) */ |
| 1954 |
/* (broken hash => ignore AUTHENTICATION_FAILED) */ |
1995 |
/* (broken hash => ignore AUTHENTICATION_FAILED) */ |
|
|
1996 |
if (reject == 0 |
| 1997 |
&& r->payload->next->type == ISAKMP_PAYLOAD_D && rekey) { |
| 1998 |
DEBUG(2, printf("ignoring delete old ESP SA notify\n")); |
| 1999 |
r_length = sendrecv(r_packet, sizeof(*r_packet), NULL, 0, 0); |
| 2000 |
continue; |
| 2001 |
} |
| 2002 |
|
| 1955 |
if (reject == 0 && r->payload->next->type != ISAKMP_PAYLOAD_N) |
2003 |
if (reject == 0 && r->payload->next->type != ISAKMP_PAYLOAD_N) |
| 1956 |
reject = ISAKMP_N_INVALID_PAYLOAD_TYPE; |
2004 |
reject = ISAKMP_N_INVALID_PAYLOAD_TYPE; |
| 1957 |
|
2005 |
|
|
Lines 2122-2172
Link Here
|
| 2122 |
nonce_r->u.nonce.data, nonce_r->u.nonce.length); |
2170 |
nonce_r->u.nonce.data, nonce_r->u.nonce.length); |
| 2123 |
|
2171 |
|
| 2124 |
DEBUG(2, printf("S7.7\n")); |
2172 |
DEBUG(2, printf("S7.7\n")); |
| 2125 |
/* Create the delete payload, now that we have all the information. */ |
|
|
| 2126 |
{ |
| 2127 |
struct isakmp_payload *d_isakmp, *d_ipsec; |
| 2128 |
uint32_t del_msgid; |
| 2129 |
|
| 2130 |
gcry_randomize((uint8_t *) & del_msgid, sizeof(del_msgid), GCRY_WEAK_RANDOM); |
| 2131 |
d_isakmp = new_isakmp_payload(ISAKMP_PAYLOAD_D); |
| 2132 |
d_isakmp->u.d.doi = ISAKMP_DOI_IPSEC; |
| 2133 |
d_isakmp->u.d.protocol = ISAKMP_IPSEC_PROTO_ISAKMP; |
| 2134 |
d_isakmp->u.d.spi_length = 2 * ISAKMP_COOKIE_LENGTH; |
| 2135 |
d_isakmp->u.d.num_spi = 1; |
| 2136 |
d_isakmp->u.d.spi = xallocc(1 * sizeof(uint8_t *)); |
| 2137 |
d_isakmp->u.d.spi[0] = xallocc(2 * ISAKMP_COOKIE_LENGTH); |
| 2138 |
memcpy(d_isakmp->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 0, s->i_cookie, |
| 2139 |
ISAKMP_COOKIE_LENGTH); |
| 2140 |
memcpy(d_isakmp->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 1, s->r_cookie, |
| 2141 |
ISAKMP_COOKIE_LENGTH); |
| 2142 |
d_ipsec = new_isakmp_payload(ISAKMP_PAYLOAD_D); |
| 2143 |
d_ipsec->next = d_isakmp; |
| 2144 |
d_ipsec->u.d.doi = ISAKMP_DOI_IPSEC; |
| 2145 |
d_ipsec->u.d.protocol = ISAKMP_IPSEC_PROTO_IPSEC_ESP; |
| 2146 |
d_ipsec->u.d.spi_length = 4; |
| 2147 |
d_ipsec->u.d.num_spi = 2; |
| 2148 |
d_ipsec->u.d.spi = xallocc(2 * sizeof(uint8_t *)); |
| 2149 |
d_ipsec->u.d.spi[0] = xallocc(d_ipsec->u.d.spi_length); |
| 2150 |
memcpy(d_ipsec->u.d.spi[0], &s->tous_esp_spi, 4); |
| 2151 |
d_ipsec->u.d.spi[1] = xallocc(d_ipsec->u.d.spi_length); |
| 2152 |
memcpy(d_ipsec->u.d.spi[1], &s->tothem_esp_spi, 4); |
| 2153 |
phase2_authpacket(s, d_ipsec, ISAKMP_EXCHANGE_INFORMATIONAL, |
| 2154 |
del_msgid, &s->kill_packet, &s->kill_packet_size, |
| 2155 |
nonce, sizeof(nonce), nonce_r->u.nonce.data, nonce_r->u.nonce.length); |
| 2156 |
isakmp_crypt(s, s->kill_packet, s->kill_packet_size, 1); |
| 2157 |
} |
| 2158 |
DEBUG(2, printf("S7.8\n")); |
| 2159 |
|
2173 |
|
| 2160 |
/* Set up the interface here so it's ready when our acknowledgement |
2174 |
/* Set up the interface here so it's ready when our acknowledgement |
| 2161 |
* arrives. */ |
2175 |
* arrives. */ |
| 2162 |
config_tunnel(); |
2176 |
if (!rekey) { |
| 2163 |
DEBUG(2, printf("S7.9\n")); |
2177 |
config_tunnel(); |
|
|
2178 |
} |
| 2179 |
|
| 2180 |
DEBUG(2, printf("S7.8\n")); |
| 2164 |
{ |
2181 |
{ |
| 2165 |
uint8_t *tous_keys, *tothem_keys; |
2182 |
uint8_t *tous_keys, *tothem_keys; |
| 2166 |
struct sockaddr_in tothem_dest, tous_dest; |
2183 |
struct sockaddr_in tothem_dest, tous_dest; |
| 2167 |
unsigned char *dh_shared_secret = NULL; |
2184 |
unsigned char *dh_shared_secret = NULL; |
| 2168 |
int tunnelfd = sockfd; |
2185 |
uint16_t em = encap_mode; |
| 2169 |
|
2186 |
|
| 2170 |
if (dh_grp) { |
2187 |
if (dh_grp) { |
| 2171 |
/* Determine the shared secret. */ |
2188 |
/* Determine the shared secret. */ |
| 2172 |
dh_shared_secret = xallocc(dh_getlen(dh_grp)); |
2189 |
dh_shared_secret = xallocc(dh_getlen(dh_grp)); |
|
Lines 2186-2206
Link Here
|
| 2186 |
nonce, sizeof(nonce), nonce_r->u.nonce.data, nonce_r->u.nonce.length); |
2203 |
nonce, sizeof(nonce), nonce_r->u.nonce.data, nonce_r->u.nonce.length); |
| 2187 |
memcpy(&tous_dest, dest_addr, sizeof(tous_dest)); |
2204 |
memcpy(&tous_dest, dest_addr, sizeof(tous_dest)); |
| 2188 |
if (opt_udpencap && s->peer_udpencap_port) { |
2205 |
if (opt_udpencap && s->peer_udpencap_port) { |
| 2189 |
close(tunnelfd); |
2206 |
if (!rekey) { |
| 2190 |
tunnelfd = make_socket(htons(opt_udpencapport)); |
2207 |
tunnelfd = make_socket(htons(opt_udpencapport)); |
|
|
2208 |
} |
| 2191 |
tous_dest.sin_port = htons(s->peer_udpencap_port); |
2209 |
tous_dest.sin_port = htons(s->peer_udpencap_port); |
| 2192 |
encap_mode = IPSEC_ENCAP_UDP_TUNNEL; |
2210 |
em = IPSEC_ENCAP_UDP_TUNNEL; |
|
|
2211 |
} else if (em != IPSEC_ENCAP_TUNNEL) { |
| 2212 |
tunnelfd = sockfd; |
| 2213 |
} else { |
| 2214 |
if (!rekey) { |
| 2215 |
tunnelfd = socket(PF_INET, SOCK_RAW, IPPROTO_ESP); |
| 2216 |
if (tunnelfd == -1) { |
| 2217 |
error(1, errno, "socket(SOCK_RAW) failed"); |
| 2218 |
} |
| 2219 |
} |
| 2193 |
} |
2220 |
} |
| 2194 |
if (dh_grp) |
2221 |
if (dh_grp) |
| 2195 |
group_free(dh_grp); |
2222 |
group_free(dh_grp); |
| 2196 |
DEBUG(2, printf("S7.10\n")); |
2223 |
DEBUG(2, printf("S7.9\n")); |
| 2197 |
vpnc_doit(s->tous_esp_spi, tous_keys, &tothem_dest, |
2224 |
reject = vpnc_doit(s->tous_esp_spi, tous_keys, &tothem_dest, |
| 2198 |
s->tothem_esp_spi, tothem_keys, (struct sockaddr_in *)&tous_dest, |
2225 |
s->tothem_esp_spi, tothem_keys, (struct sockaddr_in *)&tous_dest, |
| 2199 |
s->tun_fd, ipsec_hash_algo, ipsec_cry_algo, |
2226 |
s->tun_fd, ipsec_hash_algo, ipsec_cry_algo, em, tunnelfd, |
| 2200 |
s->kill_packet, s->kill_packet_size, dest_addr, |
|
|
| 2201 |
encap_mode, tunnelfd, |
| 2202 |
config[CONFIG_PID_FILE]); |
2227 |
config[CONFIG_PID_FILE]); |
|
|
2228 |
rekey = reject == 0; |
| 2229 |
} |
| 2230 |
|
| 2231 |
DEBUG(2, printf("S7.10\n")); |
| 2232 |
/* Create and send the delete payload. */ |
| 2233 |
if (reject != 0) { |
| 2234 |
struct isakmp_payload *d_isakmp = NULL, *d_ipsec; |
| 2235 |
uint32_t del_msgid; |
| 2236 |
|
| 2237 |
gcry_create_nonce((uint8_t *) & del_msgid, sizeof(del_msgid)); |
| 2238 |
d_isakmp = new_isakmp_payload(ISAKMP_PAYLOAD_D); |
| 2239 |
d_isakmp->u.d.doi = ISAKMP_DOI_IPSEC; |
| 2240 |
d_isakmp->u.d.protocol = ISAKMP_IPSEC_PROTO_ISAKMP; |
| 2241 |
d_isakmp->u.d.spi_length = 2 * ISAKMP_COOKIE_LENGTH; |
| 2242 |
d_isakmp->u.d.num_spi = 1; |
| 2243 |
d_isakmp->u.d.spi = xallocc(1 * sizeof(uint8_t *)); |
| 2244 |
d_isakmp->u.d.spi[0] = xallocc(2 * ISAKMP_COOKIE_LENGTH); |
| 2245 |
memcpy(d_isakmp->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 0, s->i_cookie, |
| 2246 |
ISAKMP_COOKIE_LENGTH); |
| 2247 |
memcpy(d_isakmp->u.d.spi[0] + ISAKMP_COOKIE_LENGTH * 1, s->r_cookie, |
| 2248 |
ISAKMP_COOKIE_LENGTH); |
| 2249 |
|
| 2250 |
d_ipsec = new_isakmp_payload(ISAKMP_PAYLOAD_D); |
| 2251 |
d_ipsec->next = d_isakmp; |
| 2252 |
d_ipsec->u.d.doi = ISAKMP_DOI_IPSEC; |
| 2253 |
d_ipsec->u.d.protocol = ISAKMP_IPSEC_PROTO_IPSEC_ESP; |
| 2254 |
d_ipsec->u.d.spi_length = 4; |
| 2255 |
d_ipsec->u.d.num_spi = 2; |
| 2256 |
d_ipsec->u.d.spi = xallocc(2 * sizeof(uint8_t *)); |
| 2257 |
d_ipsec->u.d.spi[0] = xallocc(d_ipsec->u.d.spi_length); |
| 2258 |
memcpy(d_ipsec->u.d.spi[0], &s->tous_esp_spi, 4); |
| 2259 |
d_ipsec->u.d.spi[1] = xallocc(d_ipsec->u.d.spi_length); |
| 2260 |
memcpy(d_ipsec->u.d.spi[1], &s->tothem_esp_spi, 4); |
| 2261 |
sendrecv_phase2(s, d_ipsec, ISAKMP_EXCHANGE_INFORMATIONAL, |
| 2262 |
del_msgid, 1, NULL, NULL, |
| 2263 |
NULL, 0, NULL, 0); |
| 2203 |
} |
2264 |
} |
|
|
2265 |
return reject; |
| 2204 |
} |
2266 |
} |
| 2205 |
|
2267 |
|
| 2206 |
int main(int argc, char **argv) |
2268 |
int main(int argc, char **argv) |
|
Lines 2239-2245
Link Here
|
| 2239 |
do_load_balance = do_phase_2_config(oursa); |
2301 |
do_load_balance = do_phase_2_config(oursa); |
| 2240 |
} while (do_load_balance); |
2302 |
} while (do_load_balance); |
| 2241 |
DEBUG(2, printf("S7\n")); |
2303 |
DEBUG(2, printf("S7\n")); |
| 2242 |
setup_link(oursa); |
2304 |
while(setup_link(oursa) == 0) { |
|
|
2305 |
DEBUG(2, printf("S7 Rekeying\n")); |
| 2306 |
} |
| 2243 |
DEBUG(2, printf("S8\n")); |
2307 |
DEBUG(2, printf("S8\n")); |
| 2244 |
setenv("reason", "disconnect", 1); |
2308 |
setenv("reason", "disconnect", 1); |
| 2245 |
system(config[CONFIG_SCRIPT]); |
2309 |
system(config[CONFIG_SCRIPT]); |