summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/krb5
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2000-01-09 20:58:00 +0000
committermarkm <markm@FreeBSD.org>2000-01-09 20:58:00 +0000
commit4ecbd6db44d79348bc815f31096e53104f50838b (patch)
tree36fa73706fa0587a390c45a3fbf17c9523cb0e35 /crypto/heimdal/lib/krb5
downloadFreeBSD-src-4ecbd6db44d79348bc815f31096e53104f50838b.zip
FreeBSD-src-4ecbd6db44d79348bc815f31096e53104f50838b.tar.gz
Import KTH Heimdal, which will be the core of our Kerberos5.
Userland to follow.
Diffstat (limited to 'crypto/heimdal/lib/krb5')
-rw-r--r--crypto/heimdal/lib/krb5/Makefile.am148
-rw-r--r--crypto/heimdal/lib/krb5/Makefile.in956
-rw-r--r--crypto/heimdal/lib/krb5/add_et_list.c50
-rw-r--r--crypto/heimdal/lib/krb5/addr_families.c544
-rw-r--r--crypto/heimdal/lib/krb5/address.c197
-rw-r--r--crypto/heimdal/lib/krb5/aname_to_localname.c76
-rw-r--r--crypto/heimdal/lib/krb5/asn1_glue.c59
-rw-r--r--crypto/heimdal/lib/krb5/auth_context.c426
-rw-r--r--crypto/heimdal/lib/krb5/build_ap_req.c79
-rw-r--r--crypto/heimdal/lib/krb5/build_auth.c156
-rw-r--r--crypto/heimdal/lib/krb5/cache.c422
-rw-r--r--crypto/heimdal/lib/krb5/changepw.c346
-rw-r--r--crypto/heimdal/lib/krb5/codec.c251
-rw-r--r--crypto/heimdal/lib/krb5/config_file.c750
-rw-r--r--crypto/heimdal/lib/krb5/config_file_netinfo.c178
-rw-r--r--crypto/heimdal/lib/krb5/constants.c39
-rw-r--r--crypto/heimdal/lib/krb5/context.c357
-rw-r--r--crypto/heimdal/lib/krb5/convert_creds.c215
-rw-r--r--crypto/heimdal/lib/krb5/copy_host_realm.c66
-rw-r--r--crypto/heimdal/lib/krb5/crc.c71
-rw-r--r--crypto/heimdal/lib/krb5/creds.c149
-rw-r--r--crypto/heimdal/lib/krb5/crypto.c2314
-rw-r--r--crypto/heimdal/lib/krb5/data.c109
-rw-r--r--crypto/heimdal/lib/krb5/dump_config.c71
-rw-r--r--crypto/heimdal/lib/krb5/expand_hostname.c80
-rw-r--r--crypto/heimdal/lib/krb5/fcache.c431
-rw-r--r--crypto/heimdal/lib/krb5/free.c52
-rw-r--r--crypto/heimdal/lib/krb5/free_host_realm.c54
-rw-r--r--crypto/heimdal/lib/krb5/generate_seq_number.c62
-rw-r--r--crypto/heimdal/lib/krb5/generate_subkey.c52
-rw-r--r--crypto/heimdal/lib/krb5/get_addrs.c310
-rw-r--r--crypto/heimdal/lib/krb5/get_cred.c776
-rw-r--r--crypto/heimdal/lib/krb5/get_default_principal.c67
-rw-r--r--crypto/heimdal/lib/krb5/get_default_realm.c80
-rw-r--r--crypto/heimdal/lib/krb5/get_for_creds.c287
-rw-r--r--crypto/heimdal/lib/krb5/get_host_realm.c194
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt.c794
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt_pw.c87
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c103
-rw-r--r--crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c82
-rw-r--r--crypto/heimdal/lib/krb5/get_port.c52
-rw-r--r--crypto/heimdal/lib/krb5/heim_err.et18
-rw-r--r--crypto/heimdal/lib/krb5/init_creds.c111
-rw-r--r--crypto/heimdal/lib/krb5/init_creds_pw.c547
-rw-r--r--crypto/heimdal/lib/krb5/keyblock.c77
-rw-r--r--crypto/heimdal/lib/krb5/keytab.c407
-rw-r--r--crypto/heimdal/lib/krb5/keytab_file.c540
-rw-r--r--crypto/heimdal/lib/krb5/keytab_keyfile.c316
-rw-r--r--crypto/heimdal/lib/krb5/keytab_krb4.c272
-rw-r--r--crypto/heimdal/lib/krb5/keytab_memory.c161
-rw-r--r--crypto/heimdal/lib/krb5/krb5-private.h58
-rw-r--r--crypto/heimdal/lib/krb5/krb5-protos.h2352
-rw-r--r--crypto/heimdal/lib/krb5/krb5.conf.5167
-rw-r--r--crypto/heimdal/lib/krb5/krb5.h600
-rw-r--r--crypto/heimdal/lib/krb5/krb5_425_conv_principal.3198
-rw-r--r--crypto/heimdal/lib/krb5/krb5_build_principal.378
-rw-r--r--crypto/heimdal/lib/krb5/krb5_create_checksum.368
-rw-r--r--crypto/heimdal/lib/krb5/krb5_crypto_init.341
-rw-r--r--crypto/heimdal/lib/krb5/krb5_encrypt.360
-rw-r--r--crypto/heimdal/lib/krb5/krb5_err.et215
-rw-r--r--crypto/heimdal/lib/krb5/krb5_free_principal.330
-rw-r--r--crypto/heimdal/lib/krb5/krb5_locl.h136
-rw-r--r--crypto/heimdal/lib/krb5/krb5_openlog.3225
-rw-r--r--crypto/heimdal/lib/krb5/krb5_parse_name.339
-rw-r--r--crypto/heimdal/lib/krb5/krb5_sname_to_principal.358
-rw-r--r--crypto/heimdal/lib/krb5/krb5_unparse_name.334
-rw-r--r--crypto/heimdal/lib/krb5/krb5_warn.373
-rw-r--r--crypto/heimdal/lib/krb5/krbhst.c196
-rw-r--r--crypto/heimdal/lib/krb5/kuserok.c108
-rw-r--r--crypto/heimdal/lib/krb5/log.c426
-rw-r--r--crypto/heimdal/lib/krb5/mcache.c227
-rw-r--r--crypto/heimdal/lib/krb5/misc.c36
-rw-r--r--crypto/heimdal/lib/krb5/mk_error.c124
-rw-r--r--crypto/heimdal/lib/krb5/mk_priv.c168
-rw-r--r--crypto/heimdal/lib/krb5/mk_rep.c116
-rw-r--r--crypto/heimdal/lib/krb5/mk_req.c102
-rw-r--r--crypto/heimdal/lib/krb5/mk_req_ext.c151
-rw-r--r--crypto/heimdal/lib/krb5/mk_safe.c115
-rw-r--r--crypto/heimdal/lib/krb5/n-fold-test.c104
-rw-r--r--crypto/heimdal/lib/krb5/n-fold.c126
-rw-r--r--crypto/heimdal/lib/krb5/net_read.c47
-rw-r--r--crypto/heimdal/lib/krb5/net_write.c47
-rw-r--r--crypto/heimdal/lib/krb5/padata.c45
-rw-r--r--crypto/heimdal/lib/krb5/principal.c898
-rw-r--r--crypto/heimdal/lib/krb5/prog_setup.c62
-rw-r--r--crypto/heimdal/lib/krb5/prompter_posix.c70
-rw-r--r--crypto/heimdal/lib/krb5/rd_cred.c185
-rw-r--r--crypto/heimdal/lib/krb5/rd_error.c66
-rw-r--r--crypto/heimdal/lib/krb5/rd_priv.c150
-rw-r--r--crypto/heimdal/lib/krb5/rd_rep.c108
-rw-r--r--crypto/heimdal/lib/krb5/rd_req.c441
-rw-r--r--crypto/heimdal/lib/krb5/rd_safe.c172
-rw-r--r--crypto/heimdal/lib/krb5/read_message.c63
-rw-r--r--crypto/heimdal/lib/krb5/recvauth.c190
-rw-r--r--crypto/heimdal/lib/krb5/replay.c224
-rw-r--r--crypto/heimdal/lib/krb5/send_to_kdc.c395
-rw-r--r--crypto/heimdal/lib/krb5/sendauth.c208
-rw-r--r--crypto/heimdal/lib/krb5/set_default_realm.c87
-rw-r--r--crypto/heimdal/lib/krb5/sock_principal.c74
-rw-r--r--crypto/heimdal/lib/krb5/store.c609
-rw-r--r--crypto/heimdal/lib/krb5/store_emem.c126
-rw-r--r--crypto/heimdal/lib/krb5/store_fd.c74
-rw-r--r--crypto/heimdal/lib/krb5/store_mem.c117
-rw-r--r--crypto/heimdal/lib/krb5/string-to-key-test.c106
-rw-r--r--crypto/heimdal/lib/krb5/ticket.c74
-rw-r--r--crypto/heimdal/lib/krb5/time.c58
-rw-r--r--crypto/heimdal/lib/krb5/transited.c382
-rw-r--r--crypto/heimdal/lib/krb5/verify_init.c196
-rw-r--r--crypto/heimdal/lib/krb5/verify_krb5_conf.c102
-rw-r--r--crypto/heimdal/lib/krb5/verify_user.c170
-rw-r--r--crypto/heimdal/lib/krb5/version.c43
-rw-r--r--crypto/heimdal/lib/krb5/warn.c193
-rw-r--r--crypto/heimdal/lib/krb5/write_message.c55
113 files changed, 26309 insertions, 0 deletions
diff --git a/crypto/heimdal/lib/krb5/Makefile.am b/crypto/heimdal/lib/krb5/Makefile.am
new file mode 100644
index 0000000..17551cb
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/Makefile.am
@@ -0,0 +1,148 @@
+# $Id: Makefile.am,v 1.95 2000/01/08 17:03:51 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = verify_krb5_conf
+
+noinst_PROGRAMS = dump_config
+
+check_PROGRAMS = n-fold-test string-to-key-test
+TESTS = n-fold-test string-to-key-test
+
+if KRB4
+KRB4LIB = $(LIB_krb4)
+keytab_krb4_c = keytab_krb4.c
+endif
+
+LDADD = libkrb5.la \
+ $(KRB4LIB) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+lib_LTLIBRARIES = libkrb5.la
+
+ERR_FILES = krb5_err.c heim_err.c
+
+libkrb5_la_SOURCES = \
+ add_et_list.c \
+ addr_families.c \
+ address.c \
+ aname_to_localname.c \
+ asn1_glue.c \
+ auth_context.c \
+ build_ap_req.c \
+ build_auth.c \
+ cache.c \
+ changepw.c \
+ codec.c \
+ config_file.c \
+ config_file_netinfo.c \
+ convert_creds.c \
+ constants.c \
+ context.c \
+ copy_host_realm.c \
+ crc.c \
+ creds.c \
+ crypto.c \
+ data.c \
+ expand_hostname.c \
+ fcache.c \
+ free.c \
+ free_host_realm.c \
+ generate_seq_number.c \
+ generate_subkey.c \
+ get_addrs.c \
+ get_cred.c \
+ get_default_principal.c \
+ get_default_realm.c \
+ get_for_creds.c \
+ get_host_realm.c \
+ get_in_tkt.c \
+ get_in_tkt_pw.c \
+ get_in_tkt_with_keytab.c \
+ get_in_tkt_with_skey.c \
+ get_port.c \
+ init_creds.c \
+ init_creds_pw.c \
+ keyblock.c \
+ keytab.c \
+ keytab_file.c \
+ keytab_memory.c \
+ $(keytab_krb4_c) \
+ keytab_keyfile.c \
+ krbhst.c \
+ kuserok.c \
+ log.c \
+ mcache.c \
+ misc.c \
+ mk_error.c \
+ mk_priv.c \
+ mk_rep.c \
+ mk_req.c \
+ mk_req_ext.c \
+ mk_safe.c \
+ net_read.c \
+ net_write.c \
+ n-fold.c \
+ padata.c \
+ principal.c \
+ prog_setup.c \
+ prompter_posix.c \
+ rd_cred.c \
+ rd_error.c \
+ rd_priv.c \
+ rd_rep.c \
+ rd_req.c \
+ rd_safe.c \
+ read_message.c \
+ recvauth.c \
+ send_to_kdc.c \
+ sendauth.c \
+ set_default_realm.c \
+ sock_principal.c \
+ store.c \
+ store_emem.c \
+ store_fd.c \
+ store_mem.c \
+ ticket.c \
+ time.c \
+ transited.c \
+ verify_init.c \
+ verify_user.c \
+ version.c \
+ warn.c \
+ write_message.c \
+ $(ERR_FILES)
+
+EXTRA_libkrb5_la_SOURCES = keytab_krb4.c
+
+libkrb5_la_LDFLAGS = -version-info 7:1:0
+
+$(libkrb5_la_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h
+
+$(srcdir)/krb5-protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o krb5-protos.h $(libkrb5_la_SOURCES) || rm -f krb5-protos.h
+
+$(srcdir)/krb5-private.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -p krb5-private.h $(libkrb5_la_SOURCES) || rm -f krb5-private.h
+
+libkrb5_la_LIBADD = ../com_err/error.lo ../com_err/com_err.lo
+
+man_MANS = krb5.conf.5 krb5_warn.3 krb5_openlog.3 \
+ krb5_425_conv_principal.3 krb5_build_principal.3 krb5_free_principal.3 \
+ krb5_parse_name.3 krb5_sname_to_principal.3 krb5_unparse_name.3
+
+include_HEADERS = krb5.h krb5-protos.h krb5-private.h krb5_err.h heim_err.h
+
+CLEANFILES = krb5_err.c krb5_err.h heim_err.c heim_err.h
+
+$(libkrb5_la_OBJECTS): krb5_err.h heim_err.h
+
+# to help stupid solaris make
+
+krb5_err.h: krb5_err.et
+
+heim_err.h: heim_err.et
diff --git a/crypto/heimdal/lib/krb5/Makefile.in b/crypto/heimdal/lib/krb5/Makefile.in
new file mode 100644
index 0000000..6f3652e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/Makefile.in
@@ -0,0 +1,956 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile.am,v 1.95 2000/01/08 17:03:51 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = verify_krb5_conf
+
+noinst_PROGRAMS = dump_config
+
+check_PROGRAMS = n-fold-test string-to-key-test
+TESTS = n-fold-test string-to-key-test
+
+@KRB4_TRUE@KRB4LIB = $(LIB_krb4)
+@KRB4_TRUE@keytab_krb4_c = keytab_krb4.c
+
+LDADD = libkrb5.la $(KRB4LIB) $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken)
+
+
+lib_LTLIBRARIES = libkrb5.la
+
+ERR_FILES = krb5_err.c heim_err.c
+
+libkrb5_la_SOURCES = add_et_list.c addr_families.c address.c aname_to_localname.c asn1_glue.c auth_context.c build_ap_req.c build_auth.c cache.c changepw.c codec.c config_file.c config_file_netinfo.c convert_creds.c constants.c context.c copy_host_realm.c crc.c creds.c crypto.c data.c expand_hostname.c fcache.c free.c free_host_realm.c generate_seq_number.c generate_subkey.c get_addrs.c get_cred.c get_default_principal.c get_default_realm.c get_for_creds.c get_host_realm.c get_in_tkt.c get_in_tkt_pw.c get_in_tkt_with_keytab.c get_in_tkt_with_skey.c get_port.c init_creds.c init_creds_pw.c keyblock.c keytab.c keytab_file.c keytab_memory.c $(keytab_krb4_c) keytab_keyfile.c krbhst.c kuserok.c log.c mcache.c misc.c mk_error.c mk_priv.c mk_rep.c mk_req.c mk_req_ext.c mk_safe.c net_read.c net_write.c n-fold.c padata.c principal.c prog_setup.c prompter_posix.c rd_cred.c rd_error.c rd_priv.c rd_rep.c rd_req.c rd_safe.c read_message.c recvauth.c send_to_kdc.c sendauth.c set_default_realm.c sock_principal.c store.c store_emem.c store_fd.c store_mem.c ticket.c time.c transited.c verify_init.c verify_user.c version.c warn.c write_message.c $(ERR_FILES)
+
+
+EXTRA_libkrb5_la_SOURCES = keytab_krb4.c
+
+libkrb5_la_LDFLAGS = -version-info 7:1:0
+
+libkrb5_la_LIBADD = ../com_err/error.lo ../com_err/com_err.lo
+
+man_MANS = krb5.conf.5 krb5_warn.3 krb5_openlog.3 krb5_425_conv_principal.3 krb5_build_principal.3 krb5_free_principal.3 krb5_parse_name.3 krb5_sname_to_principal.3 krb5_unparse_name.3
+
+
+include_HEADERS = krb5.h krb5-protos.h krb5-private.h krb5_err.h heim_err.h
+
+CLEANFILES = krb5_err.c krb5_err.h heim_err.c heim_err.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libkrb5_la_DEPENDENCIES = ../com_err/error.lo ../com_err/com_err.lo
+@KRB4_TRUE@libkrb5_la_OBJECTS = add_et_list.lo addr_families.lo \
+@KRB4_TRUE@address.lo aname_to_localname.lo asn1_glue.lo \
+@KRB4_TRUE@auth_context.lo build_ap_req.lo build_auth.lo cache.lo \
+@KRB4_TRUE@changepw.lo codec.lo config_file.lo config_file_netinfo.lo \
+@KRB4_TRUE@convert_creds.lo constants.lo context.lo copy_host_realm.lo \
+@KRB4_TRUE@crc.lo creds.lo crypto.lo data.lo expand_hostname.lo \
+@KRB4_TRUE@fcache.lo free.lo free_host_realm.lo generate_seq_number.lo \
+@KRB4_TRUE@generate_subkey.lo get_addrs.lo get_cred.lo \
+@KRB4_TRUE@get_default_principal.lo get_default_realm.lo \
+@KRB4_TRUE@get_for_creds.lo get_host_realm.lo get_in_tkt.lo \
+@KRB4_TRUE@get_in_tkt_pw.lo get_in_tkt_with_keytab.lo \
+@KRB4_TRUE@get_in_tkt_with_skey.lo get_port.lo init_creds.lo \
+@KRB4_TRUE@init_creds_pw.lo keyblock.lo keytab.lo keytab_file.lo \
+@KRB4_TRUE@keytab_memory.lo keytab_krb4.lo keytab_keyfile.lo krbhst.lo \
+@KRB4_TRUE@kuserok.lo log.lo mcache.lo misc.lo mk_error.lo mk_priv.lo \
+@KRB4_TRUE@mk_rep.lo mk_req.lo mk_req_ext.lo mk_safe.lo net_read.lo \
+@KRB4_TRUE@net_write.lo n-fold.lo padata.lo principal.lo prog_setup.lo \
+@KRB4_TRUE@prompter_posix.lo rd_cred.lo rd_error.lo rd_priv.lo \
+@KRB4_TRUE@rd_rep.lo rd_req.lo rd_safe.lo read_message.lo recvauth.lo \
+@KRB4_TRUE@send_to_kdc.lo sendauth.lo set_default_realm.lo \
+@KRB4_TRUE@sock_principal.lo store.lo store_emem.lo store_fd.lo \
+@KRB4_TRUE@store_mem.lo ticket.lo time.lo transited.lo verify_init.lo \
+@KRB4_TRUE@verify_user.lo version.lo warn.lo write_message.lo \
+@KRB4_TRUE@krb5_err.lo heim_err.lo
+@KRB4_FALSE@libkrb5_la_OBJECTS = add_et_list.lo addr_families.lo \
+@KRB4_FALSE@address.lo aname_to_localname.lo asn1_glue.lo \
+@KRB4_FALSE@auth_context.lo build_ap_req.lo build_auth.lo cache.lo \
+@KRB4_FALSE@changepw.lo codec.lo config_file.lo config_file_netinfo.lo \
+@KRB4_FALSE@convert_creds.lo constants.lo context.lo copy_host_realm.lo \
+@KRB4_FALSE@crc.lo creds.lo crypto.lo data.lo expand_hostname.lo \
+@KRB4_FALSE@fcache.lo free.lo free_host_realm.lo generate_seq_number.lo \
+@KRB4_FALSE@generate_subkey.lo get_addrs.lo get_cred.lo \
+@KRB4_FALSE@get_default_principal.lo get_default_realm.lo \
+@KRB4_FALSE@get_for_creds.lo get_host_realm.lo get_in_tkt.lo \
+@KRB4_FALSE@get_in_tkt_pw.lo get_in_tkt_with_keytab.lo \
+@KRB4_FALSE@get_in_tkt_with_skey.lo get_port.lo init_creds.lo \
+@KRB4_FALSE@init_creds_pw.lo keyblock.lo keytab.lo keytab_file.lo \
+@KRB4_FALSE@keytab_memory.lo keytab_keyfile.lo krbhst.lo kuserok.lo \
+@KRB4_FALSE@log.lo mcache.lo misc.lo mk_error.lo mk_priv.lo mk_rep.lo \
+@KRB4_FALSE@mk_req.lo mk_req_ext.lo mk_safe.lo net_read.lo net_write.lo \
+@KRB4_FALSE@n-fold.lo padata.lo principal.lo prog_setup.lo \
+@KRB4_FALSE@prompter_posix.lo rd_cred.lo rd_error.lo rd_priv.lo \
+@KRB4_FALSE@rd_rep.lo rd_req.lo rd_safe.lo read_message.lo recvauth.lo \
+@KRB4_FALSE@send_to_kdc.lo sendauth.lo set_default_realm.lo \
+@KRB4_FALSE@sock_principal.lo store.lo store_emem.lo store_fd.lo \
+@KRB4_FALSE@store_mem.lo ticket.lo time.lo transited.lo verify_init.lo \
+@KRB4_FALSE@verify_user.lo version.lo warn.lo write_message.lo \
+@KRB4_FALSE@krb5_err.lo heim_err.lo
+bin_PROGRAMS = verify_krb5_conf$(EXEEXT)
+check_PROGRAMS = n-fold-test$(EXEEXT) string-to-key-test$(EXEEXT)
+noinst_PROGRAMS = dump_config$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+verify_krb5_conf_SOURCES = verify_krb5_conf.c
+verify_krb5_conf_OBJECTS = verify_krb5_conf.$(OBJEXT)
+verify_krb5_conf_LDADD = $(LDADD)
+@KRB4_TRUE@verify_krb5_conf_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@verify_krb5_conf_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+verify_krb5_conf_LDFLAGS =
+n_fold_test_SOURCES = n-fold-test.c
+n_fold_test_OBJECTS = n-fold-test.$(OBJEXT)
+n_fold_test_LDADD = $(LDADD)
+@KRB4_TRUE@n_fold_test_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@n_fold_test_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+n_fold_test_LDFLAGS =
+string_to_key_test_SOURCES = string-to-key-test.c
+string_to_key_test_OBJECTS = string-to-key-test.$(OBJEXT)
+string_to_key_test_LDADD = $(LDADD)
+@KRB4_TRUE@string_to_key_test_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@string_to_key_test_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+string_to_key_test_LDFLAGS =
+dump_config_SOURCES = dump_config.c
+dump_config_OBJECTS = dump_config.$(OBJEXT)
+dump_config_LDADD = $(LDADD)
+@KRB4_TRUE@dump_config_DEPENDENCIES = libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@dump_config_DEPENDENCIES = libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+dump_config_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+man3dir = $(mandir)/man3
+man5dir = $(mandir)/man5
+MANS = $(man_MANS)
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libkrb5_la_SOURCES) $(EXTRA_libkrb5_la_SOURCES) verify_krb5_conf.c n-fold-test.c string-to-key-test.c dump_config.c
+OBJECTS = $(libkrb5_la_OBJECTS) verify_krb5_conf.$(OBJEXT) n-fold-test.$(OBJEXT) string-to-key-test.$(OBJEXT) dump_config.$(OBJEXT)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/krb5/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libkrb5.la: $(libkrb5_la_OBJECTS) $(libkrb5_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libkrb5_la_LDFLAGS) $(libkrb5_la_OBJECTS) $(libkrb5_la_LIBADD) $(LIBS)
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+verify_krb5_conf$(EXEEXT): $(verify_krb5_conf_OBJECTS) $(verify_krb5_conf_DEPENDENCIES)
+ @rm -f verify_krb5_conf$(EXEEXT)
+ $(LINK) $(verify_krb5_conf_LDFLAGS) $(verify_krb5_conf_OBJECTS) $(verify_krb5_conf_LDADD) $(LIBS)
+
+n-fold-test$(EXEEXT): $(n_fold_test_OBJECTS) $(n_fold_test_DEPENDENCIES)
+ @rm -f n-fold-test$(EXEEXT)
+ $(LINK) $(n_fold_test_LDFLAGS) $(n_fold_test_OBJECTS) $(n_fold_test_LDADD) $(LIBS)
+
+string-to-key-test$(EXEEXT): $(string_to_key_test_OBJECTS) $(string_to_key_test_DEPENDENCIES)
+ @rm -f string-to-key-test$(EXEEXT)
+ $(LINK) $(string_to_key_test_LDFLAGS) $(string_to_key_test_OBJECTS) $(string_to_key_test_LDADD) $(LIBS)
+
+dump_config$(EXEEXT): $(dump_config_OBJECTS) $(dump_config_DEPENDENCIES)
+ @rm -f dump_config$(EXEEXT)
+ $(LINK) $(dump_config_LDFLAGS) $(dump_config_OBJECTS) $(dump_config_LDADD) $(LIBS)
+
+install-man3:
+ $(mkinstalldirs) $(DESTDIR)$(man3dir)
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+uninstall-man3:
+ @list='$(man3_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man3dir)/$$inst; \
+ done
+
+install-man5:
+ $(mkinstalldirs) $(DESTDIR)$(man5dir)
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \
+ done
+
+uninstall-man5:
+ @list='$(man5_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man5dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man3 install-man5
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man3 uninstall-man5
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib/krb5
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+check-TESTS: $(TESTS)
+ @failed=0; all=0; \
+ srcdir=$(srcdir); export srcdir; \
+ for tst in $(TESTS); do \
+ if test -f $$tst; then dir=.; \
+ else dir="$(srcdir)"; fi; \
+ if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \
+ all=`expr $$all + 1`; \
+ echo "PASS: $$tst"; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-man install-includeHEADERS install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS \
+ uninstall-man uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(mandir)/man3 $(DESTDIR)$(mandir)/man5 \
+ $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-binPROGRAMS \
+ mostlyclean-checkPROGRAMS mostlyclean-noinstPROGRAMS \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-binPROGRAMS clean-checkPROGRAMS \
+ clean-noinstPROGRAMS clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-binPROGRAMS \
+ distclean-checkPROGRAMS distclean-noinstPROGRAMS \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-binPROGRAMS \
+ maintainer-clean-checkPROGRAMS \
+ maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-binPROGRAMS distclean-binPROGRAMS \
+clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
+install-binPROGRAMS mostlyclean-checkPROGRAMS distclean-checkPROGRAMS \
+clean-checkPROGRAMS maintainer-clean-checkPROGRAMS \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS install-man3 \
+uninstall-man3 install-man5 uninstall-man5 install-man uninstall-man \
+uninstall-includeHEADERS install-includeHEADERS tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir check-TESTS \
+info-am info dvi-am dvi check-local check check-am installcheck-am \
+installcheck install-exec-am install-exec install-data-local \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-local all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+$(libkrb5_la_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h
+
+$(srcdir)/krb5-protos.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -o krb5-protos.h $(libkrb5_la_SOURCES) || rm -f krb5-protos.h
+
+$(srcdir)/krb5-private.h:
+ cd $(srcdir); perl ../../cf/make-proto.pl -p krb5-private.h $(libkrb5_la_SOURCES) || rm -f krb5-private.h
+
+$(libkrb5_la_OBJECTS): krb5_err.h heim_err.h
+
+# to help stupid solaris make
+
+krb5_err.h: krb5_err.et
+
+heim_err.h: heim_err.et
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/krb5/add_et_list.c b/crypto/heimdal/lib/krb5/add_et_list.c
new file mode 100644
index 0000000..cfc42f4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/add_et_list.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: add_et_list.c,v 1.2 1999/12/02 17:05:07 joda Exp $");
+
+/*
+ * Add a specified list of error messages to the et list in context.
+ * Call func (probably a comerr-generated function) with a pointer to
+ * the current et_list.
+ */
+
+krb5_error_code
+krb5_add_et_list (krb5_context context,
+ void (*func)(struct et_list **))
+{
+ (*func)(&context->et_list);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/addr_families.c b/crypto/heimdal/lib/krb5/addr_families.c
new file mode 100644
index 0000000..e8214ba
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/addr_families.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: addr_families.c,v 1.22 1999/12/04 17:53:33 assar Exp $");
+
+struct addr_operations {
+ int af;
+ krb5_address_type atype;
+ size_t max_sockaddr_size;
+ krb5_error_code (*sockaddr2addr)(const struct sockaddr *, krb5_address *);
+ krb5_error_code (*sockaddr2port)(const struct sockaddr *, int16_t *);
+ void (*addr2sockaddr)(const krb5_address *, struct sockaddr *,
+ int *sa_size, int port);
+ void (*h_addr2sockaddr)(const char *, struct sockaddr *, int *, int);
+ krb5_error_code (*h_addr2addr)(const char *, krb5_address *);
+ krb5_boolean (*uninteresting)(const struct sockaddr *);
+ void (*anyaddr)(struct sockaddr *, int *, int);
+ int (*print_addr)(const krb5_address *, char *, size_t);
+ int (*parse_addr)(const char*, krb5_address *);
+};
+
+/*
+ * AF_INET - aka IPv4 implementation
+ */
+
+static krb5_error_code
+ipv4_sockaddr2addr (const struct sockaddr *sa, krb5_address *a)
+{
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+ unsigned char buf[4];
+
+ a->addr_type = KRB5_ADDRESS_INET;
+ memcpy (buf, &sin->sin_addr, 4);
+ return krb5_data_copy(&a->address, buf, 4);
+}
+
+static krb5_error_code
+ipv4_sockaddr2port (const struct sockaddr *sa, int16_t *port)
+{
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+
+ *port = sin->sin_port;
+ return 0;
+}
+
+static void
+ipv4_addr2sockaddr (const krb5_address *a,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ memcpy (&sin->sin_addr, a->address.data, 4);
+ sin->sin_port = port;
+ *sa_size = sizeof(*sin);
+}
+
+static void
+ipv4_h_addr2sockaddr(const char *addr,
+ struct sockaddr *sa, int *sa_size, int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ *sa_size = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ sin->sin_addr = *((const struct in_addr *)addr);
+}
+
+static krb5_error_code
+ipv4_h_addr2addr (const char *addr,
+ krb5_address *a)
+{
+ unsigned char buf[4];
+
+ a->addr_type = KRB5_ADDRESS_INET;
+ memcpy(buf, addr, 4);
+ return krb5_data_copy(&a->address, buf, 4);
+}
+
+/*
+ * Are there any addresses that should be considered `uninteresting'?
+ */
+
+static krb5_boolean
+ipv4_uninteresting (const struct sockaddr *sa)
+{
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+ipv4_anyaddr (struct sockaddr *sa, int *sa_size, int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ memset (sin, 0, sizeof(*sin));
+ *sa_size = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ sin->sin_addr.s_addr = INADDR_ANY;
+}
+
+static int
+ipv4_print_addr (const krb5_address *addr, char *str, size_t len)
+{
+ struct in_addr ia;
+
+ memcpy (&ia, addr->address.data, 4);
+
+ return snprintf (str, len, "IPv4:%s", inet_ntoa(ia));
+}
+
+static int
+ipv4_parse_addr (const char *address, krb5_address *addr)
+{
+ const char *p;
+ struct in_addr a;
+
+ p = strchr(address, ':');
+ if(p) {
+ p++;
+ if(strncasecmp(address, "ip:", p - address) != 0 &&
+ strncasecmp(address, "ip4:", p - address) != 0 &&
+ strncasecmp(address, "ipv4:", p - address) != 0 &&
+ strncasecmp(address, "inet:", p - address) != 0)
+ return -1;
+ } else
+ p = address;
+#ifdef HAVE_INET_ATON
+ if(inet_aton(p, &a) == 0)
+ return -1;
+#elif defined(HAVE_INET_ADDR)
+ a.s_addr = inet_addr(p);
+ if(a.s_addr == INADDR_NONE)
+ return -1;
+#else
+ return -1;
+#endif
+ addr->addr_type = KRB5_ADDRESS_INET;
+ if(krb5_data_alloc(&addr->address, 4) != 0)
+ return -1;
+ _krb5_put_int(addr->address.data, ntohl(a.s_addr), addr->address.length);
+ return 0;
+}
+
+/*
+ * AF_INET6 - aka IPv6 implementation
+ */
+
+#ifdef HAVE_IPV6
+
+static krb5_error_code
+ipv6_sockaddr2addr (const struct sockaddr *sa, krb5_address *a)
+{
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ unsigned char buf[4];
+
+ a->addr_type = KRB5_ADDRESS_INET;
+#ifndef IN6_ADDR_V6_TO_V4
+#ifdef IN6_EXTRACT_V4ADDR
+#define IN6_ADDR_V6_TO_V4(x) (&IN6_EXTRACT_V4ADDR(x))
+#else
+#define IN6_ADDR_V6_TO_V4(x) ((const struct in_addr *)&(x)->s6_addr[12])
+#endif
+#endif
+ memcpy (buf, IN6_ADDR_V6_TO_V4(&sin6->sin6_addr), 4);
+ return krb5_data_copy(&a->address, buf, 4);
+ } else {
+ a->addr_type = KRB5_ADDRESS_INET6;
+ return krb5_data_copy(&a->address,
+ &sin6->sin6_addr,
+ sizeof(sin6->sin6_addr));
+ }
+}
+
+static krb5_error_code
+ipv6_sockaddr2port (const struct sockaddr *sa, int16_t *port)
+{
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+
+ *port = sin6->sin6_port;
+ return 0;
+}
+
+static void
+ipv6_addr2sockaddr (const krb5_address *a,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ memcpy (&sin6->sin6_addr, a->address.data, sizeof(sin6->sin6_addr));
+ sin6->sin6_port = port;
+ *sa_size = sizeof(*sin6);
+}
+
+static void
+ipv6_h_addr2sockaddr(const char *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ *sa_size = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = port;
+ sin6->sin6_addr = *((const struct in6_addr *)addr);
+}
+
+static krb5_error_code
+ipv6_h_addr2addr (const char *addr,
+ krb5_address *a)
+{
+ a->addr_type = KRB5_ADDRESS_INET6;
+ return krb5_data_copy(&a->address, addr, sizeof(struct in6_addr));
+}
+
+/*
+ *
+ */
+
+static krb5_boolean
+ipv6_uninteresting (const struct sockaddr *sa)
+{
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+ const struct in6_addr *in6 = (const struct in6_addr *)&sin6->sin6_addr;
+
+ return
+ IN6_IS_ADDR_LINKLOCAL(in6)
+ || IN6_IS_ADDR_V4COMPAT(in6);
+}
+
+static void
+ipv6_anyaddr (struct sockaddr *sa, int *sa_size, int port)
+{
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ memset (sin6, 0, sizeof(*sin6));
+ *sa_size = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = port;
+ sin6->sin6_addr = in6addr_any;
+}
+
+static int
+ipv6_print_addr (const krb5_address *addr, char *str, size_t len)
+{
+ char buf[128], buf2[3];
+#ifdef HAVE_INET_NTOP
+ if(inet_ntop(AF_INET6, addr->address.data, buf, sizeof(buf)) == NULL)
+#endif
+ {
+ /* XXX this is pretty ugly, but better than abort() */
+ int i;
+ unsigned char *p = addr->address.data;
+ buf[0] = '\0';
+ for(i = 0; i < addr->address.length; i++) {
+ snprintf(buf2, sizeof(buf2), "%02x", p[i]);
+ if(i > 0 && (i & 1) == 0)
+ strlcat(buf, ":", sizeof(buf));
+ strlcat(buf, buf2, sizeof(buf));
+ }
+ }
+ return snprintf(str, len, "IPv6:%s", buf);
+}
+
+static int
+ipv6_parse_addr (const char *address, krb5_address *addr)
+{
+ int ret;
+ struct in6_addr in6;
+
+ ret = inet_pton(AF_INET6, address, &in6.s6_addr);
+ if(ret == 1) {
+ addr->addr_type = KRB5_ADDRESS_INET6;
+ ret = krb5_data_alloc(&addr->address, sizeof(in6.s6_addr));
+ if (ret)
+ return -1;
+ memcpy(addr->address.data, in6.s6_addr, sizeof(in6.s6_addr));
+ return 0;
+ }
+ return -1;
+}
+
+#endif /* IPv6 */
+
+/*
+ * table
+ */
+
+static struct addr_operations at[] = {
+ {AF_INET, KRB5_ADDRESS_INET, sizeof(struct sockaddr_in),
+ ipv4_sockaddr2addr,
+ ipv4_sockaddr2port,
+ ipv4_addr2sockaddr,
+ ipv4_h_addr2sockaddr,
+ ipv4_h_addr2addr,
+ ipv4_uninteresting, ipv4_anyaddr, ipv4_print_addr, ipv4_parse_addr},
+#ifdef HAVE_IPV6
+ {AF_INET6, KRB5_ADDRESS_INET6, sizeof(struct sockaddr_in6),
+ ipv6_sockaddr2addr,
+ ipv6_sockaddr2port,
+ ipv6_addr2sockaddr,
+ ipv6_h_addr2sockaddr,
+ ipv6_h_addr2addr,
+ ipv6_uninteresting, ipv6_anyaddr, ipv6_print_addr, ipv6_parse_addr}
+#endif
+};
+
+static int num_addrs = sizeof(at) / sizeof(at[0]);
+
+static size_t max_sockaddr_size = 0;
+
+/*
+ * generic functions
+ */
+
+static struct addr_operations *
+find_af(int af)
+{
+ struct addr_operations *a;
+
+ for (a = at; a < at + num_addrs; ++a)
+ if (af == a->af)
+ return a;
+ return NULL;
+}
+
+static struct addr_operations *
+find_atype(int atype)
+{
+ struct addr_operations *a;
+
+ for (a = at; a < at + num_addrs; ++a)
+ if (atype == a->atype)
+ return a;
+ return NULL;
+}
+
+krb5_error_code
+krb5_sockaddr2address (const struct sockaddr *sa, krb5_address *addr)
+{
+ struct addr_operations *a = find_af(sa->sa_family);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ return (*a->sockaddr2addr)(sa, addr);
+}
+
+krb5_error_code
+krb5_sockaddr2port (const struct sockaddr *sa, int16_t *port)
+{
+ struct addr_operations *a = find_af(sa->sa_family);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ return (*a->sockaddr2port)(sa, port);
+}
+
+krb5_error_code
+krb5_addr2sockaddr (const krb5_address *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct addr_operations *a = find_atype(addr->addr_type);
+
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ (*a->addr2sockaddr)(addr, sa, sa_size, port);
+ return 0;
+}
+
+size_t
+krb5_max_sockaddr_size (void)
+{
+ if (max_sockaddr_size == 0) {
+ struct addr_operations *a;
+
+ for(a = at; a < at + num_addrs; ++a)
+ max_sockaddr_size = max(max_sockaddr_size, a->max_sockaddr_size);
+ }
+ return max_sockaddr_size;
+}
+
+krb5_boolean
+krb5_sockaddr_uninteresting(const struct sockaddr *sa)
+{
+ struct addr_operations *a = find_af(sa->sa_family);
+ if (a == NULL)
+ return TRUE;
+ return (*a->uninteresting)(sa);
+}
+
+krb5_error_code
+krb5_h_addr2sockaddr (int af,
+ const char *addr, struct sockaddr *sa, int *sa_size,
+ int port)
+{
+ struct addr_operations *a = find_af(af);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ (*a->h_addr2sockaddr)(addr, sa, sa_size, port);
+ return 0;
+}
+
+krb5_error_code
+krb5_h_addr2addr (int af,
+ const char *haddr, krb5_address *addr)
+{
+ struct addr_operations *a = find_af(af);
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+ return (*a->h_addr2addr)(haddr, addr);
+}
+
+krb5_error_code
+krb5_anyaddr (int af,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port)
+{
+ struct addr_operations *a = find_af (af);
+
+ if (a == NULL)
+ return KRB5_PROG_ATYPE_NOSUPP;
+
+ (*a->anyaddr)(sa, sa_size, port);
+ return 0;
+}
+
+krb5_error_code
+krb5_print_address (const krb5_address *addr,
+ char *str, size_t len, size_t *ret_len)
+{
+ struct addr_operations *a = find_atype(addr->addr_type);
+
+ if (a == NULL) {
+ char *s;
+ size_t l;
+ int i;
+ s = str;
+ l = snprintf(s, len, "TYPE_%d:", addr->addr_type);
+ s += l;
+ len -= len;
+ for(i = 0; i < addr->address.length; i++) {
+ l = snprintf(s, len, "%02x", ((char*)addr->address.data)[i]);
+ len -= l;
+ s += l;
+ }
+ *ret_len = s - str;
+ return 0;
+ }
+ *ret_len = (*a->print_addr)(addr, str, len);
+ return 0;
+}
+
+krb5_error_code
+krb5_parse_address(krb5_context context,
+ const char *string,
+ krb5_addresses *addresses)
+{
+ int i, n;
+ struct addrinfo *ai, *a;
+ int error;
+
+ for(i = 0; i < num_addrs; i++) {
+ if(at[i].parse_addr) {
+ krb5_address a;
+ if((*at[i].parse_addr)(string, &a) == 0) {
+ ALLOC_SEQ(addresses, 1);
+ addresses->val[0] = a;
+ return 0;
+ }
+ }
+ }
+
+ error = getaddrinfo (string, NULL, NULL, &ai);
+ if (error)
+ return -1;
+
+ n = 0;
+ for (a = ai; a != NULL; a = a->ai_next)
+ ++n;
+
+ ALLOC_SEQ(addresses, n);
+
+ for (a = ai, i = 0; a != NULL; a = a->ai_next, ++i) {
+ struct addr_operations *aop = find_af (ai->ai_family);
+
+ addresses->val[i].addr_type = aop->atype;
+ krb5_data_copy (&addresses->val[i].address,
+ ai->ai_addr,
+ ai->ai_addrlen);
+ }
+ freeaddrinfo (ai);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/address.c b/crypto/heimdal/lib/krb5/address.c
new file mode 100644
index 0000000..8b0704f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/address.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: address.c,v 1.14 1999/12/02 17:05:07 joda Exp $");
+
+#if 0
+/* This is the supposedly MIT-api version */
+
+krb5_boolean
+krb5_address_search(krb5_context context,
+ const krb5_address *addr,
+ krb5_address *const *addrlist)
+{
+ krb5_address *a;
+
+ while((a = *addrlist++))
+ if (krb5_address_compare (context, addr, a))
+ return TRUE;
+ return FALSE;
+}
+#endif
+
+krb5_boolean
+krb5_address_search(krb5_context context,
+ const krb5_address *addr,
+ const krb5_addresses *addrlist)
+{
+ int i;
+
+ for (i = 0; i < addrlist->len; ++i)
+ if (krb5_address_compare (context, addr, &addrlist->val[i]))
+ return TRUE;
+ return FALSE;
+}
+
+int
+krb5_address_order(krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2)
+{
+ return (addr1->addr_type - addr2->addr_type)
+ || memcmp (addr1->address.data,
+ addr2->address.data,
+ addr1->address.length);
+}
+
+krb5_boolean
+krb5_address_compare(krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2)
+{
+ return krb5_address_order (context, addr1, addr2) == 0;
+}
+
+krb5_error_code
+krb5_copy_address(krb5_context context,
+ const krb5_address *inaddr,
+ krb5_address *outaddr)
+{
+ copy_HostAddress(inaddr, outaddr);
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_addresses(krb5_context context,
+ const krb5_addresses *inaddr,
+ krb5_addresses *outaddr)
+{
+ copy_HostAddresses(inaddr, outaddr);
+ return 0;
+}
+
+krb5_error_code
+krb5_free_address(krb5_context context,
+ krb5_address *address)
+{
+ krb5_data_free (&address->address);
+ return 0;
+}
+
+krb5_error_code
+krb5_free_addresses(krb5_context context,
+ krb5_addresses *addresses)
+{
+ free_HostAddresses(addresses);
+ return 0;
+}
+
+krb5_error_code
+krb5_append_addresses(krb5_context context,
+ krb5_addresses *dest,
+ const krb5_addresses *source)
+{
+ krb5_address *tmp;
+ krb5_error_code ret;
+ int i;
+ if(source->len > 0) {
+ tmp = realloc(dest->val, (dest->len + source->len) * sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ dest->val = tmp;
+ for(i = 0; i < source->len; i++) {
+ /* skip duplicates */
+ if(krb5_address_search(context, &source->val[i], dest))
+ continue;
+ ret = krb5_copy_address(context,
+ &source->val[i],
+ &dest->val[dest->len]);
+ if(ret)
+ return ret;
+ dest->len++;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Create an address of type KRB5_ADDRESS_ADDRPORT from (addr, port)
+ */
+
+krb5_error_code
+krb5_make_addrport (krb5_address **res, const krb5_address *addr, int16_t port)
+{
+ krb5_error_code ret;
+ size_t len = addr->address.length + 2 + 4 * 4;
+ u_char *p;
+
+ *res = malloc (sizeof(**res));
+ if (*res == NULL)
+ return ENOMEM;
+ (*res)->addr_type = KRB5_ADDRESS_ADDRPORT;
+ ret = krb5_data_alloc (&(*res)->address, len);
+ if (ret) {
+ free (*res);
+ return ret;
+ }
+ p = (*res)->address.data;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = (addr->addr_type ) & 0xFF;
+ *p++ = (addr->addr_type >> 8) & 0xFF;
+
+ *p++ = (addr->address.length ) & 0xFF;
+ *p++ = (addr->address.length >> 8) & 0xFF;
+ *p++ = (addr->address.length >> 16) & 0xFF;
+ *p++ = (addr->address.length >> 24) & 0xFF;
+
+ memcpy (p, addr->address.data, addr->address.length);
+ p += addr->address.length;
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = (KRB5_ADDRESS_IPPORT ) & 0xFF;
+ *p++ = (KRB5_ADDRESS_IPPORT >> 8) & 0xFF;
+
+ *p++ = (2 ) & 0xFF;
+ *p++ = (2 >> 8) & 0xFF;
+ *p++ = (2 >> 16) & 0xFF;
+ *p++ = (2 >> 24) & 0xFF;
+
+ memcpy (p, &port, 2);
+ p += 2;
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/aname_to_localname.c b/crypto/heimdal/lib/krb5/aname_to_localname.c
new file mode 100644
index 0000000..c125580
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/aname_to_localname.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: aname_to_localname.c,v 1.3 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_aname_to_localname (krb5_context context,
+ krb5_const_principal aname,
+ size_t lnsize,
+ char *lname)
+{
+ krb5_error_code ret;
+ krb5_realm *lrealms, *r;
+ int foo = 1;
+ size_t len;
+ char *res;
+
+ ret = krb5_get_default_realms (context, &lrealms);
+ if (ret)
+ return ret;
+
+ for (r = lrealms; *r != NULL; ++r) {
+ foo = strcmp (*r, aname->realm);
+ if (foo == 0)
+ break;
+ }
+ krb5_free_host_realm (context, lrealms);
+ if (foo != 0)
+ return KRB5_NO_LOCALNAME;
+
+ if (aname->name.name_string.len == 1)
+ res = aname->name.name_string.val[0];
+ else if (aname->name.name_string.len == 2
+ && strcmp (aname->name.name_string.val[1], "root") == 0)
+ res = "root";
+ else
+ return KRB5_NO_LOCALNAME;
+
+ len = strlen (res);
+ if (len >= lnsize)
+ return ERANGE;
+ strcpy (lname, res);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/asn1_glue.c b/crypto/heimdal/lib/krb5/asn1_glue.c
new file mode 100644
index 0000000..ac83ff7
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/asn1_glue.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: asn1_glue.c,v 1.7 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_principal2principalname (PrincipalName *p,
+ const krb5_principal from)
+{
+ return copy_PrincipalName(&from->name, p);
+}
+
+krb5_error_code
+principalname2krb5_principal (krb5_principal *principal,
+ const PrincipalName from,
+ const Realm realm)
+{
+ krb5_principal p = malloc(sizeof(*p));
+ copy_PrincipalName(&from, &p->name);
+ p->realm = strdup(realm);
+ *principal = p;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/auth_context.c b/crypto/heimdal/lib/krb5/auth_context.c
new file mode 100644
index 0000000..94b1376
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/auth_context.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: auth_context.c,v 1.50 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_auth_con_init(krb5_context context,
+ krb5_auth_context *auth_context)
+{
+ krb5_auth_context p;
+
+ ALLOC(p, 1);
+ if(!p)
+ return ENOMEM;
+ memset(p, 0, sizeof(*p));
+ ALLOC(p->authenticator, 1);
+ if (!p->authenticator) {
+ free(p);
+ return ENOMEM;
+ }
+ memset (p->authenticator, 0, sizeof(*p->authenticator));
+ p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
+
+ p->local_address = NULL;
+ p->remote_address = NULL;
+ p->local_port = 0;
+ p->remote_port = 0;
+ p->keytype = KEYTYPE_NULL;
+ p->cksumtype = CKSUMTYPE_NONE;
+ *auth_context = p;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_free(krb5_context context,
+ krb5_auth_context auth_context)
+{
+ krb5_free_authenticator(context, &auth_context->authenticator);
+ if(auth_context->local_address){
+ free_HostAddress(auth_context->local_address);
+ free(auth_context->local_address);
+ }
+ if(auth_context->remote_address){
+ free_HostAddress(auth_context->remote_address);
+ free(auth_context->remote_address);
+ }
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ krb5_free_keyblock(context, auth_context->remote_subkey);
+ krb5_free_keyblock(context, auth_context->local_subkey);
+ free (auth_context);
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_setflags(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t flags)
+{
+ auth_context->flags = flags;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_auth_con_getflags(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *flags)
+{
+ *flags = auth_context->flags;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_auth_con_setaddrs(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address *local_addr,
+ krb5_address *remote_addr)
+{
+ if (local_addr) {
+ if (auth_context->local_address)
+ krb5_free_address (context, auth_context->local_address);
+ else
+ auth_context->local_address = malloc(sizeof(krb5_address));
+ krb5_copy_address(context, local_addr, auth_context->local_address);
+ }
+ if (remote_addr) {
+ if (auth_context->remote_address)
+ krb5_free_address (context, auth_context->remote_address);
+ else
+ auth_context->remote_address = malloc(sizeof(krb5_address));
+ krb5_copy_address(context, remote_addr, auth_context->remote_address);
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_setaddrs_from_fd (krb5_context context,
+ krb5_auth_context auth_context,
+ void *p_fd)
+{
+ int fd = *((int *)p_fd);
+ krb5_error_code ret;
+ krb5_address local_k_address, remote_k_address;
+ krb5_address *lptr = NULL, *rptr = NULL;
+ struct sockaddr_storage ss_local, ss_remote;
+ struct sockaddr *local = (struct sockaddr *)&ss_local;
+ struct sockaddr *remote = (struct sockaddr *)&ss_remote;
+ int len;
+
+ if (auth_context->local_address == NULL) {
+ len = sizeof(ss_local);
+ if(getsockname(fd, local, &len) < 0) {
+ ret = errno;
+ goto out;
+ }
+ krb5_sockaddr2address (local, &local_k_address);
+ krb5_sockaddr2port (local, &auth_context->local_port);
+ lptr = &local_k_address;
+ }
+ if (auth_context->remote_address == NULL) {
+ len = sizeof(ss_remote);
+ if(getpeername(fd, remote, &len) < 0) {
+ ret = errno;
+ goto out;
+ }
+ krb5_sockaddr2address (remote, &remote_k_address);
+ krb5_sockaddr2port (remote, &auth_context->remote_port);
+ rptr = &remote_k_address;
+ }
+ ret = krb5_auth_con_setaddrs (context,
+ auth_context,
+ lptr,
+ rptr);
+out:
+ if (lptr)
+ krb5_free_address (context, lptr);
+ if (rptr)
+ krb5_free_address (context, rptr);
+ return ret;
+}
+
+krb5_error_code
+krb5_auth_con_getaddrs(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address **local_addr,
+ krb5_address **remote_addr)
+{
+ if(*local_addr)
+ krb5_free_address (context, *local_addr);
+ *local_addr = malloc (sizeof(**local_addr));
+ if (*local_addr == NULL)
+ return ENOMEM;
+ krb5_copy_address(context,
+ auth_context->local_address,
+ *local_addr);
+
+ if(*remote_addr)
+ krb5_free_address (context, *remote_addr);
+ *remote_addr = malloc (sizeof(**remote_addr));
+ if (*remote_addr == NULL)
+ return ENOMEM;
+ krb5_copy_address(context,
+ auth_context->remote_address,
+ *remote_addr);
+ return 0;
+}
+
+static krb5_error_code
+copy_key(krb5_context context,
+ krb5_keyblock *in,
+ krb5_keyblock **out)
+{
+ if(in)
+ return krb5_copy_keyblock(context, in, out);
+ *out = NULL; /* is this right? */
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_con_getkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return copy_key(context, auth_context->keyblock, keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_getlocalsubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return copy_key(context, auth_context->local_subkey, keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_getremotesubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return copy_key(context, auth_context->remote_subkey, keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_setkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ return copy_key(context, keyblock, &auth_context->keyblock);
+}
+
+krb5_error_code
+krb5_auth_con_setlocalsubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->local_subkey)
+ krb5_free_keyblock(context, auth_context->local_subkey);
+ return copy_key(context, keyblock, &auth_context->local_subkey);
+}
+
+krb5_error_code
+krb5_auth_con_setremotesubkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->remote_subkey)
+ krb5_free_keyblock(context, auth_context->remote_subkey);
+ return copy_key(context, keyblock, &auth_context->remote_subkey);
+}
+
+krb5_error_code
+krb5_auth_setcksumtype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype cksumtype)
+{
+ auth_context->cksumtype = cksumtype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getcksumtype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype *cksumtype)
+{
+ *cksumtype = auth_context->cksumtype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_setkeytype (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype keytype)
+{
+ auth_context->keytype = keytype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getkeytype (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype *keytype)
+{
+ *keytype = auth_context->keytype;
+ return 0;
+}
+
+#if 0
+krb5_error_code
+krb5_auth_setenctype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype etype)
+{
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ ALLOC(auth_context->keyblock, 1);
+ if(auth_context->keyblock == NULL)
+ return ENOMEM;
+ auth_context->keyblock->keytype = etype;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getenctype(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype *etype)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
+}
+#endif
+
+krb5_error_code
+krb5_auth_getlocalseqnumber(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber)
+{
+ *seqnumber = auth_context->local_seqnumber;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_setlocalseqnumber (krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber)
+{
+ auth_context->local_seqnumber = seqnumber;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_getremoteseqnumber(krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber)
+{
+ *seqnumber = auth_context->remote_seqnumber;
+ return 0;
+}
+
+krb5_error_code
+krb5_auth_setremoteseqnumber (krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber)
+{
+ auth_context->remote_seqnumber = seqnumber;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_auth_getauthenticator(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authenticator *authenticator)
+{
+ *authenticator = malloc(sizeof(**authenticator));
+ if (*authenticator == NULL)
+ return ENOMEM;
+
+ copy_Authenticator(auth_context->authenticator,
+ *authenticator);
+ return 0;
+}
+
+
+void
+krb5_free_authenticator(krb5_context context,
+ krb5_authenticator *authenticator)
+{
+ free_Authenticator (*authenticator);
+ free (*authenticator);
+ *authenticator = NULL;
+}
+
+
+krb5_error_code
+krb5_auth_con_setuserkey(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ if(auth_context->keyblock)
+ krb5_free_keyblock(context, auth_context->keyblock);
+ return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
+}
+
+#if 0 /* not implemented */
+
+krb5_error_code
+krb5_auth_con_initivector(krb5_context context,
+ krb5_auth_context auth_context)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
+}
+
+
+krb5_error_code
+krb5_auth_con_setivector(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_pointer ivector)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
+}
+
+
+krb5_error_code
+krb5_auth_con_setrcache(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_rcache rcache)
+{
+ krb5_abortx(context, "unimplemented krb5_auth_con_setrcache called");
+}
+
+#endif /* not implemented */
diff --git a/crypto/heimdal/lib/krb5/build_ap_req.c b/crypto/heimdal/lib/krb5/build_ap_req.c
new file mode 100644
index 0000000..c8a89ca
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/build_ap_req.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: build_ap_req.c,v 1.16 1999/12/02 17:05:07 joda Exp $");
+
+krb5_error_code
+krb5_build_ap_req (krb5_context context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ krb5_flags ap_options,
+ krb5_data authenticator,
+ krb5_data *retdata)
+{
+ krb5_error_code ret = 0;
+ AP_REQ ap;
+ Ticket t;
+ size_t len;
+
+ ap.pvno = 5;
+ ap.msg_type = krb_ap_req;
+ memset(&ap.ap_options, 0, sizeof(ap.ap_options));
+ ap.ap_options.use_session_key = (ap_options & AP_OPTS_USE_SESSION_KEY) > 0;
+ ap.ap_options.mutual_required = (ap_options & AP_OPTS_MUTUAL_REQUIRED) > 0;
+
+ ap.ticket.tkt_vno = 5;
+ copy_Realm(&cred->server->realm, &ap.ticket.realm);
+ copy_PrincipalName(&cred->server->name, &ap.ticket.sname);
+
+ decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
+ copy_EncryptedData(&t.enc_part, &ap.ticket.enc_part);
+ free_Ticket(&t);
+
+ ap.authenticator.etype = enctype;
+ ap.authenticator.kvno = NULL;
+ ap.authenticator.cipher = authenticator;
+
+ retdata->length = length_AP_REQ(&ap);
+ retdata->data = malloc(retdata->length);
+ if(retdata->data == NULL)
+ ret = ENOMEM;
+ else
+ encode_AP_REQ((unsigned char *)retdata->data + retdata->length - 1,
+ retdata->length, &ap, &len);
+ free_AP_REQ(&ap);
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/build_auth.c b/crypto/heimdal/lib/krb5/build_auth.c
new file mode 100644
index 0000000..a38393b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/build_auth.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: build_auth.c,v 1.32 1999/12/02 17:05:08 joda Exp $");
+
+krb5_error_code
+krb5_build_authenticator (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ Checksum *cksum,
+ Authenticator **auth_result,
+ krb5_data *result)
+{
+ Authenticator *auth;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ krb5_error_code ret;
+ krb5_crypto crypto;
+
+ auth = malloc(sizeof(*auth));
+ if (auth == NULL)
+ return ENOMEM;
+
+ memset (auth, 0, sizeof(*auth));
+ auth->authenticator_vno = 5;
+ copy_Realm(&cred->client->realm, &auth->crealm);
+ copy_PrincipalName(&cred->client->name, &auth->cname);
+
+ {
+ int32_t sec, usec;
+
+ krb5_us_timeofday (context, &sec, &usec);
+ auth->ctime = sec;
+ auth->cusec = usec;
+ }
+ ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth->subkey);
+ if(ret)
+ goto fail;
+
+ if(auth->subkey == NULL) {
+ krb5_generate_subkey (context, &cred->session, &auth->subkey);
+ ret = krb5_auth_con_setlocalsubkey(context, auth_context, auth->subkey);
+ if(ret)
+ goto fail;
+ }
+
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ krb5_generate_seq_number (context,
+ &cred->session,
+ &auth_context->local_seqnumber);
+ ALLOC(auth->seq_number, 1);
+ *auth->seq_number = auth_context->local_seqnumber;
+ } else
+ auth->seq_number = NULL;
+ auth->authorization_data = NULL;
+ auth->cksum = cksum;
+
+ /* XXX - Copy more to auth_context? */
+
+ if (auth_context) {
+ auth_context->authenticator->ctime = auth->ctime;
+ auth_context->authenticator->cusec = auth->cusec;
+ }
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ do {
+ ret = krb5_encode_Authenticator (context,
+ buf + buf_size - 1,
+ buf_size,
+ auth, &len);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ buf = tmp;
+ } else {
+ goto fail;
+ }
+ }
+ } while(ret == ASN1_OVERFLOW);
+
+ ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
+ ret = krb5_encrypt (context,
+ crypto,
+ KRB5_KU_AP_REQ_AUTH,
+ buf + buf_size - len,
+ len,
+ result);
+ krb5_crypto_destroy(context, crypto);
+
+ if (ret)
+ goto fail;
+
+ free (buf);
+
+ if (auth_result)
+ *auth_result = auth;
+ else {
+ /* Don't free the `cksum', it's allocated by the caller */
+ auth->cksum = NULL;
+ free_Authenticator (auth);
+ free (auth);
+ }
+ return ret;
+fail:
+ free_Authenticator (auth);
+ free (auth);
+ free (buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/cache.c b/crypto/heimdal/lib/krb5/cache.c
new file mode 100644
index 0000000..e78d4de
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/cache.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: cache.c,v 1.44 1999/12/02 17:05:08 joda Exp $");
+
+/*
+ * Add a new ccache type with operations `ops', overwriting any
+ * existing one if `override'.
+ * Return an error code or 0.
+ */
+
+krb5_error_code
+krb5_cc_register(krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_boolean override)
+{
+ int i;
+
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
+ if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) {
+ if(override)
+ free(context->cc_ops[i].prefix);
+ else
+ return KRB5_CC_TYPE_EXISTS;
+ }
+ }
+ if(i == context->num_cc_ops) {
+ krb5_cc_ops *o = realloc(context->cc_ops,
+ (context->num_cc_ops + 1) *
+ sizeof(*context->cc_ops));
+ if(o == NULL)
+ return KRB5_CC_NOMEM;
+ context->num_cc_ops++;
+ context->cc_ops = o;
+ memset(context->cc_ops + i, 0,
+ (context->num_cc_ops - i) * sizeof(*context->cc_ops));
+ }
+ memcpy(&context->cc_ops[i], ops, sizeof(context->cc_ops[i]));
+ context->cc_ops[i].prefix = strdup(ops->prefix);
+ if(context->cc_ops[i].prefix == NULL)
+ return KRB5_CC_NOMEM;
+
+ return 0;
+}
+
+/*
+ * Allocate memory for a new ccache in `id' with operations `ops'
+ * and name `residual'.
+ * Return 0 or an error code.
+ */
+
+static krb5_error_code
+allocate_ccache (krb5_context context,
+ const krb5_cc_ops *ops,
+ const char *residual,
+ krb5_ccache *id)
+{
+ krb5_error_code ret;
+ krb5_ccache p;
+
+ p = malloc(sizeof(*p));
+ if(p == NULL)
+ return KRB5_CC_NOMEM;
+ p->ops = ops;
+ *id = p;
+ ret = p->ops->resolve(context, id, residual);
+ if(ret)
+ free(p);
+ return ret;
+}
+
+/*
+ * Find and allocate a ccache in `id' from the specification in `residual'.
+ * If the ccache name doesn't contain any colon, interpret it as a file name.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_resolve(krb5_context context,
+ const char *name,
+ krb5_ccache *id)
+{
+ int i;
+
+ for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
+ size_t prefix_len = strlen(context->cc_ops[i].prefix);
+
+ if(strncmp(context->cc_ops[i].prefix, name, prefix_len) == 0
+ && name[prefix_len] == ':') {
+ return allocate_ccache (context, &context->cc_ops[i],
+ name + prefix_len + 1,
+ id);
+ }
+ }
+ if (strchr (name, ':') == NULL)
+ return allocate_ccache (context, &krb5_fcc_ops, name, id);
+ else
+ return KRB5_CC_UNKNOWN_TYPE;
+}
+
+/*
+ * Generate a new ccache of type `ops' in `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_gen_new(krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_ccache *id)
+{
+ krb5_ccache p;
+
+ p = malloc (sizeof(*p));
+ if (p == NULL)
+ return KRB5_CC_NOMEM;
+ p->ops = ops;
+ *id = p;
+ return p->ops->gen_new(context, id);
+}
+
+/*
+ * Return the name of the ccache `id'
+ */
+
+const char*
+krb5_cc_get_name(krb5_context context,
+ krb5_ccache id)
+{
+ return id->ops->get_name(context, id);
+}
+
+/*
+ * Return the type of the ccache `id'.
+ */
+
+const char*
+krb5_cc_get_type(krb5_context context,
+ krb5_ccache id)
+{
+ return id->ops->prefix;
+}
+
+/*
+ * Return a pointer to a static string containing the default ccache name.
+ */
+
+const char*
+krb5_cc_default_name(krb5_context context)
+{
+ static char name[1024];
+ char *p;
+
+ p = getenv("KRB5CCNAME");
+ if(p)
+ strlcpy (name, p, sizeof(name));
+ else
+ snprintf(name,
+ sizeof(name),
+ "FILE:/tmp/krb5cc_%u",
+ (unsigned)getuid());
+ return name;
+}
+
+/*
+ * Open the default ccache in `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_default(krb5_context context,
+ krb5_ccache *id)
+{
+ return krb5_cc_resolve(context,
+ krb5_cc_default_name(context),
+ id);
+}
+
+/*
+ * Create a new ccache in `id' for `primary_principal'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_initialize(krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal)
+{
+ return id->ops->init(context, id, primary_principal);
+}
+
+
+/*
+ * Remove the ccache `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_destroy(krb5_context context,
+ krb5_ccache id)
+{
+ krb5_error_code ret;
+
+ ret = id->ops->destroy(context, id);
+ krb5_cc_close (context, id);
+ return ret;
+}
+
+/*
+ * Stop using the ccache `id' and free the related resources.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_close(krb5_context context,
+ krb5_ccache id)
+{
+ krb5_error_code ret;
+ ret = id->ops->close(context, id);
+ free(id);
+ return ret;
+}
+
+/*
+ * Store `creds' in the ccache `id'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_store_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds)
+{
+ return id->ops->store(context, id, creds);
+}
+
+/*
+ * Retrieve the credential identified by `mcreds' (and `whichfields')
+ * from `id' in `creds'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_retrieve_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags whichfields,
+ const krb5_creds *mcreds,
+ krb5_creds *creds)
+{
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_cc_start_seq_get(context, id, &cursor);
+ while((ret = krb5_cc_next_cred(context, id, creds, &cursor)) == 0){
+ if(krb5_compare_creds(context, whichfields, mcreds, creds)){
+ ret = 0;
+ break;
+ }
+ krb5_free_creds_contents (context, creds);
+ }
+ krb5_cc_end_seq_get(context, id, &cursor);
+ return ret;
+}
+
+/*
+ * Return the principal of `id' in `principal'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_get_principal(krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal)
+{
+ return id->ops->get_princ(context, id, principal);
+}
+
+/*
+ * Start iterating over `id', `cursor' is initialized to the
+ * beginning.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_start_seq_get (krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ return id->ops->get_first(context, id, cursor);
+}
+
+/*
+ * Retrieve the next cred pointed to by (`id', `cursor') in `creds'
+ * and advance `cursor'.
+ * Return 0 or an error code.
+ */
+
+krb5_error_code
+krb5_cc_next_cred (krb5_context context,
+ const krb5_ccache id,
+ krb5_creds *creds,
+ krb5_cc_cursor *cursor)
+{
+ return id->ops->get_next(context, id, cursor, creds);
+}
+
+/*
+ * Destroy the cursor `cursor'.
+ */
+
+krb5_error_code
+krb5_cc_end_seq_get (krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ return id->ops->end_get(context, id, cursor);
+}
+
+/*
+ * Remove the credential identified by `cred', `which' from `id'.
+ */
+
+krb5_error_code
+krb5_cc_remove_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred)
+{
+ return id->ops->remove_cred(context, id, which, cred);
+}
+
+/*
+ * Set the flags of `id' to `flags'.
+ */
+
+krb5_error_code
+krb5_cc_set_flags(krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags)
+{
+ return id->ops->set_flags(context, id, flags);
+}
+
+/*
+ * Copy the contents of `from' to `to'.
+ */
+
+krb5_error_code
+krb5_cc_copy_cache(krb5_context context,
+ const krb5_ccache from,
+ krb5_ccache to)
+{
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_creds cred;
+ krb5_principal princ;
+
+ ret = krb5_cc_get_principal(context, from, &princ);
+ if(ret)
+ return ret;
+ ret = krb5_cc_initialize(context, to, princ);
+ if(ret){
+ krb5_free_principal(context, princ);
+ return ret;
+ }
+ ret = krb5_cc_start_seq_get(context, from, &cursor);
+ if(ret){
+ krb5_free_principal(context, princ);
+ return ret;
+ }
+ while(ret == 0 && krb5_cc_next_cred(context, from, &cred, &cursor) == 0){
+ ret = krb5_cc_store_cred(context, to, &cred);
+ krb5_free_creds_contents (context, &cred);
+ }
+ krb5_cc_end_seq_get(context, from, &cursor);
+ krb5_free_principal(context, princ);
+ return ret;
+}
+
+/*
+ * Return the version of `id'.
+ */
+
+krb5_error_code
+krb5_cc_get_version(krb5_context context,
+ const krb5_ccache id)
+{
+ if(id->ops->get_version)
+ return id->ops->get_version(context, id);
+ else
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/changepw.c b/crypto/heimdal/lib/krb5/changepw.c
new file mode 100644
index 0000000..fd94440
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/changepw.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: changepw.c,v 1.19 1999/12/11 23:14:51 assar Exp $");
+
+static krb5_error_code
+get_kdc_address (krb5_context context,
+ krb5_realm realm,
+ struct addrinfo **ai)
+{
+ struct addrinfo hints;
+ krb5_error_code ret;
+ char **hostlist;
+ int port = 0;
+ char portstr[NI_MAXSERV];
+ int error;
+ char *host;
+ char *dot;
+
+ ret = krb5_get_krb_changepw_hst (context,
+ &realm,
+ &hostlist);
+ if (ret)
+ return ret;
+
+ host = *hostlist;
+
+ dot = strchr (host, ':');
+ if (dot != NULL) {
+ char *end;
+
+ *dot++ = '\0';
+ port = strtol (dot, &end, 0);
+ }
+ if (port == 0)
+ port = krb5_getportbyname (context, "kpasswd", "udp", KPASSWD_PORT);
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ error = getaddrinfo (host, portstr, &hints, ai);
+ krb5_free_krbhst (context, hostlist);
+ return error;
+}
+
+static krb5_error_code
+send_request (krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_creds *creds,
+ int sock,
+ struct sockaddr *sa,
+ int sa_size,
+ char *passwd)
+{
+ krb5_error_code ret;
+ krb5_data ap_req_data;
+ krb5_data krb_priv_data;
+ krb5_data passwd_data;
+ size_t len;
+ u_char header[6];
+ u_char *p;
+ struct iovec iov[3];
+ struct msghdr msghdr;
+
+ krb5_data_zero (&ap_req_data);
+
+ ret = krb5_mk_req_extended (context,
+ auth_context,
+ AP_OPTS_MUTUAL_REQUIRED,
+ NULL, /* in_data */
+ creds,
+ &ap_req_data);
+ if (ret)
+ return ret;
+
+ passwd_data.data = passwd;
+ passwd_data.length = strlen(passwd);
+
+ krb5_data_zero (&krb_priv_data);
+
+ ret = krb5_mk_priv (context,
+ *auth_context,
+ &passwd_data,
+ &krb_priv_data,
+ NULL);
+ if (ret)
+ goto out2;
+
+ len = 6 + ap_req_data.length + krb_priv_data.length;
+ p = header;
+ *p++ = (len >> 8) & 0xFF;
+ *p++ = (len >> 0) & 0xFF;
+ *p++ = 0;
+ *p++ = 1;
+ *p++ = (ap_req_data.length >> 8) & 0xFF;
+ *p++ = (ap_req_data.length >> 0) & 0xFF;
+
+ memset(&msghdr, 0, sizeof(msghdr));
+ msghdr.msg_name = (void *)sa;
+ msghdr.msg_namelen = sa_size;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
+#if 0
+ msghdr.msg_control = NULL;
+ msghdr.msg_controllen = 0;
+#endif
+
+ iov[0].iov_base = (void*)header;
+ iov[0].iov_len = 6;
+ iov[1].iov_base = ap_req_data.data;
+ iov[1].iov_len = ap_req_data.length;
+ iov[2].iov_base = krb_priv_data.data;
+ iov[2].iov_len = krb_priv_data.length;
+
+ if (sendmsg (sock, &msghdr, 0) < 0)
+ ret = errno;
+
+ krb5_data_free (&krb_priv_data);
+out2:
+ krb5_data_free (&ap_req_data);
+ return ret;
+}
+
+static void
+str2data (krb5_data *d,
+ char *fmt,
+ ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ d->length = vasprintf ((char **)&d->data, fmt, args);
+ va_end(args);
+}
+
+static krb5_error_code
+process_reply (krb5_context context,
+ krb5_auth_context auth_context,
+ int sock,
+ int *result_code,
+ krb5_data *result_code_string,
+ krb5_data *result_string)
+{
+ krb5_error_code ret;
+ u_char reply[BUFSIZ];
+ size_t len;
+ u_int16_t pkt_len, pkt_ver;
+ krb5_data ap_rep_data;
+
+ ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL);
+ if (ret < 0)
+ return errno;
+
+ len = ret;
+ pkt_len = (reply[0] << 8) | (reply[1]);
+ pkt_ver = (reply[2] << 8) | (reply[3]);
+
+ if (pkt_len != len) {
+ str2data (result_string, "client: wrong len in reply");
+ *result_code = KRB5_KPASSWD_MALFORMED;
+ return 0;
+ }
+ if (pkt_ver != 0x0001) {
+ str2data (result_string,
+ "client: wrong version number (%d)", pkt_ver);
+ *result_code = KRB5_KPASSWD_MALFORMED;
+ return 0;
+ }
+
+ ap_rep_data.data = reply + 6;
+ ap_rep_data.length = (reply[4] << 8) | (reply[5]);
+
+ if (ap_rep_data.length) {
+ krb5_ap_rep_enc_part *ap_rep;
+ krb5_data priv_data;
+ u_char *p;
+
+ ret = krb5_rd_rep (context,
+ auth_context,
+ &ap_rep_data,
+ &ap_rep);
+ if (ret)
+ return ret;
+
+ krb5_free_ap_rep_enc_part (context, ap_rep);
+
+ priv_data.data = (u_char*)ap_rep_data.data + ap_rep_data.length;
+ priv_data.length = len - ap_rep_data.length - 6;
+
+ ret = krb5_rd_priv (context,
+ auth_context,
+ &priv_data,
+ result_code_string,
+ NULL);
+ if (ret) {
+ krb5_data_free (result_code_string);
+ return ret;
+ }
+
+ if (result_code_string->length < 2) {
+ *result_code = KRB5_KPASSWD_MALFORMED;
+ str2data (result_string,
+ "client: bad length in result");
+ return 0;
+ }
+ p = result_code_string->data;
+
+ *result_code = (p[0] << 8) | p[1];
+ krb5_data_copy (result_string,
+ (unsigned char*)result_code_string->data + 2,
+ result_code_string->length - 2);
+ return 0;
+ } else {
+ KRB_ERROR error;
+ size_t size;
+ u_char *p;
+
+ ret = decode_KRB_ERROR(reply + 6, len - 6, &error, &size);
+ if (ret) {
+ return ret;
+ }
+ if (error.e_data->length < 2) {
+ krb5_warnx (context, "too short e_data to print anything usable");
+ return 1;
+ }
+
+ p = error.e_data->data;
+ *result_code = (p[0] << 8) | p[1];
+ krb5_data_copy (result_string,
+ p + 2,
+ error.e_data->length - 2);
+ return 0;
+ }
+}
+
+krb5_error_code
+krb5_change_password (krb5_context context,
+ krb5_creds *creds,
+ char *newpw,
+ int *result_code,
+ krb5_data *result_code_string,
+ krb5_data *result_string)
+{
+ krb5_error_code ret;
+ krb5_auth_context auth_context = NULL;
+ int sock;
+ int i;
+ struct addrinfo *ai, *a;
+
+ ret = krb5_auth_con_init (context, &auth_context);
+ if (ret)
+ return ret;
+
+ ret = get_kdc_address (context, creds->client->realm, &ai);
+ if (ret)
+ goto out;
+
+ krb5_auth_con_setflags (context, auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (sock < 0)
+ continue;
+
+ for (i = 0; i < 5; ++i) {
+ fd_set fdset;
+ struct timeval tv;
+
+ ret = send_request (context,
+ &auth_context,
+ creds,
+ sock,
+ a->ai_addr,
+ a->ai_addrlen,
+ newpw);
+ if (ret)
+ goto out;
+
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_usec = 0;
+ tv.tv_sec = 1 << i;
+
+ ret = select (sock + 1, &fdset, NULL, NULL, &tv);
+ if (ret < 0 && errno != EINTR)
+ goto out;
+ if (ret == 1)
+ break;
+ }
+ if (i == 5) {
+ ret = KRB5_KDC_UNREACH;
+ close (sock);
+ continue;
+ }
+
+ ret = process_reply (context,
+ auth_context,
+ sock,
+ result_code,
+ result_code_string,
+ result_string);
+ close (sock);
+ if (ret == 0)
+ break;
+ }
+ freeaddrinfo (ai);
+
+out:
+ krb5_auth_con_free (context, auth_context);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/codec.c b/crypto/heimdal/lib/krb5/codec.c
new file mode 100644
index 0000000..1d94613
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/codec.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 1998 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: codec.c,v 1.6 1999/12/02 17:05:08 joda Exp $");
+
+/* these functions does what the normal asn.1-functions does, but
+ converts the keytype to/from the on-the-wire enctypes */
+
+#if 1
+#define DECODE(T, K) return decode_ ## T(data, length, t, len)
+#define ENCODE(T, K) return encode_ ## T(data, length, t, len)
+#else
+#define DECODE(T, K) \
+{ \
+ krb5_error_code ret; \
+ ret = decode_ ## T((void*)data, length, t, len); \
+ if(ret) \
+ return ret; \
+ if(K) \
+ ret = krb5_decode_keyblock(context, (K), 1); \
+ return ret; \
+}
+
+#define ENCODE(T, K) \
+{ \
+ krb5_error_code ret = 0; \
+ if(K) \
+ ret = krb5_decode_keyblock(context, (K), 0); \
+ if(ret) \
+ return ret; \
+ return encode_ ## T(data, length, t, len); \
+}
+#endif
+
+krb5_error_code
+krb5_decode_EncTicketPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len)
+{
+ DECODE(EncTicketPart, &t->key);
+}
+
+krb5_error_code
+krb5_encode_EncTicketPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len)
+{
+ ENCODE(EncTicketPart, &t->key);
+}
+
+krb5_error_code
+krb5_decode_EncASRepPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len)
+{
+ DECODE(EncASRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_encode_EncASRepPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len)
+{
+ ENCODE(EncASRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_decode_EncTGSRepPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len)
+{
+ DECODE(EncTGSRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_encode_EncTGSRepPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len)
+{
+ ENCODE(EncTGSRepPart, &t->key);
+}
+
+krb5_error_code
+krb5_decode_EncAPRepPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len)
+{
+ DECODE(EncAPRepPart, t->subkey);
+}
+
+krb5_error_code
+krb5_encode_EncAPRepPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len)
+{
+ ENCODE(EncAPRepPart, t->subkey);
+}
+
+krb5_error_code
+krb5_decode_Authenticator (krb5_context context,
+ const void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len)
+{
+ DECODE(Authenticator, t->subkey);
+}
+
+krb5_error_code
+krb5_encode_Authenticator (krb5_context context,
+ void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len)
+{
+ ENCODE(Authenticator, t->subkey);
+}
+
+krb5_error_code
+krb5_decode_EncKrbCredPart (krb5_context context,
+ const void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len)
+{
+#if 1
+ return decode_EncKrbCredPart(data, length, t, len);
+#else
+ krb5_error_code ret;
+ int i;
+ ret = decode_EncKrbCredPart((void*)data, length, t, len);
+ if(ret)
+ return ret;
+ for(i = 0; i < t->ticket_info.len; i++)
+ if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 1)))
+ break;
+ return ret;
+#endif
+}
+
+krb5_error_code
+krb5_encode_EncKrbCredPart (krb5_context context,
+ void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len)
+{
+#if 0
+ krb5_error_code ret = 0;
+ int i;
+
+ for(i = 0; i < t->ticket_info.len; i++)
+ if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 0)))
+ break;
+ if(ret) return ret;
+#endif
+ return encode_EncKrbCredPart (data, length, t, len);
+}
+
+krb5_error_code
+krb5_decode_ETYPE_INFO (krb5_context context,
+ const void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len)
+{
+#if 1
+ return decode_ETYPE_INFO(data, length, t, len);
+#else
+ krb5_error_code ret;
+ int i;
+
+ ret = decode_ETYPE_INFO((void*)data, length, t, len);
+ if(ret)
+ return ret;
+ for(i = 0; i < t->len; i++) {
+ if((ret = krb5_decode_keytype(context, &t->val[i].etype, 1)))
+ break;
+ }
+ return ret;
+#endif
+}
+
+krb5_error_code
+krb5_encode_ETYPE_INFO (krb5_context context,
+ void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len)
+{
+#if 0
+ krb5_error_code ret = 0;
+
+ int i;
+ /* XXX this will break, since we need one key-info for each enctype */
+ /* XXX or do we? */
+ for(i = 0; i < t->len; i++)
+ if((ret = krb5_decode_keytype(context, &t->val[i].etype, 0)))
+ break;
+ if(ret) return ret;
+#endif
+ return encode_ETYPE_INFO (data, length, t, len);
+}
diff --git a/crypto/heimdal/lib/krb5/config_file.c b/crypto/heimdal/lib/krb5/config_file.c
new file mode 100644
index 0000000..3d1ff1e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/config_file.c
@@ -0,0 +1,750 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: config_file.c,v 1.38 1999/12/02 17:05:08 joda Exp $");
+
+#ifndef HAVE_NETINFO
+
+static int parse_section(char *p, krb5_config_section **s,
+ krb5_config_section **res,
+ char **error_message);
+static int parse_binding(FILE *f, unsigned *lineno, char *p,
+ krb5_config_binding **b,
+ krb5_config_binding **parent,
+ char **error_message);
+static int parse_list(FILE *f, unsigned *lineno, krb5_config_binding **parent,
+ char **error_message);
+
+/*
+ * Parse a section:
+ *
+ * [section]
+ * foo = bar
+ * b = {
+ * a
+ * }
+ * ...
+ *
+ * starting at the line in `p', storing the resulting structure in
+ * `s' and hooking it into `parent'.
+ * Store the error message in `error_message'.
+ */
+
+static int
+parse_section(char *p, krb5_config_section **s, krb5_config_section **parent,
+ char **error_message)
+{
+ char *p1;
+ krb5_config_section *tmp;
+
+ p1 = strchr (p + 1, ']');
+ if (p1 == NULL) {
+ *error_message = "missing ]";
+ return -1;
+ }
+ *p1 = '\0';
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ tmp->name = strdup(p+1);
+ if (tmp->name == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ tmp->type = krb5_config_list;
+ tmp->u.list = NULL;
+ tmp->next = NULL;
+ if (*s)
+ (*s)->next = tmp;
+ else
+ *parent = tmp;
+ *s = tmp;
+ return 0;
+}
+
+/*
+ * Parse a brace-enclosed list from `f', hooking in the structure at
+ * `parent'.
+ * Store the error message in `error_message'.
+ */
+
+static int
+parse_list(FILE *f, unsigned *lineno, krb5_config_binding **parent,
+ char **error_message)
+{
+ char buf[BUFSIZ];
+ int ret;
+ krb5_config_binding *b = NULL;
+ unsigned beg_lineno = *lineno;
+
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ char *p;
+
+ ++*lineno;
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ p = buf;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '#' || *p == ';' || *p == '\0')
+ continue;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '}')
+ return 0;
+ if (*p == '\0')
+ continue;
+ ret = parse_binding (f, lineno, p, &b, parent, error_message);
+ if (ret)
+ return ret;
+ }
+ *lineno = beg_lineno;
+ *error_message = "unclosed {";
+ return -1;
+}
+
+/*
+ *
+ */
+
+static int
+parse_binding(FILE *f, unsigned *lineno, char *p,
+ krb5_config_binding **b, krb5_config_binding **parent,
+ char **error_message)
+{
+ krb5_config_binding *tmp;
+ char *p1, *p2;
+ int ret = 0;
+
+ p1 = p;
+ while (*p && *p != '=' && !isspace((unsigned char)*p))
+ ++p;
+ if (*p == '\0') {
+ *error_message = "no =";
+ return -1;
+ }
+ p2 = p;
+ while (isspace((unsigned char)*p))
+ ++p;
+ if (*p != '=') {
+ *error_message = "no =";
+ return -1;
+ }
+ ++p;
+ while(isspace((unsigned char)*p))
+ ++p;
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ *p2 = '\0';
+ tmp->name = strdup(p1);
+ tmp->next = NULL;
+ if (*p == '{') {
+ tmp->type = krb5_config_list;
+ tmp->u.list = NULL;
+ ret = parse_list (f, lineno, &tmp->u.list, error_message);
+ } else {
+ p1 = p;
+ p = p1 + strlen(p1);
+ while(p > p1 && isspace((unsigned char)*(p-1)))
+ --p;
+ *p = '\0';
+ tmp->type = krb5_config_string;
+ tmp->u.string = strdup(p1);
+ }
+ if (*b)
+ (*b)->next = tmp;
+ else
+ *parent = tmp;
+ *b = tmp;
+ return ret;
+}
+
+/*
+ * Parse the config file `fname', generating the structures into `res'
+ * returning error messages in `error_message'
+ */
+
+krb5_error_code
+krb5_config_parse_file_debug (const char *fname,
+ krb5_config_section **res,
+ unsigned *lineno,
+ char **error_message)
+{
+ FILE *f;
+ krb5_config_section *s;
+ krb5_config_binding *b;
+ char buf[BUFSIZ];
+ int ret;
+
+ s = NULL;
+ b = NULL;
+ *lineno = 0;
+ f = fopen (fname, "r");
+ if (f == NULL) {
+ *error_message = "cannot open file";
+ return -1;
+ }
+ *res = NULL;
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ char *p;
+
+ ++*lineno;
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ p = buf;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '#' || *p == ';')
+ continue;
+ if (*p == '[') {
+ ret = parse_section(p, &s, res, error_message);
+ if (ret)
+ return ret;
+ b = NULL;
+ } else if (*p == '}') {
+ *error_message = "unmatched }";
+ return -1;
+ } else if(*p != '\0') {
+ ret = parse_binding(f, lineno, p, &b, &s->u.list, error_message);
+ if (ret)
+ return ret;
+ }
+ }
+ fclose (f);
+ return 0;
+}
+
+krb5_error_code
+krb5_config_parse_file (const char *fname, krb5_config_section **res)
+{
+ char *foo;
+ unsigned lineno;
+
+ return krb5_config_parse_file_debug (fname, res, &lineno, &foo);
+}
+
+#endif /* !HAVE_NETINFO */
+
+static void
+free_binding (krb5_context context, krb5_config_binding *b)
+{
+ krb5_config_binding *next_b;
+
+ while (b) {
+ free (b->name);
+ if (b->type == krb5_config_string)
+ free (b->u.string);
+ else if (b->type == krb5_config_list)
+ free_binding (context, b->u.list);
+ else
+ krb5_abortx(context, "unknown binding type (%d) in free_binding",
+ b->type);
+ next_b = b->next;
+ free (b);
+ b = next_b;
+ }
+}
+
+krb5_error_code
+krb5_config_file_free (krb5_context context, krb5_config_section *s)
+{
+ free_binding (context, s);
+ return 0;
+}
+
+const void *
+krb5_config_get_next (krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, type);
+ ret = krb5_config_vget_next (context, c, pointer, type, args);
+ va_end(args);
+ return ret;
+}
+
+const void *
+krb5_config_vget_next (krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ va_list args)
+{
+ krb5_config_binding *b;
+ const char *p;
+
+ if(c == NULL)
+ c = context->cf;
+
+ if (c == NULL)
+ return NULL;
+
+ if (*pointer == NULL) {
+ b = (c != NULL) ? c : context->cf;
+ p = va_arg(args, const char *);
+ if (p == NULL)
+ return NULL;
+ } else {
+ b = *pointer;
+ p = b->name;
+ b = b->next;
+ }
+
+ while (b) {
+ if (strcmp (b->name, p) == 0) {
+ if (*pointer == NULL)
+ p = va_arg(args, const char *);
+ else
+ p = NULL;
+ if (type == b->type && p == NULL) {
+ *pointer = b;
+ return b->u.generic;
+ } else if(b->type == krb5_config_list && p != NULL) {
+ b = b->u.list;
+ } else {
+ return NULL;
+ }
+ } else {
+ b = b->next;
+ }
+ }
+ return NULL;
+}
+
+const void *
+krb5_config_get (krb5_context context,
+ krb5_config_section *c,
+ int type,
+ ...)
+{
+ const void *ret;
+ va_list args;
+
+ va_start(args, type);
+ ret = krb5_config_vget (context, c, type, args);
+ va_end(args);
+ return ret;
+}
+
+const void *
+krb5_config_vget (krb5_context context,
+ krb5_config_section *c,
+ int type,
+ va_list args)
+{
+ krb5_config_binding *foo = NULL;
+
+ return krb5_config_vget_next (context, c, &foo, type, args);
+}
+
+const krb5_config_binding *
+krb5_config_get_list (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ const krb5_config_binding *ret;
+ va_list args;
+
+ va_start(args, c);
+ ret = krb5_config_vget_list (context, c, args);
+ va_end(args);
+ return ret;
+}
+
+const krb5_config_binding *
+krb5_config_vget_list (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget (context, c, krb5_config_list, args);
+}
+
+const char *
+krb5_config_get_string (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, c);
+ ret = krb5_config_vget_string (context, c, args);
+ va_end(args);
+ return ret;
+}
+
+const char *
+krb5_config_vget_string (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget (context, c, krb5_config_string, args);
+}
+
+char **
+krb5_config_vget_strings(krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ char **strings = NULL;
+ int nstr = 0;
+ krb5_config_binding *b = NULL;
+ const char *p;
+
+ while((p = krb5_config_vget_next(context, c, &b,
+ krb5_config_string, args))) {
+ char *tmp = strdup(p);
+ char *pos = NULL;
+ char *s;
+ if(tmp == NULL)
+ goto cleanup;
+ s = strtok_r(tmp, " \t", &pos);
+ while(s){
+ char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
+ if(tmp == NULL)
+ goto cleanup;
+ strings = tmp;
+ strings[nstr] = strdup(s);
+ nstr++;
+ if(strings[nstr-1] == NULL)
+ goto cleanup;
+ s = strtok_r(NULL, " \t", &pos);
+ }
+ free(tmp);
+ }
+ if(nstr){
+ char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
+ if(strings == NULL)
+ goto cleanup;
+ strings = tmp;
+ strings[nstr] = NULL;
+ }
+ return strings;
+cleanup:
+ while(nstr--)
+ free(strings[nstr]);
+ free(strings);
+ return NULL;
+
+}
+
+char**
+krb5_config_get_strings(krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ char **ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_strings(context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+void
+krb5_config_free_strings(char **strings)
+{
+ char **s = strings;
+ while(s && *s){
+ free(*s);
+ s++;
+ }
+ free(strings);
+}
+
+krb5_boolean
+krb5_config_vget_bool_default (krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ va_list args)
+{
+ const char *str;
+ str = krb5_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ if(strcasecmp(str, "yes") == 0 ||
+ strcasecmp(str, "true") == 0 ||
+ atoi(str)) return TRUE;
+ return FALSE;
+}
+
+krb5_boolean
+krb5_config_vget_bool (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget_bool_default (context, c, FALSE, args);
+}
+
+krb5_boolean
+krb5_config_get_bool_default (krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ ...)
+{
+ va_list ap;
+ krb5_boolean ret;
+ va_start(ap, def_value);
+ ret = krb5_config_vget_bool_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+krb5_boolean
+krb5_config_get_bool (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ krb5_boolean ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_bool (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+krb5_config_vget_time_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args)
+{
+ const char *str;
+ str = krb5_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ return parse_time (str, NULL);
+}
+
+int
+krb5_config_vget_time (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget_time_default (context, c, -1, args);
+}
+
+int
+krb5_config_get_time_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, def_value);
+ ret = krb5_config_vget_time_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+krb5_config_get_time (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_time (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+int
+krb5_config_vget_int_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args)
+{
+ const char *str;
+ str = krb5_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ else {
+ char *endptr;
+ long l;
+ l = strtol(str, &endptr, 0);
+ if (endptr == str)
+ return def_value;
+ else
+ return l;
+ }
+}
+
+int
+krb5_config_vget_int (krb5_context context,
+ krb5_config_section *c,
+ va_list args)
+{
+ return krb5_config_vget_int_default (context, c, -1, args);
+}
+
+int
+krb5_config_get_int_default (krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, def_value);
+ ret = krb5_config_vget_int_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+krb5_config_get_int (krb5_context context,
+ krb5_config_section *c,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, c);
+ ret = krb5_config_vget_int (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+#ifdef TEST
+
+static int print_list (krb5_context context, FILE *f,
+ krb5_config_binding *l, unsigned level);
+static int print_binding (krb5_context context, FILE *f,
+ krb5_config_binding *b, unsigned level);
+static int print_section (krb5_context context, FILE *f,
+ krb5_config_section *s, unsigned level);
+static int print_config (krb5_context context, FILE *f,
+ krb5_config_section *c);
+
+static void
+tab (FILE *f, unsigned count)
+{
+ while(count--)
+ fprintf (f, "\t");
+}
+
+static int
+print_list (krb5_context context,
+ FILE *f,
+ krb5_config_binding *l,
+ unsigned level)
+{
+ while(l) {
+ print_binding (context, f, l, level);
+ l = l->next;
+ }
+ return 0;
+}
+
+static int
+print_binding (krb5_context context,
+ FILE *f,
+ krb5_config_binding *b,
+ unsigned level)
+{
+ tab (f, level);
+ fprintf (f, "%s = ", b->name);
+ if (b->type == krb5_config_string)
+ fprintf (f, "%s\n", b->u.string);
+ else if (b->type == krb5_config_list) {
+ fprintf (f, "{\n");
+ print_list (f, b->u.list, level + 1);
+ tab (f, level);
+ fprintf (f, "}\n");
+ } else
+ krb5_abortx(context, "unknown binding type (%d) in print_binding",
+ b->type);
+ return 0;
+}
+
+static int
+print_section (FILE *f, krb5_config_section *s, unsigned level)
+{
+ fprintf (f, "[%s]\n", s->name);
+ print_list (f, s->u.list, level + 1);
+ return 0;
+}
+
+static int
+print_config (FILE *f, krb5_config_section *c)
+{
+ while (c) {
+ print_section (f, c, 0);
+ c = c->next;
+ }
+ return 0;
+}
+
+
+int
+main(void)
+{
+ krb5_config_section *c;
+
+ printf ("%d\n", krb5_config_parse_file ("/etc/krb5.conf", &c));
+ print_config (stdout, c);
+ printf ("[libdefaults]ticket_lifetime = %s\n",
+ krb5_config_get_string (context, c,
+ "libdefaults",
+ "ticket_lifetime",
+ NULL));
+ printf ("[realms]foo = %s\n",
+ krb5_config_get_string (context, c,
+ "realms",
+ "foo",
+ NULL));
+ printf ("[realms]ATHENA.MIT.EDU/v4_instance_convert/lithium = %s\n",
+ krb5_config_get_string (context, c,
+ "realms",
+ "ATHENA.MIT.EDU",
+ "v4_instance_convert",
+ "lithium",
+ NULL));
+ return 0;
+}
+
+#endif /* TEST */
diff --git a/crypto/heimdal/lib/krb5/config_file_netinfo.c b/crypto/heimdal/lib/krb5/config_file_netinfo.c
new file mode 100644
index 0000000..aeb939a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/config_file_netinfo.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: config_file_netinfo.c,v 1.2 1999/12/02 17:05:08 joda Exp $");
+
+/*
+ * Netinfo implementation from Luke Howard <lukeh@xedoc.com.au>
+ */
+
+#ifdef HAVE_NETINFO
+#include <netinfo/ni.h>
+static ni_status
+ni_proplist2binding(ni_proplist *pl, krb5_config_section **ret)
+{
+ int i, j;
+ krb5_config_section **next = NULL;
+
+ for (i = 0; i < pl->ni_proplist_len; i++) {
+ if (!strcmp(pl->nipl_val[i].nip_name, "name"))
+ continue;
+
+ for (j = 0; j < pl->nipl_val[i].nip_val.ni_namelist_len; j++) {
+ krb5_config_binding *b;
+
+ b = malloc(sizeof(*b));
+ if (b == NULL)
+ return NI_FAILED;
+
+ b->next = NULL;
+ b->type = krb5_config_string;
+ b->name = ni_name_dup(pl->nipl_val[i].nip_name);
+ b->u.string = ni_name_dup(pl->nipl_val[i].nip_val.ninl_val[j]);
+
+ if (next == NULL) {
+ *ret = b;
+ } else {
+ *next = b;
+ }
+ next = &b->next;
+ }
+ }
+ return NI_OK;
+}
+
+static ni_status
+ni_idlist2binding(void *ni, ni_idlist *idlist, krb5_config_section **ret)
+{
+ int i;
+ ni_status nis;
+ krb5_config_section **next;
+
+ for (i = 0; i < idlist->ni_idlist_len; i++) {
+ ni_proplist pl;
+ ni_id nid;
+ ni_idlist children;
+ krb5_config_binding *b;
+ ni_index index;
+
+ nid.nii_instance = 0;
+ nid.nii_object = idlist->ni_idlist_val[i];
+
+ nis = ni_read(ni, &nid, &pl);
+
+ if (nis != NI_OK) {
+ return nis;
+ }
+ index = ni_proplist_match(pl, "name", NULL);
+ b = malloc(sizeof(*b));
+ if (b == NULL) return NI_FAILED;
+
+ if (i == 0) {
+ *ret = b;
+ } else {
+ *next = b;
+ }
+
+ b->type = krb5_config_list;
+ b->name = ni_name_dup(pl.nipl_val[index].nip_val.ninl_val[0]);
+ b->next = NULL;
+ b->u.list = NULL;
+
+ /* get the child directories */
+ nis = ni_children(ni, &nid, &children);
+ if (nis == NI_OK) {
+ nis = ni_idlist2binding(ni, &children, &b->u.list);
+ if (nis != NI_OK) {
+ return nis;
+ }
+ }
+
+ nis = ni_proplist2binding(&pl, b->u.list == NULL ? &b->u.list : &b->u.list->next);
+ ni_proplist_free(&pl);
+ if (nis != NI_OK) {
+ return nis;
+ }
+ next = &b->next;
+ }
+ ni_idlist_free(idlist);
+ return NI_OK;
+}
+
+krb5_error_code
+krb5_config_parse_file (const char *fname, krb5_config_section **res)
+{
+ void *ni = NULL, *lastni = NULL;
+ int i;
+ ni_status nis;
+ ni_id nid;
+ ni_idlist children;
+
+ krb5_config_section *s;
+ int ret;
+
+ s = NULL;
+
+ for (i = 0; i < 256; i++) {
+ if (i == 0) {
+ nis = ni_open(NULL, ".", &ni);
+ } else {
+ if (lastni != NULL) ni_free(lastni);
+ lastni = ni;
+ nis = ni_open(lastni, "..", &ni);
+ }
+ if (nis != NI_OK)
+ break;
+ nis = ni_pathsearch(ni, &nid, "/locations/kerberos");
+ if (nis == NI_OK) {
+ nis = ni_children(ni, &nid, &children);
+ if (nis != NI_OK)
+ break;
+ nis = ni_idlist2binding(ni, &children, &s);
+ break;
+ }
+ }
+
+ if (ni != NULL) ni_free(ni);
+ if (ni != lastni && lastni != NULL) ni_free(lastni);
+
+ ret = (nis == NI_OK) ? 0 : -1;
+ if (ret == 0) {
+ *res = s;
+ } else {
+ *res = NULL;
+ }
+ return ret;
+}
+#endif /* HAVE_NETINFO */
diff --git a/crypto/heimdal/lib/krb5/constants.c b/crypto/heimdal/lib/krb5/constants.c
new file mode 100644
index 0000000..8314c26
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/constants.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: constants.c,v 1.4 1999/12/02 17:05:08 joda Exp $");
+
+const char krb5_config_file[] = "/etc/krb5.conf";
+const char krb5_defkeyname[] = "/etc/v5srvtab";
diff --git a/crypto/heimdal/lib/krb5/context.c b/crypto/heimdal/lib/krb5/context.c
new file mode 100644
index 0000000..cf25f7b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/context.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: context.c,v 1.51 1999/12/02 17:05:08 joda Exp $");
+
+#define INIT_FIELD(C, T, E, D, F) \
+ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \
+ "libdefaults", F, NULL)
+
+#ifdef KRB4
+extern krb5_kt_ops krb4_fkt_ops;
+#endif
+
+/*
+ * Set the list of etypes `ret_etypes' from the configuration variable
+ * `name'
+ */
+
+static krb5_error_code
+set_etypes (krb5_context context,
+ const char *name,
+ krb5_enctype **ret_enctypes)
+{
+ char **etypes_str;
+ krb5_enctype *etypes;
+
+ etypes_str = krb5_config_get_strings(context, NULL, "libdefaults",
+ name, NULL);
+ if(etypes_str){
+ int i, j, k;
+ for(i = 0; etypes_str[i]; i++);
+ etypes = malloc((i+1) * sizeof(*etypes));
+ if (etypes == NULL) {
+ krb5_config_free_strings (etypes_str);
+ return ENOMEM;
+ }
+ for(j = 0, k = 0; j < i; j++) {
+ if(krb5_string_to_enctype(context, etypes_str[j], &etypes[k]) == 0)
+ k++;
+ }
+ etypes[k] = ETYPE_NULL;
+ krb5_config_free_strings(etypes_str);
+ *ret_enctypes = etypes;
+ }
+ return 0;
+}
+
+/*
+ * read variables from the configuration file and set in `context'
+ */
+
+static krb5_error_code
+init_context_from_config_file(krb5_context context)
+{
+ const char * tmp;
+ INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew");
+ INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout");
+ INIT_FIELD(context, int, max_retries, 3, "max_retries");
+
+ context->http_proxy = krb5_config_get_string(context, NULL, "libdefaults",
+ "http_proxy", NULL);
+
+ set_etypes (context, "default_etypes", &context->etypes);
+ set_etypes (context, "default_etypes_des", &context->etypes_des);
+
+ /* default keytab name */
+ context->default_keytab = krb5_config_get_string(context, NULL,
+ "libdefaults",
+ "default_keytab_name",
+ NULL);
+ if(context->default_keytab == NULL)
+ context->default_keytab = KEYTAB_DEFAULT;
+
+ context->time_fmt = krb5_config_get_string(context, NULL, "libdefaults",
+ "time_format", NULL);
+ if(context->time_fmt == NULL)
+ context->time_fmt = "%d-%b-%Y %H:%M:%S";
+ context->log_utc = krb5_config_get_bool(context, NULL, "libdefaults",
+ "log_utc", NULL);
+
+ /* init dns-proxy slime */
+ tmp = krb5_config_get_string(context, NULL, "libdefaults",
+ "dns_proxy", NULL);
+ if(tmp)
+ roken_gethostby_setup(context->http_proxy, tmp);
+ context->default_realms = NULL;
+
+ {
+ krb5_addresses addresses;
+ char **adr, **a;
+ adr = krb5_config_get_strings(context, NULL,
+ "libdefaults",
+ "extra_addresses",
+ NULL);
+ memset(&addresses, 0, sizeof(addresses));
+ for(a = adr; a && *a; a++) {
+ krb5_parse_address(context, *a, &addresses);
+ krb5_add_extra_addresses(context, &addresses);
+ krb5_free_addresses(context, &addresses);
+ }
+ krb5_config_free_strings(adr);
+ }
+
+ INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces");
+ INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
+ INIT_FIELD(context, bool, srv_try_txt, FALSE, "srv_try_txt");
+ INIT_FIELD(context, bool, srv_try_rfc2052, TRUE, "srv_try_rfc2052");
+ INIT_FIELD(context, int, fcache_vno, 0, "fcache_version");
+
+ context->cc_ops = NULL;
+ context->num_cc_ops = 0;
+ krb5_cc_register(context, &krb5_fcc_ops, TRUE);
+ krb5_cc_register(context, &krb5_mcc_ops, TRUE);
+
+ context->num_kt_types = 0;
+ context->kt_types = NULL;
+ krb5_kt_register (context, &krb5_fkt_ops);
+ krb5_kt_register (context, &krb5_mkt_ops);
+#ifdef KRB4
+ krb5_kt_register (context, &krb4_fkt_ops);
+#endif
+ krb5_kt_register (context, &krb5_akf_ops);
+ return 0;
+}
+
+krb5_error_code
+krb5_init_context(krb5_context *context)
+{
+ krb5_context p;
+ const char *config_file = NULL;
+ krb5_config_section *tmp_cf;
+ krb5_error_code ret;
+
+ ALLOC(p, 1);
+ if(!p)
+ return ENOMEM;
+ memset(p, 0, sizeof(krb5_context_data));
+
+ /* init error tables */
+ krb5_init_ets(p);
+
+ if(!issuid())
+ config_file = getenv("KRB5_CONFIG");
+ if (config_file == NULL)
+ config_file = krb5_config_file;
+
+ ret = krb5_config_parse_file (config_file, &tmp_cf);
+
+ if (ret == 0)
+ p->cf = tmp_cf;
+#if 0
+ else
+ krb5_warnx (p, "Unable to parse config file %s. Ignoring.",
+ config_file); /* XXX */
+#endif
+
+ ret = init_context_from_config_file(p);
+ if(ret)
+ return ret;
+
+ *context = p;
+ return 0;
+}
+
+void
+krb5_free_context(krb5_context context)
+{
+ int i;
+
+ free(context->etypes);
+ free(context->etypes_des);
+ krb5_free_host_realm (context, context->default_realms);
+ krb5_config_file_free (context, context->cf);
+ free_error_table (context->et_list);
+ for(i = 0; i < context->num_cc_ops; ++i)
+ free(context->cc_ops[i].prefix);
+ free(context->cc_ops);
+ free(context->kt_types);
+ free(context);
+}
+
+static krb5_error_code
+default_etypes(krb5_enctype **etype)
+{
+ krb5_enctype p[] = {
+ ETYPE_DES3_CBC_SHA1,
+ ETYPE_DES3_CBC_MD5,
+ ETYPE_DES_CBC_MD5,
+ ETYPE_DES_CBC_MD4,
+ ETYPE_DES_CBC_CRC,
+ ETYPE_NULL
+ };
+ *etype = malloc(sizeof(p));
+ if(*etype == NULL)
+ return ENOMEM;
+ memcpy(*etype, p, sizeof(p));
+ return 0;
+}
+
+krb5_error_code
+krb5_set_default_in_tkt_etypes(krb5_context context,
+ const krb5_enctype *etypes)
+{
+ int i;
+ krb5_enctype *p = NULL;
+
+ if(etypes) {
+ i = 0;
+ while(etypes[i])
+ if(!krb5_enctype_valid(context, etypes[i++]))
+ return KRB5_PROG_ETYPE_NOSUPP;
+ ++i;
+ ALLOC(p, i);
+ if(!p)
+ return ENOMEM;
+ memmove(p, etypes, i * sizeof(krb5_enctype));
+ }
+ if(context->etypes)
+ free(context->etypes);
+ context->etypes = p;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_get_default_in_tkt_etypes(krb5_context context,
+ krb5_enctype **etypes)
+{
+ krb5_enctype *p;
+ int i;
+
+ if(context->etypes) {
+ for(i = 0; context->etypes[i]; i++);
+ ++i;
+ ALLOC(p, i);
+ if(!p)
+ return ENOMEM;
+ memmove(p, context->etypes, i * sizeof(krb5_enctype));
+ } else
+ if(default_etypes(&p))
+ return ENOMEM;
+ *etypes = p;
+ return 0;
+}
+
+const char *
+krb5_get_err_text(krb5_context context, krb5_error_code code)
+{
+ const char *p = com_right(context->et_list, code);
+ if(p == NULL)
+ p = strerror(code);
+ return p;
+}
+
+void
+krb5_init_ets(krb5_context context)
+{
+ if(context->et_list == NULL){
+ initialize_krb5_error_table_r(&context->et_list);
+ initialize_asn1_error_table_r(&context->et_list);
+ initialize_heim_error_table_r(&context->et_list);
+ }
+}
+
+void
+krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
+{
+ context->use_admin_kdc = flag;
+}
+
+krb5_boolean
+krb5_get_use_admin_kdc (krb5_context context)
+{
+ return context->use_admin_kdc;
+}
+
+krb5_error_code
+krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
+{
+
+ if(context->extra_addresses)
+ return krb5_append_addresses(context,
+ context->extra_addresses, addresses);
+ else
+ return krb5_set_extra_addresses(context, addresses);
+}
+
+krb5_error_code
+krb5_set_extra_addresses(krb5_context context, krb5_addresses *addresses)
+{
+ if(context->extra_addresses) {
+ krb5_free_addresses(context, context->extra_addresses);
+ free(context->extra_addresses);
+ }
+ if(context->extra_addresses == NULL) {
+ context->extra_addresses = malloc(sizeof(*context->extra_addresses));
+ if(context->extra_addresses == NULL)
+ return ENOMEM;
+ }
+ return copy_HostAddresses(addresses, context->extra_addresses);
+}
+
+krb5_error_code
+krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
+{
+ if(context->extra_addresses == NULL) {
+ memset(addresses, 0, sizeof(*addresses));
+ return 0;
+ }
+ return copy_HostAddresses(context->extra_addresses, addresses);
+}
+
+krb5_error_code
+krb5_set_fcache_version(krb5_context context, int version)
+{
+ context->fcache_vno = version;
+ return 0;
+}
+
+krb5_error_code
+krb5_get_fcache_version(krb5_context context, int *version)
+{
+ *version = context->fcache_vno;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/convert_creds.c b/crypto/heimdal/lib/krb5/convert_creds.c
new file mode 100644
index 0000000..24dea0b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/convert_creds.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: convert_creds.c,v 1.13 1999/12/02 17:05:08 joda Exp $");
+
+static krb5_error_code
+check_ticket_flags(TicketFlags f)
+{
+ return 0; /* maybe add some more tests here? */
+}
+
+/* include this here, to avoid dependencies on libkrb */
+
+#define MAX_KTXT_LEN 1250
+
+#define ANAME_SZ 40
+#define REALM_SZ 40
+#define SNAME_SZ 40
+#define INST_SZ 40
+
+struct ktext {
+ unsigned int length; /* Length of the text */
+ unsigned char dat[MAX_KTXT_LEN]; /* The data itself */
+ u_int32_t mbz; /* zero to catch runaway strings */
+};
+
+struct credentials {
+ char service[ANAME_SZ]; /* Service name */
+ char instance[INST_SZ]; /* Instance */
+ char realm[REALM_SZ]; /* Auth domain */
+ des_cblock session; /* Session key */
+ int lifetime; /* Lifetime */
+ int kvno; /* Key version number */
+ struct ktext ticket_st; /* The ticket itself */
+ int32_t issue_date; /* The issue time */
+ char pname[ANAME_SZ]; /* Principal's name */
+ char pinst[INST_SZ]; /* Principal's instance */
+};
+
+
+#define TKTLIFENUMFIXED 64
+#define TKTLIFEMINFIXED 0x80
+#define TKTLIFEMAXFIXED 0xBF
+#define TKTLIFENOEXPIRE 0xFF
+#define MAXTKTLIFETIME (30*24*3600) /* 30 days */
+#ifndef NEVERDATE
+#define NEVERDATE ((time_t)0x7fffffffL)
+#endif
+
+static const int _tkt_lifetimes[TKTLIFENUMFIXED] = {
+ 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318,
+ 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684,
+ 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720,
+ 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116,
+ 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904,
+ 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303,
+ 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247,
+ 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000
+};
+
+static int
+_krb_time_to_life(time_t start, time_t end)
+{
+ int i;
+ time_t life = end - start;
+
+ if (life > MAXTKTLIFETIME || life <= 0)
+ return 0;
+#if 0
+ if (krb_no_long_lifetimes)
+ return (life + 5*60 - 1)/(5*60);
+#endif
+
+ if (end >= NEVERDATE)
+ return TKTLIFENOEXPIRE;
+ if (life < _tkt_lifetimes[0])
+ return (life + 5*60 - 1)/(5*60);
+ for (i=0; i<TKTLIFENUMFIXED; i++)
+ if (life <= _tkt_lifetimes[i])
+ return i + TKTLIFEMINFIXED;
+ return 0;
+
+}
+
+/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'.
+ * This is done by sending them to the 524 function in the KDC. If
+ * `in_cred' doesn't contain a DES session key, then a new one is
+ * gotten from the KDC and stored in the cred cache `ccache'.
+ */
+
+krb5_error_code
+krb524_convert_creds_kdc(krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_cred,
+ struct credentials *v4creds)
+{
+ krb5_error_code ret;
+ krb5_data reply;
+ krb5_storage *sp;
+ int32_t tmp;
+ krb5_data ticket;
+ char realm[REALM_SZ];
+ krb5_creds *v5_creds = in_cred;
+ krb5_keytype keytype;
+
+ ret = krb5_enctype_to_keytype (context, v5_creds->session.keytype,
+ &keytype);
+ if (ret)
+ return ret;
+
+ if (keytype != KEYTYPE_DES) {
+ krb5_creds template;
+
+ memset (&template, 0, sizeof(template));
+ template.session.keytype = KEYTYPE_DES;
+ ret = krb5_copy_principal (context, in_cred->client, &template.client);
+ if (ret) {
+ krb5_free_creds_contents (context, &template);
+ return ret;
+ }
+ ret = krb5_copy_principal (context, in_cred->server, &template.server);
+ if (ret) {
+ krb5_free_creds_contents (context, &template);
+ return ret;
+ }
+
+ ret = krb5_get_credentials (context, 0, ccache,
+ &template, &v5_creds);
+ krb5_free_creds_contents (context, &template);
+ if (ret)
+ return ret;
+ }
+
+ ret = check_ticket_flags(v5_creds->flags.b);
+ if(ret)
+ goto out2;
+
+ ret = krb5_sendto_kdc (context,
+ &v5_creds->ticket,
+ krb5_princ_realm(context, v5_creds->server),
+ &reply);
+ if (ret)
+ goto out2;
+ sp = krb5_storage_from_mem(reply.data, reply.length);
+ if(sp == NULL) {
+ ret = ENOMEM;
+ goto out2;
+ }
+ krb5_ret_int32(sp, &tmp);
+ ret = tmp;
+ if(ret == 0) {
+ memset(v4creds, 0, sizeof(*v4creds));
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret) goto out;
+ v4creds->kvno = tmp;
+ ret = krb5_ret_data(sp, &ticket);
+ if(ret) goto out;
+ v4creds->ticket_st.length = ticket.length;
+ memcpy(v4creds->ticket_st.dat, ticket.data, ticket.length);
+ krb5_data_free(&ticket);
+ ret = krb5_524_conv_principal(context,
+ v5_creds->server,
+ v4creds->service,
+ v4creds->instance,
+ v4creds->realm);
+ if(ret) goto out;
+ v4creds->issue_date = v5_creds->times.authtime;
+ v4creds->lifetime = _krb_time_to_life(v4creds->issue_date,
+ v5_creds->times.endtime);
+ ret = krb5_524_conv_principal(context, v5_creds->client,
+ v4creds->pname,
+ v4creds->pinst,
+ realm);
+ if(ret) goto out;
+ memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8);
+ }
+out:
+ krb5_storage_free(sp);
+ krb5_data_free(&reply);
+out2:
+ if (v5_creds != in_cred)
+ krb5_free_creds (context, v5_creds);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/copy_host_realm.c b/crypto/heimdal/lib/krb5/copy_host_realm.c
new file mode 100644
index 0000000..4a8f3ec
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/copy_host_realm.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: copy_host_realm.c,v 1.3 1999/12/02 17:05:08 joda Exp $");
+
+/*
+ * Copy the list of realms from `from' to `to'.
+ */
+
+krb5_error_code
+krb5_copy_host_realm(krb5_context context,
+ const krb5_realm *from,
+ krb5_realm **to)
+{
+ int n, i;
+ const krb5_realm *p;
+
+ for (n = 0, p = from; *p != NULL; ++p)
+ ++n;
+ ++n;
+ *to = malloc (n * sizeof(**to));
+ if (*to == NULL)
+ return ENOMEM;
+ for (i = 0; i < n; ++i)
+ (*to)[i] = NULL;
+ for (i = 0, p = from; *p != NULL; ++p, ++i) {
+ (*to)[i] = strdup(*p);
+ if ((*to)[i] == NULL) {
+ krb5_free_host_realm (context, *to);
+ return ENOMEM;
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/crc.c b/crypto/heimdal/lib/krb5/crc.c
new file mode 100644
index 0000000..2f9ef95
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/crc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: crc.c,v 1.8 1999/12/02 17:05:08 joda Exp $");
+
+static u_long table[256];
+
+#define CRC_GEN 0xEDB88320L
+
+void
+_krb5_crc_init_table(void)
+{
+ static int flag = 0;
+ unsigned long crc, poly;
+ int i, j;
+
+ if(flag) return;
+ poly = CRC_GEN;
+ for (i = 0; i < 256; i++) {
+ crc = i;
+ for (j = 8; j > 0; j--) {
+ if (crc & 1) {
+ crc = (crc >> 1) ^ poly;
+ } else {
+ crc >>= 1;
+ }
+ }
+ table[i] = crc;
+ }
+ flag = 1;
+}
+
+u_int32_t
+_krb5_crc_update (char *p, size_t len, u_int32_t res)
+{
+ while (len--)
+ res = table[(res ^ *p++) & 0xFF] ^ (res >> 8);
+ return res & 0xFFFFFFFF;
+}
diff --git a/crypto/heimdal/lib/krb5/creds.c b/crypto/heimdal/lib/krb5/creds.c
new file mode 100644
index 0000000..7051168
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/creds.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: creds.c,v 1.14 1999/12/02 17:05:08 joda Exp $");
+
+krb5_error_code
+krb5_free_cred_contents (krb5_context context, krb5_creds *c)
+{
+ return krb5_free_creds_contents (context, c);
+}
+
+krb5_error_code
+krb5_free_creds_contents (krb5_context context, krb5_creds *c)
+{
+ krb5_free_principal (context, c->client);
+ c->client = NULL;
+ krb5_free_principal (context, c->server);
+ c->server = NULL;
+ krb5_free_keyblock_contents (context, &c->session);
+ krb5_data_free (&c->ticket);
+ krb5_data_free (&c->second_ticket);
+ free_AuthorizationData (&c->authdata);
+ krb5_free_addresses (context, &c->addresses);
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_creds_contents (krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds *c)
+{
+ krb5_error_code ret;
+
+ memset(c, 0, sizeof(*c));
+ ret = krb5_copy_principal (context, incred->client, &c->client);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_principal (context, incred->server, &c->server);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_keyblock_contents (context, &incred->session, &c->session);
+ if (ret)
+ goto fail;
+ c->times = incred->times;
+ ret = krb5_data_copy (&c->ticket,
+ incred->ticket.data,
+ incred->ticket.length);
+ if (ret)
+ goto fail;
+ ret = krb5_data_copy (&c->second_ticket,
+ incred->second_ticket.data,
+ incred->second_ticket.length);
+ if (ret)
+ goto fail;
+ ret = copy_AuthorizationData(&incred->authdata, &c->authdata);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_addresses (context,
+ &incred->addresses,
+ &c->addresses);
+ if (ret)
+ goto fail;
+ c->flags = incred->flags;
+ return 0;
+
+fail:
+ krb5_free_creds_contents (context, c);
+ return ret;
+}
+
+krb5_error_code
+krb5_copy_creds (krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds **outcred)
+{
+ krb5_creds *c;
+
+ c = malloc (sizeof (*c));
+ if (c == NULL)
+ return ENOMEM;
+ memset (c, 0, sizeof(*c));
+ *outcred = c;
+ return krb5_copy_creds_contents (context, incred, c);
+}
+
+krb5_error_code
+krb5_free_creds (krb5_context context, krb5_creds *c)
+{
+ krb5_free_creds_contents (context, c);
+ free (c);
+ return 0;
+}
+
+/*
+ * Return TRUE if `mcreds' and `creds' are equal (`whichfields'
+ * determines what equal means).
+ */
+
+krb5_boolean
+krb5_compare_creds(krb5_context context, krb5_flags whichfields,
+ const krb5_creds *mcreds, const krb5_creds *creds)
+{
+ krb5_boolean match;
+
+ if(whichfields & KRB5_TC_DONT_MATCH_REALM)
+ match = krb5_principal_compare_any_realm(context,
+ mcreds->server,
+ creds->server);
+ else
+ match = krb5_principal_compare(context, mcreds->server, creds->server);
+ if(match && (whichfields & KRB5_TC_MATCH_KEYTYPE) &&
+ !krb5_enctypes_compatible_keys (context,
+ mcreds->session.keytype,
+ creds->session.keytype))
+ match = FALSE;
+ return match;
+}
diff --git a/crypto/heimdal/lib/krb5/crypto.c b/crypto/heimdal/lib/krb5/crypto.c
new file mode 100644
index 0000000..b6db6ce
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/crypto.c
@@ -0,0 +1,2314 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: crypto.c,v 1.28 2000/01/06 20:21:13 assar Exp $");
+
+#undef CRYPTO_DEBUG
+#ifdef CRYPTO_DEBUG
+static void krb5_crypto_debug(krb5_context, int, size_t, krb5_keyblock*);
+#endif
+
+
+struct key_data {
+ krb5_keyblock *key;
+ krb5_data *schedule;
+};
+
+struct key_usage {
+ unsigned usage;
+ struct key_data key;
+};
+
+struct krb5_crypto_data {
+ struct encryption_type *et;
+ struct key_data key;
+ int num_key_usage;
+ struct key_usage *key_usage;
+};
+
+#define CRYPTO_ETYPE(C) ((C)->et->type)
+
+/* bits for `flags' below */
+#define F_KEYED 1 /* checksum is keyed */
+#define F_CPROOF 2 /* checksum is collision proof */
+#define F_DERIVED 4 /* uses derived keys */
+#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
+#define F_PSEUDO 16 /* not a real protocol type */
+
+struct salt_type {
+ krb5_salttype type;
+ const char *name;
+ krb5_error_code (*string_to_key)(krb5_context, krb5_enctype, krb5_data,
+ krb5_salt, krb5_keyblock*);
+};
+
+struct key_type {
+ krb5_keytype type; /* XXX */
+ const char *name;
+ size_t bits;
+ size_t size;
+ size_t schedule_size;
+#if 0
+ krb5_enctype best_etype;
+#endif
+ void (*random_key)(krb5_context, krb5_keyblock*);
+ void (*schedule)(krb5_context, struct key_data *);
+ struct salt_type *string_to_key;
+};
+
+struct checksum_type {
+ krb5_cksumtype type;
+ const char *name;
+ size_t blocksize;
+ size_t checksumsize;
+ unsigned flags;
+ void (*checksum)(krb5_context, struct key_data*, void*, size_t, Checksum*);
+ krb5_error_code (*verify)(krb5_context, struct key_data*,
+ void*, size_t, Checksum*);
+};
+
+struct encryption_type {
+ krb5_enctype type;
+ const char *name;
+ size_t blocksize;
+ size_t confoundersize;
+ struct key_type *keytype;
+ struct checksum_type *cksumtype;
+ struct checksum_type *keyed_checksum;
+ unsigned flags;
+ void (*encrypt)(struct key_data *, void *, size_t, int);
+};
+
+#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
+#define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)
+#define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)
+
+static struct checksum_type *_find_checksum(krb5_cksumtype type);
+static struct encryption_type *_find_enctype(krb5_enctype type);
+static struct key_type *_find_keytype(krb5_keytype type);
+static krb5_error_code _get_derived_key(krb5_context, krb5_crypto,
+ unsigned, struct key_data**);
+static struct key_data *_new_derived_key(krb5_crypto crypto, unsigned usage);
+
+/************************************************************
+ * *
+ ************************************************************/
+
+static void
+DES_random_key(krb5_context context,
+ krb5_keyblock *key)
+{
+ des_cblock *k = key->keyvalue.data;
+ do {
+ krb5_generate_random_block(k, sizeof(des_cblock));
+ des_set_odd_parity(k);
+ } while(des_is_weak_key(k));
+}
+
+static void
+DES_schedule(krb5_context context,
+ struct key_data *key)
+{
+ des_set_key(key->key->keyvalue.data, key->schedule->data);
+}
+
+static krb5_error_code
+DES_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ char *s;
+ size_t len;
+ des_cblock tmp;
+
+ len = password.length + salt.saltvalue.length + 1;
+ s = malloc(len);
+ if(s == NULL)
+ return ENOMEM;
+ memcpy(s, password.data, password.length);
+ memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ s[len - 1] = '\0';
+ des_string_to_key(s, &tmp);
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));
+ memset(&tmp, 0, sizeof(tmp));
+ memset(s, 0, len);
+ free(s);
+ return 0;
+}
+
+/* This defines the Andrew string_to_key function. It accepts a password
+ * string as input and converts its via a one-way encryption algorithm to a DES
+ * encryption key. It is compatible with the original Andrew authentication
+ * service password database.
+ */
+
+/*
+ * Short passwords, i.e 8 characters or less.
+ */
+static void
+DES_AFS3_CMU_string_to_key (krb5_data pw,
+ krb5_data cell,
+ des_cblock *key)
+{
+ char password[8+1]; /* crypt is limited to 8 chars anyway */
+ int i;
+
+ for(i = 0; i < 8; i++) {
+ char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^
+ ((i < cell.length) ? ((char*)cell.data)[i] : 0);
+ password[i] = c ? c : 'X';
+ }
+ password[8] = '\0';
+
+ memcpy(key, crypt(password, "#~") + 2, sizeof(des_cblock));
+
+ /* parity is inserted into the LSB so left shift each byte up one
+ bit. This allows ascii characters with a zero MSB to retain as
+ much significance as possible. */
+ for (i = 0; i < sizeof(des_cblock); i++)
+ ((unsigned char*)key)[i] <<= 1;
+ des_set_odd_parity (key);
+}
+
+/*
+ * Long passwords, i.e 9 characters or more.
+ */
+static void
+DES_AFS3_Transarc_string_to_key (krb5_data pw,
+ krb5_data cell,
+ des_cblock *key)
+{
+ des_key_schedule schedule;
+ des_cblock temp_key;
+ des_cblock ivec;
+ char password[512];
+ size_t passlen;
+
+ memcpy(password, pw.data, min(pw.length, sizeof(password)));
+ if(pw.length < sizeof(password))
+ memcpy(password + pw.length,
+ cell.data, min(cell.length,
+ sizeof(password) - pw.length));
+ passlen = min(sizeof(password), pw.length + cell.length);
+ memcpy(&ivec, "kerberos", 8);
+ memcpy(&temp_key, "kerberos", 8);
+ des_set_odd_parity (&temp_key);
+ des_set_key (&temp_key, schedule);
+ des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
+
+ memcpy(&temp_key, &ivec, 8);
+ des_set_odd_parity (&temp_key);
+ des_set_key (&temp_key, schedule);
+ des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
+ memset(&schedule, 0, sizeof(schedule));
+ memset(&temp_key, 0, sizeof(temp_key));
+ memset(&ivec, 0, sizeof(ivec));
+ memset(password, 0, sizeof(password));
+
+ des_set_odd_parity (key);
+}
+
+static krb5_error_code
+DES_AFS3_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ des_cblock tmp;
+ if(password.length > 8)
+ DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp);
+ else
+ DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp);
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));
+ memset(&key, 0, sizeof(key));
+ return 0;
+}
+
+static void
+DES3_random_key(krb5_context context,
+ krb5_keyblock *key)
+{
+ des_cblock *k = key->keyvalue.data;
+ do {
+ krb5_generate_random_block(k, 3 * sizeof(des_cblock));
+ des_set_odd_parity(&k[0]);
+ des_set_odd_parity(&k[1]);
+ des_set_odd_parity(&k[2]);
+ } while(des_is_weak_key(&k[0]) ||
+ des_is_weak_key(&k[1]) ||
+ des_is_weak_key(&k[2]));
+}
+
+static void
+DES3_schedule(krb5_context context,
+ struct key_data *key)
+{
+ des_cblock *k = key->key->keyvalue.data;
+ des_key_schedule *s = key->schedule->data;
+ des_set_key(&k[0], s[0]);
+ des_set_key(&k[1], s[1]);
+ des_set_key(&k[2], s[2]);
+}
+
+/*
+ * A = A xor B. A & B are 8 bytes.
+ */
+
+static void
+xor (des_cblock *key, const unsigned char *b)
+{
+ unsigned char *a = (unsigned char*)key;
+ a[0] ^= b[0];
+ a[1] ^= b[1];
+ a[2] ^= b[2];
+ a[3] ^= b[3];
+ a[4] ^= b[4];
+ a[5] ^= b[5];
+ a[6] ^= b[6];
+ a[7] ^= b[7];
+}
+
+static krb5_error_code
+DES3_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ char *str;
+ size_t len;
+ unsigned char tmp[24];
+ des_cblock keys[3];
+
+ len = password.length + salt.saltvalue.length;
+ str = malloc(len);
+ if(len != 0 && str == NULL)
+ return ENOMEM;
+ memcpy(str, password.data, password.length);
+ memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ {
+ des_cblock ivec;
+ des_key_schedule s[3];
+ int i;
+
+ _krb5_n_fold(str, len, tmp, 24);
+
+ for(i = 0; i < 3; i++){
+ memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
+ des_set_odd_parity(keys + i);
+ if(des_is_weak_key(keys + i))
+ xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ des_set_key(keys + i, s[i]);
+ }
+ memset(&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt((void*)tmp, (void*)tmp, sizeof(tmp),
+ s[0], s[1], s[2], &ivec, DES_ENCRYPT);
+ memset(s, 0, sizeof(s));
+ memset(&ivec, 0, sizeof(ivec));
+ for(i = 0; i < 3; i++){
+ memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
+ des_set_odd_parity(keys + i);
+ if(des_is_weak_key(keys + i))
+ xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ }
+ memset(tmp, 0, sizeof(tmp));
+ }
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
+ memset(keys, 0, sizeof(keys));
+ memset(str, 0, len);
+ free(str);
+ return 0;
+}
+
+static krb5_error_code
+DES3_string_to_key_derived(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ size_t len = password.length + salt.saltvalue.length;
+ char *s;
+
+ s = malloc(len);
+ if(len != 0 && s == NULL)
+ return ENOMEM;
+ memcpy(s, password.data, password.length);
+ memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ ret = krb5_string_to_key_derived(context,
+ s,
+ len,
+ enctype,
+ key);
+ memset(s, 0, len);
+ free(s);
+ return ret;
+}
+
+/*
+ * ARCFOUR
+ */
+
+static void
+ARCFOUR_random_key(krb5_context context, krb5_keyblock *key)
+{
+ krb5_generate_random_block (key->keyvalue.data,
+ key->keyvalue.length);
+}
+
+static void
+ARCFOUR_schedule(krb5_context context, struct key_data *kd)
+{
+ RC4_set_key (kd->schedule->data,
+ kd->key->keyvalue.length, kd->key->keyvalue.data);
+}
+
+static krb5_error_code
+ARCFOUR_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ char *s, *p;
+ size_t len;
+ int i;
+ struct md4 m;
+
+ len = 2 * (password.length + salt.saltvalue.length);
+ s = malloc (len);
+ if (len != 0 && s == NULL)
+ return ENOMEM;
+ for (p = s, i = 0; i < password.length; ++i) {
+ *p++ = ((char *)password.data)[i];
+ *p++ = 0;
+ }
+ for (i = 0; i < salt.saltvalue.length; ++i) {
+ *p++ = ((char *)salt.saltvalue.data)[i];
+ *p++ = 0;
+ }
+ md4_init(&m);
+ md4_update(&m, s, len);
+ key->keytype = enctype;
+ krb5_data_alloc (&key->keyvalue, 16);
+ md4_finito(&m, key->keyvalue.data);
+ memset (s, 0, len);
+ free (s);
+ return 0;
+}
+
+extern struct salt_type des_salt[],
+ des3_salt[], des3_salt_derived[], arcfour_salt[];
+
+struct key_type keytype_null = {
+ KEYTYPE_NULL,
+ "null",
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct key_type keytype_des = {
+ KEYTYPE_DES,
+ "des",
+ 56,
+ sizeof(des_cblock),
+ sizeof(des_key_schedule),
+ DES_random_key,
+ DES_schedule,
+ des_salt
+};
+
+struct key_type keytype_des3 = {
+ KEYTYPE_DES3,
+ "des3",
+ 168,
+ 3 * sizeof(des_cblock),
+ 3 * sizeof(des_key_schedule),
+ DES3_random_key,
+ DES3_schedule,
+ des3_salt
+};
+
+struct key_type keytype_des3_derived = {
+ KEYTYPE_DES3,
+ "des3",
+ 168,
+ 3 * sizeof(des_cblock),
+ 3 * sizeof(des_key_schedule),
+ DES3_random_key,
+ DES3_schedule,
+ des3_salt_derived
+};
+
+struct key_type keytype_arcfour = {
+ KEYTYPE_ARCFOUR,
+ "arcfour",
+ 128,
+ 16,
+ sizeof(RC4_KEY),
+ ARCFOUR_random_key,
+ ARCFOUR_schedule,
+ arcfour_salt
+};
+
+struct key_type *keytypes[] = {
+ &keytype_null,
+ &keytype_des,
+ &keytype_des3_derived,
+ &keytype_des3,
+ &keytype_arcfour
+};
+
+static int num_keytypes = sizeof(keytypes) / sizeof(keytypes[0]);
+
+static struct key_type *
+_find_keytype(krb5_keytype type)
+{
+ int i;
+ for(i = 0; i < num_keytypes; i++)
+ if(keytypes[i]->type == type)
+ return keytypes[i];
+ return NULL;
+}
+
+
+struct salt_type des_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES_string_to_key
+ },
+ {
+ KRB5_AFS3_SALT,
+ "afs3-salt",
+ DES_AFS3_string_to_key
+ },
+ { 0 }
+};
+
+struct salt_type des3_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES3_string_to_key
+ },
+ { 0 }
+};
+
+struct salt_type des3_salt_derived[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES3_string_to_key_derived
+ },
+ { 0 }
+};
+
+struct salt_type arcfour_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ ARCFOUR_string_to_key
+ },
+ { 0 }
+};
+
+krb5_error_code
+krb5_salttype_to_string (krb5_context context,
+ krb5_enctype etype,
+ krb5_salttype stype,
+ char **string)
+{
+ struct encryption_type *e;
+ struct salt_type *st;
+
+ e = _find_enctype (etype);
+ if (e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ for (st = e->keytype->string_to_key; st && st->type; st++) {
+ if (st->type == stype) {
+ *string = strdup (st->name);
+ if (*string == NULL)
+ return ENOMEM;
+ return 0;
+ }
+ }
+ return HEIM_ERR_SALTTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_string_to_salttype (krb5_context context,
+ krb5_enctype etype,
+ const char *string,
+ krb5_salttype *salttype)
+{
+ struct encryption_type *e;
+ struct salt_type *st;
+
+ e = _find_enctype (etype);
+ if (e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ for (st = e->keytype->string_to_key; st && st->type; st++) {
+ if (strcasecmp (st->name, string) == 0) {
+ *salttype = st->type;
+ return 0;
+ }
+ }
+ return HEIM_ERR_SALTTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_get_pw_salt(krb5_context context,
+ krb5_const_principal principal,
+ krb5_salt *salt)
+{
+ size_t len;
+ int i;
+ krb5_error_code ret;
+ char *p;
+
+ salt->salttype = KRB5_PW_SALT;
+ len = strlen(principal->realm);
+ for (i = 0; i < principal->name.name_string.len; ++i)
+ len += strlen(principal->name.name_string.val[i]);
+ ret = krb5_data_alloc (&salt->saltvalue, len);
+ if (ret)
+ return ret;
+ p = salt->saltvalue.data;
+ memcpy (p, principal->realm, strlen(principal->realm));
+ p += strlen(principal->realm);
+ for (i = 0; i < principal->name.name_string.len; ++i) {
+ memcpy (p,
+ principal->name.name_string.val[i],
+ strlen(principal->name.name_string.val[i]));
+ p += strlen(principal->name.name_string.val[i]);
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_free_salt(krb5_context context,
+ krb5_salt salt)
+{
+ krb5_data_free(&salt.saltvalue);
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_key_data (krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_principal principal,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ krb5_salt salt;
+
+ ret = krb5_get_pw_salt(context, principal, &salt);
+ if(ret)
+ return ret;
+ ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key);
+ krb5_free_salt(context, salt);
+ return ret;
+}
+
+krb5_error_code
+krb5_string_to_key (krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_principal principal,
+ krb5_keyblock *key)
+{
+ krb5_data pw;
+ pw.data = (void*)password;
+ pw.length = strlen(password);
+ return krb5_string_to_key_data(context, enctype, pw, principal, key);
+}
+
+krb5_error_code
+krb5_string_to_key_data_salt (krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ struct encryption_type *et =_find_enctype(enctype);
+ struct salt_type *st;
+ if(et == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ for(st = et->keytype->string_to_key; st && st->type; st++)
+ if(st->type == salt.salttype)
+ return (*st->string_to_key)(context, enctype, password, salt, key);
+ return HEIM_ERR_SALTTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_string_to_key_salt (krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_salt salt,
+ krb5_keyblock *key)
+{
+ krb5_data pw;
+ pw.data = (void*)password;
+ pw.length = strlen(password);
+ return krb5_string_to_key_data_salt(context, enctype, pw, salt, key);
+}
+
+krb5_error_code
+krb5_keytype_to_string(krb5_context context,
+ krb5_keytype keytype,
+ char **string)
+{
+ struct key_type *kt = _find_keytype(keytype);
+ if(kt == NULL)
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+ *string = strdup(kt->name);
+ if(*string == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_keytype(krb5_context context,
+ const char *string,
+ krb5_keytype *keytype)
+{
+ int i;
+ for(i = 0; i < num_keytypes; i++)
+ if(strcasecmp(keytypes[i]->name, string) == 0){
+ *keytype = keytypes[i]->type;
+ return 0;
+ }
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_generate_random_keyblock(krb5_context context,
+ krb5_enctype type,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ struct encryption_type *et = _find_enctype(type);
+ if(et == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ ret = krb5_data_alloc(&key->keyvalue, et->keytype->size);
+ if(ret)
+ return ret;
+ key->keytype = type;
+ if(et->keytype->random_key)
+ (*et->keytype->random_key)(context, key);
+ else
+ krb5_generate_random_block(key->keyvalue.data,
+ key->keyvalue.length);
+ return 0;
+}
+
+static krb5_error_code
+_key_schedule(krb5_context context,
+ struct key_data *key)
+{
+ krb5_error_code ret;
+ struct encryption_type *et = _find_enctype(key->key->keytype);
+ struct key_type *kt = et->keytype;
+
+ if(kt->schedule == NULL)
+ return 0;
+ ALLOC(key->schedule, 1);
+ if(key->schedule == NULL)
+ return ENOMEM;
+ ret = krb5_data_alloc(key->schedule, kt->schedule_size);
+ if(ret) {
+ free(key->schedule);
+ key->schedule = NULL;
+ return ret;
+ }
+ (*kt->schedule)(context, key);
+ return 0;
+}
+
+/************************************************************
+ * *
+ ************************************************************/
+
+static void
+NONE_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+}
+
+static void
+CRC32_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ u_int32_t crc;
+ unsigned char *r = C->checksum.data;
+ _krb5_crc_init_table ();
+ crc = _krb5_crc_update (data, len, 0);
+ r[0] = crc & 0xff;
+ r[1] = (crc >> 8) & 0xff;
+ r[2] = (crc >> 16) & 0xff;
+ r[3] = (crc >> 24) & 0xff;
+}
+
+static void
+RSA_MD4_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md4 m;
+ md4_init(&m);
+ md4_update(&m, data, len);
+ md4_finito(&m, C->checksum.data);
+}
+
+static void
+RSA_MD4_DES_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ struct md4 md4;
+ des_cblock ivec;
+ unsigned char *p = cksum->checksum.data;
+
+ krb5_generate_random_block(p, 8);
+ md4_init(&md4);
+ md4_update(&md4, p, 8);
+ md4_update(&md4, data, len);
+ md4_finito(&md4, p + 8);
+ memset (&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt((des_cblock*)p,
+ (des_cblock*)p,
+ 24,
+ key->schedule->data,
+ &ivec,
+ DES_ENCRYPT);
+}
+
+static krb5_error_code
+RSA_MD4_DES_verify(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md4 md4;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ des_cblock ivec;
+ krb5_error_code ret = 0;
+
+ memset(&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt(C->checksum.data,
+ (void*)tmp,
+ C->checksum.length,
+ key->schedule->data,
+ &ivec,
+ DES_DECRYPT);
+ md4_init(&md4);
+ md4_update(&md4, tmp, 8); /* confounder */
+ md4_update(&md4, data, len);
+ md4_finito(&md4, res);
+ if(memcmp(res, tmp + 8, sizeof(res)) != 0)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+static void
+RSA_MD5_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 m;
+ md5_init(&m);
+ md5_update(&m, data, len);
+ md5_finito(&m, C->checksum.data);
+}
+
+static void
+RSA_MD5_DES_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ des_cblock ivec;
+ unsigned char *p = C->checksum.data;
+
+ krb5_generate_random_block(p, 8);
+ md5_init(&md5);
+ md5_update(&md5, p, 8);
+ md5_update(&md5, data, len);
+ md5_finito(&md5, p + 8);
+ memset (&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt((des_cblock*)p,
+ (des_cblock*)p,
+ 24,
+ key->schedule->data,
+ &ivec,
+ DES_ENCRYPT);
+}
+
+static krb5_error_code
+RSA_MD5_DES_verify(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ des_cblock ivec;
+ des_key_schedule *sched = key->schedule->data;
+ krb5_error_code ret = 0;
+
+ memset(&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt(C->checksum.data,
+ (void*)tmp,
+ C->checksum.length,
+ sched[0],
+ &ivec,
+ DES_DECRYPT);
+ md5_init(&md5);
+ md5_update(&md5, tmp, 8); /* confounder */
+ md5_update(&md5, data, len);
+ md5_finito(&md5, res);
+ if(memcmp(res, tmp + 8, sizeof(res)) != 0)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+static void
+RSA_MD5_DES3_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ des_cblock ivec;
+ unsigned char *p = C->checksum.data;
+ des_key_schedule *sched = key->schedule->data;
+
+ krb5_generate_random_block(p, 8);
+ md5_init(&md5);
+ md5_update(&md5, p, 8);
+ md5_update(&md5, data, len);
+ md5_finito(&md5, p + 8);
+ memset (&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt((des_cblock*)p,
+ (des_cblock*)p,
+ 24,
+ sched[0], sched[1], sched[2],
+ &ivec,
+ DES_ENCRYPT);
+}
+
+static krb5_error_code
+RSA_MD5_DES3_verify(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct md5 md5;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ des_cblock ivec;
+ des_key_schedule *sched = key->schedule->data;
+ krb5_error_code ret = 0;
+
+ memset(&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt(C->checksum.data,
+ (void*)tmp,
+ C->checksum.length,
+ sched[0], sched[1], sched[2],
+ &ivec,
+ DES_DECRYPT);
+ md5_init(&md5);
+ md5_update(&md5, tmp, 8); /* confounder */
+ md5_update(&md5, data, len);
+ md5_finito(&md5, res);
+ if(memcmp(res, tmp + 8, sizeof(res)) != 0)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+static void
+SHA1_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct sha m;
+ sha_init(&m);
+ sha_update(&m, data, len);
+ sha_finito(&m, C->checksum.data);
+}
+
+/* HMAC according to RFC2104 */
+static void
+hmac(krb5_context context,
+ struct checksum_type *cm,
+ void *data,
+ size_t len,
+ struct key_data *keyblock,
+ Checksum *result)
+{
+ unsigned char *ipad, *opad;
+ unsigned char *key;
+ size_t key_len;
+ int i;
+
+ if(keyblock->key->keyvalue.length > cm->blocksize){
+ (*cm->checksum)(context,
+ keyblock,
+ keyblock->key->keyvalue.data,
+ keyblock->key->keyvalue.length,
+ result);
+ key = result->checksum.data;
+ key_len = result->checksum.length;
+ } else {
+ key = keyblock->key->keyvalue.data;
+ key_len = keyblock->key->keyvalue.length;
+ }
+ ipad = malloc(cm->blocksize + len);
+ opad = malloc(cm->blocksize + cm->checksumsize);
+ memset(ipad, 0x36, cm->blocksize);
+ memset(opad, 0x5c, cm->blocksize);
+ for(i = 0; i < key_len; i++){
+ ipad[i] ^= key[i];
+ opad[i] ^= key[i];
+ }
+ memcpy(ipad + cm->blocksize, data, len);
+ (*cm->checksum)(context, keyblock, ipad, cm->blocksize + len, result);
+ memcpy(opad + cm->blocksize, result->checksum.data,
+ result->checksum.length);
+ (*cm->checksum)(context, keyblock, opad,
+ cm->blocksize + cm->checksumsize, result);
+ memset(ipad, 0, cm->blocksize + len);
+ free(ipad);
+ memset(opad, 0, cm->blocksize + cm->checksumsize);
+ free(opad);
+}
+
+static void
+HMAC_SHA1_DES3_checksum(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1);
+
+ hmac(context, c, data, len, key, result);
+}
+
+struct checksum_type checksum_none = {
+ CKSUMTYPE_NONE,
+ "none",
+ 1,
+ 0,
+ 0,
+ NONE_checksum,
+ NULL
+};
+struct checksum_type checksum_crc32 = {
+ CKSUMTYPE_CRC32,
+ "crc32",
+ 1,
+ 4,
+ 0,
+ CRC32_checksum,
+ NULL
+};
+struct checksum_type checksum_rsa_md4 = {
+ CKSUMTYPE_RSA_MD4,
+ "rsa-md4",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD4_checksum,
+ NULL
+};
+struct checksum_type checksum_rsa_md4_des = {
+ CKSUMTYPE_RSA_MD4_DES,
+ "rsa-md4-des",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD4_DES_checksum,
+ RSA_MD4_DES_verify
+};
+#if 0
+struct checksum_type checksum_des_mac = {
+ CKSUMTYPE_DES_MAC,
+ "des-mac",
+ 0,
+ 0,
+ 0,
+ DES_MAC_checksum,
+};
+struct checksum_type checksum_des_mac_k = {
+ CKSUMTYPE_DES_MAC_K,
+ "des-mac-k",
+ 0,
+ 0,
+ 0,
+ DES_MAC_K_checksum,
+};
+struct checksum_type checksum_rsa_md4_des_k = {
+ CKSUMTYPE_RSA_MD4_DES_K,
+ "rsa-md4-des-k",
+ 0,
+ 0,
+ 0,
+ RSA_MD4_DES_K_checksum,
+ RSA_MD4_DES_K_verify,
+};
+#endif
+struct checksum_type checksum_rsa_md5 = {
+ CKSUMTYPE_RSA_MD5,
+ "rsa-md5",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD5_checksum,
+ NULL
+};
+struct checksum_type checksum_rsa_md5_des = {
+ CKSUMTYPE_RSA_MD5_DES,
+ "rsa-md5-des",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD5_DES_checksum,
+ RSA_MD5_DES_verify,
+};
+struct checksum_type checksum_rsa_md5_des3 = {
+ CKSUMTYPE_RSA_MD5_DES3,
+ "rsa-md5-des3",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD5_DES3_checksum,
+ RSA_MD5_DES3_verify,
+};
+struct checksum_type checksum_sha1 = {
+ CKSUMTYPE_SHA1,
+ "sha1",
+ 64,
+ 20,
+ F_CPROOF,
+ SHA1_checksum,
+ NULL
+};
+struct checksum_type checksum_hmac_sha1_des3 = {
+ CKSUMTYPE_HMAC_SHA1_DES3,
+ "hmac-sha1-des3",
+ 64,
+ 20,
+ F_KEYED | F_CPROOF | F_DERIVED,
+ HMAC_SHA1_DES3_checksum,
+ NULL
+};
+
+struct checksum_type *checksum_types[] = {
+ &checksum_none,
+ &checksum_crc32,
+ &checksum_rsa_md4,
+ &checksum_rsa_md4_des,
+#if 0
+ &checksum_des_mac,
+ &checksum_des_mac_k,
+ &checksum_rsa_md4_des_k,
+#endif
+ &checksum_rsa_md5,
+ &checksum_rsa_md5_des,
+ &checksum_rsa_md5_des3,
+ &checksum_sha1,
+ &checksum_hmac_sha1_des3
+};
+
+static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]);
+
+static struct checksum_type *
+_find_checksum(krb5_cksumtype type)
+{
+ int i;
+ for(i = 0; i < num_checksums; i++)
+ if(checksum_types[i]->type == type)
+ return checksum_types[i];
+ return NULL;
+}
+
+static krb5_error_code
+get_checksum_key(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage, /* not krb5_key_usage */
+ struct checksum_type *ct,
+ struct key_data **key)
+{
+ krb5_error_code ret = 0;
+
+ if(ct->flags & F_DERIVED)
+ ret = _get_derived_key(context, crypto, usage, key);
+ else if(ct->flags & F_VARIANT) {
+ int i;
+
+ *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */);
+ if(*key == NULL)
+ return ENOMEM;
+ ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key);
+ if(ret)
+ return ret;
+ for(i = 0; i < (*key)->key->keyvalue.length; i++)
+ ((unsigned char*)(*key)->key->keyvalue.data)[i] ^= 0xF0;
+ } else {
+ *key = &crypto->key;
+ }
+ if(ret == 0)
+ ret = _key_schedule(context, *key);
+ return ret;
+}
+
+static krb5_error_code
+do_checksum (krb5_context context,
+ struct checksum_type *ct,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ krb5_error_code ret;
+ struct key_data *dkey;
+ int keyed_checksum;
+
+ keyed_checksum = (ct->flags & F_KEYED) != 0;
+ if(keyed_checksum && crypto == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
+ if(keyed_checksum)
+ ret = get_checksum_key(context, crypto, usage, ct, &dkey);
+ else
+ dkey = NULL;
+ result->cksumtype = ct->type;
+ krb5_data_alloc(&result->checksum, ct->checksumsize);
+ (*ct->checksum)(context, dkey, data, len, result);
+ return 0;
+}
+
+static krb5_error_code
+create_checksum(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage, /* not krb5_key_usage */
+ krb5_cksumtype type, /* if crypto == NULL */
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ struct checksum_type *ct;
+
+ if(crypto) {
+ ct = crypto->et->keyed_checksum;
+ if(ct == NULL)
+ ct = crypto->et->cksumtype;
+ } else
+ ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ return do_checksum (context, ct, crypto, usage, data, len, result);
+}
+
+krb5_error_code
+krb5_create_checksum(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage_or_type,
+ void *data,
+ size_t len,
+ Checksum *result)
+{
+ return create_checksum(context, crypto,
+ CHECKSUM_USAGE(usage_or_type),
+ usage_or_type, data, len, result);
+}
+
+static krb5_error_code
+verify_checksum(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage, /* not krb5_key_usage */
+ void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ krb5_error_code ret;
+ struct key_data *dkey;
+ int keyed_checksum;
+ Checksum c;
+ struct checksum_type *ct;
+
+ ct = _find_checksum(cksum->cksumtype);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ if(ct->checksumsize != cksum->checksum.length)
+ return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
+ keyed_checksum = (ct->flags & F_KEYED) != 0;
+ if(keyed_checksum && crypto == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
+ if(keyed_checksum)
+ ret = get_checksum_key(context, crypto, usage, ct, &dkey);
+ else
+ dkey = NULL;
+ if(ct->verify)
+ return (*ct->verify)(context, dkey, data, len, cksum);
+
+ ret = krb5_data_alloc (&c.checksum, ct->checksumsize);
+ if (ret)
+ return ret;
+
+ (*ct->checksum)(context, dkey, data, len, &c);
+
+ if(c.checksum.length != cksum->checksum.length ||
+ memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length))
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ else
+ ret = 0;
+ krb5_data_free (&c.checksum);
+ return ret;
+}
+
+krb5_error_code
+krb5_verify_checksum(krb5_context context,
+ krb5_crypto crypto,
+ krb5_key_usage usage,
+ void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ return verify_checksum(context, crypto,
+ CHECKSUM_USAGE(usage), data, len, cksum);
+}
+
+krb5_error_code
+krb5_checksumsize(krb5_context context,
+ krb5_cksumtype type,
+ size_t *size)
+{
+ struct checksum_type *ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ *size = ct->checksumsize;
+ return 0;
+}
+
+krb5_boolean
+krb5_checksum_is_keyed(krb5_context context,
+ krb5_cksumtype type)
+{
+ struct checksum_type *ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ return ct->flags & F_KEYED;
+}
+
+krb5_boolean
+krb5_checksum_is_collision_proof(krb5_context context,
+ krb5_cksumtype type)
+{
+ struct checksum_type *ct = _find_checksum(type);
+ if(ct == NULL)
+ return KRB5_PROG_SUMTYPE_NOSUPP;
+ return ct->flags & F_CPROOF;
+}
+
+/************************************************************
+ * *
+ ************************************************************/
+
+static void
+NULL_encrypt(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+}
+
+static void
+DES_CBC_encrypt_null_ivec(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+ des_cblock ivec;
+ des_key_schedule *s = key->schedule->data;
+ memset(&ivec, 0, sizeof(ivec));
+ des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
+}
+
+static void
+DES_CBC_encrypt_key_ivec(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+ des_cblock ivec;
+ des_key_schedule *s = key->schedule->data;
+ memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
+ des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
+}
+
+static void
+DES3_CBC_encrypt(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+ des_cblock ivec;
+ des_key_schedule *s = key->schedule->data;
+ memset(&ivec, 0, sizeof(ivec));
+ des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], &ivec, encrypt);
+}
+
+static void
+ARCFOUR_encrypt(struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encrypt)
+{
+
+}
+
+/*
+ * these should currently be in reverse preference order.
+ */
+
+static struct encryption_type etypes[] = {
+ {
+ ETYPE_NULL,
+ "null",
+ 1,
+ 0,
+ &keytype_null,
+ &checksum_none,
+ NULL,
+ 0,
+ NULL_encrypt,
+ },
+ {
+ ETYPE_DES_CBC_CRC,
+ "des-cbc-crc",
+ 8,
+ 8,
+ &keytype_des,
+ &checksum_crc32,
+ NULL,
+ 0,
+ DES_CBC_encrypt_key_ivec,
+ },
+ {
+ ETYPE_DES_CBC_MD4,
+ "des-cbc-md4",
+ 8,
+ 8,
+ &keytype_des,
+ &checksum_rsa_md4,
+ &checksum_rsa_md4_des,
+ 0,
+ DES_CBC_encrypt_null_ivec,
+ },
+ {
+ ETYPE_DES_CBC_MD5,
+ "des-cbc-md5",
+ 8,
+ 8,
+ &keytype_des,
+ &checksum_rsa_md5,
+ &checksum_rsa_md5_des,
+ 0,
+ DES_CBC_encrypt_null_ivec,
+ },
+ {
+ ETYPE_DES3_CBC_MD5,
+ "des3-cbc-md5",
+ 8,
+ 8,
+ &keytype_des3,
+ &checksum_rsa_md5,
+ &checksum_rsa_md5_des3,
+ 0,
+ DES3_CBC_encrypt,
+ },
+ {
+ ETYPE_DES3_CBC_SHA1,
+ "des3-cbc-sha1",
+ 8,
+ 8,
+ &keytype_des3_derived,
+ &checksum_sha1,
+ &checksum_hmac_sha1_des3,
+ F_DERIVED,
+ DES3_CBC_encrypt,
+ },
+ {
+ ETYPE_OLD_DES3_CBC_SHA1,
+ "old-des3-cbc-sha1",
+ 8,
+ 8,
+ &keytype_des3,
+ &checksum_sha1,
+ &checksum_hmac_sha1_des3,
+ 0,
+ DES3_CBC_encrypt,
+ },
+ {
+ ETYPE_DES_CBC_NONE,
+ "des-cbc-none",
+ 8,
+ 0,
+ &keytype_des,
+ &checksum_none,
+ NULL,
+ F_PSEUDO,
+ DES_CBC_encrypt_null_ivec,
+ },
+ {
+ ETYPE_DES3_CBC_NONE,
+ "des3-cbc-none",
+ 8,
+ 0,
+ &keytype_des3_derived,
+ &checksum_none,
+ NULL,
+ F_PSEUDO,
+ DES_CBC_encrypt_null_ivec,
+ },
+};
+
+static unsigned num_etypes = sizeof(etypes) / sizeof(etypes[0]);
+
+
+static struct encryption_type *
+_find_enctype(krb5_enctype type)
+{
+ int i;
+ for(i = 0; i < num_etypes; i++)
+ if(etypes[i].type == type)
+ return &etypes[i];
+ return NULL;
+}
+
+
+krb5_error_code
+krb5_enctype_to_string(krb5_context context,
+ krb5_enctype etype,
+ char **string)
+{
+ struct encryption_type *e;
+ e = _find_enctype(etype);
+ if(e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ *string = strdup(e->name);
+ if(*string == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_enctype(krb5_context context,
+ const char *string,
+ krb5_enctype *etype)
+{
+ int i;
+ for(i = 0; i < num_etypes; i++)
+ if(strcasecmp(etypes[i].name, string) == 0){
+ *etype = etypes[i].type;
+ return 0;
+ }
+ return KRB5_PROG_ETYPE_NOSUPP;
+}
+
+krb5_error_code
+krb5_enctype_to_keytype(krb5_context context,
+ krb5_enctype etype,
+ krb5_keytype *keytype)
+{
+ struct encryption_type *e = _find_enctype(etype);
+ if(e == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ *keytype = e->keytype->type; /* XXX */
+ return 0;
+}
+
+#if 0
+krb5_error_code
+krb5_keytype_to_enctype(krb5_context context,
+ krb5_keytype keytype,
+ krb5_enctype *etype)
+{
+ struct key_type *kt = _find_keytype(keytype);
+ krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype);
+ if(kt == NULL)
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+ *etype = kt->best_etype;
+ return 0;
+}
+#endif
+
+krb5_error_code
+krb5_keytype_to_enctypes (krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val)
+{
+ int i;
+ unsigned n = 0;
+ int *ret;
+
+ for (i = num_etypes - 1; i >= 0; --i) {
+ if (etypes[i].keytype->type == keytype
+ && !(etypes[i].flags & F_PSEUDO))
+ ++n;
+ }
+ ret = malloc(n * sizeof(int));
+ if (ret == NULL && n != 0)
+ return ENOMEM;
+ n = 0;
+ for (i = num_etypes - 1; i >= 0; --i) {
+ if (etypes[i].keytype->type == keytype
+ && !(etypes[i].flags & F_PSEUDO))
+ ret[n++] = etypes[i].type;
+ }
+ *len = n;
+ *val = ret;
+ return 0;
+}
+
+/*
+ * First take the configured list of etypes for `keytype' if available,
+ * else, do `krb5_keytype_to_enctypes'.
+ */
+
+krb5_error_code
+krb5_keytype_to_enctypes_default (krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val)
+{
+ int i, n;
+ int *ret;
+
+ if (keytype != KEYTYPE_DES || context->etypes_des == NULL)
+ return krb5_keytype_to_enctypes (context, keytype, len, val);
+
+ for (n = 0; context->etypes_des[n]; ++n)
+ ;
+ ret = malloc (n * sizeof(*ret));
+ if (ret == NULL && n != 0)
+ return ENOMEM;
+ for (i = 0; i < n; ++i)
+ ret[i] = context->etypes_des[i];
+ *len = n;
+ *val = ret;
+ return 0;
+}
+
+krb5_error_code
+krb5_enctype_valid(krb5_context context,
+ krb5_enctype etype)
+{
+ return _find_enctype(etype) != NULL;
+}
+
+/* if two enctypes have compatible keys */
+krb5_boolean
+krb5_enctypes_compatible_keys(krb5_context context,
+ krb5_enctype etype1,
+ krb5_enctype etype2)
+{
+ struct encryption_type *e1 = _find_enctype(etype1);
+ struct encryption_type *e2 = _find_enctype(etype2);
+ return e1 != NULL && e2 != NULL && e1->keytype == e2->keytype;
+}
+
+static krb5_boolean
+derived_crypto(krb5_context context,
+ krb5_crypto crypto)
+{
+ return (crypto->et->flags & F_DERIVED) != 0;
+}
+
+
+#define CHECKSUMSIZE(C) ((C)->checksumsize)
+#define CHECKSUMTYPE(C) ((C)->type)
+
+static krb5_error_code
+encrypt_internal_derived(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ size_t sz, block_sz, checksum_sz;
+ Checksum cksum;
+ unsigned char *p, *q;
+ krb5_error_code ret;
+ struct key_data *dkey;
+ struct encryption_type *et = crypto->et;
+
+ checksum_sz = CHECKSUMSIZE(et->keyed_checksum);
+
+ sz = et->confoundersize + /* 4 - length */ len;
+ block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */
+ p = calloc(1, block_sz + checksum_sz);
+ if(p == NULL)
+ return ENOMEM;
+
+ q = p;
+ krb5_generate_random_block(q, et->confoundersize); /* XXX */
+ q += et->confoundersize;
+ memcpy(q, data, len);
+
+ ret = create_checksum(context,
+ crypto,
+ INTEGRITY_USAGE(usage),
+ 0,
+ p,
+ block_sz,
+ &cksum);
+ if(ret == 0 && cksum.checksum.length != checksum_sz)
+ ret = KRB5_CRYPTO_INTERNAL;
+ if(ret) {
+ memset(p, 0, block_sz + checksum_sz);
+ free(p);
+ return ret;
+ }
+ memcpy(p + block_sz, cksum.checksum.data, cksum.checksum.length);
+ ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
+ if(ret) {
+ memset(p, 0, block_sz + checksum_sz);
+ free(p);
+ return ret;
+ }
+ ret = _key_schedule(context, dkey);
+ if(ret) {
+ memset(p, 0, block_sz);
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 1, block_sz, dkey->key);
+#endif
+ (*et->encrypt)(dkey, p, block_sz, 1);
+ result->data = p;
+ result->length = block_sz + checksum_sz;
+ return 0;
+}
+
+static krb5_error_code
+encrypt_internal(krb5_context context,
+ krb5_crypto crypto,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ size_t sz, block_sz, checksum_sz;
+ Checksum cksum;
+ unsigned char *p, *q;
+ krb5_error_code ret;
+ struct encryption_type *et = crypto->et;
+
+ checksum_sz = CHECKSUMSIZE(et->cksumtype);
+
+ sz = et->confoundersize + checksum_sz + len;
+ block_sz = (sz + et->blocksize - 1) &~ (et->blocksize - 1); /* pad */
+ p = calloc(1, block_sz);
+ if(p == NULL)
+ return ENOMEM;
+
+ q = p;
+ krb5_generate_random_block(q, et->confoundersize); /* XXX */
+ q += et->confoundersize;
+ memset(q, 0, checksum_sz);
+ q += checksum_sz;
+ memcpy(q, data, len);
+
+ ret = create_checksum(context,
+ NULL,
+ 0,
+ CHECKSUMTYPE(et->cksumtype),
+ p,
+ block_sz,
+ &cksum);
+ if(ret == 0 && cksum.checksum.length != checksum_sz) {
+ free_Checksum (&cksum);
+ ret = KRB5_CRYPTO_INTERNAL;
+ }
+ if(ret) {
+ memset(p, 0, block_sz);
+ free(p);
+ free_Checksum(&cksum);
+ return ret;
+ }
+ memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length);
+ free_Checksum(&cksum);
+ ret = _key_schedule(context, &crypto->key);
+ if(ret) {
+ memset(p, 0, block_sz);
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 1, block_sz, crypto->key.key);
+#endif
+ (*et->encrypt)(&crypto->key, p, block_sz, 1);
+ result->data = p;
+ result->length = block_sz;
+ return 0;
+}
+
+static krb5_error_code
+decrypt_internal_derived(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ size_t checksum_sz;
+ Checksum cksum;
+ unsigned char *p;
+ krb5_error_code ret;
+ struct key_data *dkey;
+ struct encryption_type *et = crypto->et;
+ unsigned long l;
+
+ p = malloc(len);
+ if(len != 0 && p == NULL)
+ return ENOMEM;
+ memcpy(p, data, len);
+
+ checksum_sz = CHECKSUMSIZE(et->keyed_checksum);
+ len -= checksum_sz;
+
+ ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ ret = _key_schedule(context, dkey);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 0, len, dkey->key);
+#endif
+ (*et->encrypt)(dkey, p, len, 0);
+
+ cksum.checksum.data = p + len;
+ cksum.checksum.length = checksum_sz;
+ cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum);
+
+ ret = verify_checksum(context,
+ crypto,
+ INTEGRITY_USAGE(usage),
+ p,
+ len,
+ &cksum);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ l = len - et->confoundersize;
+ memmove(p, p + et->confoundersize, l);
+ result->data = realloc(p, l);
+ if(p == NULL) {
+ free(p);
+ return ENOMEM;
+ }
+ result->length = l;
+ return 0;
+}
+
+static krb5_error_code
+decrypt_internal(krb5_context context,
+ krb5_crypto crypto,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ krb5_error_code ret;
+ unsigned char *p;
+ Checksum cksum;
+ size_t checksum_sz, l;
+ struct encryption_type *et = crypto->et;
+
+ checksum_sz = CHECKSUMSIZE(et->cksumtype);
+ p = malloc(len);
+ if(len != 0 && p == NULL)
+ return ENOMEM;
+ memcpy(p, data, len);
+
+ ret = _key_schedule(context, &crypto->key);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+#ifdef CRYPTO_DEBUG
+ krb5_crypto_debug(context, 0, len, crypto->key.key);
+#endif
+ (*et->encrypt)(&crypto->key, p, len, 0);
+ ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ memset(p + et->confoundersize, 0, checksum_sz);
+ cksum.cksumtype = CHECKSUMTYPE(et->cksumtype);
+ ret = verify_checksum(context, NULL, 0, p, len, &cksum);
+ free_Checksum(&cksum);
+ if(ret) {
+ free(p);
+ return ret;
+ }
+ l = len - et->confoundersize - checksum_sz;
+ memmove(p, p + et->confoundersize + checksum_sz, l);
+ result->data = realloc(p, l);
+ if(result->data == NULL) {
+ free(p);
+ return ENOMEM;
+ }
+ result->length = l;
+ return 0;
+}
+
+krb5_error_code
+krb5_encrypt(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ if(derived_crypto(context, crypto))
+ return encrypt_internal_derived(context, crypto, usage,
+ data, len, result);
+ else
+ return encrypt_internal(context, crypto, data, len, result);
+}
+
+krb5_error_code
+krb5_encrypt_EncryptedData(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ int kvno,
+ EncryptedData *result)
+{
+ result->etype = CRYPTO_ETYPE(crypto);
+ if(kvno){
+ ALLOC(result->kvno, 1);
+ *result->kvno = kvno;
+ }else
+ result->kvno = NULL;
+ return krb5_encrypt(context, crypto, usage, data, len, &result->cipher);
+}
+
+krb5_error_code
+krb5_decrypt(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result)
+{
+ if(derived_crypto(context, crypto))
+ return decrypt_internal_derived(context, crypto, usage,
+ data, len, result);
+ else
+ return decrypt_internal(context, crypto, data, len, result);
+}
+
+krb5_error_code
+krb5_decrypt_EncryptedData(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ EncryptedData *e,
+ krb5_data *result)
+{
+ return krb5_decrypt(context, crypto, usage,
+ e->cipher.data, e->cipher.length, result);
+}
+
+/************************************************************
+ * *
+ ************************************************************/
+
+void
+krb5_generate_random_block(void *buf, size_t len)
+{
+ des_cblock key, out;
+ static des_cblock counter;
+ static des_key_schedule schedule;
+ int i;
+ static int initialized = 0;
+
+ if(!initialized) {
+ des_new_random_key(&key);
+ des_set_key(&key, schedule);
+ memset(&key, 0, sizeof(key));
+ des_new_random_key(&counter);
+ }
+ while(len > 0) {
+ des_ecb_encrypt(&counter, &out, schedule, DES_ENCRYPT);
+ for(i = 7; i >=0; i--)
+ if(counter[i]++)
+ break;
+ memcpy(buf, out, min(len, sizeof(out)));
+ len -= min(len, sizeof(out));
+ buf = (char*)buf + sizeof(out);
+ }
+}
+
+static void
+DES3_postproc(krb5_context context,
+ unsigned char *k, size_t len, struct key_data *key)
+{
+ unsigned char x[24];
+ int i, j;
+
+ memset(x, 0, sizeof(x));
+ for (i = 0; i < 3; ++i) {
+ unsigned char foo;
+
+ for (j = 0; j < 7; ++j) {
+ unsigned char b = k[7 * i + j];
+
+ x[8 * i + j] = b;
+ }
+ foo = 0;
+ for (j = 6; j >= 0; --j) {
+ foo |= k[7 * i + j] & 1;
+ foo <<= 1;
+ }
+ x[8 * i + 7] = foo;
+ }
+ k = key->key->keyvalue.data;
+ memcpy(k, x, 24);
+ memset(x, 0, sizeof(x));
+ if (key->schedule) {
+ krb5_free_data(context, key->schedule);
+ key->schedule = NULL;
+ }
+ des_set_odd_parity((des_cblock*)k);
+ des_set_odd_parity((des_cblock*)(k + 8));
+ des_set_odd_parity((des_cblock*)(k + 16));
+}
+
+static krb5_error_code
+derive_key(krb5_context context,
+ struct encryption_type *et,
+ struct key_data *key,
+ void *constant,
+ size_t len)
+{
+ unsigned char *k;
+ unsigned int nblocks = 0, i;
+ krb5_error_code ret = 0;
+
+ struct key_type *kt = et->keytype;
+ ret = _key_schedule(context, key);
+ if(ret)
+ return ret;
+ if(et->blocksize * 8 < kt->bits ||
+ len != et->blocksize) {
+ nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
+ k = malloc(nblocks * et->blocksize);
+ if(k == NULL)
+ return ENOMEM;
+ _krb5_n_fold(constant, len, k, et->blocksize);
+ for(i = 0; i < nblocks; i++) {
+ if(i > 0)
+ memcpy(k + i * et->blocksize,
+ k + (i - 1) * et->blocksize,
+ et->blocksize);
+ (*et->encrypt)(key, k + i * et->blocksize, et->blocksize, 1);
+ }
+ } else {
+ void *c = malloc(len);
+ size_t res_len = (kt->bits + 7) / 8;
+
+ if(len != 0 && c == NULL)
+ return ENOMEM;
+ memcpy(c, constant, len);
+ (*et->encrypt)(key, c, len, 1);
+ k = malloc(res_len);
+ if(res_len != 0 && k == NULL)
+ return ENOMEM;
+ _krb5_n_fold(c, len, k, res_len);
+ free(c);
+ }
+
+ /* XXX keytype dependent post-processing */
+ switch(kt->type) {
+ case KEYTYPE_DES3:
+ DES3_postproc(context, k, nblocks * et->blocksize, key);
+ break;
+ default:
+ krb5_warnx(context, "derive_key() called with unknown keytype (%u)",
+ kt->type);
+ ret = KRB5_CRYPTO_INTERNAL;
+ break;
+ }
+ memset(k, 0, nblocks * et->blocksize);
+ free(k);
+ return ret;
+}
+
+static struct key_data *
+_new_derived_key(krb5_crypto crypto, unsigned usage)
+{
+ struct key_usage *d = crypto->key_usage;
+ d = realloc(d, (crypto->num_key_usage + 1) * sizeof(*d));
+ if(d == NULL)
+ return NULL;
+ crypto->key_usage = d;
+ d += crypto->num_key_usage++;
+ memset(d, 0, sizeof(*d));
+ d->usage = usage;
+ return &d->key;
+}
+
+static krb5_error_code
+_get_derived_key(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ struct key_data **key)
+{
+ int i;
+ struct key_data *d;
+ unsigned char constant[5];
+
+ for(i = 0; i < crypto->num_key_usage; i++)
+ if(crypto->key_usage[i].usage == usage) {
+ *key = &crypto->key_usage[i].key;
+ return 0;
+ }
+ d = _new_derived_key(crypto, usage);
+ if(d == NULL)
+ return ENOMEM;
+ krb5_copy_keyblock(context, crypto->key.key, &d->key);
+ _krb5_put_int(constant, usage, 5);
+ derive_key(context, crypto->et, d, constant, sizeof(constant));
+ *key = d;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_crypto_init(krb5_context context,
+ krb5_keyblock *key,
+ krb5_enctype etype,
+ krb5_crypto *crypto)
+{
+ krb5_error_code ret;
+ ALLOC(*crypto, 1);
+ if(*crypto == NULL)
+ return ENOMEM;
+ if(etype == ETYPE_NULL)
+ etype = key->keytype;
+ (*crypto)->et = _find_enctype(etype);
+ if((*crypto)->et == NULL) {
+ free(*crypto);
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
+ ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key);
+ if(ret) {
+ free(*crypto);
+ return ret;
+ }
+ (*crypto)->key.schedule = NULL;
+ (*crypto)->num_key_usage = 0;
+ (*crypto)->key_usage = NULL;
+ return 0;
+}
+
+static void
+free_key_data(krb5_context context, struct key_data *key)
+{
+ krb5_free_keyblock(context, key->key);
+ if(key->schedule) {
+ memset(key->schedule->data, 0, key->schedule->length);
+ krb5_free_data(context, key->schedule);
+ }
+}
+
+static void
+free_key_usage(krb5_context context, struct key_usage *ku)
+{
+ free_key_data(context, &ku->key);
+}
+
+krb5_error_code
+krb5_crypto_destroy(krb5_context context,
+ krb5_crypto crypto)
+{
+ int i;
+
+ for(i = 0; i < crypto->num_key_usage; i++)
+ free_key_usage(context, &crypto->key_usage[i]);
+ free(crypto->key_usage);
+ free_key_data(context, &crypto->key);
+ free (crypto);
+ return 0;
+}
+
+krb5_error_code
+krb5_string_to_key_derived(krb5_context context,
+ const void *str,
+ size_t len,
+ krb5_enctype etype,
+ krb5_keyblock *key)
+{
+ struct encryption_type *et = _find_enctype(etype);
+ krb5_error_code ret;
+ struct key_data kd;
+ u_char *tmp;
+
+ if(et == NULL)
+ return KRB5_PROG_ETYPE_NOSUPP;
+ ALLOC(kd.key, 1);
+ kd.key->keytype = etype;
+ tmp = malloc (et->keytype->bits / 8);
+ _krb5_n_fold(str, len, tmp, et->keytype->bits / 8);
+ krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
+ kd.schedule = NULL;
+ DES3_postproc (context, tmp, et->keytype->bits / 8, &kd); /* XXX */
+ ret = derive_key(context,
+ et,
+ &kd,
+ "kerberos", /* XXX well known constant */
+ strlen("kerberos"));
+ ret = krb5_copy_keyblock_contents(context, kd.key, key);
+ free_key_data(context, &kd);
+ return ret;
+}
+
+/*
+ * Return the size of an encrypted packet of length `data_len'
+ */
+
+size_t
+krb5_get_wrapped_length (krb5_context context,
+ krb5_crypto crypto,
+ size_t data_len)
+{
+ struct encryption_type *et = crypto->et;
+ size_t blocksize = et->blocksize;
+ size_t res;
+
+ res = (data_len + blocksize - 1) / blocksize * blocksize;
+ res = res + et->confoundersize + et->cksumtype->checksumsize;
+ return res;
+}
+
+#ifdef CRYPTO_DEBUG
+
+static krb5_error_code
+krb5_get_keyid(krb5_context context,
+ krb5_keyblock *key,
+ u_int32_t *keyid)
+{
+ struct md5 md5;
+ unsigned char tmp[16];
+ md5_init(&md5);
+ md5_update(&md5, key->keyvalue.data, key->keyvalue.length);
+ md5_finito(&md5, tmp);
+ *keyid = (tmp[12] << 24) | (tmp[13] << 16) | (tmp[14] << 8) | tmp[15];
+ return 0;
+}
+
+static void
+krb5_crypto_debug(krb5_context context,
+ int encrypt,
+ size_t len,
+ krb5_keyblock *key)
+{
+ u_int32_t keyid;
+ char *kt;
+ krb5_get_keyid(context, key, &keyid);
+ krb5_enctype_to_string(context, key->keytype, &kt);
+ krb5_warnx(context, "%s %lu bytes with key-id %#x (%s)",
+ encrypt ? "encrypting" : "decrypting",
+ (unsigned long)len,
+ keyid,
+ kt);
+ free(kt);
+}
+
+#endif /* CRYPTO_DEBUG */
diff --git a/crypto/heimdal/lib/krb5/data.c b/crypto/heimdal/lib/krb5/data.c
new file mode 100644
index 0000000..21191e2
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/data.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: data.c,v 1.15 1999/12/02 17:05:09 joda Exp $");
+
+void
+krb5_data_zero(krb5_data *p)
+{
+ p->length = 0;
+ p->data = NULL;
+}
+
+void
+krb5_data_free(krb5_data *p)
+{
+ if(p->data != NULL)
+ free(p->data);
+ p->length = 0;
+}
+
+void
+krb5_free_data(krb5_context context,
+ krb5_data *p)
+{
+ krb5_data_free(p);
+ free(p);
+}
+
+krb5_error_code
+krb5_data_alloc(krb5_data *p, int len)
+{
+ p->data = malloc(len);
+ if(len && p->data == NULL)
+ return ENOMEM;
+ p->length = len;
+ return 0;
+}
+
+krb5_error_code
+krb5_data_realloc(krb5_data *p, int len)
+{
+ void *tmp;
+ tmp = realloc(p->data, len);
+ if(len && !tmp)
+ return ENOMEM;
+ p->data = tmp;
+ p->length = len;
+ return 0;
+}
+
+krb5_error_code
+krb5_data_copy(krb5_data *p, const void *data, size_t len)
+{
+ if (len) {
+ if(krb5_data_alloc(p, len))
+ return ENOMEM;
+ memmove(p->data, data, len);
+ } else
+ p->data = NULL;
+ p->length = len;
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_data(krb5_context context,
+ const krb5_data *indata,
+ krb5_data **outdata)
+{
+ krb5_error_code ret;
+ ALLOC(*outdata, 1);
+ if(*outdata == NULL)
+ return ENOMEM;
+ ret = copy_octet_string(indata, *outdata);
+ if(ret)
+ free(*outdata);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/dump_config.c b/crypto/heimdal/lib/krb5/dump_config.c
new file mode 100644
index 0000000..074595e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/dump_config.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: dump_config.c,v 1.2 1999/10/28 23:22:41 assar Exp $");
+
+/* print contents of krb5.conf */
+
+static void
+print_tree(struct krb5_config_binding *b, int level)
+{
+ if (b == NULL)
+ return;
+
+ printf("%*s%s%s%s", level * 4, "",
+ (level == 0) ? "[" : "", b->name, (level == 0) ? "]" : "");
+ if(b->type == krb5_config_list) {
+ if(level > 0)
+ printf(" = {");
+ printf("\n");
+ print_tree(b->u.list, level + 1);
+ if(level > 0)
+ printf("%*s}\n", level * 4, "");
+ } else if(b->type == krb5_config_string) {
+ printf(" = %s\n", b->u.string);
+ }
+ if(b->next)
+ print_tree(b->next, level);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret = krb5_init_context(&context);
+ if(ret == 0) {
+ print_tree(context->cf, 0);
+ return 0;
+ }
+ return 1;
+}
diff --git a/crypto/heimdal/lib/krb5/expand_hostname.c b/crypto/heimdal/lib/krb5/expand_hostname.c
new file mode 100644
index 0000000..698b300
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/expand_hostname.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: expand_hostname.c,v 1.5 2000/01/08 08:07:18 assar Exp $");
+
+static krb5_error_code
+copy_hostname(krb5_context context,
+ const char *orig_hostname,
+ char **new_hostname)
+{
+ *new_hostname = strdup (orig_hostname);
+ if (*new_hostname == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+/*
+ * Try to make `orig_hostname' into a more canonical one in the newly
+ * allocated space returned in `new_hostname'.
+ */
+
+krb5_error_code
+krb5_expand_hostname (krb5_context context,
+ const char *orig_hostname,
+ char **new_hostname)
+{
+ struct addrinfo *ai, *a, hints;
+ int error;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+
+ error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
+ if (error)
+ return copy_hostname (context, orig_hostname, new_hostname);
+ for (a = ai; a != NULL; a = a->ai_next) {
+ if (a->ai_canonname != NULL) {
+ *new_hostname = strdup (a->ai_canonname);
+ freeaddrinfo (ai);
+ if (*new_hostname == NULL)
+ return ENOMEM;
+ else
+ return 0;
+ }
+ }
+ freeaddrinfo (ai);
+ return copy_hostname (context, orig_hostname, new_hostname);
+}
diff --git a/crypto/heimdal/lib/krb5/fcache.c b/crypto/heimdal/lib/krb5/fcache.c
new file mode 100644
index 0000000..df88e6f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/fcache.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: fcache.c,v 1.22 1999/12/02 17:05:09 joda Exp $");
+
+typedef struct krb5_fcache{
+ char *filename;
+ int version;
+}krb5_fcache;
+
+struct fcc_cursor {
+ int fd;
+ krb5_storage *sp;
+};
+
+#define KRB5_FCC_FVNO_1 1
+#define KRB5_FCC_FVNO_2 2
+#define KRB5_FCC_FVNO_3 3
+#define KRB5_FCC_FVNO_4 4
+
+#define FCC_TAG_DELTATIME 1
+
+#define FCACHE(X) ((krb5_fcache*)(X)->data.data)
+
+#define FILENAME(X) (FCACHE(X)->filename)
+
+#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))
+
+static char*
+fcc_get_name(krb5_context context,
+ krb5_ccache id)
+{
+ return FILENAME(id);
+}
+
+static krb5_error_code
+fcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
+{
+ krb5_fcache *f;
+ f = malloc(sizeof(*f));
+ if(f == NULL)
+ return KRB5_CC_NOMEM;
+ f->filename = strdup(res);
+ if(f->filename == NULL){
+ free(f);
+ return KRB5_CC_NOMEM;
+ }
+ f->version = 0;
+ (*id)->data.data = f;
+ (*id)->data.length = sizeof(*f);
+ return 0;
+}
+
+static krb5_error_code
+erase_file(const char *filename)
+{
+ int fd;
+ off_t pos;
+ char buf[128];
+
+ fd = open(filename, O_RDWR | O_BINARY);
+ if(fd < 0){
+ if(errno == ENOENT)
+ return 0;
+ else
+ return errno;
+ }
+ pos = lseek(fd, 0, SEEK_END);
+ lseek(fd, 0, SEEK_SET);
+ memset(buf, 0, sizeof(buf));
+ while(pos > 0)
+ pos -= write(fd, buf, sizeof(buf));
+ close(fd);
+ unlink(filename);
+ return 0;
+}
+
+static krb5_error_code
+fcc_gen_new(krb5_context context, krb5_ccache *id)
+{
+ krb5_fcache *f;
+ int fd;
+ char *file;
+ f = malloc(sizeof(*f));
+ if(f == NULL)
+ return KRB5_CC_NOMEM;
+ asprintf(&file, "/tmp/krb5cc_XXXXXX"); /* XXX */
+ if(file == NULL) {
+ free(f);
+ return KRB5_CC_NOMEM;
+ }
+ fd = mkstemp(file);
+ if(fd < 0) {
+ free(f);
+ free(file);
+ return errno;
+ }
+ close(fd);
+ f->filename = file;
+ f->version = 0;
+ (*id)->data.data = f;
+ (*id)->data.length = sizeof(*f);
+ return 0;
+}
+
+static void
+storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
+{
+ int flags = 0;
+ switch(vno) {
+ case KRB5_FCC_FVNO_1:
+ flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;
+ flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;
+ flags |= KRB5_STORAGE_HOST_BYTEORDER;
+ break;
+ case KRB5_FCC_FVNO_2:
+ flags |= KRB5_STORAGE_HOST_BYTEORDER;
+ break;
+ case KRB5_FCC_FVNO_3:
+ flags |= KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE;
+ break;
+ case KRB5_FCC_FVNO_4:
+ break;
+ default:
+ krb5_abortx(context,
+ "storage_set_flags called with bad vno (%x)", vno);
+ }
+ krb5_storage_set_flags(sp, flags);
+}
+
+static krb5_error_code
+fcc_initialize(krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal)
+{
+ krb5_fcache *f = FCACHE(id);
+ int ret;
+ int fd;
+ char *filename = f->filename;
+
+ if((ret = erase_file(filename)))
+ return ret;
+
+ fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+ if(fd == -1)
+ return errno;
+ {
+ krb5_storage *sp;
+ sp = krb5_storage_from_fd(fd);
+ if(context->fcache_vno != 0)
+ f->version = context->fcache_vno;
+ else
+ f->version = KRB5_FCC_FVNO_4;
+ krb5_store_int8(sp, 5);
+ krb5_store_int8(sp, f->version);
+ storage_set_flags(context, sp, f->version);
+ if(f->version == KRB5_FCC_FVNO_4) {
+ /* V4 stuff */
+ if (context->kdc_sec_offset) {
+ krb5_store_int16 (sp, 12); /* length */
+ krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */
+ krb5_store_int16 (sp, 8); /* length of data */
+ krb5_store_int32 (sp, context->kdc_sec_offset);
+ krb5_store_int32 (sp, context->kdc_usec_offset);
+ } else {
+ krb5_store_int16 (sp, 0);
+ }
+ }
+ krb5_store_principal(sp, primary_principal);
+ krb5_storage_free(sp);
+ }
+ close(fd);
+
+ return 0;
+}
+
+static krb5_error_code
+fcc_close(krb5_context context,
+ krb5_ccache id)
+{
+ free (FILENAME(id));
+ krb5_data_free(&id->data);
+ return 0;
+}
+
+static krb5_error_code
+fcc_destroy(krb5_context context,
+ krb5_ccache id)
+{
+ char *f;
+ f = FILENAME(id);
+
+ erase_file(f);
+
+ return 0;
+}
+
+static krb5_error_code
+fcc_store_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds)
+{
+ int fd;
+ char *f;
+
+ f = FILENAME(id);
+
+ fd = open(f, O_WRONLY | O_APPEND | O_BINARY);
+ if(fd < 0)
+ return errno;
+ {
+ krb5_storage *sp;
+ sp = krb5_storage_from_fd(fd);
+ storage_set_flags(context, sp, FCACHE(id)->version);
+ krb5_store_creds(sp, creds);
+ krb5_storage_free(sp);
+ }
+ close(fd);
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+fcc_read_cred (krb5_context context,
+ krb5_fcache *fc,
+ krb5_storage *sp,
+ krb5_creds *creds)
+{
+ krb5_error_code ret;
+
+ storage_set_flags(context, sp, fc->version);
+
+ ret = krb5_ret_creds(sp, creds);
+ return ret;
+}
+
+static krb5_error_code
+init_fcc (krb5_context context,
+ krb5_fcache *fcache,
+ krb5_storage **ret_sp,
+ int *ret_fd)
+{
+ int fd;
+ int8_t pvno, tag;
+ krb5_storage *sp;
+
+ fd = open(fcache->filename, O_RDONLY | O_BINARY);
+ if(fd < 0)
+ return errno;
+ sp = krb5_storage_from_fd(fd);
+ krb5_ret_int8(sp, &pvno);
+ if(pvno != 5) {
+ krb5_storage_free(sp);
+ close(fd);
+ return KRB5_CCACHE_BADVNO;
+ }
+ krb5_ret_int8(sp, &tag); /* should not be host byte order */
+ fcache->version = tag;
+ storage_set_flags(context, sp, fcache->version);
+ switch (tag) {
+ case KRB5_FCC_FVNO_4: {
+ int16_t length;
+
+ krb5_ret_int16 (sp, &length);
+ while(length > 0) {
+ int16_t tag, data_len;
+ int i;
+ int8_t dummy;
+
+ krb5_ret_int16 (sp, &tag);
+ krb5_ret_int16 (sp, &data_len);
+ switch (tag) {
+ case FCC_TAG_DELTATIME :
+ krb5_ret_int32 (sp, &context->kdc_sec_offset);
+ krb5_ret_int32 (sp, &context->kdc_usec_offset);
+ break;
+ default :
+ for (i = 0; i < data_len; ++i)
+ krb5_ret_int8 (sp, &dummy);
+ break;
+ }
+ length -= 4 + data_len;
+ }
+ break;
+ }
+ case KRB5_FCC_FVNO_3:
+ case KRB5_FCC_FVNO_2:
+ case KRB5_FCC_FVNO_1:
+ break;
+ default :
+ krb5_storage_free (sp);
+ close (fd);
+ return KRB5_CCACHE_BADVNO;
+ }
+ *ret_sp = sp;
+ *ret_fd = fd;
+ return 0;
+}
+
+static krb5_error_code
+fcc_get_principal(krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal)
+{
+ krb5_error_code ret;
+ krb5_fcache *f = FCACHE(id);
+ int fd;
+ krb5_storage *sp;
+
+ ret = init_fcc (context, f, &sp, &fd);
+ if (ret)
+ return ret;
+ krb5_ret_principal(sp, principal);
+ krb5_storage_free(sp);
+ close(fd);
+ return 0;
+}
+
+static krb5_error_code
+fcc_get_first (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ krb5_error_code ret;
+ krb5_principal principal;
+ krb5_fcache *f = FCACHE(id);
+
+ *cursor = malloc(sizeof(struct fcc_cursor));
+
+ ret = init_fcc (context, f, &FCC_CURSOR(*cursor)->sp,
+ &FCC_CURSOR(*cursor)->fd);
+ if (ret)
+ return ret;
+ krb5_ret_principal (FCC_CURSOR(*cursor)->sp, &principal);
+ krb5_free_principal (context, principal);
+ return 0;
+}
+
+static krb5_error_code
+fcc_get_next (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor,
+ krb5_creds *creds)
+{
+ return fcc_read_cred (context, FCACHE(id), FCC_CURSOR(*cursor)->sp, creds);
+}
+
+static krb5_error_code
+fcc_end_get (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ krb5_storage_free(FCC_CURSOR(*cursor)->sp);
+ close (FCC_CURSOR(*cursor)->fd);
+ free(*cursor);
+ return 0;
+}
+
+static krb5_error_code
+fcc_remove_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred)
+{
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+fcc_set_flags(krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags)
+{
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+fcc_get_version(krb5_context context,
+ krb5_ccache id)
+{
+ return FCACHE(id)->version;
+}
+
+const krb5_cc_ops krb5_fcc_ops = {
+ "FILE",
+ fcc_get_name,
+ fcc_resolve,
+ fcc_gen_new,
+ fcc_initialize,
+ fcc_destroy,
+ fcc_close,
+ fcc_store_cred,
+ NULL, /* fcc_retrieve */
+ fcc_get_principal,
+ fcc_get_first,
+ fcc_get_next,
+ fcc_end_get,
+ fcc_remove_cred,
+ fcc_set_flags,
+ fcc_get_version
+};
diff --git a/crypto/heimdal/lib/krb5/free.c b/crypto/heimdal/lib/krb5/free.c
new file mode 100644
index 0000000..251ec32
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/free.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: free.c,v 1.5 1999/12/02 17:05:09 joda Exp $");
+
+krb5_error_code
+krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *rep)
+{
+ free_KDC_REP(&rep->kdc_rep);
+ free_EncTGSRepPart(&rep->enc_part);
+ free_KRB_ERROR(&rep->error);
+ return 0;
+}
+
+krb5_error_code
+krb5_xfree (void *ptr)
+{
+ free (ptr);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/free_host_realm.c b/crypto/heimdal/lib/krb5/free_host_realm.c
new file mode 100644
index 0000000..a69f29b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/free_host_realm.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: free_host_realm.c,v 1.4 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Free all memory allocated by `realmlist'
+ */
+
+krb5_error_code
+krb5_free_host_realm(krb5_context context,
+ krb5_realm *realmlist)
+{
+ krb5_realm *p;
+
+ if(realmlist == NULL)
+ return 0;
+ for (p = realmlist; *p; ++p)
+ free (*p);
+ free (realmlist);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/generate_seq_number.c b/crypto/heimdal/lib/krb5/generate_seq_number.c
new file mode 100644
index 0000000..a000ea1
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/generate_seq_number.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: generate_seq_number.c,v 1.6 1999/12/02 17:05:09 joda Exp $");
+
+krb5_error_code
+krb5_generate_seq_number(krb5_context context,
+ const krb5_keyblock *key,
+ int32_t *seqno)
+{
+ krb5_error_code ret;
+ krb5_keyblock *subkey;
+ u_int32_t q;
+ u_char *p;
+ int i;
+
+ ret = krb5_generate_subkey (context, key, &subkey);
+ if (ret)
+ return ret;
+
+ q = 0;
+ for (p = (u_char *)subkey->keyvalue.data, i = 0;
+ i < subkey->keyvalue.length;
+ ++i, ++p)
+ q = (q << 8) | *p;
+ q &= 0xffffffff;
+ *seqno = q;
+ krb5_free_keyblock_contents (context, subkey);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/generate_subkey.c b/crypto/heimdal/lib/krb5/generate_subkey.c
new file mode 100644
index 0000000..a5b2e9e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/generate_subkey.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: generate_subkey.c,v 1.7 1999/12/02 17:05:09 joda Exp $");
+
+krb5_error_code
+krb5_generate_subkey(krb5_context context,
+ const krb5_keyblock *key,
+ krb5_keyblock **subkey)
+{
+ krb5_error_code ret;
+
+ ALLOC(*subkey, 1);
+ if (*subkey == NULL)
+ return ENOMEM;
+ ret = krb5_generate_random_keyblock(context, key->keytype, *subkey);
+ if(ret)
+ free(*subkey);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_addrs.c b/crypto/heimdal/lib/krb5/get_addrs.c
new file mode 100644
index 0000000..65a1b3c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_addrs.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_addrs.c,v 1.35 1999/12/02 17:05:09 joda Exp $");
+
+#ifdef __osf__
+/* hate */
+struct rtentry;
+struct mbuf;
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif /* HAVE_SYS_SOCKIO_H */
+
+#ifdef HAVE_NETINET_IN6_VAR_H
+#include <netinet/in6_var.h>
+#endif /* HAVE_NETINET_IN6_VAR_H */
+
+static krb5_error_code
+gethostname_fallback (krb5_addresses *res)
+{
+ krb5_error_code err;
+ char hostname[MAXHOSTNAMELEN];
+ struct hostent *hostent;
+
+ if (gethostname (hostname, sizeof(hostname)))
+ return errno;
+ hostent = roken_gethostbyname (hostname);
+ if (hostent == NULL)
+ return errno;
+ res->len = 1;
+ res->val = malloc (sizeof(*res->val));
+ if (res->val == NULL)
+ return ENOMEM;
+ res->val[0].addr_type = hostent->h_addrtype;
+ res->val[0].address.data = NULL;
+ res->val[0].address.length = 0;
+ err = krb5_data_copy (&res->val[0].address,
+ hostent->h_addr,
+ hostent->h_length);
+ if (err) {
+ free (res->val);
+ return err;
+ }
+ return 0;
+}
+
+enum {
+ LOOP = 1, /* do include loopback interfaces */
+ LOOP_IF_NONE = 2, /* include loopback if no other if's */
+ EXTRA_ADDRESSES = 4, /* include extra addresses */
+ SCAN_INTERFACES = 8 /* scan interfaces for addresses */
+};
+
+/*
+ * Try to figure out the addresses of all configured interfaces with a
+ * lot of magic ioctls.
+ */
+
+static krb5_error_code
+find_all_addresses (krb5_context context,
+ krb5_addresses *res, int flags,
+ int af, int siocgifconf, int siocgifflags,
+ size_t ifreq_sz)
+{
+ krb5_error_code ret;
+ int fd;
+ size_t buf_size;
+ char *buf;
+ struct ifconf ifconf;
+ int num, j = 0;
+ char *p;
+ size_t sz;
+ struct sockaddr sa_zero;
+ struct ifreq *ifr;
+ krb5_address lo_addr;
+ int got_lo = FALSE;
+
+ buf = NULL;
+ res->val = NULL;
+
+ memset (&sa_zero, 0, sizeof(sa_zero));
+ fd = socket(af, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return -1;
+
+ buf_size = 8192;
+ for (;;) {
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+ ifconf.ifc_len = buf_size;
+ ifconf.ifc_buf = buf;
+ if (ioctl (fd, siocgifconf, &ifconf) < 0) {
+ ret = errno;
+ goto error_out;
+ }
+ /*
+ * Can the difference between a full and a overfull buf
+ * be determined?
+ */
+
+ if (ifconf.ifc_len < buf_size)
+ break;
+ free (buf);
+ buf_size *= 2;
+ }
+
+ num = ifconf.ifc_len / ifreq_sz;
+ res->len = num;
+ res->val = calloc(num, sizeof(*res->val));
+ if (res->val == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+
+ j = 0;
+ for (p = ifconf.ifc_buf;
+ p < ifconf.ifc_buf + ifconf.ifc_len;
+ p += sz) {
+ struct ifreq ifreq;
+ struct sockaddr *sa;
+
+ ifr = (struct ifreq *)p;
+ sa = &ifr->ifr_addr;
+
+ sz = ifreq_sz;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sz = max(sz, sizeof(ifr->ifr_name) + sa->sa_len);
+#endif
+#ifdef SA_LEN
+ sz = max(sz, SA_LEN(sa));
+#endif
+ memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
+
+ if (ioctl(fd, siocgifflags, &ifreq) < 0) {
+ ret = errno;
+ goto error_out;
+ }
+
+ if (!(ifreq.ifr_flags & IFF_UP))
+ continue;
+ if (memcmp (sa, &sa_zero, sizeof(sa_zero)) == 0)
+ continue;
+ if (krb5_sockaddr_uninteresting (sa))
+ continue;
+
+ if (ifreq.ifr_flags & IFF_LOOPBACK) {
+ if (flags & LOOP_IF_NONE) {
+ ret = krb5_sockaddr2address (sa, &lo_addr);
+ if (ret)
+ goto error_out;
+ got_lo = TRUE;
+ continue;
+ } else if((flags & LOOP) == 0)
+ continue;
+ }
+
+ ret = krb5_sockaddr2address (sa, &res->val[j]);
+ if (ret)
+ goto error_out;
+ ++j;
+ }
+ if ((flags & LOOP_IF_NONE) && got_lo) {
+ if (j == 0)
+ res->val[j++] = lo_addr;
+ else
+ krb5_free_address (context, &lo_addr);
+ }
+
+ if (j != num) {
+ void *tmp;
+
+ res->len = j;
+ tmp = realloc (res->val, j * sizeof(*res->val));
+ if (j != 0 && tmp == NULL) {
+ ret = ENOMEM;
+ goto error_out;
+ }
+ res->val = tmp;
+ }
+ ret = 0;
+ goto cleanup;
+
+error_out:
+ if (got_lo)
+ krb5_free_address (context, &lo_addr);
+ while(j--) {
+ krb5_free_address (context, &res->val[j]);
+ }
+ free (res->val);
+cleanup:
+ close (fd);
+ free (buf);
+ return ret;
+}
+
+static krb5_error_code
+get_addrs_int (krb5_context context, krb5_addresses *res, int flags)
+{
+ krb5_error_code ret = -1;
+
+ if (flags & SCAN_INTERFACES) {
+#if defined(AF_INET6) && defined(SIOCGIF6CONF) && defined(SIOCGIF6FLAGS)
+ if (ret)
+ ret = find_all_addresses (context, res, flags,
+ AF_INET6, SIOCGIF6CONF, SIOCGIF6FLAGS,
+ sizeof(struct in6_ifreq));
+#endif
+#if defined(HAVE_IPV6) && defined(SIOCGIFCONF)
+ if (ret)
+ ret = find_all_addresses (context, res, flags,
+ AF_INET6, SIOCGIFCONF, SIOCGIFFLAGS,
+ sizeof(struct ifreq));
+#endif
+#if defined(AF_INET) && defined(SIOCGIFCONF) && defined(SIOCGIFFLAGS)
+ if (ret)
+ ret = find_all_addresses (context, res, flags,
+ AF_INET, SIOCGIFCONF, SIOCGIFFLAGS,
+ sizeof(struct ifreq));
+ if(ret || res->len == 0)
+ ret = gethostname_fallback (res);
+#endif
+ } else
+ ret = 0;
+
+ if(ret == 0 && (flags & EXTRA_ADDRESSES)) {
+ /* append user specified addresses */
+ krb5_addresses a;
+ ret = krb5_get_extra_addresses(context, &a);
+ if(ret) {
+ krb5_free_addresses(context, res);
+ return ret;
+ }
+ ret = krb5_append_addresses(context, res, &a);
+ if(ret) {
+ krb5_free_addresses(context, res);
+ return ret;
+ }
+ krb5_free_addresses(context, &a);
+ }
+ return ret;
+}
+
+/*
+ * Try to get all addresses, but return the one corresponding to
+ * `hostname' if we fail.
+ *
+ * Only include loopback address if there are no other.
+ */
+
+krb5_error_code
+krb5_get_all_client_addrs (krb5_context context, krb5_addresses *res)
+{
+ int flags = LOOP_IF_NONE | EXTRA_ADDRESSES;
+
+ if (context->scan_interfaces)
+ flags |= SCAN_INTERFACES;
+
+ return get_addrs_int (context, res, flags);
+}
+
+/*
+ * Try to get all local addresses that a server should listen to.
+ * If that fails, we return the address corresponding to `hostname'.
+ */
+
+krb5_error_code
+krb5_get_all_server_addrs (krb5_context context, krb5_addresses *res)
+{
+ return get_addrs_int (context, res, LOOP | SCAN_INTERFACES);
+}
diff --git a/crypto/heimdal/lib/krb5/get_cred.c b/crypto/heimdal/lib/krb5/get_cred.c
new file mode 100644
index 0000000..61951c1
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_cred.c
@@ -0,0 +1,776 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: get_cred.c,v 1.75 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Take the `body' and encode it into `padata' using the credentials
+ * in `creds'.
+ */
+
+static krb5_error_code
+make_pa_tgs_req(krb5_context context,
+ krb5_auth_context ac,
+ KDC_REQ_BODY *body,
+ PA_DATA *padata,
+ krb5_creds *creds)
+{
+ u_char *buf;
+ size_t buf_size;
+ size_t len;
+ krb5_data in_data;
+ krb5_error_code ret;
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL)
+ return ENOMEM;
+
+ do {
+ ret = encode_KDC_REQ_BODY(buf + buf_size - 1, buf_size,
+ body, &len);
+ if (ret){
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ buf = tmp;
+ } else {
+ goto out;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ in_data.length = len;
+ in_data.data = buf + buf_size - len;
+ ret = krb5_mk_req_internal(context, &ac, 0, &in_data, creds,
+ &padata->padata_value,
+ KRB5_KU_TGS_REQ_AUTH_CKSUM);
+out:
+ free (buf);
+ if(ret)
+ return ret;
+ padata->padata_type = pa_tgs_req;
+ return 0;
+}
+
+/*
+ * Set the `enc-authorization-data' in `req_body' based on `authdata'
+ */
+
+static krb5_error_code
+set_auth_data (krb5_context context,
+ KDC_REQ_BODY *req_body,
+ krb5_authdata *authdata,
+ krb5_keyblock *key)
+{
+ if(authdata->len) {
+ size_t len;
+ unsigned char *buf;
+ krb5_crypto crypto;
+ krb5_error_code ret;
+
+ len = length_AuthorizationData(authdata);
+ buf = malloc(len);
+ if (buf == NULL)
+ return ENOMEM;
+ ret = encode_AuthorizationData(buf + len - 1,
+ len, authdata, &len);
+ if (ret) {
+ free (buf);
+ return ret;
+ }
+
+ ALLOC(req_body->enc_authorization_data, 1);
+ if (req_body->enc_authorization_data == NULL) {
+ free (buf);
+ return ret;
+ }
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret) {
+ free (buf);
+ free (req_body->enc_authorization_data);
+ return ret;
+ }
+ krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+ /* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
+ buf,
+ len,
+ 0,
+ req_body->enc_authorization_data);
+ free (buf);
+ krb5_crypto_destroy(context, crypto);
+ } else {
+ req_body->enc_authorization_data = NULL;
+ }
+ return 0;
+}
+
+/*
+ * Create a tgs-req in `t' with `addresses', `flags', `second_ticket'
+ * (if not-NULL), `in_creds', `krbtgt', and returning the generated
+ * subkey in `subkey'.
+ */
+
+static krb5_error_code
+init_tgs_req (krb5_context context,
+ krb5_ccache ccache,
+ krb5_addresses *addresses,
+ krb5_kdc_flags flags,
+ Ticket *second_ticket,
+ krb5_creds *in_creds,
+ krb5_creds *krbtgt,
+ unsigned nonce,
+ krb5_keyblock **subkey,
+ TGS_REQ *t)
+{
+ krb5_error_code ret;
+
+ memset(t, 0, sizeof(*t));
+ t->pvno = 5;
+ t->msg_type = krb_tgs_req;
+ if (in_creds->session.keytype) {
+ ret = krb5_keytype_to_enctypes_default (context,
+ in_creds->session.keytype,
+ &t->req_body.etype.len,
+ &t->req_body.etype.val);
+ } else {
+ ret = krb5_init_etype(context,
+ &t->req_body.etype.len,
+ &t->req_body.etype.val,
+ NULL);
+ }
+ if (ret)
+ goto fail;
+ t->req_body.addresses = addresses;
+ t->req_body.kdc_options = flags.b;
+ ret = copy_Realm(&in_creds->server->realm, &t->req_body.realm);
+ if (ret)
+ goto fail;
+ ALLOC(t->req_body.sname, 1);
+ if (t->req_body.sname == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ret = copy_PrincipalName(&in_creds->server->name, t->req_body.sname);
+ if (ret)
+ goto fail;
+
+ /* req_body.till should be NULL if there is no endtime specified,
+ but old MIT code (like DCE secd) doesn't like that */
+ ALLOC(t->req_body.till, 1);
+ if(t->req_body.till == NULL){
+ ret = ENOMEM;
+ goto fail;
+ }
+ *t->req_body.till = in_creds->times.endtime;
+
+ t->req_body.nonce = nonce;
+ if(second_ticket){
+ ALLOC(t->req_body.additional_tickets, 1);
+ if (t->req_body.additional_tickets == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ALLOC_SEQ(t->req_body.additional_tickets, 1);
+ if (t->req_body.additional_tickets->val == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val);
+ if (ret)
+ goto fail;
+ }
+ ALLOC(t->padata, 1);
+ if (t->padata == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ALLOC_SEQ(t->padata, 1);
+ if (t->padata->val == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ {
+ krb5_auth_context ac;
+ krb5_keyblock *key;
+
+ ret = krb5_auth_con_init(context, &ac);
+ if(ret)
+ goto fail;
+ ret = krb5_generate_subkey (context, &krbtgt->session, &key);
+ if (ret) {
+ krb5_auth_con_free (context, ac);
+ goto fail;
+ }
+ ret = krb5_auth_con_setlocalsubkey(context, ac, key);
+ if (ret) {
+ krb5_free_keyblock (context, key);
+ krb5_auth_con_free (context, ac);
+ goto fail;
+ }
+
+ ret = set_auth_data (context, &t->req_body, &in_creds->authdata, key);
+ if (ret) {
+ krb5_free_keyblock (context, key);
+ krb5_auth_con_free (context, ac);
+ goto fail;
+ }
+
+ ret = make_pa_tgs_req(context,
+ ac,
+ &t->req_body,
+ t->padata->val,
+ krbtgt);
+ if(ret) {
+ krb5_free_keyblock (context, key);
+ krb5_auth_con_free(context, ac);
+ goto fail;
+ }
+ *subkey = key;
+
+ krb5_auth_con_free(context, ac);
+ }
+fail:
+ if (ret)
+ free_TGS_REQ (t);
+ return ret;
+}
+
+static krb5_error_code
+get_krbtgt(krb5_context context,
+ krb5_ccache id,
+ krb5_realm realm,
+ krb5_creds **cred)
+{
+ krb5_error_code ret;
+ krb5_creds tmp_cred;
+
+ memset(&tmp_cred, 0, sizeof(tmp_cred));
+
+ ret = krb5_make_principal(context,
+ &tmp_cred.server,
+ realm,
+ KRB5_TGS_NAME,
+ realm,
+ NULL);
+ if(ret)
+ return ret;
+ ret = krb5_get_credentials(context,
+ KRB5_GC_CACHED,
+ id,
+ &tmp_cred,
+ cred);
+ krb5_free_principal(context, tmp_cred.server);
+ if(ret)
+ return ret;
+ return 0;
+}
+
+/* DCE compatible decrypt proc */
+static krb5_error_code
+decrypt_tkt_with_subkey (krb5_context context,
+ krb5_keyblock *key,
+ krb5_key_usage usage,
+ krb5_const_pointer subkey,
+ krb5_kdc_rep *dec_rep)
+{
+ krb5_error_code ret;
+ krb5_data data;
+ size_t size;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ usage,
+ &dec_rep->kdc_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+ if(ret && subkey){
+ /* DCE compat -- try to decrypt with subkey */
+ krb5_crypto_init(context, (krb5_keyblock*)subkey, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TGS_REP_ENC_PART_SUB_KEY,
+ &dec_rep->kdc_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+ }
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_EncASRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ if (ret)
+ ret = krb5_decode_EncTGSRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ krb5_data_free (&data);
+ return ret;
+}
+
+static krb5_error_code
+get_cred_kdc(krb5_context context,
+ krb5_ccache id,
+ krb5_kdc_flags flags,
+ krb5_addresses *addresses,
+ krb5_creds *in_creds,
+ krb5_creds *krbtgt,
+ krb5_creds *out_creds)
+{
+ TGS_REQ req;
+ krb5_data enc;
+ krb5_data resp;
+ krb5_kdc_rep rep;
+ KRB_ERROR error;
+ krb5_error_code ret;
+ unsigned nonce;
+ krb5_keyblock *subkey = NULL;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ Ticket second_ticket;
+
+ krb5_generate_random_block(&nonce, sizeof(nonce));
+ nonce &= 0xffffffff;
+
+ if(flags.b.enc_tkt_in_skey){
+ ret = decode_Ticket(in_creds->second_ticket.data,
+ in_creds->second_ticket.length,
+ &second_ticket, &len);
+ if(ret)
+ return ret;
+ }
+
+ ret = init_tgs_req (context,
+ id,
+ addresses,
+ flags,
+ flags.b.enc_tkt_in_skey ? &second_ticket : NULL,
+ in_creds,
+ krbtgt,
+ nonce,
+ &subkey,
+ &req);
+ if(flags.b.enc_tkt_in_skey)
+ free_Ticket(&second_ticket);
+ if (ret)
+ goto out;
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ do {
+ ret = encode_TGS_REQ (buf + buf_size - 1, buf_size,
+ &req, &enc.length);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ buf = tmp;
+ } else {
+ goto out;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ /* don't free addresses */
+ req.req_body.addresses = NULL;
+ free_TGS_REQ(&req);
+
+ enc.data = buf + buf_size - enc.length;
+ if (ret)
+ goto out;
+
+ /*
+ * Send and receive
+ */
+
+ ret = krb5_sendto_kdc (context, &enc,
+ &krbtgt->server->name.name_string.val[1], &resp);
+ if(ret)
+ goto out;
+
+ memset(&rep, 0, sizeof(rep));
+ if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0){
+ ret = krb5_copy_principal(context,
+ in_creds->client,
+ &out_creds->client);
+ if(ret)
+ goto out;
+ ret = krb5_copy_principal(context,
+ in_creds->server,
+ &out_creds->server);
+ if(ret)
+ goto out;
+ /* this should go someplace else */
+ out_creds->times.endtime = in_creds->times.endtime;
+
+ ret = _krb5_extract_ticket(context,
+ &rep,
+ out_creds,
+ &krbtgt->session,
+ NULL,
+ KRB5_KU_TGS_REP_ENC_PART_SESSION,
+ &krbtgt->addresses,
+ nonce,
+ TRUE,
+ decrypt_tkt_with_subkey,
+ subkey);
+ krb5_free_kdc_rep(context, &rep);
+ if (ret)
+ goto out;
+ }else if(krb5_rd_error(context, &resp, &error) == 0){
+ ret = error.error_code;
+ free_KRB_ERROR(&error);
+ }else if(resp.data && ((char*)resp.data)[0] == 4)
+ ret = KRB5KRB_AP_ERR_V4_REPLY;
+ else
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ krb5_data_free(&resp);
+out:
+ if(subkey){
+ krb5_free_keyblock_contents(context, subkey);
+ free(subkey);
+ }
+ if (buf)
+ free (buf);
+ return ret;
+
+}
+
+/* same as above, just get local addresses first */
+
+static krb5_error_code
+get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags,
+ krb5_creds *in_creds, krb5_creds *krbtgt,
+ krb5_creds *out_creds)
+{
+ krb5_error_code ret;
+ krb5_addresses addresses;
+
+ krb5_get_all_client_addrs(context, &addresses);
+ ret = get_cred_kdc(context, id, flags, &addresses,
+ in_creds, krbtgt, out_creds);
+ krb5_free_addresses(context, &addresses);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_kdc_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_kdc_flags flags,
+ krb5_addresses *addresses,
+ Ticket *second_ticket,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds
+ )
+{
+ krb5_error_code ret;
+ krb5_creds *krbtgt;
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if(*out_creds == NULL)
+ return ENOMEM;
+ ret = get_krbtgt (context,
+ id,
+ in_creds->server->realm,
+ &krbtgt);
+ if(ret) {
+ free(*out_creds);
+ return ret;
+ }
+ ret = get_cred_kdc(context, id, flags, addresses,
+ in_creds, krbtgt, *out_creds);
+ krb5_free_creds (context, krbtgt);
+ if(ret)
+ free(*out_creds);
+ return ret;
+}
+
+
+static krb5_error_code
+find_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_principal server,
+ krb5_creds **tgts,
+ krb5_creds *out_creds)
+{
+ krb5_error_code ret;
+ krb5_creds mcreds;
+ mcreds.server = server;
+ ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM,
+ &mcreds, out_creds);
+ if(ret == 0)
+ return 0;
+ while(tgts && *tgts){
+ if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM,
+ &mcreds, *tgts)){
+ ret = krb5_copy_creds_contents(context, *tgts, out_creds);
+ return ret;
+ }
+ tgts++;
+ }
+ return KRB5_CC_NOTFOUND;
+}
+
+static krb5_error_code
+add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt)
+{
+ int i;
+ krb5_error_code ret;
+ krb5_creds **tmp = *tgts;
+ for(i = 0; tmp && tmp[i]; i++); /* XXX */
+ tmp = realloc(tmp, (i+2)*sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ *tgts = tmp;
+ ret = krb5_copy_creds(context, tkt, &tmp[i]);
+ tmp[i+1] = NULL;
+ return ret;
+}
+
+/*
+get_cred(server)
+ creds = cc_get_cred(server)
+ if(creds) return creds
+ tgt = cc_get_cred(krbtgt/server_realm@any_realm)
+ if(tgt)
+ return get_cred_tgt(server, tgt)
+ if(client_realm == server_realm)
+ return NULL
+ tgt = get_cred(krbtgt/server_realm@client_realm)
+ while(tgt_inst != server_realm)
+ tgt = get_cred(krbtgt/server_realm@tgt_inst)
+ return get_cred_tgt(server, tgt)
+ */
+
+static krb5_error_code
+get_cred_from_kdc_flags(krb5_context context,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts)
+{
+ krb5_error_code ret;
+ krb5_creds *tgt, tmp_creds;
+ krb5_realm client_realm, server_realm;
+
+ *out_creds = NULL;
+
+ client_realm = *krb5_princ_realm(context, in_creds->client);
+ server_realm = *krb5_princ_realm(context, in_creds->server);
+ memset(&tmp_creds, 0, sizeof(tmp_creds));
+ ret = krb5_copy_principal(context, in_creds->client, &tmp_creds.client);
+ if(ret)
+ return ret;
+ ret = krb5_make_principal(context,
+ &tmp_creds.server,
+ client_realm,
+ KRB5_TGS_NAME,
+ server_realm,
+ NULL);
+ if(ret){
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ {
+ krb5_creds tgts;
+ /* XXX try krb5_cc_retrieve_cred first? */
+ ret = find_cred(context, ccache, tmp_creds.server,
+ *ret_tgts, &tgts);
+ if(ret == 0){
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if(*out_creds == NULL)
+ ret = ENOMEM;
+ else {
+ ret = get_cred_kdc_la(context, ccache, flags,
+ in_creds, &tgts, *out_creds);
+ if (ret)
+ free (*out_creds);
+ }
+ krb5_free_creds_contents(context, &tgts);
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ }
+ if(krb5_realm_compare(context, in_creds->client, in_creds->server))
+ return KRB5_CC_NOTFOUND;
+ /* XXX this can loop forever */
+ while(1){
+ general_string tgt_inst;
+ krb5_kdc_flags f;
+ f.i = 0;
+ ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds,
+ &tgt, ret_tgts);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ ret = add_cred(context, ret_tgts, tgt);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ tgt_inst = tgt->server->name.name_string.val[1];
+ if(strcmp(tgt_inst, server_realm) == 0)
+ break;
+ krb5_free_principal(context, tmp_creds.server);
+ ret = krb5_make_principal(context, &tmp_creds.server,
+ tgt_inst, KRB5_TGS_NAME, server_realm, NULL);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ ret = krb5_free_creds(context, tgt);
+ if(ret) {
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ return ret;
+ }
+ }
+
+ krb5_free_principal(context, tmp_creds.server);
+ krb5_free_principal(context, tmp_creds.client);
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if(*out_creds == NULL)
+ ret = ENOMEM;
+ else {
+ ret = get_cred_kdc_la(context, ccache, flags,
+ in_creds, tgt, *out_creds);
+ if (ret)
+ free (*out_creds);
+ }
+ krb5_free_creds(context, tgt);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_cred_from_kdc(krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts)
+{
+ krb5_kdc_flags f;
+ f.i = 0;
+ return get_cred_from_kdc_flags(context, f, ccache,
+ in_creds, out_creds, ret_tgts);
+}
+
+
+krb5_error_code
+krb5_get_credentials_with_flags(krb5_context context,
+ krb5_flags options,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds)
+{
+ krb5_error_code ret;
+ krb5_creds **tgts;
+ int i;
+
+ *out_creds = calloc(1, sizeof(**out_creds));
+ if (*out_creds == NULL)
+ return ENOMEM;
+
+ ret = krb5_cc_retrieve_cred(context,
+ ccache,
+ in_creds->session.keytype ?
+ KRB5_TC_MATCH_KEYTYPE : 0,
+ in_creds, *out_creds);
+ if(ret == 0)
+ return 0;
+ free(*out_creds);
+ if(ret != KRB5_CC_END)
+ return ret;
+ if(options & KRB5_GC_CACHED)
+ return KRB5_CC_NOTFOUND;
+ if(options & KRB5_GC_USER_USER)
+ flags.b.enc_tkt_in_skey = 1;
+ tgts = NULL;
+ ret = get_cred_from_kdc_flags(context, flags, ccache,
+ in_creds, out_creds, &tgts);
+ for(i = 0; tgts && tgts[i]; i++){
+ krb5_cc_store_cred(context, ccache, tgts[i]);
+ krb5_free_creds(context, tgts[i]);
+ }
+ free(tgts);
+ if(ret == 0 && flags.b.enc_tkt_in_skey == 0)
+ krb5_cc_store_cred(context, ccache, *out_creds);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_credentials(krb5_context context,
+ krb5_flags options,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds)
+{
+ krb5_kdc_flags flags;
+ flags.i = 0;
+ return krb5_get_credentials_with_flags(context, options, flags,
+ ccache, in_creds, out_creds);
+}
diff --git a/crypto/heimdal/lib/krb5/get_default_principal.c b/crypto/heimdal/lib/krb5/get_default_principal.c
new file mode 100644
index 0000000..84d7a5e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_default_principal.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_default_principal.c,v 1.5 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Try to find out what's a reasonable default principal.
+ */
+
+krb5_error_code
+krb5_get_default_principal (krb5_context context,
+ krb5_principal *princ)
+{
+ krb5_error_code ret;
+ krb5_ccache id;
+ const char *user;
+
+ ret = krb5_cc_default (context, &id);
+ if (ret == 0) {
+ ret = krb5_cc_get_principal (context, id, princ);
+ krb5_cc_close (context, id);
+ if (ret == 0)
+ return 0;
+ }
+
+ user = get_default_username ();
+ if (user == NULL)
+ return ENOTTY;
+ if (getuid () == 0) {
+ ret = krb5_make_principal(context, princ, NULL, user, "root", NULL);
+ } else {
+ ret = krb5_make_principal(context, princ, NULL, user, NULL);
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_default_realm.c b/crypto/heimdal/lib/krb5/get_default_realm.c
new file mode 100644
index 0000000..3f9b901
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_default_realm.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_default_realm.c,v 1.8 1999/12/02 17:05:09 joda Exp $");
+
+/*
+ * Return a NULL-terminated list of default realms in `realms'.
+ * Free this memory with krb5_free_host_realm.
+ */
+
+krb5_error_code
+krb5_get_default_realms (krb5_context context,
+ krb5_realm **realms)
+{
+ if (context->default_realms == NULL) {
+ krb5_error_code ret = krb5_set_default_realm (context, NULL);
+ if (ret)
+ return KRB5_CONFIG_NODEFREALM;
+ }
+
+ return krb5_copy_host_realm (context,
+ context->default_realms,
+ realms);
+}
+
+/*
+ * Return the first default realm. For compatability.
+ */
+
+krb5_error_code
+krb5_get_default_realm(krb5_context context,
+ krb5_realm *realm)
+{
+ char *res;
+
+ if (context->default_realms == NULL
+ || context->default_realms[0] == NULL) {
+ krb5_error_code ret = krb5_set_default_realm (context, NULL);
+ if (ret)
+ return KRB5_CONFIG_NODEFREALM;
+ }
+
+ res = strdup (context->default_realms[0]);
+ if (res == NULL)
+ return ENOMEM;
+ *realm = res;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/get_for_creds.c b/crypto/heimdal/lib/krb5/get_for_creds.c
new file mode 100644
index 0000000..977515f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_for_creds.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: get_for_creds.c,v 1.21 1999/12/20 00:57:37 assar Exp $");
+
+static krb5_error_code
+add_addrs(krb5_context context,
+ krb5_addresses *addr,
+ struct addrinfo *ai)
+{
+ krb5_error_code ret;
+ unsigned n, i;
+ void *tmp;
+ struct addrinfo *a;
+
+ n = 0;
+ for (a = ai; a != NULL; a = a->ai_next)
+ ++n;
+
+ i = addr->len;
+ addr->len += n;
+ tmp = realloc(addr->val, addr->len * sizeof(*addr->val));
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ addr->val = tmp;
+ for (a = ai; a != NULL; a = a->ai_next) {
+ ret = krb5_sockaddr2address (a->ai_addr, &addr->val[i++]);
+ if (ret)
+ goto fail;
+ }
+ return 0;
+fail:
+ krb5_free_addresses (context, addr);
+ return ret;
+}
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_fwd_tgt_creds (krb5_context context,
+ krb5_auth_context auth_context,
+ const char *hostname,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_ccache ccache,
+ int forwardable,
+ krb5_data *out_data)
+{
+ krb5_flags flags = 0;
+ krb5_creds creds;
+ krb5_error_code ret;
+
+ flags |= KDC_OPT_FORWARDED;
+
+ if (forwardable)
+ flags |= KDC_OPT_FORWARDABLE;
+
+
+ memset (&creds, 0, sizeof(creds));
+ creds.client = client;
+ creds.server = server;
+
+ ret = krb5_get_forwarded_creds (context,
+ auth_context,
+ ccache,
+ flags,
+ hostname,
+ &creds,
+ out_data);
+ return ret;
+}
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_get_forwarded_creds (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_flags flags,
+ const char *hostname,
+ krb5_creds *in_creds,
+ krb5_data *out_data)
+{
+ krb5_error_code ret;
+ krb5_creds *out_creds;
+ krb5_addresses addrs;
+ KRB_CRED cred;
+ KrbCredInfo *krb_cred_info;
+ EncKrbCredPart enc_krb_cred_part;
+ size_t len;
+ u_char buf[1024];
+ int32_t sec, usec;
+ krb5_kdc_flags kdc_flags;
+ krb5_crypto crypto;
+ struct addrinfo *ai;
+
+ addrs.len = 0;
+ addrs.val = NULL;
+
+ ret = getaddrinfo (hostname, NULL, NULL, &ai);
+ if (ret)
+ return ret;
+
+ ret = add_addrs (context, &addrs, ai);
+ freeaddrinfo (ai);
+ if (ret)
+ return ret;
+
+ kdc_flags.i = flags;
+
+ ret = krb5_get_kdc_cred (context,
+ ccache,
+ kdc_flags,
+ &addrs,
+ NULL,
+ in_creds,
+ &out_creds);
+ krb5_free_addresses (context, &addrs);
+ if (ret) {
+ return ret;
+ }
+
+ memset (&cred, 0, sizeof(cred));
+ cred.pvno = 5;
+ cred.msg_type = krb_cred;
+ ALLOC_SEQ(&cred.tickets, 1);
+ if (cred.tickets.val == NULL) {
+ ret = ENOMEM;
+ goto out2;
+ }
+ ret = decode_Ticket(out_creds->ticket.data,
+ out_creds->ticket.length,
+ cred.tickets.val, &len);
+ if (ret)
+ goto out3;
+
+ memset (&enc_krb_cred_part, 0, sizeof(enc_krb_cred_part));
+ ALLOC_SEQ(&enc_krb_cred_part.ticket_info, 1);
+ if (enc_krb_cred_part.ticket_info.val == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ ALLOC(enc_krb_cred_part.timestamp, 1);
+ if (enc_krb_cred_part.timestamp == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+ *enc_krb_cred_part.timestamp = sec;
+ ALLOC(enc_krb_cred_part.usec, 1);
+ if (enc_krb_cred_part.usec == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+ *enc_krb_cred_part.usec = usec;
+
+ ret = krb5_make_addrport (&enc_krb_cred_part.s_address,
+ auth_context->local_address,
+ auth_context->local_port);
+ if (ret)
+ goto out4;
+
+ ALLOC(enc_krb_cred_part.r_address, 1);
+ if (enc_krb_cred_part.r_address == NULL) {
+ ret = ENOMEM;
+ goto out4;
+ }
+
+ ret = krb5_copy_address (context, auth_context->remote_address,
+ enc_krb_cred_part.r_address);
+ if (ret)
+ goto out4;
+
+ /* fill ticket_info.val[0] */
+
+ enc_krb_cred_part.ticket_info.len = 1;
+
+ krb_cred_info = enc_krb_cred_part.ticket_info.val;
+
+ copy_EncryptionKey (&out_creds->session, &krb_cred_info->key);
+ ALLOC(krb_cred_info->prealm, 1);
+ copy_Realm (&out_creds->client->realm, krb_cred_info->prealm);
+ ALLOC(krb_cred_info->pname, 1);
+ copy_PrincipalName(&out_creds->client->name, krb_cred_info->pname);
+ ALLOC(krb_cred_info->flags, 1);
+ *krb_cred_info->flags = out_creds->flags.b;
+ ALLOC(krb_cred_info->authtime, 1);
+ *krb_cred_info->authtime = out_creds->times.authtime;
+ ALLOC(krb_cred_info->starttime, 1);
+ *krb_cred_info->starttime = out_creds->times.starttime;
+ ALLOC(krb_cred_info->endtime, 1);
+ *krb_cred_info->endtime = out_creds->times.endtime;
+ ALLOC(krb_cred_info->renew_till, 1);
+ *krb_cred_info->renew_till = out_creds->times.renew_till;
+ ALLOC(krb_cred_info->srealm, 1);
+ copy_Realm (&out_creds->server->realm, krb_cred_info->srealm);
+ ALLOC(krb_cred_info->sname, 1);
+ copy_PrincipalName (&out_creds->server->name, krb_cred_info->sname);
+ ALLOC(krb_cred_info->caddr, 1);
+ copy_HostAddresses (&out_creds->addresses, krb_cred_info->caddr);
+
+ krb5_free_creds (context, out_creds);
+
+ /* encode EncKrbCredPart */
+
+ ret = krb5_encode_EncKrbCredPart (context,
+ buf + sizeof(buf) - 1, sizeof(buf),
+ &enc_krb_cred_part, &len);
+ free_EncKrbCredPart (&enc_krb_cred_part);
+ if (ret) {
+ free_KRB_CRED(&cred);
+ return ret;
+ }
+
+ krb5_crypto_init(context, auth_context->local_subkey, 0, &crypto);
+ ret = krb5_encrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_KRB_CRED,
+ buf + sizeof(buf) - len,
+ len,
+ 0,
+ &cred.enc_part);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free_KRB_CRED(&cred);
+ return ret;
+ }
+
+ ret = encode_KRB_CRED (buf + sizeof(buf) - 1, sizeof(buf),
+ &cred, &len);
+ free_KRB_CRED (&cred);
+ if (ret)
+ return ret;
+ out_data->length = len;
+ out_data->data = malloc(len);
+ if (out_data->data == NULL)
+ return ENOMEM;
+ memcpy (out_data->data, buf + sizeof(buf) - len, len);
+ return 0;
+out4:
+ free_EncKrbCredPart(&enc_krb_cred_part);
+out3:
+ free_KRB_CRED(&cred);
+out2:
+ krb5_free_creds (context, out_creds);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_host_realm.c b/crypto/heimdal/lib/krb5/get_host_realm.c
new file mode 100644
index 0000000..e8522cb
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_host_realm.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#include <resolve.h>
+
+RCSID("$Id: get_host_realm.c,v 1.25 1999/12/11 23:14:07 assar Exp $");
+
+/* To automagically find the correct realm of a host (without
+ * [domain_realm] in krb5.conf) add a text record for your domain with
+ * the name of your realm, like this:
+ *
+ * krb5-realm IN TXT FOO.SE
+ *
+ * The search is recursive, so you can add entries for specific
+ * hosts. To find the realm of host a.b.c, it first tries
+ * krb5-realm.a.b.c, then krb5-realm.b.c and so on.
+ *
+ * Also supported is _kerberos (following draft-ietf-cat-krb-dns-locate-01.txt)
+ *
+ */
+
+static int
+copy_txt_to_realms (struct resource_record *head,
+ krb5_realm **realms)
+{
+ struct resource_record *rr;
+ int n, i;
+
+ for(n = 0, rr = head; rr; rr = rr->next)
+ if (rr->type == T_TXT)
+ ++n;
+
+ if (n == 0)
+ return -1;
+
+ *realms = malloc ((n + 1) * sizeof(krb5_realm));
+ if (*realms == NULL)
+ return -1;
+
+ for (i = 0; i < n + 1; ++i)
+ (*realms)[i] = NULL;
+
+ for (i = 0, rr = head; rr; rr = rr->next) {
+ if (rr->type == T_TXT) {
+ char *tmp;
+
+ tmp = strdup(rr->u.txt);
+ if (tmp == NULL) {
+ for (i = 0; i < n; ++i)
+ free ((*realms)[i]);
+ free (*realms);
+ return -1;
+ }
+ (*realms)[i] = tmp;
+ ++i;
+ }
+ }
+ return 0;
+}
+
+static int
+dns_find_realm(krb5_context context,
+ const char *domain,
+ const char *dom_string,
+ krb5_realm **realms)
+{
+ char dom[MAXHOSTNAMELEN];
+ struct dns_reply *r;
+ int ret;
+
+ if(*domain == '.')
+ domain++;
+ snprintf(dom, sizeof(dom), "%s.%s.", dom_string, domain);
+ r = dns_lookup(dom, "TXT");
+ if(r == NULL)
+ return -1;
+
+ ret = copy_txt_to_realms (r->head, realms);
+ dns_free_data(r);
+ return ret;
+}
+
+/*
+ * Try to figure out what realms host in `domain' belong to from the
+ * configuration file.
+ */
+
+static int
+config_find_realm(krb5_context context,
+ const char *domain,
+ krb5_realm **realms)
+{
+ char **tmp = krb5_config_get_strings (context, NULL,
+ "domain_realm",
+ domain,
+ NULL);
+
+ if (tmp == NULL)
+ return -1;
+ *realms = tmp;
+ return 0;
+}
+
+/*
+ * This function assumes that `host' is a FQDN (and doesn't handle the
+ * special case of host == NULL either).
+ * Try to find mapping in the config file or DNS and it that fails,
+ * fall back to guessing
+ */
+
+krb5_error_code
+krb5_get_host_realm_int (krb5_context context,
+ const char *host,
+ krb5_realm **realms)
+{
+ const char *p;
+
+ for (p = host; p != NULL; p = strchr (p + 1, '.')) {
+ if(config_find_realm(context, p, realms) == 0)
+ return 0;
+ else if(dns_find_realm(context, p, "krb5-realm", realms) == 0)
+ return 0;
+ else if(dns_find_realm(context, p, "_kerberos", realms) == 0)
+ return 0;
+ }
+ p = strchr(host, '.');
+ if(p != NULL) {
+ p++;
+ *realms = malloc(2 * sizeof(krb5_realm));
+ if (*realms == NULL)
+ return ENOMEM;
+
+ (*realms)[0] = strdup(p);
+ if((*realms)[0] == NULL) {
+ free(*realms);
+ return ENOMEM;
+ }
+ strupr((*realms)[0]);
+ (*realms)[1] = NULL;
+ return 0;
+ }
+ return KRB5_ERR_HOST_REALM_UNKNOWN;
+}
+
+/*
+ * Return the realm(s) of `host' as a NULL-terminated list in `realms'.
+ */
+
+krb5_error_code
+krb5_get_host_realm(krb5_context context,
+ const char *host,
+ krb5_realm **realms)
+{
+ char hostname[MAXHOSTNAMELEN];
+
+ if (host == NULL) {
+ if (gethostname (hostname, sizeof(hostname)))
+ return errno;
+ host = hostname;
+ }
+
+ return krb5_get_host_realm_int (context, host, realms);
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt.c b/crypto/heimdal/lib/krb5/get_in_tkt.c
new file mode 100644
index 0000000..f65af47
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt.c,v 1.93 2000/01/06 20:36:28 assar Exp $");
+
+krb5_error_code
+krb5_init_etype (krb5_context context,
+ unsigned *len,
+ int **val,
+ const krb5_enctype *etypes)
+{
+ int i;
+ krb5_error_code ret;
+ krb5_enctype *tmp;
+
+ ret = 0;
+ if (etypes)
+ tmp = (krb5_enctype*)etypes;
+ else {
+ ret = krb5_get_default_in_tkt_etypes(context,
+ &tmp);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; tmp[i]; ++i)
+ ;
+ *len = i;
+ *val = malloc(i * sizeof(int));
+ if (i != 0 && *val == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+ memmove (*val,
+ tmp,
+ i * sizeof(*tmp));
+cleanup:
+ if (etypes == NULL)
+ free (tmp);
+ return ret;
+}
+
+
+static krb5_error_code
+decrypt_tkt (krb5_context context,
+ krb5_keyblock *key,
+ krb5_key_usage usage,
+ krb5_const_pointer decrypt_arg,
+ krb5_kdc_rep *dec_rep)
+{
+ krb5_error_code ret;
+ krb5_data data;
+ size_t size;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ usage,
+ &dec_rep->kdc_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_EncASRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ if (ret)
+ ret = krb5_decode_EncTGSRepPart(context,
+ data.data,
+ data.length,
+ &dec_rep->enc_part,
+ &size);
+ krb5_data_free (&data);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+int
+_krb5_extract_ticket(krb5_context context,
+ krb5_kdc_rep *rep,
+ krb5_creds *creds,
+ krb5_keyblock *key,
+ krb5_const_pointer keyseed,
+ krb5_key_usage key_usage,
+ krb5_addresses *addrs,
+ unsigned nonce,
+ krb5_boolean allow_server_mismatch,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg)
+{
+ krb5_error_code ret;
+ krb5_principal tmp_principal;
+ int tmp;
+ time_t tmp_time;
+ int32_t sec_now;
+
+ /* compare client */
+
+ ret = principalname2krb5_principal (&tmp_principal,
+ rep->kdc_rep.cname,
+ rep->kdc_rep.crealm);
+ if (ret)
+ goto out;
+ tmp = krb5_principal_compare (context, tmp_principal, creds->client);
+ krb5_free_principal (context, tmp_principal);
+ if (!tmp) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ /* extract ticket */
+ {
+ unsigned char *buf;
+ size_t len;
+ len = length_Ticket(&rep->kdc_rep.ticket);
+ buf = malloc(len);
+ if(buf == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ encode_Ticket(buf + len - 1, len, &rep->kdc_rep.ticket, &len);
+ creds->ticket.data = buf;
+ creds->ticket.length = len;
+ creds->second_ticket.length = 0;
+ creds->second_ticket.data = NULL;
+ }
+
+ /* compare server */
+
+ ret = principalname2krb5_principal (&tmp_principal,
+ rep->kdc_rep.ticket.sname,
+ rep->kdc_rep.ticket.realm);
+ if (ret)
+ goto out;
+ if(allow_server_mismatch){
+ krb5_free_principal(context, creds->server);
+ creds->server = tmp_principal;
+ tmp_principal = NULL;
+ }else{
+ tmp = krb5_principal_compare (context, tmp_principal, creds->server);
+ krb5_free_principal (context, tmp_principal);
+ if (!tmp) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+ }
+
+ /* decrypt */
+
+ if (decrypt_proc == NULL)
+ decrypt_proc = decrypt_tkt;
+
+ ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
+ if (ret)
+ goto out;
+
+#if 0
+ /* XXX should this decode be here, or in the decrypt_proc? */
+ ret = krb5_decode_keyblock(context, &rep->enc_part.key, 1);
+ if(ret)
+ goto out;
+#endif
+
+ /* compare nonces */
+
+ if (nonce != rep->enc_part.nonce) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ /* set kdc-offset */
+
+ krb5_timeofday (context, &sec_now);
+ if (context->kdc_sec_offset == 0
+ && krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "kdc_timesync",
+ NULL)) {
+ context->kdc_sec_offset = rep->enc_part.authtime - sec_now;
+ krb5_timeofday (context, &sec_now);
+ }
+
+ /* check all times */
+
+ if (rep->enc_part.starttime) {
+ tmp_time = *rep->enc_part.starttime;
+ } else
+ tmp_time = rep->enc_part.authtime;
+
+ if (creds->times.starttime == 0
+ && abs(tmp_time - sec_now) > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto out;
+ }
+
+ if (creds->times.starttime != 0
+ && tmp_time != creds->times.starttime) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ creds->times.starttime = tmp_time;
+
+ if (rep->enc_part.renew_till) {
+ tmp_time = *rep->enc_part.renew_till;
+ } else
+ tmp_time = 0;
+
+ if (creds->times.renew_till != 0
+ && tmp_time > creds->times.renew_till) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ creds->times.renew_till = tmp_time;
+
+ creds->times.authtime = rep->enc_part.authtime;
+
+ if (creds->times.endtime != 0
+ && rep->enc_part.endtime > creds->times.endtime) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto out;
+ }
+
+ creds->times.endtime = rep->enc_part.endtime;
+
+ if(rep->enc_part.caddr)
+ krb5_copy_addresses (context, rep->enc_part.caddr, &creds->addresses);
+ else if(addrs)
+ krb5_copy_addresses (context, addrs, &creds->addresses);
+ else {
+ creds->addresses.len = 0;
+ creds->addresses.val = NULL;
+ }
+ creds->flags.b = rep->enc_part.flags;
+
+ creds->authdata.len = 0;
+ creds->authdata.val = NULL;
+ creds->session.keyvalue.length = 0;
+ creds->session.keyvalue.data = NULL;
+ creds->session.keytype = rep->enc_part.key.keytype;
+ ret = krb5_data_copy (&creds->session.keyvalue,
+ rep->enc_part.key.keyvalue.data,
+ rep->enc_part.key.keyvalue.length);
+
+out:
+ memset (rep->enc_part.key.keyvalue.data, 0,
+ rep->enc_part.key.keyvalue.length);
+ return ret;
+}
+
+
+static krb5_error_code
+make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
+ krb5_enctype etype, krb5_keyblock *key)
+{
+ PA_ENC_TS_ENC p;
+ u_char buf[1024];
+ size_t len;
+ EncryptedData encdata;
+ krb5_error_code ret;
+ int32_t sec, usec;
+ int usec2;
+ krb5_crypto crypto;
+
+ krb5_us_timeofday (context, &sec, &usec);
+ p.patimestamp = sec;
+ usec2 = usec;
+ p.pausec = &usec2;
+
+ ret = encode_PA_ENC_TS_ENC(buf + sizeof(buf) - 1,
+ sizeof(buf),
+ &p,
+ &len);
+ if (ret)
+ return ret;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_encrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_PA_ENC_TIMESTAMP,
+ buf + sizeof(buf) - len,
+ len,
+ 0,
+ &encdata);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ return ret;
+
+ ret = encode_EncryptedData(buf + sizeof(buf) - 1,
+ sizeof(buf),
+ &encdata,
+ &len);
+ free_EncryptedData(&encdata);
+ if (ret)
+ return ret;
+ pa->padata_type = pa_enc_timestamp;
+ pa->padata_value.length = 0;
+ krb5_data_copy(&pa->padata_value,
+ buf + sizeof(buf) - len,
+ len);
+ return 0;
+}
+
+static krb5_error_code
+add_padata(krb5_context context,
+ METHOD_DATA *md,
+ krb5_principal client,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ int *enctypes,
+ unsigned netypes,
+ krb5_salt *salt)
+{
+ krb5_error_code ret;
+ PA_DATA *pa2;
+ krb5_salt salt2;
+ int *ep;
+ int i;
+
+ if(salt == NULL) {
+ /* default to standard salt */
+ ret = krb5_get_pw_salt (context, client, &salt2);
+ salt = &salt2;
+ }
+ if (!enctypes) {
+ enctypes = (int *)context->etypes; /* XXX */
+ netypes = 0;
+ for (ep = enctypes; *ep != ETYPE_NULL; ep++)
+ netypes++;
+ }
+ pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val));
+ if (pa2 == NULL)
+ return ENOMEM;
+ md->val = pa2;
+
+ for (i = 0; i < netypes; ++i) {
+ krb5_keyblock *key;
+
+ ret = (*key_proc)(context, enctypes[i], *salt, keyseed, &key);
+ if (ret)
+ continue;
+ ret = make_pa_enc_timestamp (context, &md->val[md->len],
+ enctypes[i], key);
+ krb5_free_keyblock (context, key);
+ if (ret)
+ return ret;
+ ++md->len;
+ }
+ if(salt == &salt2)
+ krb5_free_salt(context, salt2);
+ return 0;
+}
+
+static krb5_error_code
+init_as_req (krb5_context context,
+ krb5_kdc_flags opts,
+ krb5_creds *creds,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ const krb5_preauthdata *preauth,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ unsigned nonce,
+ AS_REQ *a)
+{
+ krb5_error_code ret;
+ krb5_salt salt;
+
+ memset(a, 0, sizeof(*a));
+
+ a->pvno = 5;
+ a->msg_type = krb_as_req;
+ a->req_body.kdc_options = opts.b;
+ a->req_body.cname = malloc(sizeof(*a->req_body.cname));
+ if (a->req_body.cname == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ a->req_body.sname = malloc(sizeof(*a->req_body.sname));
+ if (a->req_body.sname == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ ret = krb5_principal2principalname (a->req_body.cname, creds->client);
+ if (ret)
+ goto fail;
+ ret = krb5_principal2principalname (a->req_body.sname, creds->server);
+ if (ret)
+ goto fail;
+ ret = copy_Realm(&creds->client->realm, &a->req_body.realm);
+ if (ret)
+ goto fail;
+
+ if(creds->times.starttime) {
+ a->req_body.from = malloc(sizeof(*a->req_body.from));
+ if (a->req_body.from == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ *a->req_body.from = creds->times.starttime;
+ }
+ if(creds->times.endtime){
+ ALLOC(a->req_body.till, 1);
+ *a->req_body.till = creds->times.endtime;
+ }
+ if(creds->times.renew_till){
+ a->req_body.rtime = malloc(sizeof(*a->req_body.rtime));
+ if (a->req_body.rtime == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ *a->req_body.rtime = creds->times.renew_till;
+ }
+ a->req_body.nonce = nonce;
+ ret = krb5_init_etype (context,
+ &a->req_body.etype.len,
+ &a->req_body.etype.val,
+ etypes);
+ if (ret)
+ goto fail;
+
+ /*
+ * This means no addresses
+ */
+
+ if (addrs && addrs->len == 0) {
+ a->req_body.addresses = NULL;
+ } else {
+ a->req_body.addresses = malloc(sizeof(*a->req_body.addresses));
+ if (a->req_body.addresses == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ if (addrs)
+ ret = krb5_copy_addresses(context, addrs, a->req_body.addresses);
+ else
+ ret = krb5_get_all_client_addrs (context, a->req_body.addresses);
+ if (ret)
+ return ret;
+ }
+
+ a->req_body.enc_authorization_data = NULL;
+ a->req_body.additional_tickets = NULL;
+
+ if(preauth != NULL) {
+ int i;
+ ALLOC(a->padata, 1);
+ if(a->padata == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ for(i = 0; i < preauth->len; i++) {
+ if(preauth->val[i].type == KRB5_PADATA_ENC_TIMESTAMP){
+ int j;
+ PA_DATA *tmp = realloc(a->padata->val,
+ (a->padata->len +
+ preauth->val[i].info.len) *
+ sizeof(*a->padata->val));
+ if(tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ a->padata->val = tmp;
+ for(j = 0; j < preauth->val[i].info.len; j++) {
+ krb5_salt *sp = &salt;
+ if(preauth->val[i].info.val[j].salttype)
+ salt.salttype = *preauth->val[i].info.val[j].salttype;
+ else
+ salt.salttype = KRB5_PW_SALT;
+ if(preauth->val[i].info.val[j].salt)
+ salt.saltvalue = *preauth->val[i].info.val[j].salt;
+ else
+ if(salt.salttype == KRB5_PW_SALT)
+ sp = NULL;
+ else
+ krb5_data_zero(&salt.saltvalue);
+ add_padata(context, a->padata, creds->client,
+ key_proc, keyseed,
+ &preauth->val[i].info.val[j].etype, 1,
+ sp);
+ }
+ }
+ }
+ } else
+ /* not sure this is the way to use `ptypes' */
+ if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
+ a->padata = NULL;
+ else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) {
+ ALLOC(a->padata, 1);
+ if (a->padata == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ a->padata->len = 0;
+ a->padata->val = NULL;
+
+ /* make a v5 salted pa-data */
+ add_padata(context, a->padata, creds->client,
+ key_proc, keyseed, a->req_body.etype.val,
+ a->req_body.etype.len, NULL);
+
+ /* make a v4 salted pa-data */
+ salt.salttype = KRB5_PW_SALT;
+ krb5_data_zero(&salt.saltvalue);
+ add_padata(context, a->padata, creds->client,
+ key_proc, keyseed, a->req_body.etype.val,
+ a->req_body.etype.len, &salt);
+ } else {
+ ret = KRB5_PREAUTH_BAD_TYPE;
+ goto fail;
+ }
+ return 0;
+fail:
+ free_AS_REQ(a);
+ return ret;
+}
+
+static int
+set_ptypes(krb5_context context,
+ KRB_ERROR *error,
+ krb5_preauthtype **ptypes,
+ krb5_preauthdata **preauth)
+{
+ static krb5_preauthdata preauth2;
+ static krb5_preauthtype ptypes2[] = { KRB5_PADATA_ENC_TIMESTAMP, KRB5_PADATA_NONE };
+
+ if(error->e_data) {
+ METHOD_DATA md;
+ int i;
+ decode_METHOD_DATA(error->e_data->data,
+ error->e_data->length,
+ &md,
+ NULL);
+ for(i = 0; i < md.len; i++){
+ switch(md.val[i].padata_type){
+ case pa_enc_timestamp:
+ *ptypes = ptypes2;
+ break;
+ case pa_etype_info:
+ *preauth = &preauth2;
+ ALLOC_SEQ(*preauth, 1);
+ (*preauth)->val[0].type = KRB5_PADATA_ENC_TIMESTAMP;
+ krb5_decode_ETYPE_INFO(context,
+ md.val[i].padata_value.data,
+ md.val[i].padata_value.length,
+ &(*preauth)->val[0].info,
+ NULL);
+ break;
+ }
+ }
+ free_METHOD_DATA(&md);
+ } else {
+ *ptypes = ptypes2;
+ }
+ return(1);
+}
+
+krb5_error_code
+krb5_get_in_cred(krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ const krb5_preauthdata *preauth,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ krb5_error_code ret;
+ AS_REQ a;
+ krb5_kdc_rep rep;
+ krb5_data req, resp;
+ char buf[BUFSIZ];
+ krb5_salt salt;
+ krb5_keyblock *key;
+ size_t size;
+ krb5_kdc_flags opts;
+ PA_DATA *pa;
+ krb5_enctype etype;
+ krb5_preauthdata *my_preauth = NULL;
+ unsigned nonce;
+ int done;
+
+ opts.i = options;
+
+ krb5_generate_random_block (&nonce, sizeof(nonce));
+ nonce &= 0xffffffff;
+
+ do {
+ done = 1;
+ ret = init_as_req (context,
+ opts,
+ creds,
+ addrs,
+ etypes,
+ ptypes,
+ preauth,
+ key_proc,
+ keyseed,
+ nonce,
+ &a);
+ if (my_preauth) {
+ free_ETYPE_INFO(&my_preauth->val[0].info);
+ free (my_preauth->val);
+ }
+ if (ret)
+ return ret;
+
+ ret = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
+ sizeof(buf),
+ &a,
+ &req.length);
+ free_AS_REQ(&a);
+ if (ret)
+ return ret;
+
+ req.data = buf + sizeof(buf) - req.length;
+
+ ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
+ if (ret)
+ return ret;
+
+ memset (&rep, 0, sizeof(rep));
+ ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size);
+ if(ret) {
+ /* let's try to parse it as a KRB-ERROR */
+ KRB_ERROR error;
+ int ret2;
+
+ ret2 = krb5_rd_error(context, &resp, &error);
+ if(ret2 && resp.data && ((char*)resp.data)[0] == 4)
+ ret = KRB5KRB_AP_ERR_V4_REPLY;
+ krb5_data_free(&resp);
+ if (ret2 == 0) {
+ ret = error.error_code;
+ /* if no preauth was set and KDC requires it, give it
+ one more try */
+ if (!ptypes && !preauth
+ && ret == KRB5KDC_ERR_PREAUTH_REQUIRED
+#if 0
+ || ret == KRB5KDC_ERR_BADOPTION
+#endif
+ && set_ptypes(context, &error, &ptypes, &my_preauth)) {
+ done = 0;
+ preauth = my_preauth;
+ free_KRB_ERROR(&error);
+ continue;
+ }
+ if(ret_as_reply)
+ ret_as_reply->error = error;
+ else
+ free_KRB_ERROR (&error);
+ return ret;
+ }
+ return ret;
+ }
+ krb5_data_free(&resp);
+ } while(!done);
+
+ pa = NULL;
+ etype = rep.kdc_rep.enc_part.etype;
+ if(rep.kdc_rep.padata){
+ int index = 0;
+ pa = krb5_find_padata(rep.kdc_rep.padata->val, rep.kdc_rep.padata->len,
+ pa_pw_salt, &index);
+ if(pa == NULL) {
+ index = 0;
+ pa = krb5_find_padata(rep.kdc_rep.padata->val,
+ rep.kdc_rep.padata->len,
+ pa_afs3_salt, &index);
+ }
+ }
+ if(pa) {
+ salt.salttype = pa->padata_type;
+ salt.saltvalue = pa->padata_value;
+
+ ret = (*key_proc)(context, etype, salt, keyseed, &key);
+ } else {
+ /* make a v5 salted pa-data */
+ ret = krb5_get_pw_salt (context, creds->client, &salt);
+
+ if (ret)
+ goto out;
+ ret = (*key_proc)(context, etype, salt, keyseed, &key);
+ krb5_free_salt(context, salt);
+ }
+ if (ret)
+ goto out;
+
+ ret = _krb5_extract_ticket(context,
+ &rep,
+ creds,
+ key,
+ keyseed,
+ KRB5_KU_AS_REP_ENC_PART,
+ NULL,
+ nonce,
+ FALSE,
+ decrypt_proc,
+ decryptarg);
+ memset (key->keyvalue.data, 0, key->keyvalue.length);
+ krb5_free_keyblock_contents (context, key);
+ free (key);
+
+out:
+ if (ret == 0 && ret_as_reply)
+ *ret_as_reply = rep;
+ else
+ krb5_free_kdc_rep (context, &rep);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_in_tkt(krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_ccache ccache,
+ krb5_kdc_rep *ret_as_reply)
+{
+ krb5_error_code ret;
+ krb5_kdc_flags opts;
+ opts.i = 0;
+ opts.b = int2KDCOptions(options);
+
+ ret = krb5_get_in_cred (context,
+ opts.i,
+ addrs,
+ etypes,
+ ptypes,
+ NULL,
+ key_proc,
+ keyseed,
+ decrypt_proc,
+ decryptarg,
+ creds,
+ ret_as_reply);
+ if(ret)
+ return ret;
+ ret = krb5_cc_store_cred (context, ccache, creds);
+ krb5_free_creds_contents (context, creds);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt_pw.c b/crypto/heimdal/lib/krb5/get_in_tkt_pw.c
new file mode 100644
index 0000000..4fb8800
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt_pw.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt_pw.c,v 1.15 1999/12/02 17:05:10 joda Exp $");
+
+krb5_error_code
+krb5_password_key_proc (krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ krb5_error_code ret;
+ const char *password = (const char *)keyseed;
+ char buf[BUFSIZ];
+
+ *key = malloc (sizeof (**key));
+ if (*key == NULL)
+ return ENOMEM;
+ if (password == NULL) {
+ if(des_read_pw_string (buf, sizeof(buf), "Password: ", 0)) {
+ free (*key);
+ return KRB5_LIBOS_PWDINTR;
+ }
+ password = buf;
+ }
+ ret = krb5_string_to_key_salt (context, type, password, salt, *key);
+ memset (buf, 0, sizeof(buf));
+ return ret;
+}
+
+krb5_error_code
+krb5_get_in_tkt_with_password (krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const char *password,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ return krb5_get_in_tkt (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ krb5_password_key_proc,
+ password,
+ NULL,
+ NULL,
+ creds,
+ ccache,
+ ret_as_reply);
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c b/crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c
new file mode 100644
index 0000000..d78ef35
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt_with_keytab.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt_with_keytab.c,v 1.5 1999/12/02 17:05:10 joda Exp $");
+
+krb5_error_code
+krb5_keytab_key_proc (krb5_context context,
+ krb5_enctype enctype,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ krb5_keytab_key_proc_args *args = (krb5_keytab_key_proc_args *)keyseed;
+ krb5_keytab keytab = args->keytab;
+ krb5_principal principal = args->principal;
+ krb5_error_code ret;
+ krb5_keytab real_keytab;
+ krb5_keytab_entry entry;
+
+ if(keytab == NULL)
+ krb5_kt_default(context, &real_keytab);
+ else
+ real_keytab = keytab;
+
+ ret = krb5_kt_get_entry (context, real_keytab, principal,
+ 0, enctype, &entry);
+
+ if (keytab == NULL)
+ krb5_kt_close (context, real_keytab);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_copy_keyblock (context, &entry.keyblock, key);
+ krb5_kt_free_entry(context, &entry);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_in_tkt_with_keytab (krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ krb5_keytab keytab,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ krb5_keytab_key_proc_args *a;
+
+ a = malloc(sizeof(*a));
+ if (a == NULL)
+ return ENOMEM;
+
+ a->principal = creds->client;
+ a->keytab = keytab;
+
+ return krb5_get_in_tkt (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ krb5_keytab_key_proc,
+ a,
+ NULL,
+ NULL,
+ creds,
+ ccache,
+ ret_as_reply);
+}
diff --git a/crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c b/crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c
new file mode 100644
index 0000000..773d361
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_in_tkt_with_skey.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: get_in_tkt_with_skey.c,v 1.3 1999/12/02 17:05:10 joda Exp $");
+
+static krb5_error_code
+krb5_skey_key_proc (krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ return krb5_copy_keyblock (context, keyseed, key);
+}
+
+krb5_error_code
+krb5_get_in_tkt_with_skey (krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const krb5_keyblock *key,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply)
+{
+ if(key == NULL)
+ return krb5_get_in_tkt_with_keytab (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ NULL,
+ ccache,
+ creds,
+ ret_as_reply);
+ else
+ return krb5_get_in_tkt (context,
+ options,
+ addrs,
+ etypes,
+ pre_auth_types,
+ krb5_skey_key_proc,
+ key,
+ NULL,
+ NULL,
+ creds,
+ ccache,
+ ret_as_reply);
+}
diff --git a/crypto/heimdal/lib/krb5/get_port.c b/crypto/heimdal/lib/krb5/get_port.c
new file mode 100644
index 0000000..17bb45f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/get_port.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: get_port.c,v 1.7 1999/12/02 17:05:10 joda Exp $");
+
+int
+krb5_getportbyname (krb5_context context,
+ const char *service,
+ const char *proto,
+ int default_port)
+{
+ struct servent *sp;
+
+ if ((sp = roken_getservbyname (service, proto)) == NULL) {
+ krb5_warnx(context, "%s/%s unknown service, using default port %d",
+ service, proto, default_port);
+ return htons(default_port);
+ } else
+ return sp->s_port;
+}
diff --git a/crypto/heimdal/lib/krb5/heim_err.et b/crypto/heimdal/lib/krb5/heim_err.et
new file mode 100644
index 0000000..5ec3543
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/heim_err.et
@@ -0,0 +1,18 @@
+#
+# Error messages for the krb5 library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: heim_err.et,v 1.7 1999/08/25 20:49:17 joda Exp $"
+
+error_table heim
+
+prefix HEIM_ERR
+
+error_code LOG_PARSE, "Error parsing log destination"
+error_code V4_PRINC_NO_CONV, "Failed to convert v4 principal"
+error_code SALTTYPE_NOSUPP, "Salt type is not supported by enctype"
+error_code NOHOST, "Host not found"
+error_code OPNOTSUPP, "Operation not supported"
+
+end
diff --git a/crypto/heimdal/lib/krb5/init_creds.c b/crypto/heimdal/lib/krb5/init_creds.c
new file mode 100644
index 0000000..404fa5a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/init_creds.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: init_creds.c,v 1.2 1999/12/02 17:05:10 joda Exp $");
+
+void
+krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
+{
+ memset (opt, 0, sizeof(*opt));
+ opt->flags = 0;
+}
+
+void
+krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt,
+ krb5_deltat tkt_life)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_TKT_LIFE;
+ opt->tkt_life = tkt_life;
+}
+
+void
+krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt,
+ krb5_deltat renew_life)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE;
+ opt->renew_life = renew_life;
+}
+
+void
+krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt,
+ int forwardable)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_FORWARDABLE;
+ opt->forwardable = forwardable;
+}
+
+void
+krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt,
+ int proxiable)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_PROXIABLE;
+ opt->proxiable = proxiable;
+}
+
+void
+krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
+ krb5_enctype *etype_list,
+ int etype_list_length)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST;
+ opt->etype_list = etype_list;
+ opt->etype_list_length = etype_list_length;
+}
+
+void
+krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt,
+ krb5_addresses *addresses)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST;
+ opt->address_list = addresses;
+}
+
+void
+krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
+ krb5_preauthtype *preauth_list,
+ int preauth_list_length)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST;
+ opt->preauth_list_length = preauth_list_length;
+ opt->preauth_list = preauth_list;
+}
+
+void
+krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
+ krb5_data *salt)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_SALT;
+ opt->salt = salt;
+}
diff --git a/crypto/heimdal/lib/krb5/init_creds_pw.c b/crypto/heimdal/lib/krb5/init_creds_pw.c
new file mode 100644
index 0000000..84b295f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/init_creds_pw.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: init_creds_pw.c,v 1.36 1999/12/02 17:05:10 joda Exp $");
+
+static int
+get_config_time (krb5_context context,
+ char *realm,
+ char *name,
+ int def)
+{
+ int ret;
+
+ ret = krb5_config_get_time (context, NULL,
+ "realms",
+ realm,
+ name,
+ NULL);
+ if (ret >= 0)
+ return ret;
+ ret = krb5_config_get_time (context, NULL,
+ "libdefaults",
+ name,
+ NULL);
+ if (ret >= 0)
+ return ret;
+ return def;
+}
+
+static krb5_boolean
+get_config_bool (krb5_context context,
+ char *realm,
+ char *name)
+{
+ return krb5_config_get_bool (context,
+ NULL,
+ "realms",
+ realm,
+ name,
+ NULL)
+ || krb5_config_get_bool (context,
+ NULL,
+ "libdefaults",
+ name,
+ NULL);
+}
+
+static krb5_error_code
+init_cred (krb5_context context,
+ krb5_creds *cred,
+ krb5_principal client,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_realm *client_realm;
+ int tmp;
+ int32_t now;
+
+ krb5_timeofday (context, &now);
+
+ memset (cred, 0, sizeof(*cred));
+
+ if (client)
+ krb5_copy_principal(context, client, &cred->client);
+ else {
+ ret = krb5_get_default_principal (context,
+ &cred->client);
+ if (ret)
+ goto out;
+ }
+
+ client_realm = krb5_princ_realm (context, cred->client);
+
+ if (start_time)
+ cred->times.starttime = now + start_time;
+
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE)
+ tmp = options->tkt_life;
+ else
+ tmp = get_config_time (context,
+ *client_realm,
+ "ticket_lifetime",
+ 10 * 60 * 60);
+ cred->times.endtime = now + tmp;
+
+ tmp = 0;
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE)
+ tmp = options->renew_life;
+ else
+ tmp = get_config_time (context,
+ *client_realm,
+ "renew_lifetime",
+ 0);
+ if (tmp)
+ cred->times.renew_till = now + tmp;
+
+ if (in_tkt_service) {
+ krb5_realm server_realm;
+
+ ret = krb5_parse_name (context, in_tkt_service, &cred->server);
+ if (ret)
+ goto out;
+ server_realm = strdup (*client_realm);
+ free (cred->server->realm);
+ krb5_princ_set_realm (context, cred->server, &server_realm);
+ } else {
+ ret = krb5_make_principal(context, &cred->server,
+ *client_realm, KRB5_TGS_NAME, *client_realm,
+ NULL);
+ if (ret)
+ goto out;
+ }
+ return 0;
+
+out:
+ krb5_free_creds_contents (context, cred);
+ return ret;
+}
+
+/*
+ * Parse the last_req data and show it to the user if it's interesting
+ */
+
+static void
+print_expire (krb5_context context,
+ krb5_realm *realm,
+ krb5_kdc_rep *rep,
+ krb5_prompter_fct prompter,
+ krb5_data *data)
+{
+ int i;
+ LastReq *lr = &rep->enc_part.last_req;
+ int32_t sec;
+ time_t t;
+
+ krb5_timeofday (context, &sec);
+
+ t = sec + get_config_time (context,
+ *realm,
+ "warn_pwexpire",
+ 7 * 24 * 60 * 60);
+
+ for (i = 0; i < lr->len; ++i) {
+ if (lr->val[i].lr_type == 6
+ && lr->val[i].lr_value <= t) {
+ char *p;
+
+ asprintf (&p, "Your password will expire at %s",
+ ctime(&lr->val[i].lr_value));
+ (*prompter) (context, data, p, 0, NULL);
+ free (p);
+ return;
+ }
+ }
+
+ if (rep->enc_part.key_expiration
+ && *rep->enc_part.key_expiration <= t) {
+ char *p;
+
+ asprintf (&p, "Your password/account will expire at %s",
+ ctime(rep->enc_part.key_expiration));
+ (*prompter) (context, data, p, 0, NULL);
+ free (p);
+ }
+}
+
+static krb5_error_code
+get_init_creds_common(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options,
+ krb5_addresses **addrs,
+ krb5_enctype **etypes,
+ krb5_creds *cred,
+ krb5_preauthtype **pre_auth_types,
+ krb5_kdc_flags *flags)
+{
+ krb5_error_code ret;
+ krb5_realm *client_realm;
+
+ ret = init_cred (context, cred, client, start_time,
+ in_tkt_service, options);
+ if (ret)
+ return ret;
+
+ client_realm = krb5_princ_realm (context, cred->client);
+
+ flags->i = 0;
+
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)
+ flags->b.forwardable = options->forwardable;
+ else
+ flags->b.forwardable = get_config_bool (context,
+ *client_realm,
+ "forwardable");
+
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE)
+ flags->b.proxiable = options->proxiable;
+ else
+ flags->b.proxiable = get_config_bool (context,
+ *client_realm,
+ "proxiable");
+
+ if (start_time)
+ flags->b.postdated = 1;
+ if (cred->times.renew_till)
+ flags->b.renewable = 1;
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST)
+ *addrs = options->address_list;
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) {
+ *etypes = malloc((options->etype_list_length + 1)
+ * sizeof(krb5_enctype));
+ if (*etypes == NULL)
+ return ENOMEM;
+ memcpy (*etypes, options->etype_list,
+ options->etype_list_length * sizeof(krb5_enctype));
+ (*etypes)[options->etype_list_length] = ETYPE_NULL;
+ }
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) {
+ *pre_auth_types = malloc((options->preauth_list_length + 1)
+ * sizeof(krb5_preauthtype));
+ if (*pre_auth_types == NULL)
+ return ENOMEM;
+ memcpy (*pre_auth_types, options->preauth_list,
+ options->preauth_list_length * sizeof(krb5_preauthtype));
+ (*pre_auth_types)[options->preauth_list_length] = KRB5_PADATA_NONE;
+ }
+ if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT)
+ ; /* XXX */
+ return 0;
+}
+
+static krb5_error_code
+change_password (krb5_context context,
+ krb5_principal client,
+ const char *password,
+ char *newpw,
+ size_t newpw_sz,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_get_init_creds_opt *old_options)
+{
+ krb5_prompt prompt;
+ krb5_error_code ret;
+ krb5_creds cpw_cred;
+ char buf1[BUFSIZ], buf2[BUFSIZ];
+ krb5_data password_data;
+ int result_code;
+ krb5_data result_code_string;
+ krb5_data result_string;
+ char *p;
+ krb5_get_init_creds_opt options;
+
+ memset (&cpw_cred, 0, sizeof(cpw_cred));
+
+ krb5_get_init_creds_opt_init (&options);
+ krb5_get_init_creds_opt_set_tkt_life (&options, 60);
+ krb5_get_init_creds_opt_set_preauth_list (&options,
+ old_options->preauth_list,
+ old_options->preauth_list_length);
+
+ krb5_data_zero (&result_code_string);
+ krb5_data_zero (&result_string);
+
+ ret = krb5_get_init_creds_password (context,
+ &cpw_cred,
+ client,
+ password,
+ prompter,
+ data,
+ 0,
+ "kadmin/changepw",
+ &options);
+ if (ret)
+ goto out;
+
+ for(;;) {
+ password_data.data = buf1;
+ password_data.length = sizeof(buf1);
+
+ prompt.hidden = 1;
+ prompt.prompt = "New password: ";
+ prompt.reply = &password_data;
+
+ ret = (*prompter) (context, data, "Changing password", 1, &prompt);
+ if (ret)
+ goto out;
+
+ password_data.data = buf2;
+ password_data.length = sizeof(buf2);
+
+ prompt.hidden = 1;
+ prompt.prompt = "Repeat new password: ";
+ prompt.reply = &password_data;
+
+ ret = (*prompter) (context, data, "Changing password", 1, &prompt);
+ if (ret)
+ goto out;
+
+ if (strcmp (buf1, buf2) == 0)
+ break;
+ }
+
+ ret = krb5_change_password (context,
+ &cpw_cred,
+ buf1,
+ &result_code,
+ &result_code_string,
+ &result_string);
+ if (ret)
+ goto out;
+ asprintf (&p, "%s: %.*s\n",
+ result_code ? "Error" : "Success",
+ (int)result_string.length,
+ (char*)result_string.data);
+
+ ret = (*prompter) (context, data, p, 0, NULL);
+ free (p);
+ if (result_code == 0) {
+ strncpy (newpw, buf1, newpw_sz);
+ ret = 0;
+ } else
+ ret = ENOTTY;
+
+out:
+ memset (buf1, 0, sizeof(buf1));
+ memset (buf2, 0, sizeof(buf2));
+ krb5_data_free (&result_string);
+ krb5_data_free (&result_code_string);
+ krb5_free_creds_contents (context, &cpw_cred);
+ return ret;
+}
+
+krb5_error_code
+krb5_get_init_creds_password(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ const char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_kdc_flags flags;
+ krb5_addresses *addrs = NULL;
+ krb5_enctype *etypes = NULL;
+ krb5_preauthtype *pre_auth_types = NULL;
+ krb5_creds this_cred;
+ krb5_kdc_rep kdc_reply;
+ char buf[BUFSIZ];
+ krb5_data password_data;
+ int done;
+
+ ret = get_init_creds_common(context, creds, client, start_time,
+ in_tkt_service, options,
+ &addrs, &etypes, &this_cred, &pre_auth_types,
+ &flags);
+ if(ret)
+ goto out;
+
+ if (password == NULL) {
+ krb5_prompt prompt;
+ char *p;
+
+ krb5_unparse_name (context, this_cred.client, &p);
+ asprintf (&prompt.prompt, "%s's Password: ", p);
+ free (p);
+ password_data.data = buf;
+ password_data.length = sizeof(buf);
+ prompt.hidden = 1;
+ prompt.reply = &password_data;
+
+ ret = (*prompter) (context, data, NULL, 1, &prompt);
+ free (prompt.prompt);
+ if (ret) {
+ memset (buf, 0, sizeof(buf));
+ ret = KRB5_LIBOS_PWDINTR;
+ goto out;
+ }
+ password = password_data.data;
+ }
+
+ done = 0;
+ while(!done) {
+ memset(&kdc_reply, 0, sizeof(kdc_reply));
+ ret = krb5_get_in_cred (context,
+ flags.i,
+ addrs,
+ etypes,
+ pre_auth_types,
+ NULL,
+ krb5_password_key_proc,
+ password,
+ NULL,
+ NULL,
+ &this_cred,
+ &kdc_reply);
+ switch (ret) {
+ case 0 :
+ done = 1;
+ break;
+ case KRB5KDC_ERR_KEY_EXPIRED :
+ ret = change_password (context,
+ client,
+ password,
+ buf,
+ sizeof(buf),
+ prompter,
+ data,
+ options);
+ if (ret)
+ goto out;
+ password = buf;
+ break;
+ default:
+ goto out;
+ }
+ }
+
+ if (prompter)
+ print_expire (context,
+ krb5_princ_realm (context, this_cred.client),
+ &kdc_reply,
+ prompter,
+ data);
+out:
+ memset (buf, 0, sizeof(buf));
+ if (ret == 0)
+ krb5_free_kdc_rep (context, &kdc_reply);
+
+ free (pre_auth_types);
+ free (etypes);
+ if (ret == 0 && creds)
+ *creds = this_cred;
+ else
+ krb5_free_creds_contents (context, &this_cred);
+ return ret;
+}
+
+krb5_error_code
+krb5_keyblock_key_proc (krb5_context context,
+ krb5_keytype type,
+ krb5_data *salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ return krb5_copy_keyblock (context, keyseed, key);
+}
+
+krb5_error_code
+krb5_get_init_creds_keytab(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_keytab keytab,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_kdc_flags flags;
+ krb5_addresses *addrs = NULL;
+ krb5_enctype *etypes = NULL;
+ krb5_preauthtype *pre_auth_types = NULL;
+ krb5_creds this_cred;
+ krb5_keytab_key_proc_args *a;
+
+ ret = get_init_creds_common(context, creds, client, start_time,
+ in_tkt_service, options,
+ &addrs, &etypes, &this_cred, &pre_auth_types,
+ &flags);
+ if(ret)
+ goto out;
+
+ a = malloc (sizeof(*a));
+ if (a == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ a->principal = this_cred.client;
+ a->keytab = keytab;
+
+ ret = krb5_get_in_cred (context,
+ flags.i,
+ addrs,
+ etypes,
+ pre_auth_types,
+ NULL,
+ krb5_keytab_key_proc,
+ a,
+ NULL,
+ NULL,
+ &this_cred,
+ NULL);
+ if (ret)
+ goto out;
+ free (pre_auth_types);
+ free (etypes);
+ if (creds)
+ *creds = this_cred;
+ else
+ krb5_free_creds_contents (context, &this_cred);
+ return 0;
+
+out:
+ free (pre_auth_types);
+ free (etypes);
+ krb5_free_creds_contents (context, &this_cred);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/keyblock.c b/crypto/heimdal/lib/krb5/keyblock.c
new file mode 100644
index 0000000..89732a0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keyblock.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+void
+krb5_free_keyblock_contents(krb5_context context,
+ krb5_keyblock *keyblock)
+{
+ if(keyblock) {
+ if (keyblock->keyvalue.data != NULL)
+ memset(keyblock->keyvalue.data, 0, keyblock->keyvalue.length);
+ krb5_data_free (&keyblock->keyvalue);
+ }
+}
+
+void
+krb5_free_keyblock(krb5_context context,
+ krb5_keyblock *keyblock)
+{
+ if(keyblock){
+ krb5_free_keyblock_contents(context, keyblock);
+ free(keyblock);
+ }
+}
+
+krb5_error_code
+krb5_copy_keyblock_contents (krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock *to)
+{
+ return copy_EncryptionKey(inblock, to);
+}
+
+krb5_error_code
+krb5_copy_keyblock (krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock **to)
+{
+ krb5_keyblock *k;
+
+ k = malloc (sizeof(*k));
+ if (k == NULL)
+ return ENOMEM;
+ *to = k;
+ return krb5_copy_keyblock_contents (context, inblock, k);
+}
diff --git a/crypto/heimdal/lib/krb5/keytab.c b/crypto/heimdal/lib/krb5/keytab.c
new file mode 100644
index 0000000..af853a4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab.c,v 1.45 2000/01/02 00:31:20 assar Exp $");
+
+/*
+ * Register a new keytab in `ops'
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_register(krb5_context context,
+ const krb5_kt_ops *ops)
+{
+ struct krb5_keytab_data *tmp;
+
+ tmp = realloc(context->kt_types,
+ (context->num_kt_types + 1) * sizeof(*context->kt_types));
+ if(tmp == NULL)
+ return ENOMEM;
+ memcpy(&tmp[context->num_kt_types], ops,
+ sizeof(tmp[context->num_kt_types]));
+ context->kt_types = tmp;
+ context->num_kt_types++;
+ return 0;
+}
+
+/*
+ * Resolve the keytab name (of the form `type:residual') in `name'
+ * into a keytab in `id'.
+ * Return 0 or an error
+ */
+
+krb5_error_code
+krb5_kt_resolve(krb5_context context,
+ const char *name,
+ krb5_keytab *id)
+{
+ krb5_keytab k;
+ int i;
+ const char *type, *residual;
+ size_t type_len;
+ krb5_error_code ret;
+
+ residual = strchr(name, ':');
+ if(residual == NULL) {
+ type = "FILE";
+ type_len = strlen(type);
+ residual = name;
+ } else {
+ type = name;
+ type_len = residual - name;
+ residual++;
+ }
+
+ for(i = 0; i < context->num_kt_types; i++) {
+ if(strncmp(type, context->kt_types[i].prefix, type_len) == 0)
+ break;
+ }
+ if(i == context->num_kt_types)
+ return KRB5_KT_UNKNOWN_TYPE;
+
+ k = malloc (sizeof(*k));
+ if (k == NULL)
+ return ENOMEM;
+ memcpy(k, &context->kt_types[i], sizeof(*k));
+ k->data = NULL;
+ ret = (*k->resolve)(context, residual, k);
+ if(ret) {
+ free(k);
+ k = NULL;
+ }
+ *id = k;
+ return ret;
+}
+
+/*
+ * copy the name of the default keytab into `name'.
+ * Return 0 or KRB5_CONFIG_NOTENUFSPACE if `namesize' is too short.
+ */
+
+krb5_error_code
+krb5_kt_default_name(krb5_context context, char *name, size_t namesize)
+{
+ strncpy(name, context->default_keytab, namesize);
+ if(strlen(context->default_keytab) >= namesize)
+ return KRB5_CONFIG_NOTENUFSPACE;
+ return 0;
+}
+
+/*
+ * Set `id' to the default keytab.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_default(krb5_context context, krb5_keytab *id)
+{
+ return krb5_kt_resolve (context, context->default_keytab, id);
+}
+
+/*
+ * Read the key identified by `(principal, vno, enctype)' from the
+ * keytab in `keyprocarg' (the default if == NULL) into `*key'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_read_service_key(krb5_context context,
+ krb5_pointer keyprocarg,
+ krb5_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype,
+ krb5_keyblock **key)
+{
+ krb5_keytab keytab;
+ krb5_keytab_entry entry;
+ krb5_error_code ret;
+
+ if (keyprocarg)
+ ret = krb5_kt_resolve (context, keyprocarg, &keytab);
+ else
+ ret = krb5_kt_default (context, &keytab);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
+ krb5_kt_close (context, keytab);
+ if (ret)
+ return ret;
+ ret = krb5_copy_keyblock (context, &entry.keyblock, key);
+ krb5_kt_free_entry(context, &entry);
+ return ret;
+}
+
+/*
+ * Retrieve the name of the keytab `keytab' into `name', `namesize'
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_get_name(krb5_context context,
+ krb5_keytab keytab,
+ char *name,
+ size_t namesize)
+{
+ return (*keytab->get_name)(context, keytab, name, namesize);
+}
+
+/*
+ * Finish using the keytab in `id'. All resources will be released.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_close(krb5_context context,
+ krb5_keytab id)
+{
+ krb5_error_code ret;
+
+ ret = (*id->close)(context, id);
+ if(ret == 0)
+ free(id);
+ return ret;
+}
+
+/*
+ * Compare `entry' against `principal, vno, enctype'.
+ * Any of `principal, vno, enctype' might be 0 which acts as a wildcard.
+ * Return TRUE if they compare the same, FALSE otherwise.
+ */
+
+krb5_boolean
+krb5_kt_compare(krb5_context context,
+ krb5_keytab_entry *entry,
+ krb5_const_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype)
+{
+ if(principal != NULL &&
+ !krb5_principal_compare(context, entry->principal, principal))
+ return FALSE;
+ if(vno && vno != entry->vno)
+ return FALSE;
+ if(enctype && enctype != entry->keyblock.keytype)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Retrieve the keytab entry for `principal, kvno, enctype' into `entry'
+ * from the keytab `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_get_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry)
+{
+ krb5_keytab_entry tmp;
+ krb5_error_code ret;
+ krb5_kt_cursor cursor;
+
+ if(id->get)
+ return (*id->get)(context, id, principal, kvno, enctype, entry);
+
+ ret = krb5_kt_start_seq_get (context, id, &cursor);
+ if (ret)
+ return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */
+
+ entry->vno = 0;
+ while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
+ if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) {
+ if (kvno == tmp.vno) {
+ krb5_kt_copy_entry_contents (context, &tmp, entry);
+ krb5_kt_free_entry (context, &tmp);
+ krb5_kt_end_seq_get(context, id, &cursor);
+ return 0;
+ } else if (kvno == 0 && tmp.vno > entry->vno) {
+ if (entry->vno)
+ krb5_kt_free_entry (context, entry);
+ krb5_kt_copy_entry_contents (context, &tmp, entry);
+ }
+ }
+ krb5_kt_free_entry(context, &tmp);
+ }
+ krb5_kt_end_seq_get (context, id, &cursor);
+ if (entry->vno)
+ return 0;
+ else
+ return KRB5_KT_NOTFOUND;
+}
+
+/*
+ * Copy the contents of `in' into `out'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_copy_entry_contents(krb5_context context,
+ const krb5_keytab_entry *in,
+ krb5_keytab_entry *out)
+{
+ krb5_error_code ret;
+
+ memset(out, 0, sizeof(*out));
+ out->vno = in->vno;
+
+ ret = krb5_copy_principal (context, in->principal, &out->principal);
+ if (ret)
+ goto fail;
+ ret = krb5_copy_keyblock_contents (context,
+ &in->keyblock,
+ &out->keyblock);
+ if (ret)
+ goto fail;
+ out->timestamp = in->timestamp;
+ return 0;
+fail:
+ krb5_kt_free_entry (context, out);
+ return ret;
+}
+
+/*
+ * Free the contents of `entry'.
+ */
+
+krb5_error_code
+krb5_kt_free_entry(krb5_context context,
+ krb5_keytab_entry *entry)
+{
+ krb5_free_principal (context, entry->principal);
+ krb5_free_keyblock_contents (context, &entry->keyblock);
+ return 0;
+}
+
+#if 0
+static int
+xxxlock(int fd, int write)
+{
+ if(flock(fd, (write ? LOCK_EX : LOCK_SH) | LOCK_NB) < 0) {
+ sleep(1);
+ if(flock(fd, (write ? LOCK_EX : LOCK_SH) | LOCK_NB) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static void
+xxxunlock(int fd)
+{
+ flock(fd, LOCK_UN);
+}
+#endif
+
+/*
+ * Set `cursor' to point at the beginning of `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ if(id->start_seq_get == NULL)
+ return HEIM_ERR_OPNOTSUPP;
+ return (*id->start_seq_get)(context, id, cursor);
+}
+
+/*
+ * Get the next entry from `id' pointed to by `cursor' and advance the
+ * `cursor'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor)
+{
+ if(id->next_entry == NULL)
+ return HEIM_ERR_OPNOTSUPP;
+ return (*id->next_entry)(context, id, entry, cursor);
+}
+
+/*
+ * Release all resources associated with `cursor'.
+ */
+
+krb5_error_code
+krb5_kt_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ if(id->end_seq_get == NULL)
+ return HEIM_ERR_OPNOTSUPP;
+ return (*id->end_seq_get)(context, id, cursor);
+}
+
+/*
+ * Add the entry in `entry' to the keytab `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ if(id->add == NULL)
+ return KRB5_KT_NOWRITE;
+ return (*id->add)(context, id,entry);
+}
+
+/*
+ * Remove the entry `entry' from the keytab `id'.
+ * Return 0 or an error.
+ */
+
+krb5_error_code
+krb5_kt_remove_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ if(id->remove == NULL)
+ return KRB5_KT_NOWRITE;
+ return (*id->remove)(context, id, entry);
+}
diff --git a/crypto/heimdal/lib/krb5/keytab_file.c b/crypto/heimdal/lib/krb5/keytab_file.c
new file mode 100644
index 0000000..c6c35e5
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_file.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab_file.c,v 1.6 2000/01/02 00:20:22 assar Exp $");
+
+#define KRB5_KT_VNO_1 1
+#define KRB5_KT_VNO_2 2
+#define KRB5_KT_VNO KRB5_KT_VNO_2
+
+/* file operations -------------------------------------------- */
+
+struct fkt_data {
+ char *filename;
+};
+
+static krb5_error_code
+krb5_kt_ret_data(krb5_storage *sp,
+ krb5_data *data)
+{
+ int ret;
+ int16_t size;
+ ret = krb5_ret_int16(sp, &size);
+ if(ret)
+ return ret;
+ data->length = size;
+ data->data = malloc(size);
+ if (data->data == NULL)
+ return ENOMEM;
+ ret = sp->fetch(sp, data->data, size);
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_KT_END;
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_ret_string(krb5_storage *sp,
+ general_string *data)
+{
+ int ret;
+ int16_t size;
+ ret = krb5_ret_int16(sp, &size);
+ if(ret)
+ return ret;
+ *data = malloc(size + 1);
+ if (*data == NULL)
+ return ENOMEM;
+ ret = sp->fetch(sp, *data, size);
+ (*data)[size] = '\0';
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_KT_END;
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_store_data(krb5_storage *sp,
+ krb5_data data)
+{
+ int ret;
+ ret = krb5_store_int16(sp, data.length);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data.data, data.length);
+ if(ret != data.length){
+ if(ret < 0)
+ return errno;
+ return KRB5_KT_END;
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_store_string(krb5_storage *sp,
+ general_string data)
+{
+ int ret;
+ size_t len = strlen(data);
+ ret = krb5_store_int16(sp, len);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data, len);
+ if(ret != len){
+ if(ret < 0)
+ return errno;
+ return KRB5_KT_END;
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
+{
+ int ret;
+ int16_t tmp;
+
+ ret = krb5_ret_int16(sp, &tmp); /* keytype + etype */
+ if(ret) return ret;
+ p->keytype = tmp;
+ ret = krb5_kt_ret_data(sp, &p->keyvalue);
+ return ret;
+}
+
+static krb5_error_code
+krb5_kt_store_keyblock(krb5_storage *sp,
+ krb5_keyblock *p)
+{
+ int ret;
+
+ ret = krb5_store_int16(sp, p->keytype); /* keytype + etype */
+ if(ret) return ret;
+ ret = krb5_kt_store_data(sp, p->keyvalue);
+ return ret;
+}
+
+
+static krb5_error_code
+krb5_kt_ret_principal(krb5_storage *sp,
+ krb5_principal *princ)
+{
+ int i;
+ int ret;
+ krb5_principal p;
+ int16_t tmp;
+
+ ALLOC(p, 1);
+ if(p == NULL)
+ return ENOMEM;
+
+ ret = krb5_ret_int16(sp, &tmp);
+ if(ret)
+ return ret;
+ if (sp->flags & KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)
+ tmp--;
+ p->name.name_string.len = tmp;
+ ret = krb5_kt_ret_string(sp, &p->realm);
+ if(ret) return ret;
+ p->name.name_string.val = calloc(p->name.name_string.len,
+ sizeof(*p->name.name_string.val));
+ if(p->name.name_string.val == NULL)
+ return ENOMEM;
+ for(i = 0; i < p->name.name_string.len; i++){
+ ret = krb5_kt_ret_string(sp, p->name.name_string.val + i);
+ if(ret) return ret;
+ }
+ if (krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
+ p->name.name_type = KRB5_NT_UNKNOWN;
+ else {
+ int32_t tmp32;
+ ret = krb5_ret_int32(sp, &tmp32);
+ p->name.name_type = tmp32;
+ if (ret)
+ return ret;
+ }
+ *princ = p;
+ return 0;
+}
+
+static krb5_error_code
+krb5_kt_store_principal(krb5_storage *sp,
+ krb5_principal p)
+{
+ int i;
+ int ret;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
+ ret = krb5_store_int16(sp, p->name.name_string.len + 1);
+ else
+ ret = krb5_store_int16(sp, p->name.name_string.len);
+ if(ret) return ret;
+ ret = krb5_kt_store_string(sp, p->realm);
+ if(ret) return ret;
+ for(i = 0; i < p->name.name_string.len; i++){
+ ret = krb5_kt_store_string(sp, p->name.name_string.val[i]);
+ if(ret) return ret;
+ }
+ if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
+ ret = krb5_store_int32(sp, p->name.name_type);
+ if(ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static krb5_error_code
+fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct fkt_data *d;
+ d = malloc(sizeof(*d));
+ if(d == NULL)
+ return ENOMEM;
+ d->filename = strdup(name);
+ if(d->filename == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+fkt_close(krb5_context context, krb5_keytab id)
+{
+ struct fkt_data *d = id->data;
+ free(d->filename);
+ free(d);
+ return 0;
+}
+
+static krb5_error_code
+fkt_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t namesize)
+{
+ /* This function is XXX */
+ struct fkt_data *d = id->data;
+ strlcpy(name, d->filename, namesize);
+ return 0;
+}
+
+static void
+storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
+{
+ int flags = 0;
+ switch(vno) {
+ case KRB5_KT_VNO_1:
+ flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;
+ flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;
+ flags |= KRB5_STORAGE_HOST_BYTEORDER;
+ break;
+ case KRB5_KT_VNO_2:
+ break;
+ default:
+ krb5_abortx(context,
+ "storage_set_flags called with bad vno (%x)", vno);
+ }
+ krb5_storage_set_flags(sp, flags);
+}
+
+static krb5_error_code
+fkt_start_seq_get_int(krb5_context context,
+ krb5_keytab id,
+ int flags,
+ krb5_kt_cursor *c)
+{
+ int8_t pvno, tag;
+ krb5_error_code ret;
+ struct fkt_data *d = id->data;
+
+ c->fd = open (d->filename, flags);
+ if (c->fd < 0)
+ return errno;
+ c->sp = krb5_storage_from_fd(c->fd);
+ ret = krb5_ret_int8(c->sp, &pvno);
+ if(ret) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return ret;
+ }
+ if(pvno != 5) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return KRB5_KEYTAB_BADVNO;
+ }
+ ret = krb5_ret_int8(c->sp, &tag);
+ if (ret) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return ret;
+ }
+ id->version = tag;
+ storage_set_flags(context, c->sp, id->version);
+ return 0;
+}
+
+static krb5_error_code
+fkt_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ return fkt_start_seq_get_int(context, id, O_RDONLY | O_BINARY, c);
+}
+
+static krb5_error_code
+fkt_next_entry_int(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor,
+ off_t *start,
+ off_t *end)
+{
+ int32_t len;
+ int ret;
+ int8_t tmp8;
+ int32_t tmp32;
+ off_t pos;
+
+ pos = cursor->sp->seek(cursor->sp, 0, SEEK_CUR);
+loop:
+ ret = krb5_ret_int32(cursor->sp, &len);
+ if (ret)
+ return ret;
+ if(len < 0) {
+ pos = cursor->sp->seek(cursor->sp, -len, SEEK_CUR);
+ goto loop;
+ }
+ ret = krb5_kt_ret_principal (cursor->sp, &entry->principal);
+ if (ret)
+ goto out;
+ ret = krb5_ret_int32(cursor->sp, &tmp32);
+ entry->timestamp = tmp32;
+ if (ret)
+ goto out;
+ ret = krb5_ret_int8(cursor->sp, &tmp8);
+ if (ret)
+ goto out;
+ entry->vno = tmp8;
+ ret = krb5_kt_ret_keyblock (cursor->sp, &entry->keyblock);
+ if (ret)
+ goto out;
+ if(start) *start = pos;
+ if(end) *end = *start + 4 + len;
+ out:
+ cursor->sp->seek(cursor->sp, pos + 4 + len, SEEK_SET);
+ return ret;
+}
+
+static krb5_error_code
+fkt_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor)
+{
+ return fkt_next_entry_int(context, id, entry, cursor, NULL, NULL);
+}
+
+static krb5_error_code
+fkt_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ krb5_storage_free(cursor->sp);
+ close(cursor->fd);
+ return 0;
+}
+
+static krb5_error_code
+fkt_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ int ret;
+ int fd;
+ krb5_storage *sp;
+ struct fkt_data *d = id->data;
+ krb5_data keytab;
+ int32_t len;
+
+ fd = open (d->filename, O_RDWR | O_BINARY);
+ if (fd < 0) {
+ fd = open (d->filename, O_RDWR | O_CREAT | O_BINARY, 0600);
+ if (fd < 0)
+ return errno;
+ sp = krb5_storage_from_fd(fd);
+ ret = krb5_store_int8(sp, 5);
+ if(ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ if(id->version == 0)
+ id->version = KRB5_KT_VNO;
+ ret = krb5_store_int8 (sp, id->version);
+ if (ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ storage_set_flags(context, sp, id->version);
+ } else {
+ int8_t pvno, tag;
+ sp = krb5_storage_from_fd(fd);
+ ret = krb5_ret_int8(sp, &pvno);
+ if(ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ if(pvno != 5) {
+ krb5_storage_free(sp);
+ close(fd);
+ return KRB5_KEYTAB_BADVNO;
+ }
+ ret = krb5_ret_int8 (sp, &tag);
+ if (ret) {
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+ }
+ id->version = tag;
+ storage_set_flags(context, sp, id->version);
+ }
+
+ {
+ krb5_storage *emem;
+ emem = krb5_storage_emem();
+ if(emem == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = krb5_kt_store_principal(emem, entry->principal);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_store_int32 (emem, entry->timestamp);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_store_int8 (emem, entry->vno);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_kt_store_keyblock (emem, &entry->keyblock);
+ if(ret) {
+ krb5_storage_free(emem);
+ goto out;
+ }
+ ret = krb5_storage_to_data(emem, &keytab);
+ krb5_storage_free(emem);
+ if(ret)
+ goto out;
+ }
+
+ while(1) {
+ ret = krb5_ret_int32(sp, &len);
+ if(ret == KRB5_CC_END) {
+ len = keytab.length;
+ break;
+ }
+ if(len < 0) {
+ len = -len;
+ if(len >= keytab.length) {
+ sp->seek(sp, -4, SEEK_CUR);
+ break;
+ }
+ }
+ sp->seek(sp, len, SEEK_CUR);
+ }
+ ret = krb5_store_int32(sp, len);
+ if(sp->store(sp, keytab.data, keytab.length) < 0)
+ ret = errno;
+ memset(keytab.data, 0, keytab.length);
+ krb5_data_free(&keytab);
+ out:
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+}
+
+static krb5_error_code
+fkt_remove_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ krb5_keytab_entry e;
+ krb5_kt_cursor cursor;
+ off_t pos_start, pos_end;
+ int found = 0;
+
+ fkt_start_seq_get_int(context, id, O_RDWR | O_BINARY, &cursor);
+ while(fkt_next_entry_int(context, id, &e, &cursor,
+ &pos_start, &pos_end) == 0) {
+ if(krb5_kt_compare(context, &e, entry->principal,
+ entry->vno, entry->keyblock.keytype)) {
+ int32_t len;
+ unsigned char buf[128];
+ found = 1;
+ cursor.sp->seek(cursor.sp, pos_start, SEEK_SET);
+ len = pos_end - pos_start - 4;
+ krb5_store_int32(cursor.sp, -len);
+ memset(buf, 0, sizeof(buf));
+ while(len > 0) {
+ cursor.sp->store(cursor.sp, buf, min(len, sizeof(buf)));
+ len -= min(len, sizeof(buf));
+ }
+ }
+ }
+ krb5_kt_end_seq_get(context, id, &cursor);
+ if (!found)
+ return KRB5_KT_NOTFOUND;
+ return 0;
+}
+
+const krb5_kt_ops krb5_fkt_ops = {
+ "FILE",
+ fkt_resolve,
+ fkt_get_name,
+ fkt_close,
+ NULL, /* get */
+ fkt_start_seq_get,
+ fkt_next_entry,
+ fkt_end_seq_get,
+ fkt_add_entry,
+ fkt_remove_entry
+};
diff --git a/crypto/heimdal/lib/krb5/keytab_keyfile.c b/crypto/heimdal/lib/krb5/keytab_keyfile.c
new file mode 100644
index 0000000..fa14e62
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_keyfile.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab_keyfile.c,v 1.7 2000/01/02 04:00:22 assar Exp $");
+
+/* afs keyfile operations --------------------------------------- */
+
+/*
+ * Minimum tools to handle the AFS KeyFile.
+ *
+ * Format of the KeyFile is:
+ * <int32_t numkeys> {[<int32_t kvno> <char[8] deskey>] * numkeys}
+ *
+ * It just adds to the end of the keyfile, deleting isn't implemented.
+ * Use your favorite text/hex editor to delete keys.
+ *
+ */
+
+#define AFS_SERVERTHISCELL "/usr/afs/etc/ThisCell"
+#define AFS_SERVERMAGICKRBCONF "/usr/afs/etc/krb.conf"
+
+struct akf_data {
+ int num_entries;
+ char *filename;
+ char *cell;
+ char *realm;
+};
+
+/*
+ * set `d->cell' and `d->realm'
+ */
+
+static int
+get_cell_and_realm (struct akf_data *d)
+{
+ FILE *f;
+ char buf[BUFSIZ], *cp;
+
+ f = fopen (AFS_SERVERTHISCELL, "r");
+ if (f == NULL)
+ return errno;
+ if (fgets (buf, sizeof(buf), f) == NULL) {
+ fclose (f);
+ return EINVAL;
+ }
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ fclose(f);
+
+ d->cell = strdup (buf);
+ if (d->cell == NULL)
+ return errno;
+
+ f = fopen (AFS_SERVERMAGICKRBCONF, "r");
+ if (f != NULL) {
+ if (fgets (buf, sizeof(buf), f) == NULL) {
+ fclose (f);
+ return EINVAL;
+ }
+ if (buf[strlen(buf)-1] == '\n')
+ buf[strlen(buf)-1] = '\0';
+ fclose(f);
+ }
+ /* uppercase */
+ for (cp = buf; *cp != '\0'; cp++)
+ *cp = toupper(*cp);
+
+ d->realm = strdup (buf);
+ if (d->realm == NULL) {
+ free (d->cell);
+ return errno;
+ }
+ return 0;
+}
+
+/*
+ * init and get filename
+ */
+
+static krb5_error_code
+akf_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ int ret;
+ struct akf_data *d = malloc(sizeof (struct akf_data));
+
+ if (d == NULL)
+ return errno;
+
+ d->num_entries = 0;
+ ret = get_cell_and_realm (d);
+ if (ret) {
+ free (d);
+ return ret;
+ }
+ d->filename = strdup (name);
+ if (d->filename == NULL) {
+ free (d->cell);
+ free (d->realm);
+ free (d);
+ return ENOMEM;
+ }
+ id->data = d;
+
+ return 0;
+}
+
+/*
+ * cleanup
+ */
+
+static krb5_error_code
+akf_close(krb5_context context, krb5_keytab id)
+{
+ struct akf_data *d = id->data;
+
+ free (d->filename);
+ free (d->cell);
+ free (d);
+ return 0;
+}
+
+/*
+ * Return filename
+ */
+
+static krb5_error_code
+akf_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t name_sz)
+{
+ struct akf_data *d = id->data;
+
+ strlcpy (name, d->filename, name_sz);
+ return 0;
+}
+
+/*
+ * Init
+ */
+
+static krb5_error_code
+akf_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ int32_t ret;
+ struct akf_data *d = id->data;
+
+ c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600);
+ if (c->fd < 0)
+ return errno;
+
+ c->sp = krb5_storage_from_fd(c->fd);
+ ret = krb5_ret_int32(c->sp, &d->num_entries);
+ if(ret) {
+ krb5_storage_free(c->sp);
+ close(c->fd);
+ return ret;
+ }
+
+ return 0;
+}
+
+static krb5_error_code
+akf_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor)
+{
+ struct akf_data *d = id->data;
+ int32_t kvno;
+ off_t pos;
+ int ret;
+
+ pos = cursor->sp->seek(cursor->sp, 0, SEEK_CUR);
+
+ if ((pos - 4) / (4 + 8) >= d->num_entries)
+ return KRB5_KT_END;
+
+ ret = krb5_make_principal (context, &entry->principal,
+ d->realm, "afs", d->cell, NULL);
+ if (ret)
+ goto out;
+
+ ret = krb5_ret_int32(cursor->sp, &kvno);
+ if (ret) {
+ krb5_free_principal (context, entry->principal);
+ goto out;
+ }
+
+ entry->vno = (int8_t) kvno;
+
+ entry->keyblock.keytype = ETYPE_DES_CBC_MD5;
+ entry->keyblock.keyvalue.length = 8;
+ entry->keyblock.keyvalue.data = malloc (8);
+ if (entry->keyblock.keyvalue.data == NULL) {
+ krb5_free_principal (context, entry->principal);
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = cursor->sp->fetch(cursor->sp, entry->keyblock.keyvalue.data, 8);
+ if(ret != 8)
+ ret = (ret < 0) ? errno : KRB5_KT_END;
+
+ entry->timestamp = time(NULL);
+
+ out:
+ cursor->sp->seek(cursor->sp, pos + 4 + 8, SEEK_SET);
+ return ret;
+}
+
+static krb5_error_code
+akf_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ krb5_storage_free(cursor->sp);
+ close(cursor->fd);
+ return 0;
+}
+
+static krb5_error_code
+akf_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct akf_data *d = id->data;
+ int fd, created = 0;
+ int32_t kvno;
+
+ fd = open (d->filename, O_RDWR | O_BINARY);
+ if (fd < 0) {
+ fd = open (d->filename,
+ O_RDWR | O_BINARY | O_CREAT, 0600);
+ if (fd < 0)
+ return errno;
+ created = 1;
+ }
+
+ if (entry->keyblock.keyvalue.length == 8
+ && entry->keyblock.keytype == ETYPE_DES_CBC_MD5) {
+
+ int32_t len = 0;
+
+ if (!created) {
+ if (lseek (fd, 0, SEEK_SET))
+ return errno;
+
+ if (read (fd, &len, sizeof(len)) != sizeof(len))
+ return errno;
+ }
+ len += 1;
+
+ if (lseek (fd, 0, SEEK_SET))
+ return errno;
+
+ if (write (fd, &len, sizeof(len)) != sizeof(len))
+ return errno;
+
+ if (lseek (fd, 4 + (len-1) * (8+4), SEEK_SET))
+ return errno;
+
+ kvno = entry->vno;
+ write(fd, &kvno, sizeof(kvno));
+ write(fd, entry->keyblock.keyvalue.data, 8);
+ }
+ close (fd);
+ return 0;
+}
+
+const krb5_kt_ops krb5_akf_ops = {
+ "AFSKEYFILE",
+ akf_resolve,
+ akf_get_name,
+ akf_close,
+ NULL, /* get */
+ akf_start_seq_get,
+ akf_next_entry,
+ akf_end_seq_get,
+ akf_add_entry,
+ NULL /* remove */
+};
diff --git a/crypto/heimdal/lib/krb5/keytab_krb4.c b/crypto/heimdal/lib/krb5/keytab_krb4.c
new file mode 100644
index 0000000..b1f425c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_krb4.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#include <krb.h>
+
+RCSID("$Id: keytab_krb4.c,v 1.5 2000/01/06 08:04:58 assar Exp $");
+
+struct krb4_kt_data {
+ char *filename;
+};
+
+static krb5_error_code
+krb4_kt_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct krb4_kt_data *d;
+
+ d = malloc (sizeof(*d));
+ if (d == NULL)
+ return ENOMEM;
+ d->filename = strdup (name);
+ if (d->filename == NULL) {
+ free(d);
+ return ENOMEM;
+ }
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_get_name (krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t name_sz)
+{
+ struct krb4_kt_data *d = id->data;
+
+ strlcpy (name, d->filename, name_sz);
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_close (krb5_context context,
+ krb5_keytab id)
+{
+ struct krb4_kt_data *d = id->data;
+
+ free (d->filename);
+ free (d);
+ return 0;
+}
+
+struct krb4_cursor_extra_data {
+ krb5_keytab_entry entry;
+ int num;
+};
+
+static krb5_error_code
+krb4_kt_start_seq_get_int (krb5_context context,
+ krb5_keytab id,
+ int flags,
+ krb5_kt_cursor *c)
+{
+ struct krb4_kt_data *d = id->data;
+ struct krb4_cursor_extra_data *ed;
+
+ ed = malloc (sizeof(*ed));
+ if (ed == NULL)
+ return ENOMEM;
+ ed->entry.principal = NULL;
+ ed->num = -1;
+ c->data = ed;
+ c->fd = open (d->filename, flags);
+ if (c->fd < 0) {
+ free (ed);
+ return errno;
+ }
+ c->sp = krb5_storage_from_fd(c->fd);
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_start_seq_get (krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ return krb4_kt_start_seq_get_int (context, id, O_BINARY | O_RDONLY, c);
+}
+
+static krb5_error_code
+read_v4_entry (krb5_context context,
+ struct krb4_kt_data *d,
+ krb5_kt_cursor *c,
+ struct krb4_cursor_extra_data *ed)
+{
+ krb5_error_code ret;
+ char *service, *instance, *realm;
+ int8_t kvno;
+ des_cblock key;
+
+ ret = krb5_ret_stringz(c->sp, &service);
+ if (ret)
+ return ret;
+ ret = krb5_ret_stringz(c->sp, &instance);
+ if (ret) {
+ free (service);
+ return ret;
+ }
+ ret = krb5_ret_stringz(c->sp, &realm);
+ if (ret) {
+ free (service);
+ free (instance);
+ return ret;
+ }
+ ret = krb5_425_conv_principal (context, service, instance, realm,
+ &ed->entry.principal);
+ free (service);
+ free (instance);
+ free (realm);
+ if (ret)
+ return ret;
+ ret = krb5_ret_int8(c->sp, &kvno);
+ if (ret) {
+ krb5_free_principal (context, ed->entry.principal);
+ return ret;
+ }
+ ret = c->sp->fetch(c->sp, key, 8);
+ if (ret < 0) {
+ krb5_free_principal(context, ed->entry.principal);
+ return ret;
+ }
+ if (ret < 8) {
+ krb5_free_principal(context, ed->entry.principal);
+ return EINVAL;
+ }
+ ed->entry.vno = kvno;
+ ret = krb5_data_copy (&ed->entry.keyblock.keyvalue,
+ key, 8);
+ if (ret)
+ return ret;
+ ed->entry.timestamp = time(NULL);
+ ed->num = 0;
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_next_entry (krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *c)
+{
+ krb5_error_code ret;
+ struct krb4_kt_data *d = id->data;
+ struct krb4_cursor_extra_data *ed = c->data;
+ const krb5_enctype keytypes[] = {ETYPE_DES_CBC_MD5,
+ ETYPE_DES_CBC_MD4,
+ ETYPE_DES_CBC_CRC};
+
+ if (ed->num == -1) {
+ ret = read_v4_entry (context, d, c, ed);
+ if (ret)
+ return ret;
+ }
+ ret = krb5_kt_copy_entry_contents (context,
+ &ed->entry,
+ entry);
+ if (ret)
+ return ret;
+ entry->keyblock.keytype = keytypes[ed->num];
+ if (++ed->num == 3) {
+ krb5_kt_free_entry (context, &ed->entry);
+ ed->num = -1;
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_end_seq_get (krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ struct krb4_cursor_extra_data *ed = c->data;
+
+ krb5_storage_free (c->sp);
+ if (ed->num != -1)
+ krb5_kt_free_entry (context, &ed->entry);
+ free (c->data);
+ close (c->fd);
+ return 0;
+}
+
+static krb5_error_code
+krb4_kt_add_entry (krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct krb4_kt_data *d = id->data;
+ krb5_error_code ret;
+ int fd;
+ char service[ANAME_SZ];
+ char instance[INST_SZ];
+ char realm[REALM_SZ];
+ int8_t kvno;
+
+ fd = open (d->filename, O_WRONLY | O_APPEND | O_BINARY);
+ if (fd < 0) {
+ fd = open (d->filename,
+ O_WRONLY | O_APPEND | O_BINARY | O_CREAT, 0600);
+ if (fd < 0)
+ return errno;
+ }
+ ret = krb5_524_conv_principal (context, entry->principal,
+ service, instance, realm);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ if (entry->keyblock.keyvalue.length == 8
+ && entry->keyblock.keytype == ETYPE_DES_CBC_MD5) {
+ write(fd, service, strlen(service)+1);
+ write(fd, instance, strlen(instance)+1);
+ write(fd, realm, strlen(realm)+1);
+ kvno = entry->vno;
+ write(fd, &kvno, sizeof(kvno));
+ write(fd, entry->keyblock.keyvalue.data, 8);
+ }
+ close (fd);
+ return 0;
+}
+
+krb5_kt_ops krb4_fkt_ops = {
+ "krb4",
+ krb4_kt_resolve,
+ krb4_kt_get_name,
+ krb4_kt_close,
+ NULL, /* get */
+ krb4_kt_start_seq_get,
+ krb4_kt_next_entry,
+ krb4_kt_end_seq_get,
+ krb4_kt_add_entry, /* add_entry */
+ NULL /* remove_entry */
+};
diff --git a/crypto/heimdal/lib/krb5/keytab_memory.c b/crypto/heimdal/lib/krb5/keytab_memory.c
new file mode 100644
index 0000000..924b4cd
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/keytab_memory.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: keytab_memory.c,v 1.3 1999/12/02 17:05:10 joda Exp $");
+
+/* memory operations -------------------------------------------- */
+
+struct mkt_data {
+ krb5_keytab_entry *entries;
+ int num_entries;
+};
+
+static krb5_error_code
+mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct mkt_data *d;
+ d = malloc(sizeof(*d));
+ if(d == NULL)
+ return ENOMEM;
+ d->entries = NULL;
+ d->num_entries = 0;
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+mkt_close(krb5_context context, krb5_keytab id)
+{
+ struct mkt_data *d = id->data;
+ int i;
+ for(i = 0; i < d->num_entries; i++)
+ krb5_kt_free_entry(context, &d->entries[i]);
+ free(d->entries);
+ free(d);
+ return 0;
+}
+
+static krb5_error_code
+mkt_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t namesize)
+{
+ strncpy(name, "", namesize);
+ return 0;
+}
+
+static krb5_error_code
+mkt_start_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *c)
+{
+ /* XXX */
+ c->fd = 0;
+ return 0;
+}
+
+static krb5_error_code
+mkt_next_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *c)
+{
+ struct mkt_data *d = id->data;
+ if(c->fd >= d->num_entries)
+ return KRB5_KT_END;
+ return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry);
+}
+
+static krb5_error_code
+mkt_end_seq_get(krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor)
+{
+ return 0;
+}
+
+static krb5_error_code
+mkt_add_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct mkt_data *d = id->data;
+ krb5_keytab_entry *tmp;
+ tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries));
+ if(tmp == NULL)
+ return ENOMEM;
+ d->entries = tmp;
+ return krb5_kt_copy_entry_contents(context, entry,
+ &d->entries[d->num_entries++]);
+}
+
+static krb5_error_code
+mkt_remove_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
+{
+ struct mkt_data *d = id->data;
+ krb5_keytab_entry *e, *end;
+
+ /* do this backwards to minimize copying */
+ for(end = d->entries + d->num_entries, e = end - 1; e >= d->entries; e--) {
+ if(krb5_kt_compare(context, e, entry->principal,
+ entry->vno, entry->keyblock.keytype)) {
+ krb5_kt_free_entry(context, e);
+ memmove(e, e + 1, (end - e - 1) * sizeof(*e));
+ memset(end - 1, 0, sizeof(*end));
+ d->num_entries--;
+ end--;
+ }
+ }
+ e = realloc(d->entries, d->num_entries * sizeof(*d->entries));
+ if(e != NULL)
+ d->entries = e;
+ return 0;
+}
+
+const krb5_kt_ops krb5_mkt_ops = {
+ "MEMORY",
+ mkt_resolve,
+ mkt_get_name,
+ mkt_close,
+ NULL, /* get */
+ mkt_start_seq_get,
+ mkt_next_entry,
+ mkt_end_seq_get,
+ mkt_add_entry,
+ mkt_remove_entry
+};
diff --git a/crypto/heimdal/lib/krb5/krb5-private.h b/crypto/heimdal/lib/krb5/krb5-private.h
new file mode 100644
index 0000000..b24328a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5-private.h
@@ -0,0 +1,58 @@
+/* This is a generated file */
+#ifndef __krb5_private_h__
+#define __krb5_private_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+void
+_krb5_crc_init_table __P((void));
+
+u_int32_t
+_krb5_crc_update __P((
+ char *p,
+ size_t len,
+ u_int32_t res));
+
+int
+_krb5_extract_ticket __P((
+ krb5_context context,
+ krb5_kdc_rep *rep,
+ krb5_creds *creds,
+ krb5_keyblock *key,
+ krb5_const_pointer keyseed,
+ krb5_key_usage key_usage,
+ krb5_addresses *addrs,
+ unsigned nonce,
+ krb5_boolean allow_server_mismatch,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg));
+
+ssize_t
+_krb5_get_int __P((
+ void *buffer,
+ unsigned long *value,
+ size_t size));
+
+void
+_krb5_n_fold __P((
+ const void *str,
+ size_t len,
+ void *key,
+ size_t size));
+
+ssize_t
+_krb5_put_int __P((
+ void *buffer,
+ unsigned long value,
+ size_t size));
+
+#endif /* __krb5_private_h__ */
diff --git a/crypto/heimdal/lib/krb5/krb5-protos.h b/crypto/heimdal/lib/krb5/krb5-protos.h
new file mode 100644
index 0000000..8813c7a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5-protos.h
@@ -0,0 +1,2352 @@
+/* This is a generated file */
+#ifndef __krb5_protos_h__
+#define __krb5_protos_h__
+
+#ifdef __STDC__
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+krb5_error_code
+krb524_convert_creds_kdc __P((
+ krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_cred,
+ struct credentials *v4creds));
+
+krb5_error_code
+krb5_425_conv_principal __P((
+ krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_425_conv_principal_ext __P((
+ krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_boolean (*func)(krb5_context, krb5_principal),
+ krb5_boolean resolve,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_524_conv_principal __P((
+ krb5_context context,
+ const krb5_principal principal,
+ char *name,
+ char *instance,
+ char *realm));
+
+krb5_error_code
+krb5_abort __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 3, 4)));
+
+krb5_error_code
+krb5_abortx __P((
+ krb5_context context,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+
+krb5_error_code
+krb5_add_et_list __P((
+ krb5_context context,
+ void (*func)(struct et_list **)));
+
+krb5_error_code
+krb5_add_extra_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_addlog_dest __P((
+ krb5_context context,
+ krb5_log_facility *f,
+ const char *p));
+
+krb5_error_code
+krb5_addlog_func __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int min,
+ int max,
+ krb5_log_log_func_t log,
+ krb5_log_close_func_t close,
+ void *data));
+
+krb5_error_code
+krb5_addr2sockaddr __P((
+ const krb5_address *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port));
+
+krb5_boolean
+krb5_address_compare __P((
+ krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2));
+
+int
+krb5_address_order __P((
+ krb5_context context,
+ const krb5_address *addr1,
+ const krb5_address *addr2));
+
+krb5_boolean
+krb5_address_search __P((
+ krb5_context context,
+ const krb5_address *addr,
+ const krb5_addresses *addrlist));
+
+krb5_error_code
+krb5_aname_to_localname __P((
+ krb5_context context,
+ krb5_const_principal aname,
+ size_t lnsize,
+ char *lname));
+
+krb5_error_code
+krb5_anyaddr __P((
+ int af,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port));
+
+krb5_error_code
+krb5_append_addresses __P((
+ krb5_context context,
+ krb5_addresses *dest,
+ const krb5_addresses *source));
+
+krb5_error_code
+krb5_auth_con_free __P((
+ krb5_context context,
+ krb5_auth_context auth_context));
+
+krb5_error_code
+krb5_auth_con_getaddrs __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address **local_addr,
+ krb5_address **remote_addr));
+
+krb5_error_code
+krb5_auth_con_getflags __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *flags));
+
+krb5_error_code
+krb5_auth_con_getkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock));
+
+krb5_error_code
+krb5_auth_con_getlocalsubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock));
+
+krb5_error_code
+krb5_auth_con_getremotesubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock **keyblock));
+
+krb5_error_code
+krb5_auth_con_init __P((
+ krb5_context context,
+ krb5_auth_context *auth_context));
+
+krb5_error_code
+krb5_auth_con_setaddrs __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_address *local_addr,
+ krb5_address *remote_addr));
+
+krb5_error_code
+krb5_auth_con_setaddrs_from_fd __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ void *p_fd));
+
+krb5_error_code
+krb5_auth_con_setflags __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t flags));
+
+krb5_error_code
+krb5_auth_con_setkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_con_setlocalsubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_con_setremotesubkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_con_setuserkey __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_auth_getauthenticator __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authenticator *authenticator));
+
+krb5_error_code
+krb5_auth_getcksumtype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype *cksumtype));
+
+krb5_error_code
+krb5_auth_getkeytype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype *keytype));
+
+krb5_error_code
+krb5_auth_getlocalseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber));
+
+krb5_error_code
+krb5_auth_getremoteseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t *seqnumber));
+
+krb5_error_code
+krb5_auth_setcksumtype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_cksumtype cksumtype));
+
+krb5_error_code
+krb5_auth_setkeytype __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_keytype keytype));
+
+krb5_error_code
+krb5_auth_setlocalseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber));
+
+krb5_error_code
+krb5_auth_setremoteseqnumber __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ int32_t seqnumber));
+
+krb5_error_code
+krb5_build_ap_req __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ krb5_flags ap_options,
+ krb5_data authenticator,
+ krb5_data *retdata));
+
+krb5_error_code
+krb5_build_authenticator __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_enctype enctype,
+ krb5_creds *cred,
+ Checksum *cksum,
+ Authenticator **auth_result,
+ krb5_data *result));
+
+krb5_error_code
+krb5_build_principal __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...));
+
+krb5_error_code
+krb5_build_principal_ext __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...));
+
+krb5_error_code
+krb5_build_principal_va __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap));
+
+krb5_error_code
+krb5_build_principal_va_ext __P((
+ krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap));
+
+krb5_error_code
+krb5_cc_close __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_copy_cache __P((
+ krb5_context context,
+ const krb5_ccache from,
+ krb5_ccache to));
+
+krb5_error_code
+krb5_cc_default __P((
+ krb5_context context,
+ krb5_ccache *id));
+
+const char*
+krb5_cc_default_name __P((krb5_context context));
+
+krb5_error_code
+krb5_cc_destroy __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_end_seq_get __P((
+ krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor));
+
+krb5_error_code
+krb5_cc_gen_new __P((
+ krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_ccache *id));
+
+const char*
+krb5_cc_get_name __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_get_principal __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal));
+
+const char*
+krb5_cc_get_type __P((
+ krb5_context context,
+ krb5_ccache id));
+
+krb5_error_code
+krb5_cc_get_version __P((
+ krb5_context context,
+ const krb5_ccache id));
+
+krb5_error_code
+krb5_cc_initialize __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal));
+
+krb5_error_code
+krb5_cc_next_cred __P((
+ krb5_context context,
+ const krb5_ccache id,
+ krb5_creds *creds,
+ krb5_cc_cursor *cursor));
+
+krb5_error_code
+krb5_cc_register __P((
+ krb5_context context,
+ const krb5_cc_ops *ops,
+ krb5_boolean override));
+
+krb5_error_code
+krb5_cc_remove_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred));
+
+krb5_error_code
+krb5_cc_resolve __P((
+ krb5_context context,
+ const char *name,
+ krb5_ccache *id));
+
+krb5_error_code
+krb5_cc_retrieve_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_flags whichfields,
+ const krb5_creds *mcreds,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_cc_set_flags __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags));
+
+krb5_error_code
+krb5_cc_start_seq_get __P((
+ krb5_context context,
+ const krb5_ccache id,
+ krb5_cc_cursor *cursor));
+
+krb5_error_code
+krb5_cc_store_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_change_password __P((
+ krb5_context context,
+ krb5_creds *creds,
+ char *newpw,
+ int *result_code,
+ krb5_data *result_code_string,
+ krb5_data *result_string));
+
+krb5_boolean
+krb5_checksum_is_collision_proof __P((
+ krb5_context context,
+ krb5_cksumtype type));
+
+krb5_boolean
+krb5_checksum_is_keyed __P((
+ krb5_context context,
+ krb5_cksumtype type));
+
+krb5_error_code
+krb5_checksumsize __P((
+ krb5_context context,
+ krb5_cksumtype type,
+ size_t *size));
+
+krb5_error_code
+krb5_closelog __P((
+ krb5_context context,
+ krb5_log_facility *fac));
+
+krb5_boolean
+krb5_compare_creds __P((
+ krb5_context context,
+ krb5_flags whichfields,
+ const krb5_creds *mcreds,
+ const krb5_creds *creds));
+
+krb5_error_code
+krb5_config_file_free __P((
+ krb5_context context,
+ krb5_config_section *s));
+
+void
+krb5_config_free_strings __P((char **strings));
+
+const void *
+krb5_config_get __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int type,
+ ...));
+
+krb5_boolean
+krb5_config_get_bool __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+krb5_boolean
+krb5_config_get_bool_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ ...));
+
+int
+krb5_config_get_int __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+int
+krb5_config_get_int_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...));
+
+const krb5_config_binding *
+krb5_config_get_list __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+const void *
+krb5_config_get_next __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ ...));
+
+const char *
+krb5_config_get_string __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+char**
+krb5_config_get_strings __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+int
+krb5_config_get_time __P((
+ krb5_context context,
+ krb5_config_section *c,
+ ...));
+
+int
+krb5_config_get_time_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ ...));
+
+krb5_error_code
+krb5_config_parse_file __P((
+ const char *fname,
+ krb5_config_section **res));
+
+krb5_error_code
+krb5_config_parse_file_debug __P((
+ const char *fname,
+ krb5_config_section **res,
+ unsigned *lineno,
+ char **error_message));
+
+const void *
+krb5_config_vget __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int type,
+ va_list args));
+
+krb5_boolean
+krb5_config_vget_bool __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+krb5_boolean
+krb5_config_vget_bool_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_boolean def_value,
+ va_list args));
+
+int
+krb5_config_vget_int __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+int
+krb5_config_vget_int_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args));
+
+const krb5_config_binding *
+krb5_config_vget_list __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+const void *
+krb5_config_vget_next __P((
+ krb5_context context,
+ krb5_config_section *c,
+ krb5_config_binding **pointer,
+ int type,
+ va_list args));
+
+const char *
+krb5_config_vget_string __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+char **
+krb5_config_vget_strings __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+int
+krb5_config_vget_time __P((
+ krb5_context context,
+ krb5_config_section *c,
+ va_list args));
+
+int
+krb5_config_vget_time_default __P((
+ krb5_context context,
+ krb5_config_section *c,
+ int def_value,
+ va_list args));
+
+krb5_error_code
+krb5_copy_address __P((
+ krb5_context context,
+ const krb5_address *inaddr,
+ krb5_address *outaddr));
+
+krb5_error_code
+krb5_copy_addresses __P((
+ krb5_context context,
+ const krb5_addresses *inaddr,
+ krb5_addresses *outaddr));
+
+krb5_error_code
+krb5_copy_creds __P((
+ krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds **outcred));
+
+krb5_error_code
+krb5_copy_creds_contents __P((
+ krb5_context context,
+ const krb5_creds *incred,
+ krb5_creds *c));
+
+krb5_error_code
+krb5_copy_data __P((
+ krb5_context context,
+ const krb5_data *indata,
+ krb5_data **outdata));
+
+krb5_error_code
+krb5_copy_host_realm __P((
+ krb5_context context,
+ const krb5_realm *from,
+ krb5_realm **to));
+
+krb5_error_code
+krb5_copy_keyblock __P((
+ krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock **to));
+
+krb5_error_code
+krb5_copy_keyblock_contents __P((
+ krb5_context context,
+ const krb5_keyblock *inblock,
+ krb5_keyblock *to));
+
+krb5_error_code
+krb5_copy_principal __P((
+ krb5_context context,
+ krb5_const_principal inprinc,
+ krb5_principal *outprinc));
+
+krb5_error_code
+krb5_copy_ticket __P((
+ krb5_context context,
+ const krb5_ticket *from,
+ krb5_ticket **to));
+
+krb5_error_code
+krb5_create_checksum __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage_or_type,
+ void *data,
+ size_t len,
+ Checksum *result));
+
+krb5_error_code
+krb5_crypto_destroy __P((
+ krb5_context context,
+ krb5_crypto crypto));
+
+krb5_error_code
+krb5_crypto_init __P((
+ krb5_context context,
+ krb5_keyblock *key,
+ krb5_enctype etype,
+ krb5_crypto *crypto));
+
+krb5_error_code
+krb5_data_alloc __P((
+ krb5_data *p,
+ int len));
+
+krb5_error_code
+krb5_data_copy __P((
+ krb5_data *p,
+ const void *data,
+ size_t len));
+
+void
+krb5_data_free __P((krb5_data *p));
+
+krb5_error_code
+krb5_data_realloc __P((
+ krb5_data *p,
+ int len));
+
+void
+krb5_data_zero __P((krb5_data *p));
+
+krb5_error_code
+krb5_decode_Authenticator __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_ETYPE_INFO __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncAPRepPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncASRepPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncKrbCredPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncTGSRepPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_EncTicketPart __P((
+ krb5_context context,
+ const void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_decode_ap_req __P((
+ krb5_context context,
+ const krb5_data *inbuf,
+ krb5_ap_req *ap_req));
+
+krb5_error_code
+krb5_decrypt __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result));
+
+krb5_error_code
+krb5_decrypt_EncryptedData __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ EncryptedData *e,
+ krb5_data *result));
+
+krb5_error_code
+krb5_decrypt_ticket __P((
+ krb5_context context,
+ Ticket *ticket,
+ krb5_keyblock *key,
+ EncTicketPart *out,
+ krb5_flags flags));
+
+krb5_error_code
+krb5_domain_x500_decode __P((
+ krb5_data tr,
+ char ***realms,
+ int *num_realms,
+ const char *client_realm,
+ const char *server_realm));
+
+krb5_error_code
+krb5_domain_x500_encode __P((
+ char **realms,
+ int num_realms,
+ krb5_data *encoding));
+
+krb5_error_code
+krb5_encode_Authenticator __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ Authenticator *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_ETYPE_INFO __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ ETYPE_INFO *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncAPRepPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncAPRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncASRepPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncASRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncKrbCredPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncKrbCredPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncTGSRepPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncTGSRepPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encode_EncTicketPart __P((
+ krb5_context context,
+ void *data,
+ size_t length,
+ EncTicketPart *t,
+ size_t *len));
+
+krb5_error_code
+krb5_encrypt __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ krb5_data *result));
+
+krb5_error_code
+krb5_encrypt_EncryptedData __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ void *data,
+ size_t len,
+ int kvno,
+ EncryptedData *result));
+
+krb5_error_code
+krb5_enctype_to_keytype __P((
+ krb5_context context,
+ krb5_enctype etype,
+ krb5_keytype *keytype));
+
+krb5_error_code
+krb5_enctype_to_string __P((
+ krb5_context context,
+ krb5_enctype etype,
+ char **string));
+
+krb5_error_code
+krb5_enctype_valid __P((
+ krb5_context context,
+ krb5_enctype etype));
+
+krb5_boolean
+krb5_enctypes_compatible_keys __P((
+ krb5_context context,
+ krb5_enctype etype1,
+ krb5_enctype etype2));
+
+krb5_error_code
+krb5_err __P((
+ krb5_context context,
+ int eval,
+ krb5_error_code code,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 4, 5)));
+
+krb5_error_code
+krb5_errx __P((
+ krb5_context context,
+ int eval,
+ const char *fmt,
+ ...))
+ __attribute__ ((noreturn, format (printf, 3, 4)));
+
+krb5_error_code
+krb5_expand_hostname __P((
+ krb5_context context,
+ const char *orig_hostname,
+ char **new_hostname));
+
+PA_DATA *
+krb5_find_padata __P((
+ PA_DATA *val,
+ unsigned len,
+ int type,
+ int *index));
+
+krb5_error_code
+krb5_free_address __P((
+ krb5_context context,
+ krb5_address *address));
+
+krb5_error_code
+krb5_free_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+void
+krb5_free_ap_rep_enc_part __P((
+ krb5_context context,
+ krb5_ap_rep_enc_part *val));
+
+void
+krb5_free_authenticator __P((
+ krb5_context context,
+ krb5_authenticator *authenticator));
+
+void
+krb5_free_context __P((krb5_context context));
+
+krb5_error_code
+krb5_free_cred_contents __P((
+ krb5_context context,
+ krb5_creds *c));
+
+krb5_error_code
+krb5_free_creds __P((
+ krb5_context context,
+ krb5_creds *c));
+
+krb5_error_code
+krb5_free_creds_contents __P((
+ krb5_context context,
+ krb5_creds *c));
+
+void
+krb5_free_data __P((
+ krb5_context context,
+ krb5_data *p));
+
+void
+krb5_free_error __P((
+ krb5_context context,
+ krb5_error *error));
+
+void
+krb5_free_error_contents __P((
+ krb5_context context,
+ krb5_error *error));
+
+krb5_error_code
+krb5_free_host_realm __P((
+ krb5_context context,
+ krb5_realm *realmlist));
+
+krb5_error_code
+krb5_free_kdc_rep __P((
+ krb5_context context,
+ krb5_kdc_rep *rep));
+
+void
+krb5_free_keyblock __P((
+ krb5_context context,
+ krb5_keyblock *keyblock));
+
+void
+krb5_free_keyblock_contents __P((
+ krb5_context context,
+ krb5_keyblock *keyblock));
+
+krb5_error_code
+krb5_free_krbhst __P((
+ krb5_context context,
+ char **hostlist));
+
+void
+krb5_free_principal __P((
+ krb5_context context,
+ krb5_principal p));
+
+krb5_error_code
+krb5_free_salt __P((
+ krb5_context context,
+ krb5_salt salt));
+
+krb5_error_code
+krb5_free_ticket __P((
+ krb5_context context,
+ krb5_ticket *ticket));
+
+krb5_error_code
+krb5_fwd_tgt_creds __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const char *hostname,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_ccache ccache,
+ int forwardable,
+ krb5_data *out_data));
+
+void
+krb5_generate_random_block __P((
+ void *buf,
+ size_t len));
+
+krb5_error_code
+krb5_generate_random_keyblock __P((
+ krb5_context context,
+ krb5_enctype type,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_generate_seq_number __P((
+ krb5_context context,
+ const krb5_keyblock *key,
+ int32_t *seqno));
+
+krb5_error_code
+krb5_generate_subkey __P((
+ krb5_context context,
+ const krb5_keyblock *key,
+ krb5_keyblock **subkey));
+
+krb5_error_code
+krb5_get_all_client_addrs __P((
+ krb5_context context,
+ krb5_addresses *res));
+
+krb5_error_code
+krb5_get_all_server_addrs __P((
+ krb5_context context,
+ krb5_addresses *res));
+
+krb5_error_code
+krb5_get_cred_from_kdc __P((
+ krb5_context context,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds,
+ krb5_creds ***ret_tgts));
+
+krb5_error_code
+krb5_get_credentials __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds));
+
+krb5_error_code
+krb5_get_credentials_with_flags __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_kdc_flags flags,
+ krb5_ccache ccache,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds));
+
+krb5_error_code
+krb5_get_default_in_tkt_etypes __P((
+ krb5_context context,
+ krb5_enctype **etypes));
+
+krb5_error_code
+krb5_get_default_principal __P((
+ krb5_context context,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_get_default_realm __P((
+ krb5_context context,
+ krb5_realm *realm));
+
+krb5_error_code
+krb5_get_default_realms __P((
+ krb5_context context,
+ krb5_realm **realms));
+
+const char *
+krb5_get_err_text __P((
+ krb5_context context,
+ krb5_error_code code));
+
+krb5_error_code
+krb5_get_extra_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_get_fcache_version __P((
+ krb5_context context,
+ int *version));
+
+krb5_error_code
+krb5_get_forwarded_creds __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_flags flags,
+ const char *hostname,
+ krb5_creds *in_creds,
+ krb5_data *out_data));
+
+krb5_error_code
+krb5_get_host_realm __P((
+ krb5_context context,
+ const char *host,
+ krb5_realm **realms));
+
+krb5_error_code
+krb5_get_host_realm_int __P((
+ krb5_context context,
+ const char *host,
+ krb5_realm **realms));
+
+krb5_error_code
+krb5_get_in_cred __P((
+ krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ const krb5_preauthdata *preauth,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt __P((
+ krb5_context context,
+ krb5_flags options,
+ const krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *ptypes,
+ krb5_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ krb5_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds *creds,
+ krb5_ccache ccache,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt_with_keytab __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ krb5_keytab keytab,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt_with_password __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const char *password,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_in_tkt_with_skey __P((
+ krb5_context context,
+ krb5_flags options,
+ krb5_addresses *addrs,
+ const krb5_enctype *etypes,
+ const krb5_preauthtype *pre_auth_types,
+ const krb5_keyblock *key,
+ krb5_ccache ccache,
+ krb5_creds *creds,
+ krb5_kdc_rep *ret_as_reply));
+
+krb5_error_code
+krb5_get_init_creds_keytab __P((
+ krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_keytab keytab,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options));
+
+void
+krb5_get_init_creds_opt_init __P((krb5_get_init_creds_opt *opt));
+
+void
+krb5_get_init_creds_opt_set_address_list __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_addresses *addresses));
+
+void
+krb5_get_init_creds_opt_set_etype_list __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_enctype *etype_list,
+ int etype_list_length));
+
+void
+krb5_get_init_creds_opt_set_forwardable __P((
+ krb5_get_init_creds_opt *opt,
+ int forwardable));
+
+void
+krb5_get_init_creds_opt_set_preauth_list __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_preauthtype *preauth_list,
+ int preauth_list_length));
+
+void
+krb5_get_init_creds_opt_set_proxiable __P((
+ krb5_get_init_creds_opt *opt,
+ int proxiable));
+
+void
+krb5_get_init_creds_opt_set_renew_life __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_deltat renew_life));
+
+void
+krb5_get_init_creds_opt_set_salt __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_data *salt));
+
+void
+krb5_get_init_creds_opt_set_tkt_life __P((
+ krb5_get_init_creds_opt *opt,
+ krb5_deltat tkt_life));
+
+krb5_error_code
+krb5_get_init_creds_password __P((
+ krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ const char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ const char *in_tkt_service,
+ krb5_get_init_creds_opt *options));
+
+krb5_error_code
+krb5_get_kdc_cred __P((
+ krb5_context context,
+ krb5_ccache id,
+ krb5_kdc_flags flags,
+ krb5_addresses *addresses,
+ Ticket *second_ticket,
+ krb5_creds *in_creds,
+ krb5_creds **out_creds ));
+
+krb5_error_code
+krb5_get_krb_admin_hst __P((
+ krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist));
+
+krb5_error_code
+krb5_get_krb_changepw_hst __P((
+ krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist));
+
+krb5_error_code
+krb5_get_krbhst __P((
+ krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist));
+
+krb5_error_code
+krb5_get_pw_salt __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ krb5_salt *salt));
+
+krb5_boolean
+krb5_get_use_admin_kdc __P((krb5_context context));
+
+size_t
+krb5_get_wrapped_length __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ size_t data_len));
+
+int
+krb5_getportbyname __P((
+ krb5_context context,
+ const char *service,
+ const char *proto,
+ int default_port));
+
+krb5_error_code
+krb5_h_addr2addr __P((
+ int af,
+ const char *haddr,
+ krb5_address *addr));
+
+krb5_error_code
+krb5_h_addr2sockaddr __P((
+ int af,
+ const char *addr,
+ struct sockaddr *sa,
+ int *sa_size,
+ int port));
+
+krb5_error_code
+krb5_init_context __P((krb5_context *context));
+
+void
+krb5_init_ets __P((krb5_context context));
+
+krb5_error_code
+krb5_init_etype __P((
+ krb5_context context,
+ unsigned *len,
+ int **val,
+ const krb5_enctype *etypes));
+
+krb5_error_code
+krb5_initlog __P((
+ krb5_context context,
+ const char *program,
+ krb5_log_facility **fac));
+
+krb5_error_code
+krb5_keyblock_key_proc __P((
+ krb5_context context,
+ krb5_keytype type,
+ krb5_data *salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key));
+
+krb5_error_code
+krb5_keytab_key_proc __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key));
+
+krb5_error_code
+krb5_keytype_to_enctypes __P((
+ krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val));
+
+krb5_error_code
+krb5_keytype_to_enctypes_default __P((
+ krb5_context context,
+ krb5_keytype keytype,
+ unsigned *len,
+ int **val));
+
+krb5_error_code
+krb5_keytype_to_string __P((
+ krb5_context context,
+ krb5_keytype keytype,
+ char **string));
+
+krb5_error_code
+krb5_kt_add_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_close __P((
+ krb5_context context,
+ krb5_keytab id));
+
+krb5_boolean
+krb5_kt_compare __P((
+ krb5_context context,
+ krb5_keytab_entry *entry,
+ krb5_const_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype));
+
+krb5_error_code
+krb5_kt_copy_entry_contents __P((
+ krb5_context context,
+ const krb5_keytab_entry *in,
+ krb5_keytab_entry *out));
+
+krb5_error_code
+krb5_kt_default __P((
+ krb5_context context,
+ krb5_keytab *id));
+
+krb5_error_code
+krb5_kt_default_name __P((
+ krb5_context context,
+ char *name,
+ size_t namesize));
+
+krb5_error_code
+krb5_kt_end_seq_get __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor));
+
+krb5_error_code
+krb5_kt_free_entry __P((
+ krb5_context context,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_get_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_get_name __P((
+ krb5_context context,
+ krb5_keytab keytab,
+ char *name,
+ size_t namesize));
+
+krb5_error_code
+krb5_kt_next_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor));
+
+krb5_error_code
+krb5_kt_read_service_key __P((
+ krb5_context context,
+ krb5_pointer keyprocarg,
+ krb5_principal principal,
+ krb5_kvno vno,
+ krb5_enctype enctype,
+ krb5_keyblock **key));
+
+krb5_error_code
+krb5_kt_register __P((
+ krb5_context context,
+ const krb5_kt_ops *ops));
+
+krb5_error_code
+krb5_kt_remove_entry __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry));
+
+krb5_error_code
+krb5_kt_resolve __P((
+ krb5_context context,
+ const char *name,
+ krb5_keytab *id));
+
+krb5_error_code
+krb5_kt_start_seq_get __P((
+ krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor));
+
+krb5_boolean
+krb5_kuserok __P((
+ krb5_context context,
+ krb5_principal principal,
+ const char *luser));
+
+krb5_error_code
+krb5_log __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ ...))
+ __attribute__((format (printf, 4, 5)));
+
+krb5_error_code
+krb5_log_msg __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ char **reply,
+ const char *fmt,
+ ...))
+ __attribute__((format (printf, 5, 6)));
+
+krb5_error_code
+krb5_make_addrport __P((
+ krb5_address **res,
+ const krb5_address *addr,
+ int16_t port));
+
+krb5_error_code
+krb5_make_principal __P((
+ krb5_context context,
+ krb5_principal *principal,
+ krb5_const_realm realm,
+ ...));
+
+size_t
+krb5_max_sockaddr_size __P((void));
+
+krb5_error_code
+krb5_mk_error __P((
+ krb5_context context,
+ krb5_error_code error_code,
+ const char *e_text,
+ const krb5_data *e_data,
+ const krb5_principal client,
+ const krb5_principal server,
+ time_t ctime,
+ krb5_data *reply));
+
+krb5_error_code
+krb5_mk_priv __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ void *outdata));
+
+krb5_error_code
+krb5_mk_rep __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_data *outbuf));
+
+krb5_error_code
+krb5_mk_req __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ char *service,
+ char *hostname,
+ krb5_data *in_data,
+ krb5_ccache ccache,
+ krb5_data *outbuf));
+
+krb5_error_code
+krb5_mk_req_extended __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf));
+
+krb5_error_code
+krb5_mk_req_internal __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf,
+ krb5_key_usage usage));
+
+krb5_error_code
+krb5_mk_safe __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ void *outdata));
+
+ssize_t
+krb5_net_read __P((
+ krb5_context context,
+ void *p_fd,
+ void *buf,
+ size_t len));
+
+ssize_t
+krb5_net_write __P((
+ krb5_context context,
+ void *p_fd,
+ const void *buf,
+ size_t len));
+
+krb5_error_code
+krb5_openlog __P((
+ krb5_context context,
+ const char *program,
+ krb5_log_facility **fac));
+
+krb5_error_code
+krb5_parse_address __P((
+ krb5_context context,
+ const char *string,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_parse_name __P((
+ krb5_context context,
+ const char *name,
+ krb5_principal *principal));
+
+krb5_error_code
+krb5_password_key_proc __P((
+ krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key));
+
+krb5_realm*
+krb5_princ_realm __P((
+ krb5_context context,
+ krb5_principal principal));
+
+void
+krb5_princ_set_realm __P((
+ krb5_context context,
+ krb5_principal principal,
+ krb5_realm *realm));
+
+krb5_error_code
+krb5_principal2principalname __P((
+ PrincipalName *p,
+ const krb5_principal from));
+
+krb5_boolean
+krb5_principal_compare __P((
+ krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2));
+
+krb5_boolean
+krb5_principal_compare_any_realm __P((
+ krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2));
+
+krb5_error_code
+krb5_print_address __P((
+ const krb5_address *addr,
+ char *str,
+ size_t len,
+ size_t *ret_len));
+
+int
+krb5_program_setup __P((
+ krb5_context *context,
+ int argc,
+ char **argv,
+ struct getargs *args,
+ int num_args,
+ void (*usage)(int, struct getargs*, int)));
+
+int
+krb5_prompter_posix __P((
+ krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]));
+
+krb5_error_code
+krb5_rd_cred __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_data *in_data));
+
+krb5_error_code
+krb5_rd_error __P((
+ krb5_context context,
+ krb5_data *msg,
+ KRB_ERROR *result));
+
+krb5_error_code
+krb5_rd_priv __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ void *outdata));
+
+krb5_error_code
+krb5_rd_rep __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_ap_rep_enc_part **repl));
+
+krb5_error_code
+krb5_rd_req __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_rd_req_with_keyblock __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_rd_safe __P((
+ krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ void *outdata));
+
+krb5_error_code
+krb5_read_message __P((
+ krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data));
+
+krb5_boolean
+krb5_realm_compare __P((
+ krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2));
+
+krb5_error_code
+krb5_recvauth __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ char *appl_version,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_recvauth_match_version __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ krb5_boolean (*match_appl_version)(void *, const char*),
+ void *match_data,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_ret_address __P((
+ krb5_storage *sp,
+ krb5_address *adr));
+
+krb5_error_code
+krb5_ret_addrs __P((
+ krb5_storage *sp,
+ krb5_addresses *adr));
+
+krb5_error_code
+krb5_ret_authdata __P((
+ krb5_storage *sp,
+ krb5_authdata *auth));
+
+krb5_error_code
+krb5_ret_creds __P((
+ krb5_storage *sp,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_ret_data __P((
+ krb5_storage *sp,
+ krb5_data *data));
+
+krb5_error_code
+krb5_ret_int16 __P((
+ krb5_storage *sp,
+ int16_t *value));
+
+krb5_error_code
+krb5_ret_int32 __P((
+ krb5_storage *sp,
+ int32_t *value));
+
+krb5_error_code
+krb5_ret_int8 __P((
+ krb5_storage *sp,
+ int8_t *value));
+
+krb5_error_code
+krb5_ret_keyblock __P((
+ krb5_storage *sp,
+ krb5_keyblock *p));
+
+krb5_error_code
+krb5_ret_principal __P((
+ krb5_storage *sp,
+ krb5_principal *princ));
+
+krb5_error_code
+krb5_ret_string __P((
+ krb5_storage *sp,
+ char **string));
+
+krb5_error_code
+krb5_ret_stringz __P((
+ krb5_storage *sp,
+ char **string));
+
+krb5_error_code
+krb5_ret_times __P((
+ krb5_storage *sp,
+ krb5_times *times));
+
+krb5_error_code
+krb5_salttype_to_string __P((
+ krb5_context context,
+ krb5_enctype etype,
+ krb5_salttype stype,
+ char **string));
+
+krb5_error_code
+krb5_sendauth __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ const char *appl_version,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_ccache ccache,
+ krb5_error **ret_error,
+ krb5_ap_rep_enc_part **rep_result,
+ krb5_creds **out_creds));
+
+krb5_error_code
+krb5_sendto_kdc __P((
+ krb5_context context,
+ const krb5_data *send,
+ const krb5_realm *realm,
+ krb5_data *receive));
+
+krb5_error_code
+krb5_set_default_in_tkt_etypes __P((
+ krb5_context context,
+ const krb5_enctype *etypes));
+
+krb5_error_code
+krb5_set_default_realm __P((
+ krb5_context context,
+ char *realm));
+
+krb5_error_code
+krb5_set_extra_addresses __P((
+ krb5_context context,
+ krb5_addresses *addresses));
+
+krb5_error_code
+krb5_set_fcache_version __P((
+ krb5_context context,
+ int version));
+
+void
+krb5_set_use_admin_kdc __P((
+ krb5_context context,
+ krb5_boolean flag));
+
+krb5_error_code
+krb5_set_warn_dest __P((
+ krb5_context context,
+ krb5_log_facility *fac));
+
+krb5_error_code
+krb5_sname_to_principal __P((
+ krb5_context context,
+ const char *hostname,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ));
+
+krb5_error_code
+krb5_sock_to_principal __P((
+ krb5_context context,
+ int sock,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ));
+
+krb5_error_code
+krb5_sockaddr2address __P((
+ const struct sockaddr *sa,
+ krb5_address *addr));
+
+krb5_error_code
+krb5_sockaddr2port __P((
+ const struct sockaddr *sa,
+ int16_t *port));
+
+krb5_boolean
+krb5_sockaddr_uninteresting __P((const struct sockaddr *sa));
+
+void
+krb5_std_usage __P((
+ int code,
+ struct getargs *args,
+ int num_args));
+
+void
+krb5_storage_clear_flags __P((
+ krb5_storage *sp,
+ krb5_flags flags));
+
+krb5_storage *
+krb5_storage_emem __P((void));
+
+krb5_error_code
+krb5_storage_free __P((krb5_storage *sp));
+
+krb5_storage *
+krb5_storage_from_data __P((krb5_data *data));
+
+krb5_storage *
+krb5_storage_from_fd __P((int fd));
+
+krb5_storage *
+krb5_storage_from_mem __P((
+ void *buf,
+ size_t len));
+
+krb5_boolean
+krb5_storage_is_flags __P((
+ krb5_storage *sp,
+ krb5_flags flags));
+
+void
+krb5_storage_set_flags __P((
+ krb5_storage *sp,
+ krb5_flags flags));
+
+krb5_error_code
+krb5_storage_to_data __P((
+ krb5_storage *sp,
+ krb5_data *data));
+
+krb5_error_code
+krb5_store_address __P((
+ krb5_storage *sp,
+ krb5_address p));
+
+krb5_error_code
+krb5_store_addrs __P((
+ krb5_storage *sp,
+ krb5_addresses p));
+
+krb5_error_code
+krb5_store_authdata __P((
+ krb5_storage *sp,
+ krb5_authdata auth));
+
+krb5_error_code
+krb5_store_creds __P((
+ krb5_storage *sp,
+ krb5_creds *creds));
+
+krb5_error_code
+krb5_store_data __P((
+ krb5_storage *sp,
+ krb5_data data));
+
+krb5_error_code
+krb5_store_int16 __P((
+ krb5_storage *sp,
+ int16_t value));
+
+krb5_error_code
+krb5_store_int32 __P((
+ krb5_storage *sp,
+ int32_t value));
+
+krb5_error_code
+krb5_store_int8 __P((
+ krb5_storage *sp,
+ int8_t value));
+
+krb5_error_code
+krb5_store_keyblock __P((
+ krb5_storage *sp,
+ krb5_keyblock p));
+
+krb5_error_code
+krb5_store_principal __P((
+ krb5_storage *sp,
+ krb5_principal p));
+
+krb5_error_code
+krb5_store_string __P((
+ krb5_storage *sp,
+ const char *s));
+
+krb5_error_code
+krb5_store_stringz __P((
+ krb5_storage *sp,
+ char *s));
+
+krb5_error_code
+krb5_store_times __P((
+ krb5_storage *sp,
+ krb5_times times));
+
+krb5_error_code
+krb5_string_to_enctype __P((
+ krb5_context context,
+ const char *string,
+ krb5_enctype *etype));
+
+krb5_error_code
+krb5_string_to_key __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_principal principal,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_data __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_principal principal,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_data_salt __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_derived __P((
+ krb5_context context,
+ const void *str,
+ size_t len,
+ krb5_enctype etype,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_key_salt __P((
+ krb5_context context,
+ krb5_enctype enctype,
+ const char *password,
+ krb5_salt salt,
+ krb5_keyblock *key));
+
+krb5_error_code
+krb5_string_to_keytype __P((
+ krb5_context context,
+ const char *string,
+ krb5_keytype *keytype));
+
+krb5_error_code
+krb5_string_to_salttype __P((
+ krb5_context context,
+ krb5_enctype etype,
+ const char *string,
+ krb5_salttype *salttype));
+
+krb5_error_code
+krb5_timeofday __P((
+ krb5_context context,
+ int32_t *timeret));
+
+krb5_error_code
+krb5_unparse_name __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char **name));
+
+krb5_error_code
+krb5_unparse_name_fixed __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len));
+
+krb5_error_code
+krb5_unparse_name_fixed_short __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len));
+
+krb5_error_code
+krb5_unparse_name_short __P((
+ krb5_context context,
+ krb5_const_principal principal,
+ char **name));
+
+krb5_error_code
+krb5_us_timeofday __P((
+ krb5_context context,
+ int32_t *sec,
+ int32_t *usec));
+
+krb5_error_code
+krb5_vabort __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 3, 0)));
+
+krb5_error_code
+krb5_vabortx __P((
+ krb5_context context,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 2, 0)));
+
+krb5_error_code
+krb5_verify_ap_req __P((
+ krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_ap_req *ap_req,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags flags,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket));
+
+krb5_error_code
+krb5_verify_authenticator_checksum __P((
+ krb5_context context,
+ krb5_auth_context ac,
+ void *data,
+ size_t len));
+
+krb5_error_code
+krb5_verify_checksum __P((
+ krb5_context context,
+ krb5_crypto crypto,
+ krb5_key_usage usage,
+ void *data,
+ size_t len,
+ Checksum *cksum));
+
+krb5_error_code
+krb5_verify_init_creds __P((
+ krb5_context context,
+ krb5_creds *creds,
+ krb5_principal ap_req_server,
+ krb5_keytab ap_req_keytab,
+ krb5_ccache *ccache,
+ krb5_verify_init_creds_opt *options));
+
+void
+krb5_verify_init_creds_opt_init __P((krb5_verify_init_creds_opt *options));
+
+void
+krb5_verify_init_creds_opt_set_ap_req_nofail __P((
+ krb5_verify_init_creds_opt *options,
+ int ap_req_nofail));
+
+krb5_error_code
+krb5_verify_user __P((
+ krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service));
+
+krb5_error_code
+krb5_verify_user_lrealm __P((
+ krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service));
+
+krb5_error_code
+krb5_verr __P((
+ krb5_context context,
+ int eval,
+ krb5_error_code code,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 4, 0)));
+
+krb5_error_code
+krb5_verrx __P((
+ krb5_context context,
+ int eval,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((noreturn, format (printf, 3, 0)));
+
+krb5_error_code
+krb5_vlog __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ va_list ap))
+ __attribute__((format (printf, 4, 0)));
+
+krb5_error_code
+krb5_vlog_msg __P((
+ krb5_context context,
+ krb5_log_facility *fac,
+ char **reply,
+ int level,
+ const char *fmt,
+ va_list ap))
+ __attribute__((format (printf, 5, 0)));
+
+krb5_error_code
+krb5_vwarn __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((format (printf, 3, 0)));
+
+krb5_error_code
+krb5_vwarnx __P((
+ krb5_context context,
+ const char *fmt,
+ va_list ap))
+ __attribute__ ((format (printf, 2, 0)));
+
+krb5_error_code
+krb5_warn __P((
+ krb5_context context,
+ krb5_error_code code,
+ const char *fmt,
+ ...))
+ __attribute__ ((format (printf, 3, 4)));
+
+krb5_error_code
+krb5_warnx __P((
+ krb5_context context,
+ const char *fmt,
+ ...))
+ __attribute__ ((format (printf, 2, 3)));
+
+krb5_error_code
+krb5_write_message __P((
+ krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data));
+
+krb5_error_code
+krb5_xfree __P((void *ptr));
+
+krb5_error_code
+principalname2krb5_principal __P((
+ krb5_principal *principal,
+ const PrincipalName from,
+ const Realm realm));
+
+#endif /* __krb5_protos_h__ */
diff --git a/crypto/heimdal/lib/krb5/krb5.conf.5 b/crypto/heimdal/lib/krb5/krb5.conf.5
new file mode 100644
index 0000000..2a0adb6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5.conf.5
@@ -0,0 +1,167 @@
+.\" $Id: krb5.conf.5,v 1.7 1999/11/04 01:57:28 assar Exp $
+.\"
+.Dd April 11, 1999
+.Dt KRB5.CONF 5
+.Os HEIMDAL
+.Sh NAME
+.Nm /etc/krb5.conf
+.Nd
+Configuration file for Kerberos 5
+.Sh DESCRIPTION
+The
+.Nm
+file specifies several configuration parameters for the Kerberos 5
+library, as well as for some programs.
+.Pp
+The file consists of one or more sections, containing a number of
+bindings. The value of each binding can be either a string or a list
+of other bindings. The grammar looks like:
+.Bd -literal -offset indent
+file:
+ /* empty */
+ sections
+
+sections:
+ section sections
+ section
+
+section:
+ '[' section_name ']' bindings
+
+section_name:
+ STRING
+
+bindings:
+ binding bindings
+ binding
+
+binding:
+ name '=' STRING
+ name '=' '{' bindings '}'
+
+name:
+ STRING
+
+.Ed
+.Li STRINGs
+consists of one or more non-white space characters.
+Currently recognised sections and bindings are:
+
+.Bl -tag -width "xxx" -offset indent
+.It Li [libdefaults]
+.Bl -tag -width "xxx" -offset indent
+.It Li default_realm = Va REALM
+Default realm to use, this is also known as your
+.Dq local realm .
+The default is the result of
+.Fn krb5_get_host_realm "local hostname" .
+.It Li clockskew = Va time
+Maximum time differential (in seconds) allowed when comparing
+times. Default is 300 seconds (five minutes).
+.It Li kdc_timeout = Va time
+Maximum time to wait for a reply from the kdc, default is 3 seconds.
+.It v4_name_convert
+.It v4_instance_resolve
+These are decribed in the
+.Xr krb5_425_conv_principal 3
+manual page.
+.It Li capath = Va realm-routing-table
+.It Li default_etypes = Va etypes...
+A list of default etypes to use.
+.It Li default_etypes_des = Va etypes...
+A list of default etypes to use when requesting a DES credential.
+.It Li default_keytab_name = Va keytab
+The keytab to use if none other is specified, default is
+.Dq FILE:/etc/krb5.keytab .
+.It Li kdc_timesync = Va boolean
+Try to keep track of the time differential between the local machine
+and the KDC, and then compensate for that when issuing requests.
+.It Li max_retries = Va number
+The max number of times to try to contact each KDC.
+.It Li ticket_lifetime = Va time
+Default ticket lifetime.
+.It Li renew_lifetime = Va time
+Default renewable ticket lifetime.
+.It Li verify_ap_req_nofail = Va boolean
+Enable to make a failure to verify obtained credentials
+non-fatal. This can be useful if there is no keytab on a host.
+.It Li warn_pwexpire = Va time
+How soon to warn for expiring password. Default is seven days.
+.It Li http_proxy = Va proxy-spec
+A HTTP-proxy to use when talking to the KDC via HTTP.
+.It Li dns_proxy = Va proxy-spec
+Enable using DNS via HTTP.
+.It Li extra_addresses = Va address...
+A list of addresses to get tickets for along with all local addresses.
+.It Li time_format = Va string
+How to print time strings in logs, this string is passed to
+.Xr strftime 3 .
+.It Li log_utc = Va boolean
+Write log-entries using UTC instead of your local time zone.
+.El
+.It Li [domain_realm]
+This is a list of mappings from DNS domain to Kerberos realm. Each
+binding in this section looks like:
+.Pp
+.Dl domain = realm
+.Pp
+The domain can be either a full name of a host or a trailing
+component, in the latter case the domain-string should start with a
+perid.
+.It Li [realms]
+.Bl -tag -width "xxx" -offset indent
+.It Va REALM Li = {
+.Bl -tag -width "xxx" -offset indent
+.It Li kdc = Va host[:port]
+Specifies a kdc for this realm. If the optional port is absent, the
+default value for the
+.Dq kerberos/udp
+service will be used.
+.It Li v4_instance_convert
+.It Li v4_name_convert
+.It Li default_domain
+See
+.Xr krb5_425_conv_principal 3 .
+.El
+.It Li }
+.El
+.It Li [logging]
+.Bl -tag -width "xxx" -offset indent
+.It Va entity Li = Va destination
+Specifies that
+.Va entity
+should use the specified
+.Li destination
+for logging. See the
+.Xr krb5_openlog 3
+manual page for a list of defined destinations.
+.El
+.El
+.Sh EXAMPLE
+.Bd -literal -offset indent
+[lib_defaults]
+ default_domain = FOO.SE
+[domain_realm]
+ .foo.se = FOO.SE
+ .bar.se = FOO.SE
+[realms]
+ FOO.SE = {
+ kdc = kerberos.foo.se
+ v4_name_convert = {
+ rcmd = host
+ }
+ v4_instance_convert = {
+ xyz = xyz.bar.se
+ }
+ default_domain = foo.se
+ }
+[logging]
+ kdc = FILE:/var/heimdal/kdc.log
+ kdc = SYSLOG:INFO
+ default = SYSLOG:INFO:USER
+.Ed
+.Sh SEE ALSO
+.Xr krb5_openlog 3 ,
+.Xr krb5_425_conv_principal 3 ,
+.Xr strftime 3 ,
+.Xr Source tm
diff --git a/crypto/heimdal/lib/krb5/krb5.h b/crypto/heimdal/lib/krb5/krb5.h
new file mode 100644
index 0000000..11cabc6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5.h
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: krb5.h,v 1.162 2000/01/02 00:19:24 assar Exp $ */
+
+#ifndef __KRB5_H__
+#define __KRB5_H__
+
+#include <time.h>
+#include <krb5-types.h>
+
+#include <des.h>
+#include <asn1_err.h>
+#include <krb5_err.h>
+#include <heim_err.h>
+
+#include <asn1.h>
+
+/* simple constants */
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef int krb5_boolean;
+
+typedef int32_t krb5_error_code;
+
+typedef int krb5_kvno;
+
+typedef u_int32_t krb5_flags;
+
+typedef void *krb5_pointer;
+typedef const void *krb5_const_pointer;
+
+typedef octet_string krb5_data;
+
+struct krb5_crypto_data;
+typedef struct krb5_crypto_data *krb5_crypto;
+
+typedef enum krb5_cksumtype {
+ CKSUMTYPE_NONE = 0,
+ CKSUMTYPE_CRC32 = 1,
+ CKSUMTYPE_RSA_MD4 = 2,
+ CKSUMTYPE_RSA_MD4_DES = 3,
+ CKSUMTYPE_DES_MAC = 4,
+ CKSUMTYPE_DES_MAC_K = 5,
+ CKSUMTYPE_RSA_MD4_DES_K = 6,
+ CKSUMTYPE_RSA_MD5 = 7,
+ CKSUMTYPE_RSA_MD5_DES = 8,
+ CKSUMTYPE_RSA_MD5_DES3 = 9,
+/* CKSUMTYPE_SHA1 = 10,*/
+ CKSUMTYPE_HMAC_SHA1_DES3 = 12,
+ CKSUMTYPE_SHA1 = 1000, /* correct value? */
+ CKSUMTYPE_HMAC_MD5 = -138 /* unofficial microsoft number */
+} krb5_cksumtype;
+
+
+typedef enum krb5_enctype {
+ ETYPE_NULL = 0,
+ ETYPE_DES_CBC_CRC = 1,
+ ETYPE_DES_CBC_MD4 = 2,
+ ETYPE_DES_CBC_MD5 = 3,
+ ETYPE_DES3_CBC_MD5 = 5,
+ ETYPE_OLD_DES3_CBC_SHA1 = 7,
+ ETYPE_SIGN_DSA_GENERATE = 8,
+ ETYPE_ENCRYPT_RSA_PRIV = 9,
+ ETYPE_ENCRYPT_RSA_PUB = 10,
+ ETYPE_DES3_CBC_SHA1 = 16, /* with key derivation */
+ ETYPE_ARCFOUR_HMAC_MD5 = 23,
+ ETYPE_ARCFOUR_HMAC_MD5_56 = 24,
+ ETYPE_ENCTYPE_PK_CROSS = 48,
+ ETYPE_DES_CBC_NONE = 0x1000,
+ ETYPE_DES3_CBC_NONE = 0x1001
+} krb5_enctype;
+
+typedef enum krb5_preauthtype {
+ KRB5_PADATA_NONE = 0,
+ KRB5_PADATA_AP_REQ,
+ KRB5_PADATA_TGS_REQ = 1,
+ KRB5_PADATA_ENC_TIMESTAMP = 2,
+ KRB5_PADATA_ENC_SECURID
+} krb5_preauthtype;
+
+typedef enum krb5_key_usage {
+ KRB5_KU_PA_ENC_TIMESTAMP = 1,
+ /* AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
+ client key (section 5.4.1) */
+ KRB5_KU_TICKET = 2,
+ /* AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
+ application session key), encrypted with the service key
+ (section 5.4.2) */
+ KRB5_KU_AS_REP_ENC_PART = 3,
+ /* AS-REP encrypted part (includes tgs session key or application
+ session key), encrypted with the client key (section 5.4.2) */
+ KRB5_KU_TGS_REQ_AUTH_DAT_SESSION = 4,
+ /* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ session key (section 5.4.1) */
+ KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY = 5,
+ /* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
+ authenticator subkey (section 5.4.1) */
+ KRB5_KU_TGS_REQ_AUTH_CKSUM = 6,
+ /* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
+ with the tgs session key (sections 5.3.2, 5.4.1) */
+ KRB5_KU_TGS_REQ_AUTH = 7,
+ /* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
+ authenticator subkey), encrypted with the tgs session key
+ (section 5.3.2) */
+ KRB5_KU_TGS_REP_ENC_PART_SESSION = 8,
+ /* TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs session key (section 5.4.2) */
+ KRB5_KU_TGS_REP_ENC_PART_SUB_KEY = 9,
+ /* TGS-REP encrypted part (includes application session key),
+ encrypted with the tgs authenticator subkey (section 5.4.2) */
+ KRB5_KU_AP_REQ_AUTH_CKSUM = 10,
+ /* AP-REQ Authenticator cksum, keyed with the application session
+ key (section 5.3.2) */
+ KRB5_KU_AP_REQ_AUTH = 11,
+ /* AP-REQ Authenticator (includes application authenticator
+ subkey), encrypted with the application session key (section
+ 5.3.2) */
+ KRB5_KU_AP_REQ_ENC_PART = 12,
+ /* AP-REP encrypted part (includes application session subkey),
+ encrypted with the application session key (section 5.5.2) */
+ KRB5_KU_KRB_PRIV = 13,
+ /* KRB-PRIV encrypted part, encrypted with a key chosen by the
+ application (section 5.7.1) */
+ KRB5_KU_KRB_CRED = 14,
+ /* KRB-CRED encrypted part, encrypted with a key chosen by the
+ application (section 5.8.1) */
+ KRB5_KU_KRB_SAFE_CKSUM = 15,
+ /* KRB-SAFE cksum, keyed with a key chosen by the application
+ (section 5.6.1) */
+ KRB5_KU_OTHER_ENCRYPTED = 16,
+ /* Data which is defined in some specification outside of
+ Kerberos to be encrypted using an RFC1510 encryption type. */
+ KRB5_KU_OTHER_CKSUM = 17
+ /* Data which is defined in some specification outside of
+ Kerberos to be checksummed using an RFC1510 checksum type. */
+} krb5_key_usage;
+
+typedef enum krb5_salttype {
+ KRB5_PW_SALT = pa_pw_salt,
+ KRB5_AFS3_SALT = pa_afs3_salt
+}krb5_salttype;
+
+typedef struct krb5_salt {
+ krb5_salttype salttype;
+ krb5_data saltvalue;
+} krb5_salt;
+
+typedef ETYPE_INFO krb5_preauthinfo;
+
+typedef struct {
+ krb5_preauthtype type;
+ krb5_preauthinfo info; /* list of preauthinfo for this type */
+} krb5_preauthdata_entry;
+
+typedef struct krb5_preauthdata {
+ unsigned len;
+ krb5_preauthdata_entry *val;
+}krb5_preauthdata;
+
+typedef enum krb5_address_type {
+ KRB5_ADDRESS_INET = 2,
+ KRB5_ADDRESS_INET6 = 24,
+ KRB5_ADDRESS_ADDRPORT = 256,
+ KRB5_ADDRESS_IPPORT = 257
+} krb5_address_type;
+
+enum {
+ AP_OPTS_USE_SESSION_KEY = 1,
+ AP_OPTS_MUTUAL_REQUIRED = 2
+};
+
+typedef HostAddress krb5_address;
+
+typedef HostAddresses krb5_addresses;
+
+typedef enum krb5_keytype {
+ KEYTYPE_NULL = 0,
+ KEYTYPE_DES = 1,
+ KEYTYPE_DES3 = 7,
+ KEYTYPE_ARCFOUR = 23
+} krb5_keytype;
+
+typedef EncryptionKey krb5_keyblock;
+
+typedef AP_REQ krb5_ap_req;
+
+struct krb5_cc_ops;
+
+#define KRB5_DEFAULT_CCROOT "FILE:/tmp/krb5cc_"
+
+typedef void *krb5_cc_cursor;
+
+typedef struct krb5_ccache_data {
+ const struct krb5_cc_ops *ops;
+ krb5_data data;
+}krb5_ccache_data;
+
+typedef struct krb5_ccache_data *krb5_ccache;
+
+typedef struct krb5_context_data *krb5_context;
+
+typedef Realm krb5_realm;
+typedef const char *krb5_const_realm; /* stupid language */
+typedef Principal krb5_principal_data;
+typedef struct Principal *krb5_principal;
+typedef const struct Principal *krb5_const_principal;
+
+typedef time_t krb5_deltat;
+typedef time_t krb5_timestamp;
+
+typedef struct krb5_times {
+ krb5_timestamp authtime;
+ krb5_timestamp starttime;
+ krb5_timestamp endtime;
+ krb5_timestamp renew_till;
+} krb5_times;
+
+typedef union {
+ TicketFlags b;
+ krb5_flags i;
+} krb5_ticket_flags;
+
+/* options for krb5_get_in_tkt() */
+#define KDC_OPT_FORWARDABLE (1 << 1)
+#define KDC_OPT_FORWARDED (1 << 2)
+#define KDC_OPT_PROXIABLE (1 << 3)
+#define KDC_OPT_PROXY (1 << 4)
+#define KDC_OPT_ALLOW_POSTDATE (1 << 5)
+#define KDC_OPT_POSTDATED (1 << 6)
+#define KDC_OPT_RENEWABLE (1 << 8)
+#define KDC_OPT_REQUEST_ANONYMOUS (1 << 14)
+#define KDC_OPT_DISABLE_TRANSITED_CHECK (1 << 26)
+#define KDC_OPT_RENEWABLE_OK (1 << 27)
+#define KDC_OPT_ENC_TKT_IN_SKEY (1 << 28)
+#define KDC_OPT_RENEW (1 << 30)
+#define KDC_OPT_VALIDATE (1 << 31)
+
+typedef union {
+ KDCOptions b;
+ krb5_flags i;
+} krb5_kdc_flags;
+
+/* flags for krb5_verify_ap_req */
+
+#define KRB5_VERIFY_AP_REQ_IGNORE_INVALID (1 << 0)
+
+#define KRB5_GC_CACHED 1
+#define KRB5_GC_USER_USER 2
+
+/* constants for compare_creds (and cc_retrieve_cred) */
+#define KRB5_TC_DONT_MATCH_REALM (1U << 31)
+#define KRB5_TC_MATCH_KEYTYPE (1U << 30)
+
+typedef AuthorizationData krb5_authdata;
+
+typedef KRB_ERROR krb5_error;
+
+typedef struct krb5_creds {
+ krb5_principal client;
+ krb5_principal server;
+ krb5_keyblock session;
+ krb5_times times;
+ krb5_data ticket;
+ krb5_data second_ticket;
+ krb5_authdata authdata;
+ krb5_addresses addresses;
+ krb5_ticket_flags flags;
+} krb5_creds;
+
+typedef struct krb5_cc_ops {
+ char *prefix;
+ char* (*get_name)(krb5_context, krb5_ccache);
+ krb5_error_code (*resolve)(krb5_context, krb5_ccache *, const char *);
+ krb5_error_code (*gen_new)(krb5_context, krb5_ccache *);
+ krb5_error_code (*init)(krb5_context, krb5_ccache, krb5_principal);
+ krb5_error_code (*destroy)(krb5_context, krb5_ccache);
+ krb5_error_code (*close)(krb5_context, krb5_ccache);
+ krb5_error_code (*store)(krb5_context, krb5_ccache, krb5_creds*);
+ krb5_error_code (*retrieve)(krb5_context, krb5_ccache,
+ krb5_flags, krb5_creds*, krb5_creds);
+ krb5_error_code (*get_princ)(krb5_context, krb5_ccache, krb5_principal*);
+ krb5_error_code (*get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *);
+ krb5_error_code (*get_next)(krb5_context, krb5_ccache,
+ krb5_cc_cursor*, krb5_creds*);
+ krb5_error_code (*end_get)(krb5_context, krb5_ccache, krb5_cc_cursor*);
+ krb5_error_code (*remove_cred)(krb5_context, krb5_ccache,
+ krb5_flags, krb5_creds*);
+ krb5_error_code (*set_flags)(krb5_context, krb5_ccache, krb5_flags);
+ int (*get_version)(krb5_context, krb5_ccache);
+} krb5_cc_ops;
+
+struct krb5_log_facility;
+
+struct krb5_config_binding {
+ enum { krb5_config_string, krb5_config_list } type;
+ char *name;
+ struct krb5_config_binding *next;
+ union {
+ char *string;
+ struct krb5_config_binding *list;
+ void *generic;
+ } u;
+};
+
+typedef struct krb5_config_binding krb5_config_binding;
+
+typedef krb5_config_binding krb5_config_section;
+
+typedef struct krb5_context_data {
+ krb5_enctype *etypes;
+ krb5_enctype *etypes_des;
+ char **default_realms;
+ time_t max_skew;
+ time_t kdc_timeout;
+ unsigned max_retries;
+ int32_t kdc_sec_offset;
+ int32_t kdc_usec_offset;
+ krb5_config_section *cf;
+ struct et_list *et_list;
+ struct krb5_log_facility *warn_dest;
+ krb5_cc_ops *cc_ops;
+ int num_cc_ops;
+ const char *http_proxy;
+ const char *time_fmt;
+ krb5_boolean log_utc;
+ const char *default_keytab;
+ krb5_boolean use_admin_kdc;
+ krb5_addresses *extra_addresses;
+ krb5_boolean scan_interfaces; /* `ifconfig -a' */
+ krb5_boolean srv_lookup; /* do SRV lookups */
+ krb5_boolean srv_try_txt; /* try TXT records also */
+ krb5_boolean srv_try_rfc2052; /* try RFC2052 compatible records */
+ int32_t fcache_vno; /* create cache files w/ this
+ version */
+ int num_kt_types; /* # of registered keytab types */
+ struct krb5_keytab_data *kt_types; /* registered keytab types */
+} krb5_context_data;
+
+enum {
+ KRB5_NT_UNKNOWN = 0,
+ KRB5_NT_PRINCIPAL = 1,
+ KRB5_NT_SRV_INST = 2,
+ KRB5_NT_SRV_HST = 3,
+ KRB5_NT_SRV_XHST = 4,
+ KRB5_NT_UID = 5
+};
+
+
+typedef struct krb5_ticket {
+ EncTicketPart ticket;
+ krb5_principal client;
+ krb5_principal server;
+} krb5_ticket;
+
+typedef Authenticator krb5_authenticator_data;
+
+typedef krb5_authenticator_data *krb5_authenticator;
+
+struct krb5_rcache_data;
+typedef struct krb5_rcache_data *krb5_rcache;
+typedef Authenticator krb5_donot_reply;
+
+#define KRB5_STORAGE_HOST_BYTEORDER 0x01
+#define KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS 0x02
+#define KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE 0x04
+#define KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE 0x08
+
+typedef struct krb5_storage {
+ void *data;
+ ssize_t (*fetch)(struct krb5_storage*, void*, size_t);
+ ssize_t (*store)(struct krb5_storage*, void*, size_t);
+ off_t (*seek)(struct krb5_storage*, off_t, int);
+ void (*free)(struct krb5_storage*);
+ krb5_flags flags;
+} krb5_storage;
+
+typedef struct krb5_keytab_entry {
+ krb5_principal principal;
+ krb5_kvno vno;
+ krb5_keyblock keyblock;
+ u_int32_t timestamp;
+} krb5_keytab_entry;
+
+typedef struct krb5_kt_cursor {
+ int fd;
+ krb5_storage *sp;
+ void *data;
+} krb5_kt_cursor;
+
+struct krb5_keytab_data;
+
+typedef struct krb5_keytab_data *krb5_keytab;
+
+struct krb5_keytab_data {
+ char *prefix;
+ krb5_error_code (*resolve)(krb5_context, const char*, krb5_keytab);
+ krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
+ krb5_error_code (*close)(krb5_context, krb5_keytab);
+ krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
+ krb5_kvno, krb5_enctype, krb5_keytab_entry*);
+ krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
+ krb5_error_code (*next_entry)(krb5_context, krb5_keytab,
+ krb5_keytab_entry*, krb5_kt_cursor*);
+ krb5_error_code (*end_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
+ krb5_error_code (*add)(krb5_context, krb5_keytab, krb5_keytab_entry*);
+ krb5_error_code (*remove)(krb5_context, krb5_keytab, krb5_keytab_entry*);
+ void *data;
+ int32_t version;
+};
+
+typedef struct krb5_keytab_data krb5_kt_ops;
+
+struct krb5_keytab_key_proc_args {
+ krb5_keytab keytab;
+ krb5_principal principal;
+};
+
+typedef struct krb5_keytab_key_proc_args krb5_keytab_key_proc_args;
+
+enum {
+ KRB5_AUTH_CONTEXT_DO_TIME = 1,
+ KRB5_AUTH_CONTEXT_RET_TIME = 2,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE = 4,
+ KRB5_AUTH_CONTEXT_RET_SEQUENCE = 8
+};
+
+typedef struct krb5_auth_context_data {
+ unsigned int flags;
+
+ krb5_address *local_address;
+ krb5_address *remote_address;
+ int16_t local_port;
+ int16_t remote_port;
+ krb5_keyblock *keyblock;
+ krb5_keyblock *local_subkey;
+ krb5_keyblock *remote_subkey;
+
+ int32_t local_seqnumber;
+ int32_t remote_seqnumber;
+
+ krb5_authenticator authenticator;
+
+ krb5_pointer i_vector;
+
+ krb5_rcache rcache;
+
+ krb5_keytype keytype; /* ¿requested key type ? */
+ krb5_cksumtype cksumtype; /* ¡requested checksum type! */
+
+}krb5_auth_context_data, *krb5_auth_context;
+
+typedef struct {
+ KDC_REP kdc_rep;
+ EncKDCRepPart enc_part;
+ KRB_ERROR error;
+} krb5_kdc_rep;
+
+extern char *heimdal_version, *heimdal_long_version;
+
+typedef void (*krb5_log_log_func_t)(const char*, const char*, void*);
+typedef void (*krb5_log_close_func_t)(void*);
+
+typedef struct krb5_log_facility {
+ const char *program;
+ int len;
+ struct facility *val;
+} krb5_log_facility;
+
+typedef EncAPRepPart krb5_ap_rep_enc_part;
+
+#define KRB5_RECVAUTH_IGNORE_VERSION 1
+
+#define KRB5_SENDAUTH_VERSION "KRB5_SENDAUTH_V1.0"
+
+#define KRB5_TGS_NAME_SIZE (6)
+#define KRB5_TGS_NAME ("krbtgt")
+
+/* variables */
+
+extern const char krb5_config_file[];
+extern const char krb5_defkeyname[];
+
+typedef struct _krb5_prompt {
+ char *prompt;
+ int hidden;
+ krb5_data *reply;
+} krb5_prompt;
+
+typedef int (*krb5_prompter_fct)(krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[]);
+
+typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key);
+typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
+ krb5_keyblock *key,
+ krb5_key_usage usage,
+ krb5_const_pointer decrypt_arg,
+ krb5_kdc_rep *dec_rep);
+
+
+typedef struct _krb5_get_init_creds_opt {
+ krb5_flags flags;
+ krb5_deltat tkt_life;
+ krb5_deltat renew_life;
+ int forwardable;
+ int proxiable;
+ krb5_enctype *etype_list;
+ int etype_list_length;
+ krb5_addresses *address_list;
+#if 0 /* this is the MIT-way */
+ krb5_address **address_list;
+#endif
+ /* XXX the next three should not be used, as they may be
+ removed later */
+ krb5_preauthtype *preauth_list;
+ int preauth_list_length;
+ krb5_data *salt;
+} krb5_get_init_creds_opt;
+
+#define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE 0x0001
+#define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE 0x0002
+#define KRB5_GET_INIT_CREDS_OPT_FORWARDABLE 0x0004
+#define KRB5_GET_INIT_CREDS_OPT_PROXIABLE 0x0008
+#define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST 0x0010
+#define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST 0x0020
+#define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST 0x0040
+#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
+
+typedef struct _krb5_verify_init_creds_opt {
+ krb5_flags flags;
+ int ap_req_nofail;
+} krb5_verify_init_creds_opt;
+
+#define KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL 0x0001
+
+extern const krb5_cc_ops krb5_fcc_ops;
+extern const krb5_cc_ops krb5_mcc_ops;
+
+extern const krb5_kt_ops krb5_fkt_ops;
+extern const krb5_kt_ops krb5_mkt_ops;
+extern const krb5_kt_ops krb5_akf_ops;
+
+#define KRB5_KPASSWD_SUCCESS 0
+#define KRB5_KPASSWD_MALFORMED 0
+#define KRB5_KPASSWD_HARDERROR 0
+#define KRB5_KPASSWD_AUTHERROR 0
+#define KRB5_KPASSWD_SOFTERROR 0
+
+#define KPASSWD_PORT 464
+
+struct credentials; /* this is to keep the compiler happy */
+struct getargs;
+
+struct sockaddr;
+
+#include <krb5-protos.h>
+
+#endif /* __KRB5_H__ */
+
diff --git a/crypto/heimdal/lib/krb5/krb5_425_conv_principal.3 b/crypto/heimdal/lib/krb5/krb5_425_conv_principal.3
new file mode 100644
index 0000000..231c3ff
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_425_conv_principal.3
@@ -0,0 +1,198 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_425_conv_principal.3,v 1.3 1999/04/11 01:47:22 joda Exp $
+.Dd April 11, 1999
+.Dt KRB5_425_CONV_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_425_conv_principal ,
+.Nm krb5_425_conv_principal_ext ,
+.Nm krb5_524_conv_principal
+.Nd Converts to and from version 4 principals
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_425_conv_principal "krb5_context context" "const char *name" "const char *instance" "const char *realm" "krb5_principal *principal"
+
+.Ft krb5_error_code
+.Fn krb5_425_conv_principal_ext "krb5_context context" "const char *name" "const char *instance" "const char *realm" "krb5_boolean (*func)(krb5_context, krb5_principal)" "krb5_boolean resolve" "krb5_principal *principal"
+
+.Ft krb5_error_code
+.Fn krb5_524_conv_principal "krb5_context context" "const krb5_principal principal" "char *name" "char *instance" "char *realm"
+
+.Sh DESCRIPTION
+
+Converting between version 4 and version 5 principals can at best be
+described as a mess.
+.Pp
+A version 4 principal consists of a name, an instance, and a realm. A
+version 5 principal consists of one or more components, and a
+realm. In some cases also the first component/name will differ between
+version 4 and version 5. Furthermore the second component of a host
+principal will be the fully qualified domain name of the host in
+question, while the instance of a version 4 principal will only
+contain the first component. Because of these problems the conversion
+between principals will have to be site customized.
+.Pp
+.Fn krb5_425_conv_principal_ext
+will try to convert a version 4 principal, given by
+.Fa name ,
+.Fa instance ,
+and
+.Fa realm ,
+to a version 5 principal. This can result in several possible
+principals, and if
+.Fa func
+is non-NULL, it will be called for each candidate principal.
+.Fa func
+should return true if the principal was
+.Dq good .
+To accomplish this,
+.Fn krb5_425_conv_principal_ext
+will look up the name in
+.Pa krb5.conf .
+It first looks in the
+.Li v4_name_convert/host
+subsection, which should contain a list of version 4 names whose
+instance should be treated as a hostname. This list can be specified
+for each realm (in the
+.Li realms
+section), or in the
+.Li libdefaults
+section. If the name is found the resulting name of the principal
+will be the value of this binding. The instance is then first looked
+up in
+.Li v4_instance_convert
+for the specified realm. If found the resulting value will be used as
+instance (this can be used for special cases), no further attempts
+will be made to find a conversion if this fails (with
+.Fa func ) .
+If the
+.Fa resolve
+parameter is true, the instance will be looked up with
+.Fn gethostbyname .
+This can be a time consuming, error prone, and unsafe operation. Next
+a list of hostnames will be created from the instance and the
+.Li v4_domains
+variable, which should contain a list of possible domains for the
+specific realm.
+.Pp
+On the other hand, if the name is not found in a
+.Li host
+section, it is looked up in a
+.Li v4_name_convert/plain
+binding. If found here the name will be converted, but the instance
+will be untouched.
+.Pp
+This list of default host-type conversions is compiled-in:
+.Bd -literal -offset indent
+v4_name_convert = {
+ host = {
+ ftp = ftp
+ hprop = hprop
+ pop = pop
+ rcmd = host
+ }
+}
+.Ed
+.Pp
+It will only be used if there isn't an entry for these names in the
+config file, so you can override these defaults.
+.Pp
+.Fn krb5_425_conv_principal
+will call
+.Fn krb5_425_conv_principal_ext
+with
+.Dv NULL
+as
+.Fa func ,
+and the value of
+.Li v4_instance_resolve
+(from the
+.Li libdefaults
+section) as
+.Fa resolve .
+.Pp
+.Fn krb5_524_conv_principal
+basically does the opposite of
+.Fn krb5_425_conv_principal ,
+it just doesn't have to look up any names, but will instead truncate
+instances found to belong to a host principal. The
+.Fa name ,
+.Fa instance ,
+and
+.Fa realm
+should be at least 40 characters long.
+
+.Sh EXAMPLES
+
+Since this is confusing an example is in place.
+.Pp
+Assume that we have the
+.Dq foo.com ,
+and
+.Dq bar.com
+domains that have shared a single version 4 realm, FOO.COM. The version 4
+.Pa krb.realms
+file looked like:
+.Bd -literal -offset indent
+foo.com FOO.COM
+\&.foo.com FOO.COM
+\&.bar.com FOO.COM
+.Ed
+.Pp
+A
+.Pa krb5.conf
+file that covers this case might look like:
+.Bd -literal -offset indent
+[libdefaults]
+ v4_instance_resolve = yes
+[realms]
+ FOO.COM = {
+ kdc = kerberos.foo.com
+ v4_instance_convert = {
+ foo = foo.com
+ }
+ v4_domains = foo.com
+ }
+.Ed
+.Pp
+With this setup and the following host table:
+.Bd -literal -offset indent
+foo.com
+a-host.foo.com
+b-host.bar.com
+.Ed
+the following conversions will be made:
+.Bd -literal -offset indent
+rcmd.a-host \(-> host/a-host.foo.com
+ftp.b-host \(-> ftp/b-host.bar.com
+pop.foo \(-> pop/foo.com
+ftp.other \(-> ftp/other.foo.com
+other.a-host \(-> other/a-host
+.Ed
+.Pp
+The first three are what you expect. If you remove the
+.Dq v4_domains ,
+the fourth entry will result in an error (since the host
+.Dq other
+can't be found). Even if
+.Dq a-host
+is a valid host name, the last entry will not be converted, since the
+.Dq other
+name is not known to represent a host-type principal.
+If you turn off
+.Dq v4_instance_resolve
+the second example will result in
+.Dq ftp/b-host.foo.com
+(because of the default domain). And all of this is of course only
+valid if you have working name resolving.
+
+.Sh SEE ALSO
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3 ,
+.Xr krb5.conf 5
diff --git a/crypto/heimdal/lib/krb5/krb5_build_principal.3 b/crypto/heimdal/lib/krb5/krb5_build_principal.3
new file mode 100644
index 0000000..16ccf72
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_build_principal.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_build_principal.3,v 1.1 1997/08/14 00:03:16 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_BUILD_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_build_principal ,
+.Nm krb5_build_principal_ext ,
+.Nm krb5_build_principal_va ,
+.Nm krb5_build_principal_va_ext ,
+.Nm krb5_make_principal
+.Nd Principal creation functions
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_build_principal "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "..."
+
+.Ft krb5_error_code
+.Fn krb5_build_principal_ext "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "..."
+
+.Ft krb5_error_code
+.Fn krb5_build_principal_va "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_build_principal_va_ext "krb5_context context" "krb5_principal *principal" "int realm_len" "krb5_const_realm realm" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_make_principal "krb5_context context" "krb5_principal *principal" "krb5_const_realm realm" "..."
+
+
+.Sh DESCRIPTION
+
+These functions create a Kerberos 5 principal from a realm and a list
+of components.
+All of these functions return an allocated principal in the
+.Fa principal
+parameter, this should be freed with
+.Fn krb5_free_principal
+after use.
+.Pp
+The
+.Dq build
+functions take a
+.Fa realm
+and the length of the realm. The
+.Fn krb5_build_principal
+and
+.Fn krb5_build_principal_va
+also takes a list of components (zero-terminated strings), terminated
+with
+.Dv NULL .
+The
+.Fn krb5_build_principal_ext
+and
+.Fn krb5_build_principal_va_ext
+takes a list of length-value pairs, the list is terminated with a zero
+length.
+.Pp
+The
+.Fn krb5_make_principal
+is a wrapper around
+.Fn krb5_build_principal .
+If the realm is
+.Dv NULL ,
+the default realm will be used.
+
+.Sh BUGS
+You can not have a NUL in a component. Until someone can give a good
+example of where it would be a good idea to have NUL's in a component,
+this will not be fixed.
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_create_checksum.3 b/crypto/heimdal/lib/krb5/krb5_create_checksum.3
new file mode 100644
index 0000000..e2362a9
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_create_checksum.3
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: krb5_create_checksum.3,v 1.1 1999/04/18 13:47:11 joda Exp $
+.Dd April 7, 1999
+.Dt NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_checksum_is_collision_proof ,
+.Nm krb5_checksum_is_keyed ,
+.Nm krb5_checksumsize ,
+.Nm krb5_create_checksum ,
+.Nm krb5_verify_checksum
+.Nd creates and verifies checksums
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_create_checksum "krb5_context context" "krb5_crypto crypto" "unsigned usage_or_type" "void *data" "size_t len" "Checksum *result"
+
+.Ft krb5_error_code
+.Fn krb5_verify_checksum "krb5_context context" "krb5_crypto crypto" "krb5_key_usage usage" "void *data" "size_t len" "Checksum *cksum"
+
+.Ft krb5_boolean
+.Fn krb5_checksum_is_collision_proof "krb5_context context" "krb5_cksumtype type"
+
+.Ft krb5_boolean
+.Fn krb5_checksum_is_keyed "krb5_context context" "krb5_cksumtype type"
+
+.Sh DESCRIPTION
+These functions are used to create and verify checksums.
+.Fn krb5_create_checksum
+creates a checksum of the specified data, and puts it in
+.Fa result .
+If
+.Fa crypto
+is
+.Dv NULL ,
+.Fa usage_or_type
+specifies the checksum type to use; it must not be keyed. Otherwise
+.Fa crypto
+is an encryption context created by
+.Fn krb5_crypto_init ,
+and
+.Fa usage_or_type
+specifies a key-usage.
+.Pp
+.Fn krb5_verify_checksum
+verifies the
+.Fa checksum ,
+against the provided data.
+.Pp
+.Fn krb5_checksum_is_collision_proof
+returns true is the specified checksum is collision proof (that it's
+very unlikely that two strings has the same hash value, and that it's
+hard to find two strings that has the same hash). Examples of
+collision proof checksums are MD5, and SHA1, while CRC32 is not.
+.Pp
+.Fn krb5_checksum_is_keyed
+returns true if the specified checksum type is keyed (that the hash
+value is a function of both the data, and a separate key). Examples of
+keyed hash algorithms are HMAC-SHA1-DES3, and RSA-MD5-DES. The
+.Dq plain
+hash functions MD5, and SHA1 are not keyed.
+
+.\" .Sh EXAMPLE
+.\" .Sh BUGS
+.Sh SEE ALSO
+.Xr krb5_crypto_init 3 ,
+.Xr krb5_encrypt 3
diff --git a/crypto/heimdal/lib/krb5/krb5_crypto_init.3 b/crypto/heimdal/lib/krb5/krb5_crypto_init.3
new file mode 100644
index 0000000..29db8c1
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_crypto_init.3
@@ -0,0 +1,41 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: krb5_crypto_init.3,v 1.1 1999/04/18 13:47:21 joda Exp $
+.Dd April 7, 1999
+.Dt NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_crypto_init ,
+.Nm krb5_crypto_destroy
+.Nd initialize encryption context
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_crypto_init "krb5_context context" "krb5_keyblock *key" "krb5_enctype enctype" "krb5_crypto *crypto"
+
+.Ft krb5_error_code
+.Fn krb5_crypto_destroy "krb5_context context" "krb5_crypto crypto"
+
+.Sh DESCRIPTION
+These functions are used to initialize an encryption context that can
+be used to encrypt or checksum data.
+.Pp
+The
+.Fn krb5_crypt_init
+initializes the encrytion context
+.Fa crypto .
+The
+.Fa key
+parameter is the key to use for encryption, and checksums. The
+encryption type to use is taken from the key, but can be overridden
+with the
+.Fa enctype parameter .
+.Pp
+.Fn krb5_crypto_destroy
+frees a previously allocated encrypion context.
+
+.\" .Sh EXAMPLE
+.\" .Sh BUGS
+.Sh SEE ALSO
+.Xr krb5_create_checksum 3 ,
+.Xr krb5_encrypt 3
diff --git a/crypto/heimdal/lib/krb5/krb5_encrypt.3 b/crypto/heimdal/lib/krb5/krb5_encrypt.3
new file mode 100644
index 0000000..d8cc89e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_encrypt.3
@@ -0,0 +1,60 @@
+.\" Copyright (c) 1999 Kungliga Tekniska Högskolan
+.\" $Id: krb5_encrypt.3,v 1.1 1999/04/18 13:47:30 joda Exp $
+.Dd April 7, 1999
+.Dt KRB5_ENCRYPT 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_decrypt ,
+.Nm krb5_decrypt_EncryptedData ,
+.Nm krb5_encrypt ,
+.Nm krb5_encrypt_EncryptedData
+.Nd encrypt and decrypt data
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_encrypt "krb5_context context" "krb5_crypto crypto" "unsigned usage" "void *data" "size_t len" "krb5_data *result"
+
+.Ft krb5_error_code
+.Fn krb5_encrypt_EncryptedData "krb5_context context" "krb5_crypto crypto" "unsigned usage" "void *data" "size_t len" "int kvno" "EncryptedData *result"
+
+.Ft krb5_error_code
+.Fn krb5_decrypt "krb5_context context" "krb5_crypto crypto" "unsigned usage" "void *data" "size_t len" "krb5_data *result"
+
+.Ft krb5_error_code
+.Fn krb5_decrypt_EncryptedData "krb5_context context" "krb5_crypto crypto" "unsigned usage" "EncryptedData *e" "krb5_data *result"
+
+.Sh DESCRIPTION
+These functions are used to encrypt and decrypt data.
+.Pp
+.Fn krb5_encrypt
+puts the encrypted version of
+.Fa data
+(of size
+.Fa len )
+in
+.Fa result .
+If the encryption type supports using derived keys,
+.Fa usage
+should be the appropriate key-usage.
+.Fn krb5_encrypt_EncryptedData
+does the same as
+.Fn krb5_encrypt ,
+but it puts the encrypted data in a
+.Fa EncryptedData
+structure instead. If
+.Fa kvno
+is not zero, it will be put in the
+.Fa kvno field in the
+.Fa EncryptedData .
+.Pp
+.Fn krb5_decrypt ,
+and
+.Fn krb5_decrypt_EncryptedData
+works similarly.
+
+.\" .Sh EXAMPLE
+.\" .Sh BUGS
+.Sh SEE ALSO
+.Xr krb5_crypto_init 3 ,
+.Xr krb5_create_checksum 3
diff --git a/crypto/heimdal/lib/krb5/krb5_err.et b/crypto/heimdal/lib/krb5/krb5_err.et
new file mode 100644
index 0000000..e8779df
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_err.et
@@ -0,0 +1,215 @@
+#
+# Error messages for the krb5 library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: krb5_err.et,v 1.7 1999/02/11 21:03:40 joda Exp $"
+
+error_table krb5
+
+prefix KRB5KDC_ERR
+error_code NONE, "No error"
+error_code NAME_EXP, "Client's entry in database has expired"
+error_code SERVICE_EXP, "Server's entry in database has expired"
+error_code BAD_PVNO, "Requested protocol version not supported"
+error_code C_OLD_MAST_KVNO, "Client's key is encrypted in an old master key"
+error_code S_OLD_MAST_KVNO, "Server's key is encrypted in an old master key"
+error_code C_PRINCIPAL_UNKNOWN, "Client not found in Kerberos database"
+error_code S_PRINCIPAL_UNKNOWN, "Server not found in Kerberos database"
+error_code PRINCIPAL_NOT_UNIQUE,"Principal has multiple entries in Kerberos database"
+error_code NULL_KEY, "Client or server has a null key"
+error_code CANNOT_POSTDATE, "Ticket is ineligible for postdating"
+error_code NEVER_VALID, "Requested effective lifetime is negative or too short"
+error_code POLICY, "KDC policy rejects request"
+error_code BADOPTION, "KDC can't fulfill requested option"
+error_code ETYPE_NOSUPP, "KDC has no support for encryption type"
+error_code SUMTYPE_NOSUPP, "KDC has no support for checksum type"
+error_code PADATA_TYPE_NOSUPP, "KDC has no support for padata type"
+error_code TRTYPE_NOSUPP, "KDC has no support for transited type"
+error_code CLIENT_REVOKED, "Clients credentials have been revoked"
+error_code SERVICE_REVOKED, "Credentials for server have been revoked"
+error_code TGT_REVOKED, "TGT has been revoked"
+error_code CLIENT_NOTYET, "Client not yet valid - try again later"
+error_code SERVICE_NOTYET, "Server not yet valid - try again later"
+error_code KEY_EXPIRED, "Password has expired"
+error_code PREAUTH_FAILED, "Preauthentication failed"
+error_code PREAUTH_REQUIRED, "Additional pre-authentication required"
+error_code SERVER_NOMATCH, "Requested server and ticket don't match"
+
+# 27-30 are reserved
+index 31
+prefix KRB5KRB_AP
+error_code ERR_BAD_INTEGRITY, "Decrypt integrity check failed"
+error_code ERR_TKT_EXPIRED, "Ticket expired"
+error_code ERR_TKT_NYV, "Ticket not yet valid"
+error_code ERR_REPEAT, "Request is a replay"
+error_code ERR_NOT_US, "The ticket isn't for us"
+error_code ERR_BADMATCH, "Ticket/authenticator don't match"
+error_code ERR_SKEW, "Clock skew too great"
+error_code ERR_BADADDR, "Incorrect net address"
+error_code ERR_BADVERSION, "Protocol version mismatch"
+error_code ERR_MSG_TYPE, "Invalid message type"
+error_code ERR_MODIFIED, "Message stream modified"
+error_code ERR_BADORDER, "Message out of order"
+error_code ERR_ILL_CR_TKT, "Illegal cross-realm ticket"
+error_code ERR_BADKEYVER, "Key version is not available"
+error_code ERR_NOKEY, "Service key not available"
+error_code ERR_MUT_FAIL, "Mutual authentication failed"
+error_code ERR_BADDIRECTION, "Incorrect message direction"
+error_code ERR_METHOD, "Alternative authentication method required"
+error_code ERR_BADSEQ, "Incorrect sequence number in message"
+error_code ERR_INAPP_CKSUM, "Inappropriate type of checksum in message"
+error_code PATH_NOT_ACCEPTED, "Policy rejects transited path"
+
+prefix KRB5KRB_ERR
+error_code RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP"
+# 53-59 are reserved
+index 60
+error_code GENERIC, "Generic error (see e-text)"
+error_code FIELD_TOOLONG, "Field is too long for this implementation"
+
+# 62-127 are reserved
+index 128
+prefix
+error_code KRB5_ERR_RCSID, "$Id: krb5_err.et,v 1.7 1999/02/11 21:03:40 joda Exp $"
+
+error_code KRB5_LIBOS_BADLOCKFLAG, "Invalid flag for file lock mode"
+error_code KRB5_LIBOS_CANTREADPWD, "Cannot read password"
+error_code KRB5_LIBOS_BADPWDMATCH, "Password mismatch"
+error_code KRB5_LIBOS_PWDINTR, "Password read interrupted"
+
+error_code KRB5_PARSE_ILLCHAR, "Illegal character in component name"
+error_code KRB5_PARSE_MALFORMED, "Malformed representation of principal"
+
+error_code KRB5_CONFIG_CANTOPEN, "Can't open/find configuration file"
+error_code KRB5_CONFIG_BADFORMAT, "Improper format of configuration file"
+error_code KRB5_CONFIG_NOTENUFSPACE, "Insufficient space to return complete information"
+
+error_code KRB5_BADMSGTYPE, "Invalid message type specified for encoding"
+
+error_code KRB5_CC_BADNAME, "Credential cache name malformed"
+error_code KRB5_CC_UNKNOWN_TYPE, "Unknown credential cache type"
+error_code KRB5_CC_NOTFOUND, "Matching credential not found"
+error_code KRB5_CC_END, "End of credential cache reached"
+
+error_code KRB5_NO_TKT_SUPPLIED, "Request did not supply a ticket"
+
+error_code KRB5KRB_AP_WRONG_PRINC, "Wrong principal in request"
+error_code KRB5KRB_AP_ERR_TKT_INVALID, "Ticket has invalid flag set"
+
+error_code KRB5_PRINC_NOMATCH, "Requested principal and ticket don't match"
+error_code KRB5_KDCREP_MODIFIED, "KDC reply did not match expectations"
+error_code KRB5_KDCREP_SKEW, "Clock skew too great in KDC reply"
+error_code KRB5_IN_TKT_REALM_MISMATCH, "Client/server realm mismatch in initial ticket request"
+
+error_code KRB5_PROG_ETYPE_NOSUPP, "Program lacks support for encryption type"
+error_code KRB5_PROG_KEYTYPE_NOSUPP, "Program lacks support for key type"
+error_code KRB5_WRONG_ETYPE, "Requested encryption type not used in message"
+error_code KRB5_PROG_SUMTYPE_NOSUPP, "Program lacks support for checksum type"
+
+error_code KRB5_REALM_UNKNOWN, "Cannot find KDC for requested realm"
+error_code KRB5_SERVICE_UNKNOWN, "Kerberos service unknown"
+error_code KRB5_KDC_UNREACH, "Cannot contact any KDC for requested realm"
+error_code KRB5_NO_LOCALNAME, "No local name found for principal name"
+
+error_code KRB5_MUTUAL_FAILED, "Mutual authentication failed"
+
+# some of these should be combined/supplanted by system codes
+
+error_code KRB5_RC_TYPE_EXISTS, "Replay cache type is already registered"
+error_code KRB5_RC_MALLOC, "No more memory to allocate (in replay cache code)"
+error_code KRB5_RC_TYPE_NOTFOUND, "Replay cache type is unknown"
+error_code KRB5_RC_UNKNOWN, "Generic unknown RC error"
+error_code KRB5_RC_REPLAY, "Message is a replay"
+error_code KRB5_RC_IO, "Replay I/O operation failed XXX"
+error_code KRB5_RC_NOIO, "Replay cache type does not support non-volatile storage"
+error_code KRB5_RC_PARSE, "Replay cache name parse/format error"
+
+error_code KRB5_RC_IO_EOF, "End-of-file on replay cache I/O"
+error_code KRB5_RC_IO_MALLOC, "No more memory to allocate (in replay cache I/O code)"
+error_code KRB5_RC_IO_PERM, "Permission denied in replay cache code"
+error_code KRB5_RC_IO_IO, "I/O error in replay cache i/o code"
+error_code KRB5_RC_IO_UNKNOWN, "Generic unknown RC/IO error"
+error_code KRB5_RC_IO_SPACE, "Insufficient system space to store replay information"
+
+error_code KRB5_TRANS_CANTOPEN, "Can't open/find realm translation file"
+error_code KRB5_TRANS_BADFORMAT, "Improper format of realm translation file"
+
+error_code KRB5_LNAME_CANTOPEN, "Can't open/find lname translation database"
+error_code KRB5_LNAME_NOTRANS, "No translation available for requested principal"
+error_code KRB5_LNAME_BADFORMAT, "Improper format of translation database entry"
+
+error_code KRB5_CRYPTO_INTERNAL, "Cryptosystem internal error"
+
+error_code KRB5_KT_BADNAME, "Key table name malformed"
+error_code KRB5_KT_UNKNOWN_TYPE, "Unknown Key table type"
+error_code KRB5_KT_NOTFOUND, "Key table entry not found"
+error_code KRB5_KT_END, "End of key table reached"
+error_code KRB5_KT_NOWRITE, "Cannot write to specified key table"
+error_code KRB5_KT_IOERR, "Error writing to key table"
+
+error_code KRB5_NO_TKT_IN_RLM, "Cannot find ticket for requested realm"
+error_code KRB5DES_BAD_KEYPAR, "DES key has bad parity"
+error_code KRB5DES_WEAK_KEY, "DES key is a weak key"
+
+error_code KRB5_BAD_ENCTYPE, "Bad encryption type"
+error_code KRB5_BAD_KEYSIZE, "Key size is incompatible with encryption type"
+error_code KRB5_BAD_MSIZE, "Message size is incompatible with encryption type"
+
+error_code KRB5_CC_TYPE_EXISTS, "Credentials cache type is already registered."
+error_code KRB5_KT_TYPE_EXISTS, "Key table type is already registered."
+
+error_code KRB5_CC_IO, "Credentials cache I/O operation failed XXX"
+error_code KRB5_FCC_PERM, "Credentials cache file permissions incorrect"
+error_code KRB5_FCC_NOFILE, "No credentials cache file found"
+error_code KRB5_FCC_INTERNAL, "Internal file credentials cache error"
+error_code KRB5_CC_WRITE, "Error writing to credentials cache file"
+error_code KRB5_CC_NOMEM, "No more memory to allocate (in credentials cache code)"
+error_code KRB5_CC_FORMAT, "Bad format in credentials cache"
+
+# errors for dual tgt library calls
+error_code KRB5_INVALID_FLAGS, "Invalid KDC option combination (library internal error)"
+error_code KRB5_NO_2ND_TKT, "Request missing second ticket"
+
+error_code KRB5_NOCREDS_SUPPLIED, "No credentials supplied to library routine"
+
+# errors for sendauth (and recvauth)
+
+error_code KRB5_SENDAUTH_BADAUTHVERS, "Bad sendauth version was sent"
+error_code KRB5_SENDAUTH_BADAPPLVERS, "Bad application version was sent (via sendauth)"
+error_code KRB5_SENDAUTH_BADRESPONSE, "Bad response (during sendauth exchange)"
+error_code KRB5_SENDAUTH_REJECTED, "Server rejected authentication (during sendauth exchange)"
+
+# errors for preauthentication
+
+error_code KRB5_PREAUTH_BAD_TYPE, "Unsupported preauthentication type"
+error_code KRB5_PREAUTH_NO_KEY, "Required preauthentication key not supplied"
+error_code KRB5_PREAUTH_FAILED, "Generic preauthentication failure"
+
+# version number errors
+
+error_code KRB5_RCACHE_BADVNO, "Unsupported replay cache format version number"
+error_code KRB5_CCACHE_BADVNO, "Unsupported credentials cache format version number"
+error_code KRB5_KEYTAB_BADVNO, "Unsupported key table format version number"
+
+#
+#
+
+error_code KRB5_PROG_ATYPE_NOSUPP, "Program lacks support for address type"
+error_code KRB5_RC_REQUIRED, "Message replay detection requires rcache parameter"
+error_code KRB5_ERR_BAD_HOSTNAME, "Hostname cannot be canonicalized"
+error_code KRB5_ERR_HOST_REALM_UNKNOWN, "Cannot determine realm for host"
+error_code KRB5_SNAME_UNSUPP_NAMETYPE, "Conversion to service principal undefined for name type"
+
+error_code KRB5KRB_AP_ERR_V4_REPLY, "Initial Ticket response appears to be Version 4"
+error_code KRB5_REALM_CANT_RESOLVE, "Cannot resolve KDC for requested realm"
+error_code KRB5_TKT_NOT_FORWARDABLE, "Requesting ticket can't get forwardable tickets"
+error_code KRB5_FWD_BAD_PRINCIPAL, "Bad principal name while trying to forward credentials"
+
+error_code KRB5_GET_IN_TKT_LOOP, "Looping detected inside krb5_get_in_tkt"
+error_code KRB5_CONFIG_NODEFREALM, "Configuration file does not specify default realm"
+
+error_code KRB5_SAM_UNSUPPORTED, "Bad SAM flags in obtain_sam_padata"
+error_code KRB5_KT_NAME_TOOLONG, "Keytab name too long"
+
+end
diff --git a/crypto/heimdal/lib/krb5/krb5_free_principal.3 b/crypto/heimdal/lib/krb5/krb5_free_principal.3
new file mode 100644
index 0000000..ba5888a
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_free_principal.3
@@ -0,0 +1,30 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_free_principal.3,v 1.1 1997/08/14 00:03:17 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_FREE_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_free_principal
+.Nd Principal free function
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft void
+.Fn krb5_free_principal "krb5_context context" "krb5_principal principal"
+
+.Sh DESCRIPTION
+
+The
+.Fn krb5_free_principal
+will free a principal that has been created with
+.Fn krb5_build_principal ,
+.Fn krb5_parse_name ,
+or with some other function.
+
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_locl.h b/crypto/heimdal/lib/krb5/krb5_locl.h
new file mode 100644
index 0000000..b7093b1
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_locl.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: krb5_locl.h,v 1.63 1999/12/02 17:05:11 joda Exp $ */
+
+#ifndef __KRB5_LOCL_H__
+#define __KRB5_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef _AIX
+struct ether_addr;
+struct mbuf;
+struct sockaddr_dl;
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+#include <roken.h>
+#include <parse_time.h>
+#include <base64.h>
+
+#include <des.h>
+#include <md4.h>
+#include <md5.h>
+#include <sha.h>
+#include <rc4.h>
+
+#include <asn1.h>
+#include <der.h>
+
+#include <krb5.h>
+#include <krb5_err.h>
+#include <asn1_err.h>
+#include <krb5-private.h>
+
+#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
+#define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
+
+/* should this be public? */
+#define KEYTAB_DEFAULT "FILE:/etc/krb5.keytab"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#endif /* __KRB5_LOCL_H__ */
diff --git a/crypto/heimdal/lib/krb5/krb5_openlog.3 b/crypto/heimdal/lib/krb5/krb5_openlog.3
new file mode 100644
index 0000000..87040ba
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_openlog.3
@@ -0,0 +1,225 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_openlog.3,v 1.4 1999/04/07 14:06:32 joda Exp $
+.Dd August 6, 1997
+.Dt KRB5_OPENLOG 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_initlog ,
+.Nm krb5_openlog ,
+.Nm krb5_closelog ,
+.Nm krb5_addlog_dest ,
+.Nm krb5_addlog_func ,
+.Nm krb5_log ,
+.Nm krb5_vlog ,
+.Nm krb5_log_msg ,
+.Nm krb5_vlog_msg
+.Nd Heimdal logging functions
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.\" ouch!
+.ds xx \\*(fP\fR(\fP\\*(lI*\\*(fP
+.ds xy \fR)\|\fP
+.Fn "\\*(lItypedef void \\*(xxkrb5_log_log_func_t\\*(xy" "const char *time" "const char *message" "void *data"
+.Fn "\\*(lItypedef void \\*(xxkrb5_log_close_func_t\\*(xy" "void *data"
+
+.Ft krb5_error_code
+.Fn krb5_addlog_dest "krb5_context context" "krb5_log_facility *facility" "const char *destination"
+
+.Ft krb5_error_code
+.Fn krb5_addlog_func "krb5_context context" "krb5_log_facility *facility" "int min" "int max" "krb5_log_log_func_t log" "krb5_log_close_func_t close" "void *data"
+
+.Ft krb5_error_code
+.Fn krb5_closelog "krb5_context context" "krb5_log_facility *facility"
+
+.Ft krb5_error_code
+.Fn krb5_initlog "krb5_context context" "const char *program" "krb5_log_facility **facility"
+
+.Ft krb5_error_code
+.Fn krb5_log "krb5_context context" "krb5_log_facility *facility" "int level" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_log_msg "krb5_context context" "krb5_log_facility *facility" "char **reply" "int level" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_openlog "krb5_context context" "const char *program" "krb5_log_facility **facility"
+
+.Ft krb5_error_code
+.Fn krb5_vlog "krb5_context context" "krb5_log_facility *facility" "int level" "const char *format" "va_list arglist"
+
+.Ft krb5_error_code
+.Fn krb5_vlog_msg "krb5_context context" "krb5_log_facility *facility" "char **reply" "int level" "const char *format" "va_list arglist"
+
+.Sh DESCRIPTION
+These functions logs messages to one or more destinations.
+.Pp
+The
+.Fn krb5_openlog
+function creates a logging
+.Fa facility ,
+that is used to log messages. A facility consists of one or more
+destinations (which can be files or syslog or some other device). The
+.Fa program
+parameter should be the generic name of the program that is doing the
+logging. This name is used to lookup which destinations to use. This
+information is contained in the
+.Li logging
+section of the
+.Pa krb5.conf
+configuration file. If no entry is found for
+.Fa program ,
+the entry for
+.Li default
+is used, or if that is missing too,
+.Li SYSLOG
+will be used as destination.
+.Pp
+To close a logging facility, use the
+.Fn krb5_closelog
+function.
+.Pp
+To log a message to a facility use one of the functions
+.Fn krb5_log ,
+.Fn krb5_log_msg ,
+.Fn krb5_vlog ,
+or
+.Fn krb5_vlog_msg .
+The functions ending in
+.Li _msg
+return in
+.Fa reply
+a pointer to the message that just got logged. This string is allocated,
+and should be freed with
+.Fn free .
+The
+.Fa format
+is a standard
+.Fn printf
+style format string (but see the BUGS section).
+.Pp
+
+If you want better control of where things gets logged, you can instead of using
+.Fn krb5_openlog
+call
+.Fn krb5_initlog ,
+which just initializes a facility, but doesn't define any actual logging
+destinations. You can then add destinations with the
+.Fn krb5_addlog_dest
+and
+.Fn krb5_addlog_func
+functions. The first of these takes a string specifying a logging
+destination, and adds this to the facility. If you want to do some
+non-standard logging you can use the
+.Fn krb5_addlog_func
+function, which takes a function to use when logging.
+The
+.Fa log
+function is called for each message with
+.Fa time
+being a string specifying the current time, and
+.Fa message
+the message to log.
+.Fa close
+is called when the facility is closed. You can pass application specific data in the
+.Fa data
+parameter. The
+.Fa min
+and
+.Fa max
+parameter are the same as in a destination (defined below). To specify a
+max of infinity, pass -1.
+.Pp
+.Fn krb5_openlog
+calls
+.Fn krb5_initlog
+and then calls
+.Fn krb5_addlog_dest
+for each destination found.
+
+.Ss Destinations
+
+The defined destinations (as specified in
+.Pa krb5.conf )
+follows:
+.Bl -tag -width "xxx" -offset indent
+.It Li STDERR
+This logs to the program's stderr.
+.It Li FILE: Ns Pa /file
+.It Li FILE= Ns Pa /file
+Log to the specified file. The form using a colon appends to the file, the
+form with an equal truncates the file. The truncating form keeps the file
+open, while the appending form closes it after each log message (which
+makes it possible to rotate logs). The truncating form is mainly for
+compatibility with the MIT libkrb5.
+.It Li DEVICE= Ns Pa /device
+This logs to the specified device, at present this is the same as
+.Li FILE:/device .
+.It Li CONSOLE
+Log to the console, this is the same as
+.Li DEVICE=/dev/console .
+.It Li SYSLOG Ns Op :priority Ns Op :facility
+Send messages to the syslog system, using priority, and facility. To
+get the name for one of these, you take the name of the macro passed
+to
+.Xr syslog 3 ,
+and remove the leading
+.Li LOG_
+.No ( Li LOG_NOTICE
+becomes
+.Li NOTICE ) .
+The default values (as well as the values used for unrecognised
+values), are
+.Li ERR ,
+and
+.Li AUTH ,
+respectively. See
+.Xr syslog 3
+for a list of priorities and facilities.
+.El
+.Pp
+Each destination may optionally be prepended with a range of logging
+levels, specified as
+.Li min-max/ .
+If the
+.Fa level
+parameter to
+.Fn krb5_log
+is within this range (inclusive) the message gets logged to this
+destination, otherwise not. Either of the min and max valued may be
+omitted, in this case min is assumed to be zero, and max is assumed to be
+infinity. If you don't include a dash, both min and max gets set to the
+specified value. If no range is specified, all messages gets logged.
+.Sh EXAMPLE
+.Bd -literal -offset indent
+[logging]
+ kdc = 0/FILE:/var/log/kdc.log
+ kdc = 1-/SYSLOG:INFO:USER
+ default = STDERR
+.Ed
+.Pp
+This will log all messages from the
+.Nm kdc
+program with level 0 to
+.Pa /var/log/kdc.log ,
+other messages will be logged to syslog with priority
+.Li LOG_INFO ,
+and facility
+.Li LOG_USER .
+All other programs will log all messages to their stderr.
+.Sh BUGS
+These functions use
+.Fn asprintf
+to format the message. If your operating system does not have a working
+.Fn asprintf ,
+a replacement will be used. At present this replacement does not handle
+some correct conversion specifications (like floating point numbers). Until
+this is fixed, the use of these conversions should be avoided.
+.Pp
+If logging is done to the syslog facility, these functions might not be
+thread-safe, depending on the implementation of
+.Fn openlog ,
+and
+.Fn syslog .
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr krb5.conf 5
diff --git a/crypto/heimdal/lib/krb5/krb5_parse_name.3 b/crypto/heimdal/lib/krb5/krb5_parse_name.3
new file mode 100644
index 0000000..db9236c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_parse_name.3
@@ -0,0 +1,39 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_parse_name.3,v 1.1 1997/08/14 00:03:17 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_PARSE_NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_parse_name
+.Nd String to principal conversion
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_parse_name "krb5_context context" "const char *name" "krb5_principal *principal"
+
+.Sh DESCRIPTION
+
+.Fn krb5_parse_name
+converts a string representation of a princpal name to
+.Nm krb5_principal .
+The
+.Fa principal
+will point to allocated data that should be freed with
+.Fn krb5_free_principal .
+.Pp
+The string should consist of one or more name components separated with slashes
+.Pq Dq / ,
+optionally followed with an
+.Dq @
+and a realm name. A slash or @ may be contained in a name component by
+quoting it with a back-slash
+.Pq Dq \ .
+A realm should not contain slashes or colons.
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_sname_to_principal 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_sname_to_principal.3 b/crypto/heimdal/lib/krb5/krb5_sname_to_principal.3
new file mode 100644
index 0000000..aea4150
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_sname_to_principal.3
@@ -0,0 +1,58 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_sname_to_principal.3,v 1.1 1997/08/14 00:03:18 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_PRINCIPAL 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_sname_to_principal ,
+.Nm krb5_sock_to_principal
+.Nd Create a service principal
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_sname_to_principal "krb5_context context" "const char *hostname" "const char *sname" "int32_t type" "krb5_principal *principal"
+
+.Ft krb5_error_code
+.Fn krb5_sock_to_principal "krb5_context context" "int socket" "const char *sname" "int32_t type" "krb5_principal *principal"
+
+.Sh DESCRIPTION
+
+These functions create a
+.Dq service
+principal that can, for instance, be used to lookup a key in a keytab. For both these function the
+.Fa sname
+parameter will be used for the first component of the created principal. If
+.Fa sname
+is
+.Dv NULL ,
+.Dq host
+will be used instead.
+.Fn krb5_sname_to_principal
+will use the passed
+.Fa hostname
+for the second component. If type
+.Dv KRB5_NT_SRV_HST
+this name will be looked up with
+.Fn gethostbyname .
+If
+.Fa hostname is
+.Dv NULL ,
+the local hostname will be used.
+.Pp
+.Fn krb5_sock_to_principal
+will use the
+.Dq sockname
+of the passed
+.Fa socket ,
+which should be a bound
+.Dv AF_INET
+socket.
+
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_unparse_name 3
diff --git a/crypto/heimdal/lib/krb5/krb5_unparse_name.3 b/crypto/heimdal/lib/krb5/krb5_unparse_name.3
new file mode 100644
index 0000000..13277d6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_unparse_name.3
@@ -0,0 +1,34 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_unparse_name.3,v 1.1 1997/08/14 00:03:19 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_UNPARSE_NAME 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_unparse_name
+.\" .Nm krb5_unparse_name_ext
+.Nd Principal to string conversion
+
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_unparse_name "krb5_context context" "krb5_principal principal" "char **name"
+
+.\" .Ft krb5_error_code
+.\" .Fn krb5_unparse_name_ext "krb5_context context" "krb5_const_principal principal" "char **name" "size_t *size"
+
+.Sh DESCRIPTION
+
+This function takes a
+.Fa principal ,
+and will convert in to a printable representation with the same syntax as decribed in
+.Xr krb5_parse_name 3 .
+.Fa *name
+will point to allocated data and should be freed by the caller.
+
+.Sh SEE ALSO
+.Xr krb5_425_conv_principal 3 ,
+.Xr krb5_build_principal 3 ,
+.Xr krb5_free_principal 3 ,
+.Xr krb5_parse_name 3 ,
+.Xr krb5_sname_to_principal 3
diff --git a/crypto/heimdal/lib/krb5/krb5_warn.3 b/crypto/heimdal/lib/krb5/krb5_warn.3
new file mode 100644
index 0000000..521da0e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krb5_warn.3
@@ -0,0 +1,73 @@
+.\" Copyright (c) 1997 Kungliga Tekniska Högskolan
+.\" $Id: krb5_warn.3,v 1.2 1997/08/08 03:45:55 joda Exp $
+.Dd August 8, 1997
+.Dt KRB5_WARN 3
+.Os HEIMDAL
+.Sh NAME
+.Nm krb5_warn ,
+.Nm krb5_warnx ,
+.Nm krb5_vwarn ,
+.Nm krb5_vwarnx ,
+.Nm krb5_err ,
+.Nm krb5_errx ,
+.Nm krb5_verr ,
+.Nm krb5_verrx ,
+.Nm krb5_set_warn_dest
+.Nd Heimdal warning and error functions
+.Sh SYNOPSIS
+.Fd #include <krb5.h>
+
+.Ft krb5_error_code
+.Fn krb5_err "krb5_context context" "int eval" "krb5_error_code code" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_errx "krb5_context context" "int eval" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_verr "krb5_context context" "int eval" "krb5_error_code code" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_verrx "krb5_context context" "int eval" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_vwarn "krb5_context context" "krb5_error_code code" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_vwarnx "krb5_context context" "const char *format" "va_list ap"
+
+.Ft krb5_error_code
+.Fn krb5_warn "krb5_context context" "krb5_error_code code" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_warnx "krb5_context context" "const char *format" "..."
+
+.Ft krb5_error_code
+.Fn krb5_set_warn_dest "krb5_context context" "krb5_log_facility *facility"
+
+.Sh DESCRIPTION
+
+These functions prints a warning message to some destination.
+.Fa format
+is a printf style format specifying the message to print. The forms not ending in an
+.Dq x
+prints the error string associated with
+.Fa code
+along with the message.
+The
+.Dq err
+functions exits with exit status
+.Fa eval
+after printing the message.
+.Pp
+The
+.Fn krb5_set_warn_func
+function sets the destination for warning messages to the specified
+.Fa facility .
+Messages logged with the
+.Dq warn
+functions have a log level of 1, while the
+.Dq err
+functions logs with level 0.
+
+.Sh SEE ALSO
+.Xr krb5_openlog 3
diff --git a/crypto/heimdal/lib/krb5/krbhst.c b/crypto/heimdal/lib/krb5/krbhst.c
new file mode 100644
index 0000000..8d5c4e4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/krbhst.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#include <resolve.h>
+
+RCSID("$Id: krbhst.c,v 1.23 1999/12/11 23:14:25 assar Exp $");
+
+/*
+ * assuming that `*res' contains `*count' strings, add a copy of `string'.
+ */
+
+static int
+add_string(char ***res, int *count, const char *string)
+{
+ char **tmp = realloc(*res, (*count + 1) * sizeof(**res));
+
+ if(tmp == NULL)
+ return ENOMEM;
+ *res = tmp;
+ if(string) {
+ tmp[*count] = strdup(string);
+ if(tmp[*count] == NULL)
+ return ENOMEM;
+ } else
+ tmp[*count] = NULL;
+ (*count)++;
+ return 0;
+}
+
+static krb5_error_code
+srv_find_realm(krb5_context context, char ***res, int *count,
+ const char *realm, const char *proto, const char *service)
+{
+ char domain[1024];
+ char alt_domain[1024];
+ krb5_error_code ret;
+ struct dns_reply *r;
+ struct resource_record *rr;
+
+ snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
+
+ r = dns_lookup(domain, "srv");
+ if(r == NULL && context->srv_try_rfc2052) {
+ snprintf(alt_domain, sizeof(alt_domain), "%s.%s.%s.",
+ service, proto, realm);
+ r = dns_lookup(alt_domain, "srv");
+ }
+ if(r == NULL && context->srv_try_txt)
+ r = dns_lookup(domain, "txt");
+ if(r == NULL && context->srv_try_rfc2052 && context->srv_try_txt)
+ r = dns_lookup(alt_domain, "txt");
+ if(r == NULL)
+ return 0;
+
+ for(rr = r->head; rr; rr = rr->next){
+ if(rr->type == T_SRV){
+ char buf[1024];
+ char **tmp;
+
+ tmp = realloc(*res, (*count + 1) * sizeof(**res));
+ if (tmp == NULL)
+ return ENOMEM;
+ *res = tmp;
+ snprintf (buf, sizeof(buf),
+ "%s/%s:%u",
+ proto,
+ rr->u.srv->target,
+ rr->u.srv->port);
+ ret = add_string(res, count, buf);
+ if(ret)
+ return ret;
+ }else if(rr->type == T_TXT) {
+ ret = add_string(res, count, rr->u.txt);
+ if(ret)
+ return ret;
+ }
+ }
+ dns_free_data(r);
+ return 0;
+}
+
+/*
+ * lookup the servers for realm `realm', looking for the config string
+ * `conf_string' in krb5.conf or for `serv_string' in SRV records.
+ * return a malloc-ed list of servers in hostlist.
+ */
+
+static krb5_error_code
+get_krbhst (krb5_context context,
+ const krb5_realm *realm,
+ const char *conf_string,
+ const char *serv_string,
+ char ***hostlist)
+{
+ char **res, **r;
+ int count;
+ krb5_error_code ret;
+
+ res = krb5_config_get_strings(context, NULL,
+ "realms", *realm, conf_string, NULL);
+ for(r = res, count = 0; r && *r; r++, count++);
+
+ if(context->srv_lookup) {
+ char *s[] = { "udp", "tcp", "http" }, **q;
+ for(q = s; q < s + sizeof(s) / sizeof(s[0]); q++) {
+ ret = srv_find_realm(context, &res, &count, *realm, *q,
+ serv_string);
+ if(ret) {
+ krb5_config_free_strings(res);
+ return ret;
+ }
+ }
+ }
+
+ if(count == 0) {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "kerberos.%s", *realm);
+ ret = add_string(&res, &count, buf);
+ if(ret) {
+ krb5_config_free_strings(res);
+ return ret;
+ }
+ }
+ add_string(&res, &count, NULL);
+ *hostlist = res;
+ return 0;
+}
+
+krb5_error_code
+krb5_get_krb_admin_hst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return get_krbhst (context, realm, "admin_server", "kerberos-adm",
+ hostlist);
+}
+
+krb5_error_code
+krb5_get_krb_changepw_hst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return get_krbhst (context, realm, "admin_server", "kpasswd",
+ hostlist);
+}
+
+krb5_error_code
+krb5_get_krbhst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return get_krbhst (context, realm, "kdc", "kerberos", hostlist);
+}
+
+krb5_error_code
+krb5_free_krbhst (krb5_context context,
+ char **hostlist)
+{
+ char **p;
+
+ for (p = hostlist; *p; ++p)
+ free (*p);
+ free (hostlist);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/kuserok.c b/crypto/heimdal/lib/krb5/kuserok.c
new file mode 100644
index 0000000..ae8ddec
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/kuserok.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: kuserok.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+
+/*
+ * Return TRUE iff `principal' is allowed to login as `luser'.
+ */
+
+krb5_boolean
+krb5_kuserok (krb5_context context,
+ krb5_principal principal,
+ const char *luser)
+{
+ char buf[BUFSIZ];
+ struct passwd *pwd;
+ FILE *f;
+ krb5_realm *realms, *r;
+ krb5_error_code ret;
+ krb5_boolean b;
+
+ ret = krb5_get_default_realms (context, &realms);
+ if (ret)
+ return FALSE;
+
+ for (r = realms; *r != NULL; ++r) {
+ krb5_principal local_principal;
+
+ ret = krb5_build_principal (context,
+ &local_principal,
+ strlen(*r),
+ *r,
+ luser,
+ NULL);
+ if (ret) {
+ krb5_free_host_realm (context, realms);
+ return FALSE;
+ }
+
+ b = krb5_principal_compare (context, principal, local_principal);
+ krb5_free_principal (context, local_principal);
+ if (b) {
+ krb5_free_host_realm (context, realms);
+ return TRUE;
+ }
+ }
+ krb5_free_host_realm (context, realms);
+
+ pwd = getpwnam (luser); /* XXX - Should use k_getpwnam? */
+ if (pwd == NULL)
+ return FALSE;
+ snprintf (buf, sizeof(buf), "%s/.k5login", pwd->pw_dir);
+ f = fopen (buf, "r");
+ if (f == NULL)
+ return FALSE;
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ krb5_principal tmp;
+
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+
+ ret = krb5_parse_name (context, buf, &tmp);
+ if (ret) {
+ fclose (f);
+ return FALSE;
+ }
+ b = krb5_principal_compare (context, principal, tmp);
+ krb5_free_principal (context, tmp);
+ if (b) {
+ fclose (f);
+ return TRUE;
+ }
+ }
+ fclose (f);
+ return FALSE;
+}
diff --git a/crypto/heimdal/lib/krb5/log.c b/crypto/heimdal/lib/krb5/log.c
new file mode 100644
index 0000000..e1511e2
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/log.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: log.c,v 1.21 1999/12/02 17:05:11 joda Exp $");
+
+struct facility {
+ int min;
+ int max;
+ krb5_log_log_func_t log;
+ krb5_log_close_func_t close;
+ void *data;
+};
+
+static struct facility*
+log_realloc(krb5_log_facility *f)
+{
+ struct facility *fp;
+ f->len++;
+ fp = realloc(f->val, f->len * sizeof(*f->val));
+ if(fp == NULL)
+ return NULL;
+ f->val = fp;
+ fp += f->len - 1;
+ return fp;
+}
+
+struct s2i{
+ char *s;
+ int val;
+};
+
+#define L(X) { #X, LOG_ ## X }
+
+struct s2i syslogvals[] = {
+ L(EMERG),
+ L(ALERT),
+ L(CRIT),
+ L(ERR),
+ L(WARNING),
+ L(NOTICE),
+ L(INFO),
+ L(DEBUG),
+
+ L(AUTH),
+#ifdef LOG_AUTHPRIV
+ L(AUTHPRIV),
+#endif
+#ifdef LOG_CRON
+ L(CRON),
+#endif
+ L(DAEMON),
+#ifdef LOG_FTP
+ L(FTP),
+#endif
+ L(KERN),
+ L(LPR),
+ L(MAIL),
+#ifdef LOG_NEWS
+ L(NEWS),
+#endif
+ L(SYSLOG),
+ L(USER),
+#ifdef LOG_UUCP
+ L(UUCP),
+#endif
+ L(LOCAL0),
+ L(LOCAL1),
+ L(LOCAL2),
+ L(LOCAL3),
+ L(LOCAL4),
+ L(LOCAL5),
+ L(LOCAL6),
+ L(LOCAL7),
+ { NULL, -1 }
+};
+
+static int
+find_value(const char *s, struct s2i *table)
+{
+ while(table->s && strcasecmp(table->s, s))
+ table++;
+ return table->val;
+}
+
+krb5_error_code
+krb5_initlog(krb5_context context,
+ const char *program,
+ krb5_log_facility **fac)
+{
+ krb5_log_facility *f = calloc(1, sizeof(*f));
+ if(f == NULL)
+ return ENOMEM;
+ f->program = strdup(program);
+ if(f->program == NULL){
+ free(f);
+ return ENOMEM;
+ }
+ *fac = f;
+ return 0;
+}
+
+krb5_error_code
+krb5_addlog_func(krb5_context context,
+ krb5_log_facility *fac,
+ int min,
+ int max,
+ krb5_log_log_func_t log,
+ krb5_log_close_func_t close,
+ void *data)
+{
+ struct facility *fp = log_realloc(fac);
+ if(fp == NULL)
+ return ENOMEM;
+ fp->min = min;
+ fp->max = max;
+ fp->log = log;
+ fp->close = close;
+ fp->data = data;
+ return 0;
+}
+
+
+struct syslog_data{
+ int priority;
+};
+
+static void
+log_syslog(const char *time,
+ const char *msg,
+ void *data)
+
+{
+ struct syslog_data *s = data;
+ syslog(s->priority, "%s", msg);
+}
+
+static void
+close_syslog(void *data)
+{
+ free(data);
+ closelog();
+}
+
+static krb5_error_code
+open_syslog(krb5_context context,
+ krb5_log_facility *facility, int min, int max,
+ const char *sev, const char *fac)
+{
+ struct syslog_data *sd = malloc(sizeof(*sd));
+ int i;
+
+ if(sd == NULL)
+ return ENOMEM;
+ i = find_value(sev, syslogvals);
+ if(i == -1)
+ i = LOG_ERR;
+ sd->priority = i;
+ i = find_value(fac, syslogvals);
+ if(i == -1)
+ i = LOG_AUTH;
+ sd->priority |= i;
+ roken_openlog(facility->program, LOG_PID | LOG_NDELAY, i);
+ return krb5_addlog_func(context, facility, min, max,
+ log_syslog, close_syslog, sd);
+}
+
+struct file_data{
+ char *filename;
+ char *mode;
+ FILE *fd;
+ int keep_open;
+};
+
+static void
+log_file(const char *time,
+ const char *msg,
+ void *data)
+{
+ struct file_data *f = data;
+ if(f->keep_open == 0)
+ f->fd = fopen(f->filename, f->mode);
+ if(f->fd == NULL)
+ return;
+ fprintf(f->fd, "%s %s\n", time, msg);
+ if(f->keep_open == 0)
+ fclose(f->fd);
+}
+
+static void
+close_file(void *data)
+{
+ struct file_data *f = data;
+ if(f->keep_open && f->filename)
+ fclose(f->fd);
+ free(data);
+}
+
+static krb5_error_code
+open_file(krb5_context context, krb5_log_facility *fac, int min, int max,
+ char *filename, char *mode, FILE *f, int keep_open)
+{
+ struct file_data *fd = malloc(sizeof(*fd));
+ if(fd == NULL)
+ return ENOMEM;
+ fd->filename = filename;
+ fd->mode = mode;
+ fd->fd = f;
+ fd->keep_open = keep_open;
+
+ return krb5_addlog_func(context, fac, min, max, log_file, close_file, fd);
+}
+
+
+
+krb5_error_code
+krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *p)
+{
+ krb5_error_code ret = 0;
+ int min = 0, max = -1, n;
+ char c;
+ n = sscanf(p, "%d%c%d/", &min, &c, &max);
+ if(n == 2){
+ if(c == '/') {
+ if(min < 0){
+ max = -min;
+ min = 0;
+ }else{
+ max = min;
+ }
+ }
+ }
+ if(n){
+ p = strchr(p, '/');
+ if(p == NULL) return HEIM_ERR_LOG_PARSE;
+ p++;
+ }
+ if(strcmp(p, "STDERR") == 0){
+ ret = open_file(context, f, min, max, NULL, NULL, stderr, 1);
+ }else if(strcmp(p, "CONSOLE") == 0){
+ ret = open_file(context, f, min, max, "/dev/console", "w", NULL, 0);
+ }else if(strncmp(p, "FILE:", 4) == 0 && (p[4] == ':' || p[4] == '=')){
+ char *fn;
+ FILE *file = NULL;
+ int keep_open = 0;
+ fn = strdup(p + 5);
+ if(fn == NULL)
+ return ENOMEM;
+ if(p[4] == '='){
+ int i = open(fn, O_WRONLY | O_CREAT |
+ O_TRUNC | O_APPEND, 0666);
+ if(i < 0)
+ return errno;
+ file = fdopen(i, "a");
+ if(file == NULL){
+ close(i);
+ return errno;
+ }
+ keep_open = 1;
+ }
+ ret = open_file(context, f, min, max, fn, "a", file, keep_open);
+ }else if(strncmp(p, "DEVICE=", 6) == 0){
+ ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, 0);
+ }else if(strncmp(p, "SYSLOG", 6) == 0){
+ char *severity;
+ char *facility;
+ severity = strchr(p, ':');
+ if(severity == NULL)
+ severity = "ERR";
+ facility = strchr(severity, ':');
+ if(facility == NULL)
+ facility = "AUTH";
+ ret = open_syslog(context, f, min, max, severity, facility);
+ }else{
+ ret = HEIM_ERR_LOG_PARSE; /* XXX */
+ }
+ return ret;
+}
+
+
+krb5_error_code
+krb5_openlog(krb5_context context,
+ const char *program,
+ krb5_log_facility **fac)
+{
+ krb5_error_code ret;
+ char **p, **q;
+
+ ret = krb5_initlog(context, program, fac);
+ if(ret)
+ return ret;
+
+ p = krb5_config_get_strings(context, NULL, "logging", program, NULL);
+ if(p == NULL)
+ p = krb5_config_get_strings(context, NULL, "logging", "default", NULL);
+ if(p){
+ for(q = p; *q; q++)
+ ret = krb5_addlog_dest(context, *fac, *q);
+ krb5_config_free_strings(p);
+ }else
+ ret = krb5_addlog_dest(context, *fac, "SYSLOG");
+ return 0;
+}
+
+krb5_error_code
+krb5_closelog(krb5_context context,
+ krb5_log_facility *fac)
+{
+ int i;
+ for(i = 0; i < fac->len; i++)
+ (*fac->val[i].close)(&fac->val[i].data);
+ return 0;
+}
+
+#undef __attribute__
+#define __attribute__(X)
+
+krb5_error_code
+krb5_vlog_msg(krb5_context context,
+ krb5_log_facility *fac,
+ char **reply,
+ int level,
+ const char *fmt,
+ va_list ap)
+ __attribute__((format (printf, 5, 0)))
+{
+ char *msg;
+ char buf[64];
+ time_t t;
+ int i;
+
+ vasprintf(&msg, fmt, ap);
+ t = time(NULL);
+ strftime(buf, sizeof(buf), context->time_fmt,
+ context->log_utc ? gmtime(&t) : localtime(&t));
+ for(i = 0; i < fac->len; i++)
+ if(fac->val[i].min <= level &&
+ (fac->val[i].max < 0 || fac->val[i].max >= level))
+ (*fac->val[i].log)(buf, msg, fac->val[i].data);
+ *reply = msg;
+ return 0;
+}
+
+krb5_error_code
+krb5_vlog(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ va_list ap)
+ __attribute__((format (printf, 4, 0)))
+{
+ char *msg;
+ krb5_error_code ret;
+
+ ret = krb5_vlog_msg(context, fac, &msg, level, fmt, ap);
+ free(msg);
+ return ret;
+}
+
+krb5_error_code
+krb5_log_msg(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ char **reply,
+ const char *fmt,
+ ...)
+ __attribute__((format (printf, 5, 6)))
+{
+ va_list ap;
+ krb5_error_code ret;
+
+ va_start(ap, fmt);
+ ret = krb5_vlog_msg(context, fac, reply, level, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+krb5_error_code
+krb5_log(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ ...)
+ __attribute__((format (printf, 4, 5)))
+{
+ va_list ap;
+ krb5_error_code ret;
+
+ va_start(ap, fmt);
+ ret = krb5_vlog(context, fac, level, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
diff --git a/crypto/heimdal/lib/krb5/mcache.c b/crypto/heimdal/lib/krb5/mcache.c
new file mode 100644
index 0000000..d45deea
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mcache.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: mcache.c,v 1.10 1999/12/02 17:05:11 joda Exp $");
+
+typedef struct krb5_mcache {
+ krb5_principal primary_principal;
+ struct link {
+ krb5_creds cred;
+ struct link *next;
+ } *creds;
+} krb5_mcache;
+
+#define MCC_CURSOR(C) ((struct link*)(C))
+
+static char*
+mcc_get_name(krb5_context context,
+ krb5_ccache id)
+{
+ return ""; /* XXX */
+}
+
+static krb5_error_code
+mcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
+{
+ krb5_abortx(context, "unimplemented mcc_resolve called");
+}
+
+static krb5_error_code
+mcc_gen_new(krb5_context context, krb5_ccache *id)
+{
+ krb5_mcache *m;
+
+ m = malloc (sizeof(*m));
+ if (m == NULL)
+ return KRB5_CC_NOMEM;
+ m->primary_principal = NULL;
+ m->creds = NULL;
+ (*id)->data.data = m;
+ (*id)->data.length = sizeof(*m);
+ return 0;
+}
+
+static krb5_error_code
+mcc_initialize(krb5_context context,
+ krb5_ccache id,
+ krb5_principal primary_principal)
+{
+ krb5_error_code ret;
+ krb5_mcache *m;
+
+ m = (krb5_mcache *)id->data.data;
+
+ ret = krb5_copy_principal (context,
+ primary_principal,
+ &m->primary_principal);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+static krb5_error_code
+mcc_close(krb5_context context,
+ krb5_ccache id)
+{
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+ struct link *l;
+
+ krb5_free_principal (context, m->primary_principal);
+ l = m->creds;
+ while (l != NULL) {
+ struct link *old;
+
+ krb5_free_creds_contents (context, &l->cred);
+ old = l;
+ l = l->next;
+ free (old);
+ }
+ krb5_data_free(&id->data);
+ return 0;
+}
+
+static krb5_error_code
+mcc_destroy(krb5_context context,
+ krb5_ccache id)
+{
+ return 0;
+}
+
+static krb5_error_code
+mcc_store_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_creds *creds)
+{
+ krb5_error_code ret;
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+ struct link *l;
+
+ l = malloc (sizeof(*l));
+ if (l == NULL)
+ return KRB5_CC_NOMEM;
+ l->next = m->creds;
+ m->creds = l;
+ memset (&l->cred, 0, sizeof(l->cred));
+ ret = krb5_copy_creds_contents (context, creds, &l->cred);
+ if (ret) {
+ m->creds = l->next;
+ free (l);
+ return ret;
+ }
+ return 0;
+}
+
+static krb5_error_code
+mcc_get_principal(krb5_context context,
+ krb5_ccache id,
+ krb5_principal *principal)
+{
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+
+ return krb5_copy_principal (context,
+ m->primary_principal,
+ principal);
+}
+
+static krb5_error_code
+mcc_get_first (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ krb5_mcache *m = (krb5_mcache *)id->data.data;
+ *cursor = m->creds;
+ return 0;
+}
+
+static krb5_error_code
+mcc_get_next (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor,
+ krb5_creds *creds)
+{
+ struct link *l;
+
+ l = *cursor;
+ if (l != NULL) {
+ *cursor = l->next;
+ return krb5_copy_creds_contents (context,
+ &l->cred,
+ creds);
+ } else
+ return KRB5_CC_END;
+}
+
+static krb5_error_code
+mcc_end_get (krb5_context context,
+ krb5_ccache id,
+ krb5_cc_cursor *cursor)
+{
+ return 0;
+}
+
+static krb5_error_code
+mcc_remove_cred(krb5_context context,
+ krb5_ccache id,
+ krb5_flags which,
+ krb5_creds *cred)
+{
+ return 0; /* XXX */
+}
+
+static krb5_error_code
+mcc_set_flags(krb5_context context,
+ krb5_ccache id,
+ krb5_flags flags)
+{
+ return 0; /* XXX */
+}
+
+const krb5_cc_ops krb5_mcc_ops = {
+ "MEMORY",
+ mcc_get_name,
+ mcc_resolve,
+ mcc_gen_new,
+ mcc_initialize,
+ mcc_destroy,
+ mcc_close,
+ mcc_store_cred,
+ NULL, /* mcc_retrieve */
+ mcc_get_principal,
+ mcc_get_first,
+ mcc_get_next,
+ mcc_end_get,
+ mcc_remove_cred,
+ mcc_set_flags
+};
diff --git a/crypto/heimdal/lib/krb5/misc.c b/crypto/heimdal/lib/krb5/misc.c
new file mode 100644
index 0000000..baf63f6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/misc.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: misc.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
diff --git a/crypto/heimdal/lib/krb5/mk_error.c b/crypto/heimdal/lib/krb5/mk_error.c
new file mode 100644
index 0000000..2b173db
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_error.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: mk_error.c,v 1.14 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_error(krb5_context context,
+ krb5_error_code error_code,
+ const char *e_text,
+ const krb5_data *e_data,
+ const krb5_principal client,
+ const krb5_principal server,
+ time_t ctime,
+ krb5_data *reply)
+{
+ KRB_ERROR msg;
+ u_char *buf;
+ size_t buf_size;
+ int32_t sec, usec;
+ size_t len;
+ krb5_error_code ret = 0;
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.pvno = 5;
+ msg.msg_type = krb_error;
+ msg.stime = sec;
+ msg.susec = usec;
+ if(ctime) {
+ msg.ctime = &ctime;
+ }
+ /* Make sure we only send `protocol' error codes */
+ if(error_code < KRB5KDC_ERR_NONE || error_code >= KRB5_ERR_RCSID) {
+ if(e_text == NULL)
+ e_text = krb5_get_err_text(context, error_code);
+ error_code = KRB5KRB_ERR_GENERIC;
+ }
+ msg.error_code = error_code - KRB5KDC_ERR_NONE;
+ if (e_text)
+ msg.e_text = (general_string*)&e_text;
+ if (e_data)
+ msg.e_data = (octet_string*)e_data;
+ if(server){
+ msg.realm = server->realm;
+ msg.sname = server->name;
+ }else{
+ msg.realm = "<unspecified realm>";
+ }
+ if(client){
+ msg.crealm = &client->realm;
+ msg.cname = &client->name;
+ }
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL)
+ return ENOMEM;
+
+ do {
+ ret = encode_KRB_ERROR(buf + buf_size - 1,
+ buf_size,
+ &msg,
+ &len);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ buf = tmp;
+ } else {
+ goto out;
+ }
+ }
+ } while (ret == ASN1_OVERFLOW);
+
+ reply->length = len;
+ reply->data = malloc(len);
+ if (reply->data == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ memcpy (reply->data, buf + buf_size - len, len);
+out:
+ free (buf);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/mk_priv.c b/crypto/heimdal/lib/krb5/mk_priv.c
new file mode 100644
index 0000000..1ee2bed
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_priv.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_priv.c,v 1.25 1999/12/02 17:05:11 joda Exp $");
+
+/*
+ *
+ */
+
+krb5_error_code
+krb5_mk_priv(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_PRIV s;
+ EncKrbPrivPart part;
+ u_char *buf;
+ size_t buf_size;
+ size_t len;
+ int tmp_seq;
+ krb5_keyblock *key;
+ int32_t sec, usec;
+ KerberosTime sec2;
+ int usec2;
+ krb5_crypto crypto;
+
+ /* XXX - Is this right? */
+
+ if (auth_context->local_subkey)
+ key = auth_context->local_subkey;
+ else if (auth_context->remote_subkey)
+ key = auth_context->remote_subkey;
+ else
+ key = auth_context->keyblock;
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ part.user_data = *userdata;
+ sec2 = sec;
+ part.timestamp = &sec2;
+ usec2 = usec;
+ part.usec = &usec2;
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ tmp_seq = ++auth_context->local_seqnumber;
+ part.seq_number = &tmp_seq;
+ } else {
+ part.seq_number = NULL;
+ }
+
+ part.s_address = auth_context->local_address;
+ part.r_address = auth_context->remote_address;
+
+ buf_size = 1024;
+ buf = malloc (buf_size);
+ if (buf == NULL)
+ return ENOMEM;
+
+ krb5_data_zero (&s.enc_part.cipher);
+
+ do {
+ ret = encode_EncKrbPrivPart (buf + buf_size - 1, buf_size,
+ &part, &len);
+ if (ret) {
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ buf = tmp;
+ } else {
+ goto fail;
+ }
+ }
+ } while(ret == ASN1_OVERFLOW);
+
+ s.pvno = 5;
+ s.msg_type = krb_priv;
+ s.enc_part.etype = key->keytype;
+ s.enc_part.kvno = NULL;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_encrypt (context,
+ crypto,
+ KRB5_KU_KRB_PRIV,
+ buf + buf_size - len,
+ len,
+ &s.enc_part.cipher);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free(buf);
+ return ret;
+ }
+
+ do {
+ ret = encode_KRB_PRIV (buf + buf_size - 1, buf_size, &s, &len);
+
+ if (ret){
+ if (ret == ASN1_OVERFLOW) {
+ u_char *tmp;
+
+ buf_size *= 2;
+ tmp = realloc (buf, buf_size);
+ if (tmp == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ buf = tmp;
+ } else {
+ goto fail;
+ }
+ }
+ } while(ret == ASN1_OVERFLOW);
+ krb5_data_free (&s.enc_part.cipher);
+
+ outbuf->length = len;
+ outbuf->data = malloc (len);
+ if (outbuf->data == NULL) {
+ free(buf);
+ return ENOMEM;
+ }
+ memcpy (outbuf->data, buf + buf_size - len, len);
+ free (buf);
+ return 0;
+
+fail:
+ free (buf);
+ krb5_data_free (&s.enc_part.cipher);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/mk_rep.c b/crypto/heimdal/lib/krb5/mk_rep.c
new file mode 100644
index 0000000..060be03
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_rep.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_rep.c,v 1.16 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_rep(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_data *outbuf)
+{
+ krb5_error_code ret;
+ AP_REP ap;
+ EncAPRepPart body;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ krb5_crypto crypto;
+
+ ap.pvno = 5;
+ ap.msg_type = krb_ap_rep;
+
+ memset (&body, 0, sizeof(body));
+
+ body.ctime = (*auth_context)->authenticator->ctime;
+ body.cusec = (*auth_context)->authenticator->cusec;
+ body.subkey = NULL;
+ if ((*auth_context)->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ krb5_generate_seq_number (context,
+ (*auth_context)->keyblock,
+ &(*auth_context)->local_seqnumber);
+ body.seq_number = malloc (sizeof(*body.seq_number));
+ if (body.seq_number == NULL)
+ return ENOMEM;
+ *(body.seq_number) = (*auth_context)->local_seqnumber;
+ } else
+ body.seq_number = NULL;
+
+ ap.enc_part.etype = (*auth_context)->keyblock->keytype;
+ ap.enc_part.kvno = NULL;
+
+ buf_size = length_EncAPRepPart(&body);
+ buf = malloc (buf_size);
+ if (buf == NULL) {
+ free_EncAPRepPart (&body);
+ return ENOMEM;
+ }
+
+ ret = krb5_encode_EncAPRepPart (context,
+ buf + buf_size - 1,
+ buf_size,
+ &body,
+ &len);
+
+ free_EncAPRepPart (&body);
+ krb5_crypto_init(context, (*auth_context)->keyblock,
+ 0 /* ap.enc_part.etype */, &crypto);
+ ret = krb5_encrypt (context,
+ crypto,
+ KRB5_KU_AP_REQ_ENC_PART,
+ buf + buf_size - len,
+ len,
+ &ap.enc_part.cipher);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free(buf);
+ return ret;
+ }
+
+ buf_size = length_AP_REP(&ap);
+ buf = realloc(buf, buf_size);
+ if(buf == NULL) {
+ free_AP_REP (&ap);
+ return ENOMEM;
+ }
+ ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len);
+
+ free_AP_REP (&ap);
+
+ if(len != buf_size)
+ krb5_abortx(context, "krb5_mk_rep: encoded length != calculated length");
+ outbuf->data = buf;
+ outbuf->length = len;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/mk_req.c b/crypto/heimdal/lib/krb5/mk_req.c
new file mode 100644
index 0000000..e92d326
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_req.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_req.c,v 1.18 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ char *service,
+ char *hostname,
+ krb5_data *in_data,
+ krb5_ccache ccache,
+ krb5_data *outbuf)
+{
+ krb5_error_code r;
+ krb5_creds this_cred, *cred;
+ char **realms;
+ krb5_data realm_data;
+ char *real_hostname;
+
+ memset(&this_cred, 0, sizeof(this_cred));
+
+ r = krb5_cc_get_principal(context, ccache, &this_cred.client);
+
+ if(r)
+ return r;
+
+ r = krb5_expand_hostname (context, hostname, &real_hostname);
+ if (r) {
+ krb5_free_principal (context, this_cred.client);
+ return r;
+ }
+
+ r = krb5_get_host_realm(context, real_hostname, &realms);
+ if (r) {
+ krb5_free_principal (context, this_cred.client);
+ return r;
+ }
+ realm_data.length = strlen(*realms);
+ realm_data.data = *realms;
+
+ r = krb5_build_principal (context, &this_cred.server,
+ strlen(*realms),
+ *realms,
+ service,
+ real_hostname,
+ NULL);
+ free (real_hostname);
+ krb5_free_host_realm (context, realms);
+
+ if (r) {
+ krb5_free_principal (context, this_cred.client);
+ return r;
+ }
+ this_cred.times.endtime = 0;
+ if (auth_context && *auth_context && (*auth_context)->keytype)
+ this_cred.session.keytype = (*auth_context)->keytype;
+
+ r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
+ if (r)
+ return r;
+
+ return krb5_mk_req_extended (context,
+ auth_context,
+ ap_req_options,
+ in_data,
+ cred,
+ outbuf);
+}
diff --git a/crypto/heimdal/lib/krb5/mk_req_ext.c b/crypto/heimdal/lib/krb5/mk_req_ext.c
new file mode 100644
index 0000000..2b7b886
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_req_ext.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_req_ext.c,v 1.21 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_req_internal(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf,
+ krb5_key_usage usage)
+{
+ krb5_error_code ret;
+ krb5_data authenticator;
+ Checksum c;
+ Checksum *c_opt;
+ krb5_auth_context ac;
+
+ if(auth_context) {
+ if(*auth_context == NULL)
+ ret = krb5_auth_con_init(context, auth_context);
+ else
+ ret = 0;
+ ac = *auth_context;
+ } else
+ ret = krb5_auth_con_init(context, &ac);
+ if(ret)
+ return ret;
+
+#if 0
+ {
+ /* This is somewhat bogus since we're possibly overwriting a
+ value specified by the user, but it's the easiest way to make
+ the code use a compatible enctype */
+ Ticket ticket;
+ krb5_keytype ticket_keytype;
+
+ ret = decode_Ticket(in_creds->ticket.data,
+ in_creds->ticket.length,
+ &ticket,
+ NULL);
+ krb5_enctype_to_keytype (context,
+ ticket.enc_part.etype,
+ &ticket_keytype);
+
+ if (ticket_keytype == in_creds->session.keytype)
+ krb5_auth_setenctype(context,
+ ac,
+ ticket.enc_part.etype);
+ free_Ticket(&ticket);
+ }
+#endif
+
+ krb5_free_keyblock(context, ac->keyblock);
+ krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock);
+
+ if (in_data) {
+ if(ac->keyblock->keytype == ETYPE_DES_CBC_CRC) {
+ /* this is to make DCE secd (and older MIT kdcs?) happy */
+ ret = krb5_create_checksum(context,
+ NULL,
+ CKSUMTYPE_RSA_MD4,
+ in_data->data,
+ in_data->length,
+ &c);
+ } else {
+ krb5_crypto crypto;
+ krb5_crypto_init(context, ac->keyblock, 0, &crypto);
+ ret = krb5_create_checksum(context,
+ crypto,
+ usage,
+ in_data->data,
+ in_data->length,
+ &c);
+
+ krb5_crypto_destroy(context, crypto);
+ }
+ c_opt = &c;
+ } else {
+ c_opt = NULL;
+ }
+
+ ret = krb5_build_authenticator (context,
+ ac,
+ ac->keyblock->keytype,
+ in_creds,
+ c_opt,
+ NULL,
+ &authenticator);
+ if (c_opt)
+ free_Checksum (c_opt);
+ if (ret)
+ return ret;
+
+ ret = krb5_build_ap_req (context, ac->keyblock->keytype,
+ in_creds, ap_req_options, authenticator, outbuf);
+ if(auth_context == NULL)
+ krb5_auth_con_free(context, ac);
+ return ret;
+}
+
+krb5_error_code
+krb5_mk_req_extended(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_data *outbuf)
+{
+ return krb5_mk_req_internal (context,
+ auth_context,
+ ap_req_options,
+ in_data,
+ in_creds,
+ outbuf,
+ KRB5_KU_AP_REQ_AUTH_CKSUM);
+}
diff --git a/crypto/heimdal/lib/krb5/mk_safe.c b/crypto/heimdal/lib/krb5/mk_safe.c
new file mode 100644
index 0000000..4d848a6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/mk_safe.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: mk_safe.c,v 1.20 1999/12/02 17:05:11 joda Exp $");
+
+krb5_error_code
+krb5_mk_safe(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *userdata,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_SAFE s;
+ int32_t sec, usec;
+ KerberosTime sec2;
+ int usec2;
+ u_char *buf = NULL;
+ size_t buf_size;
+ size_t len;
+ int tmp_seq;
+ krb5_crypto crypto;
+
+ s.pvno = 5;
+ s.msg_type = krb_safe;
+
+ s.safe_body.user_data = *userdata;
+ krb5_us_timeofday (context, &sec, &usec);
+
+ sec2 = sec;
+ s.safe_body.timestamp = &sec2;
+ usec2 = usec2;
+ s.safe_body.usec = &usec2;
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ tmp_seq = ++auth_context->local_seqnumber;
+ s.safe_body.seq_number = &tmp_seq;
+ } else
+ s.safe_body.seq_number = NULL;
+
+ s.safe_body.s_address = auth_context->local_address;
+ s.safe_body.r_address = auth_context->remote_address;
+
+ s.cksum.cksumtype = 0;
+ s.cksum.checksum.data = NULL;
+ s.cksum.checksum.length = 0;
+
+
+ buf_size = length_KRB_SAFE(&s);
+ buf = malloc(buf_size + 128); /* add some for checksum */
+ if(buf == NULL)
+ return ENOMEM;
+ ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
+ ret = krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
+ ret = krb5_create_checksum(context,
+ crypto,
+ KRB5_KU_KRB_SAFE_CKSUM,
+ buf + buf_size - len,
+ len,
+ &s.cksum);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free (buf);
+ return ret;
+ }
+
+ buf_size = length_KRB_SAFE(&s);
+ buf = realloc(buf, buf_size);
+ if(buf == NULL)
+ return ENOMEM;
+
+ ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
+ free_Checksum (&s.cksum);
+
+ outbuf->length = len;
+ outbuf->data = malloc (len);
+ if (outbuf->data == NULL) {
+ free (buf);
+ return ENOMEM;
+ }
+ memcpy (outbuf->data, buf + buf_size - len, len);
+ free (buf);
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/n-fold-test.c b/crypto/heimdal/lib/krb5/n-fold-test.c
new file mode 100644
index 0000000..814dc6f
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/n-fold-test.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: n-fold-test.c,v 1.3 1999/07/22 11:45:33 assar Exp $");
+
+enum { MAXSIZE = 24 };
+
+static struct testcase {
+ const char *str;
+ unsigned n;
+ unsigned char res[MAXSIZE];
+} tests[] = {
+ {"012345", 8,
+ {0xbe, 0x07, 0x26, 0x31, 0x27, 0x6b, 0x19, 0x55}
+ },
+ {"basch", 24,
+ {0x1a, 0xab, 0x6b, 0x42, 0x96, 0x4b, 0x98, 0xb2, 0x1f, 0x8c, 0xde,
+ 0x2d, 0x24, 0x48, 0xba, 0x34, 0x55, 0xd7, 0x86, 0x2c, 0x97, 0x31,
+ 0x64, 0x3f}
+ },
+ {"eichin", 24,
+ {0x65, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x4b, 0x73, 0x2b, 0x4b,
+ 0x1b, 0x43, 0xda, 0x1a, 0x5b, 0x99, 0x5a, 0x58, 0xd2, 0xc6, 0xd0,
+ 0xd2, 0xdc, 0xca}
+ },
+ {"sommerfeld", 24,
+ {0x2f, 0x7a, 0x98, 0x55, 0x7c, 0x6e, 0xe4, 0xab, 0xad, 0xf4,
+ 0xe7, 0x11, 0x92, 0xdd, 0x44, 0x2b, 0xd4, 0xff, 0x53, 0x25, 0xa5,
+ 0xde, 0xf7, 0x5c}
+ },
+ {"MASSACHVSETTS INSTITVTE OF TECHNOLOGY", 24,
+ {0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, 0x32, 0x82,
+ 0xb3, 0x08, 0xa5, 0x08, 0x41, 0x22, 0x9a, 0xd7, 0x98, 0xfa, 0xb9,
+ 0x54, 0x0c, 0x1b}
+ },
+ {"assar@NADA.KTH.SE", 24,
+ {0x5c, 0x06, 0xc3, 0x4d, 0x2c, 0x89, 0x05, 0xbe, 0x7a, 0x51,
+ 0x83, 0x6c, 0xd6, 0xf8, 0x1c, 0x4b, 0x7a, 0x93, 0x49, 0x16, 0x5a,
+ 0xb3, 0xfa, 0xa9}
+ },
+ {"testKRBTEST.MIT.EDUtestkey", 24,
+ {0x50, 0x2c, 0xf8, 0x29, 0x78, 0xe5, 0xfb, 0x1a, 0x29, 0x06,
+ 0xbd, 0x22, 0x28, 0x91, 0x56, 0xc0, 0x06, 0xa0, 0xdc, 0xf5, 0xb6,
+ 0xc2, 0xda, 0x6c}
+ },
+ {NULL, 0}
+};
+
+int
+main(int argc, char **argv)
+{
+ unsigned char data[MAXSIZE];
+ struct testcase *t;
+ int ret = 0;
+
+ for (t = tests; t->str; ++t) {
+ int i;
+
+ _krb5_n_fold (t->str, strlen(t->str), data, t->n);
+ if (memcmp (data, t->res, t->n) != 0) {
+ printf ("n-fold(\"%s\", %d) failed\n", t->str, t->n);
+ printf ("should be: ");
+ for (i = 0; i < t->n; ++i)
+ printf ("%02x", t->res[i]);
+ printf ("\nresult was: ");
+ for (i = 0; i < t->n; ++i)
+ printf ("%02x", data[i]);
+ printf ("\n");
+ ret = 1;
+ }
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/n-fold.c b/crypto/heimdal/lib/krb5/n-fold.c
new file mode 100644
index 0000000..d0db5e8
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/n-fold.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: n-fold.c,v 1.6 1999/08/27 09:03:41 joda Exp $");
+
+static void
+rr13(unsigned char *buf, size_t len)
+{
+ unsigned char *tmp;
+ int bytes = (len + 7) / 8;
+ int i;
+ if(len == 0)
+ return;
+ {
+ const int bits = 13 % len;
+ const int lbit = len % 8;
+
+ tmp = malloc(bytes);
+ memcpy(tmp, buf, bytes);
+ if(lbit) {
+ /* pad final byte with inital bits */
+ tmp[bytes - 1] &= 0xff << (8 - lbit);
+ for(i = lbit; i < 8; i += len)
+ tmp[bytes - 1] |= buf[0] >> i;
+ }
+ for(i = 0; i < bytes; i++) {
+ int bb;
+ int b1, s1, b2, s2;
+ /* calculate first bit position of this byte */
+ bb = 8 * i - bits;
+ while(bb < 0)
+ bb += len;
+ /* byte offset and shift count */
+ b1 = bb / 8;
+ s1 = bb % 8;
+
+ if(bb + 8 > bytes * 8)
+ /* watch for wraparound */
+ s2 = (len + 8 - s1) % 8;
+ else
+ s2 = 8 - s1;
+ b2 = (b1 + 1) % bytes;
+ buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
+ }
+ free(tmp);
+ }
+}
+
+/* Add `b' to `a', both beeing one's complement numbers. */
+static void
+add1(unsigned char *a, unsigned char *b, size_t len)
+{
+ int i;
+ int carry = 0;
+ for(i = len - 1; i >= 0; i--){
+ int x = a[i] + b[i] + carry;
+ carry = x > 0xff;
+ a[i] = x & 0xff;
+ }
+ for(i = len - 1; carry && i >= 0; i--){
+ int x = a[i] + carry;
+ carry = x > 0xff;
+ a[i] = x & 0xff;
+ }
+}
+
+void
+_krb5_n_fold(const void *str, size_t len, void *key, size_t size)
+{
+ /* if len < size we need at most N * len bytes, ie < 2 * size;
+ if len > size we need at most 2 * len */
+ size_t maxlen = 2 * max(size, len);
+ size_t l = 0;
+ unsigned char *tmp = malloc(maxlen);
+ unsigned char *buf = malloc(len);
+
+ memcpy(buf, str, len);
+ memset(key, 0, size);
+ do {
+ memcpy(tmp + l, buf, len);
+ l += len;
+ rr13(buf, len * 8);
+ while(l >= size) {
+ add1(key, tmp, size);
+ l -= size;
+ if(l == 0)
+ break;
+ memmove(tmp, tmp + size, l);
+ }
+ } while(l != 0);
+ memset(buf, 0, len);
+ free(buf);
+ memset(tmp, 0, maxlen);
+ free(tmp);
+}
diff --git a/crypto/heimdal/lib/krb5/net_read.c b/crypto/heimdal/lib/krb5/net_read.c
new file mode 100644
index 0000000..8cb1dc4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/net_read.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: net_read.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+
+ssize_t
+krb5_net_read (krb5_context context,
+ void *p_fd,
+ void *buf,
+ size_t len)
+{
+ int fd = *((int *)p_fd);
+
+ return net_read (fd, buf, len);
+}
diff --git a/crypto/heimdal/lib/krb5/net_write.c b/crypto/heimdal/lib/krb5/net_write.c
new file mode 100644
index 0000000..5cc719b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/net_write.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: net_write.c,v 1.6 1999/12/02 17:05:11 joda Exp $");
+
+ssize_t
+krb5_net_write (krb5_context context,
+ void *p_fd,
+ const void *buf,
+ size_t len)
+{
+ int fd = *((int *)p_fd);
+
+ return net_write (fd, buf, len);
+}
diff --git a/crypto/heimdal/lib/krb5/padata.c b/crypto/heimdal/lib/krb5/padata.c
new file mode 100644
index 0000000..bcf7952
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/padata.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: padata.c,v 1.2 1999/12/02 17:05:11 joda Exp $");
+
+PA_DATA *
+krb5_find_padata(PA_DATA *val, unsigned len, int type, int *index)
+{
+ for(; *index < len; (*index)++)
+ if(val[*index].padata_type == type)
+ return val + *index;
+ return NULL;
+}
diff --git a/crypto/heimdal/lib/krb5/principal.c b/crypto/heimdal/lib/krb5/principal.c
new file mode 100644
index 0000000..3fd022d
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/principal.c
@@ -0,0 +1,898 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#ifdef HAVE_RES_SEARCH
+#define USE_RESOLVER
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#include "resolve.h"
+
+RCSID("$Id: principal.c,v 1.57 2000/01/08 08:08:03 assar Exp $");
+
+#define princ_num_comp(P) ((P)->name.name_string.len)
+#define princ_type(P) ((P)->name.name_type)
+#define princ_comp(P) ((P)->name.name_string.val)
+#define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
+#define princ_realm(P) ((P)->realm)
+
+void
+krb5_free_principal(krb5_context context,
+ krb5_principal p)
+{
+ if(p){
+ free_Principal(p);
+ free(p);
+ }
+}
+
+krb5_error_code
+krb5_parse_name(krb5_context context,
+ const char *name,
+ krb5_principal *principal)
+{
+ krb5_error_code ret;
+ general_string *comp;
+ general_string realm;
+ int ncomp;
+
+ char *p;
+ char *q;
+ char *s;
+ char *start;
+
+ int n;
+ char c;
+ int got_realm = 0;
+
+ /* count number of component */
+ ncomp = 1;
+ for(p = (char*)name; *p; p++){
+ if(*p=='\\'){
+ if(!p[1])
+ return KRB5_PARSE_MALFORMED;
+ p++;
+ } else if(*p == '/')
+ ncomp++;
+ }
+ comp = calloc(ncomp, sizeof(*comp));
+ if (comp == NULL)
+ return ENOMEM;
+
+ n = 0;
+ start = q = p = s = strdup(name);
+ if (start == NULL) {
+ free (comp);
+ return ENOMEM;
+ }
+ while(*p){
+ c = *p++;
+ if(c == '\\'){
+ c = *p++;
+ if(c == 'n')
+ c = '\n';
+ else if(c == 't')
+ c = '\t';
+ else if(c == 'b')
+ c = '\b';
+ else if(c == '0')
+ c = '\0';
+ }else if(c == '/' || c == '@'){
+ if(got_realm){
+ ret = KRB5_PARSE_MALFORMED;
+ goto exit;
+ }else{
+ comp[n] = malloc(q - start + 1);
+ if (comp[n] == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ strncpy(comp[n], start, q - start);
+ comp[n][q - start] = 0;
+ n++;
+ }
+ if(c == '@')
+ got_realm = 1;
+ start = q;
+ continue;
+ }
+ if(got_realm && (c == ':' || c == '/' || c == '\0')) {
+ ret = KRB5_PARSE_MALFORMED;
+ goto exit;
+ }
+ *q++ = c;
+ }
+ if(got_realm){
+ realm = malloc(q - start + 1);
+ if (realm == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ strncpy(realm, start, q - start);
+ realm[q - start] = 0;
+ }else{
+ ret = krb5_get_default_realm (context, &realm);
+ if (ret)
+ goto exit;
+
+ comp[n] = malloc(q - start + 1);
+ if (comp[n] == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ strncpy(comp[n], start, q - start);
+ comp[n][q - start] = 0;
+ n++;
+ }
+ *principal = malloc(sizeof(**principal));
+ if (*principal == NULL) {
+ ret = ENOMEM;
+ goto exit;
+ }
+ (*principal)->name.name_type = KRB5_NT_PRINCIPAL;
+ (*principal)->name.name_string.val = comp;
+ princ_num_comp(*principal) = n;
+ (*principal)->realm = realm;
+ free(s);
+ return 0;
+exit:
+ while(n>0){
+ free(comp[--n]);
+ }
+ free(comp);
+ free(s);
+ return ret;
+}
+
+static const char quotable_chars[] = "\n\t\b\\/@";
+static const char replace_chars[] = "ntb\\/@";
+
+#define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
+
+static size_t
+quote_string(const char *s, char *out, size_t index, size_t len)
+{
+ const char *p, *q;
+ for(p = s; *p && index < len; p++){
+ if((q = strchr(quotable_chars, *p))){
+ add_char(out, index, len, '\\');
+ add_char(out, index, len, replace_chars[q - quotable_chars]);
+ }else
+ add_char(out, index, len, *p);
+ }
+ if(index < len)
+ out[index] = '\0';
+ return index;
+}
+
+
+static krb5_error_code
+unparse_name_fixed(krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len,
+ krb5_boolean short_form)
+{
+ size_t index = 0;
+ int i;
+ for(i = 0; i < princ_num_comp(principal); i++){
+ if(i)
+ add_char(name, index, len, '/');
+ index = quote_string(princ_ncomp(principal, i), name, index, len);
+ if(index == len)
+ return ERANGE;
+ }
+ /* add realm if different from default realm */
+ if(short_form) {
+ krb5_realm r;
+ krb5_error_code ret;
+ ret = krb5_get_default_realm(context, &r);
+ if(ret)
+ return ret;
+ if(strcmp(princ_realm(principal), r) != 0)
+ short_form = 0;
+ free(r);
+ }
+ if(!short_form) {
+ add_char(name, index, len, '@');
+ index = quote_string(princ_realm(principal), name, index, len);
+ if(index == len)
+ return ERANGE;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_unparse_name_fixed(krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len)
+{
+ return unparse_name_fixed(context, principal, name, len, FALSE);
+}
+
+krb5_error_code
+krb5_unparse_name_fixed_short(krb5_context context,
+ krb5_const_principal principal,
+ char *name,
+ size_t len)
+{
+ return unparse_name_fixed(context, principal, name, len, TRUE);
+}
+
+static krb5_error_code
+unparse_name(krb5_context context,
+ krb5_const_principal principal,
+ char **name,
+ krb5_boolean short_flag)
+{
+ size_t len = 0, plen;
+ int i;
+ krb5_error_code ret;
+ /* count length */
+ plen = strlen(princ_realm(principal));
+ if(strcspn(princ_realm(principal), quotable_chars) == plen)
+ len += plen;
+ else
+ len += 2*plen;
+ len++;
+ for(i = 0; i < princ_num_comp(principal); i++){
+ plen = strlen(princ_ncomp(principal, i));
+ if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen)
+ len += plen;
+ else
+ len += 2*plen;
+ len++;
+ }
+ *name = malloc(len);
+ if(len != 0 && *name == NULL)
+ return ENOMEM;
+ ret = unparse_name_fixed(context, principal, *name, len, short_flag);
+ if(ret)
+ free(*name);
+ return ret;
+}
+
+krb5_error_code
+krb5_unparse_name(krb5_context context,
+ krb5_const_principal principal,
+ char **name)
+{
+ return unparse_name(context, principal, name, FALSE);
+}
+
+krb5_error_code
+krb5_unparse_name_short(krb5_context context,
+ krb5_const_principal principal,
+ char **name)
+{
+ return unparse_name(context, principal, name, TRUE);
+}
+
+#if 0 /* not implemented */
+
+krb5_error_code
+krb5_unparse_name_ext(krb5_context context,
+ krb5_const_principal principal,
+ char **name,
+ size_t *size)
+{
+ krb5_abortx(context, "unimplemented krb5_unparse_name_ext called");
+}
+
+#endif
+
+krb5_realm*
+krb5_princ_realm(krb5_context context,
+ krb5_principal principal)
+{
+ return &princ_realm(principal);
+}
+
+
+void
+krb5_princ_set_realm(krb5_context context,
+ krb5_principal principal,
+ krb5_realm *realm)
+{
+ princ_realm(principal) = *realm;
+}
+
+
+krb5_error_code
+krb5_build_principal(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...)
+{
+ krb5_error_code ret;
+ va_list ap;
+ va_start(ap, realm);
+ ret = krb5_build_principal_va(context, principal, rlen, realm, ap);
+ va_end(ap);
+ return ret;
+}
+
+static krb5_error_code
+append_component(krb5_context context, krb5_principal p,
+ general_string comp,
+ size_t comp_len)
+{
+ general_string *tmp;
+ size_t len = princ_num_comp(p);
+ tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ princ_comp(p) = tmp;
+ princ_ncomp(p, len) = malloc(comp_len + 1);
+ memcpy (princ_ncomp(p, len), comp, comp_len);
+ princ_ncomp(p, len)[comp_len] = '\0';
+ princ_num_comp(p)++;
+ return 0;
+}
+
+static void
+va_ext_princ(krb5_context context, krb5_principal p, va_list ap)
+{
+ while(1){
+ char *s;
+ int len;
+ len = va_arg(ap, int);
+ if(len == 0)
+ break;
+ s = va_arg(ap, char*);
+ append_component(context, p, s, len);
+ }
+}
+
+static void
+va_princ(krb5_context context, krb5_principal p, va_list ap)
+{
+ while(1){
+ char *s;
+ s = va_arg(ap, char*);
+ if(s == NULL)
+ break;
+ append_component(context, p, s, strlen(s));
+ }
+}
+
+
+static krb5_error_code
+build_principal(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ void (*func)(krb5_context, krb5_principal, va_list),
+ va_list ap)
+{
+ krb5_principal p;
+
+ p = calloc(1, sizeof(*p));
+ if (p == NULL)
+ return ENOMEM;
+ princ_type(p) = KRB5_NT_PRINCIPAL;
+
+ princ_realm(p) = strdup(realm);
+ if(p->realm == NULL){
+ free(p);
+ return ENOMEM;
+ }
+
+ (*func)(context, p, ap);
+ *principal = p;
+ return 0;
+}
+
+krb5_error_code
+krb5_make_principal(krb5_context context,
+ krb5_principal *principal,
+ krb5_const_realm realm,
+ ...)
+{
+ krb5_error_code ret;
+ krb5_realm r = NULL;
+ va_list ap;
+ if(realm == NULL) {
+ ret = krb5_get_default_realm(context, &r);
+ if(ret)
+ return ret;
+ realm = r;
+ }
+ va_start(ap, realm);
+ ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
+ va_end(ap);
+ if(r)
+ free(r);
+ return ret;
+}
+
+krb5_error_code
+krb5_build_principal_va(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap)
+{
+ return build_principal(context, principal, rlen, realm, va_princ, ap);
+}
+
+krb5_error_code
+krb5_build_principal_va_ext(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ va_list ap)
+{
+ return build_principal(context, principal, rlen, realm, va_ext_princ, ap);
+}
+
+
+krb5_error_code
+krb5_build_principal_ext(krb5_context context,
+ krb5_principal *principal,
+ int rlen,
+ krb5_const_realm realm,
+ ...)
+{
+ krb5_error_code ret;
+ va_list ap;
+ va_start(ap, realm);
+ ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+krb5_error_code
+krb5_copy_principal(krb5_context context,
+ krb5_const_principal inprinc,
+ krb5_principal *outprinc)
+{
+ krb5_principal p = malloc(sizeof(*p));
+ if (p == NULL)
+ return ENOMEM;
+ if(copy_Principal(inprinc, p))
+ return ENOMEM;
+ *outprinc = p;
+ return 0;
+}
+
+
+krb5_boolean
+krb5_principal_compare_any_realm(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+ int i;
+ if(princ_num_comp(princ1) != princ_num_comp(princ2))
+ return FALSE;
+ for(i = 0; i < princ_num_comp(princ1); i++){
+ if(strcmp(princ_ncomp(princ1, i), princ_ncomp(princ2, i)) != 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+krb5_boolean
+krb5_principal_compare(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+ if(!krb5_realm_compare(context, princ1, princ2))
+ return FALSE;
+ return krb5_principal_compare_any_realm(context, princ1, princ2);
+}
+
+
+krb5_boolean
+krb5_realm_compare(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+ return strcmp(princ_realm(princ1), princ_realm(princ2)) == 0;
+}
+
+struct v4_name_convert {
+ const char *from;
+ const char *to;
+} default_v4_name_convert[] = {
+ { "ftp", "ftp" },
+ { "hprop", "hprop" },
+ { "pop", "pop" },
+ { "rcmd", "host" },
+ { NULL, NULL }
+};
+
+static const char*
+get_name_conversion(krb5_context context, const char *realm, const char *name)
+{
+ struct v4_name_convert *q;
+ const char *p;
+ p = krb5_config_get_string(context, NULL, "realms", realm,
+ "v4_name_convert", "host", name, NULL);
+ if(p == NULL)
+ p = krb5_config_get_string(context, NULL, "libdefaults",
+ "v4_name_convert", "host", name, NULL);
+ if(p)
+ return p;
+
+ /* XXX should be possible to override default list */
+ p = krb5_config_get_string(context, NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p)
+ return NULL;
+ p = krb5_config_get_string(context, NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p)
+ return NULL;
+ for(q = default_v4_name_convert; q->from; q++)
+ if(strcmp(q->from, name) == 0)
+ return q->to;
+ return NULL;
+}
+
+krb5_error_code
+krb5_425_conv_principal_ext(krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_boolean (*func)(krb5_context, krb5_principal),
+ krb5_boolean resolve,
+ krb5_principal *princ)
+{
+ const char *p;
+ krb5_error_code ret;
+ krb5_principal pr;
+ char host[128];
+
+ /* do the following: if the name is found in the
+ `v4_name_convert:host' part, is is assumed to be a `host' type
+ principal, and the instance is looked up in the
+ `v4_instance_convert' part. if not found there the name is
+ (optionally) looked up as a hostname, and if that doesn't yield
+ anything, the `default_domain' is appended to the instance
+ */
+
+ if(instance == NULL)
+ goto no_host;
+ if(instance[0] == 0){
+ instance = NULL;
+ goto no_host;
+ }
+ p = get_name_conversion(context, realm, name);
+ if(p == NULL)
+ goto no_host;
+ name = p;
+ p = krb5_config_get_string(context, NULL, "realms", realm,
+ "v4_instance_convert", instance, NULL);
+ if(p){
+ instance = p;
+ ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ *princ = NULL;
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+ }
+ if(resolve){
+ const char *inst = NULL;
+#ifdef USE_RESOLVER
+ struct dns_reply *r;
+ r = dns_lookup(instance, "a");
+ if(r && r->head && r->head->type == T_A)
+ inst = r->head->domain;
+#else
+ struct hostent *hp = roken_gethostbyname(instance);
+ if(hp)
+ inst = hp->h_name;
+#endif
+ if(inst) {
+ ret = krb5_make_principal(context, &pr, realm, name, inst, NULL);
+ if(ret == 0) {
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+#ifdef USE_RESOLVER
+ dns_free_data(r);
+#endif
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ }
+ }
+#ifdef USE_RESOLVER
+ if(r)
+ dns_free_data(r);
+#endif
+ }
+ {
+ char **domains, **d;
+ domains = krb5_config_get_strings(context, NULL, "realms", realm,
+ "v4_domains", NULL);
+ for(d = domains; d && *d; d++){
+ snprintf(host, sizeof(host), "%s.%s", instance, *d);
+ ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ krb5_config_free_strings(domains);
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ }
+ krb5_config_free_strings(domains);
+ }
+
+
+ p = krb5_config_get_string(context, NULL, "realms", realm,
+ "default_domain", NULL);
+ if(p == NULL){
+ /* should this be an error or should it silently
+ succeed? */
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+ }
+
+ if (*p == '.')
+ ++p;
+ snprintf(host, sizeof(host), "%s.%s", instance, p);
+ ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+no_host:
+ p = krb5_config_get_string(context, NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p == NULL)
+ p = krb5_config_get_string(context, NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "plain",
+ name,
+ NULL);
+ if(p)
+ name = p;
+
+ ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
+ if(func == NULL || (*func)(context, pr)){
+ *princ = pr;
+ return 0;
+ }
+ krb5_free_principal(context, pr);
+ return HEIM_ERR_V4_PRINC_NO_CONV;
+}
+
+krb5_error_code
+krb5_425_conv_principal(krb5_context context,
+ const char *name,
+ const char *instance,
+ const char *realm,
+ krb5_principal *princ)
+{
+ krb5_boolean resolve = krb5_config_get_bool(context,
+ NULL,
+ "libdefaults",
+ "v4_instance_resolve",
+ NULL);
+
+ return krb5_425_conv_principal_ext(context, name, instance, realm,
+ NULL, resolve, princ);
+}
+
+
+static int
+check_list(const krb5_config_binding *l, const char *name, const char **out)
+{
+ while(l){
+ if (l->type != krb5_config_string)
+ continue;
+ if(strcmp(name, l->u.string) == 0) {
+ *out = l->name;
+ return 1;
+ }
+ l = l->next;
+ }
+ return 0;
+}
+
+static int
+name_convert(krb5_context context, const char *name, const char *realm,
+ const char **out)
+{
+ const krb5_config_binding *l;
+ l = krb5_config_get_list (context,
+ NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "host",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_SRV_HST;
+ l = krb5_config_get_list (context,
+ NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "host",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_SRV_HST;
+ l = krb5_config_get_list (context,
+ NULL,
+ "realms",
+ realm,
+ "v4_name_convert",
+ "plain",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_UNKNOWN;
+ l = krb5_config_get_list (context,
+ NULL,
+ "libdefaults",
+ "v4_name_convert",
+ "host",
+ NULL);
+ if(l && check_list(l, name, out))
+ return KRB5_NT_UNKNOWN;
+
+ /* didn't find it in config file, try built-in list */
+ {
+ struct v4_name_convert *q;
+ for(q = default_v4_name_convert; q->from; q++) {
+ if(strcmp(name, q->to) == 0) {
+ *out = q->from;
+ return KRB5_NT_SRV_HST;
+ }
+ }
+ }
+ return -1;
+}
+
+krb5_error_code
+krb5_524_conv_principal(krb5_context context,
+ const krb5_principal principal,
+ char *name,
+ char *instance,
+ char *realm)
+{
+ const char *n, *i, *r;
+ char tmpinst[40];
+ int type = princ_type(principal);
+
+ r = principal->realm;
+
+ switch(principal->name.name_string.len){
+ case 1:
+ n = principal->name.name_string.val[0];
+ i = "";
+ break;
+ case 2:
+ n = principal->name.name_string.val[0];
+ i = principal->name.name_string.val[1];
+ break;
+ default:
+ return KRB5_PARSE_MALFORMED;
+ }
+
+ {
+ const char *tmp;
+ int t = name_convert(context, n, r, &tmp);
+ if(t >= 0) {
+ type = t;
+ n = tmp;
+ }
+ }
+
+ if(type == KRB5_NT_SRV_HST){
+ char *p;
+ strncpy(tmpinst, i, sizeof(tmpinst));
+ tmpinst[sizeof(tmpinst) - 1] = 0;
+ p = strchr(tmpinst, '.');
+ if(p) *p = 0;
+ i = tmpinst;
+ }
+
+ if(strlen(r) >= 40)
+ return KRB5_PARSE_MALFORMED;
+ if(strlen(n) >= 40)
+ return KRB5_PARSE_MALFORMED;
+ if(strlen(i) >= 40)
+ return KRB5_PARSE_MALFORMED;
+ strcpy(realm, r);
+ strcpy(name, n);
+ strcpy(instance, i);
+ return 0;
+}
+
+/*
+ * Create a principal in `ret_princ' for the service `sname' running
+ * on host `hostname'.
+ */
+
+krb5_error_code
+krb5_sname_to_principal (krb5_context context,
+ const char *hostname,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ)
+{
+ krb5_error_code ret;
+ char localhost[128];
+ char **realms, *host = NULL;
+
+ if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN)
+ return KRB5_SNAME_UNSUPP_NAMETYPE;
+ if(hostname == NULL) {
+ gethostname(localhost, sizeof(localhost));
+ hostname = localhost;
+ }
+ if(sname == NULL)
+ sname = "host";
+ if(type == KRB5_NT_SRV_HST) {
+ ret = krb5_expand_hostname (context, hostname, &host);
+ if (ret)
+ return ret;
+ strlwr(host);
+ hostname = host;
+ }
+ ret = krb5_get_host_realm(context, hostname, &realms);
+ if(ret)
+ return ret;
+
+ ret = krb5_make_principal(context, ret_princ, realms[0], sname,
+ hostname, NULL);
+ if(host)
+ free(host);
+ krb5_free_host_realm(context, realms);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/prog_setup.c b/crypto/heimdal/lib/krb5/prog_setup.c
new file mode 100644
index 0000000..4693d08
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/prog_setup.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#include <getarg.h>
+
+RCSID("$Id: prog_setup.c,v 1.6 1999/12/02 17:05:11 joda Exp $");
+
+void
+krb5_std_usage(int code, struct getargs *args, int num_args)
+{
+ arg_printusage(args, num_args, NULL, "");
+ exit(code);
+}
+
+int
+krb5_program_setup(krb5_context *context, int argc, char **argv,
+ struct getargs *args, int num_args,
+ void (*usage)(int, struct getargs*, int))
+{
+ int optind = 0;
+
+ if(usage == NULL)
+ usage = krb5_std_usage;
+
+ set_progname(argv[0]);
+ krb5_init_context(context);
+
+ if(getarg(args, num_args, argc, argv, &optind))
+ (*usage)(1, args, num_args);
+ return optind;
+}
diff --git a/crypto/heimdal/lib/krb5/prompter_posix.c b/crypto/heimdal/lib/krb5/prompter_posix.c
new file mode 100644
index 0000000..a849254
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/prompter_posix.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: prompter_posix.c,v 1.5 1999/12/02 17:05:11 joda Exp $");
+
+int
+krb5_prompter_posix (krb5_context context,
+ void *data,
+ const char *banner,
+ int num_prompts,
+ krb5_prompt prompts[])
+{
+ int i;
+
+ if (banner)
+ fprintf (stderr, "%s\n", banner);
+ for (i = 0; i < num_prompts; ++i) {
+ if (prompts[i].hidden) {
+ if(des_read_pw_string(prompts[i].reply->data,
+ prompts[i].reply->length,
+ prompts[i].prompt,
+ 0))
+ return 1;
+ } else {
+ char *s = prompts[i].reply->data;
+
+ fputs (prompts[i].prompt, stdout);
+ fflush (stdout);
+ if(fgets(prompts[i].reply->data,
+ prompts[i].reply->length,
+ stdin) == NULL)
+ return 1;
+ if(s[strlen(s) - 1] == '\n')
+ s[strlen(s) - 1] = '\0';
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_cred.c b/crypto/heimdal/lib/krb5/rd_cred.c
new file mode 100644
index 0000000..c330791
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_cred.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_cred.c,v 1.8 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_cred (krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_ccache ccache,
+ krb5_data *in_data)
+{
+ krb5_error_code ret;
+ size_t len;
+ KRB_CRED cred;
+ EncKrbCredPart enc_krb_cred_part;
+ krb5_data enc_krb_cred_part_data;
+ krb5_crypto crypto;
+ int i;
+
+ ret = decode_KRB_CRED (in_data->data, in_data->length,
+ &cred, &len);
+ if (ret)
+ return ret;
+
+ if (cred.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto out;
+ }
+
+ if (cred.msg_type != krb_cred) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto out;
+ }
+
+ krb5_crypto_init(context, auth_context->remote_subkey, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_KRB_CRED,
+ &cred.enc_part,
+ &enc_krb_cred_part_data);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ goto out;
+
+
+ ret = krb5_decode_EncKrbCredPart (context,
+ enc_krb_cred_part_data.data,
+ enc_krb_cred_part_data.length,
+ &enc_krb_cred_part,
+ &len);
+ if (ret)
+ goto out;
+
+ /* check sender address */
+
+ if (enc_krb_cred_part.s_address
+ && auth_context->remote_address) {
+ krb5_address *a;
+ int cmp;
+
+ ret = krb5_make_addrport (&a,
+ auth_context->remote_address,
+ auth_context->remote_port);
+ if (ret)
+ goto out;
+
+
+ cmp = krb5_address_compare (context,
+ a,
+ enc_krb_cred_part.s_address);
+
+ krb5_free_address (context, a);
+ free (a);
+
+ if (cmp == 0) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto out;
+ }
+ }
+
+ /* check receiver address */
+
+ if (enc_krb_cred_part.r_address
+ && !krb5_address_compare (context,
+ auth_context->local_address,
+ enc_krb_cred_part.r_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto out;
+ }
+
+ /* check timestamp */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+
+ if (enc_krb_cred_part.timestamp == NULL ||
+ enc_krb_cred_part.usec == NULL ||
+ abs(*enc_krb_cred_part.timestamp - sec)
+ > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto out;
+ }
+ }
+
+ /* XXX - check replay cache */
+
+ /* Store the creds in the ccache */
+
+ for (i = 0; i < enc_krb_cred_part.ticket_info.len; ++i) {
+ KrbCredInfo *kci = &enc_krb_cred_part.ticket_info.val[i];
+ krb5_creds creds;
+ u_char buf[1024];
+ size_t len;
+
+ memset (&creds, 0, sizeof(creds));
+
+ ret = encode_Ticket (buf + sizeof(buf) - 1, sizeof(buf),
+ &cred.tickets.val[i],
+ &len);
+ if (ret)
+ goto out;
+ krb5_data_copy (&creds.ticket, buf + sizeof(buf) - len, len);
+ copy_EncryptionKey (&kci->key, &creds.session);
+ if (kci->prealm && kci->pname)
+ principalname2krb5_principal (&creds.client,
+ *kci->pname,
+ *kci->prealm);
+ if (kci->flags)
+ creds.flags.b = *kci->flags;
+ if (kci->authtime)
+ creds.times.authtime = *kci->authtime;
+ if (kci->starttime)
+ creds.times.starttime = *kci->starttime;
+ if (kci->endtime)
+ creds.times.endtime = *kci->endtime;
+ if (kci->renew_till)
+ creds.times.renew_till = *kci->renew_till;
+ if (kci->srealm && kci->sname)
+ principalname2krb5_principal (&creds.server,
+ *kci->sname,
+ *kci->srealm);
+ if (kci->caddr)
+ krb5_copy_addresses (context,
+ kci->caddr,
+ &creds.addresses);
+ krb5_cc_store_cred (context, ccache, &creds);
+ }
+
+out:
+ free_KRB_CRED (&cred);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_error.c b/crypto/heimdal/lib/krb5/rd_error.c
new file mode 100644
index 0000000..df9b45e
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_error.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: rd_error.c,v 1.4 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_error(krb5_context context,
+ krb5_data *msg,
+ KRB_ERROR *result)
+{
+
+ size_t len;
+ krb5_error_code ret;
+ ret = decode_KRB_ERROR(msg->data, msg->length, result, &len);
+ if(ret)
+ return ret;
+ result->error_code += KRB5KDC_ERR_NONE;
+ return 0;
+}
+
+void
+krb5_free_error_contents (krb5_context context,
+ krb5_error *error)
+{
+ free_KRB_ERROR(error);
+}
+
+void
+krb5_free_error (krb5_context context,
+ krb5_error *error)
+{
+ krb5_free_error_contents (context, error);
+ free (error);
+}
diff --git a/crypto/heimdal/lib/krb5/rd_priv.c b/crypto/heimdal/lib/krb5/rd_priv.c
new file mode 100644
index 0000000..0bc8564
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_priv.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_priv.c,v 1.22 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_priv(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_PRIV priv;
+ EncKrbPrivPart part;
+ size_t len;
+ krb5_data plain;
+ krb5_keyblock *key;
+ krb5_crypto crypto;
+
+ memset(&priv, 0, sizeof(priv));
+ ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
+ if (ret)
+ goto failure;
+ if (priv.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto failure;
+ }
+ if (priv.msg_type != krb_priv) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto failure;
+ }
+
+ /* XXX - Is this right? */
+
+ if (auth_context->local_subkey)
+ key = auth_context->local_subkey;
+ else if (auth_context->remote_subkey)
+ key = auth_context->remote_subkey;
+ else
+ key = auth_context->keyblock;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData(context,
+ crypto,
+ KRB5_KU_KRB_PRIV,
+ &priv.enc_part,
+ &plain);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ goto failure;
+
+ ret = decode_EncKrbPrivPart (plain.data, plain.length, &part, &len);
+ krb5_data_free (&plain);
+ if (ret)
+ goto failure;
+
+ /* check sender address */
+
+ if (part.s_address
+ && auth_context->remote_address
+ && !krb5_address_compare (context,
+ auth_context->remote_address,
+ part.s_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure_part;
+ }
+
+ /* check receiver address */
+
+ if (part.r_address
+ && auth_context->local_address
+ && !krb5_address_compare (context,
+ auth_context->local_address,
+ part.r_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure_part;
+ }
+
+ /* check timestamp */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+ if (part.timestamp == NULL ||
+ part.usec == NULL ||
+ abs(*part.timestamp - sec) > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto failure_part;
+ }
+ }
+
+ /* XXX - check replay cache */
+
+ /* check sequence number */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ if (part.seq_number == NULL ||
+ *part.seq_number != ++auth_context->remote_seqnumber) {
+ ret = KRB5KRB_AP_ERR_BADORDER;
+ goto failure_part;
+ }
+ }
+
+ ret = krb5_data_copy (outbuf, part.user_data.data, part.user_data.length);
+ if (ret)
+ goto failure_part;
+
+ free_EncKrbPrivPart (&part);
+ free_KRB_PRIV (&priv);
+ return 0;
+
+failure_part:
+ free_EncKrbPrivPart (&part);
+
+failure:
+ free_KRB_PRIV (&priv);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_rep.c b/crypto/heimdal/lib/krb5/rd_rep.c
new file mode 100644
index 0000000..e2c401c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_rep.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_rep.c,v 1.19 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_rd_rep(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_ap_rep_enc_part **repl)
+{
+ krb5_error_code ret;
+ AP_REP ap_rep;
+ size_t len;
+ krb5_data data;
+ krb5_crypto crypto;
+
+ krb5_data_zero (&data);
+ ret = 0;
+
+ ret = decode_AP_REP(inbuf->data, inbuf->length, &ap_rep, &len);
+ if (ret)
+ return ret;
+ if (ap_rep.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto out;
+ }
+ if (ap_rep.msg_type != krb_ap_rep) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto out;
+ }
+
+ krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_AP_REQ_ENC_PART,
+ &ap_rep.enc_part,
+ &data);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ goto out;
+
+ *repl = malloc(sizeof(**repl));
+ if (*repl == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = krb5_decode_EncAPRepPart(context,
+ data.data,
+ data.length,
+ *repl,
+ &len);
+ if (ret)
+ return ret;
+
+ if ((*repl)->ctime != auth_context->authenticator->ctime ||
+ (*repl)->cusec != auth_context->authenticator->cusec) {
+ ret = KRB5KRB_AP_ERR_MUT_FAIL;
+ goto out;
+ }
+ if ((*repl)->seq_number)
+ auth_context->remote_seqnumber = *((*repl)->seq_number);
+
+out:
+ krb5_data_free (&data);
+ free_AP_REP (&ap_rep);
+ return ret;
+}
+
+void
+krb5_free_ap_rep_enc_part (krb5_context context,
+ krb5_ap_rep_enc_part *val)
+{
+ free_EncAPRepPart (val);
+ free (val);
+}
diff --git a/crypto/heimdal/lib/krb5/rd_req.c b/crypto/heimdal/lib/krb5/rd_req.c
new file mode 100644
index 0000000..9f8df1d
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_req.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_req.c,v 1.38 1999/12/02 17:05:12 joda Exp $");
+
+static krb5_error_code
+decrypt_tkt_enc_part (krb5_context context,
+ krb5_keyblock *key,
+ EncryptedData *enc_part,
+ EncTicketPart *decr_part)
+{
+ krb5_error_code ret;
+ krb5_data plain;
+ size_t len;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TICKET,
+ enc_part,
+ &plain);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_EncTicketPart(context, plain.data, plain.length,
+ decr_part, &len);
+ krb5_data_free (&plain);
+ return ret;
+}
+
+static krb5_error_code
+decrypt_authenticator (krb5_context context,
+ EncryptionKey *key,
+ EncryptedData *enc_part,
+ Authenticator *authenticator)
+{
+ krb5_error_code ret;
+ krb5_data plain;
+ size_t len;
+ krb5_crypto crypto;
+
+ krb5_crypto_init(context, key, 0, &crypto);
+ ret = krb5_decrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_AP_REQ_AUTH,
+ enc_part,
+ &plain);
+ krb5_crypto_destroy(context, crypto);
+ if (ret)
+ return ret;
+
+ ret = krb5_decode_Authenticator(context, plain.data, plain.length,
+ authenticator, &len);
+ krb5_data_free (&plain);
+ return ret;
+}
+
+krb5_error_code
+krb5_decode_ap_req(krb5_context context,
+ const krb5_data *inbuf,
+ krb5_ap_req *ap_req)
+{
+ krb5_error_code ret;
+ size_t len;
+ ret = decode_AP_REQ(inbuf->data, inbuf->length, ap_req, &len);
+ if (ret)
+ return ret;
+ if (ap_req->pvno != 5){
+ free_AP_REQ(ap_req);
+ return KRB5KRB_AP_ERR_BADVERSION;
+ }
+ if (ap_req->msg_type != krb_ap_req){
+ free_AP_REQ(ap_req);
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+ }
+ if (ap_req->ticket.tkt_vno != 5){
+ free_AP_REQ(ap_req);
+ return KRB5KRB_AP_ERR_BADVERSION;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_decrypt_ticket(krb5_context context,
+ Ticket *ticket,
+ krb5_keyblock *key,
+ EncTicketPart *out,
+ krb5_flags flags)
+{
+ EncTicketPart t;
+ krb5_error_code ret;
+ ret = decrypt_tkt_enc_part (context, key, &ticket->enc_part, &t);
+ if (ret)
+ return ret;
+
+ {
+ int32_t now;
+ time_t start = t.authtime;
+
+ krb5_timeofday (context, &now);
+ if(t.starttime)
+ start = *t.starttime;
+ if(start - now > context->max_skew
+ || (t.flags.invalid
+ && !(flags & KRB5_VERIFY_AP_REQ_IGNORE_INVALID)))
+ return KRB5KRB_AP_ERR_TKT_NYV;
+ if(now - t.endtime > context->max_skew)
+ return KRB5KRB_AP_ERR_TKT_EXPIRED;
+ }
+
+ if(out)
+ *out = t;
+ else
+ free_EncTicketPart(&t);
+ return 0;
+}
+
+krb5_error_code
+krb5_verify_authenticator_checksum(krb5_context context,
+ krb5_auth_context ac,
+ void *data,
+ size_t len)
+{
+ krb5_error_code ret;
+ krb5_keyblock *key;
+ krb5_authenticator authenticator;
+ krb5_crypto crypto;
+
+ ret = krb5_auth_getauthenticator (context,
+ ac,
+ &authenticator);
+ if(ret)
+ return ret;
+ if(authenticator->cksum == NULL)
+ return -17;
+ ret = krb5_auth_con_getkey(context, ac, &key);
+ if(ret) {
+ krb5_free_authenticator(context, &authenticator);
+ return ret;
+ }
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if(ret)
+ goto out;
+ ret = krb5_verify_checksum (context,
+ crypto,
+ KRB5_KU_AP_REQ_AUTH_CKSUM,
+ data,
+ len,
+ authenticator->cksum);
+ krb5_crypto_destroy(context, crypto);
+out:
+ krb5_free_authenticator(context, &authenticator);
+ krb5_free_keyblock(context, key);
+ return ret;
+}
+
+krb5_error_code
+krb5_verify_ap_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_ap_req *ap_req,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags flags,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
+{
+ krb5_ticket t;
+ krb5_auth_context ac;
+ krb5_error_code ret;
+
+ if(auth_context){
+ if(*auth_context == NULL){
+ krb5_auth_con_init(context, &ac);
+ *auth_context = ac;
+ }else
+ ac = *auth_context;
+ }else
+ krb5_auth_con_init(context, &ac);
+
+ if (ap_req->ap_options.use_session_key && ac->keyblock){
+ ret = krb5_decrypt_ticket(context, &ap_req->ticket,
+ ac->keyblock,
+ &t.ticket,
+ flags);
+ krb5_free_keyblock(context, ac->keyblock);
+ ac->keyblock = NULL;
+ }else
+ ret = krb5_decrypt_ticket(context, &ap_req->ticket,
+ keyblock,
+ &t.ticket,
+ flags);
+
+ if(ret)
+ return ret;
+
+ principalname2krb5_principal(&t.server, ap_req->ticket.sname,
+ ap_req->ticket.realm);
+ principalname2krb5_principal(&t.client, t.ticket.cname,
+ t.ticket.crealm);
+
+ /* save key */
+
+ krb5_copy_keyblock(context, &t.ticket.key, &ac->keyblock);
+
+ ret = decrypt_authenticator (context,
+ &t.ticket.key,
+ &ap_req->authenticator,
+ ac->authenticator);
+ if (ret){
+ /* XXX free data */
+ return ret;
+ }
+
+ {
+ krb5_principal p1, p2;
+ krb5_boolean res;
+
+ principalname2krb5_principal(&p1,
+ ac->authenticator->cname,
+ ac->authenticator->crealm);
+ principalname2krb5_principal(&p2,
+ t.ticket.cname,
+ t.ticket.crealm);
+ res = krb5_principal_compare (context, p1, p2);
+ krb5_free_principal (context, p1);
+ krb5_free_principal (context, p2);
+ if (!res)
+ return KRB5KRB_AP_ERR_BADMATCH;
+ }
+
+ /* check addresses */
+
+ if (t.ticket.caddr
+ && ac->remote_address
+ && !krb5_address_search (context,
+ ac->remote_address,
+ t.ticket.caddr))
+ return KRB5KRB_AP_ERR_BADADDR;
+
+ if (ac->authenticator->seq_number)
+ ac->remote_seqnumber = *ac->authenticator->seq_number;
+
+ /* XXX - Xor sequence numbers */
+
+ /* XXX - subkeys? */
+ /* And where should it be stored? */
+
+ if (ac->authenticator->subkey) {
+ krb5_copy_keyblock(context,
+ ac->authenticator->subkey,
+ &ac->remote_subkey);
+ }
+
+ if (ap_req_options) {
+ *ap_req_options = 0;
+ if (ap_req->ap_options.use_session_key)
+ *ap_req_options |= AP_OPTS_USE_SESSION_KEY;
+ if (ap_req->ap_options.mutual_required)
+ *ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+
+ if(ticket){
+ *ticket = malloc(sizeof(**ticket));
+ **ticket = t;
+ } else
+ krb5_free_ticket (context, &t);
+ return 0;
+}
+
+
+krb5_error_code
+krb5_rd_req_with_keyblock(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keyblock *keyblock,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
+{
+ krb5_error_code ret;
+ krb5_ap_req ap_req;
+
+ if (*auth_context == NULL) {
+ ret = krb5_auth_con_init(context, auth_context);
+ if (ret)
+ return ret;
+ }
+
+ ret = krb5_decode_ap_req(context, inbuf, &ap_req);
+ if(ret)
+ return ret;
+
+ ret = krb5_verify_ap_req(context,
+ auth_context,
+ &ap_req,
+ server,
+ keyblock,
+ 0,
+ ap_req_options,
+ ticket);
+
+ free_AP_REQ(&ap_req);
+ return ret;
+}
+
+static krb5_error_code
+get_key_from_keytab(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_ap_req *ap_req,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_keyblock **out)
+{
+ krb5_keytab_entry entry;
+ krb5_error_code ret;
+ int kvno;
+ krb5_keytab real_keytab;
+
+ if(keytab == NULL)
+ krb5_kt_default(context, &real_keytab);
+ else
+ real_keytab = keytab;
+
+ if (ap_req->ticket.enc_part.kvno)
+ kvno = *ap_req->ticket.enc_part.kvno;
+ else
+ kvno = 0;
+
+ ret = krb5_kt_get_entry (context,
+ real_keytab,
+ server,
+ kvno,
+ ap_req->ticket.enc_part.etype,
+ &entry);
+ if(ret)
+ goto out;
+ ret = krb5_copy_keyblock(context, &entry.keyblock, out);
+ krb5_kt_free_entry (context, &entry);
+out:
+ if(keytab == NULL)
+ krb5_kt_close(context, real_keytab);
+
+ return ret;
+}
+
+krb5_error_code
+krb5_rd_req(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
+{
+ krb5_error_code ret;
+ krb5_ap_req ap_req;
+ krb5_keyblock *keyblock = NULL;
+ krb5_principal service = NULL;
+
+ if (*auth_context == NULL) {
+ ret = krb5_auth_con_init(context, auth_context);
+ if (ret)
+ return ret;
+ }
+
+ ret = krb5_decode_ap_req(context, inbuf, &ap_req);
+ if(ret)
+ return ret;
+
+ if(server == NULL){
+ principalname2krb5_principal(&service,
+ ap_req.ticket.sname,
+ ap_req.ticket.realm);
+ server = service;
+ }
+
+ if(ap_req.ap_options.use_session_key == 0 ||
+ (*auth_context)->keyblock == NULL){
+ ret = get_key_from_keytab(context,
+ auth_context,
+ &ap_req,
+ server,
+ keytab,
+ &keyblock);
+ if(ret)
+ goto out;
+ }
+
+
+ ret = krb5_verify_ap_req(context,
+ auth_context,
+ &ap_req,
+ server,
+ keyblock,
+ 0,
+ ap_req_options,
+ ticket);
+
+ if(keyblock != NULL)
+ krb5_free_keyblock(context, keyblock);
+
+out:
+ free_AP_REQ(&ap_req);
+ if(service)
+ krb5_free_principal(context, service);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/rd_safe.c b/crypto/heimdal/lib/krb5/rd_safe.c
new file mode 100644
index 0000000..aebf215
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/rd_safe.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+RCSID("$Id: rd_safe.c,v 1.18 1999/12/02 17:05:12 joda Exp $");
+
+static krb5_error_code
+verify_checksum(krb5_context context,
+ krb5_auth_context auth_context,
+ KRB_SAFE *safe)
+{
+ krb5_error_code ret;
+ u_char *buf;
+ size_t buf_size;
+ size_t len;
+ Checksum c;
+ krb5_crypto crypto;
+
+ c = safe->cksum;
+ safe->cksum.cksumtype = 0;
+ safe->cksum.checksum.data = NULL;
+ safe->cksum.checksum.length = 0;
+
+
+ buf_size = length_KRB_SAFE(safe);
+ buf = malloc(buf_size);
+
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = encode_KRB_SAFE (buf + buf_size - 1,
+ buf_size,
+ safe,
+ &len);
+ krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
+ ret = krb5_verify_checksum (context,
+ crypto,
+ KRB5_KU_KRB_SAFE_CKSUM,
+ buf + buf_size - len,
+ len,
+ &c);
+ krb5_crypto_destroy(context, crypto);
+out:
+ safe->cksum = c;
+ free (buf);
+ return ret;
+}
+
+krb5_error_code
+krb5_rd_safe(krb5_context context,
+ krb5_auth_context auth_context,
+ const krb5_data *inbuf,
+ krb5_data *outbuf,
+ /*krb5_replay_data*/ void *outdata)
+{
+ krb5_error_code ret;
+ KRB_SAFE safe;
+ size_t len;
+
+ ret = decode_KRB_SAFE (inbuf->data, inbuf->length, &safe, &len);
+ if (ret)
+ return ret;
+ if (safe.pvno != 5) {
+ ret = KRB5KRB_AP_ERR_BADVERSION;
+ goto failure;
+ }
+ if (safe.msg_type != krb_safe) {
+ ret = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto failure;
+ }
+ if (!krb5_checksum_is_keyed(context, safe.cksum.cksumtype)
+ || !krb5_checksum_is_collision_proof(context, safe.cksum.cksumtype)) {
+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ goto failure;
+ }
+
+ /* check sender address */
+
+ if (safe.safe_body.s_address
+ && auth_context->remote_address
+ && !krb5_address_compare (context,
+ auth_context->remote_address,
+ safe.safe_body.s_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure;
+ }
+
+ /* check receiver address */
+
+ if (safe.safe_body.r_address
+ && auth_context->local_address
+ && !krb5_address_compare (context,
+ auth_context->local_address,
+ safe.safe_body.r_address)) {
+ ret = KRB5KRB_AP_ERR_BADADDR;
+ goto failure;
+ }
+
+ /* check timestamp */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+ int32_t sec;
+
+ krb5_timeofday (context, &sec);
+
+ if (safe.safe_body.timestamp == NULL ||
+ safe.safe_body.usec == NULL ||
+ abs(*safe.safe_body.timestamp - sec) > context->max_skew) {
+ ret = KRB5KRB_AP_ERR_SKEW;
+ goto failure;
+ }
+ }
+ /* XXX - check replay cache */
+
+ /* check sequence number */
+ if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+ if (safe.safe_body.seq_number == NULL ||
+ *safe.safe_body.seq_number != ++auth_context->remote_seqnumber) {
+ ret = KRB5KRB_AP_ERR_BADORDER;
+ goto failure;
+ }
+ }
+
+ ret = verify_checksum (context, auth_context, &safe);
+ if (ret)
+ goto failure;
+
+ outbuf->length = safe.safe_body.user_data.length;
+ outbuf->data = malloc(outbuf->length);
+ if (outbuf->data == NULL) {
+ ret = ENOMEM;
+ goto failure;
+ }
+ memcpy (outbuf->data, safe.safe_body.user_data.data, outbuf->length);
+ free_KRB_SAFE (&safe);
+ return 0;
+failure:
+ free_KRB_SAFE (&safe);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/read_message.c b/crypto/heimdal/lib/krb5/read_message.c
new file mode 100644
index 0000000..f2cae03
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/read_message.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: read_message.c,v 1.5 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_read_message (krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data)
+{
+ krb5_error_code ret;
+ u_int32_t len;
+ u_int8_t buf[4];
+
+ ret = krb5_net_read (context, p_fd, buf, 4);
+ if(ret == -1)
+ return errno;
+ if(ret < 4) {
+ data->length = 0;
+ return 0;
+ }
+ len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ ret = krb5_data_alloc (data, len);
+ if (ret)
+ return ret;
+ if (krb5_net_read (context, p_fd, data->data, len) != len) {
+ krb5_data_free (data);
+ return errno;
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/recvauth.c b/crypto/heimdal/lib/krb5/recvauth.c
new file mode 100644
index 0000000..49fe7b6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/recvauth.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: recvauth.c,v 1.12 1999/12/02 17:05:12 joda Exp $");
+
+/*
+ * See `sendauth.c' for the format.
+ */
+
+static krb5_boolean
+match_exact(void *data, const char *appl_version)
+{
+ return strcmp(data, appl_version) == 0;
+}
+
+krb5_error_code
+krb5_recvauth(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ char *appl_version,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket)
+{
+ return krb5_recvauth_match_version(context, auth_context, p_fd,
+ match_exact, appl_version,
+ server, flags,
+ keytab, ticket);
+}
+
+krb5_error_code
+krb5_recvauth_match_version(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ krb5_boolean (*match_appl_version)(void *,
+ const char*),
+ void *match_data,
+ krb5_principal server,
+ int32_t flags,
+ krb5_keytab keytab,
+ krb5_ticket **ticket)
+{
+ krb5_error_code ret;
+ const char *version = KRB5_SENDAUTH_VERSION;
+ char her_version[sizeof(KRB5_SENDAUTH_VERSION)];
+ char *her_appl_version;
+ u_int32_t len;
+ u_char repl;
+ krb5_data data;
+ krb5_flags ap_options;
+ ssize_t n;
+
+ /*
+ * If there are no addresses in auth_context, get them from `fd'.
+ */
+
+ if (*auth_context == NULL) {
+ ret = krb5_auth_con_init (context, auth_context);
+ if (ret)
+ return ret;
+ }
+
+ ret = krb5_auth_con_setaddrs_from_fd (context,
+ *auth_context,
+ p_fd);
+ if (ret)
+ return ret;
+
+ if(!(flags & KRB5_RECVAUTH_IGNORE_VERSION)) {
+ n = krb5_net_read (context, p_fd, &len, 4);
+ if (n < 0)
+ return errno;
+ if (n == 0)
+ return KRB5_SENDAUTH_BADAUTHVERS;
+ len = ntohl(len);
+ if (len != sizeof(her_version)
+ || krb5_net_read (context, p_fd, her_version, len) != len
+ || strncmp (version, her_version, len)) {
+ repl = 1;
+ krb5_net_write (context, p_fd, &repl, 1);
+ return KRB5_SENDAUTH_BADAUTHVERS;
+ }
+ }
+
+ n = krb5_net_read (context, p_fd, &len, 4);
+ if (n < 0)
+ return errno;
+ if (n == 0)
+ return KRB5_SENDAUTH_BADAPPLVERS;
+ len = ntohl(len);
+ her_appl_version = malloc (len);
+ if (her_appl_version == NULL) {
+ repl = 2;
+ krb5_net_write (context, p_fd, &repl, 1);
+ return ENOMEM;
+ }
+ if (krb5_net_read (context, p_fd, her_appl_version, len) != len
+ || !(*match_appl_version)(match_data, her_appl_version)) {
+ repl = 2;
+ krb5_net_write (context, p_fd, &repl, 1);
+ free (her_appl_version);
+ return KRB5_SENDAUTH_BADAPPLVERS;
+ }
+ free (her_appl_version);
+
+ repl = 0;
+ if (krb5_net_write (context, p_fd, &repl, 1) != 1)
+ return errno;
+
+ krb5_data_zero (&data);
+ ret = krb5_read_message (context, p_fd, &data);
+ if (ret)
+ return ret;
+
+ ret = krb5_rd_req (context,
+ auth_context,
+ &data,
+ server,
+ keytab,
+ &ap_options,
+ ticket);
+ krb5_data_free (&data);
+ if (ret) {
+ krb5_data error_data;
+ krb5_error_code ret2;
+
+ ret2 = krb5_mk_error (context,
+ ret,
+ NULL,
+ NULL,
+ NULL,
+ server,
+ 0,
+ &error_data);
+ if (ret2 == 0) {
+ krb5_write_message (context, p_fd, &error_data);
+ krb5_data_free (&error_data);
+ }
+ return ret;
+ }
+
+ len = 0;
+ if (krb5_net_write (context, p_fd, &len, 4) != 4)
+ return errno;
+
+ if (ap_options & AP_OPTS_MUTUAL_REQUIRED) {
+ ret = krb5_mk_rep (context, auth_context, &data);
+ if (ret)
+ return ret;
+
+ ret = krb5_write_message (context, p_fd, &data);
+ if (ret)
+ return ret;
+ krb5_data_free (&data);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/replay.c b/crypto/heimdal/lib/krb5/replay.c
new file mode 100644
index 0000000..5adc3db
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/replay.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+struct krb5_rcache_data {
+ char *name;
+};
+
+krb5_error_code
+krb5_rc_resolve(krb5_context context,
+ krb5_rcache id,
+ const char *name)
+{
+ id->name = strdup(name);
+ if(id->name == NULL)
+ return KRB5_RC_MALLOC;
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_resolve_type(krb5_context context,
+ krb5_rcache *id,
+ const char *type)
+{
+ if(strcmp(type, "FILE"))
+ return KRB5_RC_TYPE_NOTFOUND;
+ *id = calloc(1, sizeof(**id));
+ if(*id == NULL)
+ return KRB5_RC_MALLOC;
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_resolve_full(krb5_context context,
+ krb5_rcache *id,
+ const char *string_name)
+{
+ krb5_error_code ret;
+ if(strncmp(string_name, "FILE:", 5))
+ return KRB5_RC_TYPE_NOTFOUND;
+ ret = krb5_rc_resolve_type(context, id, "FILE");
+ if(ret)
+ return ret;
+ ret = krb5_rc_resolve(context, *id, string_name + 5);
+ return ret;
+}
+
+const char *
+krb5_rc_default_name(krb5_context context)
+{
+ return "FILE:/var/run/default_rcache";
+}
+
+krb5_error_code
+krb5_rc_default(krb5_context context,
+ krb5_rcache *id)
+{
+ return krb5_rc_resolve_full(context, id, krb5_rc_default_name(context));
+}
+
+struct rc_entry{
+ time_t stamp;
+ unsigned char data[16];
+};
+
+krb5_error_code
+krb5_rc_initialize(krb5_context context,
+ krb5_rcache id,
+ krb5_deltat auth_lifespan)
+{
+ FILE *f = fopen(id->name, "w");
+ struct rc_entry tmp;
+ if(f == NULL)
+ return errno;
+ tmp.stamp = auth_lifespan;
+ fwrite(&tmp, 1, sizeof(tmp), f);
+ fclose(f);
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_recover(krb5_context context,
+ krb5_rcache id)
+{
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_destroy(krb5_context context,
+ krb5_rcache id)
+{
+ if(remove(id->name) < 0)
+ return errno;
+ return krb5_rc_close(context, id);
+}
+
+krb5_error_code
+krb5_rc_close(krb5_context context,
+ krb5_rcache id)
+{
+ free(id->name);
+ free(id);
+ return 0;
+}
+
+static void
+checksum_authenticator(Authenticator *auth, void *data)
+{
+ struct md5 md5;
+ int i;
+ md5_init(&md5);
+ md5_update(&md5, auth->crealm, strlen(auth->crealm));
+ for(i = 0; i < auth->cname.name_string.len; i++)
+ md5_update(&md5, auth->cname.name_string.val[i],
+ strlen(auth->cname.name_string.val[i]));
+ md5_update(&md5, &auth->ctime, sizeof(auth->ctime));
+ md5_update(&md5, &auth->cusec, sizeof(auth->cusec));
+ md5_finito(&md5, data);
+}
+
+krb5_error_code
+krb5_rc_store(krb5_context context,
+ krb5_rcache id,
+ krb5_donot_reply *rep)
+{
+ struct rc_entry ent, tmp;
+ time_t t;
+ FILE *f;
+ ent.stamp = time(NULL);
+ checksum_authenticator(rep, ent.data);
+ f = fopen(id->name, "r");
+ if(f == NULL)
+ return errno;
+ fread(&tmp, sizeof(ent), 1, f);
+ t = ent.stamp - tmp.stamp;
+ while(fread(&tmp, sizeof(ent), 1, f)){
+ if(tmp.stamp < t)
+ continue;
+ if(memcmp(tmp.data, ent.data, sizeof(ent.data)) == 0){
+ fclose(f);
+ return KRB5_RC_REPLAY;
+ }
+ }
+ if(ferror(f)){
+ fclose(f);
+ return errno;
+ }
+ fclose(f);
+ f = fopen(id->name, "a");
+ if(f == NULL)
+ return KRB5_RC_IO_UNKNOWN;
+ fwrite(&ent, 1, sizeof(ent), f);
+ fclose(f);
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_expunge(krb5_context context,
+ krb5_rcache id)
+{
+ return 0;
+}
+
+krb5_error_code
+krb5_rc_get_lifespan(krb5_context context,
+ krb5_rcache id,
+ krb5_deltat *auth_lifespan)
+{
+ FILE *f = fopen(id->name, "r");
+ int r;
+ struct rc_entry ent;
+ r = fread(&ent, sizeof(ent), 1, f);
+ fclose(f);
+ if(r){
+ *auth_lifespan = ent.stamp;
+ return 0;
+ }
+ return KRB5_RC_IO_UNKNOWN;
+}
+const char*
+krb5_rc_get_name(krb5_context context,
+ krb5_rcache id)
+{
+ return id->name;
+}
+
+const char*
+krb5_rc_get_type(krb5_context context,
+ krb5_rcache id)
+{
+ return "FILE";
+}
+
diff --git a/crypto/heimdal/lib/krb5/send_to_kdc.c b/crypto/heimdal/lib/krb5/send_to_kdc.c
new file mode 100644
index 0000000..2872322
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/send_to_kdc.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: send_to_kdc.c,v 1.36 2000/01/06 07:59:11 assar Exp $");
+
+/*
+ * send the data in `req' on the socket `fd' (which is datagram iff udp)
+ * waiting `tmout' for a reply and returning the reply in `rep'.
+ * iff limit read up to this many bytes
+ * returns 0 and data in `rep' if succesful, otherwise -1
+ */
+
+static int
+recv_loop (int fd,
+ time_t tmout,
+ int udp,
+ size_t limit,
+ krb5_data *rep)
+{
+ fd_set fdset;
+ struct timeval timeout;
+ int ret;
+ int nbytes;
+
+ krb5_data_zero(rep);
+ do {
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ timeout.tv_sec = tmout;
+ timeout.tv_usec = 0;
+ ret = select (fd + 1, &fdset, NULL, NULL, &timeout);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return -1;
+ } else if (ret == 0) {
+ return 0;
+ } else {
+ void *tmp;
+
+ if (ioctl (fd, FIONREAD, &nbytes) < 0) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ if(nbytes == 0)
+ return 0;
+
+ if (limit)
+ nbytes = min(nbytes, limit - rep->length);
+
+ tmp = realloc (rep->data, rep->length + nbytes);
+ if (tmp == NULL) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ rep->data = tmp;
+ ret = recv (fd, (char*)tmp + rep->length, nbytes, 0);
+ if (ret < 0) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ rep->length += ret;
+ }
+ } while(!udp && (limit == 0 || rep->length < limit));
+ return 0;
+}
+
+/*
+ * Send kerberos requests and receive a reply on a udp or any other kind
+ * of a datagram socket. See `recv_loop'.
+ */
+
+static int
+send_and_recv_udp(int fd,
+ time_t tmout,
+ const krb5_data *req,
+ krb5_data *rep)
+{
+ if (send (fd, req->data, req->length, 0) < 0)
+ return -1;
+
+ return recv_loop(fd, tmout, 1, 0, rep);
+}
+
+/*
+ * `send_and_recv' for a TCP (or any other stream) socket.
+ * Since there are no record limits on a stream socket the protocol here
+ * is to prepend the request with 4 bytes of its length and the reply
+ * is similarly encoded.
+ */
+
+static int
+send_and_recv_tcp(int fd,
+ time_t tmout,
+ const krb5_data *req,
+ krb5_data *rep)
+{
+ unsigned char len[4];
+ unsigned long rep_len;
+ krb5_data len_data;
+
+ _krb5_put_int(len, req->length, 4);
+ if(net_write(fd, len, sizeof(len)) < 0)
+ return -1;
+ if(net_write(fd, req->data, req->length) < 0)
+ return -1;
+ if (recv_loop (fd, tmout, 0, 4, &len_data) < 0)
+ return -1;
+ if (len_data.length != 4) {
+ krb5_data_free (&len_data);
+ return -1;
+ }
+ _krb5_get_int(len_data.data, &rep_len, 4);
+ krb5_data_free (&len_data);
+ if (recv_loop (fd, tmout, 0, rep_len, rep) < 0)
+ return -1;
+ if(rep->length != rep_len) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * `send_and_recv' tailored for the HTTP protocol.
+ */
+
+static int
+send_and_recv_http(int fd,
+ time_t tmout,
+ const char *prefix,
+ const krb5_data *req,
+ krb5_data *rep)
+{
+ char *request;
+ char *str;
+ int ret;
+ int len = base64_encode(req->data, req->length, &str);
+
+ if(len < 0)
+ return -1;
+ asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str);
+ free(str);
+ if (request == NULL)
+ return -1;
+ ret = net_write (fd, request, strlen(request));
+ free (request);
+ if (ret < 0)
+ return ret;
+ ret = recv_loop(fd, tmout, 0, 0, rep);
+ if(ret)
+ return ret;
+ {
+ unsigned long rep_len;
+ char *s, *p;
+
+ s = realloc(rep->data, rep->length + 1);
+ if (s == NULL) {
+ krb5_data_free (rep);
+ return -1;
+ }
+ s[rep->length] = 0;
+ p = strstr(s, "\r\n\r\n");
+ if(p == NULL) {
+ free(s);
+ return -1;
+ }
+ p += 4;
+ rep->data = s;
+ rep->length -= p - s;
+ if(rep->length < 4) { /* remove length */
+ free(s);
+ return -1;
+ }
+ rep->length -= 4;
+ _krb5_get_int(p, &rep_len, 4);
+ if (rep_len != rep->length) {
+ free(s);
+ return -1;
+ }
+ memmove(rep->data, p + 4, rep->length);
+ }
+ return 0;
+}
+
+static int
+init_port(const char *s, int fallback)
+{
+ if (s) {
+ int tmp;
+
+ sscanf (s, "%d", &tmp);
+ return htons(tmp);
+ } else
+ return fallback;
+}
+
+/*
+ * Return 0 if succesful, otherwise 1
+ */
+
+static int
+send_via_proxy (krb5_context context,
+ const char *hostname,
+ const krb5_data *send,
+ krb5_data *receive)
+{
+ char *proxy = strdup(context->http_proxy);
+ char *prefix;
+ char *colon;
+ struct addrinfo hints;
+ struct addrinfo *ai, *a;
+ int ret;
+ int s;
+ char portstr[NI_MAXSERV];
+
+ colon = strchr(proxy, ':');
+ if(colon != NULL)
+ *colon++ = '\0';
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ snprintf (portstr, sizeof(portstr), "%d",
+ ntohs(init_port (colon, htons(80))));
+ ret = getaddrinfo (proxy, portstr, NULL, &ai);
+ free (proxy);
+ if (ret)
+ return ret;
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ close (s);
+ continue;
+ }
+ break;
+ }
+ if (a == NULL) {
+ freeaddrinfo (ai);
+ return 1;
+ }
+ freeaddrinfo (ai);
+
+ asprintf(&prefix, "http://%s/", hostname);
+ if(prefix == NULL) {
+ close(s);
+ return 1;
+ }
+ ret = send_and_recv_http(s, context->kdc_timeout,
+ prefix, send, receive);
+ close (s);
+ free(prefix);
+ if(ret == 0 && receive->length != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Send the data `send' to one KDC in `realm' and get back the reply
+ * in `receive'.
+ */
+
+krb5_error_code
+krb5_sendto_kdc (krb5_context context,
+ const krb5_data *send,
+ const krb5_realm *realm,
+ krb5_data *receive)
+{
+ krb5_error_code ret;
+ char **hostlist, **hp, *p;
+ int fd;
+ int port;
+ int i;
+
+ port = krb5_getportbyname (context, "kerberos", "udp", 88);
+
+ if (context->use_admin_kdc)
+ ret = krb5_get_krb_admin_hst (context, realm, &hostlist);
+ else
+ ret = krb5_get_krbhst (context, realm, &hostlist);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < context->max_retries; ++i)
+ for (hp = hostlist; (p = *hp); ++hp) {
+ char *colon;
+ int http_flag = 0;
+ int tcp_flag = 0;
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ char portstr[NI_MAXSERV];
+
+ if(strncmp(p, "http://", 7) == 0){
+ p += 7;
+ http_flag = 1;
+ port = htons(80);
+ } else if(strncmp(p, "http/", 5) == 0) {
+ p += 5;
+ http_flag = 1;
+ port = htons(80);
+ }else if(strncmp(p, "tcp/", 4) == 0){
+ p += 4;
+ tcp_flag = 1;
+ } else if(strncmp(p, "udp/", 4) == 0) {
+ p += 4;
+ }
+ if(http_flag && context->http_proxy) {
+ if (send_via_proxy (context, p, send, receive))
+ continue;
+ else
+ goto out;
+ }
+ colon = strchr (p, ':');
+ if (colon)
+ *colon++ = '\0';
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ if (tcp_flag || http_flag)
+ hints.ai_socktype = SOCK_STREAM;
+ else
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf (portstr, sizeof(portstr), "%d",
+ ntohs(init_port (colon, port)));
+ ret = getaddrinfo (p, portstr, &hints, &ai);
+ if (ret)
+ continue;
+ for (a = ai; a != NULL; a = a->ai_next) {
+ fd = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (fd < 0)
+ continue;
+ if (connect (fd, a->ai_addr, a->ai_addrlen) < 0) {
+ close (fd);
+ continue;
+ }
+ break;
+ }
+ if (a == NULL) {
+ freeaddrinfo (ai);
+ continue;
+ }
+ freeaddrinfo (ai);
+
+ if(http_flag)
+ ret = send_and_recv_http(fd, context->kdc_timeout,
+ "", send, receive);
+ else if(tcp_flag)
+ ret = send_and_recv_tcp (fd, context->kdc_timeout,
+ send, receive);
+ else
+ ret = send_and_recv_udp (fd, context->kdc_timeout,
+ send, receive);
+ close (fd);
+ if(ret == 0 && receive->length != 0)
+ goto out;
+ }
+ ret = KRB5_KDC_UNREACH;
+out:
+ krb5_free_krbhst (context, hostlist);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/sendauth.c b/crypto/heimdal/lib/krb5/sendauth.c
new file mode 100644
index 0000000..b9e8dd0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/sendauth.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: sendauth.c,v 1.17 1999/12/02 17:05:12 joda Exp $");
+
+/*
+ * The format seems to be:
+ * client -> server
+ *
+ * 4 bytes - length
+ * KRB5_SENDAUTH_V1.0 (including zero)
+ * 4 bytes - length
+ * protocol string (with terminating zero)
+ *
+ * server -> client
+ * 1 byte - (0 = OK, else some kind of error)
+ *
+ * client -> server
+ * 4 bytes - length
+ * AP-REQ
+ *
+ * server -> client
+ * 4 bytes - length (0 = OK, else length of error)
+ * (error)
+ *
+ * if(mutual) {
+ * server -> client
+ * 4 bytes - length
+ * AP-REP
+ * }
+ */
+
+krb5_error_code
+krb5_sendauth(krb5_context context,
+ krb5_auth_context *auth_context,
+ krb5_pointer p_fd,
+ const char *appl_version,
+ krb5_principal client,
+ krb5_principal server,
+ krb5_flags ap_req_options,
+ krb5_data *in_data,
+ krb5_creds *in_creds,
+ krb5_ccache ccache,
+ krb5_error **ret_error,
+ krb5_ap_rep_enc_part **rep_result,
+ krb5_creds **out_creds)
+{
+ krb5_error_code ret;
+ u_int32_t len, net_len;
+ const char *version = KRB5_SENDAUTH_VERSION;
+ u_char repl;
+ krb5_data ap_req, error_data;
+ krb5_creds this_cred;
+ krb5_principal this_client = NULL;
+ krb5_creds *creds;
+ ssize_t sret;
+
+ len = strlen(version) + 1;
+ net_len = htonl(len);
+ if (krb5_net_write (context, p_fd, &net_len, 4) != 4
+ || krb5_net_write (context, p_fd, version, len) != len)
+ return errno;
+
+ len = strlen(appl_version) + 1;
+ net_len = htonl(len);
+ if (krb5_net_write (context, p_fd, &net_len, 4) != 4
+ || krb5_net_write (context, p_fd, appl_version, len) != len)
+ return errno;
+
+ sret = krb5_net_read (context, p_fd, &repl, sizeof(repl));
+ if (sret < 0)
+ return errno;
+ else if (sret != sizeof(repl))
+ return KRB5_SENDAUTH_BADRESPONSE;
+
+ if (repl != 0)
+ return KRB5_SENDAUTH_REJECTED;
+
+ if (in_creds == NULL) {
+ if (ccache == NULL) {
+ ret = krb5_cc_default (context, &ccache);
+ if (ret)
+ return ret;
+ }
+
+ if (client == NULL) {
+ ret = krb5_cc_get_principal (context, ccache, &this_client);
+ if (ret)
+ return ret;
+ client = this_client;
+ }
+ memset(&this_cred, 0, sizeof(this_cred));
+ this_cred.client = client;
+ this_cred.server = server;
+ this_cred.times.endtime = 0;
+ this_cred.ticket.length = 0;
+ in_creds = &this_cred;
+ }
+ if (in_creds->ticket.length == 0) {
+ ret = krb5_get_credentials (context, 0, ccache, in_creds, &creds);
+ if (ret)
+ return ret;
+ } else {
+ creds = in_creds;
+ }
+ ret = krb5_mk_req_extended (context,
+ auth_context,
+ ap_req_options,
+ in_data,
+ creds,
+ &ap_req);
+
+ if (out_creds)
+ *out_creds = creds;
+ else
+ krb5_free_creds(context, creds);
+ if(this_client)
+ krb5_free_principal(context, this_client);
+
+ if (ret)
+ return ret;
+
+ ret = krb5_write_message (context,
+ p_fd,
+ &ap_req);
+ if (ret)
+ return ret;
+
+ krb5_data_free (&ap_req);
+
+ ret = krb5_read_message (context, p_fd, &error_data);
+ if (ret)
+ return ret;
+
+ if (error_data.length != 0) {
+ KRB_ERROR error;
+
+ ret = krb5_rd_error (context, &error_data, &error);
+ krb5_data_free (&error_data);
+ if (ret == 0) {
+ if (ret_error != NULL) {
+ *ret_error = malloc (sizeof(krb5_error));
+ if (*ret_error == NULL) {
+ free_KRB_ERROR(&error);
+ } else {
+ **ret_error = error;
+ }
+ } else {
+ free_KRB_ERROR(&error);
+ }
+ return error.error_code;
+ } else
+ return ret;
+ }
+
+ if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED) {
+ krb5_data ap_rep;
+ krb5_ap_rep_enc_part *ignore;
+
+ krb5_data_zero (&ap_rep);
+ ret = krb5_read_message (context,
+ p_fd,
+ &ap_rep);
+ if (ret)
+ return ret;
+
+ ret = krb5_rd_rep (context, *auth_context, &ap_rep,
+ rep_result ? rep_result : &ignore);
+ if (ret)
+ return ret;
+ if (rep_result == NULL)
+ krb5_free_ap_rep_enc_part (context, ignore);
+ krb5_data_free (&ap_rep);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/set_default_realm.c b/crypto/heimdal/lib/krb5/set_default_realm.c
new file mode 100644
index 0000000..b917a92
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/set_default_realm.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: set_default_realm.c,v 1.11 1999/12/02 17:05:12 joda Exp $");
+
+/*
+ * Convert the simple string `s' into a NULL-terminated and freshly allocated
+ * list in `list'. Return an error code.
+ */
+
+static krb5_error_code
+string_to_list (const char *s, krb5_realm **list)
+{
+
+ *list = malloc (2 * sizeof(**list));
+ if (*list == NULL)
+ return ENOMEM;
+ (*list)[0] = strdup (s);
+ if ((*list)[0] == NULL) {
+ free (*list);
+ return ENOMEM;
+ }
+ (*list)[1] = NULL;
+ return 0;
+}
+
+/*
+ * Set the knowledge of the default realm(s) in `context'.
+ * If realm != NULL, that's the new default realm.
+ * Otherwise, the realm(s) are figured out from configuration or DNS.
+ */
+
+krb5_error_code
+krb5_set_default_realm(krb5_context context,
+ char *realm)
+{
+ krb5_error_code ret = 0;
+ krb5_realm *realms = NULL;
+
+ if (realm == NULL) {
+ realms = krb5_config_get_strings (context, NULL,
+ "libdefaults",
+ "default_realm",
+ NULL);
+ if (realms == NULL)
+ ret = krb5_get_host_realm(context, NULL, &realms);
+ } else {
+ ret = string_to_list (realm, &realms);
+ }
+ if (ret)
+ return ret;
+ krb5_free_host_realm (context, context->default_realms);
+ context->default_realms = realms;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/sock_principal.c b/crypto/heimdal/lib/krb5/sock_principal.c
new file mode 100644
index 0000000..bfd4eb4
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/sock_principal.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: sock_principal.c,v 1.9 1999/12/02 17:05:12 joda Exp $");
+
+krb5_error_code
+krb5_sock_to_principal (krb5_context context,
+ int sock,
+ const char *sname,
+ int32_t type,
+ krb5_principal *ret_princ)
+{
+ krb5_error_code ret;
+ krb5_address address;
+ struct sockaddr_storage __ss;
+ struct sockaddr *sa = (struct sockaddr *)&__ss;
+ int len = sizeof(__ss);
+ struct hostent *hostent;
+ int family;
+ char hname[256];
+
+ if (getsockname (sock, sa, &len) < 0)
+ return errno;
+ family = sa->sa_family;
+
+ ret = krb5_sockaddr2address (sa, &address);
+ if (ret)
+ return ret;
+
+ hostent = roken_gethostbyaddr (address.address.data,
+ address.address.length,
+ family);
+
+ if (hostent == NULL)
+ return h_errno;
+ strlcpy(hname, hostent->h_name, sizeof(hname));
+ return krb5_sname_to_principal (context,
+ hname,
+ sname,
+ type,
+ ret_princ);
+}
diff --git a/crypto/heimdal/lib/krb5/store.c b/crypto/heimdal/lib/krb5/store.c
new file mode 100644
index 0000000..17b1547
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store.c
@@ -0,0 +1,609 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store.c,v 1.32 1999/12/02 17:05:12 joda Exp $");
+
+void
+krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
+{
+ sp->flags |= flags;
+}
+
+void
+krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
+{
+ sp->flags &= ~flags;
+}
+
+krb5_boolean
+krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
+{
+ return (sp->flags & flags) == flags;
+}
+
+ssize_t
+_krb5_put_int(void *buffer, unsigned long value, size_t size)
+{
+ unsigned char *p = buffer;
+ int i;
+ for (i = size - 1; i >= 0; i--) {
+ p[i] = value & 0xff;
+ value >>= 8;
+ }
+ return size;
+}
+
+ssize_t
+_krb5_get_int(void *buffer, unsigned long *value, size_t size)
+{
+ unsigned char *p = buffer;
+ unsigned long v = 0;
+ int i;
+ for (i = 0; i < size; i++)
+ v = (v << 8) + p[i];
+ *value = v;
+ return size;
+}
+
+krb5_error_code
+krb5_storage_free(krb5_storage *sp)
+{
+ if(sp->free)
+ (*sp->free)(sp);
+ free(sp->data);
+ free(sp);
+ return 0;
+}
+
+krb5_error_code
+krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
+{
+ off_t pos;
+ size_t size;
+ krb5_error_code ret;
+
+ pos = sp->seek(sp, 0, SEEK_CUR);
+ size = (size_t)sp->seek(sp, 0, SEEK_END);
+ ret = krb5_data_alloc (data, size);
+ if (ret) {
+ sp->seek(sp, pos, SEEK_SET);
+ return ret;
+ }
+ if (size) {
+ sp->seek(sp, 0, SEEK_SET);
+ sp->fetch(sp, data->data, data->length);
+ sp->seek(sp, pos, SEEK_SET);
+ }
+ return 0;
+}
+
+static krb5_error_code
+krb5_store_int(krb5_storage *sp,
+ int32_t value,
+ size_t len)
+{
+ int ret;
+ unsigned char v[4];
+
+ _krb5_put_int(v, value, len);
+ ret = sp->store(sp, v, len);
+ if (ret != len)
+ return (ret<0)?errno:KRB5_CC_END;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_int32(krb5_storage *sp,
+ int32_t value)
+{
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ value = htonl(value);
+ return krb5_store_int(sp, value, 4);
+}
+
+static krb5_error_code
+krb5_ret_int(krb5_storage *sp,
+ int32_t *value,
+ size_t len)
+{
+ int ret;
+ unsigned char v[4];
+ unsigned long w;
+ ret = sp->fetch(sp, v, len);
+ if(ret != len)
+ return (ret<0)?errno:KRB5_CC_END;
+ _krb5_get_int(v, &w, len);
+ *value = w;
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_int32(krb5_storage *sp,
+ int32_t *value)
+{
+ krb5_error_code ret = krb5_ret_int(sp, value, 4);
+ if(ret)
+ return ret;
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ *value = ntohl(*value);
+ return 0;
+}
+
+krb5_error_code
+krb5_store_int16(krb5_storage *sp,
+ int16_t value)
+{
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ value = htons(value);
+ return krb5_store_int(sp, value, 2);
+}
+
+krb5_error_code
+krb5_ret_int16(krb5_storage *sp,
+ int16_t *value)
+{
+ int32_t v;
+ int ret;
+ ret = krb5_ret_int(sp, &v, 2);
+ if(ret)
+ return ret;
+ *value = v;
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER))
+ *value = ntohs(*value);
+ return 0;
+}
+
+krb5_error_code
+krb5_store_int8(krb5_storage *sp,
+ int8_t value)
+{
+ int ret;
+
+ ret = sp->store(sp, &value, sizeof(value));
+ if (ret != sizeof(value))
+ return (ret<0)?errno:KRB5_CC_END;
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_int8(krb5_storage *sp,
+ int8_t *value)
+{
+ int ret;
+
+ ret = sp->fetch(sp, value, sizeof(*value));
+ if (ret != sizeof(*value))
+ return (ret<0)?errno:KRB5_CC_END;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_data(krb5_storage *sp,
+ krb5_data data)
+{
+ int ret;
+ ret = krb5_store_int32(sp, data.length);
+ if(ret < 0)
+ return ret;
+ ret = sp->store(sp, data.data, data.length);
+ if(ret != data.length){
+ if(ret < 0)
+ return errno;
+ return KRB5_CC_END;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_data(krb5_storage *sp,
+ krb5_data *data)
+{
+ int ret;
+ int32_t size;
+
+ ret = krb5_ret_int32(sp, &size);
+ if(ret)
+ return ret;
+ ret = krb5_data_alloc (data, size);
+ if (ret)
+ return ret;
+ if (size) {
+ ret = sp->fetch(sp, data->data, size);
+ if(ret != size)
+ return (ret < 0)? errno : KRB5_CC_END;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_store_string(krb5_storage *sp, const char *s)
+{
+ krb5_data data;
+ data.length = strlen(s);
+ data.data = (void*)s;
+ return krb5_store_data(sp, data);
+}
+
+krb5_error_code
+krb5_ret_string(krb5_storage *sp,
+ char **string)
+{
+ int ret;
+ krb5_data data;
+ ret = krb5_ret_data(sp, &data);
+ if(ret)
+ return ret;
+ *string = realloc(data.data, data.length + 1);
+ if(*string == NULL){
+ free(data.data);
+ return ENOMEM;
+ }
+ (*string)[data.length] = 0;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_stringz(krb5_storage *sp,
+ char *s)
+{
+ size_t len = strlen(s) + 1;
+ ssize_t ret;
+
+ ret = sp->store(sp, s, len);
+ if(ret != len) {
+ if(ret < 0)
+ return ret;
+ else
+ return KRB5_CC_END;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_stringz(krb5_storage *sp,
+ char **string)
+{
+ char c;
+ char *s = NULL;
+ size_t len = 0;
+ ssize_t ret;
+
+ while((ret = sp->fetch(sp, &c, 1)) == 1){
+ char *tmp;
+
+ len++;
+ tmp = realloc (s, len);
+ if (tmp == NULL) {
+ free (s);
+ return ENOMEM;
+ }
+ s = tmp;
+ s[len - 1] = c;
+ if(c == 0)
+ break;
+ }
+ if(ret != 1){
+ free(s);
+ if(ret == 0)
+ return KRB5_CC_END;
+ return ret;
+ }
+ *string = s;
+ return 0;
+}
+
+
+krb5_error_code
+krb5_store_principal(krb5_storage *sp,
+ krb5_principal p)
+{
+ int i;
+ int ret;
+
+ if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
+ ret = krb5_store_int32(sp, p->name.name_type);
+ if(ret) return ret;
+ }
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
+ ret = krb5_store_int32(sp, p->name.name_string.len + 1);
+ else
+ ret = krb5_store_int32(sp, p->name.name_string.len);
+
+ if(ret) return ret;
+ ret = krb5_store_string(sp, p->realm);
+ if(ret) return ret;
+ for(i = 0; i < p->name.name_string.len; i++){
+ ret = krb5_store_string(sp, p->name.name_string.val[i]);
+ if(ret) return ret;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_principal(krb5_storage *sp,
+ krb5_principal *princ)
+{
+ int i;
+ int ret;
+ krb5_principal p;
+ int32_t type;
+ int32_t ncomp;
+
+ p = calloc(1, sizeof(*p));
+ if(p == NULL)
+ return ENOMEM;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
+ type = KRB5_NT_UNKNOWN;
+ else if((ret = krb5_ret_int32(sp, &type))){
+ free(p);
+ return ret;
+ }
+ if((ret = krb5_ret_int32(sp, &ncomp))){
+ free(p);
+ return ret;
+ }
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
+ ncomp--;
+ p->name.name_type = type;
+ p->name.name_string.len = ncomp;
+ ret = krb5_ret_string(sp, &p->realm);
+ if(ret) return ret;
+ p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
+ if(p->name.name_string.val == NULL){
+ free(p->realm);
+ return ENOMEM;
+ }
+ for(i = 0; i < ncomp; i++){
+ ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
+ if(ret) return ret; /* XXX */
+ }
+ *princ = p;
+ return 0;
+}
+
+krb5_error_code
+krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
+{
+ int ret;
+ ret = krb5_store_int16(sp, p.keytype);
+ if(ret) return ret;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
+ /* this should really be enctype, but it is the same as
+ keytype nowadays */
+ ret = krb5_store_int16(sp, p.keytype);
+ if(ret) return ret;
+ }
+
+ ret = krb5_store_data(sp, p.keyvalue);
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
+{
+ int ret;
+ int16_t tmp;
+
+ ret = krb5_ret_int16(sp, &tmp);
+ if(ret) return ret;
+ p->keytype = tmp;
+
+ if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
+ ret = krb5_ret_int16(sp, &tmp);
+ if(ret) return ret;
+ }
+
+ ret = krb5_ret_data(sp, &p->keyvalue);
+ return ret;
+}
+
+krb5_error_code
+krb5_store_times(krb5_storage *sp, krb5_times times)
+{
+ int ret;
+ ret = krb5_store_int32(sp, times.authtime);
+ if(ret) return ret;
+ ret = krb5_store_int32(sp, times.starttime);
+ if(ret) return ret;
+ ret = krb5_store_int32(sp, times.endtime);
+ if(ret) return ret;
+ ret = krb5_store_int32(sp, times.renew_till);
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_times(krb5_storage *sp, krb5_times *times)
+{
+ int ret;
+ int32_t tmp;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->authtime = tmp;
+ if(ret) return ret;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->starttime = tmp;
+ if(ret) return ret;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->endtime = tmp;
+ if(ret) return ret;
+ ret = krb5_ret_int32(sp, &tmp);
+ times->renew_till = tmp;
+ return ret;
+}
+
+krb5_error_code
+krb5_store_address(krb5_storage *sp, krb5_address p)
+{
+ int ret;
+ ret = krb5_store_int16(sp, p.addr_type);
+ if(ret) return ret;
+ ret = krb5_store_data(sp, p.address);
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_address(krb5_storage *sp, krb5_address *adr)
+{
+ int16_t t;
+ int ret;
+ ret = krb5_ret_int16(sp, &t);
+ if(ret) return ret;
+ adr->addr_type = t;
+ ret = krb5_ret_data(sp, &adr->address);
+ return ret;
+}
+
+krb5_error_code
+krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
+{
+ int i;
+ int ret;
+ ret = krb5_store_int32(sp, p.len);
+ if(ret) return ret;
+ for(i = 0; i<p.len; i++){
+ ret = krb5_store_address(sp, p.val[i]);
+ if(ret) break;
+ }
+ return ret;
+}
+
+krb5_error_code
+krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
+{
+ int i;
+ int ret;
+ int32_t tmp;
+
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret) return ret;
+ adr->len = tmp;
+ ALLOC(adr->val, adr->len);
+ for(i = 0; i < adr->len; i++){
+ ret = krb5_ret_address(sp, &adr->val[i]);
+ if(ret) break;
+ }
+ return ret;
+}
+
+krb5_error_code
+krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
+{
+ krb5_error_code ret;
+ int i;
+ ret = krb5_store_int32(sp, auth.len);
+ if(ret) return ret;
+ for(i = 0; i < auth.len; i++){
+ ret = krb5_store_int16(sp, auth.val[i].ad_type);
+ if(ret) break;
+ ret = krb5_store_data(sp, auth.val[i].ad_data);
+ if(ret) break;
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
+{
+ krb5_error_code ret;
+ int32_t tmp;
+ int16_t tmp2;
+ int i;
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret) return ret;
+ ALLOC_SEQ(auth, tmp);
+ for(i = 0; i < tmp; i++){
+ ret = krb5_ret_int16(sp, &tmp2);
+ if(ret) break;
+ auth->val[i].ad_type = tmp2;
+ ret = krb5_ret_data(sp, &auth->val[i].ad_data);
+ if(ret) break;
+ }
+ return ret;
+}
+
+krb5_error_code
+krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
+{
+ krb5_store_principal(sp, creds->client);
+ krb5_store_principal(sp, creds->server);
+ krb5_store_keyblock(sp, creds->session);
+ krb5_store_times(sp, creds->times);
+ krb5_store_int8(sp, 0); /* this is probably the
+ enc-tkt-in-skey bit from KDCOptions */
+ krb5_store_int32(sp, creds->flags.i);
+ krb5_store_addrs(sp, creds->addresses);
+ krb5_store_authdata(sp, creds->authdata);
+ krb5_store_data(sp, creds->ticket);
+ krb5_store_data(sp, creds->second_ticket);
+ return 0;
+}
+
+krb5_error_code
+krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
+{
+ krb5_error_code ret;
+ int8_t dummy8;
+ int32_t dummy32;
+
+ memset(creds, 0, sizeof(*creds));
+ ret = krb5_ret_principal (sp, &creds->client);
+ if(ret) goto cleanup;
+ ret = krb5_ret_principal (sp, &creds->server);
+ if(ret) goto cleanup;
+ ret = krb5_ret_keyblock (sp, &creds->session);
+ if(ret) goto cleanup;
+ ret = krb5_ret_times (sp, &creds->times);
+ if(ret) goto cleanup;
+ ret = krb5_ret_int8 (sp, &dummy8);
+ if(ret) goto cleanup;
+ ret = krb5_ret_int32 (sp, &dummy32);
+ if(ret) goto cleanup;
+ creds->flags.i = dummy32;
+ ret = krb5_ret_addrs (sp, &creds->addresses);
+ if(ret) goto cleanup;
+ ret = krb5_ret_authdata (sp, &creds->authdata);
+ if(ret) goto cleanup;
+ ret = krb5_ret_data (sp, &creds->ticket);
+ if(ret) goto cleanup;
+ ret = krb5_ret_data (sp, &creds->second_ticket);
+cleanup:
+ if(ret)
+#if 0
+ krb5_free_creds_contents(context, creds) /* XXX */
+#endif
+ ;
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/store_emem.c b/crypto/heimdal/lib/krb5/store_emem.c
new file mode 100644
index 0000000..d2497ef
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store_emem.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store_emem.c,v 1.9 1999/12/02 17:05:12 joda Exp $");
+
+typedef struct emem_storage{
+ unsigned char *base;
+ size_t size;
+ size_t len;
+ unsigned char *ptr;
+}emem_storage;
+
+static ssize_t
+emem_fetch(krb5_storage *sp, void *data, size_t size)
+{
+ emem_storage *s = (emem_storage*)sp->data;
+ if(s->base + s->len - s->ptr < size)
+ size = s->base + s->len - s->ptr;
+ memmove(data, s->ptr, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static ssize_t
+emem_store(krb5_storage *sp, void *data, size_t size)
+{
+ emem_storage *s = (emem_storage*)sp->data;
+ if(size > s->base + s->size - s->ptr){
+ void *base;
+ size_t sz, off;
+ sz = 2 * (size + (s->ptr - s->base)); /* XXX */
+ off = s->ptr - s->base;
+ base = realloc(s->base, sz);
+ if(base == NULL)
+ return 0;
+ s->size = sz;
+ s->base = base;
+ s->ptr = (unsigned char*)base + off;
+ }
+ memmove(s->ptr, data, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static off_t
+emem_seek(krb5_storage *sp, off_t offset, int whence)
+{
+ emem_storage *s = (emem_storage*)sp->data;
+ switch(whence){
+ case SEEK_SET:
+ if(offset > s->size)
+ offset = s->size;
+ if(offset < 0)
+ offset = 0;
+ s->ptr = s->base + offset;
+ if(offset > s->len)
+ s->len = offset;
+ break;
+ case SEEK_CUR:
+ sp->seek(sp,s->ptr - s->base + offset, SEEK_SET);
+ break;
+ case SEEK_END:
+ sp->seek(sp, s->len + offset, SEEK_SET);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ return s->ptr - s->base;
+}
+
+static void
+emem_free(krb5_storage *sp)
+{
+ free(((emem_storage*)sp->data)->base);
+}
+
+krb5_storage *
+krb5_storage_emem(void)
+{
+ krb5_storage *sp = malloc(sizeof(krb5_storage));
+ emem_storage *s = malloc(sizeof(*s));
+ sp->data = s;
+ sp->flags = 0;
+ s->size = 1024;
+ s->base = malloc(s->size);
+ s->len = 0;
+ s->ptr = s->base;
+ sp->fetch = emem_fetch;
+ sp->store = emem_store;
+ sp->seek = emem_seek;
+ sp->free = emem_free;
+ return sp;
+}
diff --git a/crypto/heimdal/lib/krb5/store_fd.c b/crypto/heimdal/lib/krb5/store_fd.c
new file mode 100644
index 0000000..e4c507c
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store_fd.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store_fd.c,v 1.6 1999/12/02 17:05:13 joda Exp $");
+
+typedef struct fd_storage{
+ int fd;
+}fd_storage;
+
+#define FD(S) (((fd_storage*)(S)->data)->fd)
+
+static ssize_t
+fd_fetch(krb5_storage *sp, void *data, size_t size)
+{
+ return read(FD(sp), data, size);
+}
+
+static ssize_t
+fd_store(krb5_storage *sp, void *data, size_t size)
+{
+ return write(FD(sp), data, size);
+}
+
+static off_t
+fd_seek(krb5_storage *sp, off_t offset, int whence)
+{
+ return lseek(FD(sp), offset, whence);
+}
+
+krb5_storage *
+krb5_storage_from_fd(int fd)
+{
+ krb5_storage *sp = malloc(sizeof(krb5_storage));
+ sp->data = malloc(sizeof(fd_storage));
+ sp->flags = 0;
+ FD(sp) = fd;
+ sp->fetch = fd_fetch;
+ sp->store = fd_store;
+ sp->seek = fd_seek;
+ sp->free = NULL;
+ return sp;
+}
diff --git a/crypto/heimdal/lib/krb5/store_mem.c b/crypto/heimdal/lib/krb5/store_mem.c
new file mode 100644
index 0000000..a8019e6
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/store_mem.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: store_mem.c,v 1.9 1999/12/02 17:05:13 joda Exp $");
+
+typedef struct mem_storage{
+ unsigned char *base;
+ size_t size;
+ unsigned char *ptr;
+}mem_storage;
+
+static ssize_t
+mem_fetch(krb5_storage *sp, void *data, size_t size)
+{
+ mem_storage *s = (mem_storage*)sp->data;
+ if(size > s->base + s->size - s->ptr)
+ size = s->base + s->size - s->ptr;
+ memmove(data, s->ptr, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static ssize_t
+mem_store(krb5_storage *sp, void *data, size_t size)
+{
+ mem_storage *s = (mem_storage*)sp->data;
+ if(size > s->base + s->size - s->ptr)
+ size = s->base + s->size - s->ptr;
+ memmove(s->ptr, data, size);
+ sp->seek(sp, size, SEEK_CUR);
+ return size;
+}
+
+static off_t
+mem_seek(krb5_storage *sp, off_t offset, int whence)
+{
+ mem_storage *s = (mem_storage*)sp->data;
+ switch(whence){
+ case SEEK_SET:
+ if(offset > s->size)
+ offset = s->size;
+ if(offset < 0)
+ offset = 0;
+ s->ptr = s->base + offset;
+ break;
+ case SEEK_CUR:
+ return sp->seek(sp, s->ptr - s->base + offset, SEEK_SET);
+ case SEEK_END:
+ return sp->seek(sp, s->size + offset, SEEK_SET);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ return s->ptr - s->base;
+}
+
+krb5_storage *
+krb5_storage_from_mem(void *buf, size_t len)
+{
+ krb5_storage *sp = malloc(sizeof(krb5_storage));
+ mem_storage *s;
+ if(sp == NULL)
+ return NULL;
+ s = malloc(sizeof(*s));
+ if(s == NULL) {
+ free(sp);
+ return NULL;
+ }
+ sp->data = s;
+ sp->flags = 0;
+ s->base = buf;
+ s->size = len;
+ s->ptr = buf;
+ sp->fetch = mem_fetch;
+ sp->store = mem_store;
+ sp->seek = mem_seek;
+ sp->free = NULL;
+ return sp;
+}
+
+krb5_storage *
+krb5_storage_from_data(krb5_data *data)
+{
+ return krb5_storage_from_mem(data->data, data->length);
+}
diff --git a/crypto/heimdal/lib/krb5/string-to-key-test.c b/crypto/heimdal/lib/krb5/string-to-key-test.c
new file mode 100644
index 0000000..0e884d0
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/string-to-key-test.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: string-to-key-test.c,v 1.2 1999/10/28 23:10:38 assar Exp $");
+
+enum { MAXSIZE = 24 };
+
+static struct testcase {
+ const char *principal_name;
+ const char *password;
+ krb5_enctype enctype;
+ unsigned char res[MAXSIZE];
+} tests[] = {
+ {"@", "", ETYPE_DES_CBC_MD5,
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}},
+ {"nisse@FOO.SE", "hej", ETYPE_DES_CBC_MD5,
+ {0xfe, 0x67, 0xbf, 0x9e, 0x57, 0x6b, 0xfe, 0x52}},
+ {"assar/liten@FOO.SE", "hemligt", ETYPE_DES_CBC_MD5,
+ {0x5b, 0x9b, 0xcb, 0xf2, 0x97, 0x43, 0xc8, 0x40}},
+ {"@", "", ETYPE_DES3_CBC_SHA1,
+ {0xce, 0xa2, 0x2f, 0x9b, 0x52, 0x2c, 0xb0, 0x15, 0x6e, 0x6b, 0x64,
+ 0x73, 0x62, 0x64, 0x73, 0x4f, 0x6e, 0x73, 0xce, 0xa2, 0x2f, 0x9b,
+ 0x52, 0x57}},
+ {"nisse@FOO.SE", "hej", ETYPE_DES3_CBC_SHA1,
+ {0x0e, 0xbc, 0x23, 0x9d, 0x68, 0x46, 0xf2, 0xd5, 0x51, 0x98, 0x5b,
+ 0x57, 0xc1, 0x57, 0x01, 0x79, 0x04, 0xc4, 0xe9, 0xfe, 0xc1, 0x0e,
+ 0x13, 0xd0}},
+ {"assar/liten@FOO.SE", "hemligt", ETYPE_DES3_CBC_SHA1,
+ {0x7f, 0x40, 0x67, 0xb9, 0xbc, 0xc4, 0x40, 0xfb, 0x43, 0x73, 0xd9,
+ 0xd3, 0xcd, 0x7c, 0xc7, 0x67, 0xe6, 0x79, 0x94, 0xd0, 0xa8, 0x34,
+ 0xdf, 0x62}},
+ {NULL}
+};
+
+int
+main(int argc, char **argv)
+{
+ struct testcase *t;
+ krb5_context context;
+ krb5_error_code ret;
+ int val = 0;
+
+ krb5_init_context (&context);
+
+ for (t = tests; t->principal_name; ++t) {
+ krb5_keyblock key;
+ krb5_principal principal;
+ int i;
+
+ ret = krb5_parse_name (context, t->principal_name, &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s",
+ t->principal_name);
+ ret = krb5_string_to_key (context, t->enctype, t->password,
+ principal, &key);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_string_to_key");
+ krb5_free_principal (context, principal);
+ if (memcmp (key.keyvalue.data, t->res, key.keyvalue.length) != 0) {
+ const unsigned char *p = key.keyvalue.data;
+
+ printf ("string_to_key(%s, %s) failed\n",
+ t->principal_name, t->password);
+ printf ("should be: ");
+ for (i = 0; i < key.keyvalue.length; ++i)
+ printf ("%02x", t->res[i]);
+ printf ("\nresult was: ");
+ for (i = 0; i < key.keyvalue.length; ++i)
+ printf ("%02x", p[i]);
+ printf ("\n");
+ val = 1;
+ }
+ }
+ return val;
+}
diff --git a/crypto/heimdal/lib/krb5/ticket.c b/crypto/heimdal/lib/krb5/ticket.c
new file mode 100644
index 0000000..ecb5821
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/ticket.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: ticket.c,v 1.4 1999/12/02 17:05:13 joda Exp $");
+
+krb5_error_code
+krb5_free_ticket(krb5_context context,
+ krb5_ticket *ticket)
+{
+ free_EncTicketPart(&ticket->ticket);
+ krb5_free_principal(context, ticket->client);
+ krb5_free_principal(context, ticket->server);
+ return 0;
+}
+
+krb5_error_code
+krb5_copy_ticket(krb5_context context,
+ const krb5_ticket *from,
+ krb5_ticket **to)
+{
+ krb5_error_code ret;
+ krb5_ticket *tmp = malloc(sizeof(*tmp));
+ if(tmp == NULL)
+ return ENOMEM;
+ if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){
+ free(tmp);
+ return ret;
+ }
+ ret = krb5_copy_principal(context, from->client, &tmp->client);
+ if(ret){
+ free_EncTicketPart(&tmp->ticket);
+ return ret;
+ }
+ ret = krb5_copy_principal(context, from->server, &(*to)->server);
+ if(ret){
+ krb5_free_principal(context, tmp->client);
+ free_EncTicketPart(&tmp->ticket);
+ return ret;
+ }
+ *to = tmp;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/time.c b/crypto/heimdal/lib/krb5/time.c
new file mode 100644
index 0000000..47a5f0b
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/time.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: time.c,v 1.2 1999/12/02 17:05:13 joda Exp $");
+
+krb5_error_code
+krb5_timeofday (krb5_context context,
+ int32_t *timeret)
+{
+ *timeret = time(NULL) + context->kdc_sec_offset;
+ return 0;
+}
+
+krb5_error_code
+krb5_us_timeofday (krb5_context context,
+ int32_t *sec,
+ int32_t *usec)
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ *sec = tv.tv_sec + context->kdc_sec_offset;
+ *usec = tv.tv_usec; /* XXX */
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/transited.c b/crypto/heimdal/lib/krb5/transited.c
new file mode 100644
index 0000000..ed5a5b5
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/transited.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: transited.c,v 1.5 1999/12/02 17:05:13 joda Exp $");
+
+/* this is an attempt at one of the most horrible `compression'
+ schemes that has ever been invented; it's so amazingly brain-dead
+ that words can not describe it, and all this just to save a few
+ silly bytes */
+
+struct tr_realm {
+ char *realm;
+ unsigned leading_space:1;
+ unsigned leading_slash:1;
+ unsigned trailing_dot:1;
+ struct tr_realm *next;
+};
+
+static void
+free_realms(struct tr_realm *r)
+{
+ struct tr_realm *p;
+ while(r){
+ p = r;
+ r = r->next;
+ free(p->realm);
+ free(p);
+ }
+}
+
+static int
+make_path(struct tr_realm *r, const char *from, const char *to)
+{
+ const char *p;
+ struct tr_realm *path = r->next;
+ struct tr_realm *tmp;
+
+ if(strlen(from) < strlen(to)){
+ const char *tmp;
+ tmp = from;
+ from = to;
+ to = tmp;
+ }
+
+ if(strcmp(from + strlen(from) - strlen(to), to) == 0){
+ p = from;
+ while(1){
+ p = strchr(p, '.');
+ if(p == NULL)
+ return KRB5KDC_ERR_POLICY;
+ p++;
+ if(strcmp(p, to) == 0)
+ break;
+ tmp = calloc(1, sizeof(*tmp));
+ tmp->next = path;
+ path = tmp;
+ path->realm = strdup(p);
+ if(path->realm == NULL){
+ r->next = path; /* XXX */
+ return ENOMEM;;
+ }
+ }
+ }else if(strncmp(from, to, strlen(to)) == 0){
+ p = from + strlen(from);
+ while(1){
+ while(p >= from && *p != '/') p--;
+ if(p == from)
+ return KRB5KDC_ERR_POLICY;
+ if(strncmp(to, from, p - from) == 0)
+ break;
+ tmp = calloc(1, sizeof(*tmp));
+ tmp->next = path;
+ path = tmp;
+ path->realm = malloc(p - from + 1);
+ if(path->realm == NULL){
+ r->next = path; /* XXX */
+ return ENOMEM;
+ }
+ strncpy(path->realm, from, p - from);
+ path->realm[p - from] = '\0';
+ p--;
+ }
+ }else
+ return KRB5KDC_ERR_POLICY;
+ r->next = path;
+
+ return 0;
+}
+
+static int
+make_paths(struct tr_realm *realms, const char *client_realm,
+ const char *server_realm)
+{
+ struct tr_realm *r;
+ int ret;
+ const char *prev_realm = client_realm;
+ const char *next_realm = NULL;
+ for(r = realms; r; r = r->next){
+ /* it *might* be that you can have more than one empty
+ component in a row, at least that's how I interpret the
+ "," exception in 1510 */
+ if(r->realm[0] == '\0'){
+ while(r->next && r->next->realm[0] == '\0')
+ r = r->next;
+ if(r->next)
+ next_realm = r->next->realm;
+ else
+ next_realm = server_realm;
+ ret = make_path(r, prev_realm, next_realm);
+ if(ret){
+ free_realms(realms);
+ return ret;
+ }
+ }
+ prev_realm = r->realm;
+ }
+ return 0;
+}
+
+static int
+expand_realms(struct tr_realm *realms, const char *client_realm)
+{
+ struct tr_realm *r;
+ const char *prev_realm = NULL;
+ for(r = realms; r; r = r->next){
+ if(r->trailing_dot){
+ char *tmp;
+ if(prev_realm == NULL)
+ prev_realm = client_realm;
+ tmp = realloc(r->realm, strlen(r->realm) + strlen(prev_realm) + 1);
+ if(tmp == NULL){
+ free_realms(realms);
+ return ENOMEM;
+ }
+ r->realm = tmp;
+ strcat(r->realm, prev_realm);
+ }else if(r->leading_slash && !r->leading_space && prev_realm){
+ /* yet another exception: if you use x500-names, the
+ leading realm doesn't have to be "quoted" with a space */
+ char *tmp;
+ tmp = malloc(strlen(r->realm) + strlen(prev_realm) + 1);
+ if(tmp == NULL){
+ free_realms(realms);
+ return ENOMEM;
+ }
+ strcpy(tmp, prev_realm);
+ strcat(tmp, r->realm);
+ free(r->realm);
+ r->realm = tmp;
+ }
+ prev_realm = r->realm;
+ }
+ return 0;
+}
+
+static struct tr_realm *
+make_realm(char *realm)
+{
+ struct tr_realm *r;
+ char *p, *q;
+ int quote = 0;
+ r = calloc(1, sizeof(*r));
+ if(r == NULL){
+ free(realm);
+ return NULL;
+ }
+ r->realm = realm;
+ for(p = q = r->realm; *p; p++){
+ if(p == r->realm && *p == ' '){
+ r->leading_space = 1;
+ continue;
+ }
+ if(q == r->realm && *p == '/')
+ r->leading_slash = 1;
+ if(quote){
+ *q++ = *p;
+ quote = 0;
+ continue;
+ }
+ if(*p == '\\'){
+ quote = 1;
+ continue;
+ }
+ if(p[0] == '.' && p[1] == '\0')
+ r->trailing_dot = 1;
+ *q++ = *p;
+ }
+ *q = '\0';
+ return r;
+}
+
+static struct tr_realm*
+append_realm(struct tr_realm *head, struct tr_realm *r)
+{
+ struct tr_realm *p;
+ if(head == NULL){
+ r->next = NULL;
+ return r;
+ }
+ p = head;
+ while(p->next) p = p->next;
+ p->next = r;
+ return head;
+}
+
+static int
+decode_realms(const char *tr, int length, struct tr_realm **realms)
+{
+ struct tr_realm *r = NULL;
+
+ char *tmp;
+ int quote = 0;
+ const char *start = tr;
+ int i;
+
+ for(i = 0; i < length; i++){
+ if(quote){
+ quote = 0;
+ continue;
+ }
+ if(tr[i] == '\\'){
+ quote = 1;
+ continue;
+ }
+ if(tr[i] == ','){
+ tmp = malloc(tr + i - start + 1);
+ strncpy(tmp, start, tr + i - start);
+ tmp[tr + i - start] = '\0';
+ r = make_realm(tmp);
+ if(r == NULL){
+ free_realms(*realms);
+ return ENOMEM;
+ }
+ *realms = append_realm(*realms, r);
+ start = tr + i + 1;
+ }
+ }
+ tmp = malloc(tr + i - start + 1);
+ strncpy(tmp, start, tr + i - start);
+ tmp[tr + i - start] = '\0';
+ r = make_realm(tmp);
+ if(r == NULL){
+ free_realms(*realms);
+ return ENOMEM;
+ }
+ *realms = append_realm(*realms, r);
+
+ return 0;
+}
+
+
+krb5_error_code
+krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
+ const char *client_realm, const char *server_realm)
+{
+ struct tr_realm *r = NULL;
+ struct tr_realm *p, **q;
+ int ret;
+
+ /* split string in components */
+ ret = decode_realms(tr.data, tr.length, &r);
+ if(ret)
+ return ret;
+
+ /* apply prefix rule */
+ ret = expand_realms(r, client_realm);
+ if(ret)
+ return ret;
+
+ ret = make_paths(r, client_realm, server_realm);
+ if(ret)
+ return ret;
+
+ /* remove empty components */
+ q = &r;
+ for(p = r; p; ){
+ if(p->realm[0] == '\0'){
+ free(p->realm);
+ *q = p->next;
+ free(p);
+ p = *q;
+ }else{
+ q = &p->next;
+ p = p->next;
+ }
+ }
+ {
+ char **R;
+ *realms = NULL;
+ *num_realms = 0;
+ while(r){
+ R = realloc(*realms, (*num_realms + 1) * sizeof(**realms));
+ if(R == NULL) {
+ free(*realms);
+ return ENOMEM;
+ }
+ R[*num_realms] = r->realm;
+ (*num_realms)++;
+ *realms = R;
+ p = r->next;
+ free(r);
+ r = p;
+ }
+ }
+ return 0;
+}
+
+krb5_error_code
+krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
+{
+ char *s = NULL;
+ int len = 0;
+ int i;
+ for(i = 0; i < num_realms; i++){
+ len += strlen(realms[i]);
+ if(realms[i][0] == '/')
+ len++;
+ }
+ len += num_realms - 1;
+ s = malloc(len + 1);
+ *s = '\0';
+ for(i = 0; i < num_realms; i++){
+ if(i && i < num_realms - 1)
+ strcat(s, ",");
+ if(realms[i][0] == '/')
+ strcat(s, " ");
+ strcat(s, realms[i]);
+ }
+ encoding->data = s;
+ encoding->length = strlen(s);
+ return 0;
+}
+
+#if 0
+int
+main(int argc, char **argv)
+{
+ krb5_data x;
+ char **r;
+ int num, i;
+ x.data = argv[1];
+ x.length = strlen(x.data);
+ if(domain_expand(x, &r, &num, argv[2], argv[3]))
+ exit(1);
+ for(i = 0; i < num; i++)
+ printf("%s\n", r[i]);
+ return 0;
+}
+#endif
+
diff --git a/crypto/heimdal/lib/krb5/verify_init.c b/crypto/heimdal/lib/krb5/verify_init.c
new file mode 100644
index 0000000..0f080ee
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/verify_init.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: verify_init.c,v 1.11 1999/12/02 17:05:13 joda Exp $");
+
+void
+krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt *options)
+{
+ memset (options, 0, sizeof(*options));
+}
+
+void
+krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_verify_init_creds_opt *options,
+ int ap_req_nofail)
+{
+ options->flags |= KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL;
+ options->ap_req_nofail = ap_req_nofail;
+}
+
+/*
+ *
+ */
+
+static krb5_boolean
+fail_verify_is_ok (krb5_context context,
+ krb5_verify_init_creds_opt *options)
+{
+ if ((options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL
+ && options->ap_req_nofail == 1)
+ || krb5_config_get_bool (context,
+ NULL,
+ "libdefaults",
+ "verify_ap_req_nofail",
+ NULL))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+krb5_error_code
+krb5_verify_init_creds(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal ap_req_server,
+ krb5_keytab ap_req_keytab,
+ krb5_ccache *ccache,
+ krb5_verify_init_creds_opt *options)
+{
+ krb5_error_code ret;
+ krb5_data req;
+ krb5_ccache local_ccache;
+ krb5_keytab_entry entry;
+ krb5_creds *new_creds = NULL;
+ krb5_auth_context auth_context = NULL;
+ krb5_principal server = NULL;
+ krb5_keytab keytab = NULL;
+
+ krb5_data_zero (&req);
+ memset (&entry, 0, sizeof(entry));
+
+ if (ap_req_server == NULL) {
+ char local_hostname[MAXHOSTNAMELEN];
+
+ if (gethostname (local_hostname, sizeof(local_hostname)) < 0)
+ return errno;
+
+ ret = krb5_sname_to_principal (context,
+ local_hostname,
+ "host",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (ret)
+ goto cleanup;
+ } else
+ server = ap_req_server;
+
+ if (ap_req_keytab == NULL) {
+ ret = krb5_kt_default (context, &keytab);
+ if (ret)
+ goto cleanup;
+ } else
+ keytab = ap_req_keytab;
+
+ if (ccache && *ccache)
+ local_ccache = *ccache;
+ else {
+ ret = krb5_cc_gen_new (context, &krb5_mcc_ops, &local_ccache);
+ if (ret)
+ goto cleanup;
+ ret = krb5_cc_initialize (context,
+ local_ccache,
+ creds->client);
+ if (ret)
+ goto cleanup;
+ ret = krb5_cc_store_cred (context,
+ local_ccache,
+ creds);
+ if (ret)
+ goto cleanup;
+ }
+
+ if (!krb5_principal_compare (context, server, creds->server)) {
+ krb5_creds match_cred;
+
+ memset (&match_cred, 0, sizeof(match_cred));
+
+ match_cred.client = creds->client;
+ match_cred.server = server;
+
+ ret = krb5_get_credentials (context,
+ 0,
+ local_ccache,
+ &match_cred,
+ &new_creds);
+ if (ret) {
+ if (fail_verify_is_ok (context, options))
+ ret = 0;
+ goto cleanup;
+ }
+ } else
+ new_creds = creds;
+
+ ret = krb5_mk_req_extended (context,
+ &auth_context,
+ 0,
+ NULL,
+ new_creds,
+ &req);
+
+ krb5_auth_con_free (context, auth_context);
+ auth_context = NULL;
+
+ if (ret)
+ goto cleanup;
+
+ ret = krb5_rd_req (context,
+ &auth_context,
+ &req,
+ server,
+ keytab,
+ 0,
+ NULL);
+
+ if (ret == KRB5_KT_NOTFOUND && fail_verify_is_ok (context, options))
+ ret = 0;
+cleanup:
+ if (auth_context)
+ krb5_auth_con_free (context, auth_context);
+ krb5_data_free (&req);
+ krb5_kt_free_entry (context, &entry);
+ if (new_creds)
+ krb5_free_creds (context, new_creds);
+ if (ap_req_server == NULL && server)
+ krb5_free_principal (context, server);
+ if (ap_req_keytab == NULL && keytab)
+ krb5_kt_close (context, keytab);
+ if (ccache == NULL
+ || (ret != 0 && *ccache == NULL))
+ krb5_cc_destroy (context, local_ccache);
+
+ if (ret == 0 && ccache != NULL && *ccache == NULL)
+ *ccache = local_ccache;
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/krb5/verify_krb5_conf.c b/crypto/heimdal/lib/krb5/verify_krb5_conf.c
new file mode 100644
index 0000000..2b9ce28
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/verify_krb5_conf.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#include <getarg.h>
+RCSID("$Id: verify_krb5_conf.c,v 1.3 1999/12/02 17:05:13 joda Exp $");
+
+/* verify krb5.conf */
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag,
+ "print version", NULL },
+ {"help", 0, arg_flag, &help_flag,
+ NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[config-file]");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *config_file = NULL;
+ krb5_error_code ret;
+ krb5_config_section *tmp_cf;
+ unsigned lineno;
+ char *error_message;
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0) {
+ config_file = getenv("KRB5_CONFIG");
+ if (config_file == NULL)
+ config_file = krb5_config_file;
+ } else if (argc == 1) {
+ config_file = argv[0];
+ } else {
+ usage (1);
+ }
+
+ ret = krb5_config_parse_file_debug (config_file, &tmp_cf, &lineno,
+ &error_message);
+ if (ret == 0)
+ return 0;
+ fprintf (stderr, "%s:%u: %s\n", config_file, lineno, error_message);
+ return 1;
+}
diff --git a/crypto/heimdal/lib/krb5/verify_user.c b/crypto/heimdal/lib/krb5/verify_user.c
new file mode 100644
index 0000000..10c22cb
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/verify_user.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: verify_user.c,v 1.11 1999/12/02 17:05:13 joda Exp $");
+
+static krb5_error_code
+verify_common (krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ krb5_boolean secure,
+ const char *service,
+ krb5_creds cred)
+{
+ krb5_error_code ret;
+ krb5_principal server;
+ krb5_verify_init_creds_opt vopt;
+ krb5_ccache id;
+
+ ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST,
+ &server);
+ if(ret) return ret;
+
+ krb5_verify_init_creds_opt_init(&vopt);
+ krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure);
+
+ ret = krb5_verify_init_creds(context,
+ &cred,
+ server,
+ NULL,
+ NULL,
+ &vopt);
+ krb5_free_principal(context, server);
+ if(ret) return ret;
+ if(ccache == NULL)
+ ret = krb5_cc_default (context, &id);
+ else
+ id = ccache;
+ if(ret == 0){
+ ret = krb5_cc_initialize(context, id, principal);
+ if(ret == 0){
+ ret = krb5_cc_store_cred(context, id, &cred);
+ }
+ if(ccache == NULL)
+ krb5_cc_close(context, id);
+ }
+ krb5_free_creds_contents(context, &cred);
+ return ret;
+}
+
+/*
+ * Verify user `principal' with `password'.
+ *
+ * If `secure', also verify against local service key for `service'.
+ *
+ * As a side effect, fresh tickets are obtained and stored in `ccache'.
+ */
+
+krb5_error_code
+krb5_verify_user(krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service)
+{
+
+ krb5_error_code ret;
+ krb5_get_init_creds_opt opt;
+ krb5_creds cred;
+
+ krb5_get_init_creds_opt_init (&opt);
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ (char*)password,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ NULL,
+ &opt);
+
+ if(ret)
+ return ret;
+ return verify_common (context, principal, ccache, secure, service, cred);
+}
+
+/*
+ * A variant of `krb5_verify_user'. The realm of `principal' is
+ * ignored and all the local realms are tried.
+ */
+
+krb5_error_code
+krb5_verify_user_lrealm(krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ const char *password,
+ krb5_boolean secure,
+ const char *service)
+{
+ krb5_error_code ret;
+ krb5_get_init_creds_opt opt;
+ krb5_realm *realms, *r;
+ krb5_creds cred;
+
+ krb5_get_init_creds_opt_init (&opt);
+
+ ret = krb5_get_default_realms (context, &realms);
+ if (ret)
+ return ret;
+ ret = KRB5_CONFIG_NODEFREALM;
+
+ for (r = realms; *r != NULL && ret != 0; ++r) {
+ char *tmp = strdup (*r);
+
+ if (tmp == NULL) {
+ krb5_free_host_realm (context, realms);
+ return ENOMEM;
+ }
+ free (*krb5_princ_realm (context, principal));
+ krb5_princ_set_realm (context, principal, &tmp);
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ (char*)password,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ NULL,
+ &opt);
+ }
+ krb5_free_host_realm (context, realms);
+ if(ret)
+ return ret;
+
+ return verify_common (context, principal, ccache, secure, service, cred);
+}
diff --git a/crypto/heimdal/lib/krb5/version.c b/crypto/heimdal/lib/krb5/version.c
new file mode 100644
index 0000000..5f0fd66
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/version.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: version.c,v 1.3 1999/12/02 17:05:13 joda Exp $");
+
+/* this is just to get a version stamp in the library file */
+
+#define heimdal_version __heimdal_version
+#define heimdal_long_version __heimdal_long_version
+#include "version.h"
+
diff --git a/crypto/heimdal/lib/krb5/warn.c b/crypto/heimdal/lib/krb5/warn.c
new file mode 100644
index 0000000..b202f7d
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/warn.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+#include <err.h>
+
+RCSID("$Id: warn.c,v 1.10 1999/12/02 17:05:13 joda Exp $");
+
+static krb5_error_code
+_warnerr(krb5_context context, int do_errtext,
+ krb5_error_code code, int level, const char *fmt, va_list ap)
+{
+ char xfmt[7] = "";
+ const char *args[2], **arg;
+ char *msg = NULL;
+
+ arg = args;
+ if(fmt){
+ strcat(xfmt, "%s");
+ if(do_errtext)
+ strcat(xfmt, ": ");
+ vasprintf(&msg, fmt, ap);
+ if(msg == NULL)
+ return ENOMEM;
+ *arg++ = msg;
+ }
+ if(context && do_errtext){
+ const char *err_msg;
+
+ strcat(xfmt, "%s");
+
+ err_msg = krb5_get_err_text(context, code);
+ if (err_msg)
+ *arg++ = err_msg;
+ else
+ *arg++ = "<unknown error>";
+ }
+
+ if(context && context->warn_dest)
+ krb5_log(context, context->warn_dest, level, xfmt, args[0], args[1]);
+ else
+ warnx(xfmt, args[0], args[1]);
+ free(msg);
+ return 0;
+}
+
+#define FUNC(ETEXT, CODE, LEVEL) \
+ krb5_error_code ret; \
+ va_list ap; \
+ va_start(ap, fmt); \
+ ret = _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); \
+ va_end(ap);
+
+#undef __attribute__
+#define __attribute__(X)
+
+krb5_error_code
+krb5_vwarn(krb5_context context, krb5_error_code code,
+ const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 3, 0)))
+{
+ return _warnerr(context, 1, code, 1, fmt, ap);
+}
+
+
+krb5_error_code
+krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)))
+{
+ FUNC(1, code, 1);
+ return ret;
+}
+
+krb5_error_code
+krb5_vwarnx(krb5_context context, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 2, 0)))
+{
+ return _warnerr(context, 0, 0, 1, fmt, ap);
+}
+
+krb5_error_code
+krb5_warnx(krb5_context context, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)))
+{
+ FUNC(0, 0, 1);
+ return ret;
+}
+
+krb5_error_code
+krb5_verr(krb5_context context, int eval, krb5_error_code code,
+ const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 4, 0)))
+{
+ _warnerr(context, 1, code, 0, fmt, ap);
+ exit(eval);
+}
+
+
+krb5_error_code
+krb5_err(krb5_context context, int eval, krb5_error_code code,
+ const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 4, 5)))
+{
+ FUNC(1, code, 0);
+ exit(eval);
+}
+
+krb5_error_code
+krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 3, 0)))
+{
+ _warnerr(context, 0, 0, 0, fmt, ap);
+ exit(eval);
+}
+
+krb5_error_code
+krb5_errx(krb5_context context, int eval, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 3, 4)))
+{
+ FUNC(0, 0, 0);
+ exit(eval);
+}
+
+krb5_error_code
+krb5_vabort(krb5_context context, krb5_error_code code,
+ const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 3, 0)))
+{
+ _warnerr(context, 1, code, 0, fmt, ap);
+ abort();
+}
+
+
+krb5_error_code
+krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 3, 4)))
+{
+ FUNC(1, code, 0);
+ abort();
+}
+
+krb5_error_code
+krb5_vabortx(krb5_context context, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 2, 0)))
+{
+ _warnerr(context, 0, 0, 0, fmt, ap);
+ abort();
+}
+
+krb5_error_code
+krb5_abortx(krb5_context context, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)))
+{
+ FUNC(0, 0, 0);
+ abort();
+}
+
+krb5_error_code
+krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac)
+{
+ context->warn_dest = fac;
+ return 0;
+}
diff --git a/crypto/heimdal/lib/krb5/write_message.c b/crypto/heimdal/lib/krb5/write_message.c
new file mode 100644
index 0000000..b7f2c28
--- /dev/null
+++ b/crypto/heimdal/lib/krb5/write_message.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: write_message.c,v 1.4 1999/12/02 17:05:13 joda Exp $");
+
+krb5_error_code
+krb5_write_message (krb5_context context,
+ krb5_pointer p_fd,
+ krb5_data *data)
+{
+ u_int32_t len;
+ u_int8_t buf[4];
+
+ len = data->length;
+ buf[0] = (len >> 24) & 0xFF;
+ buf[1] = (len >> 16) & 0xFF;
+ buf[2] = (len >> 8) & 0xFF;
+ buf[3] = (len >> 0) & 0xFF;
+ if (krb5_net_write (context, p_fd, buf, 4) != 4
+ || krb5_net_write (context, p_fd, data->data, len) != len)
+ return errno;
+ return 0;
+}
OpenPOWER on IntegriCloud