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 L2TP Access Concentrator (RFC 2661) which only
     18  * creates a single session. The following code only handles control packets.
     19  * Data packets are handled by PPPoLAC 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 <fcntl.h>
     27 #include <sys/types.h>
     28 #include <sys/socket.h>
     29 #include <sys/stat.h>
     30 #include <arpa/inet.h>
     31 #include <linux/netdevice.h>
     32 #include <linux/if_pppox.h>
     33 #include <openssl/md5.h>
     34 
     35 #include "mtpd.h"
     36 
     37 /* To avoid unnecessary endianness conversions, tunnels, sessions, attributes,
     38  * and values are all accessed in network order. */
     39 
     40 /* 0 is reserved. We put ACK here just for convenience. */
     41 enum l2tp_message {
     42     ACK = 0,
     43     SCCRQ = 1,
     44     SCCRP = 2,
     45     SCCCN = 3,
     46     STOPCCN = 4,
     47     HELLO = 6,
     48     OCRQ = 7,
     49     OCRP = 8,
     50     OCCN = 9,
     51     ICRQ = 10,
     52     ICRP = 11,
     53     ICCN = 12,
     54     CDN = 14,
     55     WEN = 15,
     56     SLI = 16,
     57     MESSAGE_MAX = 16,
     58 };
     59 
     60 static char *messages[] = {
     61     "ACK", "SCCRQ", "SCCRP", "SCCCN", "STOPCCN", NULL, "HELLO", "OCRQ",
     62     "OCRP", "OCCN", "ICRQ", "ICRP", "ICCN", NULL, "CDN", "WEN", "SLI",
     63 };
     64 
     65 /* This is incomplete. Only those we used are listed here. */
     66 #define RESULT_CODE             htons(1)
     67 #define PROTOCOL_VERSION        htons(2)
     68 #define FRAMING_CAPABILITIES    htons(3)
     69 #define HOST_NAME               htons(7)
     70 #define ASSIGNED_TUNNEL         htons(9)
     71 #define WINDOW_SIZE             htons(10)
     72 #define CHALLENGE               htons(11)
     73 #define CHALLENGE_RESPONSE      htons(13)
     74 #define ASSIGNED_SESSION        htons(14)
     75 #define CALL_SERIAL_NUMBER      htons(15)
     76 #define FRAMING_TYPE            htons(19)
     77 #define CONNECT_SPEED           htons(24)
     78 #define RANDOM_VECTOR           htons(36)
     79 
     80 #define MESSAGE_FLAG            0xC802
     81 #define MESSAGE_MASK            0xCB0F
     82 #define ATTRIBUTE_FLAG(length)  (0x8006 + (length))
     83 #define ATTRIBUTE_LENGTH(flag)  (0x03FF & (flag))
     84 #define ATTRIBUTE_HIDDEN(flag)  (0x4000 & (flag))
     85 
     86 #define ACK_SIZE                12
     87 #define MESSAGE_HEADER_SIZE     20
     88 #define ATTRIBUTE_HEADER_SIZE   6
     89 #define MAX_ATTRIBUTE_SIZE      1024
     90 
     91 static uint16_t local_tunnel;
     92 static uint16_t local_session;
     93 static uint16_t local_sequence;
     94 static uint16_t remote_tunnel;
     95 static uint16_t remote_session;
     96 static uint16_t remote_sequence;
     97 
     98 static uint16_t state;
     99 static int acknowledged;
    100 
    101 #define RANDOM_DEVICE   "/dev/urandom"
    102 #define CHALLENGE_SIZE  32
    103 
    104 static char *secret;
    105 static int secret_length;
    106 static uint8_t challenge[CHALLENGE_SIZE];
    107 
    108 /* According to RFC 2661 page 46, an exponential backoff strategy is required
    109  * for retransmission. However, it might waste too much time waiting for IPsec
    110  * negotiation. Here we use the same interval to keep things simple. */
    111 #define TIMEOUT_INTERVAL 2000
    112 
    113 #define MAX_PACKET_LENGTH 2048
    114 
    115 static struct packet {
    116     int message;
    117     int length;
    118     uint8_t buffer[MAX_PACKET_LENGTH] __attribute__((aligned(4)));
    119 } incoming, outgoing;
    120 
    121 struct attribute {
    122     uint16_t flag;
    123     uint16_t vendor;
    124     uint16_t type;
    125     uint8_t value[1];
    126 } __attribute__((packed));
    127 
    128 static void set_message(uint16_t session, uint16_t message)
    129 {
    130     uint16_t *p = (uint16_t *)outgoing.buffer;
    131     p[0] = htons(MESSAGE_FLAG);
    132     /* p[1] will be filled in send_packet(). */
    133     p[2] = remote_tunnel;
    134     p[3] = session;
    135     p[4] = htons(local_sequence);
    136     p[5] = htons(remote_sequence);
    137     p[6] = htons(ATTRIBUTE_FLAG(2));
    138     p[7] = 0;
    139     p[8] = 0;
    140     p[9] = htons(message);
    141     outgoing.message = message;
    142     outgoing.length = MESSAGE_HEADER_SIZE;
    143     ++local_sequence;
    144 }
    145 
    146 static void add_attribute_raw(uint16_t type, void *value, int size)
    147 {
    148     struct attribute *p = (struct attribute *)&outgoing.buffer[outgoing.length];
    149     p->flag = htons(ATTRIBUTE_FLAG(size));
    150     p->vendor = 0;
    151     p->type = type;
    152     memcpy(&p->value, value, size);
    153     outgoing.length += ATTRIBUTE_HEADER_SIZE + size;
    154 }
    155 
    156 static void add_attribute_u16(uint16_t attribute, uint16_t value)
    157 {
    158     add_attribute_raw(attribute, &value, sizeof(uint16_t));
    159 }
    160 
    161 static void add_attribute_u32(uint16_t attribute, uint32_t value)
    162 {
    163     add_attribute_raw(attribute, &value, sizeof(uint32_t));
    164 }
    165 
    166 static void send_packet()
    167 {
    168     uint16_t *p = (uint16_t *)outgoing.buffer;
    169     p[1] = htons(outgoing.length);
    170     send(the_socket, outgoing.buffer, outgoing.length, 0);
    171     acknowledged = 0;
    172 }
    173 
    174 static void send_ack()
    175 {
    176     uint16_t buffer[6] = {
    177         htons(MESSAGE_FLAG), htons(ACK_SIZE), remote_tunnel, 0,
    178         htons(local_sequence), htons(remote_sequence),
    179     };
    180     send(the_socket, buffer, ACK_SIZE, 0);
    181 }
    182 
    183 static int recv_packet(uint16_t *session)
    184 {
    185     uint16_t *p = (uint16_t *)incoming.buffer;
    186 
    187     incoming.length = recv(the_socket, incoming.buffer, MAX_PACKET_LENGTH, 0);
    188     if (incoming.length == -1) {
    189         if (errno == EINTR) {
    190             return 0;
    191         }
    192         log_print(FATAL, "Recv() %s", strerror(errno));
    193         exit(NETWORK_ERROR);
    194     }
    195 
    196     /* We only handle packets in our tunnel. */
    197     if ((incoming.length != ACK_SIZE && incoming.length < MESSAGE_HEADER_SIZE)
    198             || (p[0] & htons(MESSAGE_MASK)) != htons(MESSAGE_FLAG) ||
    199             ntohs(p[1]) != incoming.length || p[2] != local_tunnel) {
    200         return 0;
    201     }
    202 
    203     if (incoming.length == ACK_SIZE) {
    204         incoming.message = ACK;
    205     } else if (p[6] == htons(ATTRIBUTE_FLAG(2)) && !p[7] && !p[8]) {
    206         incoming.message = ntohs(p[9]);
    207     } else {
    208         return 0;
    209     }
    210 
    211     /* Check if the packet is duplicated and send ACK if necessary. */
    212     if ((uint16_t)(ntohs(p[4]) - remote_sequence) > 32767) {
    213         if (incoming.message != ACK) {
    214             send_ack();
    215         }
    216         return 0;
    217     }
    218 
    219     if (ntohs(p[5]) == local_sequence) {
    220         acknowledged = 1;
    221     }
    222 
    223     /* Our sending and receiving window sizes are both 1. Thus we only handle
    224      * this packet if it is their next one and they received our last one. */
    225     if (ntohs(p[4]) != remote_sequence || !acknowledged) {
    226         return 0;
    227     }
    228     *session = p[3];
    229     if (incoming.message != ACK) {
    230         ++remote_sequence;
    231     }
    232     return 1;
    233 }
    234 
    235 static int get_attribute_raw(uint16_t type, void *value, int size)
    236 {
    237     int offset = MESSAGE_HEADER_SIZE;
    238     uint8_t *vector = NULL;
    239     int vector_length = 0;
    240 
    241     while (incoming.length >= offset + ATTRIBUTE_HEADER_SIZE) {
    242         struct attribute *p = (struct attribute *)&incoming.buffer[offset];
    243         uint16_t flag = ntohs(p->flag);
    244         int length = ATTRIBUTE_LENGTH(flag);
    245 
    246         offset += length;
    247         length -= ATTRIBUTE_HEADER_SIZE;
    248         if (length < 0 || offset > incoming.length) {
    249             break;
    250         }
    251         if (p->vendor) {
    252             continue;
    253         }
    254         if (p->type != type) {
    255             if (p->type == RANDOM_VECTOR && !ATTRIBUTE_HIDDEN(flag)) {
    256                 vector = p->value;
    257                 vector_length = length;
    258             }
    259             continue;
    260         }
    261 
    262         if (!ATTRIBUTE_HIDDEN(flag)) {
    263             if (size > length) {
    264                 size = length;
    265             }
    266             memcpy(value, p->value, size);
    267             return size;
    268         }
    269 
    270         if (!secret || !vector || length < 2) {
    271             return 0;
    272         } else {
    273             uint8_t buffer[MAX_ATTRIBUTE_SIZE];
    274             uint8_t hash[MD5_DIGEST_LENGTH];
    275             MD5_CTX ctx;
    276             int i;
    277 
    278             MD5_Init(&ctx);
    279             MD5_Update(&ctx, &type, sizeof(uint16_t));
    280             MD5_Update(&ctx, secret, secret_length);
    281             MD5_Update(&ctx, vector, vector_length);
    282             MD5_Final(hash, &ctx);
    283 
    284             for (i = 0; i < length; ++i) {
    285                 int j = i % MD5_DIGEST_LENGTH;
    286                 if (i && !j) {
    287                     MD5_Init(&ctx);
    288                     MD5_Update(&ctx, secret, secret_length);
    289                     MD5_Update(&ctx, &p->value[i - MD5_DIGEST_LENGTH],
    290                         MD5_DIGEST_LENGTH);
    291                     MD5_Final(hash, &ctx);
    292                 }
    293                 buffer[i] = p->value[i] ^ hash[j];
    294             }
    295 
    296             length = buffer[0] << 8 | buffer[1];
    297             if (length > i - 2) {
    298                 return 0;
    299             }
    300             if (size > length) {
    301                 size = length;
    302             }
    303             memcpy(value, &buffer[2], size);
    304             return size;
    305         }
    306     }
    307     return 0;
    308 }
    309 
    310 static int get_attribute_u16(uint16_t type, uint16_t *value)
    311 {
    312     return get_attribute_raw(type, value, sizeof(uint16_t)) == sizeof(uint16_t);
    313 }
    314 
    315 static int l2tp_connect(char **arguments)
    316 {
    317     create_socket(AF_INET, SOCK_DGRAM, arguments[0], arguments[1]);
    318 
    319     while (!local_tunnel) {
    320         local_tunnel = random();
    321     }
    322 
    323     log_print(DEBUG, "Sending SCCRQ (local_tunnel = %d)", local_tunnel);
    324     state = SCCRQ;
    325     set_message(0, SCCRQ);
    326     add_attribute_u16(PROTOCOL_VERSION, htons(0x0100));
    327     add_attribute_raw(HOST_NAME, "anonymous", 9);
    328     add_attribute_u32(FRAMING_CAPABILITIES, htonl(3));
    329     add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
    330     add_attribute_u16(WINDOW_SIZE, htons(1));
    331 
    332     if (arguments[2][0]) {
    333         int fd = open(RANDOM_DEVICE, O_RDONLY);
    334         if (fd == -1 || read(fd, challenge, CHALLENGE_SIZE) != CHALLENGE_SIZE) {
    335             log_print(FATAL, "Cannot read %s", RANDOM_DEVICE);
    336             exit(SYSTEM_ERROR);
    337         }
    338         close(fd);
    339 
    340         add_attribute_raw(CHALLENGE, challenge, CHALLENGE_SIZE);
    341         secret = arguments[2];
    342         secret_length = strlen(arguments[2]);
    343     }
    344 
    345     send_packet();
    346     return TIMEOUT_INTERVAL;
    347 }
    348 
    349 static int create_pppox()
    350 {
    351     int pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC);
    352     log_print(INFO, "Creating PPPoX socket");
    353 
    354     if (pppox == -1) {
    355         log_print(FATAL, "Socket() %s", strerror(errno));
    356         exit(SYSTEM_ERROR);
    357     } else {
    358         struct sockaddr_pppolac address = {
    359             .sa_family = AF_PPPOX,
    360             .sa_protocol = PX_PROTO_OLAC,
    361             .udp_socket = the_socket,
    362             .local = {.tunnel = local_tunnel, .session = local_session},
    363             .remote = {.tunnel = remote_tunnel, .session = remote_session},
    364         };
    365         if (connect(pppox, (struct sockaddr *)&address, sizeof(address))) {
    366             log_print(FATAL, "Connect() %s", strerror(errno));
    367             exit(SYSTEM_ERROR);
    368         }
    369     }
    370     return pppox;
    371 }
    372 
    373 static uint8_t *compute_response(uint8_t type, void *challenge, int size)
    374 {
    375     static uint8_t response[MD5_DIGEST_LENGTH];
    376     MD5_CTX ctx;
    377     MD5_Init(&ctx);
    378     MD5_Update(&ctx, &type, sizeof(uint8_t));
    379     MD5_Update(&ctx, secret, secret_length);
    380     MD5_Update(&ctx, challenge, size);
    381     MD5_Final(response, &ctx);
    382     return response;
    383 }
    384 
    385 static int verify_challenge()
    386 {
    387     if (secret) {
    388         uint8_t response[MD5_DIGEST_LENGTH];
    389         if (get_attribute_raw(CHALLENGE_RESPONSE, response, MD5_DIGEST_LENGTH)
    390                 != MD5_DIGEST_LENGTH) {
    391             return 0;
    392         }
    393         return !memcmp(compute_response(SCCRP, challenge, CHALLENGE_SIZE),
    394                 response, MD5_DIGEST_LENGTH);
    395     }
    396     return 1;
    397 }
    398 
    399 static void answer_challenge()
    400 {
    401     if (secret) {
    402         uint8_t challenge[MAX_ATTRIBUTE_SIZE];
    403         int size = get_attribute_raw(CHALLENGE, challenge, MAX_ATTRIBUTE_SIZE);
    404         if (size > 0) {
    405             uint8_t *response = compute_response(SCCCN, challenge, size);
    406             add_attribute_raw(CHALLENGE_RESPONSE, response, MD5_DIGEST_LENGTH);
    407         }
    408     }
    409 }
    410 
    411 static int l2tp_process()
    412 {
    413     uint16_t sequence = local_sequence;
    414     uint16_t tunnel = 0;
    415     uint16_t session = 0;
    416 
    417     if (!recv_packet(&session)) {
    418         return acknowledged ? 0 : TIMEOUT_INTERVAL;
    419     }
    420 
    421     /* Here is the fun part. We always try to protect our tunnel and session
    422      * from being closed even if we received unexpected messages. */
    423     switch(incoming.message) {
    424         case SCCRP:
    425             if (state == SCCRQ) {
    426                 if (get_attribute_u16(ASSIGNED_TUNNEL, &tunnel) && tunnel &&
    427                         verify_challenge()) {
    428                     remote_tunnel = tunnel;
    429                     log_print(DEBUG, "Received SCCRP (remote_tunnel = %d) -> "
    430                             "Sending SCCCN", remote_tunnel);
    431                     state = SCCCN;
    432                     answer_challenge();
    433                     set_message(0, SCCCN);
    434                     break;
    435                 }
    436                 log_print(DEBUG, "Received SCCRP without %s", tunnel ?
    437                         "valid challenge response" : "assigned tunnel");
    438                 log_print(ERROR, "Protocol error");
    439                 return tunnel ? -CHALLENGE_FAILED : -PROTOCOL_ERROR;
    440             }
    441             break;
    442 
    443         case ICRP:
    444             if (state == ICRQ && session == local_session) {
    445                 if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) {
    446                     remote_session = session;
    447                     log_print(DEBUG, "Received ICRP (remote_session = %d) -> "
    448                             "Sending ICCN", remote_session);
    449                     state = ICCN;
    450                     set_message(remote_session, ICCN);
    451                     add_attribute_u32(CONNECT_SPEED, htonl(100000000));
    452                     add_attribute_u32(FRAMING_TYPE, htonl(3));
    453                     break;
    454                 }
    455                 log_print(DEBUG, "Received ICRP without assigned session");
    456                 log_print(ERROR, "Protocol error");
    457                 return -PROTOCOL_ERROR;
    458             }
    459             break;
    460 
    461         case STOPCCN:
    462             log_print(DEBUG, "Received STOPCCN");
    463             log_print(INFO, "Remote server hung up");
    464             state = STOPCCN;
    465             return -REMOTE_REQUESTED;
    466 
    467         case CDN:
    468             if (session && session == local_session) {
    469                 log_print(DEBUG, "Received CDN (local_session = %d)",
    470                         local_session);
    471                 log_print(INFO, "Remote server hung up");
    472                 return -REMOTE_REQUESTED;
    473             }
    474             break;
    475 
    476         case ACK:
    477         case HELLO:
    478         case WEN:
    479         case SLI:
    480             /* These are harmless, so we just treat them in the same way. */
    481             if (state == SCCCN) {
    482                 while (!local_session) {
    483                     local_session = random();
    484                 }
    485                 log_print(DEBUG, "Received %s -> Sending ICRQ (local_session = "
    486                         "%d)", messages[incoming.message], local_session);
    487                 log_print(INFO, "Tunnel established");
    488                 state = ICRQ;
    489                 set_message(0, ICRQ);
    490                 add_attribute_u16(ASSIGNED_SESSION, local_session);
    491                 add_attribute_u32(CALL_SERIAL_NUMBER, random());
    492                 break;
    493             }
    494 
    495             if (incoming.message == ACK) {
    496                 log_print(DEBUG, "Received ACK");
    497             } else {
    498                 log_print(DEBUG, "Received %s -> Sending ACK",
    499                           messages[incoming.message]);
    500                 send_ack();
    501             }
    502 
    503             if (state == ICCN) {
    504                 log_print(INFO, "Session established");
    505                 state = ACK;
    506                 start_pppd(create_pppox());
    507             }
    508             return 0;
    509 
    510         case ICRQ:
    511         case OCRQ:
    512             /* Since we run pppd as a client, it does not makes sense to
    513              * accept ICRQ or OCRQ. Always send CDN with a proper error. */
    514             if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) {
    515                 log_print(DEBUG, "Received %s (remote_session = %d) -> "
    516                         "Sending CDN", messages[incoming.message], session);
    517                 set_message(session, CDN);
    518                 add_attribute_u32(RESULT_CODE, htonl(0x00020006));
    519                 add_attribute_u16(ASSIGNED_SESSION, 0);
    520             }
    521             break;
    522     }
    523 
    524     if (sequence != local_sequence) {
    525         send_packet();
    526         return TIMEOUT_INTERVAL;
    527     }
    528 
    529     /* We reach here if we got an unexpected message. Log it and send ACK. */
    530     if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) {
    531         log_print(DEBUG, "Received UNKNOWN %d -> Sending ACK anyway",
    532                 incoming.message);
    533     } else {
    534         log_print(DEBUG, "Received UNEXPECTED %s -> Sending ACK anyway",
    535                 messages[incoming.message]);
    536     }
    537     send_ack();
    538     return 0;
    539 }
    540 
    541 static int l2tp_timeout()
    542 {
    543     if (acknowledged) {
    544         return 0;
    545     }
    546     log_print(DEBUG, "Timeout -> Sending %s", messages[outgoing.message]);
    547     send(the_socket, outgoing.buffer, outgoing.length, 0);
    548     return TIMEOUT_INTERVAL;
    549 }
    550 
    551 static void l2tp_shutdown()
    552 {
    553     if (state != STOPCCN) {
    554         log_print(DEBUG, "Sending STOPCCN");
    555         set_message(0, STOPCCN);
    556         add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
    557         add_attribute_u16(RESULT_CODE, htons(6));
    558         send_packet();
    559     }
    560 }
    561 
    562 struct protocol l2tp = {
    563     .name = "l2tp",
    564     .arguments = 3,
    565     .usage = "<server> <port> <secret>",
    566     .connect = l2tp_connect,
    567     .process = l2tp_process,
    568     .timeout = l2tp_timeout,
    569     .shutdown = l2tp_shutdown,
    570 };
    571