Deleted Added
full compact
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 ---