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