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