# PERFORMANCE OF THIS SOFTWARE.
#
-LIB=krb524
+LIBNAME=krb524
+##WIN32##!if 0
+LIB=$(LIBNAME)
+##WIN32##!endif
LIBMAJOR=1
LIBMINOR=0
RELDIR=../krb524
KRB524_DEPLIB = libkrb524.a
KRB524_LIB = libkrb524.a
+
+##WIN32##KRB4_INCLUDES = -I../../../krb4/krbv4/include -I../../../krb4/include
+##WIN32##K4LIB = ../../../krb4/krbv4/krbdll/$(OUTPRE)krbv4w32.lib
+###WIN32##K4LIB = ../lib/$(OUTPRE)krb4_32.lib
+K524DEF = krb524.def
+WINLIBS = kernel32.lib wsock32.lib user32.lib shell32.lib oldnames.lib \
+ version.lib advapi32.lib gdi32.lib
+
LOCALINCLUDES= $(KRB4_INCLUDES) -I. -I$(srcdir)
# Library sources
-SRCS = conv_creds.c conv_princ.c cnv_tkt_skey.c \
- encode.c misc.c globals.c sendmsg.c krb524_err.et
-STLIBOBJS = conv_creds.o conv_princ.o cnv_tkt_skey.o \
- encode.o misc.o globals.o sendmsg.o krb524_err.o
+SRCS = \
+ conv_creds.c \
+ conv_princ.c \
+ cnv_tkt_skey.c \
+ encode.c \
+ misc.c \
+ globals.c \
+ sendmsg.c \
+ krb524_err.et \
+ libinit.c
+
+STLIBOBJS = \
+ $(OUTPRE)conv_creds.$(OBJEXT) \
+ $(OUTPRE)conv_princ.$(OBJEXT) \
+ $(OUTPRE)cnv_tkt_skey.$(OBJEXT) \
+ $(OUTPRE)encode.$(OBJEXT) \
+ $(OUTPRE)misc.$(OBJEXT) \
+ $(OUTPRE)globals.$(OBJEXT) \
+ $(OUTPRE)sendmsg.$(OBJEXT) \
+ $(OUTPRE)krb524_err.$(OBJEXT) \
+ $(OUTPRE)libinit.$(OBJEXT)
GENS = krb524_err.c krb524_err.h
-all:: $(GENS)
-all:: all-libs
+all-unix:: $(GENS)
+all-unix:: all-libs
-all:: krb524d krb524test k524init
+all-unix:: krb524d krb524test k524init
+
+all-windows:: $(OUTPRE)$(LIBNAME).lib $(OUTPRE)k524init.exe
krb524test: libkrb524.a test.o $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
$(CC_LINK) -o krb524test test.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
k524init: k524init.o $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
$(CC_LINK) -o k524init k524init.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
-install:: install-libs
+$(OUTPRE)$(LIBNAME).lib: $(STLIBOBJS) $(K4LIB) $(KLIB)
+ link $(DLL_LINKOPTS) -def:$(K524DEF) -out:$*.dll $** $(WINLIBS)
+
+$(OUTPRE)k524init.exe: $(OUTPRE)k524init.$(OBJEXT) $(KLIB) $(K4LIB) $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib
+ link $(EXE_LINKOPTS) -out:$@ $** $(KLIB) $(K4LIB) $(WINLIBS) $(CLIB)\
+ $(OUTPRE)krb524.lib
+
+install-unix:: install-libs
$(INSTALL_PROGRAM) krb524d $(DESTDIR)$(SERVER_BINDIR)/krb524d
$(INSTALL_PROGRAM) k524init $(DESTDIR)$(CLIENT_BINDIR)/krb524init
-clean:: clean-libs clean-libobjs
+clean-unix:: clean-libs clean-libobjs
$(RM) $(OBJS) $(GENS) core *~ *.bak #*
$(RM) krb524test krb524d k524init test.o krb524d.o k524init.o
#include "k5-int.h" /* we need krb5_context::clockskew */
#include <stdio.h>
#include <sys/types.h>
+
+#ifndef _WIN32
#include <sys/time.h>
#include <netinet/in.h>
+#endif
+
#include <krb.h>
#include "krb524.h"
+static
+int
+krb524int_krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key, k5key);
+
+static
+int
+krb524int_krb_cr_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, k5key);
+
+static int
+krb524int_krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key, k5key);
+
/* rather than copying the cmu code, these values are derived from
a calculation based on the table and comments found there.
the expression (in elisp) is:
/* XXX are there V5 flags we should map to V4 equivalents? */
if (v4_skey->enctype == ENCTYPE_DES_CBC_CRC) {
- ret = krb_create_ticket(v4tkt,
+ ret = krb524int_krb_create_ticket(v4tkt,
0, /* flags */
pname,
pinst,
if (v4_skey->enctype == ENCTYPE_DES3_CBC_SHA1 ||
v4_skey->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1)
v4_skey->enctype = ENCTYPE_DES3_CBC_RAW;
- ret = krb_cr_tkt_krb5(v4tkt,
+ ret = krb524int_krb_cr_tkt_krb5(v4tkt,
0, /* flags */
pname,
pinst,
else
return KRB524_V4ERR;
}
+
+/*****************************************************************************
+ * Copied from krb4's cr_tkt.
+ * Modified functions below to be static.
+ *****************************************************************************/
+
+#define HOST_BYTE_ORDER (* (char *) &temp_ONE)
+static const int temp_ONE = 1;
+
+/*
+ * Create ticket takes as arguments information that should be in a
+ * ticket, and the KTEXT object in which the ticket should be
+ * constructed. It then constructs a ticket and returns, leaving the
+ * newly created ticket in tkt.
+#ifndef NOENCRYPTION
+ * The data in tkt->dat is encrypted in the server's key.
+#endif
+ * The length of the ticket is a multiple of
+ * eight bytes and is in tkt->length.
+ *
+ * If the ticket is too long, the ticket will contain nulls.
+ * The return value of the routine is undefined.
+ *
+ * The corresponding routine to extract information from a ticket it
+ * decomp_ticket. When changes are made to this routine, the
+ * corresponding changes should also be made to that file.
+ *
+ * The packet is built in the following format:
+ *
+ * variable
+ * type or constant data
+ * ---- ----------- ----
+ *
+ * tkt->length length of ticket (multiple of 8 bytes)
+ *
+#ifdef NOENCRYPTION
+ * tkt->dat:
+#else
+ * tkt->dat: (encrypted in server's key)
+#endif
+ *
+ * unsigned char flags namely, HOST_BYTE_ORDER
+ *
+ * string pname client's name
+ *
+ * string pinstance client's instance
+ *
+ * string prealm client's realm
+ *
+ * 4 bytes paddress client's address
+ *
+ * 8 bytes session session key
+ *
+ * 1 byte life ticket lifetime
+ *
+ * 4 bytes time_sec KDC timestamp
+ *
+ * string sname service's name
+ *
+ * string sinstance service's instance
+ *
+ * <=7 bytes null null pad to 8 byte multiple
+ *
+ */
+static
+int
+krb524int_krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key, k5key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ C_Block key; /* Service's secret key */
+{
+ return krb524int_krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm,
+ paddress, session, life, time_sec, sname,
+ sinstance, key, NULL);
+}
+
+static
+int
+krb524int_krb_cr_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, k5key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ krb5_keyblock *k5key; /* NULL if not present */
+{
+ C_Block key;
+
+ return krb524int_krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm,
+ paddress, session, life, time_sec, sname,
+ sinstance, key, k5key);
+}
+
+static int
+krb524int_krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress,
+ session, life, time_sec, sname, sinstance, key, k5key)
+ KTEXT tkt; /* Gets filled in by the ticket */
+ unsigned char flags; /* Various Kerberos flags */
+ char *pname; /* Principal's name */
+ char *pinstance; /* Principal's instance */
+ char *prealm; /* Principal's authentication domain */
+ long paddress; /* Net address of requesting entity */
+ char *session; /* Session key inserted in ticket */
+ short life; /* Lifetime of the ticket */
+ long time_sec; /* Issue time and date */
+ char *sname; /* Service Name */
+ char *sinstance; /* Instance Name */
+ C_Block key; /* Service's secret key */
+ krb5_keyblock *k5key; /* NULL if not present */
+{
+ Key_schedule key_s;
+ register char *data; /* running index into ticket */
+
+ tkt->length = 0; /* Clear previous data */
+
+ /* Check length of ticket */
+ if (sizeof(tkt->dat) < (sizeof(flags) +
+ 1 + strlen(pname) +
+ 1 + strlen(pinstance) +
+ 1 + strlen(prealm) +
+ 4 + /* address */
+ 8 + /* session */
+ 1 + /* life */
+ 4 + /* issue time */
+ 1 + strlen(sname) +
+ 1 + strlen(sinstance) +
+ 7) / 8) { /* roundoff */
+ memset(tkt->dat, 0, sizeof(tkt->dat));
+ return KFAILURE /* XXX */;
+ }
+
+ flags |= HOST_BYTE_ORDER; /* ticket byte order */
+ memcpy((char *) (tkt->dat), (char *) &flags, sizeof(flags));
+ data = ((char *)tkt->dat) + sizeof(flags);
+ (void) strcpy(data, pname);
+ data += 1 + strlen(pname);
+ (void) strcpy(data, pinstance);
+ data += 1 + strlen(pinstance);
+ (void) strcpy(data, prealm);
+ data += 1 + strlen(prealm);
+ memcpy(data, (char *) &paddress, 4);
+ data += 4;
+
+ memcpy(data, (char *) session, 8);
+ data += 8;
+ *(data++) = (char) life;
+ /* issue time */
+ memcpy(data, (char *) &time_sec, 4);
+ data += 4;
+ (void) strcpy(data, sname);
+ data += 1 + strlen(sname);
+ (void) strcpy(data, sinstance);
+ data += 1 + strlen(sinstance);
+
+ /* guarantee null padded ticket to multiple of 8 bytes */
+ memset(data, 0, 7);
+ tkt->length = ((data - ((char *)tkt->dat) + 7)/8)*8;
+
+ /* Check length of ticket */
+ if (tkt->length > (sizeof(KTEXT_ST) - 7)) {
+ memset(tkt->dat, 0, tkt->length);
+ tkt->length = 0;
+ return KFAILURE /* XXX */;
+ }
+
+#ifndef NOENCRYPTION
+ /* Encrypt the ticket in the services key */
+ if (k5key != NULL) {
+ /* block locals */
+ krb5_data in;
+ krb5_enc_data out;
+ krb5_error_code ret;
+ size_t enclen;
+
+ in.length = tkt->length;
+ in.data = tkt->dat;
+ /* XXX assumes context arg is ignored */
+ ret = krb5_c_encrypt_length(NULL, k5key->enctype,
+ (size_t)in.length, &enclen);
+ if (ret)
+ return KFAILURE;
+ out.ciphertext.length = enclen;
+ out.ciphertext.data = malloc(enclen);
+ if (out.ciphertext.data == NULL)
+ return KFAILURE; /* XXX maybe ENOMEM? */
+
+ /* XXX assumes context arg is ignored */
+ ret = krb5_c_encrypt(NULL, k5key, KRB5_KEYUSAGE_KDC_REP_TICKET,
+ NULL, &in, &out);
+ if (ret) {
+ free(out.ciphertext.data);
+ return KFAILURE;
+ } else {
+ tkt->length = out.ciphertext.length;
+ memcpy(tkt->dat, out.ciphertext.data, out.ciphertext.length);
+ memset(out.ciphertext.data, 0, out.ciphertext.length);
+ free(out.ciphertext.data);
+ }
+ } else {
+ key_sched(key,key_s);
+ pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat,
+ (long) tkt->length,key_s,(C_Block *)key,1);
+ }
+#endif /* !NOENCRYPTION */
+ return 0;
+}