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 ---
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 ---