summaryrefslogtreecommitdiff
path: root/crypto/heimdal/lib/krb5/send_to_kdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/krb5/send_to_kdc.c')
-rw-r--r--crypto/heimdal/lib/krb5/send_to_kdc.c395
1 files changed, 0 insertions, 395 deletions
diff --git a/crypto/heimdal/lib/krb5/send_to_kdc.c b/crypto/heimdal/lib/krb5/send_to_kdc.c
deleted file mode 100644
index 2872322bafc8a..0000000000000
--- a/crypto/heimdal/lib/krb5/send_to_kdc.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "krb5_locl.h"
-
-RCSID("$Id: send_to_kdc.c,v 1.36 2000/01/06 07:59:11 assar Exp $");
-
-/*
- * send the data in `req' on the socket `fd' (which is datagram iff udp)
- * waiting `tmout' for a reply and returning the reply in `rep'.
- * iff limit read up to this many bytes
- * returns 0 and data in `rep' if succesful, otherwise -1
- */
-
-static int
-recv_loop (int fd,
- time_t tmout,
- int udp,
- size_t limit,
- krb5_data *rep)
-{
- fd_set fdset;
- struct timeval timeout;
- int ret;
- int nbytes;
-
- krb5_data_zero(rep);
- do {
- FD_ZERO(&fdset);
- FD_SET(fd, &fdset);
- timeout.tv_sec = tmout;
- timeout.tv_usec = 0;
- ret = select (fd + 1, &fdset, NULL, NULL, &timeout);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- return -1;
- } else if (ret == 0) {
- return 0;
- } else {
- void *tmp;
-
- if (ioctl (fd, FIONREAD, &nbytes) < 0) {
- krb5_data_free (rep);
- return -1;
- }
- if(nbytes == 0)
- return 0;
-
- if (limit)
- nbytes = min(nbytes, limit - rep->length);
-
- tmp = realloc (rep->data, rep->length + nbytes);
- if (tmp == NULL) {
- krb5_data_free (rep);
- return -1;
- }
- rep->data = tmp;
- ret = recv (fd, (char*)tmp + rep->length, nbytes, 0);
- if (ret < 0) {
- krb5_data_free (rep);
- return -1;
- }
- rep->length += ret;
- }
- } while(!udp && (limit == 0 || rep->length < limit));
- return 0;
-}
-
-/*
- * Send kerberos requests and receive a reply on a udp or any other kind
- * of a datagram socket. See `recv_loop'.
- */
-
-static int
-send_and_recv_udp(int fd,
- time_t tmout,
- const krb5_data *req,
- krb5_data *rep)
-{
- if (send (fd, req->data, req->length, 0) < 0)
- return -1;
-
- return recv_loop(fd, tmout, 1, 0, rep);
-}
-
-/*
- * `send_and_recv' for a TCP (or any other stream) socket.
- * Since there are no record limits on a stream socket the protocol here
- * is to prepend the request with 4 bytes of its length and the reply
- * is similarly encoded.
- */
-
-static int
-send_and_recv_tcp(int fd,
- time_t tmout,
- const krb5_data *req,
- krb5_data *rep)
-{
- unsigned char len[4];
- unsigned long rep_len;
- krb5_data len_data;
-
- _krb5_put_int(len, req->length, 4);
- if(net_write(fd, len, sizeof(len)) < 0)
- return -1;
- if(net_write(fd, req->data, req->length) < 0)
- return -1;
- if (recv_loop (fd, tmout, 0, 4, &len_data) < 0)
- return -1;
- if (len_data.length != 4) {
- krb5_data_free (&len_data);
- return -1;
- }
- _krb5_get_int(len_data.data, &rep_len, 4);
- krb5_data_free (&len_data);
- if (recv_loop (fd, tmout, 0, rep_len, rep) < 0)
- return -1;
- if(rep->length != rep_len) {
- krb5_data_free (rep);
- return -1;
- }
- return 0;
-}
-
-/*
- * `send_and_recv' tailored for the HTTP protocol.
- */
-
-static int
-send_and_recv_http(int fd,
- time_t tmout,
- const char *prefix,
- const krb5_data *req,
- krb5_data *rep)
-{
- char *request;
- char *str;
- int ret;
- int len = base64_encode(req->data, req->length, &str);
-
- if(len < 0)
- return -1;
- asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str);
- free(str);
- if (request == NULL)
- return -1;
- ret = net_write (fd, request, strlen(request));
- free (request);
- if (ret < 0)
- return ret;
- ret = recv_loop(fd, tmout, 0, 0, rep);
- if(ret)
- return ret;
- {
- unsigned long rep_len;
- char *s, *p;
-
- s = realloc(rep->data, rep->length + 1);
- if (s == NULL) {
- krb5_data_free (rep);
- return -1;
- }
- s[rep->length] = 0;
- p = strstr(s, "\r\n\r\n");
- if(p == NULL) {
- free(s);
- return -1;
- }
- p += 4;
- rep->data = s;
- rep->length -= p - s;
- if(rep->length < 4) { /* remove length */
- free(s);
- return -1;
- }
- rep->length -= 4;
- _krb5_get_int(p, &rep_len, 4);
- if (rep_len != rep->length) {
- free(s);
- return -1;
- }
- memmove(rep->data, p + 4, rep->length);
- }
- return 0;
-}
-
-static int
-init_port(const char *s, int fallback)
-{
- if (s) {
- int tmp;
-
- sscanf (s, "%d", &tmp);
- return htons(tmp);
- } else
- return fallback;
-}
-
-/*
- * Return 0 if succesful, otherwise 1
- */
-
-static int
-send_via_proxy (krb5_context context,
- const char *hostname,
- const krb5_data *send,
- krb5_data *receive)
-{
- char *proxy = strdup(context->http_proxy);
- char *prefix;
- char *colon;
- struct addrinfo hints;
- struct addrinfo *ai, *a;
- int ret;
- int s;
- char portstr[NI_MAXSERV];
-
- colon = strchr(proxy, ':');
- if(colon != NULL)
- *colon++ = '\0';
- memset (&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- snprintf (portstr, sizeof(portstr), "%d",
- ntohs(init_port (colon, htons(80))));
- ret = getaddrinfo (proxy, portstr, NULL, &ai);
- free (proxy);
- if (ret)
- return ret;
-
- for (a = ai; a != NULL; a = a->ai_next) {
- s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
- if (s < 0)
- continue;
- if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
- close (s);
- continue;
- }
- break;
- }
- if (a == NULL) {
- freeaddrinfo (ai);
- return 1;
- }
- freeaddrinfo (ai);
-
- asprintf(&prefix, "http://%s/", hostname);
- if(prefix == NULL) {
- close(s);
- return 1;
- }
- ret = send_and_recv_http(s, context->kdc_timeout,
- prefix, send, receive);
- close (s);
- free(prefix);
- if(ret == 0 && receive->length != 0)
- return 0;
- return 1;
-}
-
-/*
- * Send the data `send' to one KDC in `realm' and get back the reply
- * in `receive'.
- */
-
-krb5_error_code
-krb5_sendto_kdc (krb5_context context,
- const krb5_data *send,
- const krb5_realm *realm,
- krb5_data *receive)
-{
- krb5_error_code ret;
- char **hostlist, **hp, *p;
- int fd;
- int port;
- int i;
-
- port = krb5_getportbyname (context, "kerberos", "udp", 88);
-
- if (context->use_admin_kdc)
- ret = krb5_get_krb_admin_hst (context, realm, &hostlist);
- else
- ret = krb5_get_krbhst (context, realm, &hostlist);
- if (ret)
- return ret;
-
- for (i = 0; i < context->max_retries; ++i)
- for (hp = hostlist; (p = *hp); ++hp) {
- char *colon;
- int http_flag = 0;
- int tcp_flag = 0;
- struct addrinfo *ai, *a;
- struct addrinfo hints;
- char portstr[NI_MAXSERV];
-
- if(strncmp(p, "http://", 7) == 0){
- p += 7;
- http_flag = 1;
- port = htons(80);
- } else if(strncmp(p, "http/", 5) == 0) {
- p += 5;
- http_flag = 1;
- port = htons(80);
- }else if(strncmp(p, "tcp/", 4) == 0){
- p += 4;
- tcp_flag = 1;
- } else if(strncmp(p, "udp/", 4) == 0) {
- p += 4;
- }
- if(http_flag && context->http_proxy) {
- if (send_via_proxy (context, p, send, receive))
- continue;
- else
- goto out;
- }
- colon = strchr (p, ':');
- if (colon)
- *colon++ = '\0';
-
- memset (&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- if (tcp_flag || http_flag)
- hints.ai_socktype = SOCK_STREAM;
- else
- hints.ai_socktype = SOCK_DGRAM;
- snprintf (portstr, sizeof(portstr), "%d",
- ntohs(init_port (colon, port)));
- ret = getaddrinfo (p, portstr, &hints, &ai);
- if (ret)
- continue;
- for (a = ai; a != NULL; a = a->ai_next) {
- fd = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
- if (fd < 0)
- continue;
- if (connect (fd, a->ai_addr, a->ai_addrlen) < 0) {
- close (fd);
- continue;
- }
- break;
- }
- if (a == NULL) {
- freeaddrinfo (ai);
- continue;
- }
- freeaddrinfo (ai);
-
- if(http_flag)
- ret = send_and_recv_http(fd, context->kdc_timeout,
- "", send, receive);
- else if(tcp_flag)
- ret = send_and_recv_tcp (fd, context->kdc_timeout,
- send, receive);
- else
- ret = send_and_recv_udp (fd, context->kdc_timeout,
- send, receive);
- close (fd);
- if(ret == 0 && receive->length != 0)
- goto out;
- }
- ret = KRB5_KDC_UNREACH;
-out:
- krb5_free_krbhst (context, hostlist);
- return ret;
-}