summaryrefslogtreecommitdiffstats
path: root/src/krb524
diff options
context:
space:
mode:
authorTheodore Tso <tytso@mit.edu>1993-06-03 19:29:40 +0000
committerTheodore Tso <tytso@mit.edu>1993-06-03 19:29:40 +0000
commit746386f12e01102acbe5637aac6f1259c74bb552 (patch)
tree715df6527f739854dc978c588047607e1907e9e9 /src/krb524
parentacbed92e113f54d33789d427e697a23a0f07ab64 (diff)
downloadkrb5-746386f12e01102acbe5637aac6f1259c74bb552.tar.gz
krb5-746386f12e01102acbe5637aac6f1259c74bb552.tar.xz
krb5-746386f12e01102acbe5637aac6f1259c74bb552.zip
Initial revision
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2611 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/krb524')
-rw-r--r--src/krb524/Makefile75
-rw-r--r--src/krb524/README120
-rw-r--r--src/krb524/RELEASE_NOTES17
-rw-r--r--src/krb524/conv_creds.c112
-rw-r--r--src/krb524/conv_princ.c42
-rw-r--r--src/krb524/conv_tkt.c86
-rw-r--r--src/krb524/conv_tkt_skey.c117
-rw-r--r--src/krb524/encode.c119
-rw-r--r--src/krb524/getcred.c68
-rw-r--r--src/krb524/globals.c25
-rw-r--r--src/krb524/k524init.c131
-rw-r--r--src/krb524/krb524.h35
-rw-r--r--src/krb524/krb524_err.et32
-rw-r--r--src/krb524/krb524_prot11
-rw-r--r--src/krb524/krb524d.c371
-rw-r--r--src/krb524/misc.c32
-rw-r--r--src/krb524/sendmsg.c156
-rw-r--r--src/krb524/test.c298
18 files changed, 1847 insertions, 0 deletions
diff --git a/src/krb524/Makefile b/src/krb524/Makefile
new file mode 100644
index 0000000000..6b4a4f162e
--- /dev/null
+++ b/src/krb524/Makefile
@@ -0,0 +1,75 @@
+# Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+#
+# 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 Geer Zolot Associates not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. Geer Zolot Associates makes no
+# representations about the suitability of this software for any
+# purpose. It is provided "as is" without express or implied warranty.
+#
+# $Id$
+
+KRB5TOP = /ua/software/build/sun4/krb5.src.B2/src
+
+# Library sources
+SRCS = conv_creds.c conv_princ.c conv_tkt.c conv_tkt_skey.c \
+ encode.c misc.c globals.c sendmsg.c krb524_err.et
+OBJS = conv_creds.o conv_princ.o conv_tkt.o conv_tkt_skey.o \
+ encode.o misc.o globals.o sendmsg.o krb524_err.o
+
+GENS = krb524_err.c krb524_err.h
+
+# Server stuff.
+LDFLAGS= -L. -L/usr/local/lib
+LIBS = -lkrb524 -lkdb5 -lkrb5 -lkrb -lcrypto /usr/local/lib/libdes.a \
+ -lisode -lcom_err
+
+CL_LIBS = -lkrb524 -lkrb5 -lcrypto -lisode -lkrb -lcom_err
+
+CC = gcc
+CFLAGS = -g -DUSE_MASTER -I. -I/usr/local/include
+
+all: libkrb524.a krb524d test k524init
+
+libkrb524.a: $(OBJS)
+ ar cru libkrb524.a $(OBJS)
+ ranlib libkrb524.a
+
+test: libkrb524.a test.o
+ $(CC) -o test $(LDFLAGS) test.o $(LIBS)
+
+krb524d: libkrb524.a krb524d.o
+ $(CC) -o krb524d krb524d.o $(LDFLAGS) $(LIBS)
+
+k524init: libkrb524.a k524init.o
+ $(CC) -o k524init $(LDFLAGS) k524init.o $(CL_LIBS)
+
+krb524d.o: krb524d.c
+ $(CC) -c $(CFLAGS) -I$(KRB5TOP)/include $*.c
+
+test.o: test.c
+ $(CC) -c $(CFLAGS) -I$(KRB5TOP)/include $*.c
+
+depend: $(GENS)
+ makedepend -- $(CFLAGS) -I$(KRB5TOP)/include -- $(SRCS) \
+ test.c krb524d.c
+
+clean:
+ -rm -f libkrb524.a $(OBJS) $(GENS) core *~ *.bak #*
+ -rm -f test krb524d k524init test.o krb524d.o k524init.o
+
+krb524_err.c krb524_err.h: krb524_err.et
+ compile_et krb524_err.et
+
+.SUFFIXES: .et
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/src/krb524/README b/src/krb524/README
new file mode 100644
index 0000000000..6f829313d8
--- /dev/null
+++ b/src/krb524/README
@@ -0,0 +1,120 @@
+Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+
+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 Geer Zolot Associates not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission. Geer Zolot Associates makes no
+representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+
+$Id$
+
+Kerberos V5 to Kerberos V4 Credentials Converting Service, ALPHA RELEASE
+========================================================================
+
+krb524 is a service that converts Kerberos V5 credentials into
+Kerberos V4 credentials suitable for use with applications that for
+whatever reason do not use V5 directly. The service consists of a
+server that has access to the secret key of the Kerberos service for
+which credentials will be converted, and a library for use by client
+programs that wish to use the server.
+
+The protocol is simple. Suppose that a client C wishes to obtain V4
+credentials for a V5 service S by using the krb524 server. The
+notation {C,S}_n represents a Vn service ticket for S for use by C.
+
+(1) C obtains V5 credentials, including a ticket {C,S}_5, for S by the
+normal V5 means.
+
+(2) C transmits {C,S}_5 to KRB524.
+
+(3) KRB524 converts {C,S}_5 into {C,S}_4.
+
+(4) KRB524 transmits {C,S}_4 to C.
+
+(5) C creates a V4 credentials strucuture from the plaintext
+information in the V5 credential and {C,S}_4.
+
+Steps (2) through (4) are encapsulated in a single function call in
+the krb524 library.
+
+Obviously, not all V5 credentials can be completely converted to V4
+credentials, since the former is a superset of the latter. The
+precise semantics of the conversion function are still undecided.
+UTSL.
+
+Programs contained in this release
+======================================================================
+
+krb524d [-m[aster]] [-k[eytab]]
+
+The krb524 server. It accepts UDP requests on the krb524 service
+port, specified in /etc/services, or on port 4444 by default. (A
+request for an official port assignment is underway.) The -m argument
+causes krb524d to access the KDC master database directly; the -k
+argument causes krb524d to use the default keytab (and therefore only
+be able to convert tickets for services in the keytab). Only one of
+-m or -k can be specified.
+
+test -remote server client service
+
+A test program that obtains a V5 credential for {client,service},
+converts it to a V4 credential, and prints out the entire contents of
+both versions. It prompts for service's secret key, which it needs to
+decrypt both tickets in order to print them out. Enter it as an eight
+digit ASCII hex number.
+
+k524init [-n] [-p principal]
+
+Convert a V5 credential into a V4 credential and store it in a V4
+ticket file. The client is 'principal', or krbtgt at the V5 ccache's
+default principal's realm if not specified. The -n argument causes
+the new ticket to be added to the existing ticket file; otherwise, the
+ticket file is initialized.
+
+Using libkrb524.a
+======================================================================
+
+To use libkrb524.a, #include <krb524.h>, link against libkrb524.a,
+call krb524_init_ets() at the beginning of your program, and call one
+of the following two functions:
+
+int krb524_convert_creds_addr(krb5_creds *v5creds, CREDENTIALS *v4creds,
+ struct sockaddr *saddr)
+
+int krb524_convert_creds_kdc(krb5_creds *v5creds, CREDENTIALS *v4creds)
+
+Both convert the V5 credential in v5creds into a V4 credential in
+v4creds. One assumes krb524d is running on the KDC, the other uses an
+explicit host. You only need to specify the address for saddr; the
+port is filled in automatically.
+
+Unresolved issues / Bugs
+======================================================================
+
+o krb524d requires access to the secret key of any service to be
+converted. Should krb524d run on the KDC or on individual server
+machines? The latter is more paranoid, since it prevents bugs in
+krb524d from provided unauthorized access to the master database.
+However, it also requires the client to provide the address of the
+server to be used. The client will usually have this information
+(since presumably it will be sending the converted V4 credentials to
+the same server) but it may not be in a convenient form. It seems
+"cleaner" to have krb524d run on the KDC.
+
+o Even if krb524d uses keytabs on server machines, it needs to be more
+flexible. You only want to run one krb524d per host, so it has to be
+able to scan multiple keytabs. This might get logistically messy.
+
+o This code is of alpha quality. Bugs, omissions, memory leaks, and
+perhaps security holes still remain. Do not use it (yet) in a
+production environment.
diff --git a/src/krb524/RELEASE_NOTES b/src/krb524/RELEASE_NOTES
new file mode 100644
index 0000000000..cd462b6fd3
--- /dev/null
+++ b/src/krb524/RELEASE_NOTES
@@ -0,0 +1,17 @@
+$Id$
+
+Kerberos V5 to Kerberos V4 Credentials Converting Service, ALPHA RELEASE
+========================================================================
+
+This is the ALPHA RELEASE of krb524. Treat it accordingly.
+
+Soon, krb524 will be integrated into the standard MIT Kerberos 5
+distribution. krb524's existence as a distinct distribution is
+temporary.
+
+If you have any questions, contact
+
+Barry Jaspan, bjaspan@gza.com
+Geer Zolot Associates
+(617) 374-3700
+
diff --git a/src/krb524/conv_creds.c b/src/krb524/conv_creds.c
new file mode 100644
index 0000000000..ce36f30c16
--- /dev/null
+++ b/src/krb524/conv_creds.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+int krb524_convert_creds_addr(krb5_creds *v5creds, CREDENTIALS *v4creds,
+ struct sockaddr *saddr)
+{
+ int ret;
+
+ if (ret = krb524_convert_creds_plain(v5creds, v4creds))
+ return ret;
+
+ return krb524_convert_tkt(v5creds->server, &v5creds->ticket,
+ &v4creds->ticket_st,
+ &v4creds->kvno,
+ saddr);
+}
+
+int krb524_convert_creds_kdc(krb5_creds *v5creds, CREDENTIALS *v4creds)
+{
+ struct sockaddr_in *addrs;
+ int ret, naddrs;
+
+ if (ret = krb5_locate_kdc(&v5creds->server->realm, &addrs, &naddrs))
+ return ret;
+ if (naddrs == 0)
+ ret = KRB5_KDC_UNREACH;
+ else {
+ addrs[0].sin_port = 0; /* use krb524 default port */
+ ret = krb524_convert_creds_addr(v5creds, v4creds,
+ (struct sockaddr *) &addrs[0]);
+ }
+
+ free(addrs);
+ return ret;
+}
+
+int krb524_convert_creds_plain(krb5_creds *v5creds, CREDENTIALS *v4creds)
+{
+ unsigned long addr;
+ krb5_data *comp;
+ int ret;
+
+ bzero((char *) v4creds, sizeof(CREDENTIALS));
+
+ if (ret = krb524_convert_princs(v5creds->client, v5creds->server,
+ v4creds->pname, v4creds->pinst,
+ v4creds->realm, v4creds->service,
+ v4creds->instance))
+ return ret;
+
+ /* Check keytype too */
+ if (v5creds->keyblock.length != sizeof(C_Block)) {
+ if (krb524_debug)
+ fprintf(stderr, "v5 session keyblock length %d != "
+ "C_Block size %d\n", v5creds->keyblock.length,
+ sizeof(C_Block));
+ return KRB524_BADKEY;
+ } else
+ bcopy((char *) v5creds->keyblock.contents, v4creds->session,
+ sizeof(C_Block));
+
+ /* V4 has no concept of authtime or renew_till, so ignore them */
+ /* V4 lifetime is 1 byte, in 5 minute increments */
+ v4creds->lifetime = 0xff &
+ ((v5creds->times.endtime - v5creds->times.starttime) / 300);
+ v4creds->issue_date = v5creds->times.starttime;
+
+ /* XXX perhaps we should use the addr of the client host if */
+ /* v5creds contains more than one addr. Q: Does V4 support */
+ /* non-INET addresses? */
+ if (!v5creds->addresses || !v5creds->addresses[0] ||
+ v5creds->addresses[0]->addrtype != ADDRTYPE_INET ||
+ v5creds->addresses[0]->length != sizeof(addr)) {
+ if (krb524_debug)
+ fprintf(stderr, "Invalid v5creds address information.\n");
+ return KRB524_BADADDR;
+ } else
+ bcopy(v5creds->addresses[0]->contents, (char *) &addr,
+ sizeof(addr));
+
+ return 0;
+}
diff --git a/src/krb524/conv_princ.c b/src/krb524/conv_princ.c
new file mode 100644
index 0000000000..82d589b79e
--- /dev/null
+++ b/src/krb524/conv_princ.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+int krb524_convert_princs(krb5_principal client, krb5_principal
+ server, char *pname, char *pinst, char
+ *prealm, char *sname, char *sinst)
+{
+ char dummy[REALM_SZ];
+ int ret;
+
+ if (ret = krb5_524_conv_principal(client, pname, pinst, prealm))
+ return ret;
+
+ return krb5_524_conv_principal(server, sname, sinst, dummy);
+}
diff --git a/src/krb524/conv_tkt.c b/src/krb524/conv_tkt.c
new file mode 100644
index 0000000000..1332a23cdb
--- /dev/null
+++ b/src/krb524/conv_tkt.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+/*
+ * krb524_convert_tkt. Open a network connection to krb524d, send it
+ * the V5 ticket, receive the V4 ticket in response.
+ */
+int krb524_convert_tkt(krb5_principal server, krb5_data *v5tkt,
+ KTEXT_ST *v4tkt,
+ int *kvno,
+ struct sockaddr_in *saddr)
+{
+ char *p;
+ krb5_data reply;
+ struct servent *serv;
+ int ret, status;
+
+ reply.data = NULL;
+
+ if (saddr->sin_port == 0) {
+ serv = getservbyname(KRB524_SERVICE, "udp");
+ if (serv)
+ saddr->sin_port = serv->s_port;
+ else
+ saddr->sin_port = htons(KRB524_PORT);
+ }
+
+ if (ret = krb524_send_message(saddr, v5tkt, &reply))
+ goto fail;
+
+ p = reply.data;
+ status = ntohl(*((krb5_error_code *) p));
+ p += sizeof(krb5_error_code);
+ reply.length -= sizeof(krb5_error_code);
+ if (status) {
+ ret = status;
+ goto fail;
+ }
+ *kvno = ntohl(*((krb5_error_code *) p));
+ p += sizeof(int);
+ reply.length -= sizeof(int);
+ ret = decode_v4tkt(v4tkt, p, &reply.length);
+
+fail:
+ if (ret) {
+ if (reply.data)
+ free(reply.data);
+ reply.data = NULL;
+ reply.length = 0;
+ }
+
+ return ret;
+}
+
diff --git a/src/krb524/conv_tkt_skey.c b/src/krb524/conv_tkt_skey.c
new file mode 100644
index 0000000000..ac6a1b9285
--- /dev/null
+++ b/src/krb524/conv_tkt_skey.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+/*
+ * Convert a v5 ticket for server to a v4 ticket, using service key
+ * skey for both.
+ */
+int krb524_convert_tkt_skey(krb5_ticket *v5tkt, KTEXT_ST *v4tkt,
+ krb5_keyblock *skey)
+{
+ char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
+ char sname[ANAME_SZ], sinst[INST_SZ];
+ krb5_enc_tkt_part *v5etkt;
+ krb5_data *comp;
+ int ret, lifetime;
+
+ v5tkt->enc_part2 = NULL;
+ if (ret = krb5_decrypt_tkt_part(skey, v5tkt)) {
+ krb5_free_ticket(v5tkt);
+ return ret;
+ }
+ v5etkt = v5tkt->enc_part2;
+
+ if (ret = krb524_convert_princs(v5etkt->client, v5tkt->server,
+ pname, pinst, prealm, sname,
+ sinst)) {
+ krb5_free_enc_tkt_part(v5etkt);
+ v5tkt->enc_part2 = NULL;
+ return ret;
+ }
+
+ if (v5etkt->session->keytype != KEYTYPE_DES ||
+ v5etkt->session->length != sizeof(C_Block)) {
+ if (krb524_debug)
+ fprintf(stderr, "v5 session keyblock type %d length %d != "
+ "C_Block size %d\n", v5etkt->session->keytype,
+ v5etkt->session->length,
+ sizeof(C_Block));
+ krb5_free_enc_tkt_part(v5etkt);
+ v5tkt->enc_part2 = NULL;
+ return KRB524_BADKEY;
+ }
+
+ /* V4 has no concept of authtime or renew_till, so ignore them */
+ /* V4 lifetime is 1 byte, in 5 minute increments */
+ if (v5etkt->times.starttime == 0)
+ v5etkt->times.starttime = v5etkt->times.authtime;
+ lifetime = 0xff &
+ ((v5etkt->times.endtime - v5etkt->times.authtime) / 300);
+
+ /* XXX perhaps we should use the addr of the client host if */
+ /* v5creds contains more than one addr. Q: Does V4 support */
+ /* non-INET addresses? */
+ if (!v5etkt->caddrs || !v5etkt->caddrs[0] ||
+ v5etkt->caddrs[0]->addrtype != ADDRTYPE_INET) {
+ if (krb524_debug)
+ fprintf(stderr, "Invalid v5creds address information.\n");
+ krb5_free_enc_tkt_part(v5etkt);
+ v5tkt->enc_part2 = NULL;
+ return KRB524_BADADDR;
+ }
+
+ if (krb524_debug)
+ printf("startime = %ld, authtime = %ld, lifetime = %ld\n",
+ (long) v5etkt->times.starttime,
+ (long) v5etkt->times.authtime,
+ (long) lifetime);
+
+ /* XXX are there V5 flags we should map to V4 equivalents? */
+ ret = krb_create_ticket(v4tkt,
+ 0, /* flags */
+ pname,
+ pinst,
+ krb5_princ_realm(v5etkt->client),
+ *((unsigned long *)v5etkt->caddrs[0]->contents),
+ v5etkt->session->contents,
+ lifetime,
+ /* issue_data */
+ v5etkt->times.starttime,
+ sname,
+ sinst,
+ skey->contents);
+
+ krb5_free_enc_tkt_part(v5etkt);
+ v5tkt->enc_part2 = NULL;
+ if (ret == KSUCCESS)
+ return 0;
+ else
+ return KRB524_V4ERR;
+}
diff --git a/src/krb524/encode.c b/src/krb524/encode.c
new file mode 100644
index 0000000000..f14fa6d90a
--- /dev/null
+++ b/src/krb524/encode.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+#include "krb524.h"
+
+/*
+ * I'm sure that this is reinventing the wheel, but I don't know where
+ * the wheel is hidden.
+ */
+
+int encode_v4tkt(KTEXT_ST *, char *, int *),
+ encode_ktext(char **, int *, KTEXT_ST *),
+ encode_bytes(char **, int *, char *, int),
+ encode_int32(char **, int *, krb5_int32 *);
+
+int decode_v4tkt(KTEXT_ST *, char *, int *),
+ decode_ktext(char **, int *, KTEXT_ST *),
+ decode_bytes(char **, int *, char *, int),
+ decode_int32(char **, int *, krb5_int32 *);
+
+int encode_bytes(char **out, int *outlen, char *in, int len)
+{
+ if (len > *outlen)
+ return KRB524_ENCFULL;
+ bcopy(in, *out, len);
+ *out += len;
+ *outlen -= len;
+ return 0;
+}
+
+int encode_int32(char **out, int *outlen, krb5_int32 *v)
+{
+ int ret;
+ int nv;
+
+ nv = htonl(*v);
+ return encode_bytes(out, outlen, (char *) &nv, sizeof(nv));
+}
+
+int encode_v4tkt(KTEXT_ST *v4tkt, char *buf, int *encoded_len)
+{
+ int buflen, ret;
+
+ buflen = *encoded_len;
+
+ if (ret = encode_int32(&buf, &buflen, &v4tkt->length))
+ return ret;
+ if (ret = encode_bytes(&buf, &buflen, v4tkt->dat, MAX_KTXT_LEN))
+ return ret;
+ if (ret = encode_int32(&buf, &buflen, &v4tkt->mbz))
+ return ret;
+
+ *encoded_len -= buflen;
+ return 0;
+}
+
+/* decode functions */
+
+int decode_bytes(char **out, int *outlen, char *in, int len)
+{
+ if (len > *outlen)
+ return KRB524_DECEMPTY;
+ bcopy(*out, in, len);
+ *out += len;
+ *outlen -= len;
+ return 0;
+}
+
+int decode_int32(char **out, int *outlen, krb5_int32 *v)
+{
+ int ret;
+ int nv;
+
+ if (ret = decode_bytes(out, outlen, (char *) &nv, sizeof(nv)))
+ return ret;
+ *v = ntohl(nv);
+ return 0;
+}
+
+int decode_v4tkt(KTEXT_ST *v4tkt, char *buf, int *encoded_len)
+{
+ int buflen, ret;
+
+ buflen = *encoded_len;
+ if (ret = decode_int32(&buf, &buflen, &v4tkt->length))
+ return ret;
+ if (ret = decode_bytes(&buf, &buflen, v4tkt->dat, MAX_KTXT_LEN))
+ return ret;
+ if (ret = decode_int32(&buf, &buflen, &v4tkt->mbz))
+ return ret;
+ *encoded_len -= buflen;
+ return 0;
+}
+
diff --git a/src/krb524/getcred.c b/src/krb524/getcred.c
new file mode 100644
index 0000000000..e81ef25389
--- /dev/null
+++ b/src/krb524/getcred.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+main(int argc, char **argv)
+{
+ krb5_principal client, server;
+ krb5_ccache cc;
+ krb5_creds v5creds;
+ CREDENTIALS v4creds;
+ int i, ret;
+
+ krb524_init_ets();
+
+ if (ret = krb5_parse_name(argv[1], &client)) {
+ com_err("getcred", ret, "parsing client name");
+ exit(1);
+ }
+ if (ret = krb5_parse_name(argv[2], &server)) {
+ com_err("getcred", ret, "parsing server name");
+ exit(1);
+ }
+ if (ret = krb5_cc_default(&cc)) {
+ com_err("getcred", ret, "opening default credentials cache");
+ exit(1);
+ }
+
+ bzero((char *) &v5creds, sizeof(v5creds));
+ v5creds.client = client;
+ v5creds.server = server;
+ v5creds.times.endtime = 0;
+ v5creds.keyblock.keytype = KEYTYPE_DES;
+ if (ret = krb5_get_credentials(0, cc, &v5creds)) {
+ com_err("getcred", ret, "getting V5 credentials");
+ exit(1);
+ }
+
+ if (ret = krb524_convert_creds_kdc(&v5creds, &v4creds)) {
+ com_err("getcred", ret, "converting to V4 credentials");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/src/krb524/globals.c b/src/krb524/globals.c
new file mode 100644
index 0000000000..eb7884a454
--- /dev/null
+++ b/src/krb524/globals.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+int krb524_debug = 0;
diff --git a/src/krb524/k524init.c b/src/krb524/k524init.c
new file mode 100644
index 0000000000..39045e54e0
--- /dev/null
+++ b/src/krb524/k524init.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb.h>
+
+extern int optind;
+extern char *optarg;
+
+#if !defined(lint) && !defined(SABER)
+const char rcsid[] = "$Id$";
+#endif
+
+main(int argc, char **argv)
+{
+ krb5_principal client, server;
+ krb5_ccache cc;
+ krb5_creds v5creds;
+ CREDENTIALS v4creds;
+ int code;
+ int option;
+ char *princ = NULL;
+ int nodelete = 0;
+ int lose = 0;
+
+ while((option = getopt(argc, argv, "p:n")) != EOF) {
+ switch(option) {
+ case 'p':
+ princ = optarg;
+ break;
+ case 'n':
+ nodelete++;
+ break;
+ default:
+ lose++;
+ break;
+ }
+ }
+
+ if (lose || (argc - optind > 1)) {
+ fprintf(stderr, "Usage: k524init [-p principal]\n");
+ exit(1);
+ }
+
+ krb524_init_ets();
+
+ if (code = krb5_cc_default(&cc)) {
+ com_err("k524init", code, "opening default credentials cache");
+ exit(1);
+ }
+
+ if (code = krb5_cc_get_principal(cc, &client)) {
+ com_err("k524init", code, "while retrieving user principal name");
+ exit(1);
+ }
+
+ if (princ) {
+ if (code = krb5_parse_name(princ, &server)) {
+ com_err("k524init", code, "while parsing service principal name");
+ exit(1);
+ }
+ } else {
+ if (code = krb5_build_principal(&server,
+ krb5_princ_realm(client)->length,
+ krb5_princ_realm(client)->data,
+ "krbtgt",
+ krb5_princ_realm(client)->data,
+ NULL)) {
+ com_err("k524init", code, "while creating service principal name");
+ exit(1);
+ }
+ }
+
+ bzero((char *) &v5creds, sizeof(v5creds));
+ v5creds.client = client;
+ v5creds.server = server;
+ v5creds.times.endtime = 0;
+ v5creds.keyblock.keytype = KEYTYPE_DES;
+ if (code = krb5_get_credentials(0, cc, &v5creds)) {
+ com_err("k524init", code, "getting V5 credentials");
+ exit(1);
+ }
+
+ if (code = krb524_convert_creds_kdc(&v5creds, &v4creds)) {
+ com_err("k524init", code, "converting to V4 credentials");
+ exit(1);
+ }
+
+ /* this is stolen from the v4 kinit */
+
+ if (!nodelete) {
+ /* initialize ticket cache */
+ if (code = in_tkt(v4creds.pname,v4creds.pinst) != KSUCCESS) {
+ com_err("k524init", code, "trying to create the V4 ticket file");
+ exit(1);
+ }
+ }
+
+ /* stash ticket, session key, etc. for future use */
+ if (code = save_credentials(v4creds.service, v4creds.instance,
+ v4creds.realm, v4creds.session,
+ v4creds.lifetime, v4creds.kvno,
+ &(v4creds.ticket_st), v4creds.issue_date)) {
+ com_err("k524init", code, "trying to save the V4 ticket");
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/src/krb524/krb524.h b/src/krb524/krb524.h
new file mode 100644
index 0000000000..2b9a3b6f8b
--- /dev/null
+++ b/src/krb524/krb524.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __KRB524_H__
+#define __KRB524_H__
+
+/*
+ * $Id$
+ */
+
+#define KRB524_SERVICE "krb524"
+#define KRB524_PORT 4444
+
+#include <krb524_err.h>
+
+extern int krb524_debug;
+
+#endif /* __KRB524_H__ */
diff --git a/src/krb524/krb524_err.et b/src/krb524/krb524_err.et
new file mode 100644
index 0000000000..237d084ac9
--- /dev/null
+++ b/src/krb524/krb524_err.et
@@ -0,0 +1,32 @@
+# Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+#
+# 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 Geer Zolot Associates not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. Geer Zolot Associates makes no
+# representations about the suitability of this software for any
+# purpose. It is provided "as is" without express or implied warranty.
+#
+# $Id$
+
+error_table k524
+
+error_code KRB524_BADKEY, "Cannot convert V5 keyblock"
+error_code KRB524_BADADDR, "Cannot convert V5 address information"
+error_code KRB524_BADPRINC, "Cannot convert V5 principal"
+error_code KRB524_BADREALM, "V5 realm name longer than V4 maximum"
+error_code KRB524_V4ERR, "Kerberos V4 error"
+error_code KRB524_ENCFULL, "Encoding too large"
+error_code KRB524_DECEMPTY, "Decoding out of data"
+error_code KRB524_NOTRESP, "Service not responding"
+
+end
diff --git a/src/krb524/krb524_prot b/src/krb524/krb524_prot
new file mode 100644
index 0000000000..f83854d77f
--- /dev/null
+++ b/src/krb524/krb524_prot
@@ -0,0 +1,11 @@
+Protocol:
+
+ -> ASN.1 encoded V5 ticket
+ <- int status_code, [int kvno, encode_v4tkt encoded KTEXT_ST]
+
+kvno and V4 ticket are only included if status_code is zero.
+
+The kvno for the converted ticket is sent explicitly because the field
+is ASN.1 encoded in the krb5_creds structure; the client would have to
+decode (but not decrypt) the entire krb5_ticket structure to get it,
+which would be inefficient.
diff --git a/src/krb524/krb524d.c b/src/krb524/krb524d.c
new file mode 100644
index 0000000000..c681758ced
--- /dev/null
+++ b/src/krb524/krb524d.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <krb5/krb5.h>
+#include <krb5/asn1.h>
+#include <krb5/kdb.h>
+#include <krb5/kdb_dbm.h>
+#ifdef PROVIDE_DES_CBC_CRC
+#include <krb5/mit-des.h>
+#endif
+#include <krb.h>
+
+#include "krb524.h"
+
+#define TIMEOUT 60
+#define TKT_BUFSIZ 2048
+#define MSGSIZE 8192
+
+char *whoami;
+int signalled = 0;
+static int debug = 0;
+
+int use_keytab;
+char *keytab = NULL;
+krb5_keytab kt;
+
+int use_master;
+krb5_principal master_princ;
+krb5_encrypt_block master_encblock;
+krb5_keyblock master_keyblock;
+
+void init_keytab(), init_master();
+krb5_error_code do_connection(), lookup_service_key(), kdc_get_server_key();
+
+void usage()
+{
+ fprintf(stderr, "Usage: %s [-m[aster]] [-k[eytab]]\n", whoami);
+ cleanup_and_exit(1);
+}
+
+int request_exit()
+{
+ signalled = 1;
+}
+
+int krb5_free_keyblock_contents(krb5_keyblock *key)
+{
+ memset(key->contents, 0, key->length);
+ xfree(key->contents);
+ return 0;
+}
+
+main(int argc, char **argv)
+{
+ struct servent *serv;
+ struct sockaddr_in saddr;
+ struct timeval timeout;
+ int ret, s, conn;
+ fd_set rfds;
+
+ krb5_init_ets();
+
+ whoami = ((whoami = strrchr(argv[0], '/')) ? whoami + 1 : argv[0]);
+
+ argv++; argc--;
+ use_master = use_keytab = 0;
+ while (argc) {
+ if (strncmp(*argv, "-k", 2) == 0)
+ use_keytab = 1;
+ else if (strncmp(*argv, "-m", 2) == 0)
+ use_master = 1;
+ else
+ break;
+ argv++; argc--;
+ }
+ if (argc || use_keytab + use_master > 1 ||
+ use_keytab + use_master == 0)
+ usage();
+
+ signal(SIGINT, request_exit);
+ signal(SIGHUP, request_exit);
+ signal(SIGTERM, request_exit);
+
+ if (use_keytab)
+ init_keytab();
+ if (use_master)
+ init_master();
+
+ bzero((char *) &saddr, sizeof(struct sockaddr_in));
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr.s_addr = INADDR_ANY;
+ serv = getservbyname(KRB524_SERVICE, "udp");
+ if (serv == NULL) {
+ com_err(whoami, 0, "service entry not found, using %d", KRB524_PORT);
+ saddr.sin_port = htons(KRB524_PORT);
+ } else
+ saddr.sin_port = serv->s_port;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ com_err(whoami, errno, "creating main socket");
+ cleanup_and_exit(1);
+ }
+ if ((ret = bind(s, (struct sockaddr *) &saddr,
+ sizeof(struct sockaddr_in))) < 0) {
+ com_err(whoami, errno, "binding main socket");
+ cleanup_and_exit(1);
+ }
+
+ timeout.tv_sec = TIMEOUT;
+ timeout.tv_usec = 0;
+ while (1) {
+ FD_ZERO(&rfds);
+ FD_SET(s, &rfds);
+
+ ret = select(s+1, &rfds, NULL, NULL, &timeout);
+ if (signalled)
+ cleanup_and_exit(0);
+ else if (ret == 0) {
+ if (use_master) {
+ ret = krb5_dbm_db_fini();
+ if (ret && ret != KRB5_KDB_DBNOTINITED) {
+ com_err(whoami, ret, "closing kerberos database");
+ cleanup_and_exit(1);
+ }
+ }
+ } else if (ret < 0 && errno != EINTR) {
+ com_err(whoami, errno, "in select");
+ cleanup_and_exit(1);
+ } else if (FD_ISSET(s, &rfds)) {
+ if (debug)
+ printf("received packet\n");
+ if (ret = do_connection(s)) {
+ com_err(whoami, ret, "handling packet");
+ }
+ } else
+ com_err(whoami, 0, "impossible situation occurred!");
+ }
+
+ return cleanup_and_exit(0);
+}
+
+int cleanup_and_exit(int ret)
+{
+ if (use_master) {
+ krb5_finish_key(&master_encblock);
+ memset((char *)&master_encblock, 0, sizeof(master_encblock));
+ (void) krb5_db_fini();
+ }
+ exit(ret);
+}
+
+void init_keytab()
+{
+ int ret;
+ if (keytab == NULL) {
+ if (ret = krb5_kt_default(&kt)) {
+ com_err(whoami, ret, "while opening default keytab");
+ cleanup_and_exit(1);
+ }
+ } else {
+ if (ret = krb5_kt_resolve(keytab, &kt)) {
+ com_err(whoami, ret, "while resolving keytab %s",
+ keytab);
+ cleanup_and_exit(1);
+ }
+ }
+}
+
+void init_master()
+{
+ int ret;
+ char *realm;
+
+ if (ret = krb5_get_default_realm(&realm)) {
+ com_err(whoami, ret, "getting default realm");
+ cleanup_and_exit(1);
+ }
+ if (ret = krb5_db_setup_mkey_name(NULL, realm, (char **) 0,
+ &master_princ)) {
+ com_err(whoami, ret, "while setting up master key name");
+ cleanup_and_exit(1);
+ }
+
+#ifdef PROVIDE_DES_CBC_CRC
+ master_encblock.crypto_entry = &mit_des_cryptosystem_entry;
+#else
+ error(You gotta figure out what cryptosystem to use in the KDC);
+#endif
+
+ master_keyblock.keytype = KEYTYPE_DES;
+ if (ret = krb5_db_fetch_mkey(master_princ, &master_encblock,
+ FALSE, /* non-manual type-in */
+ FALSE, /* irrelevant, given prev. arg */
+ 0, &master_keyblock)) {
+ com_err(whoami, ret, "while fetching master key");
+ cleanup_and_exit(1);
+ }
+
+ if (ret = krb5_db_init()) {
+ com_err(whoami, ret, "while initializing master database");
+ cleanup_and_exit(1);
+ }
+ if (ret = krb5_process_key(&master_encblock, &master_keyblock)) {
+ krb5_db_fini();
+ com_err(whoami, ret, "while processing master key");
+ cleanup_and_exit(1);
+ }
+}
+
+krb5_error_code do_connection(int s)
+{
+ struct sockaddr saddr;
+ krb5_ticket *v5tkt;
+ KTEXT_ST v4tkt;
+ krb5_keyblock service_key;
+ krb5_data msgdata, tktdata;
+ char msgbuf[MSGSIZE], tktbuf[TKT_BUFSIZ], *p;
+ int n, ret, saddrlen;
+
+ msgdata.data = msgbuf;
+ msgdata.length = MSGSIZE;
+
+ saddrlen = sizeof(struct sockaddr);
+ ret = recvfrom(s, msgdata.data, msgdata.length, 0, &saddr, &saddrlen);
+ if (ret < 0) {
+ ret = errno;
+ goto error;
+ }
+ if (debug)
+ printf("message received\n");
+
+ if (ret = decode_krb5_ticket(&msgdata, &v5tkt))
+ goto error;
+ if (debug)
+ printf("V5 ticket decoded\n");
+
+ if (ret = lookup_service_key(v5tkt->server, &service_key))
+ goto error;
+ if (debug)
+ printf("service key retrieved\n");
+
+ ret = krb524_convert_tkt_skey(v5tkt, &v4tkt, &service_key);
+ if (ret)
+ goto error;
+ krb5_free_keyblock_contents(&service_key);
+ krb5_free_ticket(v5tkt);
+ if (debug)
+ printf("credentials converted\n");
+
+ tktdata.data = tktbuf;
+ tktdata.length = TKT_BUFSIZ;
+ ret = encode_v4tkt(&v4tkt, tktdata.data, &tktdata.length);
+ if (ret)
+ goto error;
+ if (debug)
+ printf("v4 credentials encoded\n");
+
+error:
+ /* create the reply */
+ p = msgdata.data;
+ msgdata.length = 0;
+
+ n = htonl(ret);
+ memcpy(p, (char *) &n, sizeof(int));
+ p += sizeof(int);
+ msgdata.length += sizeof(int);
+
+ if (ret)
+ goto write_msg;
+
+ n = htonl(v5tkt->enc_part.kvno);
+ memcpy(p, (char *) &n, sizeof(int));
+ p += sizeof(int);
+ msgdata.length += sizeof(int);
+
+ memcpy(p, tktdata.data, tktdata.length);
+ p += tktdata.length;
+ msgdata.length += tktdata.length;
+
+write_msg:
+ if (ret)
+ (void) sendto(s, msgdata.data, msgdata.length, 0, &saddr, saddrlen);
+ else
+ if (sendto(s, msgdata.data, msgdata.length, 0, &saddr, saddrlen)<0)
+ ret = errno;
+ if (debug)
+ printf("reply written\n");
+
+ return ret;
+}
+
+krb5_error_code lookup_service_key(krb5_principal p, krb5_keyblock *key)
+{
+ int ret;
+ krb5_keytab_entry entry;
+
+ if (use_keytab) {
+ if (ret = krb5_kt_get_entry(kt, p, 0, &entry))
+ return ret;
+ bcopy((char *) &entry.key, key, sizeof(krb5_keyblock));
+ return 0;
+ } else if (use_master) {
+ if (ret = krb5_dbm_db_init())
+ return ret;
+ return kdc_get_server_key(p, key, NULL);
+ }
+}
+
+/* taken from kdc/kdc_util.c, and modified somewhat */
+krb5_error_code kdc_get_server_key(service, key, kvno)
+ krb5_principal service;
+ krb5_keyblock *key;
+ krb5_kvno *kvno;
+{
+ krb5_error_code ret;
+ int nprincs;
+ krb5_db_entry server;
+ krb5_boolean more;
+
+ nprincs = 1;
+ if (ret = krb5_db_get_principal(service, &server, &nprincs, &more))
+ return(ret);
+
+ if (more) {
+ krb5_db_free_principal(&server, nprincs);
+ return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
+ } else if (nprincs != 1) {
+ krb5_db_free_principal(&server, nprincs);
+ return(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
+ }
+
+ /*
+ * convert server.key into a real key (it is encrypted in the
+ * database)
+ */
+ ret = KDB_CONVERT_KEY_OUTOF_DB(&server.key, key);
+ if (kvno)
+ *kvno = server.kvno;
+ krb5_db_free_principal(&server, nprincs);
+ return ret;
+}
diff --git a/src/krb524/misc.c b/src/krb524/misc.c
new file mode 100644
index 0000000000..75a2755644
--- /dev/null
+++ b/src/krb524/misc.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include "krb524.h"
+
+void krb524_init_ets()
+{
+ krb5_init_ets();
+ initialize_k524_error_table();
+}
diff --git a/src/krb524/sendmsg.c b/src/krb524/sendmsg.c
new file mode 100644
index 0000000000..9b21082dca
--- /dev/null
+++ b/src/krb524/sendmsg.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * 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.
+ *
+ * Send a packet to a service and await a reply, using an exponential
+ * backoff retry algorithm. This is based on krb5_sendto_kdc.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <krb5/los-proto.h>
+
+#ifdef _AIX
+#include <sys/select.h>
+#endif
+
+#include "krb524.h"
+
+/*
+ * Send the formatted request 'message' to the host/port specified in
+ * addr and return the response (if any) in 'reply'.
+ *
+ * If the message is sent and a response is received, 0 is returned,
+ * otherwise an error code is returned.
+ *
+ * The storage for 'reply' is allocated and should be freed by the caller
+ * when finished.
+ */
+
+extern int krb5_max_dgram_size;
+extern int krb5_max_skdc_timeout;
+extern int krb5_skdc_timeout_shift;
+extern int krb5_skdc_timeout_1;
+
+int krb524_send_message (DECLARG(const struct sock addr *, addr),
+ DECLARG(const krb5_data *, message),
+ DECLARG(krb5_data *, reply))
+ OLDDECLARG(const struct sockaddr *, addr)
+ OLDDECLARG(const krb5_data *, message)
+ OLDDECLARG(krb5_data *, reply)
+{
+ register int timeout;
+ int nready, received;
+ krb5_error_code retval;
+ fd_set readable;
+ struct timeval waitlen;
+ int s, cc;
+
+ if ((reply->data = malloc(krb5_max_dgram_size)) == NULL)
+ return ENOMEM;
+ reply->length = krb5_max_dgram_size;
+
+ /* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the */
+ /* socket creation here will work properly... */
+ s = socket(addr->sa_family, SOCK_DGRAM, 0);
+ if (s == -1) {
+ retval = errno;
+ goto out;
+ }
+
+ /*
+ * On BSD systems, a connected UDP socket will get connection
+ * refused and net unreachable errors while an unconnected socket
+ * will time out, so use connect, send, recv instead of sendto,
+ * recvfrom. The connect here may return an error if the
+ * destination host is known to be unreachable.
+ */
+ if (connect(s, addr, sizeof(struct sockaddr)) == -1) {
+ retval = errno;
+ goto out;
+ }
+
+ /*
+ * Send the message, and wait for a reply, using an exponential
+ * backoff. Use the kdc timeout values, just for consistency.
+ */
+
+ received = 0;
+ for (timeout = krb5_skdc_timeout_1;
+ timeout < krb5_max_skdc_timeout;
+ timeout <<= krb5_skdc_timeout_shift) {
+
+ if (send(s, message->data, message->length, 0) != message->length) {
+ retval = errno;
+ goto out;
+ }
+
+ waitlen.tv_usec = 0;
+ waitlen.tv_sec = timeout;
+ FD_ZERO(&readable);
+ FD_SET(s, &readable);
+ nready = select(1 + s, &readable, 0, 0, &waitlen);
+ if (nready < 0) {
+ retval = errno;
+ goto out;
+ } else if (nready == 1) {
+ if ((cc = recv(s, reply->data, reply->length, 0)) == -1) {
+ retval = errno;
+ goto out;
+ }
+
+ /*
+ * We might consider here verifying that the reply came
+ * from the host specified, but that check can be fouled
+ * by some implementations of some network types which
+ * might show a loopback return address, for example, if
+ * the server is on the same host as the client.
+ *
+ * Besides, reply addresses can be spoofed, and we don't
+ * want to provide a false sense of security.
+ */
+ reply->length = cc;
+ retval = 0;
+ goto out;
+ }
+ /* else timeout, try again */
+ }
+
+ /* If the loop exits normally, the max timeout expired without */
+ /* a reply having arrived. */
+ retval = KRB524_NOTRESP;
+
+out:
+ (void) close(s);
+ if (retval) {
+ free(reply->data);
+ reply->data = 0;
+ reply->length = 0;
+ }
+ return retval;
+}
diff --git a/src/krb524/test.c b/src/krb524/test.c
new file mode 100644
index 0000000000..56a675d9e9
--- /dev/null
+++ b/src/krb524/test.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright 1993 by Geer Zolot Associates. All Rights Reserved.
+ *
+ * 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 Geer Zolot Associates not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Geer Zolot Associates makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcs_id[] = "$Id$";
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <des.h>
+#include <krb.h>
+#include <krb5/krb5.h>
+#include <krb5/asn1.h>
+
+#include "krb524.h"
+
+#define KEYSIZE 8
+#define CRED_BUFSIZ 2048
+
+#define krb5_print_addrs
+
+void do_local(krb5_creds *, krb5_keyblock *),
+ do_remote(krb5_creds *, char *, krb5_keyblock *);
+
+void print_key(char *msg, char *key)
+{
+ printf("%s: ", msg);
+ C_Block_print(key);
+ printf("\n");
+}
+
+void print_time(char *msg, int t)
+{
+ printf("%s: %d, %s", msg, t, ctime(&t));
+}
+
+void krb5_print_times(char *msg, krb5_ticket_times *t)
+{
+ printf("%s: Start: %d, %s", msg, t->starttime, ctime(&t->starttime));
+ printf("%s: End: %d, %s", msg, t->endtime, ctime(&t->endtime));
+ printf("%s: Auth: %d, %s", msg, t->authtime, ctime(&t->authtime));
+ printf("%s: Renew: %d, %s", msg, t->renew_till, ctime(&t->renew_till));
+}
+
+void krb5_print_keyblock(char *msg, krb5_keyblock *key)
+{
+ printf("%s: Keytype: %d\n", msg, key->keytype);
+ printf("%s: Length: %d\n", msg, key->length);
+ printf("%s: Key: ", msg);
+ C_Block_print(key->contents);
+ printf("\n");
+}
+
+void krb5_print_ticket(krb5_data *ticket_data, krb5_keyblock *key)
+{
+ char *p;
+ krb5_ticket *tkt;
+ int ret;
+
+ if (ret = decode_krb5_ticket(ticket_data, &tkt)) {
+ com_err("test", ret, "decoding ticket");
+ exit(1);
+ }
+ if (ret = krb5_decrypt_tkt_part(key, tkt)) {
+ com_err("test", ret, "decrypting V5 ticket for print");
+ exit(1);
+ }
+
+ krb5_unparse_name(tkt->server, &p);
+ printf("Ticket: Server: %s\n", p);
+ free(p);
+ printf("Ticket: EType: %d\n", tkt->enc_part.etype);
+ printf("Ticket: kvno: %d\n", tkt->enc_part.kvno);
+ printf("Ticket: Flags: 0x%08x\n", tkt->enc_part2->flags);
+ krb5_print_keyblock("Ticket: Session Keyblock",
+ tkt->enc_part2->session);
+ krb5_unparse_name(tkt->enc_part2->client, &p);
+ printf("Ticket: Client: %s\n", p);
+ free(p);
+ krb5_print_times("Ticket: Times", &tkt->enc_part2->times);
+ printf("Ticket: Address 0: %08x\n",
+ *((unsigned long *) tkt->enc_part2->caddrs[0]->contents));
+
+ krb5_free_ticket(tkt);
+}
+
+void krb5_print_creds(krb5_creds *creds, krb5_keyblock *secret_key)
+{
+ char *p, buf[BUFSIZ];
+
+ krb5_unparse_name(creds->client, &p);
+ printf("Client: %s\n", p);
+ free(p);
+ krb5_unparse_name(creds->server, &p);
+ printf("Server: %s\n", p);
+ free(p);
+ krb5_print_keyblock("Session key", &creds->keyblock);
+ krb5_print_times("Times", &creds->times);
+ printf("is_skey: %s\n", creds->is_skey ? "True" : "False");
+ printf("Flags: 0x%08x\n", creds->ticket_flags);
+ krb5_print_addrs(creds->addresses);
+ krb5_print_ticket(&creds->ticket, secret_key);
+ /* krb5_print_ticket(&creds->second_ticket, secret_key); */
+}
+
+void krb4_print_ticket(KTEXT ticket, krb5_keyblock *secret_key)
+{
+ char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
+ char sname[ANAME_SZ], sinst[INST_SZ];
+ unsigned char flags;
+ unsigned long addr, issue_time;
+ C_Block session_key;
+ int life;
+ Key_schedule keysched;
+
+ int ret;
+
+ if (des_key_sched(secret_key->contents, keysched)) {
+ fprintf(stderr, "Bug in DES key somewhere.\n");
+ exit(1);
+ }
+
+ ret = decomp_ticket(ticket, &flags, pname, pinst, prealm, &addr,
+ session_key, &life, &issue_time, sname,
+ sinst, secret_key->contents, keysched);
+ if (ret != KSUCCESS) {
+ fprintf(stderr, "krb4 decomp_ticket failed\n");
+ exit(1);
+ }
+ printf("Ticket: Client: %s.%s@%s\n", pname, pinst, prealm);
+ printf("Ticket: Service: %s.%s%\n", sname, sinst);
+ printf("Ticket: Address: %08x\n", addr);
+ print_key("Ticket: Session Key", session_key);
+ printf("Ticket: Lifetime: %d\n", life);
+ printf("Ticket: Issue Date: %d, %s", issue_time, ctime(&issue_time));
+}
+
+void krb4_print_creds(CREDENTIALS *creds, krb5_keyblock *secret_key)
+{
+ printf("Client: %s.%s@%s\n", creds->pname, creds->pinst,
+ creds->realm);
+ printf("Service: %s.%s@%s\n", creds->service, creds->instance,
+ creds->realm);
+ print_key("Session key", creds->session);
+ printf("Lifetime: %d\n", creds->lifetime);
+ printf("Key Version: %d\n", creds->kvno);
+ print_time("Issue Date", creds->issue_date);
+ krb4_print_ticket(&creds->ticket_st, secret_key);
+}
+
+usage()
+{
+ fprintf(stderr, "Usage: test [-remote server] client service\n");
+ exit(1);
+}
+
+main(int argc, char **argv)
+{
+ krb5_principal client, server;
+ krb5_ccache cc;
+ krb5_creds v5creds;
+ krb5_keyblock key;
+ char keybuf[KEYSIZE], buf[BUFSIZ];
+ int i, ret, local;
+ char *remote;
+
+ krb524_debug = 1;
+
+ krb524_init_ets();
+
+ local = 0;
+ remote = NULL;
+ argc--; argv++;
+ while (argc) {
+ if (strcmp(*argv, "-local") == 0)
+ local++;
+ else if (strcmp(*argv, "-remote") == 0) {
+ argc--; argv++;
+ if (!argc)
+ usage();
+ remote = *argv;
+ }
+ else
+ break;
+ argc--; argv++;
+ }
+ if (argc != 2)
+ usage();
+
+ if (ret = krb5_parse_name(argv[0], &client)) {
+ com_err("test", ret, "parsing client name");
+ exit(1);
+ }
+ if (ret = krb5_parse_name(argv[1], &server)) {
+ com_err("test", ret, "parsing server name");
+ exit(1);
+ }
+ if (ret = krb5_cc_default(&cc)) {
+ com_err("test", ret, "opening default credentials cache");
+ exit(1);
+ }
+
+ bzero((char *) &v5creds, sizeof(v5creds));
+ v5creds.client = client;
+ v5creds.server = server;
+ v5creds.times.endtime = 0;
+ v5creds.keyblock.keytype = KEYTYPE_DES;
+ if (ret = krb5_get_credentials(0, cc, &v5creds)) {
+ com_err("test", ret, "getting V5 credentials");
+ exit(1);
+ }
+
+ /* We need the service key in order to locally decrypt both */
+ /* tickets for testing */
+ printf("Service's key: ");
+ fflush(stdout);
+ fgets(buf, BUFSIZ, stdin);
+ for (i = 0; i < 8; i++) {
+ unsigned char c;
+ c = buf[2*i];
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'z')
+ c = c - 'a' + 0xa;
+ keybuf[i] = c << 4;
+ c = buf[2*i+1];
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'z')
+ c = c - 'a' + 0xa;
+ keybuf[i] += c;
+ }
+
+ key.keytype = KEYTYPE_DES;
+ key.length = KEYSIZE; /* presumably */
+ key.contents = keybuf;
+
+ do_remote(&v5creds, remote, &key);
+}
+
+void do_remote(krb5_creds *v5creds, char *server, krb5_keyblock *key)
+{
+ struct sockaddr_in saddr;
+ struct hostent *hp;
+ CREDENTIALS v4creds;
+ int ret;
+
+ printf("\nV5 credentials:\n");
+ krb5_print_creds(v5creds, key);
+
+ if (strcmp(server, "kdc") != 0) {
+ hp = gethostbyname(server);
+ if (hp == NULL) {
+ fprintf(stderr, "test: host %s does not exist.\n", server);
+ exit(1);
+ }
+ bzero((char *) &saddr, sizeof(struct sockaddr_in));
+ saddr.sin_family = AF_INET;
+ bcopy(hp->h_addr, (char *) &saddr.sin_addr.s_addr,
+ sizeof(struct in_addr));
+
+ if (ret = krb524_convert_creds_addr(v5creds, &v4creds, &saddr)) {
+ com_err("test", ret, "converting credentials on %s",
+ server);
+ exit(1);
+ }
+ } else {
+ if (ret = krb524_convert_creds_kdc(v5creds, &v4creds)) {
+ com_err("test", ret, "converting credentials via kdc");
+ exit(1);
+ }
+ }
+
+ printf("\nV4 credentials:\n");
+ krb4_print_creds(&v4creds, key);
+}