blob: 14e42f86626a46b20f880234a081a1f4fcf2e27b [file] [log] [blame]
Chia-chi Yeh837a1c72009-06-26 09:40:31 +08001/*
Chia-chi Yehe9fc3762011-07-07 03:20:34 -07002 * Copyright (C) 2011 The Android Open Source Project
Chia-chi Yeh837a1c72009-06-26 09:40:31 +08003 *
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>
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070020#include <unistd.h>
Chia-chi Yeh8f3b3882011-07-07 13:43:20 -070021#include <sys/param.h>
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080022#include <sys/types.h>
23#include <sys/socket.h>
Chia-chi Yehc4549542009-07-22 06:46:14 +080024#include <netinet/in.h>
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080025#include <netinet/ip.h>
Chia-chi Yeh7197eb72009-07-13 16:43:29 +080026#include <netdb.h>
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070027#include <fcntl.h>
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080028
29#include "config.h"
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070030#include "gcmalloc.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080031#include "libpfkey.h"
32#include "var.h"
33#include "isakmp_var.h"
34#include "isakmp.h"
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -070035#include "isakmp_xauth.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080036#include "vmbuf.h"
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070037#include "crypto_openssl.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080038#include "oakley.h"
39#include "ipsec_doi.h"
40#include "algorithm.h"
41#include "vendorid.h"
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070042#include "schedule.h"
43#include "pfkey.h"
44#include "nattraversal.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080045#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"
Chia-chi Yehbd5fa3c2009-07-07 16:24:13 +080052#include "admin.h"
53#include "privsep.h"
Chia-chi Yeh514ffe22011-07-07 13:52:27 -070054#include "throttle.h"
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070055#include "misc.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080056
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080057static struct localconf localconf;
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080058static struct sainfo sainfo;
59static char *pre_shared_key;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070060
Chia-chi Yehb0d8f172011-07-12 15:14:38 -070061static struct sockaddr *targets[2];
Chia-chi Yehc91307a2012-03-26 14:18:52 -070062static struct sockaddr *source;
63static struct myaddrs myaddrs[2];
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080064
65struct localconf *lcconf = &localconf;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070066int f_local = 0;
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080067
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070068/*****************************************************************************/
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080069
70static 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
Chia-chi Yehc91307a2012-03-26 14:18:52 -070087static void set_globals(char *server)
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070088{
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
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700100 if (getaddrinfo(server, "500", &hints, &info) != 0) {
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700101 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 }
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700107 targets[0] = dupsaddr(info->ai_addr);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700108 freeaddrinfo(info);
109
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700110 source = getlocaladdr(targets[0]);
111 if (!source) {
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700112 do_plog(LLV_ERROR, "Cannot get local address\n");
113 exit(1);
114 }
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700115 set_port(targets[0], 0);
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700116 set_port(source, 0);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700117
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700118 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];
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700130 localconf.port_isakmp = PORT_ISAKMP;
131 localconf.port_isakmp_natt = PORT_ISAKMP_NATT;
132 localconf.default_af = AF_INET;
Chia-chi Yehe9fc3762011-07-07 03:20:34 -0700133 localconf.pathinfo[LC_PATHTYPE_CERT] = "./";
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700134 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;
Shinpei Sanou568db0f2013-05-28 15:35:13 +0900148 add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, 0);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700149 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);
Chia-chi Yehf82b8262011-07-13 18:07:54 -0700151 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 256);
152 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700153 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0);
154 add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0);
Chia-chi Yehe7611712011-12-29 17:09:19 -0800155
156 memset(script_names, 0, sizeof(script_names));
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700157}
158
159/*****************************************************************************/
160
161static int policy_match(struct sadb_address *address)
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700162{
163 if (address) {
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700164 struct sockaddr *addr = PFKEY_ADDR_SADDR(address);
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700165 return !cmpsaddrwop(addr, targets[0]) || !cmpsaddrwop(addr, targets[1]);
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700166 }
167 return 0;
168}
169
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800170/* flush; spdflush; */
171static void flush()
172{
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700173 struct sadb_msg *p;
174 int replies = 0;
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800175 int key = pfkey_open();
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700176
177 if (pfkey_send_dump(key, SADB_SATYPE_UNSPEC) <= 0 ||
178 pfkey_send_spddump(key) <= 0) {
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700179 do_plog(LLV_ERROR, "Cannot dump SAD and SPD\n");
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700180 exit(1);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800181 }
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700182
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 }
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700195 if (policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_SRC]) ||
196 policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_DST])) {
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700197 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);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800206}
207
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700208/* 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; */
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700213static void spdadd(struct sockaddr *src, struct sockaddr *dst,
214 int protocol, struct sockaddr *local, struct sockaddr *remote)
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800215{
216 struct __attribute__((packed)) {
217 struct sadb_x_policy p;
218 struct sadb_x_ipsecrequest q;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700219 char addresses[sizeof(struct sockaddr_storage) * 2];
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800220 } policy;
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800221
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700222 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
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700234 /* Fill values for outbound policy. */
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800235 memset(&policy, 0, sizeof(policy));
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800236 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
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800242 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
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700246 /* Deal with tunnel mode. */
247 if (!dst) {
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700248 int size = sysdep_sa_len(local);
249 memcpy(policy.addresses, local, size);
250 memcpy(&policy.addresses[size], remote, size);
251 length += size + size;
252
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700253 policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL;
254 dst = (struct sockaddr *)&any;
255 dst_prefix = 0;
256
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700257 /* Also use the source address to filter policies. */
258 targets[1] = dupsaddr(src);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700259 }
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
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700267 /* Always do a flush before adding new policies. */
Chia-chi Yeh3473d8e2011-05-31 13:26:30 -0700268 flush();
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700269
270 /* Set outbound policy. */
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700271 key = pfkey_open();
272 if (pfkey_send_spdadd(key, src, src_prefix, dst, dst_prefix, protocol,
273 (caddr_t)&policy, length, 0) <= 0) {
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700274 do_plog(LLV_ERROR, "Cannot set outbound policy\n");
Chia-chi Yeh7197eb72009-07-13 16:43:29 +0800275 exit(1);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800276 }
Chia-chi Yeh2871f2f2011-08-09 19:19:20 -0700277
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
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800293 pfkey_close(key);
Chia-chi Yehc4549542009-07-22 06:46:14 +0800294 atexit(flush);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800295}
296
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700297/*****************************************************************************/
298
299static 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;
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700311 p->rmconf = remoteconf;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700312
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
Chia-chi Yeh71076532011-08-08 12:20:14 -0700326static 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);
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700331 vchar->l -= 1;
Chia-chi Yeh71076532011-08-08 12:20:14 -0700332 }
333 return vchar;
334}
335
336static 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);
Chia-chi Yeh71076532011-08-08 12:20:14 -0700342 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
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700354static void set_certificates(struct remoteconf *remoteconf,
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800355 char *user_private_key, char *user_certificate,
356 char *ca_certificate, char *server_certificate)
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700357{
358 remoteconf->myprivfile = user_private_key;
359 remoteconf->mycertfile = user_certificate;
360 if (user_certificate) {
Chia-chi Yeh71076532011-08-08 12:20:14 -0700361 remoteconf->idvtype = IDTYPE_ASN1DN;
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700362 }
363 if (!ca_certificate[0]) {
364 remoteconf->verify_cert = FALSE;
365 } else {
366 remoteconf->cacertfile = ca_certificate;
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700367 }
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800368 if (server_certificate[0]) {
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700369 remoteconf->peerscertfile = server_certificate;
370 remoteconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800371 }
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700372}
373
374#ifdef ENABLE_HYBRID
375
376static 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));
Chia-chi Yeh10700972011-07-12 18:06:57 -0700380 xauth->login = strtovchar(username);
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700381 xauth->login->l += 1;
Chia-chi Yeh10700972011-07-12 18:06:57 -0700382 xauth->pass = strtovchar(password);
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700383 xauth->pass->l += 1;
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700384 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
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700392extern void monitor_fd(int fd, void (*callback)(int));
393
394void 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
Chia-chi Yeh7197eb72009-07-13 16:43:29 +0800403void setup(int argc, char **argv)
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800404{
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700405 struct remoteconf *remoteconf = NULL;
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800406 int auth;
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800407
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700408 if (argc > 2) {
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700409 set_globals(argv[2]);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800410
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700411 /* 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 }
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700420 monitor_fd(localconf.sock_pfkey, (void *)pfkey_handler);
421 add_isakmp_handler(myaddrs[0].sock, argv[1]);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800422#ifdef ENABLE_NATT
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700423 add_isakmp_handler(myaddrs[1].sock, argv[1]);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700424 natt_keepalive_init();
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800425#endif
426
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700427 /* Create remote configuration. */
428 remoteconf = newrmconf();
429 remoteconf->etypes = racoon_calloc(1, sizeof(struct etypes));
430 remoteconf->etypes->type = ISAKMP_ETYPE_IDENT;
Chia-chi Yeh71076532011-08-08 12:20:14 -0700431 remoteconf->idvtype = IDTYPE_ADDRESS;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700432 remoteconf->ike_frag = TRUE;
Chia-chi Yehf82b8262011-07-13 18:07:54 -0700433 remoteconf->pcheck_level = PROP_CHECK_CLAIM;
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700434 remoteconf->certtype = ISAKMP_CERT_X509SIGN;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700435 remoteconf->gen_policy = TRUE;
436 remoteconf->nat_traversal = TRUE;
Chia-chi Yeh71076532011-08-08 12:20:14 -0700437 remoteconf->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
Chia-chi Yehe7611712011-12-29 17:09:19 -0800438 remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar("");
439 remoteconf->script[SCRIPT_PHASE1_DOWN] = strtovchar("");
Chia-chi Yeh71076532011-08-08 12:20:14 -0700440 oakley_setdhgroup(remoteconf->dh_group, &remoteconf->dhgrp);
Chia-chi Yehb0d8f172011-07-12 15:14:38 -0700441 remoteconf->remote = dupsaddr(targets[0]);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800442 }
443
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700444 /* Set authentication method and credentials. */
Chia-chi Yeh71076532011-08-08 12:20:14 -0700445 if (argc == 7 && !strcmp(argv[3], "udppsk")) {
446 set_pre_shared_key(remoteconf, argv[4], argv[5]);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700447 auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY;
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700448
Chia-chi Yeh71076532011-08-08 12:20:14 -0700449 set_port(targets[0], atoi(argv[6]));
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700450 spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800451 } else if (argc == 9 && !strcmp(argv[3], "udprsa")) {
452 set_certificates(remoteconf, argv[4], argv[5], argv[6], argv[7]);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700453 auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG;
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700454
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800455 set_port(targets[0], atoi(argv[8]));
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700456 spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700457#ifdef ENABLE_HYBRID
458 } else if (argc == 10 && !strcmp(argv[3], "xauthpsk")) {
Chia-chi Yeh71076532011-08-08 12:20:14 -0700459 set_pre_shared_key(remoteconf, argv[4], argv[5]);
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700460 set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]);
461 auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800462 } 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]);
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700465 auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800466 } 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]);
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700469 auth = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
470#endif
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700471 } else {
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700472 printf("Usage: %s <interface> <server> [...], where [...] can be:\n"
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800473 " udppsk <identifier> <pre-shared-key> <port>; \n"
474 " udprsa <user-private-key> <user-certificate> \\\n"
475 " <ca-certificate> <server-certificate> <port>;\n"
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700476#ifdef ENABLE_HYBRID
Chia-chi Yehfdbd82d2011-12-06 15:13:58 -0800477 " 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"
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700484#endif
485 "", argv[0]);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700486 exit(0);
487 }
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800488
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700489 /* Add proposals. */
490 add_proposal(remoteconf, auth,
Shinpei Sanou568db0f2013-05-28 15:35:13 +0900491 OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 256);
492 add_proposal(remoteconf, auth,
Chia-chi Yehf82b8262011-07-13 18:07:54 -0700493 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,
Shinpei Sanou568db0f2013-05-28 15:35:13 +0900497 OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 128);
498 add_proposal(remoteconf, auth,
Chia-chi Yehf82b8262011-07-13 18:07:54 -0700499 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,
Shinpei Sanou568db0f2013-05-28 15:35:13 +0900503 OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_3DES, 0);
504 add_proposal(remoteconf, auth,
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700505 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,
Shinpei Sanou568db0f2013-05-28 15:35:13 +0900509 OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_DES, 0);
510 add_proposal(remoteconf, auth,
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700511 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);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700514
515 /* Install remote configuration. */
516 insrmconf(remoteconf);
517
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700518 /* Start phase 1 negotiation for xauth. */
519 if (remoteconf->xauth) {
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700520 isakmp_ph1begin_i(remoteconf, remoteconf->remote, source);
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700521 }
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800522}
523
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700524/*****************************************************************************/
525
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800526/* localconf.h */
527
528vchar_t *getpskbyaddr(struct sockaddr *addr)
529{
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700530 return strtovchar(pre_shared_key);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800531}
532
533vchar_t *getpskbyname(vchar_t *name)
534{
535 return NULL;
536}
537
538void getpathname(char *path, int length, int type, const char *name)
539{
Chia-chi Yeh8f3b3882011-07-07 13:43:20 -0700540 if (pname) {
541 snprintf(path, length, pname, name);
Chia-chi Yehe9fc3762011-07-07 03:20:34 -0700542 } else {
543 strncpy(path, name, length);
544 }
Chia-chi Yehfd76ec52011-07-07 12:28:27 -0700545 path[length - 1] = '\0';
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800546}
547
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700548/* grabmyaddr.h */
549
550int myaddr_getsport(struct sockaddr *addr)
551{
552 return 0;
553}
554
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700555int getsockmyaddr(struct sockaddr *addr)
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700556{
557#ifdef ENABLE_NATT
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700558 if (!cmpsaddrstrict(addr, myaddrs[1].addr)) {
559 return myaddrs[1].sock;
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700560 }
561#endif
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700562 if (!cmpsaddrwop(addr, myaddrs[0].addr)) {
563 return myaddrs[0].sock;
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700564 }
565 return -1;
566}
567
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700568/* privsep.h */
569
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700570int privsep_pfkey_open()
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700571{
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700572 return pfkey_open();
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700573}
574
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700575void privsep_pfkey_close(int key)
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700576{
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700577 pfkey_close(key);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700578}
579
580vchar_t *privsep_eay_get_pkcs1privkey(char *file)
581{
582 return eay_get_pkcs1privkey(file);
583}
584
Chia-chi Yehe4b12472011-07-12 17:14:47 -0700585static 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
Chia-chi Yehcfc417e2011-07-13 14:05:22 -0700594static int skip_script = 0;
Chia-chi Yeha9a07ac2011-07-19 18:29:16 -0700595extern const char *android_hook(char **envp);
Chia-chi Yeh10700972011-07-12 18:06:57 -0700596
Chia-chi Yehdbbbd5f2011-07-12 13:21:42 -0700597int privsep_script_exec(char *script, int name, char * const *envp)
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700598{
Chia-chi Yehcfc417e2011-07-13 14:05:22 -0700599 if (skip_script) {
Chia-chi Yehe7611712011-12-29 17:09:19 -0800600 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]) {
Chia-chi Yehcfc417e2011-07-13 14:05:22 -0700608 /* 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"));
Chia-chi Yehe4b12472011-07-12 17:14:47 -0700615
Chia-chi Yehcfc417e2011-07-13 14:05:22 -0700616 if (addr4 && local && remote) {
617#ifdef ANDROID_CHANGES
Chia-chi Yeha9a07ac2011-07-19 18:29:16 -0700618 if (pname) {
619 script = (char *)android_hook((char **)envp);
620 }
Chia-chi Yehcfc417e2011-07-13 14:05:22 -0700621#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
Chia-chi Yehcfc417e2011-07-13 14:05:22 -0700628 racoon_free(addr4);
629 racoon_free(local);
630 racoon_free(remote);
631 return script_exec(script, name, envp);
632 }
633 return 0;
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700634}
635
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700636int privsep_accounting_system(int port, struct sockaddr *addr,
637 char *user, int status)
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700638{
639 return 0;
640}
641
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700642int privsep_xauth_login_system(char *user, char *password)
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700643{
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700644 return -1;
645}
646
Chia-chi Yeh0ed32712011-07-12 14:06:46 -0700647/* misc.h */
648
649int racoon_hexdump(void *data, size_t length)
650{
651 return 0;
652}
653
Chia-chi Yeh0ed32712011-07-12 14:06:46 -0700654/* sainfo.h */
655
656struct sainfo *getsainfo(const vchar_t *src, const vchar_t *dst,
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700657 const vchar_t *peer, int remoteid)
Chia-chi Yeh0ed32712011-07-12 14:06:46 -0700658{
659 return &sainfo;
660}
661
662const char *sainfo2str(const struct sainfo *si)
663{
664 return "*";
665}
666
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700667/* throttle.h */
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700668
Chia-chi Yeh514ffe22011-07-07 13:52:27 -0700669int throttle_host(struct sockaddr *addr, int fail)
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700670{
671 return 0;
672}