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 
add_sainfo_algorithm(int class,int algorithm,int length)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 
set_globals(char * server)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 
policy_match(struct sadb_address * address)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; */
flush()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; */
spdadd(struct sockaddr * src,struct sockaddr * dst,int protocol,struct sockaddr * local,struct sockaddr * remote)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 
add_proposal(struct remoteconf * remoteconf,int auth,int hash,int encryption,int length)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 
strtovchar(char * string)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 
set_pre_shared_key(struct remoteconf * remoteconf,char * identifier,char * key)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 
set_certificates(struct remoteconf * remoteconf,char * user_private_key,char * user_certificate,char * ca_certificate,char * server_certificate)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 
set_xauth_and_more(struct remoteconf * remoteconf,char * username,char * password,char * phase1_up,char * script_arg)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 
add_isakmp_handler(int fd,const char * interface)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 
setup(int argc,char ** argv)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 
getpskbyaddr(struct sockaddr * addr)528 vchar_t *getpskbyaddr(struct sockaddr *addr)
529 {
530     return strtovchar(pre_shared_key);
531 }
532 
getpskbyname(vchar_t * name)533 vchar_t *getpskbyname(vchar_t *name)
534 {
535     return NULL;
536 }
537 
getpathname(char * path,int length,int type,const char * name)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 
myaddr_getsport(struct sockaddr * addr)550 int myaddr_getsport(struct sockaddr *addr)
551 {
552     return 0;
553 }
554 
getsockmyaddr(struct sockaddr * addr)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 
privsep_pfkey_open()570 int privsep_pfkey_open()
571 {
572     return pfkey_open();
573 }
574 
privsep_pfkey_close(int key)575 void privsep_pfkey_close(int key)
576 {
577     pfkey_close(key);
578 }
579 
privsep_eay_get_pkcs1privkey(char * file)580 vchar_t *privsep_eay_get_pkcs1privkey(char *file)
581 {
582     return eay_get_pkcs1privkey(file);
583 }
584 
get_env(char * const * envp,char * key)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 
privsep_script_exec(char * script,int name,char * const * envp)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 
privsep_accounting_system(int port,struct sockaddr * addr,char * user,int status)636 int privsep_accounting_system(int port, struct sockaddr *addr,
637         char *user, int status)
638 {
639     return 0;
640 }
641 
privsep_xauth_login_system(char * user,char * password)642 int privsep_xauth_login_system(char *user, char *password)
643 {
644     return -1;
645 }
646 
647 /* misc.h */
648 
racoon_hexdump(void * data,size_t length)649 int racoon_hexdump(void *data, size_t length)
650 {
651     return 0;
652 }
653 
654 /* sainfo.h */
655 
getsainfo(const vchar_t * src,const vchar_t * dst,const vchar_t * peer,int remoteid)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 
sainfo2str(const struct sainfo * si)662 const char *sainfo2str(const struct sainfo *si)
663 {
664     return "*";
665 }
666 
667 /* throttle.h */
668 
throttle_host(struct sockaddr * addr,int fail)669 int throttle_host(struct sockaddr *addr, int fail)
670 {
671     return 0;
672 }
673