1 /*
2 * Copyright (C) 2009 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 <stdarg.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/poll.h>
25 #include <sys/wait.h>
26 #include <netdb.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <time.h>
31
32 #ifdef ANDROID_CHANGES
33 #include <android/log.h>
34 #include <cutils/sockets.h>
35 #endif
36
37 #include "mtpd.h"
38 #include "NetdClient.h"
39
40 int the_socket = -1;
41
42 extern struct protocol l2tp;
43 extern struct protocol pptp;
44 static struct protocol *protocols[] = {&l2tp, &pptp, NULL};
45 static struct protocol *the_protocol;
46
47 static char *interface;
48 static int pppd_argc;
49 static char **pppd_argv;
50 static pid_t pppd_pid;
51
52 /* We redirect signals to a pipe in order to prevent race conditions. */
53 static int signals[2];
54
interrupt(int signal)55 static void interrupt(int signal)
56 {
57 write(signals[1], &signal, sizeof(int));
58 }
59
initialize(int argc,char ** argv)60 static int initialize(int argc, char **argv)
61 {
62 int i;
63
64 for (i = 0; protocols[i]; ++i) {
65 struct protocol *p = protocols[i];
66 if (argc - 3 >= p->arguments && !strcmp(argv[2], p->name)) {
67 log_print(INFO, "Using protocol %s", p->name);
68 the_protocol = p;
69 break;
70 }
71 }
72
73 if (!the_protocol) {
74 printf("Usages:\n");
75 for (i = 0; protocols[i]; ++i) {
76 struct protocol *p = protocols[i];
77 printf(" %s interface %s %s pppd-arguments\n",
78 argv[0], p->name, p->usage);
79 }
80 exit(0);
81 }
82
83 interface = argv[1];
84 pppd_argc = argc - 3 - the_protocol->arguments;
85 pppd_argv = &argv[3 + the_protocol->arguments];
86 return the_protocol->connect(&argv[3]);
87 }
88
stop_pppd()89 static void stop_pppd()
90 {
91 if (pppd_pid) {
92 int status;
93 log_print(INFO, "Sending signal to pppd (pid = %d)", pppd_pid);
94 kill(pppd_pid, SIGTERM);
95 waitpid(pppd_pid, &status, 0);
96 pppd_pid = 0;
97 }
98 }
99
100 #ifdef ANDROID_CHANGES
101
android_get_control_and_arguments(int * argc,char *** argv)102 static int android_get_control_and_arguments(int *argc, char ***argv)
103 {
104 static char *args[32];
105 int control;
106 int i;
107
108 if ((i = android_get_control_socket("mtpd")) == -1) {
109 return -1;
110 }
111 log_print(DEBUG, "Waiting for control socket");
112 if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
113 log_print(FATAL, "Cannot get control socket");
114 exit(SYSTEM_ERROR);
115 }
116 close(i);
117 fcntl(control, F_SETFD, FD_CLOEXEC);
118
119 args[0] = (*argv)[0];
120 for (i = 1; i < 32; ++i) {
121 unsigned char bytes[2];
122 if (recv(control, &bytes[0], 1, 0) != 1 ||
123 recv(control, &bytes[1], 1, 0) != 1) {
124 log_print(FATAL, "Cannot get argument length");
125 exit(SYSTEM_ERROR);
126 } else {
127 int length = bytes[0] << 8 | bytes[1];
128 int offset = 0;
129
130 if (length == 0xFFFF) {
131 break;
132 }
133 args[i] = malloc(length + 1);
134 while (offset < length) {
135 int n = recv(control, &args[i][offset], length - offset, 0);
136 if (n > 0) {
137 offset += n;
138 } else {
139 log_print(FATAL, "Cannot get argument value");
140 exit(SYSTEM_ERROR);
141 }
142 }
143 args[i][length] = 0;
144 }
145 }
146 log_print(DEBUG, "Received %d arguments", i - 1);
147
148 *argc = i;
149 *argv = args;
150 return control;
151 }
152
153 #endif
154
main(int argc,char ** argv)155 int main(int argc, char **argv)
156 {
157 struct pollfd pollfds[3];
158 int control = -1;
159 int timeout;
160 int status;
161
162 #ifdef ANDROID_CHANGES
163 control = android_get_control_and_arguments(&argc, &argv);
164 shutdown(control, SHUT_WR);
165 #endif
166
167 srandom(time(NULL));
168
169 if (pipe(signals) == -1) {
170 log_print(FATAL, "Pipe() %s", strerror(errno));
171 exit(SYSTEM_ERROR);
172 }
173 fcntl(signals[0], F_SETFD, FD_CLOEXEC);
174 fcntl(signals[1], F_SETFD, FD_CLOEXEC);
175
176 timeout = initialize(argc, argv);
177
178 signal(SIGHUP, interrupt);
179 signal(SIGINT, interrupt);
180 signal(SIGTERM, interrupt);
181 signal(SIGCHLD, interrupt);
182 signal(SIGPIPE, SIG_IGN);
183 atexit(stop_pppd);
184
185 pollfds[0].fd = the_socket;
186 pollfds[0].events = POLLIN;
187 pollfds[1].fd = signals[0];
188 pollfds[1].events = POLLIN;
189 pollfds[2].fd = control;
190 pollfds[2].events = 0;
191
192 while (timeout >= 0) {
193 if (poll(pollfds, 3, timeout ? timeout : -1) == -1 && errno != EINTR) {
194 log_print(FATAL, "Poll() %s", strerror(errno));
195 exit(SYSTEM_ERROR);
196 }
197 if (pollfds[1].revents) {
198 break;
199 }
200 if (pollfds[2].revents) {
201 interrupt(SIGTERM);
202 }
203 timeout = pollfds[0].revents ?
204 the_protocol->process() : the_protocol->timeout();
205 #ifdef ANDROID_CHANGES
206 if (!access("/data/misc/vpn/abort", F_OK)) {
207 interrupt(SIGTERM);
208 }
209 if (!timeout) {
210 timeout = 5000;
211 }
212 #endif
213 }
214
215 if (timeout < 0) {
216 status = -timeout;
217 } else {
218 int signal;
219 read(signals[0], &signal, sizeof(int));
220 log_print(INFO, "Received signal %d", signal);
221 if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid
222 && WIFEXITED(status)) {
223 status = WEXITSTATUS(status);
224 log_print(INFO, "Pppd is terminated (status = %d)", status);
225 status += PPPD_EXITED;
226 pppd_pid = 0;
227 } else {
228 status = USER_REQUESTED;
229 }
230 }
231
232 stop_pppd();
233 the_protocol->shutdown();
234 log_print(INFO, "Mtpd is terminated (status = %d)", status);
235 return status;
236 }
237
log_print(int level,char * format,...)238 void log_print(int level, char *format, ...)
239 {
240 if (level >= 0 && level <= LOG_MAX) {
241 #ifdef ANDROID_CHANGES
242 static int levels[5] = {
243 ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
244 ANDROID_LOG_ERROR, ANDROID_LOG_FATAL
245 };
246 va_list ap;
247 va_start(ap, format);
248 __android_log_vprint(levels[level], "mtpd", format, ap);
249 va_end(ap);
250 #else
251 static char *levels = "DIWEF";
252 va_list ap;
253 fprintf(stderr, "%c: ", levels[level]);
254 va_start(ap, format);
255 vfprintf(stderr, format, ap);
256 va_end(ap);
257 fputc('\n', stderr);
258 #endif
259 }
260 }
261
create_socket(int family,int type,char * server,char * port)262 void create_socket(int family, int type, char *server, char *port)
263 {
264 struct addrinfo hints = {
265 .ai_flags = AI_NUMERICSERV,
266 .ai_family = family,
267 .ai_socktype = type,
268 };
269 struct addrinfo *records;
270 struct addrinfo *r;
271 int error;
272
273 log_print(INFO, "Connecting to %s port %s via %s", server, port, interface);
274
275 error = getaddrinfo(server, port, &hints, &records);
276 if (error) {
277 log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ?
278 strerror(errno) : gai_strerror(error));
279 exit(NETWORK_ERROR);
280 }
281
282 for (r = records; r; r = r->ai_next) {
283 int s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
284 if (!setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface,
285 strlen(interface)) && !connect(s, r->ai_addr, r->ai_addrlen)) {
286 the_socket = s;
287 break;
288 }
289 close(s);
290 }
291
292 freeaddrinfo(records);
293
294 if (the_socket == -1) {
295 log_print(FATAL, "Connect() %s", strerror(errno));
296 exit(NETWORK_ERROR);
297 }
298
299 #ifdef ANDROID_CHANGES
300 protectFromVpn(the_socket);
301 #endif
302
303 fcntl(the_socket, F_SETFD, FD_CLOEXEC);
304 log_print(INFO, "Connection established (socket = %d)", the_socket);
305 }
306
start_pppd(int pppox)307 void start_pppd(int pppox)
308 {
309 if (pppd_pid) {
310 log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
311 close(pppox);
312 return;
313 }
314
315 log_print(INFO, "Starting pppd (pppox = %d)", pppox);
316
317 pppd_pid = fork();
318 if (pppd_pid < 0) {
319 log_print(FATAL, "Fork() %s", strerror(errno));
320 exit(SYSTEM_ERROR);
321 }
322
323 if (!pppd_pid) {
324 char *args[pppd_argc + 5];
325 char number[12];
326
327 sprintf(number, "%d", pppox);
328 args[0] = "pppd";
329 args[1] = "nodetach";
330 args[2] = "pppox";
331 args[3] = number;
332 memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc);
333 args[4 + pppd_argc] = NULL;
334
335 #ifdef ANDROID_CHANGES
336 {
337 char envargs[65536];
338 char *tail = envargs;
339 int i;
340 /* Hex encode the arguments using [A-P] instead of [0-9A-F]. */
341 for (i = 0; args[i]; ++i) {
342 char *p = args[i];
343 do {
344 *tail++ = 'A' + ((*p >> 4) & 0x0F);
345 *tail++ = 'A' + (*p & 0x0F);
346 } while (*p++);
347 }
348 *tail = 0;
349 setenv("envargs", envargs, 1);
350 args[1] = NULL;
351 }
352 #endif
353 execvp("pppd", args);
354 log_print(FATAL, "Exec() %s", strerror(errno));
355 exit(1); /* Pretending a fatal error in pppd. */
356 }
357
358 log_print(INFO, "Pppd started (pid = %d)", pppd_pid);
359 close(pppox);
360 }
361