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 /* A simple implementation of PPTP Network Server (RFC 2637) which only
     18  * creates a single session. The following code only handles control packets.
     19  * Data packets are handled by PPPoPNS driver which can be found in Android
     20  * kernel tree. */
     21 
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <errno.h>
     26 #include <sys/types.h>
     27 #include <sys/socket.h>
     28 #include <arpa/inet.h>
     29 #include <linux/netdevice.h>
     30 #include <linux/if_pppox.h>
     31 
     32 #include "mtpd.h"
     33 
     34 enum pptp_message {
     35     SCCRQ = 1,
     36     SCCRP = 2,
     37     STOPCCRQ = 3,
     38     STOPCCRP = 4,
     39     ECHORQ = 5,
     40     ECHORP = 6,
     41     OCRQ = 7,
     42     OCRP = 8,
     43     ICRQ = 9,
     44     ICRP = 10,
     45     ICCN = 11,
     46     CCRQ = 12,
     47     CDN = 13,
     48     WEN = 14,
     49     SLI = 15,
     50     MESSAGE_MAX = 15,
     51 };
     52 
     53 static char *messages[] = {
     54     NULL, "SCCRQ", "SCCRP", "STOPCCRQ", "STOPCCRP", "ECHORQ", "ECHORP",
     55     "OCRQ", "OCRP", "ICRQ", "ICRP", "ICCN", "CCRQ", "CDN", "WEN", "SLI",
     56 };
     57 
     58 static uint8_t lengths[] = {
     59     0, 156, 156, 16, 16, 16, 20, 168, 32, 220, 24, 28, 16, 148, 40, 24,
     60 };
     61 
     62 #define CONTROL_MESSAGE         htons(1)
     63 #define MAGIC_COOKIE            htonl(0x1A2B3C4D)
     64 #define PROTOCOL_VERSION        htons(0x0100)
     65 
     66 #define RESULT_OK               1
     67 #define RESULT_ERROR            2
     68 
     69 /* Some implementation uses 0 instead of 1, so we allow both of them. */
     70 #define ESTABLISHED(result)     (result <= 1)
     71 
     72 #define HEADER_SIZE             8
     73 #define MIN_MESSAGE_SIZE        10
     74 
     75 static uint16_t local;
     76 static uint16_t remote;
     77 static uint16_t state;
     78 
     79 #define MAX_PACKET_LENGTH       220
     80 
     81 /* We define all the fields we used in this structure. Type conversion and byte
     82  * alignment are solved in one place. Although it looks a little bit ugly, it
     83  * really makes life easier. */
     84 static struct packet {
     85     int length;
     86     int expect;
     87     union {
     88         uint8_t buffer[MAX_PACKET_LENGTH];
     89         struct {
     90             struct __attribute__((packed)) {
     91                 uint16_t length;
     92                 uint16_t type;
     93                 uint32_t cookie;
     94             } header;
     95             uint16_t message;
     96             uint16_t reserved;
     97             union {
     98                 struct __attribute__((packed)) {
     99                     uint16_t protocol_version;
    100                     uint8_t result;
    101                     uint8_t error;
    102                     uint32_t framing;
    103                     uint32_t bearer;
    104                     uint16_t channels;
    105                     uint16_t firmware_revision;
    106                     char host[64];
    107                 } sccrp, sccrq;
    108                 struct __attribute__((packed)) {
    109                     uint16_t call;
    110                     uint16_t serial;
    111                     uint32_t minimum_speed;
    112                     uint32_t maximum_speed;
    113                     uint32_t bearer;
    114                     uint32_t framing;
    115                     uint16_t window_size;
    116                 } ocrq;
    117                 struct __attribute__((packed)) {
    118                     uint16_t call;
    119                     uint16_t peer;
    120                     uint8_t result;
    121                 } ocrp, icrp;
    122                 struct __attribute__((packed)) {
    123                     uint32_t identifier;
    124                     uint8_t result;
    125                 } echorq, echorp;
    126                 struct __attribute__((packed)) {
    127                     uint16_t call;
    128                 } icrq, ccrq, cdn;
    129             };
    130         } __attribute__((packed));
    131     } __attribute__((aligned(4)));
    132 } incoming, outgoing;
    133 
    134 static void set_message(uint16_t message)
    135 {
    136     uint16_t length = lengths[message];
    137     memset(outgoing.buffer, 0, length);
    138     outgoing.length = length;
    139     outgoing.header.length = htons(length);
    140     outgoing.header.type = CONTROL_MESSAGE;
    141     outgoing.header.cookie = MAGIC_COOKIE;
    142     outgoing.message = htons(message);
    143 }
    144 
    145 static void send_packet()
    146 {
    147     send(the_socket, outgoing.buffer, outgoing.length, 0);
    148 }
    149 
    150 static int recv_packet()
    151 {
    152     int length;
    153 
    154     /* We are going to read a new message if incoming.expect is 0. */
    155     if (!incoming.expect) {
    156         incoming.length = 0;
    157         incoming.expect = HEADER_SIZE;
    158     }
    159 
    160     /* The longest message defined in RFC 2637 is 220 bytes, but the protocol
    161      * itself allows up to 65536 bytes. Therefore we always read a complete
    162      * message but only keep the first 220 bytes before passing up. */
    163     length = incoming.expect - incoming.length;
    164     if (incoming.length >= MAX_PACKET_LENGTH) {
    165         uint8_t buffer[length];
    166         length = recv(the_socket, buffer, length, 0);
    167     } else {
    168         if (incoming.expect > MAX_PACKET_LENGTH) {
    169             length = MAX_PACKET_LENGTH - incoming.length;
    170         }
    171         length = recv(the_socket, &incoming.buffer[incoming.length], length, 0);
    172     }
    173     if (length == -1) {
    174         if (errno == EINTR) {
    175             return 0;
    176         }
    177         log_print(FATAL, "Recv() %s", strerror(errno));
    178         exit(NETWORK_ERROR);
    179     }
    180     if (length == 0) {
    181         log_print(DEBUG, "Connection closed");
    182         log_print(INFO, "Remote server hung up");
    183         return -REMOTE_REQUESTED;
    184     }
    185     incoming.length += length;
    186 
    187     /* If incoming.header is valid, check cookie and update incoming.expect. */
    188     if (incoming.length == HEADER_SIZE && incoming.expect == HEADER_SIZE) {
    189         if (incoming.header.cookie != MAGIC_COOKIE) {
    190             log_print(DEBUG, "Loss of synchronization");
    191             log_print(ERROR, "Protocol error");
    192             return -PROTOCOL_ERROR;
    193         }
    194         incoming.expect = ntohs(incoming.header.length);
    195         if (incoming.expect < HEADER_SIZE) {
    196             log_print(DEBUG, "Invalid message length");
    197             log_print(ERROR, "Protocol error");
    198             return -PROTOCOL_ERROR;
    199         }
    200     }
    201 
    202     /* Now we have a complete message. Reset incoming.expect. */
    203     if (incoming.length == incoming.expect) {
    204         incoming.expect = 0;
    205 
    206         /* Return 1 if it is a control message. */
    207         if (incoming.header.type == CONTROL_MESSAGE) {
    208             return 1;
    209         }
    210         log_print(DEBUG, "Ignored non-control message (type = %d)",
    211                 ntohs(incoming.header.type));
    212     }
    213     return 0;
    214 }
    215 
    216 static int pptp_connect(char **arguments)
    217 {
    218     create_socket(AF_UNSPEC, SOCK_STREAM, arguments[0], arguments[1]);
    219 
    220     log_print(DEBUG, "Sending SCCRQ");
    221     state = SCCRQ;
    222     set_message(SCCRQ);
    223     outgoing.sccrq.protocol_version = PROTOCOL_VERSION;
    224     outgoing.sccrq.framing = htonl(3);
    225     outgoing.sccrq.bearer = htonl(3);
    226     outgoing.sccrq.channels = htons(1);
    227     strcpy(outgoing.sccrq.host, "anonymous");
    228     send_packet();
    229     return 0;
    230 }
    231 
    232 static int create_pppox()
    233 {
    234     int pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OPNS);
    235     log_print(INFO, "Creating PPPoX socket");
    236 
    237     if (pppox == -1) {
    238         log_print(FATAL, "Socket() %s", strerror(errno));
    239         exit(SYSTEM_ERROR);
    240     } else {
    241         struct sockaddr_pppopns address = {
    242             .sa_family = AF_PPPOX,
    243             .sa_protocol = PX_PROTO_OPNS,
    244             .tcp_socket = the_socket,
    245             .local = local,
    246             .remote = remote,
    247         };
    248         if (connect(pppox, (struct sockaddr *)&address, sizeof(address))) {
    249             log_print(FATAL, "Connect() %s", strerror(errno));
    250             exit(SYSTEM_ERROR);
    251         }
    252     }
    253     return pppox;
    254 }
    255 
    256 static int pptp_process()
    257 {
    258     int result = recv_packet();
    259     if (result <= 0) {
    260         return result;
    261     }
    262 
    263     if (incoming.length < MIN_MESSAGE_SIZE) {
    264         log_print(DEBUG, "Control message too short");
    265         return 0;
    266     }
    267     incoming.message = ntohs(incoming.message);
    268     if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) {
    269         log_print(DEBUG, "Received UNKNOWN %d", incoming.message);
    270         return 0;
    271     }
    272     if (incoming.length < lengths[incoming.message]) {
    273         log_print(DEBUG, "Received %s with invalid length (length = %d)",
    274                 messages[incoming.message], incoming.length);
    275         return 0;
    276     }
    277 
    278     switch(incoming.message) {
    279         case SCCRP:
    280             if (state == SCCRQ) {
    281                 if (incoming.sccrp.protocol_version == PROTOCOL_VERSION &&
    282                         ESTABLISHED(incoming.sccrp.result)) {
    283                     while (!local) {
    284                         local = random();
    285                     }
    286                     log_print(DEBUG, "Received SCCRP -> Sending OCRQ "
    287                             "(local = %d)", local);
    288                     log_print(INFO, "Tunnel established");
    289                     state = OCRQ;
    290                     set_message(OCRQ);
    291                     outgoing.ocrq.call = local;
    292                     outgoing.ocrq.serial = random();
    293                     outgoing.ocrq.minimum_speed = htonl(1000);
    294                     outgoing.ocrq.maximum_speed = htonl(100000000);
    295                     outgoing.ocrq.bearer = htonl(3);
    296                     outgoing.ocrq.framing = htonl(3);
    297                     outgoing.ocrq.window_size = htons(8192);
    298                     send_packet();
    299                     return 0;
    300                 }
    301                 log_print(DEBUG, "Received SCCRP (result = %d)",
    302                         incoming.sccrq.result);
    303                 log_print(INFO, "Remote server hung up");
    304                 return -REMOTE_REQUESTED;
    305             }
    306             break;
    307 
    308         case OCRP:
    309             if (state == OCRQ && incoming.ocrp.peer == local) {
    310                 if (ESTABLISHED(incoming.ocrp.result)) {
    311                     remote = incoming.ocrp.call;
    312                     log_print(DEBUG, "Received OCRQ (remote = %d)", remote);
    313                     log_print(INFO, "Session established");
    314                     state = OCRP;
    315                     start_pppd(create_pppox());
    316                     return 0;
    317                 }
    318                 log_print(DEBUG, "Received OCRP (result = %d)",
    319                         incoming.ocrp.result);
    320                 log_print(INFO, "Remote server hung up");
    321                 return -REMOTE_REQUESTED;
    322             }
    323             break;
    324 
    325         case STOPCCRQ:
    326             log_print(DEBUG, "Received STOPCCRQ");
    327             log_print(INFO, "Remote server hung up");
    328             state = STOPCCRQ;
    329             return -REMOTE_REQUESTED;
    330 
    331         case CCRQ:
    332             /* According to RFC 2637 page 45, we should never receive CCRQ for
    333              * outgoing calls. However, some implementation only acts as PNS and
    334              * always uses CCRQ to clear a call, so here we still handle it. */
    335             if (state == OCRP && incoming.ccrq.call == remote) {
    336                 log_print(DEBUG, "Received CCRQ (remote = %d)", remote);
    337                 log_print(INFO, "Remote server hung up");
    338                 return -REMOTE_REQUESTED;
    339             }
    340             break;
    341 
    342         case CDN:
    343             if (state == OCRP && incoming.cdn.call == remote) {
    344                 log_print(DEBUG, "Received CDN (remote = %d)", remote);
    345                 log_print(INFO, "Remote server hung up");
    346                 return -REMOTE_REQUESTED;
    347             }
    348             break;
    349 
    350         case ECHORQ:
    351             log_print(DEBUG, "Received ECHORQ -> Sending ECHORP");
    352             set_message(ECHORP);
    353             outgoing.echorp.identifier = incoming.echorq.identifier;
    354             outgoing.echorp.result = RESULT_OK;
    355             send_packet();
    356             return 0;
    357 
    358         case WEN:
    359         case SLI:
    360             log_print(DEBUG, "Recevied %s", messages[incoming.message]);
    361             return 0;
    362 
    363         case ICRQ:
    364             log_print(DEBUG, "Received ICRQ (remote = %d) -> Sending ICRP "
    365                     "with error", incoming.icrq.call);
    366             set_message(ICRP);
    367             outgoing.icrp.peer = incoming.icrq.call;
    368             outgoing.icrp.result = RESULT_ERROR;
    369             send_packet();
    370             return 0;
    371 
    372         case OCRQ:
    373             log_print(DEBUG, "Received OCRQ (remote = %d) -> Sending OCRP "
    374                     "with error", incoming.ocrq.call);
    375             set_message(OCRP);
    376             outgoing.ocrp.peer = incoming.ocrq.call;
    377             outgoing.ocrp.result = RESULT_ERROR;
    378             send_packet();
    379             return 0;
    380     }
    381 
    382     /* We reach here if we got an unexpected message. Just log it. */
    383     log_print(DEBUG, "Received UNEXPECTED %s", messages[incoming.message]);
    384     return 0;
    385 }
    386 
    387 static int pptp_timeout()
    388 {
    389     return 0;
    390 }
    391 
    392 static void pptp_shutdown()
    393 {
    394     /* Normally we should send STOPCCRQ and wait for STOPCCRP, but this might
    395      * block for a long time. Here we simply take the shortcut: do nothing. */
    396 }
    397 
    398 struct protocol pptp = {
    399     .name = "pptp",
    400     .arguments = 2,
    401     .usage = "<server> <port>",
    402     .connect = pptp_connect,
    403     .process = pptp_process,
    404     .timeout = pptp_timeout,
    405     .shutdown = pptp_shutdown,
    406 };
    407