Home | History | Annotate | Download | only in mtpd
      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 
     62 static void interrupt(int signal)
     63 {
     64     write(signals[1], &signal, sizeof(int));
     65 }
     66 
     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 
     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 
    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 
    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 
    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 
    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 
    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  */
    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  */
    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