diff options
Diffstat (limited to 'crypto/heimdal/lib/krb5')
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 000000000000..17551cb59c2a --- /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 000000000000..6f3652eaae48 --- /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 000000000000..cfc42f493ca9 --- /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 000000000000..e8214ba7f212 --- /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 000000000000..8b0704f6e1ea --- /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 000000000000..c125580a7c13 --- /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 000000000000..ac83ff78bdce --- /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 000000000000..94b1376297a6 --- /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 000000000000..c8a89caa7e18 --- /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 000000000000..a38393bbf359 --- /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 000000000000..e78d4deb23da --- /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 000000000000..fd9444062934 --- /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 000000000000..1d946135c4c8 --- /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 000000000000..3d1ff1e7a23e --- /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 000000000000..aeb939a3cb5a --- /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 000000000000..8314c2698925 --- /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 000000000000..cf25f7b2026a --- /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 000000000000..24dea0b3283d --- /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 000000000000..4a8f3ecd5a63 --- /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 000000000000..2f9ef95028f3 --- /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 000000000000..705116871224 --- /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 000000000000..b6db6ce85de9 --- /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 000000000000..21191e25639c --- /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 000000000000..074595e2139c --- /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 000000000000..698b3007b15f --- /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 000000000000..df88e6f9c91e --- /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 000000000000..251ec320106d --- /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 000000000000..a69f29b988ff --- /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 000000000000..a000ea1e6c36 --- /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 000000000000..a5b2e9ea9c00 --- /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 000000000000..65a1b3c7bdd5 --- /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 000000000000..61951c1a4daf --- /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 000000000000..84d7a5e06579 --- /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 000000000000..3f9b9019a352 --- /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 000000000000..977515facd26 --- /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 000000000000..e8522cbc48d9 --- /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 000000000000..f65af470ba12 --- /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 000000000000..4fb8800bfdcc --- /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 000000000000..d78ef354e3fd --- /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 000000000000..773d36175812 --- /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 000000000000..17bb45f67d43 --- /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 000000000000..5ec35434f396 --- /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 000000000000..404fa5a2acb4 --- /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 000000000000..84b295f4751c --- /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 000000000000..89732a0d4afa --- /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 000000000000..af853a41f9f2 --- /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 000000000000..c6c35e5b4f84 --- /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 000000000000..fa14e624f00e --- /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 000000000000..b1f425c575ed --- /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 000000000000..924b4cd0e622 --- /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 000000000000..b24328a43abd --- /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 000000000000..8813c7a848f5 --- /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 000000000000..2a0adb6859dd --- /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 000000000000..11cabc6575f6 --- /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 000000000000..231c3ff15e73 --- /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 000000000000..16ccf72ace3a --- /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 000000000000..e2362a98acb9 --- /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 000000000000..29db8c1e59e8 --- /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 000000000000..d8cc89eee3d2 --- /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 000000000000..e8779df82b27 --- /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 000000000000..ba5888af3d9a --- /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 000000000000..b7093b1b14d0 --- /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 000000000000..87040ba89c91 --- /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 000000000000..db9236c774f7 --- /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 000000000000..aea4150189e0 --- /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 000000000000..13277d6b8d44 --- /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 000000000000..521da0e7a06a --- /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 000000000000..8d5c4e407180 --- /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 000000000000..ae8ddece4403 --- /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 000000000000..e1511e255f91 --- /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 000000000000..d45deea13d19 --- /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 000000000000..baf63f6d525d --- /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 000000000000..2b173db9b545 --- /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 000000000000..1ee2bed033f0 --- /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 000000000000..060be033b13b --- /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 000000000000..e92d326390a9 --- /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 000000000000..2b7b886e6bb0 --- /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 000000000000..4d848a6d783c --- /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 000000000000..814dc6fb694c --- /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 000000000000..d0db5e81cbaa --- /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 000000000000..8cb1dc4af331 --- /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 000000000000..5cc719ba8def --- /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 000000000000..bcf795255a34 --- /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 000000000000..3fd022d17603 --- /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 000000000000..4693d08a5e61 --- /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 000000000000..a8492541e30c --- /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 000000000000..c33079167b66 --- /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 000000000000..df9b45e264d8 --- /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 000000000000..0bc85642bde2 --- /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 000000000000..e2c401c33919 --- /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 000000000000..9f8df1d6f327 --- /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 000000000000..aebf215b266b --- /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 000000000000..f2cae03d06bb --- /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 000000000000..49fe7b66f9f1 --- /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 000000000000..5adc3db159b4 --- /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 000000000000..2872322bafc8 --- /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 000000000000..b9e8dd01ef30 --- /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 000000000000..b917a923250b --- /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 000000000000..bfd4eb4e2a91 --- /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 000000000000..17b154747b8c --- /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 000000000000..d2497efd5826 --- /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 000000000000..e4c507c2c54b --- /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 000000000000..a8019e635dfd --- /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 000000000000..0e884d0e810f --- /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 000000000000..ecb58218990a --- /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 000000000000..47a5f0b3ae0a --- /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 000000000000..ed5a5b5b7965 --- /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 000000000000..0f080ee331af --- /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 000000000000..2b9ce28a38de --- /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 000000000000..10c22cb7e72c --- /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 000000000000..5f0fd6680bf5 --- /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 000000000000..b202f7dc4b9a --- /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 000000000000..b7f2c2865ce6 --- /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; +} |