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. */
41enum 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
60static 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
91static uint16_t local_tunnel;
92static uint16_t local_session;
93static uint16_t local_sequence;
94static uint16_t remote_tunnel;
95static uint16_t remote_session;
96static uint16_t remote_sequence;
97
98static uint16_t state;
99static int acknowledged;
100
101#define RANDOM_DEVICE   "/dev/urandom"
102#define CHALLENGE_SIZE  32
103
104static char *secret;
105static int secret_length;
106static 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
115static struct packet {
116    int message;
117    int length;
118    uint8_t buffer[MAX_PACKET_LENGTH] __attribute__((aligned(4)));
119} incoming, outgoing;
120
121struct attribute {
122    uint16_t flag;
123    uint16_t vendor;
124    uint16_t type;
125    uint8_t value[1];
126} __attribute__((packed));
127
128static 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
146static 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
156static void add_attribute_u16(uint16_t attribute, uint16_t value)
157{
158    add_attribute_raw(attribute, &value, sizeof(uint16_t));
159}
160
161static void add_attribute_u32(uint16_t attribute, uint32_t value)
162{
163    add_attribute_raw(attribute, &value, sizeof(uint32_t));
164}
165
166static 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
174static 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
183static 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
235static 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
310static 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
315static 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
349static 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
373static 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
385static 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
399static 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
411static 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                    set_message(0, SCCCN);
433                    answer_challenge();
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
541static 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
551static 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
562struct 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