summaryrefslogtreecommitdiff
path: root/kerberosIV/krb/send_to_kdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kerberosIV/krb/send_to_kdc.c')
-rw-r--r--kerberosIV/krb/send_to_kdc.c477
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;
-}