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