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
set_message(uint16_t session,uint16_t message)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
add_attribute_raw(uint16_t type,void * value,int size)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
add_attribute_u16(uint16_t attribute,uint16_t value)156 static void add_attribute_u16(uint16_t attribute, uint16_t value)
157 {
158 add_attribute_raw(attribute, &value, sizeof(uint16_t));
159 }
160
add_attribute_u32(uint16_t attribute,uint32_t value)161 static void add_attribute_u32(uint16_t attribute, uint32_t value)
162 {
163 add_attribute_raw(attribute, &value, sizeof(uint32_t));
164 }
165
send_packet()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
send_ack()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
recv_packet(uint16_t * session)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
get_attribute_raw(uint16_t type,void * value,int size)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
get_attribute_u16(uint16_t type,uint16_t * value)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
l2tp_connect(char ** arguments)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
create_pppox()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
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 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
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 .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