setup.c revision 1070097bb11002f8b5e289982cee9e324ea2f153
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20#include <unistd.h> 21#include <sys/param.h> 22#include <sys/types.h> 23#include <sys/socket.h> 24#include <netinet/in.h> 25#include <netinet/ip.h> 26#include <netdb.h> 27#include <fcntl.h> 28 29#include "config.h" 30#include "gcmalloc.h" 31#include "libpfkey.h" 32#include "var.h" 33#include "isakmp_var.h" 34#include "isakmp.h" 35#include "isakmp_xauth.h" 36#include "vmbuf.h" 37#include "crypto_openssl.h" 38#include "oakley.h" 39#include "ipsec_doi.h" 40#include "algorithm.h" 41#include "vendorid.h" 42#include "schedule.h" 43#include "pfkey.h" 44#include "nattraversal.h" 45#include "proposal.h" 46#include "sainfo.h" 47#include "localconf.h" 48#include "remoteconf.h" 49#include "sockmisc.h" 50#include "grabmyaddr.h" 51#include "plog.h" 52#include "admin.h" 53#include "privsep.h" 54#include "throttle.h" 55#include "misc.h" 56 57static struct localconf localconf; 58static struct sainfo sainfo; 59static char *pre_shared_key; 60 61static char *interface; 62static struct sockaddr *targets[2]; 63static struct { 64 struct sockaddr *addr; 65 int fd; 66} sources[2]; 67 68struct localconf *lcconf = &localconf; 69char *script_names[SCRIPT_MAX + 1]; 70int f_local = 0; 71 72/*****************************************************************************/ 73 74static void add_sainfo_algorithm(int class, int algorithm, int length) 75{ 76 struct sainfoalg *p = calloc(1, sizeof(struct sainfoalg)); 77 p->alg = algorithm; 78 p->encklen = length; 79 80 if (!sainfo.algs[class]) { 81 sainfo.algs[class] = p; 82 } else { 83 struct sainfoalg *q = sainfo.algs[class]; 84 while (q->next) { 85 q = q->next; 86 } 87 q->next = p; 88 } 89} 90 91static void set_globals(char *interfaze, char *server) 92{ 93 struct addrinfo hints = { 94 .ai_flags = AI_NUMERICSERV, 95#ifndef INET6 96 .ai_family = AF_INET, 97#else 98 .ai_family = AF_UNSPEC, 99#endif 100 .ai_socktype = SOCK_DGRAM, 101 }; 102 struct addrinfo *info; 103 104 if (getaddrinfo(server, "500", &hints, &info) != 0) { 105 do_plog(LLV_ERROR, "Cannot resolve address: %s\n", server); 106 exit(1); 107 } 108 if (info->ai_next) { 109 do_plog(LLV_WARNING, "Found multiple addresses. Use the first one.\n"); 110 } 111 targets[0] = dupsaddr(info->ai_addr); 112 freeaddrinfo(info); 113 114 interface = interfaze; 115 sources[0].addr = getlocaladdr(targets[0]); 116 if (!sources[0].addr) { 117 do_plog(LLV_ERROR, "Cannot get local address\n"); 118 exit(1); 119 } 120 set_port(targets[0], 0); 121 set_port(sources[0].addr, 0); 122 sources[0].fd = -1; 123 sources[1].addr = dupsaddr(sources[0].addr); 124 sources[1].fd = -1; 125 126 localconf.port_isakmp = PORT_ISAKMP; 127 localconf.port_isakmp_natt = PORT_ISAKMP_NATT; 128 localconf.default_af = AF_INET; 129 localconf.pathinfo[LC_PATHTYPE_CERT] = "./"; 130 localconf.pad_random = LC_DEFAULT_PAD_RANDOM; 131 localconf.pad_randomlen = LC_DEFAULT_PAD_RANDOM; 132 localconf.pad_strict = LC_DEFAULT_PAD_STRICT; 133 localconf.pad_excltail = LC_DEFAULT_PAD_EXCLTAIL; 134 localconf.retry_counter = 10; 135 localconf.retry_interval = 3; 136 localconf.count_persend = LC_DEFAULT_COUNT_PERSEND; 137 localconf.secret_size = LC_DEFAULT_SECRETSIZE; 138 localconf.retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1; 139 localconf.wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE; 140 localconf.natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL; 141 142 sainfo.lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; 143 sainfo.lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX; 144 add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0); 145 add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0); 146 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0); 147 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0); 148 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128); 149} 150 151/*****************************************************************************/ 152 153static int policy_match(struct sadb_address *address) 154{ 155 if (address) { 156 struct sockaddr *addr = PFKEY_ADDR_SADDR(address); 157 return cmpsaddr(addr, targets[0]) < CMPSADDR_MISMATCH || 158 cmpsaddr(addr, targets[1]) < CMPSADDR_MISMATCH; 159 } 160 return 0; 161} 162 163/* flush; spdflush; */ 164static void flush() 165{ 166 struct sadb_msg *p; 167 int replies = 0; 168 int key = pfkey_open(); 169 170 if (pfkey_send_dump(key, SADB_SATYPE_UNSPEC) <= 0 || 171 pfkey_send_spddump(key) <= 0) { 172 do_plog(LLV_ERROR, "Cannot dump SAD and SPD\n"); 173 exit(1); 174 } 175 176 for (p = NULL; replies < 2 && (p = pfkey_recv(key)) != NULL; free(p)) { 177 caddr_t q[SADB_EXT_MAX + 1]; 178 179 if (p->sadb_msg_type != SADB_DUMP && 180 p->sadb_msg_type != SADB_X_SPDDUMP) { 181 continue; 182 } 183 replies += !p->sadb_msg_seq; 184 185 if (p->sadb_msg_errno || pfkey_align(p, q) || pfkey_check(q)) { 186 continue; 187 } 188 if (policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_SRC]) || 189 policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_DST])) { 190 p->sadb_msg_type = (p->sadb_msg_type == SADB_DUMP) ? 191 SADB_DELETE : SADB_X_SPDDELETE; 192 p->sadb_msg_reserved = 0; 193 p->sadb_msg_seq = 0; 194 pfkey_send(key, p, PFKEY_UNUNIT64(p->sadb_msg_len)); 195 } 196 } 197 198 pfkey_close(key); 199} 200 201/* flush; spdflush; 202 * spdadd src dst protocol -P out ipsec esp/transport//require; OR 203 * spdadd src any protocol -P out ipsec esp/tunnel/local-remote/require; */ 204static void spdadd(struct sockaddr *src, struct sockaddr *dst, 205 int protocol, struct sockaddr *local, struct sockaddr *remote) 206{ 207 struct __attribute__((packed)) { 208 struct sadb_x_policy p; 209 struct sadb_x_ipsecrequest q; 210 char addresses[sizeof(struct sockaddr_storage) * 2]; 211 } policy; 212 213 struct sockaddr_storage any = { 214#ifndef __linux__ 215 .ss_len = src->sa_len, 216#endif 217 .ss_family = src->sa_family, 218 }; 219 220 int src_prefix = (src->sa_family == AF_INET) ? 32 : 128; 221 int dst_prefix = src_prefix; 222 int length = 0; 223 int key; 224 225 /* Fill default values. */ 226 memset(&policy, 0, sizeof(policy)); 227 policy.p.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 228 policy.p.sadb_x_policy_type = IPSEC_POLICY_IPSEC; 229 policy.p.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND; 230#ifdef HAVE_PFKEY_POLICY_PRIORITY 231 policy.p.sadb_x_policy_priority = PRIORITY_DEFAULT; 232#endif 233 policy.q.sadb_x_ipsecrequest_proto = IPPROTO_ESP; 234 policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT; 235 policy.q.sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; 236 237 /* Deal with tunnel mode. */ 238 if (!dst) { 239 policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL; 240 dst = (struct sockaddr *)&any; 241 dst_prefix = 0; 242 243 length = sysdep_sa_len(local); 244 memcpy(policy.addresses, local, length); 245 memcpy(&policy.addresses[length], remote, length); 246 length += length; 247 248 /* Also use the source address to filter policies. */ 249 targets[1] = dupsaddr(src); 250 } 251 252 /* Fix lengths. */ 253 length += sizeof(policy.q); 254 policy.q.sadb_x_ipsecrequest_len = length; 255 length += sizeof(policy.p); 256 policy.p.sadb_x_policy_len = PFKEY_UNIT64(length); 257 258 /* Always do a flush before adding the new policy. */ 259 flush(); 260 key = pfkey_open(); 261 if (pfkey_send_spdadd(key, src, src_prefix, dst, dst_prefix, protocol, 262 (caddr_t)&policy, length, 0) <= 0) { 263 do_plog(LLV_ERROR, "Cannot initialize SAD and SPD\n"); 264 exit(1); 265 } 266 pfkey_close(key); 267 atexit(flush); 268} 269 270/*****************************************************************************/ 271 272static void add_proposal(struct remoteconf *remoteconf, 273 int auth, int hash, int encryption, int length) 274{ 275 struct isakmpsa *p = racoon_calloc(1, sizeof(struct isakmpsa)); 276 p->prop_no = 1; 277 p->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT; 278 p->enctype = encryption; 279 p->encklen = length; 280 p->authmethod = auth; 281 p->hashtype = hash; 282 p->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024; 283 p->vendorid = VENDORID_UNKNOWN; 284 285 if (!remoteconf->proposal) { 286 p->trns_no = 1; 287 remoteconf->proposal = p; 288 } else { 289 struct isakmpsa *q = remoteconf->proposal; 290 while (q->next) { 291 q = q->next; 292 } 293 p->trns_no = q->trns_no + 1; 294 q->next = p; 295 } 296} 297 298static vchar_t *get_certificate(char *type, char *file) 299{ 300 char path[PATH_MAX + 1]; 301 vchar_t *certificate = NULL; 302 303 getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file); 304 certificate = eay_get_x509cert(path); 305 if (!certificate) { 306 do_plog(LLV_ERROR, "Cannot load %s certificate\n", type); 307 exit(1); 308 } 309 return certificate; 310} 311 312static void set_certificates(struct remoteconf *remoteconf, 313 char *user_private_key, char *user_certificate, char *ca_certificate) 314{ 315 remoteconf->myprivfile = user_private_key; 316 remoteconf->mycertfile = user_certificate; 317 if (user_certificate) { 318 remoteconf->mycert = get_certificate("user", user_certificate); 319 } 320 if (!ca_certificate[0]) { 321 remoteconf->verify_cert = FALSE; 322 } else { 323 remoteconf->cacertfile = ca_certificate; 324 remoteconf->cacert = get_certificate("CA", ca_certificate); 325 } 326 remoteconf->idvtype = IDTYPE_ASN1DN; 327} 328 329static vchar_t *strtovchar(char *string) 330{ 331 vchar_t *vchar = string ? vmalloc(strlen(string) + 1) : NULL; 332 if (vchar) { 333 memcpy(vchar->v, string, vchar->l); 334 } 335 return vchar; 336} 337 338#ifdef ENABLE_HYBRID 339 340static void set_xauth_and_more(struct remoteconf *remoteconf, 341 char *username, char *password, char *phase1_up, char *script_arg) 342{ 343 struct xauth_rmconf *xauth = racoon_calloc(1, sizeof(struct xauth_rmconf)); 344 xauth->login = strtovchar(username); 345 xauth->pass = strtovchar(password); 346 remoteconf->xauth = xauth; 347 remoteconf->mode_cfg = TRUE; 348 remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar(phase1_up); 349 script_names[SCRIPT_PHASE1_UP] = script_arg; 350} 351 352#endif 353 354void setup(int argc, char **argv) 355{ 356 struct remoteconf *remoteconf = NULL; 357 int auth; 358 359 if (argc > 2) { 360 set_globals(argv[1], argv[2]); 361 362 /* Initialize everything else. */ 363 eay_init(); 364 initrmconf(); 365 oakley_dhinit(); 366 compute_vendorids(); 367 sched_init(); 368 if (pfkey_init() < 0 || isakmp_init() < 0) { 369 exit(1); 370 } 371#ifdef ENABLE_NATT 372 natt_keepalive_init(); 373#endif 374 375 /* Create remote configuration. */ 376 remoteconf = newrmconf(); 377 remoteconf->etypes = racoon_calloc(1, sizeof(struct etypes)); 378 remoteconf->etypes->type = ISAKMP_ETYPE_IDENT; 379 remoteconf->ike_frag = TRUE; 380 remoteconf->pcheck_level = PROP_CHECK_OBEY; 381 remoteconf->gen_policy = TRUE; 382 remoteconf->nat_traversal = TRUE; 383 remoteconf->remote = dupsaddr(targets[0]); 384 set_port(remoteconf->remote, localconf.port_isakmp); 385 } 386 387 /* Set authentication method and credentials. */ 388 if (argc == 6 && !strcmp(argv[3], "udppsk")) { 389 pre_shared_key = argv[4]; 390 remoteconf->idvtype = IDTYPE_ADDRESS; 391 auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY; 392 393 set_port(targets[0], atoi(argv[5])); 394 spdadd(sources[0].addr, targets[0], IPPROTO_UDP, NULL, NULL); 395 } else if (argc == 8 && !strcmp(argv[3], "udprsa")) { 396 set_certificates(remoteconf, argv[4], argv[5], argv[6]); 397 auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG; 398 399 set_port(targets[0], atoi(argv[7])); 400 spdadd(sources[0].addr, targets[0], IPPROTO_UDP, NULL, NULL); 401#ifdef ENABLE_HYBRID 402 } else if (argc == 10 && !strcmp(argv[3], "xauthpsk")) { 403 pre_shared_key = argv[5]; 404 remoteconf->idvtype = IDTYPE_ADDRESS; 405 if (*argv[4]) { 406 remoteconf->idv = strtovchar(argv[4]); 407 /* We might want to add some heuristics to detect the type? */ 408 remoteconf->idvtype = IDTYPE_KEYID; 409 } 410 set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]); 411 auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; 412 } else if (argc == 11 && !strcmp(argv[3], "xauthrsa")) { 413 set_certificates(remoteconf, argv[4], argv[5], argv[6]); 414 set_xauth_and_more(remoteconf, argv[7], argv[8], argv[9], argv[10]); 415 auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; 416 } else if (argc == 9 && !strcmp(argv[3], "hybridrsa")) { 417 set_certificates(remoteconf, NULL, NULL, argv[4]); 418 set_xauth_and_more(remoteconf, argv[5], argv[6], argv[7], argv[8]); 419 auth = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; 420#endif 421 } else { 422 printf("Usage: %s <interface> <server> [...], where [...] can be:\n" 423 " udppsk <pre-shared-key> <port>\n" 424 " udprsa <user-private-key> <user-cert> <ca-cert> <port>\n" 425#ifdef ENABLE_HYBRID 426 " xauthpsk <identifier> <pre-shared-key>" 427 " <username> <password> <phase1-up> <script-arg>\n" 428 " xauthrsa <user-private-key> <user-cert> <ca-cert>" 429 " <username> <password> <phase1-up> <script-arg>\n" 430 " hybridrsa <ca-cert>" 431 " <username> <password> <phase1-up> <script-arg>\n" 432#endif 433 "", argv[0]); 434 exit(0); 435 } 436 437 /* Add proposals. */ 438 add_proposal(remoteconf, auth, 439 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_3DES, 0); 440 add_proposal(remoteconf, auth, 441 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_3DES, 0); 442 add_proposal(remoteconf, auth, 443 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_DES, 0); 444 add_proposal(remoteconf, auth, 445 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_DES, 0); 446 add_proposal(remoteconf, auth, 447 OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 128); 448 add_proposal(remoteconf, auth, 449 OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 128); 450 451 /* Install remote configuration. */ 452 insrmconf(remoteconf); 453 454 /* Create ISAKMP sockets. */ 455 set_port(sources[0].addr, localconf.port_isakmp); 456 sources[0].fd = isakmp_open(sources[0].addr, FALSE); 457 if (sources[0].fd == -1) { 458 do_plog(LLV_ERROR, "Cannot create ISAKMP socket\n"); 459 exit(1); 460 } 461#ifdef ENABLE_NATT 462 set_port(sources[1].addr, localconf.port_isakmp_natt); 463 sources[1].fd = isakmp_open(sources[1].addr, TRUE); 464 if (sources[1].fd == -1) { 465 do_plog(LLV_WARNING, "Cannot create ISAKMP socket for NAT-T\n"); 466 } 467#endif 468 469 /* Start phase 1 negotiation for xauth. */ 470 if (remoteconf->xauth) { 471 isakmp_ph1begin_i(remoteconf, remoteconf->remote, sources[0].addr); 472 } 473} 474 475/*****************************************************************************/ 476 477/* localconf.h */ 478 479vchar_t *getpskbyaddr(struct sockaddr *addr) 480{ 481 return strtovchar(pre_shared_key); 482} 483 484vchar_t *getpskbyname(vchar_t *name) 485{ 486 return NULL; 487} 488 489void getpathname(char *path, int length, int type, const char *name) 490{ 491 if (pname) { 492 snprintf(path, length, pname, name); 493 } else { 494 strncpy(path, name, length); 495 } 496 path[length - 1] = '\0'; 497} 498 499/* grabmyaddr.h */ 500 501int myaddr_getsport(struct sockaddr *addr) 502{ 503 return 0; 504} 505 506int myaddr_getfd(struct sockaddr *addr) 507{ 508#ifdef ENABLE_NATT 509 if (sources[1].fd != -1 && 510 cmpsaddr(addr, sources[1].addr) == CMPSADDR_MATCH) { 511 return sources[1].fd; 512 } 513#endif 514 if (cmpsaddr(addr, sources[0].addr) < CMPSADDR_MISMATCH) { 515 return sources[0].fd; 516 } 517 return -1; 518} 519 520/* privsep.h */ 521 522int privsep_socket(int domain, int type, int protocol) 523{ 524 int fd = socket(domain, type, protocol); 525 if ((domain == AF_INET || domain == AF_INET6) && setsockopt( 526 fd, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface))) { 527 do_plog(LLV_WARNING, "Cannot bind socket to %s\n", interface); 528 } 529 return fd; 530} 531 532int privsep_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) 533{ 534 return bind(fd, addr, addrlen); 535} 536 537vchar_t *privsep_eay_get_pkcs1privkey(char *file) 538{ 539 return eay_get_pkcs1privkey(file); 540} 541 542static char *get_env(char * const *envp, char *key) 543{ 544 int length = strlen(key); 545 while (*envp && (strncmp(*envp, key, length) || (*envp)[length] != '=')) { 546 ++envp; 547 } 548 return *envp ? &(*envp)[length + 1] : ""; 549} 550 551extern void android_setenv(char ***envp); 552 553int privsep_script_exec(char *script, int name, char * const *envp) 554{ 555 /* Racoon ignores INTERNAL_IP6_ADDRESS, so we only do IPv4. */ 556 struct sockaddr *addr4 = str2saddr(get_env(envp, "INTERNAL_ADDR4"), NULL); 557 struct sockaddr *local = str2saddr(get_env(envp, "LOCAL_ADDR"), 558 get_env(envp, "LOCAL_PORT")); 559 struct sockaddr *remote = str2saddr(get_env(envp, "REMOTE_ADDR"), 560 get_env(envp, "REMOTE_PORT")); 561 562 if (addr4 && local && remote) { 563#ifdef ANDROID_CHANGES 564 android_setenv((char ***)&envp); 565#endif 566 spdadd(addr4, NULL, IPPROTO_IP, local, remote); 567 } else { 568 do_plog(LLV_ERROR, "Cannot find parameters to generate SPD policy.\n"); 569 exit(1); 570 } 571 572 racoon_free(addr4); 573 racoon_free(local); 574 racoon_free(remote); 575 return script ? script_exec(script, name, envp) : -1; 576} 577 578int privsep_accounting_system(int port, struct sockaddr *addr, 579 char *user, int status) 580{ 581 return 0; 582} 583 584int privsep_xauth_login_system(char *user, char *password) 585{ 586 return -1; 587} 588 589/* misc.h */ 590 591int racoon_hexdump(void *data, size_t length) 592{ 593 return 0; 594} 595 596void close_on_exec(int fd) 597{ 598 fcntl(fd, F_SETFD, FD_CLOEXEC); 599} 600 601/* sainfo.h */ 602 603struct sainfo *getsainfo(const vchar_t *src, const vchar_t *dst, 604 const vchar_t *peer, const vchar_t *client, uint32_t remoteid) 605{ 606 return &sainfo; 607} 608 609const char *sainfo2str(const struct sainfo *si) 610{ 611 return "*"; 612} 613 614/* throttle.h */ 615 616int throttle_host(struct sockaddr *addr, int fail) 617{ 618 return 0; 619} 620