connect.c (57419) | connect.c (57422) |
---|---|
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 | 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.69 2000/02/11 17:45:45 assar Exp $"); | 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; | 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]; |
|
196}; 197 198/* 199 * Create the socket (family, type, port) in `d' 200 */ 201 202static void 203init_socket(struct descr *d, krb5_address *a, int family, int type, int port) 204{ 205 krb5_error_code ret; 206 struct sockaddr_storage __ss; 207 struct sockaddr *sa = (struct sockaddr *)&__ss; 208 int sa_size; 209 210 memset(d, 0, sizeof(*d)); | 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; |
|
211 d->s = -1; 212 213 ret = krb5_addr2sockaddr (a, sa, &sa_size, port); 214 if (ret) { 215 krb5_warn(context, ret, "krb5_addr2sockaddr"); 216 close(d->s); 217 d->s = -1; 218 return; --- 151 unchanged lines hidden (view full) --- 370 if(krb5_print_address(&a, str, len, &len) == 0) { 371 krb5_free_address(context, &a); 372 return; 373 } 374 krb5_free_address(context, &a); 375 snprintf(str, len, "<family=%d>", addr->sa_family); 376} 377 | 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 |
|
378static void 379do_request(void *buf, size_t len, int sendlength, | 387static void 388do_request(void *buf, size_t len, int sendlength, |
380 int socket, struct sockaddr *from, size_t from_len) | 389 struct descr *d) |
381{ 382 krb5_error_code ret; 383 krb5_data reply; | 390{ 391 krb5_error_code ret; 392 krb5_data reply; |
384 char addr[128]; | |
385 | 393 |
386 addr_to_string(from, from_len, addr, sizeof(addr)); 387 | |
388 reply.length = 0; | 394 reply.length = 0; |
389 ret = process_request(buf, len, &reply, &sendlength, addr, from); | 395 ret = process_request(buf, len, &reply, &sendlength, 396 d->addr_string, d->sa); |
390 if(reply.length){ | 397 if(reply.length){ |
391 kdc_log(5, "sending %d bytes to %s", reply.length, addr); | 398 kdc_log(5, "sending %d bytes to %s", reply.length, d->addr_string); |
392 if(sendlength){ 393 unsigned char len[4]; 394 len[0] = (reply.length >> 24) & 0xff; 395 len[1] = (reply.length >> 16) & 0xff; 396 len[2] = (reply.length >> 8) & 0xff; 397 len[3] = reply.length & 0xff; | 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; |
398 if(sendto(socket, len, sizeof(len), 0, from, from_len) < 0) { 399 kdc_log (0, "sendto(%s): %s", addr, strerror(errno)); | 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)); |
400 krb5_data_free(&reply); 401 return; 402 } 403 } | 407 krb5_data_free(&reply); 408 return; 409 } 410 } |
404 if(sendto(socket, reply.data, reply.length, 0, from, from_len) < 0) { 405 kdc_log (0, "sendto(%s): %s", addr, strerror(errno)); | 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)); |
406 krb5_data_free(&reply); 407 return; 408 } 409 krb5_data_free(&reply); 410 } 411 if(ret) 412 kdc_log(0, "Failed processing %lu byte request from %s", | 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", |
413 (unsigned long)len, addr); | 420 (unsigned long)len, d->addr_string); |
414} 415 | 421} 422 |
423/* 424 * Handle incoming data to the UDP socket in `d' 425 */ 426 |
|
416static void 417handle_udp(struct descr *d) 418{ 419 unsigned char *buf; | 427static void 428handle_udp(struct descr *d) 429{ 430 unsigned char *buf; |
420 struct sockaddr_storage __ss; 421 struct sockaddr *sa = (struct sockaddr *)&__ss; 422 int from_len; | |
423 int n; 424 425 buf = malloc(max_request); 426 if(buf == NULL){ 427 kdc_log(0, "Failed to allocate %u bytes", max_request); 428 return; 429 } 430 | 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 |
431 from_len = sizeof(__ss); 432 n = recvfrom(d->s, buf, max_request, 0, 433 sa, &from_len); 434 if(n < 0){ | 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) |
435 krb5_warn(context, errno, "recvfrom"); | 442 krb5_warn(context, errno, "recvfrom"); |
436 goto out; | 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); |
437 } | 447 } |
438 if(n == 0) { 439 goto out; 440 } 441 do_request(buf, n, 0, d->s, sa, from_len); 442out: | |
443 free (buf); 444} 445 446static void 447clear_descr(struct descr *d) 448{ 449 if(d->buf) 450 memset(d->buf, 0, d->size); --- 27 unchanged lines hidden (view full) --- 478 479/* 480 * accept a new TCP connection on `d[index]' 481 */ 482 483static void 484add_new_tcp (struct descr *d, int index, int min_free) 485{ | 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{ |
486 struct sockaddr_storage __ss; 487 struct sockaddr *sa = (struct sockaddr *)&__ss; | |
488 int s; | 491 int s; |
489 int from_len; | |
490 | 492 |
491 from_len = sizeof(__ss); 492 s = accept(d[index].s, sa, &from_len); 493 if(s < 0){ | 493 d->sock_len = sizeof(d->__ss); 494 s = accept(d[index].s, d->sa, &d->sock_len); 495 if(s < 0) { |
494 krb5_warn(context, errno, "accept"); 495 return; 496 } 497 if(min_free == -1){ 498 close(s); 499 return; 500 } 501 502 d[min_free].s = s; 503 d[min_free].timeout = time(NULL) + TCP_TIMEOUT; 504 d[min_free].type = SOCK_STREAM; | 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)); |
|
505} 506 507/* 508 * Grow `d' to handle at least `n'. 509 * Return != 0 if fails 510 */ 511 512static int --- 46 unchanged lines hidden (view full) --- 559} 560 561/* 562 * Try to handle the TCP/HTTP data at `d->buf, d->len'. 563 * Return -1 if failed, 0 if succesful, and 1 if data is complete. 564 */ 565 566static int | 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 |
567handle_http_tcp (struct descr *d, const char *addr) | 571handle_http_tcp (struct descr *d) |
568{ 569 char *s, *p, *t; 570 void *data; 571 char *proto; 572 int len; 573 574 s = (char *)d->buf; 575 576 p = strstr(s, "\r\n"); 577 if (p == NULL) { | 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) { |
578 kdc_log(0, "Malformed HTTP request from %s", addr); | 582 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
579 return -1; 580 } 581 *p = 0; 582 583 p = NULL; 584 t = strtok_r(s, " \t", &p); 585 if (t == NULL) { | 583 return -1; 584 } 585 *p = 0; 586 587 p = NULL; 588 t = strtok_r(s, " \t", &p); 589 if (t == NULL) { |
586 kdc_log(0, "Malformed HTTP request from %s", addr); | 590 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
587 return -1; 588 } 589 t = strtok_r(NULL, " \t", &p); 590 if(t == NULL) { | 591 return -1; 592 } 593 t = strtok_r(NULL, " \t", &p); 594 if(t == NULL) { |
591 kdc_log(0, "Malformed HTTP request from %s", addr); | 595 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
592 return -1; 593 } 594 data = malloc(strlen(t)); 595 if (data == NULL) { 596 kdc_log(0, "Failed to allocate %u bytes", strlen(t)); 597 return -1; 598 } 599 if(*t == '/') 600 t++; 601 if(de_http(t) != 0) { | 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) { |
602 kdc_log(0, "Malformed HTTP request from %s", addr); | 606 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
603 kdc_log(5, "Request: %s", t); 604 free(data); 605 return -1; 606 } 607 proto = strtok_r(NULL, " \t", &p); 608 if (proto == NULL) { | 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) { |
609 kdc_log(0, "Malformed HTTP request from %s", addr); | 613 kdc_log(0, "Malformed HTTP request from %s", d->addr_string); |
610 free(data); 611 return -1; 612 } 613 len = base64_decode(t, data); 614 if(len <= 0){ 615 const char *msg = 616 " 404 Not found\r\n" 617 "Server: Heimdal/" VERSION "\r\n" 618 "Content-type: text/html\r\n" 619 "Content-transfer-encoding: 8bit\r\n\r\n" 620 "<TITLE>404 Not found</TITLE>\r\n" 621 "<H1>404 Not found</H1>\r\n" 622 "That page doesn't exist, maybe you are looking for " 623 "<A HREF=\"http://www.pdc.kth.se/heimdal\">Heimdal</A>?\r\n"; 624 write(d->s, proto, strlen(proto)); 625 write(d->s, msg, strlen(msg)); | 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)); |
626 kdc_log(0, "HTTP request from %s is non KDC request", addr); | 630 kdc_log(0, "HTTP request from %s is non KDC request", d->addr_string); |
627 kdc_log(5, "Request: %s", t); 628 free(data); 629 return -1; 630 } 631 { 632 const char *msg = 633 " 200 OK\r\n" 634 "Server: Heimdal/" VERSION "\r\n" --- 11 unchanged lines hidden (view full) --- 646/* 647 * Handle incoming data to the TCP socket in `d[index]' 648 */ 649 650static void 651handle_tcp(struct descr *d, int index, int min_free) 652{ 653 unsigned char buf[1024]; | 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]; |
654 char addr[32]; 655 struct sockaddr_storage __ss; 656 struct sockaddr *sa = (struct sockaddr *)&__ss; 657 int from_len; | |
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 | 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 /* 667 * We can't trust recvfrom to return an address so we always call 668 * getpeername. 669 */ 670 | |
671 n = recvfrom(d[index].s, buf, sizeof(buf), 0, NULL, NULL); 672 if(n < 0){ 673 krb5_warn(context, errno, "recvfrom"); 674 return; 675 } | 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 } |
676 from_len = sizeof(__ss); 677 if (getpeername(d[index].s, sa, &from_len) < 0) { 678 krb5_warn(context, errno, "getpeername"); 679 return; 680 } 681 addr_to_string(sa, from_len, addr, sizeof(addr)); | |
682 if (grow_descr (&d[index], n)) 683 return; 684 memcpy(d[index].buf + d[index].len, buf, n); 685 d[index].len += n; 686 if(d[index].len > 4 && d[index].buf[0] == 0) { 687 ret = handle_vanilla_tcp (&d[index]); 688 } else if(enable_http && 689 d[index].len >= 4 && 690 strncmp((char *)d[index].buf, "GET ", 4) == 0 && 691 strncmp((char *)d[index].buf + d[index].len - 4, 692 "\r\n\r\n", 4) == 0) { | 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) { |
693 ret = handle_http_tcp (&d[index], addr); | 682 ret = handle_http_tcp (&d[index]); |
694 if (ret < 0) 695 clear_descr (d + index); 696 } else if (d[index].len > 4) { | 683 if (ret < 0) 684 clear_descr (d + index); 685 } else if (d[index].len > 4) { |
697 kdc_log (0, "TCP data of strange type from %s", addr); | 686 kdc_log (0, "TCP data of strange type from %s", d[index].addr_string); |
698 return; 699 } 700 if (ret < 0) 701 return; 702 else if (ret == 1) { | 687 return; 688 } 689 if (ret < 0) 690 return; 691 else if (ret == 1) { |
703 do_request(d[index].buf, d[index].len, 1, 704 d[index].s, sa, from_len); | 692 do_request(d[index].buf, d[index].len, 1, &d[index]); |
705 clear_descr(d + index); 706 } 707} 708 709void 710loop(void) 711{ 712 struct descr *d; --- 7 unchanged lines hidden (view full) --- 720 fd_set fds; 721 int min_free = -1; 722 int max_fd = 0; 723 int i; 724 FD_ZERO(&fds); 725 for(i = 0; i < ndescr; i++){ 726 if(d[i].s >= 0){ 727 if(d[i].type == SOCK_STREAM && | 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 && |
728 d[i].timeout && d[i].timeout < time(NULL)){ 729 struct sockaddr sa; 730 int salen = sizeof(sa); 731 char addr[32]; 732 733 getpeername(d[i].s, &sa, &salen); 734 addr_to_string(&sa, salen, addr, sizeof(addr)); | 716 d[i].timeout && d[i].timeout < time(NULL)) { |
735 kdc_log(1, "TCP-connection from %s expired after %u bytes", | 717 kdc_log(1, "TCP-connection from %s expired after %u bytes", |
736 addr, d[i].len); | 718 d[i].addr_string, d[i].len); |
737 clear_descr(&d[i]); 738 continue; 739 } 740 if(max_fd < d[i].s) 741 max_fd = d[i].s; 742 FD_SET(d[i].s, &fds); 743 }else if(min_free < 0 || i < min_free) 744 min_free = i; --- 37 unchanged lines hidden --- | 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 --- |