• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/if_pppolac.h>
32 #include <openssl/md5.h>
33 
34 #include "mtpd.h"
35 
36 /* To avoid unnecessary endianness conversions, tunnels, sessions, attributes,
37  * and values are all accessed in network order. */
38 
39 /* 0 is reserved. We put ACK here just for convenience. */
40 enum l2tp_message {
41     ACK = 0,
42     SCCRQ = 1,
43     SCCRP = 2,
44     SCCCN = 3,
45     STOPCCN = 4,
46     HELLO = 6,
47     OCRQ = 7,
48     OCRP = 8,
49     OCCN = 9,
50     ICRQ = 10,
51     ICRP = 11,
52     ICCN = 12,
53     CDN = 14,
54     WEN = 15,
55     SLI = 16,
56     MESSAGE_MAX = 16,
57 };
58 
59 static char *messages[] = {
60     "ACK", "SCCRQ", "SCCRP", "SCCCN", "STOPCCN", NULL, "HELLO", "OCRQ",
61     "OCRP", "OCCN", "ICRQ", "ICRP", "ICCN", NULL, "CDN", "WEN", "SLI",
62 };
63 
64 /* This is incomplete. Only those we used are listed here. */
65 #define RESULT_CODE             htons(1)
66 #define PROTOCOL_VERSION        htons(2)
67 #define FRAMING_CAPABILITIES    htons(3)
68 #define HOST_NAME               htons(7)
69 #define ASSIGNED_TUNNEL         htons(9)
70 #define WINDOW_SIZE             htons(10)
71 #define CHALLENGE               htons(11)
72 #define CHALLENGE_RESPONSE      htons(13)
73 #define ASSIGNED_SESSION        htons(14)
74 #define CALL_SERIAL_NUMBER      htons(15)
75 #define FRAMING_TYPE            htons(19)
76 #define CONNECT_SPEED           htons(24)
77 #define RANDOM_VECTOR           htons(36)
78 
79 #define MESSAGE_FLAG            0xC802
80 #define MESSAGE_MASK            0xCB0F
81 #define ATTRIBUTE_FLAG(length)  (0x8006 + (length))
82 #define ATTRIBUTE_LENGTH(flag)  (0x03FF & (flag))
83 #define ATTRIBUTE_HIDDEN(flag)  (0x4000 & (flag))
84 
85 #define ACK_SIZE                12
86 #define MESSAGE_HEADER_SIZE     20
87 #define ATTRIBUTE_HEADER_SIZE   6
88 #define MAX_ATTRIBUTE_SIZE      1024
89 
90 static uint16_t local_tunnel;
91 static uint16_t local_session;
92 static uint16_t local_sequence;
93 static uint16_t remote_tunnel;
94 static uint16_t remote_session;
95 static uint16_t remote_sequence;
96 
97 static uint16_t state;
98 static int acknowledged;
99 
100 #define RANDOM_DEVICE   "/dev/urandom"
101 #define CHALLENGE_SIZE  32
102 
103 static char *secret;
104 static int secret_length;
105 static uint8_t challenge[CHALLENGE_SIZE];
106 
107 /* According to RFC 2661 page 46, an exponential backoff strategy is required
108  * for retransmission. However, it might waste too much time waiting for IPsec
109  * negotiation. Here we use the same interval to keep things simple. */
110 #define TIMEOUT_INTERVAL 2000
111 
112 #define MAX_PACKET_LENGTH 2048
113 
114 static struct packet {
115     int message;
116     int length;
117     uint8_t buffer[MAX_PACKET_LENGTH] __attribute__((aligned(4)));
118 } incoming, outgoing;
119 
120 struct attribute {
121     uint16_t flag;
122     uint16_t vendor;
123     uint16_t type;
124     uint8_t value[1];
125 } __attribute__((packed));
126 
set_message(uint16_t session,uint16_t message)127 static void set_message(uint16_t session, uint16_t message)
128 {
129     uint16_t *p = (uint16_t *)outgoing.buffer;
130     p[0] = htons(MESSAGE_FLAG);
131     /* p[1] will be filled in send_packet(). */
132     p[2] = remote_tunnel;
133     p[3] = session;
134     p[4] = htons(local_sequence);
135     p[5] = htons(remote_sequence);
136     p[6] = htons(ATTRIBUTE_FLAG(2));
137     p[7] = 0;
138     p[8] = 0;
139     p[9] = htons(message);
140     outgoing.message = message;
141     outgoing.length = MESSAGE_HEADER_SIZE;
142     ++local_sequence;
143 }
144 
add_attribute_raw(uint16_t type,void * value,int size)145 static void add_attribute_raw(uint16_t type, void *value, int size)
146 {
147     struct attribute *p = (struct attribute *)&outgoing.buffer[outgoing.length];
148     p->flag = htons(ATTRIBUTE_FLAG(size));
149     p->vendor = 0;
150     p->type = type;
151     memcpy(&p->value, value, size);
152     outgoing.length += ATTRIBUTE_HEADER_SIZE + size;
153 }
154 
add_attribute_u16(uint16_t attribute,uint16_t value)155 static void add_attribute_u16(uint16_t attribute, uint16_t value)
156 {
157     add_attribute_raw(attribute, &value, sizeof(uint16_t));
158 }
159 
add_attribute_u32(uint16_t attribute,uint32_t value)160 static void add_attribute_u32(uint16_t attribute, uint32_t value)
161 {
162     add_attribute_raw(attribute, &value, sizeof(uint32_t));
163 }
164 
send_packet()165 static void send_packet()
166 {
167     uint16_t *p = (uint16_t *)outgoing.buffer;
168     p[1] = htons(outgoing.length);
169     send(the_socket, outgoing.buffer, outgoing.length, 0);
170     acknowledged = 0;
171 }
172 
send_ack()173 static void send_ack()
174 {
175     uint16_t buffer[6] = {
176         htons(MESSAGE_FLAG), htons(ACK_SIZE), remote_tunnel, 0,
177         htons(local_sequence), htons(remote_sequence),
178     };
179     send(the_socket, buffer, ACK_SIZE, 0);
180 }
181 
recv_packet(uint16_t * session)182 static int recv_packet(uint16_t *session)
183 {
184     uint16_t *p = (uint16_t *)incoming.buffer;
185 
186     incoming.length = recv(the_socket, incoming.buffer, MAX_PACKET_LENGTH, 0);
187     if (incoming.length == -1 && errno != EINTR) {
188         log_print(FATAL, "Recv() %s", strerror(errno));
189         exit(NETWORK_ERROR);
190     }
191 
192     /* We only handle packets in our tunnel. */
193     if ((incoming.length != ACK_SIZE && incoming.length < MESSAGE_HEADER_SIZE)
194         || (p[0] & htons(MESSAGE_MASK)) != htons(MESSAGE_FLAG)
195         || p[1] > htons(incoming.length) || p[2] != local_tunnel) {
196         return 0;
197     }
198 
199     if (incoming.length == ACK_SIZE) {
200         incoming.message = ACK;
201     } else if (p[6] == htons(ATTRIBUTE_FLAG(2)) && !p[7] && !p[8]) {
202         incoming.message = ntohs(p[9]);
203     } else {
204         return 0;
205     }
206 
207     /* Check if the packet is duplicated and send ACK if necessary. */
208     if ((uint16_t)(ntohs(p[4]) - remote_sequence) > 32767) {
209         if (incoming.message != ACK) {
210             send_ack();
211         }
212         return 0;
213     }
214 
215     if (ntohs(p[5]) == local_sequence) {
216         acknowledged = 1;
217     }
218 
219     /* Our sending and receiving window sizes are both 1. Thus we only handle
220      * this packet if it is their next one and they received our last one. */
221     if (ntohs(p[4]) != remote_sequence || !acknowledged) {
222         return 0;
223     }
224     *session = p[3];
225     if (incoming.message != ACK) {
226         ++remote_sequence;
227     }
228     return 1;
229 }
230 
get_attribute_raw(uint16_t type,void * value,int size)231 static int get_attribute_raw(uint16_t type, void *value, int size)
232 {
233     int offset = MESSAGE_HEADER_SIZE;
234     uint8_t *vector = NULL;
235     int vector_length = 0;
236 
237     while (incoming.length >= offset + ATTRIBUTE_HEADER_SIZE) {
238         struct attribute *p = (struct attribute *)&incoming.buffer[offset];
239         uint16_t flag = ntohs(p->flag);
240         int length = ATTRIBUTE_LENGTH(flag);
241 
242         offset += length;
243         length -= ATTRIBUTE_HEADER_SIZE;
244         if (length < 0 || offset > incoming.length) {
245             break;
246         }
247         if (p->vendor) {
248             continue;
249         }
250         if (p->type != type) {
251             if (p->type == RANDOM_VECTOR && !ATTRIBUTE_HIDDEN(flag)) {
252                 vector = p->value;
253                 vector_length = length;
254             }
255             continue;
256         }
257 
258         if (!ATTRIBUTE_HIDDEN(flag)) {
259             if (size > length) {
260                 size = length;
261             }
262             memcpy(value, p->value, size);
263             return size;
264         }
265 
266         if (!secret || !vector) {
267             return 0;
268         } else {
269             uint8_t buffer[MAX_ATTRIBUTE_SIZE];
270             uint8_t hash[MD5_DIGEST_LENGTH];
271             MD5_CTX ctx;
272             int i = 0;
273 
274             MD5_Init(&ctx);
275             MD5_Update(&ctx, &type, sizeof(uint16_t));
276             MD5_Update(&ctx, secret, secret_length);
277             MD5_Update(&ctx, vector, vector_length);
278             MD5_Final(hash, &ctx);
279 
280             while (i + MD5_DIGEST_LENGTH <= length) {
281                 int j;
282                 for (j = 0; j < MD5_DIGEST_LENGTH; ++j) {
283                     buffer[i + j] = p->value[i + j] ^ hash[j];
284                 }
285                 MD5_Init(&ctx);
286                 MD5_Update(&ctx, secret, secret_length);
287                 MD5_Update(&ctx, &buffer[i], MD5_DIGEST_LENGTH);
288                 MD5_Final(hash, &ctx);
289                 i += MD5_DIGEST_LENGTH;
290             }
291 
292             length = buffer[0] << 8 | buffer[1];
293             if (i == 0 || length > i - 2) {
294                 return 0;
295             }
296             if (size > length) {
297                 size = length;
298             }
299             memcpy(value, &buffer[2], size);
300             return size;
301         }
302     }
303     return 0;
304 }
305 
get_attribute_u16(uint16_t type,uint16_t * value)306 static int get_attribute_u16(uint16_t type, uint16_t *value)
307 {
308     return get_attribute_raw(type, value, sizeof(uint16_t)) == sizeof(uint16_t);
309 }
310 
l2tp_connect(int argc,char ** argv)311 static int l2tp_connect(int argc, char **argv)
312 {
313     if (argc < 2) {
314         return -USAGE_ERROR;
315     }
316     create_socket(AF_INET, SOCK_DGRAM, argv[0], argv[1]);
317 
318     while (!local_tunnel) {
319         local_tunnel = random();
320     }
321 
322     log_print(DEBUG, "Sending SCCRQ (local_tunnel = %d)", local_tunnel);
323     state = SCCRQ;
324     set_message(0, SCCRQ);
325     add_attribute_u16(PROTOCOL_VERSION, htons(0x0100));
326     add_attribute_raw(HOST_NAME, "anonymous", 9);
327     add_attribute_u32(FRAMING_CAPABILITIES, htonl(3));
328     add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
329     add_attribute_u16(WINDOW_SIZE, htons(1));
330 
331     if (argc >= 3) {
332         int fd = open(RANDOM_DEVICE, O_RDONLY);
333         if (fd == -1 || read(fd, challenge, CHALLENGE_SIZE) != CHALLENGE_SIZE) {
334             log_print(FATAL, "Cannot read %s", RANDOM_DEVICE);
335             exit(SYSTEM_ERROR);
336         }
337         close(fd);
338 
339         add_attribute_raw(CHALLENGE, challenge, CHALLENGE_SIZE);
340         secret = argv[2];
341         secret_length = strlen(argv[2]);
342     }
343 
344     send_packet();
345     return TIMEOUT_INTERVAL;
346 }
347 
create_pppox()348 static int create_pppox()
349 {
350     int pppox;
351     log_print(INFO, "Creating PPPoX socket");
352     pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC);
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)) != 0) {
366             log_print(FATAL, "Connect() %s", strerror(errno));
367             exit(SYSTEM_ERROR);
368         }
369     }
370     return pppox;
371 }
372 
compute_response(uint8_t type,void * challenge,int size)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 
verify_challenge()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 
answer_challenge()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 
l2tp_process()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 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 
l2tp_timeout()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 
l2tp_shutdown()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     .usage = "<server> <port> [secret]",
565     .connect = l2tp_connect,
566     .process = l2tp_process,
567     .timeout = l2tp_timeout,
568     .shutdown = l2tp_shutdown,
569 };
570