1 | /* 2 | * Layer Two Tunnelling Protocol Daemon 3 | * Copyright (C) 1998 Adtran, Inc. 4 | * 5 | * Mark Spencer 6 | * 7 | * This software is distributed under the terms 8 | * of the GPL, which you should have received 9 | * along with this source. 10 | * 11 | * Authorization, Accounting, and Access control 12 | * 13 | */ 14 | 15 | #include <stdio.h> 16 | #include <stdlib.h> 17 | #include <netinet/in.h> 18 | #include <arpa/inet.h> 19 | #include <string.h> 20 | #include <errno.h> 21 | #include "l2tp.h" 22 | 23 | extern void bufferDump (char *, int); 24 | 25 | /* FIXME: Accounting? */ 26 | 27 | static struct addr_ent *uaddr[ADDR_HASH_SIZE]; 28 | 29 | void init_addr () 30 | { 31 | int x; 32 | for (x = 0; x < ADDR_HASH_SIZE; x++) 33 | uaddr[x] = NULL; 34 | } 35 | 36 | static int ip_used (unsigned int addr) 37 | { 38 | struct addr_ent *tmp; 39 | tmp = uaddr[addr % ADDR_HASH_SIZE]; 40 | while (tmp) 41 | { 42 | if (tmp->addr == addr) 43 | return -1; 44 | tmp = tmp->next; 45 | } 46 | return 0; 47 | } 48 | 49 | void mk_challenge (char *c, int length) 50 | { 51 | int x; 52 | int *s = (int *) c; 53 | for (x = 0; x < length / sizeof (int); x++) 54 | s[x] = rand (); 55 | } 56 | 57 | void reserve_addr (unsigned int addr) 58 | { 59 | /* Mark this address as in use */ 60 | struct addr_ent *tmp, *tmp2; 61 | addr = ntohl (addr); 62 | if (ip_used (addr)) 63 | return; 64 | tmp = uaddr[addr % ADDR_HASH_SIZE]; 65 | tmp2 = (struct addr_ent *) malloc (sizeof (struct addr_ent)); 66 | uaddr[addr % ADDR_HASH_SIZE] = tmp2; 67 | tmp2->next = tmp; 68 | tmp2->addr = addr; 69 | } 70 | 71 | void unreserve_addr (unsigned int addr) 72 | { 73 | struct addr_ent *tmp, *last = NULL, *z; 74 | addr = ntohl (addr); 75 | tmp = uaddr[addr % ADDR_HASH_SIZE]; 76 | while (tmp) 77 | { 78 | if (tmp->addr == addr) 79 | { 80 | if (last) 81 | { 82 | last->next = tmp->next; 83 | } 84 | else 85 | { 86 | uaddr[addr % ADDR_HASH_SIZE] = tmp->next; 87 | } 88 | z = tmp; 89 | tmp = tmp->next; 90 | free (z); 91 | } 92 | else 93 | { 94 | last = tmp; 95 | tmp = tmp->next; 96 | } 97 | } 98 | } 99 | 100 | unsigned int get_addr (struct iprange *ipr) 101 | { 102 | unsigned int x, y; 103 | int status; 104 | struct iprange *ipr2; 105 | while (ipr) 106 | { 107 | if (ipr->sense == SENSE_ALLOW) 108 | for (x = ntohl (ipr->start); x <= ntohl (ipr->end); x++) 109 | { 110 | /* Found an IP in an ALLOW range, check to be sure it is 111 | consistant through the remaining regions */ 112 | if (!ip_used (x)) 113 | { 114 | status = SENSE_ALLOW; 115 | ipr2 = ipr->next; 116 | while (ipr2) 117 | { 118 | if ((x >= ntohl (ipr2->start)) 119 | && (x <= ntohl (ipr2->end))) 120 | status = ipr2->sense; 121 | ipr2 = ipr2->next; 122 | } 123 | y = htonl (x); 124 | if (status == SENSE_ALLOW) 125 | return y; 126 | } 127 | }; 128 | ipr = ipr->next; 129 | } 130 | return 0; 131 | } 132 | 133 | int get_secret (char *us, char *them, char *secret, int size) 134 | { 135 | FILE *f; 136 | char buf[STRLEN]; 137 | char *u, *t, *s; 138 | int num = 0; 139 | f = fopen (gconfig.authfile, "r"); 140 | if (!f) 141 | { 142 | log (LOG_WARN, "%s : Unable to open '%s' for authentication\n", 143 | __FUNCTION__, gconfig.authfile); 144 | return 0; 145 | } 146 | while (!feof (f)) 147 | { 148 | num++; 149 | fgets (buf, sizeof (buf), f); 150 | if (feof (f)) 151 | break; 152 | /* Strip comments */ 153 | for (t = buf; *t; t++) 154 | *t = ((*t == '#') || (*t == ';')) ? 0 : *t; 155 | /* Strip trailing whitespace */ 156 | for (t = buf + strlen (buf) - 1; (t >= buf) && (*t < 33); t--) 157 | *t = 0; 158 | if (!strlen (buf)) 159 | continue; /* Empty line */ 160 | u = buf; 161 | while (*u && (*u < 33)) 162 | u++; 163 | /* us */ 164 | if (!*u) 165 | { 166 | log (LOG_WARN, 167 | "%s: Invalid authentication info (no us), line %d\n", 168 | __FUNCTION__, num); 169 | continue; 170 | } 171 | t = u; 172 | while (*t > 32) 173 | t++; 174 | *(t++) = 0; 175 | while (*t && (*t < 33)) 176 | t++; 177 | /* them */ 178 | if (!*t) 179 | { 180 | log (LOG_WARN, 181 | "%s: Invalid authentication info (nothem), line %d\n", 182 | __FUNCTION__, num); 183 | continue; 184 | } 185 | s = t; 186 | while (*s > 33) 187 | s++; 188 | *(s++) = 0; 189 | while (*s && (*s < 33)) 190 | s++; 191 | if (!*s) 192 | { 193 | log (LOG_WARN, 194 | "%s: Invalid authentication info (no secret), line %d\n", 195 | __FUNCTION__, num); 196 | continue; 197 | } 198 | if ((!strcasecmp (u, us) || !strcasecmp (u, "*")) && 199 | (!strcasecmp (t, them) || !strcasecmp (t, "*"))) 200 | { 201 | #ifdef DEBUG_AUTH 202 | log (LOG_DEBUG, 203 | "%s: we are '%s', they are '%s', secret is '%s'\n", 204 | __FUNCTION__, u, t, s); 205 | #endif 206 | strncpy (secret, s, size); 207 | return -1; 208 | } 209 | } 210 | return 0; 211 | } 212 | 213 | int handle_challenge (struct tunnel *t, struct challenge *chal) 214 | { 215 | char *us; 216 | char *them; 217 | if (!t->lns && !t->lac) 218 | { 219 | log (LOG_DEBUG, "%s: No LNS or LAC to handle challenge!\n", 220 | __FUNCTION__); 221 | return -1; 222 | } 223 | #ifdef DEBUG_AUTH 224 | log (LOG_DEBUG, "%s: making response for tunnel%d\n", __FUNCTION__, 225 | t->ourtid); 226 | #endif 227 | if (t->lns) 228 | { 229 | if (t->lns->hostname[0]) 230 | us = t->lns->hostname; 231 | else 232 | us = hostname; 233 | if (t->lns->peername[0]) 234 | them = t->lns->peername; 235 | else 236 | them = t->hostname; 237 | } 238 | else 239 | { 240 | if (t->lac->hostname[0]) 241 | us = t->lac->hostname; 242 | else 243 | us = hostname; 244 | if (t->lac->peername[0]) 245 | them = t->lac->peername; 246 | else 247 | them = t->hostname; 248 | } 249 | if (!get_secret (us, them, chal->secret, sizeof (chal->secret))) 250 | { 251 | log (LOG_DEBUG, "%s: no secret found for us='%s' and them='%s'\n", 252 | __FUNCTION__, us, them); 253 | return -1; 254 | } 255 | 256 | #if DEBUG_AUTH 257 | log (LOG_DEBUG, "*%s: Here comes the chal->ss:\n", __FUNCTION__); 258 | bufferDump (&chal->ss, 1); 259 | 260 | log (LOG_DEBUG, "%s: Here comes the secret\n", __FUNCTION__); 261 | bufferDump (chal->secret, strlen (chal->secret)); 262 | 263 | log (LOG_DEBUG, "%s: Here comes the challenge\n", __FUNCTION__); 264 | bufferDump (chal->challenge, MD_SIG_SIZE); 265 | #endif 266 | 267 | memset (chal->response, 0, MD_SIG_SIZE); 268 | MD5Init (&chal->md5); 269 | MD5Update (&chal->md5, &chal->ss, 1); 270 | MD5Update (&chal->md5, chal->secret, strlen (chal->secret)); 271 | MD5Update (&chal->md5, chal->challenge, MD_SIG_SIZE); 272 | MD5Final (chal->response, &chal->md5); 273 | #ifdef DEBUG_AUTH 274 | log (LOG_DEBUG, "response is %X%X%X%X to '%s' and %X%X%X%X, %d\n", 275 | *((int *) &chal->response[0]), 276 | *((int *) &chal->response[4]), 277 | *((int *) &chal->response[8]), 278 | *((int *) &chal->response[12]), 279 | chal->secret, 280 | *((int *) &chal->challenge[0]), 281 | *((int *) &chal->challenge[4]), 282 | *((int *) &chal->challenge[8]), 283 | *((int *) &chal->challenge[12]), chal->ss); 284 | #endif 285 | chal->state = STATE_CHALLENGED; 286 | return 0; 287 | } 288 | 289 | struct lns *get_lns (struct tunnel *t) 290 | { 291 | /* 292 | * Look through our list of LNS's and 293 | * find a reasonable LNS for this call 294 | * if one is available 295 | */ 296 | struct lns *lns; 297 | struct iprange *ipr; 298 | int allow, checkdefault = 0; 299 | /* If access control is disabled, we give the default 300 | otherwise, we give nothing */ 301 | allow = 0; 302 | lns = lnslist; 303 | if (!lns) 304 | { 305 | lns = deflns; 306 | checkdefault = -1; 307 | } 308 | while (lns) 309 | { 310 | ipr = lns->lacs; 311 | while (ipr) 312 | { 313 | if ((ntohl (t->peer.sin_addr.s_addr) >= ntohl (ipr->start)) && 314 | (ntohl (t->peer.sin_addr.s_addr) <= ntohl (ipr->end))) 315 | { 316 | #ifdef DEBUG_AAA 317 | log (LOG_DEBUG, 318 | "get_lns: Rule %s to %s, sense %s matched %s\n", 319 | IPADDY (ipr->start), IPADDY (ipr->end), 320 | (ipr->sense ? "allow" : "deny"), IPADDY (t->addr)); 321 | #endif 322 | allow = ipr->sense; 323 | } 324 | ipr = ipr->next; 325 | } 326 | if (allow) 327 | return lns; 328 | lns = lns->next; 329 | if (!lns && !checkdefault) 330 | { 331 | lns = deflns; 332 | checkdefault = -1; 333 | } 334 | } 335 | if (gconfig.accesscontrol) 336 | return NULL; 337 | else 338 | return deflns; 339 | } 340 | 341 | #ifdef DEBUG_HIDDEN 342 | void print_md5 (void *md5) 343 | { 344 | int *i = (int *) md5; 345 | log (LOG_DEBUG, "%X%X%X%X\n", i[0], i[1], i[2], i[3], i[4]); 346 | } 347 | 348 | inline void print_challenge (struct challenge *chal) 349 | { 350 | log (LOG_DEBUG, "vector: "); 351 | print_md5 (chal->vector); 352 | log (LOG_DEBUG, "secret: %s\n", chal->secret); 353 | } 354 | #endif 355 | void encrypt_avp (struct buffer *buf, _u16 len, struct tunnel *t) 356 | { 357 | /* Encrypts an AVP of len, at data. We assume there 358 | are two "spare bytes" before the data pointer,l but otherwise 359 | this is just a normal AVP that is about to be returned from 360 | an avpsend routine */ 361 | struct avp_hdr *new_hdr = 362 | (struct avp_hdr *) (buf->start + buf->len - len); 363 | struct avp_hdr *old_hdr = 364 | (struct avp_hdr *) (buf->start + buf->len - len + 2); 365 | _u16 length, flags, attr; /* New length, old flags */ 366 | char *ptr, *end; 367 | int cnt; 368 | unsigned char digest[MD_SIG_SIZE]; 369 | unsigned char *previous_segment; 370 | 371 | /* FIXME: Should I pad more randomly? Right now I pad to nearest 16 bytes */ 372 | length = 373 | ((len - sizeof (struct avp_hdr) + 1) / 16 + 1) * 16 + 374 | sizeof (struct avp_hdr); 375 | flags = htons (old_hdr->length) & 0xF000; 376 | new_hdr->length = htons (length | flags | HBIT); 377 | new_hdr->vendorid = old_hdr->vendorid; 378 | new_hdr->attr = attr = old_hdr->attr; 379 | /* This is really the length field of the hidden sub-format */ 380 | old_hdr->attr = htons (len - sizeof (struct avp_hdr)); 381 | /* Okay, now we've rewritten the header, as it should be. Let's start 382 | encrypting the actual data now */ 383 | buf->len -= len; 384 | buf->len += length; 385 | /* Back to the beginning of real data, including the original length AVP */ 386 | 387 | MD5Init (&t->chal_them.md5); 388 | MD5Update (&t->chal_them.md5, (void *) &attr, 2); 389 | MD5Update (&t->chal_them.md5, t->chal_them.secret, 390 | strlen (t->chal_them.secret)); 391 | MD5Update (&t->chal_them.md5, t->chal_them.vector, VECTOR_SIZE); 392 | MD5Final (digest, &t->chal_them.md5); 393 | 394 | /* Though not a "MUST" in the spec, our subformat length is always a multiple of 16 */ 395 | ptr = ((char *) new_hdr) + sizeof (struct avp_hdr); 396 | end = ((char *) new_hdr) + length; 397 | previous_segment = ptr; 398 | while (ptr < end) 399 | { 400 | #if DEBUG_HIDDEN 401 | log (LOG_DEBUG, "%s: The digest to be XOR'ed\n", __FUNCTION__); 402 | bufferDump (digest, MD_SIG_SIZE); 403 | log (LOG_DEBUG, "%s: The plaintext to be XOR'ed\n", __FUNCTION__); 404 | bufferDump (ptr, MD_SIG_SIZE); 405 | #endif 406 | for (cnt = 0; cnt < MD_SIG_SIZE; cnt++, ptr++) 407 | { 408 | *ptr = *ptr ^ digest[cnt]; 409 | } 410 | #if DEBUG_HIDDEN 411 | log (LOG_DEBUG, "%s: The result of XOR\n", __FUNCTION__); 412 | bufferDump (previous_segment, MD_SIG_SIZE); 413 | #endif 414 | if (ptr < end) 415 | { 416 | MD5Init (&t->chal_them.md5); 417 | MD5Update (&t->chal_them.md5, t->chal_them.secret, 418 | strlen (t->chal_them.secret)); 419 | MD5Update (&t->chal_them.md5, previous_segment, MD_SIG_SIZE); 420 | MD5Final (digest, &t->chal_them.md5); 421 | } 422 | previous_segment = ptr; 423 | } 424 | } 425 | 426 | int decrypt_avp (char *buf, struct tunnel *t) 427 | { 428 | /* Decrypts a hidden AVP pointed to by buf. The 429 | new header will be exptected to be two characters 430 | offset from the old */ 431 | int cnt = 0; 432 | int len, olen, flags; 433 | char digest[MD_SIG_SIZE]; 434 | char *ptr, *end; 435 | _u16 attr; 436 | struct avp_hdr *old_hdr = (struct avp_hdr *) buf; 437 | struct avp_hdr *new_hdr = (struct avp_hdr *) (buf + 2); 438 | int saved_segment_len; /* maybe less 16; may be used if the cipher is longer than 16 octets */ 439 | char saved_segment[MD_SIG_SIZE]; 440 | ptr = ((char *) old_hdr) + sizeof (struct avp_hdr); 441 | olen = old_hdr->length & 0x0FFF; 442 | end = buf + olen; 443 | if (!t->chal_us.vector) 444 | { 445 | log (LOG_DEBUG, 446 | "decrypt_avp: Hidden bit set, but no random vector specified!\n"); 447 | return -EINVAL; 448 | } 449 | /* First, let's decrypt all the data. We're not guaranteed 450 | that it will be padded to a 16 byte boundary, so we 451 | have to be more careful than when encrypting */ 452 | attr = ntohs (old_hdr->attr); 453 | MD5Init (&t->chal_us.md5); 454 | MD5Update (&t->chal_us.md5, (void *) &attr, 2); 455 | MD5Update (&t->chal_us.md5, t->chal_us.secret, 456 | strlen (t->chal_us.secret)); 457 | MD5Update (&t->chal_us.md5, t->chal_us.vector, t->chal_us.vector_len); 458 | MD5Final (digest, &t->chal_us.md5); 459 | #ifdef DEBUG_HIDDEN 460 | log (LOG_DEBUG, "attribute is %d and challenge is: ", attr); 461 | print_challenge (&t->chal_us); 462 | log (LOG_DEBUG, "md5 is: "); 463 | print_md5 (digest); 464 | #endif 465 | while (ptr < end) 466 | { 467 | if (cnt >= MD_SIG_SIZE) 468 | { 469 | MD5Init (&t->chal_us.md5); 470 | MD5Update (&t->chal_us.md5, t->chal_us.secret, 471 | strlen (t->chal_us.secret)); 472 | MD5Update (&t->chal_us.md5, saved_segment, MD_SIG_SIZE); 473 | MD5Final (digest, &t->chal_us.md5); 474 | cnt = 0; 475 | } 476 | /* at the beginning of each segment, we save the current segment (16 octets or less) of cipher 477 | * so that the next round of MD5 (if there is a next round) hash could use it 478 | */ 479 | if (cnt == 0) 480 | { 481 | saved_segment_len = 482 | (end - ptr < MD_SIG_SIZE) ? (end - ptr) : MD_SIG_SIZE; 483 | memcpy (saved_segment, ptr, saved_segment_len); 484 | } 485 | *ptr = *ptr ^ digest[cnt++]; 486 | ptr++; 487 | } 488 | /* Hopefully we're all nice and decrypted now. Let's rewrite the header. 489 | First save the old flags, and get the new stuff */ 490 | flags = old_hdr->length & 0xF000 & ~HBIT; 491 | len = ntohs (new_hdr->attr) + sizeof (struct avp_hdr); 492 | if (len > olen - 2) 493 | { 494 | log (LOG_DEBUG, 495 | "decrypt_avp: Decrypted length is too long (%d > %d)\n", len, 496 | olen - 2); 497 | return -EINVAL; 498 | } 499 | new_hdr->attr = old_hdr->attr; 500 | new_hdr->vendorid = old_hdr->vendorid; 501 | new_hdr->length = len | flags; 502 | return 0; 503 | }