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 <unistd.h> 31 #include <arpa/inet.h> 32 #include <linux/netdevice.h> 33 #include <linux/if_pppox.h> 34 #include <openssl/md5.h> 35 36 #include "mtpd.h" 37 38 /* To avoid unnecessary endianness conversions, tunnels, sessions, attributes, 39 * and values are all accessed in network order. */ 40 41 /* 0 is reserved. We put ACK here just for convenience. */ 42 enum l2tp_message { 43 ACK = 0, 44 SCCRQ = 1, 45 SCCRP = 2, 46 SCCCN = 3, 47 STOPCCN = 4, 48 HELLO = 6, 49 OCRQ = 7, 50 OCRP = 8, 51 OCCN = 9, 52 ICRQ = 10, 53 ICRP = 11, 54 ICCN = 12, 55 CDN = 14, 56 WEN = 15, 57 SLI = 16, 58 MESSAGE_MAX = 16, 59 }; 60 61 static char *messages[] = { 62 "ACK", "SCCRQ", "SCCRP", "SCCCN", "STOPCCN", NULL, "HELLO", "OCRQ", 63 "OCRP", "OCCN", "ICRQ", "ICRP", "ICCN", NULL, "CDN", "WEN", "SLI", 64 }; 65 66 /* This is incomplete. Only those we used are listed here. */ 67 #define RESULT_CODE htons(1) 68 #define PROTOCOL_VERSION htons(2) 69 #define FRAMING_CAPABILITIES htons(3) 70 #define HOST_NAME htons(7) 71 #define ASSIGNED_TUNNEL htons(9) 72 #define WINDOW_SIZE htons(10) 73 #define CHALLENGE htons(11) 74 #define CHALLENGE_RESPONSE htons(13) 75 #define ASSIGNED_SESSION htons(14) 76 #define CALL_SERIAL_NUMBER htons(15) 77 #define FRAMING_TYPE htons(19) 78 #define CONNECT_SPEED htons(24) 79 #define RANDOM_VECTOR htons(36) 80 81 #define MESSAGE_FLAG 0xC802 82 #define MESSAGE_MASK 0xCB0F 83 #define ATTRIBUTE_FLAG(length) (0x8006 + (length)) 84 #define ATTRIBUTE_LENGTH(flag) (0x03FF & (flag)) 85 #define ATTRIBUTE_HIDDEN(flag) (0x4000 & (flag)) 86 87 #define ACK_SIZE 12 88 #define MESSAGE_HEADER_SIZE 20 89 #define ATTRIBUTE_HEADER_SIZE 6 90 #define MAX_ATTRIBUTE_SIZE 1024 91 92 static uint16_t local_tunnel; 93 static uint16_t local_session; 94 static uint16_t local_sequence; 95 static uint16_t remote_tunnel; 96 static uint16_t remote_session; 97 static uint16_t remote_sequence; 98 99 static uint16_t state; 100 static int acknowledged; 101 102 #define RANDOM_DEVICE "/dev/urandom" 103 #define CHALLENGE_SIZE 32 104 105 static char *secret; 106 static int secret_length; 107 static uint8_t challenge[CHALLENGE_SIZE]; 108 109 /* According to RFC 2661 page 46, an exponential backoff strategy is required 110 * for retransmission. However, it might waste too much time waiting for IPsec 111 * negotiation. Here we use the same interval to keep things simple. */ 112 #define TIMEOUT_INTERVAL 2000 113 114 #define MAX_PACKET_LENGTH 2048 115 116 static struct packet { 117 int message; 118 int length; 119 uint8_t buffer[MAX_PACKET_LENGTH] __attribute__((aligned(4))); 120 } incoming, outgoing; 121 122 struct attribute { 123 uint16_t flag; 124 uint16_t vendor; 125 uint16_t type; 126 uint8_t value[1]; 127 } __attribute__((packed)); 128 129 static void set_message(uint16_t session, uint16_t message) 130 { 131 uint16_t *p = (uint16_t *)outgoing.buffer; 132 p[0] = htons(MESSAGE_FLAG); 133 /* p[1] will be filled in send_packet(). */ 134 p[2] = remote_tunnel; 135 p[3] = session; 136 p[4] = htons(local_sequence); 137 p[5] = htons(remote_sequence); 138 p[6] = htons(ATTRIBUTE_FLAG(2)); 139 p[7] = 0; 140 p[8] = 0; 141 p[9] = htons(message); 142 outgoing.message = message; 143 outgoing.length = MESSAGE_HEADER_SIZE; 144 ++local_sequence; 145 } 146 147 static void add_attribute_raw(uint16_t type, void *value, int size) 148 { 149 struct attribute *p = (struct attribute *)&outgoing.buffer[outgoing.length]; 150 p->flag = htons(ATTRIBUTE_FLAG(size)); 151 p->vendor = 0; 152 p->type = type; 153 memcpy(&p->value, value, size); 154 outgoing.length += ATTRIBUTE_HEADER_SIZE + size; 155 } 156 157 static void add_attribute_u16(uint16_t attribute, uint16_t value) 158 { 159 add_attribute_raw(attribute, &value, sizeof(uint16_t)); 160 } 161 162 static void add_attribute_u32(uint16_t attribute, uint32_t value) 163 { 164 add_attribute_raw(attribute, &value, sizeof(uint32_t)); 165 } 166 167 static void send_packet() 168 { 169 uint16_t *p = (uint16_t *)outgoing.buffer; 170 p[1] = htons(outgoing.length); 171 send(the_socket, outgoing.buffer, outgoing.length, 0); 172 acknowledged = 0; 173 } 174 175 static void send_ack() 176 { 177 uint16_t buffer[6] = { 178 htons(MESSAGE_FLAG), htons(ACK_SIZE), remote_tunnel, 0, 179 htons(local_sequence), htons(remote_sequence), 180 }; 181 send(the_socket, buffer, ACK_SIZE, 0); 182 } 183 184 static int recv_packet(uint16_t *session) 185 { 186 uint16_t *p = (uint16_t *)incoming.buffer; 187 188 incoming.length = recv(the_socket, incoming.buffer, MAX_PACKET_LENGTH, 0); 189 if (incoming.length == -1) { 190 if (errno == EINTR) { 191 return 0; 192 } 193 log_print(FATAL, "Recv() %s", strerror(errno)); 194 exit(NETWORK_ERROR); 195 } 196 197 /* We only handle packets in our tunnel. */ 198 if ((incoming.length != ACK_SIZE && incoming.length < MESSAGE_HEADER_SIZE) 199 || (p[0] & htons(MESSAGE_MASK)) != htons(MESSAGE_FLAG) || 200 ntohs(p[1]) != incoming.length || p[2] != local_tunnel) { 201 return 0; 202 } 203 204 if (incoming.length == ACK_SIZE) { 205 incoming.message = ACK; 206 } else if (p[6] == htons(ATTRIBUTE_FLAG(2)) && !p[7] && !p[8]) { 207 incoming.message = ntohs(p[9]); 208 } else { 209 return 0; 210 } 211 212 /* Check if the packet is duplicated and send ACK if necessary. */ 213 if ((uint16_t)(ntohs(p[4]) - remote_sequence) > 32767) { 214 if (incoming.message != ACK) { 215 send_ack(); 216 } 217 return 0; 218 } 219 220 if (ntohs(p[5]) == local_sequence) { 221 acknowledged = 1; 222 } 223 224 /* Our sending and receiving window sizes are both 1. Thus we only handle 225 * this packet if it is their next one and they received our last one. */ 226 if (ntohs(p[4]) != remote_sequence || !acknowledged) { 227 return 0; 228 } 229 *session = p[3]; 230 if (incoming.message != ACK) { 231 ++remote_sequence; 232 } 233 return 1; 234 } 235 236 static int get_attribute_raw(uint16_t type, void *value, int size) 237 { 238 int offset = MESSAGE_HEADER_SIZE; 239 uint8_t *vector = NULL; 240 int vector_length = 0; 241 242 while (incoming.length >= offset + ATTRIBUTE_HEADER_SIZE) { 243 struct attribute *p = (struct attribute *)&incoming.buffer[offset]; 244 uint16_t flag = ntohs(p->flag); 245 int length = ATTRIBUTE_LENGTH(flag); 246 247 offset += length; 248 length -= ATTRIBUTE_HEADER_SIZE; 249 if (length < 0 || offset > incoming.length) { 250 break; 251 } 252 if (p->vendor) { 253 continue; 254 } 255 if (p->type != type) { 256 if (p->type == RANDOM_VECTOR && !ATTRIBUTE_HIDDEN(flag)) { 257 vector = p->value; 258 vector_length = length; 259 } 260 continue; 261 } 262 263 if (!ATTRIBUTE_HIDDEN(flag)) { 264 if (size > length) { 265 size = length; 266 } 267 memcpy(value, p->value, size); 268 return size; 269 } 270 271 if (!secret || !vector || length < 2) { 272 return 0; 273 } else { 274 uint8_t buffer[MAX_ATTRIBUTE_SIZE]; 275 uint8_t hash[MD5_DIGEST_LENGTH]; 276 MD5_CTX ctx; 277 int i; 278 279 MD5_Init(&ctx); 280 MD5_Update(&ctx, &type, sizeof(uint16_t)); 281 MD5_Update(&ctx, secret, secret_length); 282 MD5_Update(&ctx, vector, vector_length); 283 MD5_Final(hash, &ctx); 284 285 for (i = 0; i < length; ++i) { 286 int j = i % MD5_DIGEST_LENGTH; 287 if (i && !j) { 288 MD5_Init(&ctx); 289 MD5_Update(&ctx, secret, secret_length); 290 MD5_Update(&ctx, &p->value[i - MD5_DIGEST_LENGTH], 291 MD5_DIGEST_LENGTH); 292 MD5_Final(hash, &ctx); 293 } 294 buffer[i] = p->value[i] ^ hash[j]; 295 } 296 297 length = buffer[0] << 8 | buffer[1]; 298 if (length > i - 2) { 299 return 0; 300 } 301 if (size > length) { 302 size = length; 303 } 304 memcpy(value, &buffer[2], size); 305 return size; 306 } 307 } 308 return 0; 309 } 310 311 static int get_attribute_u16(uint16_t type, uint16_t *value) 312 { 313 return get_attribute_raw(type, value, sizeof(uint16_t)) == sizeof(uint16_t); 314 } 315 316 static int l2tp_connect(char **arguments) 317 { 318 create_socket(AF_INET, SOCK_DGRAM, arguments[0], arguments[1]); 319 320 while (!local_tunnel) { 321 local_tunnel = random(); 322 } 323 324 log_print(DEBUG, "Sending SCCRQ (local_tunnel = %d)", local_tunnel); 325 state = SCCRQ; 326 set_message(0, SCCRQ); 327 add_attribute_u16(PROTOCOL_VERSION, htons(0x0100)); 328 add_attribute_raw(HOST_NAME, "anonymous", 9); 329 add_attribute_u32(FRAMING_CAPABILITIES, htonl(3)); 330 add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel); 331 add_attribute_u16(WINDOW_SIZE, htons(1)); 332 333 if (arguments[2][0]) { 334 int fd = open(RANDOM_DEVICE, O_RDONLY); 335 if (fd == -1 || read(fd, challenge, CHALLENGE_SIZE) != CHALLENGE_SIZE) { 336 log_print(FATAL, "Cannot read %s", RANDOM_DEVICE); 337 exit(SYSTEM_ERROR); 338 } 339 close(fd); 340 341 add_attribute_raw(CHALLENGE, challenge, CHALLENGE_SIZE); 342 secret = arguments[2]; 343 secret_length = strlen(arguments[2]); 344 } 345 346 send_packet(); 347 return TIMEOUT_INTERVAL; 348 } 349 350 static int create_pppox() 351 { 352 int pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC); 353 log_print(INFO, "Creating PPPoX socket"); 354 355 if (pppox == -1) { 356 log_print(FATAL, "Socket() %s", strerror(errno)); 357 exit(SYSTEM_ERROR); 358 } else { 359 struct sockaddr_pppolac address = { 360 .sa_family = AF_PPPOX, 361 .sa_protocol = PX_PROTO_OLAC, 362 .udp_socket = the_socket, 363 .local = {.tunnel = local_tunnel, .session = local_session}, 364 .remote = {.tunnel = remote_tunnel, .session = remote_session}, 365 }; 366 if (connect(pppox, (struct sockaddr *)&address, sizeof(address))) { 367 log_print(FATAL, "Connect() %s", strerror(errno)); 368 exit(SYSTEM_ERROR); 369 } 370 } 371 return pppox; 372 } 373 374 static uint8_t *compute_response(uint8_t type, void *challenge, int size) 375 { 376 static uint8_t response[MD5_DIGEST_LENGTH]; 377 MD5_CTX ctx; 378 MD5_Init(&ctx); 379 MD5_Update(&ctx, &type, sizeof(uint8_t)); 380 MD5_Update(&ctx, secret, secret_length); 381 MD5_Update(&ctx, challenge, size); 382 MD5_Final(response, &ctx); 383 return response; 384 } 385 386 static int verify_challenge() 387 { 388 if (secret) { 389 uint8_t response[MD5_DIGEST_LENGTH]; 390 if (get_attribute_raw(CHALLENGE_RESPONSE, response, MD5_DIGEST_LENGTH) 391 != MD5_DIGEST_LENGTH) { 392 return 0; 393 } 394 return !memcmp(compute_response(SCCRP, challenge, CHALLENGE_SIZE), 395 response, MD5_DIGEST_LENGTH); 396 } 397 return 1; 398 } 399 400 static void answer_challenge() 401 { 402 if (secret) { 403 uint8_t challenge[MAX_ATTRIBUTE_SIZE]; 404 int size = get_attribute_raw(CHALLENGE, challenge, MAX_ATTRIBUTE_SIZE); 405 if (size > 0) { 406 uint8_t *response = compute_response(SCCCN, challenge, size); 407 add_attribute_raw(CHALLENGE_RESPONSE, response, MD5_DIGEST_LENGTH); 408 } 409 } 410 } 411 412 static int l2tp_process() 413 { 414 uint16_t sequence = local_sequence; 415 uint16_t tunnel = 0; 416 uint16_t session = 0; 417 418 if (!recv_packet(&session)) { 419 return acknowledged ? 0 : TIMEOUT_INTERVAL; 420 } 421 422 /* Here is the fun part. We always try to protect our tunnel and session 423 * from being closed even if we received unexpected messages. */ 424 switch(incoming.message) { 425 case SCCRP: 426 if (state == SCCRQ) { 427 if (get_attribute_u16(ASSIGNED_TUNNEL, &tunnel) && tunnel && 428 verify_challenge()) { 429 remote_tunnel = tunnel; 430 log_print(DEBUG, "Received SCCRP (remote_tunnel = %d) -> " 431 "Sending SCCCN", remote_tunnel); 432 state = SCCCN; 433 set_message(0, SCCCN); 434 answer_challenge(); 435 break; 436 } 437 log_print(DEBUG, "Received SCCRP without %s", tunnel ? 438 "valid challenge response" : "assigned tunnel"); 439 log_print(ERROR, "Protocol error"); 440 return tunnel ? -CHALLENGE_FAILED : -PROTOCOL_ERROR; 441 } 442 break; 443 444 case ICRP: 445 if (state == ICRQ && session == local_session) { 446 if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) { 447 remote_session = session; 448 log_print(DEBUG, "Received ICRP (remote_session = %d) -> " 449 "Sending ICCN", remote_session); 450 state = ICCN; 451 set_message(remote_session, ICCN); 452 add_attribute_u32(CONNECT_SPEED, htonl(100000000)); 453 add_attribute_u32(FRAMING_TYPE, htonl(3)); 454 break; 455 } 456 log_print(DEBUG, "Received ICRP without assigned session"); 457 log_print(ERROR, "Protocol error"); 458 return -PROTOCOL_ERROR; 459 } 460 break; 461 462 case STOPCCN: 463 log_print(DEBUG, "Received STOPCCN"); 464 log_print(INFO, "Remote server hung up"); 465 state = STOPCCN; 466 return -REMOTE_REQUESTED; 467 468 case CDN: 469 if (session && session == local_session) { 470 log_print(DEBUG, "Received CDN (local_session = %d)", 471 local_session); 472 log_print(INFO, "Remote server hung up"); 473 return -REMOTE_REQUESTED; 474 } 475 break; 476 477 case ACK: 478 case HELLO: 479 case WEN: 480 case SLI: 481 /* These are harmless, so we just treat them in the same way. */ 482 if (state == SCCCN) { 483 while (!local_session) { 484 local_session = random(); 485 } 486 log_print(DEBUG, "Received %s -> Sending ICRQ (local_session = " 487 "%d)", messages[incoming.message], local_session); 488 log_print(INFO, "Tunnel established"); 489 state = ICRQ; 490 set_message(0, ICRQ); 491 add_attribute_u16(ASSIGNED_SESSION, local_session); 492 add_attribute_u32(CALL_SERIAL_NUMBER, random()); 493 break; 494 } 495 496 if (incoming.message == ACK) { 497 log_print(DEBUG, "Received ACK"); 498 } else { 499 log_print(DEBUG, "Received %s -> Sending ACK", 500 messages[incoming.message]); 501 send_ack(); 502 } 503 504 if (state == ICCN) { 505 log_print(INFO, "Session established"); 506 state = ACK; 507 start_pppd(create_pppox()); 508 } 509 return 0; 510 511 case ICRQ: 512 case OCRQ: 513 /* Since we run pppd as a client, it does not makes sense to 514 * accept ICRQ or OCRQ. Always send CDN with a proper error. */ 515 if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) { 516 log_print(DEBUG, "Received %s (remote_session = %d) -> " 517 "Sending CDN", messages[incoming.message], session); 518 set_message(session, CDN); 519 add_attribute_u32(RESULT_CODE, htonl(0x00020006)); 520 add_attribute_u16(ASSIGNED_SESSION, 0); 521 } 522 break; 523 } 524 525 if (sequence != local_sequence) { 526 send_packet(); 527 return TIMEOUT_INTERVAL; 528 } 529 530 /* We reach here if we got an unexpected message. Log it and send ACK. */ 531 if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) { 532 log_print(DEBUG, "Received UNKNOWN %d -> Sending ACK anyway", 533 incoming.message); 534 } else { 535 log_print(DEBUG, "Received UNEXPECTED %s -> Sending ACK anyway", 536 messages[incoming.message]); 537 } 538 send_ack(); 539 return 0; 540 } 541 542 static int l2tp_timeout() 543 { 544 if (acknowledged) { 545 return 0; 546 } 547 log_print(DEBUG, "Timeout -> Sending %s", messages[outgoing.message]); 548 send(the_socket, outgoing.buffer, outgoing.length, 0); 549 return TIMEOUT_INTERVAL; 550 } 551 552 static void l2tp_shutdown() 553 { 554 if (state != STOPCCN) { 555 log_print(DEBUG, "Sending STOPCCN"); 556 set_message(0, STOPCCN); 557 add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel); 558 add_attribute_u16(RESULT_CODE, htons(6)); 559 send_packet(); 560 } 561 } 562 563 struct protocol l2tp = { 564 .name = "l2tp", 565 .arguments = 3, 566 .usage = "<server> <port> <secret>", 567 .connect = l2tp_connect, 568 .process = l2tp_process, 569 .timeout = l2tp_timeout, 570 .shutdown = l2tp_shutdown, 571 }; 572