diff options
Diffstat (limited to 'kerberosIV/krb/send_to_kdc.c')
-rw-r--r-- | kerberosIV/krb/send_to_kdc.c | 477 |
1 files changed, 0 insertions, 477 deletions
diff --git a/kerberosIV/krb/send_to_kdc.c b/kerberosIV/krb/send_to_kdc.c deleted file mode 100644 index 2c4c538e510..00000000000 --- a/kerberosIV/krb/send_to_kdc.c +++ /dev/null @@ -1,477 +0,0 @@ -/* $OpenBSD: send_to_kdc.c,v 1.13 1998/08/16 20:48:39 art Exp $ */ -/* $KTH: send_to_kdc.c,v 1.54 1998/02/17 23:55:35 bg Exp $ */ - -/* - * This source code is no longer held under any constraint of USA - * `cryptographic laws' since it was exported legally. The cryptographic - * functions were removed from the code and a "Bones" distribution was - * made. A Commodity Jurisdiction Request #012-94 was filed with the - * USA State Department, who handed it to the Commerce department. The - * code was determined to fall under General License GTDA under ECCN 5D96G, - * and hence exportable. The cryptographic interfaces were re-added by Eric - * Young, and then KTH proceeded to maintain the code in the free world. - * - */ - -/* - * Copyright (C) 1989 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -#include "krb_locl.h" - -struct host { - struct sockaddr_in addr; - enum krb_host_proto proto; -}; - -static const char *prog = "send_to_kdc"; -static send_recv(KTEXT pkt, KTEXT rpkt, int f, - struct sockaddr_in *adr, struct host *addrs, - int h_hosts); - -/* - * send_to_kdc() sends a message to the Kerberos authentication - * server(s) in the given realm and returns the reply message. - * The "pkt" argument points to the message to be sent to Kerberos; - * the "rpkt" argument will be filled in with Kerberos' reply. - * The "realm" argument indicates the realm of the Kerberos server(s) - * to transact with. If the realm is null, the local realm is used. - * - * If more than one Kerberos server is known for a given realm, - * different servers will be queried until one of them replies. - * Several attempts (retries) are made for each server before - * giving up entirely. - * - * If an answer was received from a Kerberos host, KSUCCESS is - * returned. The following errors can be returned: - * - * SKDC_CANT - can't get local realm - * - can't find "kerberos" in /etc/services database - * - can't open socket - * - can't bind socket - * - all ports in use - * - couldn't find any Kerberos host - * - * SKDC_RETRY - couldn't get an answer from any Kerberos server, - * after several retries - */ - -/* always use the admin server */ -static int krb_use_admin_server_flag = 0; - -int -krb_use_admin_server(int flag) -{ - int old = krb_use_admin_server_flag; - krb_use_admin_server_flag = flag; - return old; -} - -int -send_to_kdc(KTEXT pkt, KTEXT rpkt, char *realm) -{ - int i; - int no_host; /* was a kerberos host found? */ - int retry; - int n_hosts; - int retval; - struct hostent *host; - char lrealm[REALM_SZ]; - struct krb_host *k_host; - struct host *hosts = malloc(sizeof(*hosts)); - - if (hosts == NULL) - return SKDC_CANT; - - /* - * If "realm" is non-null, use that, otherwise get the - * local realm. - */ - if (realm != NULL){ - strncpy(lrealm, realm, REALM_SZ); - lrealm[REALM_SZ-1] = '\0'; - } - else - if (krb_get_lrealm(lrealm,1)) { - if (krb_debug) - krb_warning("%s: can't get local realm\n", prog); - return(SKDC_CANT); - } - if (krb_debug) - krb_warning("lrealm is %s\n", lrealm); - - no_host = 1; - /* get an initial allocation */ - n_hosts = 0; - for (i = 1; (k_host = krb_get_host(i, lrealm, krb_use_admin_server_flag)); - ++i) { - char *p; - - if (krb_debug) - krb_warning("Getting host entry for %s...", k_host->host); - host = gethostbyname(k_host->host); - if (krb_debug) { - krb_warning("%s.\n", - host ? "Got it" : "Didn't get it"); - } - if (!host) - continue; - no_host = 0; /* found at least one */ - while ((p = *(host->h_addr_list)++)) { - struct host *temp; - - temp = realloc(hosts, sizeof(*hosts) * (n_hosts + 1)); - if (temp == NULL) { - free(hosts); - return SKDC_CANT; - } - hosts = temp; - memset (&hosts[n_hosts].addr, 0, sizeof(hosts[n_hosts].addr)); - hosts[n_hosts].addr.sin_family = host->h_addrtype; - hosts[n_hosts].addr.sin_port = htons(k_host->port); - hosts[n_hosts].proto = k_host->proto; - memcpy(&hosts[n_hosts].addr.sin_addr, p, - sizeof(hosts[n_hosts].addr.sin_addr)); - ++n_hosts; - if (send_recv(pkt, rpkt, hosts[n_hosts-1].proto, - &hosts[n_hosts-1].addr, hosts, n_hosts)) { - retval = KSUCCESS; - goto rtn; - } - if (krb_debug) { - krb_warning("Timeout, error, or wrong descriptor\n"); - } - } - } - if (no_host) { - if (krb_debug) - krb_warning("%s: can't find any Kerberos host.\n", - prog); - retval = SKDC_CANT; - goto rtn; - } - /* retry each host in sequence */ - for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) { - for (i = 0; i < n_hosts; ++i) { - if (send_recv(pkt, rpkt, - hosts[i].proto, - &hosts[i].addr, - hosts, - n_hosts)) { - retval = KSUCCESS; - goto rtn; - } - } - } - retval = SKDC_RETRY; -rtn: - free(hosts); - hosts = NULL; - return(retval); -} - -static int udp_socket(void) -{ - return socket(AF_INET, SOCK_DGRAM, 0); -} - -static int udp_connect(int s, struct sockaddr_in *adr) -{ - if(krb_debug) { - krb_warning("connecting to %s udp, port %d\n", - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port)); - } - - return connect(s, (struct sockaddr*)adr, sizeof(*adr)); -} - -static int udp_send(int s, struct sockaddr_in* adr, KTEXT pkt) -{ - if(krb_debug) { - krb_warning("sending %d bytes to %s, udp port %d\n", - pkt->length, - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port)); - } - - return send(s, pkt->dat, pkt->length, 0); -} - -static int tcp_socket(void) -{ - return socket(AF_INET, SOCK_STREAM, 0); -} - -static int tcp_connect(int s, struct sockaddr_in *adr) -{ - if(krb_debug) { - krb_warning("connecting to %s, tcp port %d\n", - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port)); - } - - return connect(s, (struct sockaddr*)adr, sizeof(*adr)); -} - -static int tcp_send(int s, struct sockaddr_in* adr, KTEXT pkt) -{ - unsigned char len[4]; - - if(krb_debug) { - krb_warning("sending %d bytes to %s, tcp port %d\n", - pkt->length, - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port)); - } - - krb_put_int(pkt->length, len, 4); - if(send(s, len, sizeof(len), 0) != sizeof(len)) - return -1; - return send(s, pkt->dat, pkt->length, 0); -} - -static int udptcp_recv(void *buf, size_t len, KTEXT rpkt) -{ - int pktlen=MIN(len, MAX_KTXT_LEN - 1); - - if(krb_debug) - krb_warning("recieved %d bytes on udp/tcp socket\n", len); - - memcpy(rpkt->dat, buf, pktlen); - rpkt->length = pktlen; - return 0; -} - -static int url_parse(const char *url, char *host, size_t len, short *port) -{ - const char *p; - if (url == NULL || host == NULL) - return -1; - if(strncmp(url, "http://", 7)) - return -1; - url += 7; - strncpy(host, url, len); - p = strchr(url, ':'); - if(p){ - *port = atoi(p+1); - if(p - url >= len) - return -1; - host[p - url] = 0; - }else{ - *port = 80; - host[len - 1] = 0; - } - return 0; -} - -#define PROXY_VAR "krb4_proxy" - -static int http_connect(int s, struct sockaddr_in *adr) -{ - const char *proxy = krb_get_config_string(PROXY_VAR); - char host[MAXHOSTNAMELEN]; - short port; - struct hostent *hp; - struct sockaddr_in sin; - - if (adr == NULL) - return -1; - - if(proxy == NULL) { - if(krb_debug) - krb_warning("Not using proxy.\n"); - return tcp_connect(s, adr); - } - - if(url_parse(proxy, host, sizeof(host), &port) < 0) - return -1; - - hp = gethostbyname(host); - if(hp == NULL) - return -1; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); - sin.sin_port = htons(port); - if(krb_debug) { - krb_warning("connecting to proxy on %s (%s) port %d\n", - host, inet_ntoa(sin.sin_addr), port); - } - - return connect(s, (struct sockaddr*)&sin, sizeof(sin)); -} - -static int http_send(int s, struct sockaddr_in* adr, KTEXT pkt) -{ - char *str; - char *msg; - - if(base64_encode(pkt->dat, pkt->length, &str) < 0) - return -1; - - if(krb_get_config_string(PROXY_VAR)){ - if(krb_debug) { - krb_warning("sending %d bytes to %s, tcp port %d (via proxy)\n", - pkt->length, - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port)); - } - - asprintf(&msg, "GET http://%s:%d/%s HTTP/1.0\r\n\r\n", - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port), - str); - } else { - if(krb_debug) { - krb_warning("sending %d bytes to %s, http port %d\n", - pkt->length, - inet_ntoa(adr->sin_addr), - ntohs(adr->sin_port)); - } - asprintf(&msg, "GET %s HTTP/1.0\r\n\r\n", str); - } - free(str); - str = NULL; - - if (msg == NULL) - return -1; - - if(send(s, msg, strlen(msg), 0) != strlen(msg)){ - free(msg); - msg = NULL; - return -1; - } - free(msg); - msg = NULL; - return 0; -} - -static int http_recv(void *buf, size_t len, KTEXT rpkt) -{ - char *p; - int pktlen; - char *tmp = malloc(len + 1); - if (tmp == NULL) - return -1; - - memcpy(tmp, buf, len); - tmp[len] = 0; - p = strstr(tmp, "\r\n\r\n"); - if(p == NULL){ - free(tmp); - tmp = NULL; - return -1; - } - - p += 4; - if(krb_debug) - krb_warning("recieved %d bytes on http socket\n", (tmp + len) - p); - if (p >= tmp+len) { - free(tmp); - tmp = NULL; - return -1; - } - pktlen = MIN((tmp + len) - p, MAX_KTXT_LEN - 1); - memcpy(rpkt->dat, p, pktlen); - - rpkt->dat[pktlen] = '\0'; - rpkt->length = pktlen; - free(tmp); - tmp = NULL; - return 0; -} - -static struct proto_descr { - int proto; - int stream_flag; - int (*socket)(void); - int (*connect)(int, struct sockaddr_in*); - int (*send)(int, struct sockaddr_in*, KTEXT); - int (*recv)(void*, size_t, KTEXT); -} protos[] = { - { PROTO_UDP, 0, udp_socket, udp_connect, udp_send, udptcp_recv }, - { PROTO_TCP, 1, tcp_socket, tcp_connect, tcp_send, udptcp_recv }, - { PROTO_HTTP, 1, tcp_socket, http_connect, http_send, http_recv } -}; - -static int -send_recv(KTEXT pkt, KTEXT rpkt, int proto, struct sockaddr_in *adr, - struct host *addrs, int n_hosts) -{ - int i; - int s; - unsigned char buf[MAX_KTXT_LEN]; - int offset = 0; - fd_set *fdsp = NULL; - int fdsn; - - for(i = 0; i < sizeof(protos) / sizeof(protos[0]); i++){ - if(protos[i].proto == proto) - break; - } - if(i == sizeof(protos) / sizeof(protos[0])) - return FALSE; - if((s = (*protos[i].socket)()) < 0) - return FALSE; - if((*protos[i].connect)(s, adr) < 0){ - close(s); - return FALSE; - } - if((*protos[i].send)(s, adr, pkt) < 0){ - close(s); - return FALSE; - } - fdsn = howmany(s+1, NFDBITS) * sizeof(fd_mask); - if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) { - close(s); - return FALSE; - } - do{ - struct timeval timeout; - int len; - timeout.tv_sec = CLIENT_KRB_TIMEOUT; - timeout.tv_usec = 0; - - memset(fdsp, 0, fdsn); - FD_SET(s, fdsp); - - /* select - either recv is ready, or timeout */ - /* see if timeout or error or wrong descriptor */ - if(select(s + 1, fdsp, 0, 0, &timeout) < 1 - || !FD_ISSET(s, fdsp)) { - if (krb_debug) - krb_warning("select failed: errno = %d\n", errno); - close(s); - free(fdsp); - return FALSE; - } - len = recv(s, buf + offset, sizeof(buf) - offset, 0); - if(len <= 0) - break; - offset += len; - }while(protos[i].stream_flag); - free(fdsp); - close(s); - if((*protos[i].recv)(buf, offset, rpkt) < 0) - return FALSE; - return TRUE; -} |