Home | History | Annotate | Download | only in ipsec-tools
      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 
     57 static struct localconf localconf;
     58 static struct sainfo sainfo;
     59 static char *pre_shared_key;
     60 
     61 static struct sockaddr *targets[2];
     62 static struct sockaddr *source;
     63 static struct myaddrs myaddrs[2];
     64 
     65 struct localconf *lcconf = &localconf;
     66 int f_local = 0;
     67 
     68 /*****************************************************************************/
     69 
     70 static void add_sainfo_algorithm(int class, int algorithm, int length)
     71 {
     72     struct sainfoalg *p = calloc(1, sizeof(struct sainfoalg));
     73     p->alg = algorithm;
     74     p->encklen = length;
     75 
     76     if (!sainfo.algs[class]) {
     77         sainfo.algs[class] = p;
     78     } else {
     79         struct sainfoalg *q = sainfo.algs[class];
     80         while (q->next) {
     81             q = q->next;
     82         }
     83         q->next = p;
     84     }
     85 }
     86 
     87 static void set_globals(char *server)
     88 {
     89     struct addrinfo hints = {
     90         .ai_flags = AI_NUMERICSERV,
     91 #ifndef INET6
     92         .ai_family = AF_INET,
     93 #else
     94         .ai_family = AF_UNSPEC,
     95 #endif
     96         .ai_socktype = SOCK_DGRAM,
     97     };
     98     struct addrinfo *info;
     99 
    100     if (getaddrinfo(server, "500", &hints, &info) != 0) {
    101         do_plog(LLV_ERROR, "Cannot resolve address: %s\n", server);
    102         exit(1);
    103     }
    104     if (info->ai_next) {
    105         do_plog(LLV_WARNING, "Found multiple addresses. Use the first one.\n");
    106     }
    107     targets[0] = dupsaddr(info->ai_addr);
    108     freeaddrinfo(info);
    109 
    110     source = getlocaladdr(targets[0]);
    111     if (!source) {
    112         do_plog(LLV_ERROR, "Cannot get local address\n");
    113         exit(1);
    114     }
    115     set_port(targets[0], 0);
    116     set_port(source, 0);
    117 
    118     myaddrs[0].addr = dupsaddr(source);
    119     set_port(myaddrs[0].addr, PORT_ISAKMP);
    120     myaddrs[0].sock = -1;
    121 #ifdef ENABLE_NATT
    122     myaddrs[0].next = &myaddrs[1];
    123     myaddrs[1].addr = dupsaddr(myaddrs[0].addr);
    124     set_port(myaddrs[1].addr, PORT_ISAKMP_NATT);
    125     myaddrs[1].sock = -1;
    126     myaddrs[1].udp_encap = 1;
    127 #endif
    128 
    129     localconf.myaddrs = &myaddrs[0];
    130     localconf.port_isakmp = PORT_ISAKMP;
    131     localconf.port_isakmp_natt = PORT_ISAKMP_NATT;
    132     localconf.default_af = AF_INET;
    133     localconf.pathinfo[LC_PATHTYPE_CERT] = "./";
    134     localconf.pad_random = LC_DEFAULT_PAD_RANDOM;
    135     localconf.pad_randomlen = LC_DEFAULT_PAD_RANDOM;
    136     localconf.pad_strict = LC_DEFAULT_PAD_STRICT;
    137     localconf.pad_excltail = LC_DEFAULT_PAD_EXCLTAIL;
    138     localconf.retry_counter = 10;
    139     localconf.retry_interval = 3;
    140     localconf.count_persend = LC_DEFAULT_COUNT_PERSEND;
    141     localconf.secret_size = LC_DEFAULT_SECRETSIZE;
    142     localconf.retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1;
    143     localconf.wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE;
    144     localconf.natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;
    145 
    146     sainfo.lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
    147     sainfo.lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
    148     add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, 0);
    149     add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0);
    150     add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0);
    151     add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 256);
    152     add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128);
    153     add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0);
    154     add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0);
    155 
    156     memset(script_names, 0, sizeof(script_names));
    157 }
    158 
    159 /*****************************************************************************/
    160 
    161 static int policy_match(struct sadb_address *address)
    162 {
    163     if (address) {
    164         struct sockaddr *addr = PFKEY_ADDR_SADDR(address);
    165         return !cmpsaddrwop(addr, targets[0]) || !cmpsaddrwop(addr, targets[1]);
    166     }
    167     return 0;
    168 }
    169 
    170 /* flush; spdflush; */
    171 static void flush()
    172 {
    173     struct sadb_msg *p;
    174     int replies = 0;
    175     int key = pfkey_open();
    176 
    177     if (pfkey_send_dump(key, SADB_SATYPE_UNSPEC) <= 0 ||
    178         pfkey_send_spddump(key) <= 0) {
    179         do_plog(LLV_ERROR, "Cannot dump SAD and SPD\n");
    180         exit(1);
    181     }
    182 
    183     for (p = NULL; replies < 2 && (p = pfkey_recv(key)) != NULL; free(p)) {
    184         caddr_t q[SADB_EXT_MAX + 1];
    185 
    186         if (p->sadb_msg_type != SADB_DUMP &&
    187             p->sadb_msg_type != SADB_X_SPDDUMP) {
    188             continue;
    189         }
    190         replies += !p->sadb_msg_seq;
    191 
    192         if (p->sadb_msg_errno || pfkey_align(p, q) || pfkey_check(q)) {
    193             continue;
    194         }
    195         if (policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_SRC]) ||
    196             policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_DST])) {
    197             p->sadb_msg_type = (p->sadb_msg_type == SADB_DUMP) ?
    198                                SADB_DELETE : SADB_X_SPDDELETE;
    199             p->sadb_msg_reserved = 0;
    200             p->sadb_msg_seq = 0;
    201             pfkey_send(key, p, PFKEY_UNUNIT64(p->sadb_msg_len));
    202         }
    203     }
    204 
    205     pfkey_close(key);
    206 }
    207 
    208 /* spdadd src dst protocol -P out ipsec esp/transport//require;
    209  * spdadd dst src protocol -P in  ipsec esp/transport//require;
    210  * or
    211  * spdadd src any protocol -P out ipsec esp/tunnel/local-remote/require;
    212  * spdadd any src protocol -P in  ipsec esp/tunnel/remote-local/require; */
    213 static void spdadd(struct sockaddr *src, struct sockaddr *dst,
    214         int protocol, struct sockaddr *local, struct sockaddr *remote)
    215 {
    216     struct __attribute__((packed)) {
    217         struct sadb_x_policy p;
    218         struct sadb_x_ipsecrequest q;
    219         char addresses[sizeof(struct sockaddr_storage) * 2];
    220     } policy;
    221 
    222     struct sockaddr_storage any = {
    223 #ifndef __linux__
    224         .ss_len = src->sa_len,
    225 #endif
    226         .ss_family = src->sa_family,
    227     };
    228 
    229     int src_prefix = (src->sa_family == AF_INET) ? 32 : 128;
    230     int dst_prefix = src_prefix;
    231     int length = 0;
    232     int key;
    233 
    234     /* Fill values for outbound policy. */
    235     memset(&policy, 0, sizeof(policy));
    236     policy.p.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
    237     policy.p.sadb_x_policy_type = IPSEC_POLICY_IPSEC;
    238     policy.p.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
    239 #ifdef HAVE_PFKEY_POLICY_PRIORITY
    240     policy.p.sadb_x_policy_priority = PRIORITY_DEFAULT;
    241 #endif
    242     policy.q.sadb_x_ipsecrequest_proto = IPPROTO_ESP;
    243     policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT;
    244     policy.q.sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
    245 
    246     /* Deal with tunnel mode. */
    247     if (!dst) {
    248         int size = sysdep_sa_len(local);
    249         memcpy(policy.addresses, local, size);
    250         memcpy(&policy.addresses[size], remote, size);
    251         length += size + size;
    252 
    253         policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL;
    254         dst = (struct sockaddr *)&any;
    255         dst_prefix = 0;
    256 
    257         /* Also use the source address to filter policies. */
    258         targets[1] = dupsaddr(src);
    259     }
    260 
    261     /* Fix lengths. */
    262     length += sizeof(policy.q);
    263     policy.q.sadb_x_ipsecrequest_len = length;
    264     length += sizeof(policy.p);
    265     policy.p.sadb_x_policy_len = PFKEY_UNIT64(length);
    266 
    267     /* Always do a flush before adding new policies. */
    268     flush();
    269 
    270     /* Set outbound policy. */
    271     key = pfkey_open();
    272     if (pfkey_send_spdadd(key, src, src_prefix, dst, dst_prefix, protocol,
    273             (caddr_t)&policy, length, 0) <= 0) {
    274         do_plog(LLV_ERROR, "Cannot set outbound policy\n");
    275         exit(1);
    276     }
    277 
    278     /* Flip values for inbound policy. */
    279     policy.p.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
    280     if (!dst_prefix) {
    281         int size = sysdep_sa_len(local);
    282         memcpy(policy.addresses, remote, size);
    283         memcpy(&policy.addresses[size], local, size);
    284     }
    285 
    286     /* Set inbound policy. */
    287     if (pfkey_send_spdadd(key, dst, dst_prefix, src, src_prefix, protocol,
    288             (caddr_t)&policy, length, 0) <= 0) {
    289         do_plog(LLV_ERROR, "Cannot set inbound policy\n");
    290         exit(1);
    291     }
    292 
    293     pfkey_close(key);
    294     atexit(flush);
    295 }
    296 
    297 /*****************************************************************************/
    298 
    299 static void add_proposal(struct remoteconf *remoteconf,
    300         int auth, int hash, int encryption, int length)
    301 {
    302     struct isakmpsa *p = racoon_calloc(1, sizeof(struct isakmpsa));
    303     p->prop_no = 1;
    304     p->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
    305     p->enctype = encryption;
    306     p->encklen = length;
    307     p->authmethod = auth;
    308     p->hashtype = hash;
    309     p->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
    310     p->vendorid = VENDORID_UNKNOWN;
    311     p->rmconf = remoteconf;
    312 
    313     if (!remoteconf->proposal) {
    314       p->trns_no = 1;
    315       remoteconf->proposal = p;
    316     } else {
    317         struct isakmpsa *q = remoteconf->proposal;
    318         while (q->next) {
    319             q = q->next;
    320         }
    321         p->trns_no = q->trns_no + 1;
    322         q->next = p;
    323     }
    324 }
    325 
    326 static vchar_t *strtovchar(char *string)
    327 {
    328     vchar_t *vchar = string ? vmalloc(strlen(string) + 1) : NULL;
    329     if (vchar) {
    330         memcpy(vchar->v, string, vchar->l);
    331         vchar->l -= 1;
    332     }
    333     return vchar;
    334 }
    335 
    336 static void set_pre_shared_key(struct remoteconf *remoteconf,
    337         char *identifier, char *key)
    338 {
    339     pre_shared_key = key;
    340     if (identifier[0]) {
    341         remoteconf->idv = strtovchar(identifier);
    342         remoteconf->etypes->type = ISAKMP_ETYPE_AGG;
    343 
    344         remoteconf->idvtype = IDTYPE_KEYID;
    345         if (strchr(identifier, '.')) {
    346             remoteconf->idvtype = IDTYPE_FQDN;
    347             if (strchr(identifier, '@')) {
    348                 remoteconf->idvtype = IDTYPE_USERFQDN;
    349             }
    350         }
    351     }
    352 }
    353 
    354 static void set_certificates(struct remoteconf *remoteconf,
    355         char *user_private_key, char *user_certificate,
    356         char *ca_certificate, char *server_certificate)
    357 {
    358     remoteconf->myprivfile = user_private_key;
    359     remoteconf->mycertfile = user_certificate;
    360     if (user_certificate) {
    361         remoteconf->idvtype = IDTYPE_ASN1DN;
    362     }
    363     if (!ca_certificate[0]) {
    364         remoteconf->verify_cert = FALSE;
    365     } else {
    366         remoteconf->cacertfile = ca_certificate;
    367     }
    368     if (server_certificate[0]) {
    369         remoteconf->peerscertfile = server_certificate;
    370         remoteconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
    371     }
    372 }
    373 
    374 #ifdef ENABLE_HYBRID
    375 
    376 static void set_xauth_and_more(struct remoteconf *remoteconf,
    377         char *username, char *password, char *phase1_up, char *script_arg)
    378 {
    379     struct xauth_rmconf *xauth = racoon_calloc(1, sizeof(struct xauth_rmconf));
    380     xauth->login = strtovchar(username);
    381     xauth->login->l += 1;
    382     xauth->pass = strtovchar(password);
    383     xauth->pass->l += 1;
    384     remoteconf->xauth = xauth;
    385     remoteconf->mode_cfg = TRUE;
    386     remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar(phase1_up);
    387     script_names[SCRIPT_PHASE1_UP] = script_arg;
    388 }
    389 
    390 #endif
    391 
    392 extern void monitor_fd(int fd, void (*callback)(int));
    393 
    394 void add_isakmp_handler(int fd, const char *interface)
    395 {
    396     if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
    397             interface, strlen(interface))) {
    398         do_plog(LLV_WARNING, "Cannot bind socket to %s\n", interface);
    399     }
    400     monitor_fd(fd, (void *)isakmp_handler);
    401 }
    402 
    403 void setup(int argc, char **argv)
    404 {
    405     struct remoteconf *remoteconf = NULL;
    406     int auth;
    407 
    408     if (argc > 2) {
    409         set_globals(argv[2]);
    410 
    411         /* Initialize everything else. */
    412         eay_init();
    413         initrmconf();
    414         oakley_dhinit();
    415         compute_vendorids();
    416         sched_init();
    417         if (pfkey_init() < 0 || isakmp_init() < 0) {
    418             exit(1);
    419         }
    420         monitor_fd(localconf.sock_pfkey, (void *)pfkey_handler);
    421         add_isakmp_handler(myaddrs[0].sock, argv[1]);
    422 #ifdef ENABLE_NATT
    423         add_isakmp_handler(myaddrs[1].sock, argv[1]);
    424         natt_keepalive_init();
    425 #endif
    426 
    427         /* Create remote configuration. */
    428         remoteconf = newrmconf();
    429         remoteconf->etypes = racoon_calloc(1, sizeof(struct etypes));
    430         remoteconf->etypes->type = ISAKMP_ETYPE_IDENT;
    431         remoteconf->idvtype = IDTYPE_ADDRESS;
    432         remoteconf->ike_frag = TRUE;
    433         remoteconf->pcheck_level = PROP_CHECK_CLAIM;
    434         remoteconf->certtype = ISAKMP_CERT_X509SIGN;
    435         remoteconf->gen_policy = TRUE;
    436         remoteconf->nat_traversal = TRUE;
    437         remoteconf->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
    438         remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar("");
    439         remoteconf->script[SCRIPT_PHASE1_DOWN] = strtovchar("");
    440         oakley_setdhgroup(remoteconf->dh_group, &remoteconf->dhgrp);
    441         remoteconf->remote = dupsaddr(targets[0]);
    442     }
    443 
    444     /* Set authentication method and credentials. */
    445     if (argc == 7 && !strcmp(argv[3], "udppsk")) {
    446         set_pre_shared_key(remoteconf, argv[4], argv[5]);
    447         auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY;
    448 
    449         set_port(targets[0], atoi(argv[6]));
    450         spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
    451     } else if (argc == 9 && !strcmp(argv[3], "udprsa")) {
    452         set_certificates(remoteconf, argv[4], argv[5], argv[6], argv[7]);
    453         auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG;
    454 
    455         set_port(targets[0], atoi(argv[8]));
    456         spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
    457 #ifdef ENABLE_HYBRID
    458     } else if (argc == 10 && !strcmp(argv[3], "xauthpsk")) {
    459         set_pre_shared_key(remoteconf, argv[4], argv[5]);
    460         set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]);
    461         auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
    462     } else if (argc == 12 && !strcmp(argv[3], "xauthrsa")) {
    463         set_certificates(remoteconf, argv[4], argv[5], argv[6], argv[7]);
    464         set_xauth_and_more(remoteconf, argv[8], argv[9], argv[10], argv[11]);
    465         auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
    466     } else if (argc == 10 && !strcmp(argv[3], "hybridrsa")) {
    467         set_certificates(remoteconf, NULL, NULL, argv[4], argv[5]);
    468         set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]);
    469         auth = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
    470 #endif
    471     } else {
    472         printf("Usage: %s <interface> <server> [...], where [...] can be:\n"
    473                 " udppsk    <identifier> <pre-shared-key> <port>; \n"
    474                 " udprsa    <user-private-key> <user-certificate> \\\n"
    475                 "           <ca-certificate> <server-certificate> <port>;\n"
    476 #ifdef ENABLE_HYBRID
    477                 " xauthpsk  <identifier> <pre-shared-key> \\\n"
    478                 "           <username> <password> <phase1-up> <script-arg>;\n"
    479                 " xauthrsa  <user-private-key> <user-certificate> \\\n"
    480                 "           <ca-certificate> <server-certificate> \\\n"
    481                 "           <username> <password> <phase1-up> <script-arg>;\n"
    482                 " hybridrsa <ca-certificate> <server-certificate> \\\n"
    483                 "           <username> <password> <phase1-up> <script-arg>;\n"
    484 #endif
    485                 "", argv[0]);
    486         exit(0);
    487     }
    488 
    489     /* Add proposals. */
    490     add_proposal(remoteconf, auth,
    491             OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 256);
    492     add_proposal(remoteconf, auth,
    493             OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 256);
    494     add_proposal(remoteconf, auth,
    495             OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 256);
    496     add_proposal(remoteconf, auth,
    497             OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 128);
    498     add_proposal(remoteconf, auth,
    499             OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 128);
    500     add_proposal(remoteconf, auth,
    501             OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 128);
    502     add_proposal(remoteconf, auth,
    503             OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_3DES, 0);
    504     add_proposal(remoteconf, auth,
    505             OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_3DES, 0);
    506     add_proposal(remoteconf, auth,
    507             OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_3DES, 0);
    508     add_proposal(remoteconf, auth,
    509             OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_DES, 0);
    510     add_proposal(remoteconf, auth,
    511             OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_DES, 0);
    512     add_proposal(remoteconf, auth,
    513             OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_DES, 0);
    514 
    515     /* Install remote configuration. */
    516     insrmconf(remoteconf);
    517 
    518     /* Start phase 1 negotiation for xauth. */
    519     if (remoteconf->xauth) {
    520         isakmp_ph1begin_i(remoteconf, remoteconf->remote, source);
    521     }
    522 }
    523 
    524 /*****************************************************************************/
    525 
    526 /* localconf.h */
    527 
    528 vchar_t *getpskbyaddr(struct sockaddr *addr)
    529 {
    530     return strtovchar(pre_shared_key);
    531 }
    532 
    533 vchar_t *getpskbyname(vchar_t *name)
    534 {
    535     return NULL;
    536 }
    537 
    538 void getpathname(char *path, int length, int type, const char *name)
    539 {
    540     if (pname) {
    541         snprintf(path, length, pname, name);
    542     } else {
    543         strncpy(path, name, length);
    544     }
    545     path[length - 1] = '\0';
    546 }
    547 
    548 /* grabmyaddr.h */
    549 
    550 int myaddr_getsport(struct sockaddr *addr)
    551 {
    552     return 0;
    553 }
    554 
    555 int getsockmyaddr(struct sockaddr *addr)
    556 {
    557 #ifdef ENABLE_NATT
    558     if (!cmpsaddrstrict(addr, myaddrs[1].addr)) {
    559         return myaddrs[1].sock;
    560     }
    561 #endif
    562     if (!cmpsaddrwop(addr, myaddrs[0].addr)) {
    563         return myaddrs[0].sock;
    564     }
    565     return -1;
    566 }
    567 
    568 /* privsep.h */
    569 
    570 int privsep_pfkey_open()
    571 {
    572     return pfkey_open();
    573 }
    574 
    575 void privsep_pfkey_close(int key)
    576 {
    577     pfkey_close(key);
    578 }
    579 
    580 vchar_t *privsep_eay_get_pkcs1privkey(char *file)
    581 {
    582     return eay_get_pkcs1privkey(file);
    583 }
    584 
    585 static char *get_env(char * const *envp, char *key)
    586 {
    587     int length = strlen(key);
    588     while (*envp && (strncmp(*envp, key, length) || (*envp)[length] != '=')) {
    589         ++envp;
    590     }
    591     return *envp ? &(*envp)[length + 1] : "";
    592 }
    593 
    594 static int skip_script = 0;
    595 extern const char *android_hook(char **envp);
    596 
    597 int privsep_script_exec(char *script, int name, char * const *envp)
    598 {
    599     if (skip_script) {
    600         return 0;
    601     }
    602     skip_script = 1;
    603 
    604     if (name == SCRIPT_PHASE1_DOWN) {
    605         exit(1);
    606     }
    607     if (script_names[SCRIPT_PHASE1_UP]) {
    608         /* Racoon ignores INTERNAL_IP6_ADDRESS, so we only do IPv4. */
    609         struct sockaddr *addr4 = str2saddr(get_env(envp, "INTERNAL_ADDR4"),
    610                 NULL);
    611         struct sockaddr *local = str2saddr(get_env(envp, "LOCAL_ADDR"),
    612                 get_env(envp, "LOCAL_PORT"));
    613         struct sockaddr *remote = str2saddr(get_env(envp, "REMOTE_ADDR"),
    614                 get_env(envp, "REMOTE_PORT"));
    615 
    616         if (addr4 && local && remote) {
    617 #ifdef ANDROID_CHANGES
    618             if (pname) {
    619                 script = (char *)android_hook((char **)envp);
    620             }
    621 #endif
    622             spdadd(addr4, NULL, IPPROTO_IP, local, remote);
    623         } else {
    624             do_plog(LLV_ERROR, "Cannot get parameters for SPD policy.\n");
    625             exit(1);
    626         }
    627 
    628         racoon_free(addr4);
    629         racoon_free(local);
    630         racoon_free(remote);
    631         return script_exec(script, name, envp);
    632     }
    633     return 0;
    634 }
    635 
    636 int privsep_accounting_system(int port, struct sockaddr *addr,
    637         char *user, int status)
    638 {
    639     return 0;
    640 }
    641 
    642 int privsep_xauth_login_system(char *user, char *password)
    643 {
    644     return -1;
    645 }
    646 
    647 /* misc.h */
    648 
    649 int racoon_hexdump(void *data, size_t length)
    650 {
    651     return 0;
    652 }
    653 
    654 /* sainfo.h */
    655 
    656 struct sainfo *getsainfo(const vchar_t *src, const vchar_t *dst,
    657         const vchar_t *peer, int remoteid)
    658 {
    659     return &sainfo;
    660 }
    661 
    662 const char *sainfo2str(const struct sainfo *si)
    663 {
    664     return "*";
    665 }
    666 
    667 /* throttle.h */
    668 
    669 int throttle_host(struct sockaddr *addr, int fail)
    670 {
    671     return 0;
    672 }
    673