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