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
34enum 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
53static char *messages[] = {
54    NULL, "SCCRQ", "SCCRP", "STOPCCRQ", "STOPCCRP", "ECHORQ", "ECHORP",
55    "OCRQ", "OCRP", "ICRQ", "ICRP", "ICCN", "CCRQ", "CDN", "WEN", "SLI",
56};
57
58static 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
75static uint16_t local;
76static uint16_t remote;
77static 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. */
84static 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
134static 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
145static void send_packet()
146{
147    send(the_socket, outgoing.buffer, outgoing.length, 0);
148}
149
150static 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
216static 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
232static 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
256static 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
387static int pptp_timeout()
388{
389    return 0;
390}
391
392static 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
398struct 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