Add http support.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3184 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		| @@ -261,6 +261,53 @@ handle_tcp(struct descr *d, int index, int min_free) | |||||||
| 	    n = 0; | 	    n = 0; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  | #ifdef HTTP | ||||||
|  |     else if(strncmp(d[index].buf, "GET ", 4) == 0 &&  | ||||||
|  | 	    strncmp(d[index].buf + d[index].len - 4, "\r\n\r\n", 4) == 0){ | ||||||
|  | 	char *s, *p, *t; | ||||||
|  | 	void *data; | ||||||
|  | 	int len; | ||||||
|  | 	s = d[index].buf; | ||||||
|  | 	p = strstr(s, "\r\n"); | ||||||
|  | 	*p = 0; | ||||||
|  | 	p = NULL; | ||||||
|  | 	kdc_log(5, "HTTP request"); | ||||||
|  | 	strtok_r(s, " \t", &p); | ||||||
|  | 	t = strtok_r(NULL, " \t", &p); | ||||||
|  | 	if(t == NULL){ | ||||||
|  | 	     | ||||||
|  | 	} | ||||||
|  | 	data = malloc(strlen(t)); | ||||||
|  | 	len = base64_decode(t, data); | ||||||
|  | 	if(len < 0){ | ||||||
|  | 	    const char *msg =  | ||||||
|  | 		"HTTP/1.1 404 Not found\r\n" | ||||||
|  | 		"Server: Heimdal/" VERSION "\r\n" | ||||||
|  | 		"Content-type: text/html\r\n" | ||||||
|  | 		"Content-transfer-encoding: 8bit\r\n\r\n" | ||||||
|  | 		"<TITLE>404 Not found</TITLE>\r\n" | ||||||
|  | 		"<H1>404 Not found</H1>\r\n" | ||||||
|  | 		"That page doesn't exist, maybe you are looking for " | ||||||
|  | 		"<a href=\"http://www.pdc.kth.se/heimdal\">Heimdal</a>?\r\n"; | ||||||
|  | 	    write(d[index].s, msg, strlen(msg)); | ||||||
|  | 	    free(data); | ||||||
|  | 	    clear_descr(d + index); | ||||||
|  | 	    return; | ||||||
|  | 	} | ||||||
|  | 	{ | ||||||
|  | 	    const char *msg =  | ||||||
|  | 		"HTTP/1.1 200 OK\r\n" | ||||||
|  | 		"Server: Heimdal/" VERSION "\r\n" | ||||||
|  | 		"Content-type: application/octet-stream\r\n" | ||||||
|  | 		"Content-transfer-encoding: binary\r\n\r\n"; | ||||||
|  | 	    write(d[index].s, msg, strlen(msg)); | ||||||
|  | 	} | ||||||
|  | 	memcpy(d[index].buf, data, len); | ||||||
|  | 	d[index].len = len; | ||||||
|  | 	n = 0; | ||||||
|  | 	free(data); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|     if(n == 0){ |     if(n == 0){ | ||||||
| 	do_request(d[index].buf, d[index].len,  | 	do_request(d[index].buf, d[index].len,  | ||||||
| 		   d[index].s, (struct sockaddr*)&from, from_len); | 		   d[index].s, (struct sockaddr*)&from, from_len); | ||||||
|   | |||||||
| @@ -55,6 +55,9 @@ send_and_recv (int fd, | |||||||
|      if (sendto (fd, send->data, send->length, 0, |      if (sendto (fd, send->data, send->length, 0, | ||||||
| 		 (struct sockaddr *)addr, sizeof(*addr)) < 0) | 		 (struct sockaddr *)addr, sizeof(*addr)) < 0) | ||||||
| 	  return -1; | 	  return -1; | ||||||
|  |      recv->data = NULL; | ||||||
|  |      recv->length = 0; | ||||||
|  |      while(1){ | ||||||
| 	 FD_ZERO(&fdset); | 	 FD_ZERO(&fdset); | ||||||
| 	 FD_SET(fd, &fdset); | 	 FD_SET(fd, &fdset); | ||||||
| 	 timeout.tv_sec  = tmout; | 	 timeout.tv_sec  = tmout; | ||||||
| @@ -67,17 +70,56 @@ send_and_recv (int fd, | |||||||
|  |  | ||||||
| 	     if (ioctl (fd, FIONREAD, &nbytes) < 0) | 	     if (ioctl (fd, FIONREAD, &nbytes) < 0) | ||||||
| 		 return -1; | 		 return -1; | ||||||
|  | 	     if(nbytes == 0) | ||||||
|  | 		 return 0; | ||||||
|  |  | ||||||
| 	  recv->data = malloc (nbytes); | 	     recv->data = realloc(recv->data, recv->length + nbytes); | ||||||
| 	  ret = recvfrom (fd, recv->data, nbytes, 0, NULL, &len); | 	     ret = recvfrom (fd, recv->data + recv->length, nbytes,  | ||||||
|  | 			     0, NULL, &len); | ||||||
| 	     if (ret < 0) { | 	     if (ret < 0) { | ||||||
| 		 free (recv->data); | 		 free (recv->data); | ||||||
| 		 return -1; | 		 return -1; | ||||||
| 	     } | 	     } | ||||||
| 	  recv->data = realloc (recv->data, ret); | 	     recv->length += ret; | ||||||
| 	  recv->length  = ret; |  | ||||||
| 	  return 0; |  | ||||||
| 	 } | 	 } | ||||||
|  |      } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | send_and_recv_http(int fd,  | ||||||
|  | 		   time_t tmout, | ||||||
|  | 		   struct sockaddr_in *addr, | ||||||
|  | 		   const krb5_data *send, | ||||||
|  | 		   krb5_data *recv) | ||||||
|  | { | ||||||
|  |     char *request; | ||||||
|  |     char *str; | ||||||
|  |     krb5_data r; | ||||||
|  |     int ret; | ||||||
|  |     int len = base64_encode(send->data, send->length, &str); | ||||||
|  |     if(len < 0) | ||||||
|  | 	return -1; | ||||||
|  |     asprintf(&request, "GET %s HTTP/1.1\r\n\r\n", str); | ||||||
|  |     free(str); | ||||||
|  |     r.data = request; | ||||||
|  |     r.length = strlen(request); | ||||||
|  |     ret = send_and_recv(fd, tmout, addr, &r, recv); | ||||||
|  |     free(request); | ||||||
|  |     if(ret) | ||||||
|  | 	return ret; | ||||||
|  |     { | ||||||
|  | 	char *s, *p; | ||||||
|  | 	s = realloc(recv->data, recv->length + 1); | ||||||
|  | 	s[recv->length] = 0; | ||||||
|  | 	p = strstr(s, "\r\n\r\n"); | ||||||
|  | 	if(p == NULL) | ||||||
|  | 	    return -1; | ||||||
|  | 	p += 4; | ||||||
|  | 	recv->data = s; | ||||||
|  | 	recv->length -= p - s; | ||||||
|  | 	memmove(recv->data, p, recv->length); | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| krb5_error_code | krb5_error_code | ||||||
| @@ -94,10 +136,6 @@ krb5_sendto_kdc (krb5_context context, | |||||||
|      int i; |      int i; | ||||||
|  |  | ||||||
|      port = krb5_getportbyname ("kerberos", "udp", htons(88)); |      port = krb5_getportbyname ("kerberos", "udp", htons(88)); | ||||||
|      fd = socket (AF_INET, SOCK_DGRAM, 0); |  | ||||||
|      if (fd < 0) { |  | ||||||
| 	  return errno; |  | ||||||
|      } |  | ||||||
|  |  | ||||||
|      err = krb5_get_krbhst (context, realm, &hostlist); |      err = krb5_get_krbhst (context, realm, &hostlist); | ||||||
|      if (err) { |      if (err) { | ||||||
| @@ -109,7 +147,12 @@ krb5_sendto_kdc (krb5_context context, | |||||||
| 	 for (hp = hostlist; (p = *hp); ++hp) { | 	 for (hp = hostlist; (p = *hp); ++hp) { | ||||||
| 	       char *addr; | 	       char *addr; | ||||||
| 	       char *colon; | 	       char *colon; | ||||||
|  | 	       int http_flag = 0; | ||||||
|  |  | ||||||
|  | 	       if(strncmp(p, "http://", 7) == 0){ | ||||||
|  | 		   p += 7; | ||||||
|  | 		   http_flag = 1; | ||||||
|  | 	       } | ||||||
| 	       colon = strchr (p, ':'); | 	       colon = strchr (p, ':'); | ||||||
| 	       if (colon) | 	       if (colon) | ||||||
| 		    *colon = '\0'; | 		    *colon = '\0'; | ||||||
| @@ -120,7 +163,16 @@ krb5_sendto_kdc (krb5_context context, | |||||||
| 		    *colon++ = ':'; | 		    *colon++ = ':'; | ||||||
| 	       while ((addr = *hostent->h_addr_list++)) { | 	       while ((addr = *hostent->h_addr_list++)) { | ||||||
| 		    struct sockaddr_in a; | 		    struct sockaddr_in a; | ||||||
|  | 		    int ret; | ||||||
| 		     | 		     | ||||||
|  | 		    if(http_flag) | ||||||
|  | 			fd = socket(AF_INET, SOCK_STREAM, 0); | ||||||
|  | 		    else | ||||||
|  | 			fd = socket(AF_INET, SOCK_DGRAM, 0); | ||||||
|  | 		     | ||||||
|  | 		    if(fd < 0){ | ||||||
|  | 			return errno; | ||||||
|  | 		    } | ||||||
| 		    memset (&a, 0, sizeof(a)); | 		    memset (&a, 0, sizeof(a)); | ||||||
| 		    a.sin_family = AF_INET; | 		    a.sin_family = AF_INET; | ||||||
| 		    if (colon) { | 		    if (colon) { | ||||||
| @@ -131,16 +183,22 @@ krb5_sendto_kdc (krb5_context context, | |||||||
| 		    } else | 		    } else | ||||||
| 			 a.sin_port   = port; | 			 a.sin_port   = port; | ||||||
| 		    a.sin_addr   = *((struct in_addr *)addr); | 		    a.sin_addr   = *((struct in_addr *)addr); | ||||||
|  | 		    connect(fd, (struct sockaddr*)&a, sizeof(a)); | ||||||
| 		     | 		     | ||||||
| 		    if (send_and_recv (fd, context->kdc_timeout,  | 		    if(http_flag) | ||||||
| 				       &a, send, receive) == 0) { | 			ret = send_and_recv_http(fd, context->kdc_timeout, | ||||||
|  | 						 &a, send, receive); | ||||||
|  | 		    else | ||||||
|  | 			 | ||||||
|  | 			ret = send_and_recv (fd, context->kdc_timeout,  | ||||||
|  | 					     &a, send, receive); | ||||||
| 		    close (fd); | 		    close (fd); | ||||||
|  | 		    if(ret == 0){ | ||||||
| 			krb5_free_krbhst (context, hostlist); | 			krb5_free_krbhst (context, hostlist); | ||||||
| 			return 0; | 			return 0; | ||||||
| 		    } | 		    } | ||||||
| 	       } | 	       } | ||||||
| 	 } | 	 } | ||||||
|      close (fd); |  | ||||||
|      krb5_free_krbhst (context, hostlist); |      krb5_free_krbhst (context, hostlist); | ||||||
|      return KRB5_KDC_UNREACH; |      return KRB5_KDC_UNREACH; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Johan Danielsson
					Johan Danielsson