1/* 2 * Copyright (c) 1997-2000 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 19 unchanged lines hidden (view full) --- 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "kdc_locl.h" 35 |
36RCSID("$Id: connect.c,v 1.70 2000/02/19 18:41:24 assar Exp $"); |
37 38/* 39 * a tuple describing on what to listen 40 */ 41 42struct port_desc{ 43 int family; 44 int type; --- 143 unchanged lines hidden (view full) --- 188 189struct descr { 190 int s; 191 int type; 192 unsigned char *buf; 193 size_t size; 194 size_t len; 195 time_t timeout; |
196 struct sockaddr_storage __ss; 197 struct sockaddr *sa; 198 int sock_len; 199 char addr_string[128]; |
200}; 201 202/* 203 * Create the socket (family, type, port) in `d' 204 */ 205 206static void 207init_socket(struct descr *d, krb5_address *a, int family, int type, int port) 208{ 209 krb5_error_code ret; 210 struct sockaddr_storage __ss; 211 struct sockaddr *sa = (struct sockaddr *)&__ss; 212 int sa_size; 213 214 memset(d, 0, sizeof(*d)); |
215 d->sa = (struct sockaddr *)&d->__ss; |
216 d->s = -1; 217 218 ret = krb5_addr2sockaddr (a, sa, &sa_size, port); 219 if (ret) { 220 krb5_warn(context, ret, "krb5_addr2sockaddr"); 221 close(d->s); 222 d->s = -1; 223 return; --- 151 unchanged lines hidden (view full) --- 375 if(krb5_print_address(&a, str, len, &len) == 0) { 376 krb5_free_address(context, &a); 377 return; 378 } 379 krb5_free_address(context, &a); 380 snprintf(str, len, "<family=%d>", addr->sa_family); 381} 382 |
383/* 384 * Handle the request in `buf, len' to socket `d' 385 */ 386 |
387static void 388do_request(void *buf, size_t len, int sendlength, |
389 struct descr *d) |
390{ 391 krb5_error_code ret; 392 krb5_data reply; |
393 |
394 reply.length = 0; |
395 ret = process_request(buf, len, &reply, &sendlength, 396 d->addr_string, d->sa); |
397 if(reply.length){ |
398 kdc_log(5, "sending %d bytes to %s", reply.length, d->addr_string); |
399 if(sendlength){ 400 unsigned char len[4]; 401 len[0] = (reply.length >> 24) & 0xff; 402 len[1] = (reply.length >> 16) & 0xff; 403 len[2] = (reply.length >> 8) & 0xff; 404 len[3] = reply.length & 0xff; |
405 if(sendto(d->s, len, sizeof(len), 0, d->sa, d->sock_len) < 0) { 406 kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno)); |
407 krb5_data_free(&reply); 408 return; 409 } 410 } |
411 if(sendto(d->s, reply.data, reply.length, 0, d->sa, d->sock_len) < 0) { 412 kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno)); |
413 krb5_data_free(&reply); 414 return; 415 } 416 krb5_data_free(&reply); 417 } 418 if(ret) 419 kdc_log(0, "Failed processing %lu byte request from %s", |
420 (unsigned long)len, d->addr_string); |
421} 422 |
423/* 424 * Handle incoming data to the UDP socket in `d' 425 */ 426 |
427static void 428handle_udp(struct descr *d) 429{ 430 unsigned char *buf; |
431 int n; 432 433 buf = malloc(max_request); 434 if(buf == NULL){ 435 kdc_log(0, "Failed to allocate %u bytes", max_request); 436 return; 437 } 438 |
439 d->sock_len = sizeof(d->__ss); 440 n = recvfrom(d->s, buf, max_request, 0, d->sa, &d->sock_len); 441 if(n < 0) |
442 krb5_warn(context, errno, "recvfrom"); |
443 else { 444 addr_to_string (d->sa, d->sock_len, 445 d->addr_string, sizeof(d->addr_string)); 446 do_request(buf, n, 0, d); |
447 } |
448 free (buf); 449} 450 451static void 452clear_descr(struct descr *d) 453{ 454 if(d->buf) 455 memset(d->buf, 0, d->size); --- 27 unchanged lines hidden (view full) --- 483 484/* 485 * accept a new TCP connection on `d[index]' 486 */ 487 488static void 489add_new_tcp (struct descr *d, int index, int min_free) 490{ |
491 int s; |
492 |
493 d->sock_len = sizeof(d->__ss); 494 s = accept(d[index].s, d->sa, &d->sock_len); 495 if(s < 0) { |
496 krb5_warn(context, errno, "accept"); 497 return; 498 } 499 if(min_free == -1){ 500 close(s); 501 return; 502 } 503 504 d[min_free].s = s; 505 d[min_free].timeout = time(NULL) + TCP_TIMEOUT; 506 d[min_free].type = SOCK_STREAM; |
507 addr_to_string (d[min_free].sa, d[min_free].sock_len, 508 d[min_free].addr_string, sizeof(d[min_free].addr_string)); |
509} 510 511/* 512 * Grow `d' to handle at least `n'. 513 * Return != 0 if fails 514 */ 515 516static int --- 46 unchanged lines hidden (view full) --- 563} 564 565/* 566 * Try to handle the TCP/HTTP data at `d->buf, d->len'. 567 * Return -1 if failed, 0 if succesful, and 1 if data is complete. 568 */ 569 570static int |
571handle_http_tcp (struct descr *d) |
572{ 573 char *s, *p, *t; 574 void *data; 575 char *proto; 576 int len; 577 578 s = (char *)d->buf; 579 580 p = strstr(s, "\r\n"); 581 if (p == NULL) { |
582 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
583 return -1; 584 } 585 *p = 0; 586 587 p = NULL; 588 t = strtok_r(s, " \t", &p); 589 if (t == NULL) { |
590 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
591 return -1; 592 } 593 t = strtok_r(NULL, " \t", &p); 594 if(t == NULL) { |
595 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
596 return -1; 597 } 598 data = malloc(strlen(t)); 599 if (data == NULL) { 600 kdc_log(0, "Failed to allocate %u bytes", strlen(t)); 601 return -1; 602 } 603 if(*t == '/') 604 t++; 605 if(de_http(t) != 0) { |
606 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
607 kdc_log(5, "Request: %s", t); 608 free(data); 609 return -1; 610 } 611 proto = strtok_r(NULL, " \t", &p); 612 if (proto == NULL) { |
613 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
614 free(data); 615 return -1; 616 } 617 len = base64_decode(t, data); 618 if(len <= 0){ 619 const char *msg = 620 " 404 Not found\r\n" 621 "Server: Heimdal/" VERSION "\r\n" 622 "Content-type: text/html\r\n" 623 "Content-transfer-encoding: 8bit\r\n\r\n" 624 "<TITLE>404 Not found</TITLE>\r\n" 625 "<H1>404 Not found</H1>\r\n" 626 "That page doesn't exist, maybe you are looking for " 627 "<A HREF=\"http://www.pdc.kth.se/heimdal\">Heimdal</A>?\r\n"; 628 write(d->s, proto, strlen(proto)); 629 write(d->s, msg, strlen(msg)); |
630 kdc_log(0, "HTTP request from %s is non KDC request", d->addr_string); |
631 kdc_log(5, "Request: %s", t); 632 free(data); 633 return -1; 634 } 635 { 636 const char *msg = 637 " 200 OK\r\n" 638 "Server: Heimdal/" VERSION "\r\n" --- 11 unchanged lines hidden (view full) --- 650/* 651 * Handle incoming data to the TCP socket in `d[index]' 652 */ 653 654static void 655handle_tcp(struct descr *d, int index, int min_free) 656{ 657 unsigned char buf[1024]; |
658 int n; 659 int ret = 0; 660 661 if (d[index].timeout == 0) { 662 add_new_tcp (d, index, min_free); 663 return; 664 } 665 |
666 n = recvfrom(d[index].s, buf, sizeof(buf), 0, NULL, NULL); 667 if(n < 0){ 668 krb5_warn(context, errno, "recvfrom"); 669 return; 670 } |
671 if (grow_descr (&d[index], n)) 672 return; 673 memcpy(d[index].buf + d[index].len, buf, n); 674 d[index].len += n; 675 if(d[index].len > 4 && d[index].buf[0] == 0) { 676 ret = handle_vanilla_tcp (&d[index]); 677 } else if(enable_http && 678 d[index].len >= 4 && 679 strncmp((char *)d[index].buf, "GET ", 4) == 0 && 680 strncmp((char *)d[index].buf + d[index].len - 4, 681 "\r\n\r\n", 4) == 0) { |
682 ret = handle_http_tcp (&d[index]); |
683 if (ret < 0) 684 clear_descr (d + index); 685 } else if (d[index].len > 4) { |
686 kdc_log (0, "TCP data of strange type from %s", d[index].addr_string); |
687 return; 688 } 689 if (ret < 0) 690 return; 691 else if (ret == 1) { |
692 do_request(d[index].buf, d[index].len, 1, &d[index]); |
693 clear_descr(d + index); 694 } 695} 696 697void 698loop(void) 699{ 700 struct descr *d; --- 7 unchanged lines hidden (view full) --- 708 fd_set fds; 709 int min_free = -1; 710 int max_fd = 0; 711 int i; 712 FD_ZERO(&fds); 713 for(i = 0; i < ndescr; i++){ 714 if(d[i].s >= 0){ 715 if(d[i].type == SOCK_STREAM && |
716 d[i].timeout && d[i].timeout < time(NULL)) { |
717 kdc_log(1, "TCP-connection from %s expired after %u bytes", |
718 d[i].addr_string, d[i].len); |
719 clear_descr(&d[i]); 720 continue; 721 } 722 if(max_fd < d[i].s) 723 max_fd = d[i].s; 724 FD_SET(d[i].s, &fds); 725 }else if(min_free < 0 || i < min_free) 726 min_free = i; --- 37 unchanged lines hidden --- |