• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <limits.h>
32 
33 #ifdef ANDROID_CHANGES
34 #include <android/log.h>
35 #include <cutils/sockets.h>
36 #endif
37 
38 #include "mtpd.h"
39 #include "NetdClient.h"
40 
41 #define ARRAY_SIZE(a)           (sizeof(a) / sizeof(a[0]))
42 /* Characters count in string with max value of unsigned type t */
43 #define TYPE_STRLEN_U(t)        ((((sizeof(t) * CHAR_BIT) * 1233) >> 12) + 1)
44 /* Length of string with max file descriptor value */
45 #define FD_MAX_LEN              TYPE_STRLEN_U(int)
46 
47 int the_socket = -1;
48 
49 extern struct protocol l2tp;
50 extern struct protocol pptp;
51 static struct protocol *protocols[] = {&l2tp, &pptp, NULL};
52 static struct protocol *the_protocol;
53 
54 static char *interface;
55 static int pppd_argc;
56 static char **pppd_argv;
57 static pid_t pppd_pid;
58 
59 /* We redirect signals to a pipe in order to prevent race conditions. */
60 static int signals[2];
61 
interrupt(int signal)62 static void interrupt(int signal)
63 {
64     write(signals[1], &signal, sizeof(int));
65 }
66 
initialize(int argc,char ** argv)67 static int initialize(int argc, char **argv)
68 {
69     int i;
70 
71     for (i = 0; protocols[i]; ++i) {
72         struct protocol *p = protocols[i];
73         if (argc - 3 >= p->arguments && !strcmp(argv[2], p->name)) {
74             log_print(INFO, "Using protocol %s", p->name);
75             the_protocol = p;
76             break;
77         }
78     }
79 
80     if (!the_protocol) {
81         printf("Usages:\n");
82         for (i = 0; protocols[i]; ++i) {
83             struct protocol *p = protocols[i];
84             printf("  %s interface %s %s pppd-arguments\n",
85                     argv[0], p->name, p->usage);
86         }
87         exit(0);
88     }
89 
90     interface = argv[1];
91     pppd_argc = argc - 3 - the_protocol->arguments;
92     pppd_argv = &argv[3 + the_protocol->arguments];
93     return the_protocol->connect(&argv[3]);
94 }
95 
stop_pppd()96 static void stop_pppd()
97 {
98     if (pppd_pid) {
99         int status;
100         log_print(INFO, "Sending signal to pppd (pid = %d)", pppd_pid);
101         kill(pppd_pid, SIGTERM);
102         waitpid(pppd_pid, &status, 0);
103         pppd_pid = 0;
104     }
105 }
106 
107 #ifdef ANDROID_CHANGES
108 
android_get_control_and_arguments(int * argc,char *** argv)109 static int android_get_control_and_arguments(int *argc, char ***argv)
110 {
111     static char *args[32];
112     int control;
113     int i;
114 
115     if ((i = android_get_control_socket("mtpd")) == -1) {
116         return -1;
117     }
118     log_print(DEBUG, "Waiting for control socket");
119     if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
120         log_print(FATAL, "Cannot get control socket");
121         exit(SYSTEM_ERROR);
122     }
123     close(i);
124     fcntl(control, F_SETFD, FD_CLOEXEC);
125 
126     args[0] = (*argv)[0];
127     for (i = 1; i < 32; ++i) {
128         unsigned char bytes[2];
129         if (recv(control, &bytes[0], 1, 0) != 1 ||
130                 recv(control, &bytes[1], 1, 0) != 1) {
131             log_print(FATAL, "Cannot get argument length");
132             exit(SYSTEM_ERROR);
133         } else {
134             int length = bytes[0] << 8 | bytes[1];
135             int offset = 0;
136 
137             if (length == 0xFFFF) {
138                 break;
139             }
140             args[i] = malloc(length + 1);
141             while (offset < length) {
142                 int n = recv(control, &args[i][offset], length - offset, 0);
143                 if (n > 0) {
144                     offset += n;
145                 } else {
146                     log_print(FATAL, "Cannot get argument value");
147                     exit(SYSTEM_ERROR);
148                 }
149             }
150             args[i][length] = 0;
151         }
152     }
153     log_print(DEBUG, "Received %d arguments", i - 1);
154 
155     *argc = i;
156     *argv = args;
157     return control;
158 }
159 
160 #endif
161 
main(int argc,char ** argv)162 int main(int argc, char **argv)
163 {
164     struct pollfd pollfds[3];
165     int control = -1;
166     int timeout;
167     int status;
168 
169 #ifdef ANDROID_CHANGES
170     control = android_get_control_and_arguments(&argc, &argv);
171     shutdown(control, SHUT_WR);
172 #endif
173 
174     srandom(time(NULL));
175 
176     if (pipe(signals) == -1) {
177         log_print(FATAL, "Pipe() %s", strerror(errno));
178         exit(SYSTEM_ERROR);
179     }
180     fcntl(signals[0], F_SETFD, FD_CLOEXEC);
181     fcntl(signals[1], F_SETFD, FD_CLOEXEC);
182 
183     timeout = initialize(argc, argv);
184 
185     signal(SIGHUP, interrupt);
186     signal(SIGINT, interrupt);
187     signal(SIGTERM, interrupt);
188     signal(SIGCHLD, interrupt);
189     signal(SIGPIPE, SIG_IGN);
190     atexit(stop_pppd);
191 
192     pollfds[0].fd = the_socket;
193     pollfds[0].events = POLLIN;
194     pollfds[1].fd = signals[0];
195     pollfds[1].events = POLLIN;
196     pollfds[2].fd = control;
197     pollfds[2].events = 0;
198 
199     while (timeout >= 0) {
200         if (poll(pollfds, 3, timeout ? timeout : -1) == -1 && errno != EINTR) {
201             log_print(FATAL, "Poll() %s", strerror(errno));
202             exit(SYSTEM_ERROR);
203         }
204         if (pollfds[1].revents) {
205             break;
206         }
207         if (pollfds[2].revents) {
208             interrupt(SIGTERM);
209         }
210         timeout = pollfds[0].revents ?
211                 the_protocol->process() : the_protocol->timeout();
212 #ifdef ANDROID_CHANGES
213         if (!access("/data/misc/vpn/abort", F_OK)) {
214             interrupt(SIGTERM);
215         }
216         if (!timeout) {
217             timeout = 5000;
218         }
219 #endif
220     }
221 
222     if (timeout < 0) {
223         status = -timeout;
224     } else {
225         int signal;
226         read(signals[0], &signal, sizeof(int));
227         log_print(INFO, "Received signal %d", signal);
228         if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid
229                 && WIFEXITED(status)) {
230             status = WEXITSTATUS(status);
231             log_print(INFO, "Pppd is terminated (status = %d)", status);
232             status += PPPD_EXITED;
233             pppd_pid = 0;
234         } else {
235             status = USER_REQUESTED;
236         }
237     }
238 
239     stop_pppd();
240     the_protocol->shutdown();
241     log_print(INFO, "Mtpd is terminated (status = %d)", status);
242     return status;
243 }
244 
log_print(int level,char * format,...)245 void log_print(int level, char *format, ...)
246 {
247     if (level >= 0 && level <= LOG_MAX) {
248 #ifdef ANDROID_CHANGES
249         static int levels[5] = {
250             ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
251             ANDROID_LOG_ERROR, ANDROID_LOG_FATAL
252         };
253         va_list ap;
254         va_start(ap, format);
255         __android_log_vprint(levels[level], "mtpd", format, ap);
256         va_end(ap);
257 #else
258         static char *levels = "DIWEF";
259         va_list ap;
260         fprintf(stderr, "%c: ", levels[level]);
261         va_start(ap, format);
262         vfprintf(stderr, format, ap);
263         va_end(ap);
264         fputc('\n', stderr);
265 #endif
266     }
267 }
268 
create_socket(int family,int type,char * server,char * port)269 void create_socket(int family, int type, char *server, char *port)
270 {
271     struct addrinfo hints = {
272         .ai_flags = AI_NUMERICSERV,
273         .ai_family = family,
274         .ai_socktype = type,
275     };
276     struct addrinfo *records;
277     struct addrinfo *r;
278     int error;
279 
280     log_print(INFO, "Connecting to %s port %s via %s", server, port, interface);
281 
282     error = getaddrinfo(server, port, &hints, &records);
283     if (error) {
284         log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ?
285                 strerror(errno) : gai_strerror(error));
286         exit(NETWORK_ERROR);
287     }
288 
289     for (r = records; r; r = r->ai_next) {
290         int s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
291         if (!setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface,
292                 strlen(interface)) && !connect(s, r->ai_addr, r->ai_addrlen)) {
293             the_socket = s;
294             break;
295         }
296         close(s);
297     }
298 
299     freeaddrinfo(records);
300 
301     if (the_socket == -1) {
302         log_print(FATAL, "Connect() %s", strerror(errno));
303         exit(NETWORK_ERROR);
304     }
305 
306 #ifdef ANDROID_CHANGES
307     protectFromVpn(the_socket);
308 #endif
309 
310     fcntl(the_socket, F_SETFD, FD_CLOEXEC);
311     log_print(INFO, "Connection established (socket = %d)", the_socket);
312 }
313 
start_pppd(int pppox)314 void start_pppd(int pppox)
315 {
316     if (pppd_pid) {
317         log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
318         close(pppox);
319         return;
320     }
321 
322     log_print(INFO, "Starting pppd (pppox = %d)", pppox);
323 
324     pppd_pid = fork();
325     if (pppd_pid < 0) {
326         log_print(FATAL, "Fork() %s", strerror(errno));
327         exit(SYSTEM_ERROR);
328     }
329 
330     if (!pppd_pid) {
331         char *args[pppd_argc + 5];
332         char number[FD_MAX_LEN + 1];
333 
334         snprintf(number, FD_MAX_LEN + 1, "%d", pppox);
335         args[0] = "pppd";
336         args[1] = "nodetach";
337         args[2] = "pppox";
338         args[3] = number;
339         memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc);
340         args[4 + pppd_argc] = NULL;
341 
342         execvp("pppd", args);
343         log_print(FATAL, "Exec() %s", strerror(errno));
344         exit(SYSTEM_ERROR); /* Pretending a fatal error in pppd. */
345     }
346 
347     log_print(INFO, "Pppd started (pid = %d)", pppd_pid);
348     close(pppox);
349 }
350 
351 /**
352  * Start pppd daemon with pppol2tp-android plugin.
353  *
354  * @param tunnel_fd Tunnel socket file descriptor
355  * @param session_fd Session socket file descriptor
356  * @param tunnel_id Tunnel ID; must be in host byte order
357  * @param session_id Session ID; must be in host byte order
358  */
start_pppd_ol2tp(int tunnel_fd,int session_fd,int tunnel_id,int session_id)359 void start_pppd_ol2tp(int tunnel_fd, int session_fd, int tunnel_id,
360                       int session_id)
361 {
362     if (pppd_pid) {
363         log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
364         goto ret;
365     }
366 
367     log_print(INFO, "Starting pppd (tunnel_fd = %d, session_fd = %d)",
368               tunnel_fd, session_fd);
369 
370     pppd_pid = fork();
371     if (pppd_pid < 0) {
372         log_print(FATAL, "Fork() %s", strerror(errno));
373         exit(SYSTEM_ERROR);
374     }
375 
376     if (!pppd_pid) {
377         char tunnel_fd_str[FD_MAX_LEN + 1];
378         char session_fd_str[FD_MAX_LEN + 1];
379         char tunnel_id_str[FD_MAX_LEN + 1];
380         char session_id_str[FD_MAX_LEN + 1];
381 
382         snprintf(tunnel_fd_str, FD_MAX_LEN + 1, "%d", tunnel_fd);
383         snprintf(session_fd_str, FD_MAX_LEN + 1, "%d", session_fd);
384         snprintf(tunnel_id_str, FD_MAX_LEN + 1, "%d", tunnel_id);
385         snprintf(session_id_str, FD_MAX_LEN + 1, "%d", session_id);
386 
387         const char *l2tp_args[] = {
388             "pppd",
389             "nodetach",
390             "plugin",
391             "pppol2tp-android.so",
392             "session_fd",
393             session_fd_str,
394             "tunnel_fd",
395             tunnel_fd_str,
396             "session_id",
397             session_id_str,
398             "tunnel_id",
399             tunnel_id_str,
400         };
401         const size_t args_len = ARRAY_SIZE(l2tp_args) + pppd_argc + 1;
402         char *args[args_len];
403 
404         /* Populate args[] from l2tp_args[] and pppd_argv[] */
405         memcpy(args, l2tp_args, sizeof(l2tp_args));
406         memcpy(args + ARRAY_SIZE(l2tp_args), pppd_argv,
407                 sizeof(char *) * pppd_argc);
408         args[args_len - 1] = NULL;
409 
410         execvp("pppd", args);
411         log_print(FATAL, "Exec() %s", strerror(errno));
412         exit(SYSTEM_ERROR); /* Pretending a fatal error in pppd. */
413     }
414 
415     log_print(INFO, "Pppd started (pid = %d)", pppd_pid);
416 
417 ret:
418     close(session_fd);
419     close(tunnel_fd);
420 }
421 
422 /**
423  * Start pppd daemon with pppopptp-android plugin.
424  *
425  * @param pptp_fd PPTP socket file descriptor
426  */
start_pppd_pptp(int pptp_fd)427 void start_pppd_pptp(int pptp_fd)
428 {
429     if (pppd_pid) {
430         log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
431         goto ret;
432     }
433 
434     log_print(INFO, "Starting pppd (pptp_fd = %d)", pptp_fd);
435 
436     pppd_pid = fork();
437     if (pppd_pid < 0) {
438         log_print(FATAL, "Fork() %s", strerror(errno));
439         exit(SYSTEM_ERROR);
440     }
441 
442     if (!pppd_pid) {
443         char pptp_fd_str[FD_MAX_LEN + 1];
444 
445         snprintf(pptp_fd_str, FD_MAX_LEN + 1, "%d", pptp_fd);
446 
447         const char *pptp_args[] = {
448             "pppd",
449             "nodetach",
450             "plugin",
451             "pppopptp-android.so",
452             "pptp_socket",
453             pptp_fd_str,
454         };
455         const size_t args_len = ARRAY_SIZE(pptp_args) + pppd_argc + 1;
456         char *args[args_len];
457 
458         /* Populate args[] from pptp_args[] and pppd_argv[] */
459         memcpy(args, pptp_args, sizeof(pptp_args));
460         memcpy(args + ARRAY_SIZE(pptp_args), pppd_argv,
461                 sizeof(char *) * pppd_argc);
462         args[args_len - 1] = NULL;
463 
464         execvp("pppd", args);
465         log_print(FATAL, "Exec() %s", strerror(errno));
466         exit(SYSTEM_ERROR); /* Pretending a fatal error in pppd. */
467     }
468 
469     log_print(INFO, "Pppd started (pid = %d)", pppd_pid);
470 
471 ret:
472     close(pptp_fd);
473 }
474