Deleted Added
sdiff udiff text old ( 57419 ) new ( 57422 )
full compact
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 $");
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};
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));
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
378static void
379do_request(void *buf, size_t len, int sendlength,
380 int socket, struct sockaddr *from, size_t from_len)
381{
382 krb5_error_code ret;
383 krb5_data reply;
384 char addr[128];
385
386 addr_to_string(from, from_len, addr, sizeof(addr));
387
388 reply.length = 0;
389 ret = process_request(buf, len, &reply, &sendlength, addr, from);
390 if(reply.length){
391 kdc_log(5, "sending %d bytes to %s", reply.length, addr);
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;
398 if(sendto(socket, len, sizeof(len), 0, from, from_len) < 0) {
399 kdc_log (0, "sendto(%s): %s", addr, strerror(errno));
400 krb5_data_free(&reply);
401 return;
402 }
403 }
404 if(sendto(socket, reply.data, reply.length, 0, from, from_len) < 0) {
405 kdc_log (0, "sendto(%s): %s", addr, 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 (unsigned long)len, addr);
414}
415
416static void
417handle_udp(struct descr *d)
418{
419 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 from_len = sizeof(__ss);
432 n = recvfrom(d->s, buf, max_request, 0,
433 sa, &from_len);
434 if(n < 0){
435 krb5_warn(context, errno, "recvfrom");
436 goto out;
437 }
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{
486 struct sockaddr_storage __ss;
487 struct sockaddr *sa = (struct sockaddr *)&__ss;
488 int s;
489 int from_len;
490
491 from_len = sizeof(__ss);
492 s = accept(d[index].s, sa, &from_len);
493 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;
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
567handle_http_tcp (struct descr *d, const char *addr)
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) {
578 kdc_log(0, "Malformed HTTP request from %s", addr);
579 return -1;
580 }
581 *p = 0;
582
583 p = NULL;
584 t = strtok_r(s, " \t", &p);
585 if (t == NULL) {
586 kdc_log(0, "Malformed HTTP request from %s", addr);
587 return -1;
588 }
589 t = strtok_r(NULL, " \t", &p);
590 if(t == NULL) {
591 kdc_log(0, "Malformed HTTP request from %s", addr);
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) {
602 kdc_log(0, "Malformed HTTP request from %s", addr);
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) {
609 kdc_log(0, "Malformed HTTP request from %s", addr);
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));
626 kdc_log(0, "HTTP request from %s is non KDC request", addr);
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];
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
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 }
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) {
693 ret = handle_http_tcp (&d[index], addr);
694 if (ret < 0)
695 clear_descr (d + index);
696 } else if (d[index].len > 4) {
697 kdc_log (0, "TCP data of strange type from %s", addr);
698 return;
699 }
700 if (ret < 0)
701 return;
702 else if (ret == 1) {
703 do_request(d[index].buf, d[index].len, 1,
704 d[index].s, sa, from_len);
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 &&
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));
735 kdc_log(1, "TCP-connection from %s expired after %u bytes",
736 addr, 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 ---