blob: 524155a00a33735f1476a11ad3205ac88dabf048 [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>
Chia-chi Yehbd5fa3c2009-07-07 16:24:13 +080019#include <stdarg.h>
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080020#include <signal.h>
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070021#include <poll.h>
Chia-chi Yeh66d08f42012-09-17 00:29:46 -070022#include <unistd.h>
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070023
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080024#include "config.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080025#include "gcmalloc.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080026#include "schedule.h"
Chia-chi Yehbd5fa3c2009-07-07 16:24:13 +080027#include "plog.h"
Chia-chi Yeh837a1c72009-06-26 09:40:31 +080028
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080029#ifdef ANDROID_CHANGES
30
Chia-chi Yeh10700972011-07-12 18:06:57 -070031#include <string.h>
32#include <sys/types.h>
33#include <sys/socket.h>
34#include <sys/ioctl.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <errno.h>
38#include <linux/if.h>
39#include <linux/if_tun.h>
40
41#include <android/log.h>
42#include <cutils/sockets.h>
43#include <private/android_filesystem_config.h>
44
Chia-chi Yehcadace42011-12-08 16:22:51 -080045static void notify_death()
46{
47 creat("/data/misc/vpn/abort", 0);
48}
49
Chia-chi Yeh4dd8f6b2011-07-13 19:18:58 -070050static int android_get_control_and_arguments(int *argc, char ***argv)
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080051{
Chia-chi Yehc9ac7d22011-06-28 18:37:45 -070052 static char *args[32];
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080053 int control;
54 int i;
55
Chia-chi Yehcadace42011-12-08 16:22:51 -080056 atexit(notify_death);
57
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080058 if ((i = android_get_control_socket("racoon")) == -1) {
Chia-chi Yehe9fc3762011-07-07 03:20:34 -070059 return -1;
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080060 }
61 do_plog(LLV_DEBUG, "Waiting for control socket");
62 if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
63 do_plog(LLV_ERROR, "Cannot get control socket");
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070064 exit(1);
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080065 }
66 close(i);
Chia-chi Yeh3724e612011-08-22 13:05:42 -070067 fcntl(control, F_SETFD, FD_CLOEXEC);
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080068
69 args[0] = (*argv)[0];
Chia-chi Yehc9ac7d22011-06-28 18:37:45 -070070 for (i = 1; i < 32; ++i) {
71 unsigned char bytes[2];
Chia-chi Yeh3724e612011-08-22 13:05:42 -070072 if (recv(control, &bytes[0], 1, 0) != 1 ||
73 recv(control, &bytes[1], 1, 0) != 1) {
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080074 do_plog(LLV_ERROR, "Cannot get argument length");
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070075 exit(1);
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080076 } else {
Chia-chi Yeh3724e612011-08-22 13:05:42 -070077 int length = bytes[0] << 8 | bytes[1];
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080078 int offset = 0;
Chia-chi Yehc9ac7d22011-06-28 18:37:45 -070079
Chia-chi Yeh3724e612011-08-22 13:05:42 -070080 if (length == 0xFFFF) {
81 break;
82 }
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080083 args[i] = malloc(length + 1);
84 while (offset < length) {
85 int n = recv(control, &args[i][offset], length - offset, 0);
86 if (n > 0) {
87 offset += n;
88 } else {
89 do_plog(LLV_ERROR, "Cannot get argument value");
Chia-chi Yehf8a6a762011-07-04 17:21:23 -070090 exit(1);
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +080091 }
92 }
93 args[i][length] = 0;
94 }
95 }
96 do_plog(LLV_DEBUG, "Received %d arguments", i - 1);
97
98 *argc = i;
99 *argv = args;
Chia-chi Yehe9fc3762011-07-07 03:20:34 -0700100 return control;
Chia-chi Yehc4549542009-07-22 06:46:14 +0800101}
102
Chia-chi Yeha9a07ac2011-07-19 18:29:16 -0700103const char *android_hook(char **envp)
Chia-chi Yeh10700972011-07-12 18:06:57 -0700104{
Chia-chi Yeh10700972011-07-12 18:06:57 -0700105 struct ifreq ifr = {.ifr_flags = IFF_TUN};
Chia-chi Yehdc6f5b92011-07-14 15:29:06 -0700106 int tun = open("/dev/tun", 0);
Chia-chi Yeh10700972011-07-12 18:06:57 -0700107
Chia-chi Yeha9a07ac2011-07-19 18:29:16 -0700108 /* Android does not support INTERNAL_WINS4_LIST, so we just use it. */
Chia-chi Yehdc6f5b92011-07-14 15:29:06 -0700109 while (*envp && strncmp(*envp, "INTERNAL_WINS4_LIST=", 20)) {
110 ++envp;
111 }
112 if (!*envp) {
113 do_plog(LLV_ERROR, "Cannot find environment variable\n");
114 exit(1);
115 }
Chia-chi Yeh10700972011-07-12 18:06:57 -0700116 if (ioctl(tun, TUNSETIFF, &ifr)) {
117 do_plog(LLV_ERROR, "Cannot allocate TUN: %s\n", strerror(errno));
118 exit(1);
119 }
Chia-chi Yehdc6f5b92011-07-14 15:29:06 -0700120 sprintf(*envp, "INTERFACE=%s", ifr.ifr_name);
Chia-chi Yeha9a07ac2011-07-19 18:29:16 -0700121 return "/etc/ppp/ip-up-vpn";
Chia-chi Yeh10700972011-07-12 18:06:57 -0700122}
123
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +0800124#endif
125
Chia-chi Yehc4549542009-07-22 06:46:14 +0800126extern void setup(int argc, char **argv);
tetsuya, kobayashicb1e9552013-06-14 23:43:19 +0900127extern void shutdown_session();
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700128
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700129static int monitors;
130static void (*callbacks[10])(int fd);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700131static struct pollfd pollfds[10];
Chia-chi Yehc4549542009-07-22 06:46:14 +0800132
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700133char *pname;
134
Chia-chi Yehc4549542009-07-22 06:46:14 +0800135static void terminate(int signal)
136{
137 exit(1);
138}
139
140static void terminated()
141{
142 do_plog(LLV_INFO, "Bye\n");
143}
144
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700145void monitor_fd(int fd, void (*callback)(int))
146{
147 if (fd < 0 || monitors == 10) {
148 do_plog(LLV_ERROR, "Cannot monitor fd");
149 exit(1);
150 }
151 callbacks[monitors] = callback;
152 pollfds[monitors].fd = fd;
153 pollfds[monitors].events = callback ? POLLIN : 0;
154 ++monitors;
155}
156
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800157int main(int argc, char **argv)
158{
Chia-chi Yehe9fc3762011-07-07 03:20:34 -0700159#ifdef ANDROID_CHANGES
Chia-chi Yeh4dd8f6b2011-07-13 19:18:58 -0700160 int control = android_get_control_and_arguments(&argc, &argv);
Adam Langleya0292812014-09-30 15:20:01 -0700161
Chia-chi Yehe9fc3762011-07-07 03:20:34 -0700162 if (control != -1) {
Chia-chi Yeh8f3b3882011-07-07 13:43:20 -0700163 pname = "%p";
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700164 monitor_fd(control, NULL);
Chia-chi Yehe9fc3762011-07-07 03:20:34 -0700165 }
166#endif
167
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700168 do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n");
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800169
Chia-chi Yeh7197eb72009-07-13 16:43:29 +0800170 signal(SIGHUP, terminate);
171 signal(SIGINT, terminate);
172 signal(SIGTERM, terminate);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800173 signal(SIGPIPE, SIG_IGN);
Chia-chi Yeh9d271b62009-07-30 17:23:56 +0800174 atexit(terminated);
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800175
Chia-chi Yeh12f44932011-07-13 16:40:15 -0700176 setup(argc, argv);
177
178#ifdef ANDROID_CHANGES
Chia-chi Yeh3724e612011-08-22 13:05:42 -0700179 shutdown(control, SHUT_WR);
Chia-chi Yeh12f44932011-07-13 16:40:15 -0700180#endif
181
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800182 while (1) {
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700183 struct timeval *tv = schedular();
184 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1;
185
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700186 if (poll(pollfds, monitors, timeout) > 0) {
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700187 int i;
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700188 for (i = 0; i < monitors; ++i) {
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700189 if (pollfds[i].revents & POLLHUP) {
Chia-chi Yeh66d08f42012-09-17 00:29:46 -0700190 do_plog(LLV_INFO, "Connection is closed\n", pollfds[i].fd);
tetsuya, kobayashicb1e9552013-06-14 23:43:19 +0900191 shutdown_session();
192
Chia-chi Yeh66d08f42012-09-17 00:29:46 -0700193 /* Wait for few seconds to consume late messages. */
194 sleep(5);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700195 exit(1);
196 }
197 if (pollfds[i].revents & POLLIN) {
Chia-chi Yehc91307a2012-03-26 14:18:52 -0700198 callbacks[i](pollfds[i].fd);
Chia-chi Yehf8a6a762011-07-04 17:21:23 -0700199 }
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800200 }
201 }
202 }
Adam Langleya0292812014-09-30 15:20:01 -0700203
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800204 return 0;
205}
206
207/* plog.h */
208
209void do_plog(int level, char *format, ...)
210{
Chia-chi Yeh458fe1e2009-06-26 14:36:17 +0800211 if (level >= 0 && level <= 5) {
212#ifdef ANDROID_CHANGES
213 static int levels[6] = {
214 ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO,
215 ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE
216 };
217 va_list ap;
218 va_start(ap, format);
219 __android_log_vprint(levels[level], "racoon", format, ap);
220 va_end(ap);
221#else
222 static char *levels = "EWNIDV";
223 fprintf(stderr, "%c: ", levels[level]);
224 va_list ap;
225 va_start(ap, format);
226 vfprintf(stderr, format, ap);
227 va_end(ap);
228#endif
229 }
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800230}
231
232char *binsanitize(char *data, size_t length)
233{
234 char *output = racoon_malloc(length + 1);
235 if (output) {
236 size_t i;
237 for (i = 0; i < length; ++i) {
Chia-chi Yehc4549542009-07-22 06:46:14 +0800238 output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i];
Chia-chi Yeh837a1c72009-06-26 09:40:31 +0800239 }
240 output[length] = '\0';
241 }
242 return output;
243}