summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/kdc
diff options
context:
space:
mode:
authorstas <stas@FreeBSD.org>2012-03-22 08:48:42 +0000
committerstas <stas@FreeBSD.org>2012-03-22 08:48:42 +0000
commite7e0b349883e80d63c4e856f16351aaa6607766d (patch)
tree5518cb944fa25f627a797b58451ccf506b720fcf /crypto/heimdal/kdc
parente02fd6b8423e63f1fdbfc1f984d7c7291a1bacd1 (diff)
parent2db247d3fc10ef5304f61dbd66448efff8cc6684 (diff)
downloadFreeBSD-src-e7e0b349883e80d63c4e856f16351aaa6607766d.zip
FreeBSD-src-e7e0b349883e80d63c4e856f16351aaa6607766d.tar.gz
- Update FreeBSD Heimdal distribution to version 1.5.1. This also brings
several new kerberos related libraries and applications to FreeBSD: o kgetcred(1) allows one to manually get a ticket for a particular service. o kf(1) securily forwards ticket to another host through an authenticated and encrypted stream. o kcc(1) is an umbrella program around klist(1), kswitch(1), kgetcred(1) and other user kerberos operations. klist and kswitch are just symlinks to kcc(1) now. o kswitch(1) allows you to easily switch between kerberos credentials if you're running KCM. o hxtool(1) is a certificate management tool to use with PKINIT. o string2key(1) maps a password into key. o kdigest(8) is a userland tool to access the KDC's digest interface. o kimpersonate(8) creates a "fake" ticket for a service. We also now install manpages for some lirbaries that were not installed before, libheimntlm and libhx509. - The new HEIMDAL version no longer supports Kerberos 4. All users are recommended to switch to Kerberos 5. - Weak ciphers are now disabled by default. To enable DES support (used by telnet(8)), use "allow_weak_crypto" option in krb5.conf. - libtelnet, pam_ksu and pam_krb5 are now compiled with error on warnings disabled due to the function they use (krb5_get_err_text(3)) being deprecated. I plan to work on this next. - Heimdal's KDC now require sqlite to operate. We use the bundled version and install it as libheimsqlite. If some other FreeBSD components will require it in the future we can rename it to libbsdsqlite and use for these components as well. - This is not a latest Heimdal version, the new one was released while I was working on the update. I will update it to 1.5.2 soon, as it fixes some important bugs and security issues.
Diffstat (limited to 'crypto/heimdal/kdc')
-rw-r--r--crypto/heimdal/kdc/524.c400
-rw-r--r--crypto/heimdal/kdc/Makefile.am45
-rw-r--r--crypto/heimdal/kdc/Makefile.in752
-rw-r--r--crypto/heimdal/kdc/announce.c544
-rw-r--r--crypto/heimdal/kdc/config.c193
-rw-r--r--crypto/heimdal/kdc/connect.c309
-rw-r--r--crypto/heimdal/kdc/default_config.c306
-rw-r--r--crypto/heimdal/kdc/digest-service.c282
-rw-r--r--crypto/heimdal/kdc/digest.c669
-rw-r--r--crypto/heimdal/kdc/headers.h67
-rw-r--r--crypto/heimdal/kdc/hprop.8162
-rw-r--r--crypto/heimdal/kdc/hprop.c473
-rw-r--r--crypto/heimdal/kdc/hprop.h52
-rw-r--r--crypto/heimdal/kdc/hpropd.895
-rw-r--r--crypto/heimdal/kdc/hpropd.c132
-rw-r--r--crypto/heimdal/kdc/kadb.h84
-rw-r--r--crypto/heimdal/kdc/kaserver.c951
-rw-r--r--crypto/heimdal/kdc/kdc-private.h146
-rw-r--r--crypto/heimdal/kdc/kdc-protos.h25
-rw-r--r--crypto/heimdal/kdc/kdc-replay.c77
-rw-r--r--crypto/heimdal/kdc/kdc.8151
-rw-r--r--crypto/heimdal/kdc/kdc.h97
-rw-r--r--crypto/heimdal/kdc/kdc_locl.h70
-rw-r--r--crypto/heimdal/kdc/kerberos4.c805
-rw-r--r--crypto/heimdal/kdc/kerberos5.c1080
-rw-r--r--crypto/heimdal/kdc/krb5tgs.c1355
-rw-r--r--crypto/heimdal/kdc/kstash.890
-rw-r--r--crypto/heimdal/kdc/kstash.c88
-rw-r--r--crypto/heimdal/kdc/kx509.c184
-rw-r--r--crypto/heimdal/kdc/log.c76
-rw-r--r--crypto/heimdal/kdc/main.c124
-rw-r--r--crypto/heimdal/kdc/misc.c148
-rw-r--r--crypto/heimdal/kdc/mit_dump.c112
-rw-r--r--crypto/heimdal/kdc/pkinit.c1249
-rw-r--r--crypto/heimdal/kdc/process.c285
-rw-r--r--crypto/heimdal/kdc/rx.h52
-rw-r--r--crypto/heimdal/kdc/set_dbinfo.c107
-rw-r--r--crypto/heimdal/kdc/string2key.8111
-rw-r--r--crypto/heimdal/kdc/string2key.c105
-rw-r--r--crypto/heimdal/kdc/v4_dump.c143
-rw-r--r--crypto/heimdal/kdc/version-script.map9
-rw-r--r--crypto/heimdal/kdc/windc.c112
-rw-r--r--crypto/heimdal/kdc/windc_plugin.h75
43 files changed, 5968 insertions, 6424 deletions
diff --git a/crypto/heimdal/kdc/524.c b/crypto/heimdal/kdc/524.c
deleted file mode 100644
index 3e4ad29..0000000
--- a/crypto/heimdal/kdc/524.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (c) 1997-2005 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 "kdc_locl.h"
-
-RCSID("$Id: 524.c 18270 2006-10-06 17:06:30Z lha $");
-
-#include <krb5-v4compat.h>
-
-/*
- * fetch the server from `t', returning the name in malloced memory in
- * `spn' and the entry itself in `server'
- */
-
-static krb5_error_code
-fetch_server (krb5_context context,
- krb5_kdc_configuration *config,
- const Ticket *t,
- char **spn,
- hdb_entry_ex **server,
- const char *from)
-{
- krb5_error_code ret;
- krb5_principal sprinc;
-
- ret = _krb5_principalname2krb5_principal(context, &sprinc,
- t->sname, t->realm);
- if (ret) {
- kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
- krb5_get_err_text(context, ret));
- return ret;
- }
- ret = krb5_unparse_name(context, sprinc, spn);
- if (ret) {
- krb5_free_principal(context, sprinc);
- kdc_log(context, config, 0, "krb5_unparse_name: %s",
- krb5_get_err_text(context, ret));
- return ret;
- }
- ret = _kdc_db_fetch(context, config, sprinc, HDB_F_GET_SERVER,
- NULL, server);
- krb5_free_principal(context, sprinc);
- if (ret) {
- kdc_log(context, config, 0,
- "Request to convert ticket from %s for unknown principal %s: %s",
- from, *spn, krb5_get_err_text(context, ret));
- if (ret == HDB_ERR_NOENTRY)
- ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
- return ret;
- }
- return 0;
-}
-
-static krb5_error_code
-log_524 (krb5_context context,
- krb5_kdc_configuration *config,
- const EncTicketPart *et,
- const char *from,
- const char *spn)
-{
- krb5_principal client;
- char *cpn;
- krb5_error_code ret;
-
- ret = _krb5_principalname2krb5_principal(context, &client,
- et->cname, et->crealm);
- if (ret) {
- kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
- krb5_get_err_text (context, ret));
- return ret;
- }
- ret = krb5_unparse_name(context, client, &cpn);
- if (ret) {
- krb5_free_principal(context, client);
- kdc_log(context, config, 0, "krb5_unparse_name: %s",
- krb5_get_err_text (context, ret));
- return ret;
- }
- kdc_log(context, config, 1, "524-REQ %s from %s for %s", cpn, from, spn);
- free(cpn);
- krb5_free_principal(context, client);
- return 0;
-}
-
-static krb5_error_code
-verify_flags (krb5_context context,
- krb5_kdc_configuration *config,
- const EncTicketPart *et,
- const char *spn)
-{
- if(et->endtime < kdc_time){
- kdc_log(context, config, 0, "Ticket expired (%s)", spn);
- return KRB5KRB_AP_ERR_TKT_EXPIRED;
- }
- if(et->flags.invalid){
- kdc_log(context, config, 0, "Ticket not valid (%s)", spn);
- return KRB5KRB_AP_ERR_TKT_NYV;
- }
- return 0;
-}
-
-/*
- * set the `et->caddr' to the most appropriate address to use, where
- * `addr' is the address the request was received from.
- */
-
-static krb5_error_code
-set_address (krb5_context context,
- krb5_kdc_configuration *config,
- EncTicketPart *et,
- struct sockaddr *addr,
- const char *from)
-{
- krb5_error_code ret;
- krb5_address *v4_addr;
-
- v4_addr = malloc (sizeof(*v4_addr));
- if (v4_addr == NULL)
- return ENOMEM;
-
- ret = krb5_sockaddr2address(context, addr, v4_addr);
- if(ret) {
- free (v4_addr);
- kdc_log(context, config, 0, "Failed to convert address (%s)", from);
- return ret;
- }
-
- if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) {
- kdc_log(context, config, 0, "Incorrect network address (%s)", from);
- krb5_free_address(context, v4_addr);
- free (v4_addr);
- return KRB5KRB_AP_ERR_BADADDR;
- }
- if(v4_addr->addr_type == KRB5_ADDRESS_INET) {
- /* we need to collapse the addresses in the ticket to a
- single address; best guess is to use the address the
- connection came from */
-
- if (et->caddr != NULL) {
- free_HostAddresses(et->caddr);
- } else {
- et->caddr = malloc (sizeof (*et->caddr));
- if (et->caddr == NULL) {
- krb5_free_address(context, v4_addr);
- free(v4_addr);
- return ENOMEM;
- }
- }
- et->caddr->val = v4_addr;
- et->caddr->len = 1;
- } else {
- krb5_free_address(context, v4_addr);
- free(v4_addr);
- }
- return 0;
-}
-
-
-static krb5_error_code
-encrypt_v4_ticket(krb5_context context,
- krb5_kdc_configuration *config,
- void *buf,
- size_t len,
- krb5_keyblock *skey,
- EncryptedData *reply)
-{
- krb5_crypto crypto;
- krb5_error_code ret;
- ret = krb5_crypto_init(context, skey, ETYPE_DES_PCBC_NONE, &crypto);
- if (ret) {
- free(buf);
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
- return ret;
- }
-
- ret = krb5_encrypt_EncryptedData(context,
- crypto,
- KRB5_KU_TICKET,
- buf,
- len,
- 0,
- reply);
- krb5_crypto_destroy(context, crypto);
- if(ret) {
- kdc_log(context, config, 0, "Failed to encrypt data: %s",
- krb5_get_err_text(context, ret));
- return ret;
- }
- return 0;
-}
-
-static krb5_error_code
-encode_524_response(krb5_context context,
- krb5_kdc_configuration *config,
- const char *spn, const EncTicketPart et,
- const Ticket *t, hdb_entry_ex *server,
- EncryptedData *ticket, int *kvno)
-{
- krb5_error_code ret;
- int use_2b;
- size_t len;
-
- use_2b = krb5_config_get_bool(context, NULL, "kdc", "use_2b", spn, NULL);
- if(use_2b) {
- ASN1_MALLOC_ENCODE(EncryptedData,
- ticket->cipher.data, ticket->cipher.length,
- &t->enc_part, &len, ret);
-
- if (ret) {
- kdc_log(context, config, 0,
- "Failed to encode v4 (2b) ticket (%s)", spn);
- return ret;
- }
-
- ticket->etype = 0;
- ticket->kvno = NULL;
- *kvno = 213; /* 2b's use this magic kvno */
- } else {
- unsigned char buf[MAX_KTXT_LEN + 4 * 4];
- Key *skey;
-
- if (!config->enable_v4_cross_realm && strcmp (et.crealm, t->realm) != 0) {
- kdc_log(context, config, 0, "524 cross-realm %s -> %s disabled", et.crealm,
- t->realm);
- return KRB5KDC_ERR_POLICY;
- }
-
- ret = _kdc_encode_v4_ticket(context, config,
- buf + sizeof(buf) - 1, sizeof(buf),
- &et, &t->sname, &len);
- if(ret){
- kdc_log(context, config, 0,
- "Failed to encode v4 ticket (%s)", spn);
- return ret;
- }
- ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
- if(ret){
- kdc_log(context, config, 0,
- "no suitable DES key for server (%s)", spn);
- return ret;
- }
- ret = encrypt_v4_ticket(context, config, buf + sizeof(buf) - len, len,
- &skey->key, ticket);
- if(ret){
- kdc_log(context, config, 0,
- "Failed to encrypt v4 ticket (%s)", spn);
- return ret;
- }
- *kvno = server->entry.kvno;
- }
-
- return 0;
-}
-
-/*
- * process a 5->4 request, based on `t', and received `from, addr',
- * returning the reply in `reply'
- */
-
-krb5_error_code
-_kdc_do_524(krb5_context context,
- krb5_kdc_configuration *config,
- const Ticket *t, krb5_data *reply,
- const char *from, struct sockaddr *addr)
-{
- krb5_error_code ret = 0;
- krb5_crypto crypto;
- hdb_entry_ex *server = NULL;
- Key *skey;
- krb5_data et_data;
- EncTicketPart et;
- EncryptedData ticket;
- krb5_storage *sp;
- char *spn = NULL;
- unsigned char buf[MAX_KTXT_LEN + 4 * 4];
- size_t len;
- int kvno = 0;
-
- if(!config->enable_524) {
- ret = KRB5KDC_ERR_POLICY;
- kdc_log(context, config, 0,
- "Rejected ticket conversion request from %s", from);
- goto out;
- }
-
- ret = fetch_server (context, config, t, &spn, &server, from);
- if (ret) {
- goto out;
- }
-
- ret = hdb_enctype2key(context, &server->entry, t->enc_part.etype, &skey);
- if(ret){
- kdc_log(context, config, 0,
- "No suitable key found for server (%s) from %s", spn, from);
- goto out;
- }
- ret = krb5_crypto_init(context, &skey->key, 0, &crypto);
- if (ret) {
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
- goto out;
- }
- ret = krb5_decrypt_EncryptedData (context,
- crypto,
- KRB5_KU_TICKET,
- &t->enc_part,
- &et_data);
- krb5_crypto_destroy(context, crypto);
- if(ret){
- kdc_log(context, config, 0,
- "Failed to decrypt ticket from %s for %s", from, spn);
- goto out;
- }
- ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length,
- &et, &len);
- krb5_data_free(&et_data);
- if(ret){
- kdc_log(context, config, 0,
- "Failed to decode ticket from %s for %s", from, spn);
- goto out;
- }
-
- ret = log_524 (context, config, &et, from, spn);
- if (ret) {
- free_EncTicketPart(&et);
- goto out;
- }
-
- ret = verify_flags (context, config, &et, spn);
- if (ret) {
- free_EncTicketPart(&et);
- goto out;
- }
-
- ret = set_address (context, config, &et, addr, from);
- if (ret) {
- free_EncTicketPart(&et);
- goto out;
- }
-
- ret = encode_524_response(context, config, spn, et, t,
- server, &ticket, &kvno);
- free_EncTicketPart(&et);
-
- out:
- /* make reply */
- memset(buf, 0, sizeof(buf));
- sp = krb5_storage_from_mem(buf, sizeof(buf));
- if (sp) {
- krb5_store_int32(sp, ret);
- if(ret == 0){
- krb5_store_int32(sp, kvno);
- krb5_store_data(sp, ticket.cipher);
- /* Aargh! This is coded as a KTEXT_ST. */
- krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
- krb5_store_int32(sp, 0); /* mbz */
- free_EncryptedData(&ticket);
- }
- ret = krb5_storage_to_data(sp, reply);
- reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
- krb5_storage_free(sp);
- } else
- krb5_data_zero(reply);
- if(spn)
- free(spn);
- if(server)
- _kdc_free_ent (context, server);
- return ret;
-}
diff --git a/crypto/heimdal/kdc/Makefile.am b/crypto/heimdal/kdc/Makefile.am
index ff20bde..5ef3cbe 100644
--- a/crypto/heimdal/kdc/Makefile.am
+++ b/crypto/heimdal/kdc/Makefile.am
@@ -1,8 +1,8 @@
-# $Id: Makefile.am 22489 2008-01-21 11:49:06Z lha $
+# $Id$
include $(top_srcdir)/Makefile.am.common
-AM_CPPFLAGS += $(INCLUDE_krb4) $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
+AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_krb4) $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
lib_LTLIBRARIES = libkdc.la
@@ -10,21 +10,25 @@ bin_PROGRAMS = string2key
sbin_PROGRAMS = kstash
-libexec_PROGRAMS = hprop hpropd kdc
+libexec_PROGRAMS = hprop hpropd kdc digest-service
noinst_PROGRAMS = kdc-replay
man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8 string2key.8
-hprop_SOURCES = hprop.c mit_dump.c v4_dump.c hprop.h kadb.h
+hprop_SOURCES = hprop.c mit_dump.c hprop.h
hpropd_SOURCES = hpropd.c hprop.h
kstash_SOURCES = kstash.c headers.h
string2key_SOURCES = string2key.c headers.h
+digest_service_SOURCES = \
+ digest-service.c
+
kdc_SOURCES = connect.c \
config.c \
+ announce.c \
main.c
libkdc_la_SOURCES = \
@@ -39,9 +43,6 @@ libkdc_la_SOURCES = \
pkinit.c \
log.c \
misc.c \
- 524.c \
- kerberos4.c \
- kaserver.c \
kx509.c \
process.c \
windc.c \
@@ -66,7 +67,6 @@ $(srcdir)/kdc-private.h:
hprop_LDADD = \
$(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_kdb) $(LIB_krb4) \
$(LIB_hcrypto) \
@@ -76,7 +76,6 @@ hprop_LDADD = \
hpropd_LDADD = \
$(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_kdb) $(LIB_krb4) \
$(LIB_hcrypto) \
@@ -91,7 +90,6 @@ endif
libkdc_la_LIBADD = \
$(LIB_pkinit) \
$(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_kdb) $(LIB_krb4) \
$(top_builddir)/lib/ntlm/libheimntlm.la \
@@ -101,7 +99,6 @@ libkdc_la_LIBADD = \
$(DBLIB)
LDADD = $(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_krb4) \
$(LIB_hcrypto) \
@@ -109,14 +106,34 @@ LDADD = $(top_builddir)/lib/hdb/libhdb.la \
$(LIB_roken) \
$(DBLIB)
-kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
-kdc_replay_LDADD = $(kdc_LDADD)
+kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(CAPNG_LIBS)
+
+if FRAMEWORK_SECURITY
+kdc_LDFLAGS = -framework SystemConfiguration -framework CoreFoundation
+endif
+kdc_CFLAGS = $(CAPNG_CFLAGS)
+
+digest_service_LDADD = \
+ libkdc.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(top_builddir)/lib/ipc/libheim-ipcs.la \
+ $(LDADD) $(LIB_pidfile)
+kdc_replay_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
include_HEADERS = kdc.h kdc-protos.h
+
krb5dir = $(includedir)/krb5
krb5_HEADERS = windc_plugin.h
build_HEADERZ = $(krb5_HEADERS) # XXX
-EXTRA_DIST = $(man_MANS) version-script.map
+EXTRA_DIST = \
+ hprop-version.rc \
+ hpropd-version.rc \
+ kdc-version.rc \
+ kstash-version.rc \
+ libkdc-version.rc \
+ string2key-version.rc \
+ libkdc-exports.def \
+ NTMakefile $(man_MANS) version-script.map
diff --git a/crypto/heimdal/kdc/Makefile.in b/crypto/heimdal/kdc/Makefile.in
index d7e623a..57259cf 100644
--- a/crypto/heimdal/kdc/Makefile.in
+++ b/crypto/heimdal/kdc/Makefile.in
@@ -1,8 +1,9 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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.
@@ -14,18 +15,19 @@
@SET_MAKE@
-# $Id: Makefile.am 22489 2008-01-21 11:49:06Z lha $
+# $Id$
-# $Id: Makefile.am.common 10998 2002-05-19 18:35:37Z joda $
+# $Id$
-# $Id: Makefile.am.common 22488 2008-01-21 11:47:22Z lha $
+# $Id$
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
@@ -45,13 +47,14 @@ DIST_COMMON = $(include_HEADERS) $(krb5_HEADERS) $(srcdir)/Makefile.am \
$(top_srcdir)/cf/Makefile.am.common
bin_PROGRAMS = string2key$(EXEEXT)
sbin_PROGRAMS = kstash$(EXEEXT)
-libexec_PROGRAMS = hprop$(EXEEXT) hpropd$(EXEEXT) kdc$(EXEEXT)
+libexec_PROGRAMS = hprop$(EXEEXT) hpropd$(EXEEXT) kdc$(EXEEXT) \
+ digest-service$(EXEEXT)
noinst_PROGRAMS = kdc-replay$(EXEEXT)
@versionscript_TRUE@am__append_1 = $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
subdir = kdc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
- $(top_srcdir)/cf/auth-modules.m4 $(top_srcdir)/cf/autobuild.m4 \
+ $(top_srcdir)/cf/auth-modules.m4 \
$(top_srcdir)/cf/broken-getaddrinfo.m4 \
$(top_srcdir)/cf/broken-glob.m4 \
$(top_srcdir)/cf/broken-realloc.m4 \
@@ -66,7 +69,7 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
$(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/check-x.m4 \
$(top_srcdir)/cf/check-xau.m4 $(top_srcdir)/cf/crypto.m4 \
$(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.m4 \
- $(top_srcdir)/cf/dlopen.m4 \
+ $(top_srcdir)/cf/dispatch.m4 $(top_srcdir)/cf/dlopen.m4 \
$(top_srcdir)/cf/find-func-no-libs.m4 \
$(top_srcdir)/cf/find-func-no-libs2.m4 \
$(top_srcdir)/cf/find-func.m4 \
@@ -80,9 +83,12 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
$(top_srcdir)/cf/krb-readline.m4 \
$(top_srcdir)/cf/krb-struct-spwd.m4 \
$(top_srcdir)/cf/krb-struct-winsize.m4 \
- $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/mips-abi.m4 \
- $(top_srcdir)/cf/misc.m4 $(top_srcdir)/cf/need-proto.m4 \
- $(top_srcdir)/cf/osfc2.m4 $(top_srcdir)/cf/otp.m4 \
+ $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/libtool.m4 \
+ $(top_srcdir)/cf/ltoptions.m4 $(top_srcdir)/cf/ltsugar.m4 \
+ $(top_srcdir)/cf/ltversion.m4 $(top_srcdir)/cf/lt~obsolete.m4 \
+ $(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \
+ $(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \
+ $(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/pkg.m4 \
$(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \
$(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \
$(top_srcdir)/cf/roken-frag.m4 \
@@ -90,91 +96,108 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
$(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \
$(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \
$(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \
- $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" \
"$(DESTDIR)$(man8dir)" "$(DESTDIR)$(includedir)" \
"$(DESTDIR)$(krb5dir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libkdc_la_DEPENDENCIES = $(LIB_pkinit) \
- $(top_builddir)/lib/hdb/libhdb.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/hdb/libhdb.la \
$(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(top_builddir)/lib/ntlm/libheimntlm.la \
$(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am_libkdc_la_OBJECTS = default_config.lo set_dbinfo.lo digest.lo \
- kerberos5.lo krb5tgs.lo pkinit.lo log.lo misc.lo 524.lo \
- kerberos4.lo kaserver.lo kx509.lo process.lo windc.lo
+ kerberos5.lo krb5tgs.lo pkinit.lo log.lo misc.lo kx509.lo \
+ process.lo windc.lo
libkdc_la_OBJECTS = $(am_libkdc_la_OBJECTS)
libkdc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libkdc_la_LDFLAGS) $(LDFLAGS) -o $@
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS) \
$(sbin_PROGRAMS)
-am_hprop_OBJECTS = hprop.$(OBJEXT) mit_dump.$(OBJEXT) \
- v4_dump.$(OBJEXT)
+am_digest_service_OBJECTS = digest-service.$(OBJEXT)
+digest_service_OBJECTS = $(am_digest_service_OBJECTS)
+am__DEPENDENCIES_2 = $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+digest_service_DEPENDENCIES = libkdc.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(top_builddir)/lib/ipc/libheim-ipcs.la $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1)
+am_hprop_OBJECTS = hprop.$(OBJEXT) mit_dump.$(OBJEXT)
hprop_OBJECTS = $(am_hprop_OBJECTS)
hprop_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
am_hpropd_OBJECTS = hpropd.$(OBJEXT)
hpropd_OBJECTS = $(am_hpropd_OBJECTS)
hpropd_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am_kdc_OBJECTS = connect.$(OBJEXT) config.$(OBJEXT) main.$(OBJEXT)
-kdc_OBJECTS = $(am_kdc_OBJECTS)
-am__DEPENDENCIES_2 = $(top_builddir)/lib/hdb/libhdb.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
+am_kdc_OBJECTS = kdc-connect.$(OBJEXT) kdc-config.$(OBJEXT) \
+ kdc-announce.$(OBJEXT) kdc-main.$(OBJEXT)
+kdc_OBJECTS = $(am_kdc_OBJECTS)
kdc_DEPENDENCIES = libkdc.la $(am__DEPENDENCIES_2) \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+kdc_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(kdc_CFLAGS) $(CFLAGS) $(kdc_LDFLAGS) \
+ $(LDFLAGS) -o $@
kdc_replay_SOURCES = kdc-replay.c
kdc_replay_OBJECTS = kdc-replay.$(OBJEXT)
-am__DEPENDENCIES_3 = libkdc.la $(am__DEPENDENCIES_2) \
+kdc_replay_DEPENDENCIES = libkdc.la $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_1)
-kdc_replay_DEPENDENCIES = $(am__DEPENDENCIES_3)
am_kstash_OBJECTS = kstash.$(OBJEXT)
kstash_OBJECTS = $(am_kstash_OBJECTS)
kstash_LDADD = $(LDADD)
kstash_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am_string2key_OBJECTS = string2key.$(OBJEXT)
string2key_OBJECTS = $(am_string2key_OBJECTS)
string2key_LDADD = $(LDADD)
string2key_DEPENDENCIES = $(top_builddir)/lib/hdb/libhdb.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@
-depcomp =
-am__depfiles_maybe =
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -184,16 +207,14 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libkdc_la_SOURCES) $(hprop_SOURCES) $(hpropd_SOURCES) \
- $(kdc_SOURCES) kdc-replay.c $(kstash_SOURCES) \
- $(string2key_SOURCES)
-DIST_SOURCES = $(libkdc_la_SOURCES) $(hprop_SOURCES) $(hpropd_SOURCES) \
- $(kdc_SOURCES) kdc-replay.c $(kstash_SOURCES) \
- $(string2key_SOURCES)
+SOURCES = $(libkdc_la_SOURCES) $(digest_service_SOURCES) \
+ $(hprop_SOURCES) $(hpropd_SOURCES) $(kdc_SOURCES) kdc-replay.c \
+ $(kstash_SOURCES) $(string2key_SOURCES)
+DIST_SOURCES = $(libkdc_la_SOURCES) $(digest_service_SOURCES) \
+ $(hprop_SOURCES) $(hpropd_SOURCES) $(kdc_SOURCES) kdc-replay.c \
+ $(kstash_SOURCES) $(string2key_SOURCES)
man8dir = $(mandir)/man8
MANS = $(man_MANS)
-includeHEADERS_INSTALL = $(INSTALL_HEADER)
-krb5HEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(include_HEADERS) $(krb5_HEADERS)
ETAGS = etags
CTAGS = ctags
@@ -202,49 +223,58 @@ ACLOCAL = @ACLOCAL@
AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
AMTAR = @AMTAR@
AR = @AR@
+ASN1_COMPILE = @ASN1_COMPILE@
+ASN1_COMPILE_DEP = @ASN1_COMPILE_DEP@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CANONICAL_HOST = @CANONICAL_HOST@
+CAPNG_CFLAGS = @CAPNG_CFLAGS@
+CAPNG_LIBS = @CAPNG_LIBS@
CATMAN = @CATMAN@
CATMANEXT = @CATMANEXT@
CC = @CC@
+CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
COMPILE_ET = @COMPILE_ET@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
+DBHEADER = @DBHEADER@
DBLIB = @DBLIB@
DEFS = @DEFS@
+DEPDIR = @DEPDIR@
DIR_com_err = @DIR_com_err@
DIR_hcrypto = @DIR_hcrypto@
DIR_hdbdir = @DIR_hdbdir@
DIR_roken = @DIR_roken@
-ECHO = @ECHO@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INCLUDES_roken = @INCLUDES_roken@
INCLUDE_hcrypto = @INCLUDE_hcrypto@
INCLUDE_hesiod = @INCLUDE_hesiod@
INCLUDE_krb4 = @INCLUDE_krb4@
+INCLUDE_libedit = @INCLUDE_libedit@
+INCLUDE_libintl = @INCLUDE_libintl@
INCLUDE_openldap = @INCLUDE_openldap@
INCLUDE_readline = @INCLUDE_readline@
+INCLUDE_sqlite3 = @INCLUDE_sqlite3@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@
LEX = @LEX@
@@ -268,10 +298,11 @@ LIB_crypt = @LIB_crypt@
LIB_db_create = @LIB_db_create@
LIB_dbm_firstkey = @LIB_dbm_firstkey@
LIB_dbopen = @LIB_dbopen@
+LIB_dispatch_async_f = @LIB_dispatch_async_f@
LIB_dlopen = @LIB_dlopen@
LIB_dn_expand = @LIB_dn_expand@
+LIB_dns_search = @LIB_dns_search@
LIB_door_create = @LIB_door_create@
-LIB_el_init = @LIB_el_init@
LIB_freeaddrinfo = @LIB_freeaddrinfo@
LIB_gai_strerror = @LIB_gai_strerror@
LIB_getaddrinfo = @LIB_getaddrinfo@
@@ -288,6 +319,8 @@ LIB_hesiod = @LIB_hesiod@
LIB_hstrerror = @LIB_hstrerror@
LIB_kdb = @LIB_kdb@
LIB_krb4 = @LIB_krb4@
+LIB_libedit = @LIB_libedit@
+LIB_libintl = @LIB_libintl@
LIB_loadquery = @LIB_loadquery@
LIB_logout = @LIB_logout@
LIB_logwtmp = @LIB_logwtmp@
@@ -303,31 +336,45 @@ LIB_roken = @LIB_roken@
LIB_security = @LIB_security@
LIB_setsockopt = @LIB_setsockopt@
LIB_socket = @LIB_socket@
+LIB_sqlite3 = @LIB_sqlite3@
LIB_syslog = @LIB_syslog@
LIB_tgetent = @LIB_tgetent@
+LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_AFS = @NO_AFS@
NROFF = @NROFF@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-PTHREADS_CFLAGS = @PTHREADS_CFLAGS@
-PTHREADS_LIBS = @PTHREADS_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDADD = @PTHREAD_LDADD@
+PTHREAD_LIBADD = @PTHREAD_LIBADD@
RANLIB = @RANLIB@
+SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
+SLC = @SLC@
+SLC_DEP = @SLC_DEP@
STRIP = @STRIP@
VERSION = @VERSION@
VERSIONING = @VERSIONING@
-VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
WFLAGS = @WFLAGS@
WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
@@ -342,10 +389,12 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
@@ -386,39 +435,48 @@ psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-SUFFIXES = .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8
-AM_CPPFLAGS = -I$(top_builddir)/include $(INCLUDES_roken) \
- $(INCLUDE_krb4) $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
+SUFFIXES = .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include
+AM_CPPFLAGS = $(INCLUDES_roken) $(INCLUDE_libintl) $(INCLUDE_krb4) \
+ $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME
AM_CFLAGS = $(WFLAGS)
CP = cp
buildinclude = $(top_builddir)/include
+LIB_el_init = @LIB_el_init@
LIB_getattr = @LIB_getattr@
LIB_getpwent_r = @LIB_getpwent_r@
LIB_odm_initialize = @LIB_odm_initialize@
LIB_setpcred = @LIB_setpcred@
HESIODLIB = @HESIODLIB@
HESIODINCLUDE = @HESIODINCLUDE@
+libexec_heimdaldir = $(libexecdir)/heimdal
NROFF_MAN = groff -mandoc -Tascii
LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \
@KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la
@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
-@KRB5_TRUE@LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la
+LIB_heimbase = $(top_builddir)/base/libheimbase.la
@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la
lib_LTLIBRARIES = libkdc.la
man_MANS = kdc.8 kstash.8 hprop.8 hpropd.8 string2key.8
-hprop_SOURCES = hprop.c mit_dump.c v4_dump.c hprop.h kadb.h
+hprop_SOURCES = hprop.c mit_dump.c hprop.h
hpropd_SOURCES = hpropd.c hprop.h
kstash_SOURCES = kstash.c headers.h
string2key_SOURCES = string2key.c headers.h
+digest_service_SOURCES = \
+ digest-service.c
+
kdc_SOURCES = connect.c \
config.c \
+ announce.c \
main.c
libkdc_la_SOURCES = \
@@ -433,9 +491,6 @@ libkdc_la_SOURCES = \
pkinit.c \
log.c \
misc.c \
- 524.c \
- kerberos4.c \
- kaserver.c \
kx509.c \
process.c \
windc.c \
@@ -444,7 +499,6 @@ libkdc_la_SOURCES = \
libkdc_la_LDFLAGS = -version-info 2:0:0 $(am__append_1)
hprop_LDADD = \
$(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_kdb) $(LIB_krb4) \
$(LIB_hcrypto) \
@@ -454,7 +508,6 @@ hprop_LDADD = \
hpropd_LDADD = \
$(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_kdb) $(LIB_krb4) \
$(LIB_hcrypto) \
@@ -466,7 +519,6 @@ hpropd_LDADD = \
libkdc_la_LIBADD = \
$(LIB_pkinit) \
$(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_kdb) $(LIB_krb4) \
$(top_builddir)/lib/ntlm/libheimntlm.la \
@@ -476,7 +528,6 @@ libkdc_la_LIBADD = \
$(DBLIB)
LDADD = $(top_builddir)/lib/hdb/libhdb.la \
- $(LIB_openldap) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(LIB_krb4) \
$(LIB_hcrypto) \
@@ -484,29 +535,46 @@ LDADD = $(top_builddir)/lib/hdb/libhdb.la \
$(LIB_roken) \
$(DBLIB)
-kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
-kdc_replay_LDADD = $(kdc_LDADD)
+kdc_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(CAPNG_LIBS)
+@FRAMEWORK_SECURITY_TRUE@kdc_LDFLAGS = -framework SystemConfiguration -framework CoreFoundation
+kdc_CFLAGS = $(CAPNG_CFLAGS)
+digest_service_LDADD = \
+ libkdc.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(top_builddir)/lib/ipc/libheim-ipcs.la \
+ $(LDADD) $(LIB_pidfile)
+
+kdc_replay_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
include_HEADERS = kdc.h kdc-protos.h
krb5dir = $(includedir)/krb5
krb5_HEADERS = windc_plugin.h
build_HEADERZ = $(krb5_HEADERS) # XXX
-EXTRA_DIST = $(man_MANS) version-script.map
+EXTRA_DIST = \
+ hprop-version.rc \
+ hpropd-version.rc \
+ kdc-version.rc \
+ kstash-version.rc \
+ libkdc-version.rc \
+ string2key-version.rc \
+ libkdc-exports.def \
+ NTMakefile $(man_MANS) version-script.map
+
all: all-am
.SUFFIXES:
-.SUFFIXES: .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj
+.SUFFIXES: .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps kdc/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign --ignore-deps kdc/Makefile
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign kdc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign kdc/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -524,23 +592,28 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ list2="$$list2 $$p"; \
else :; fi; \
- done
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
@@ -556,94 +629,144 @@ libkdc.la: $(libkdc_la_OBJECTS) $(libkdc_la_DEPENDENCIES)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- if test -f $$p \
- || test -f $$p1 \
- ; then \
- f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
- else :; fi; \
- done
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
- rm -f "$(DESTDIR)$(bindir)/$$f"; \
- done
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
install-libexecPROGRAMS: $(libexec_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
- @list='$(libexec_PROGRAMS)'; for p in $$list; do \
- p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- if test -f $$p \
- || test -f $$p1 \
- ; then \
- f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(libexecdir)/$$f" || exit 1; \
- else :; fi; \
- done
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
uninstall-libexecPROGRAMS:
@$(NORMAL_UNINSTALL)
- @list='$(libexec_PROGRAMS)'; for p in $$list; do \
- f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \
- rm -f "$(DESTDIR)$(libexecdir)/$$f"; \
- done
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
clean-libexecPROGRAMS:
- @list='$(libexec_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
+ @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
clean-noinstPROGRAMS:
- @list='$(noinst_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
- @list='$(sbin_PROGRAMS)'; for p in $$list; do \
- p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- if test -f $$p \
- || test -f $$p1 \
- ; then \
- f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
- else :; fi; \
- done
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
- @list='$(sbin_PROGRAMS)'; for p in $$list; do \
- f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
- rm -f "$(DESTDIR)$(sbindir)/$$f"; \
- done
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
clean-sbinPROGRAMS:
- @list='$(sbin_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+digest-service$(EXEEXT): $(digest_service_OBJECTS) $(digest_service_DEPENDENCIES)
+ @rm -f digest-service$(EXEEXT)
+ $(LINK) $(digest_service_OBJECTS) $(digest_service_LDADD) $(LIBS)
hprop$(EXEEXT): $(hprop_OBJECTS) $(hprop_DEPENDENCIES)
@rm -f hprop$(EXEEXT)
$(LINK) $(hprop_OBJECTS) $(hprop_LDADD) $(LIBS)
@@ -652,7 +775,7 @@ hpropd$(EXEEXT): $(hpropd_OBJECTS) $(hpropd_DEPENDENCIES)
$(LINK) $(hpropd_OBJECTS) $(hpropd_LDADD) $(LIBS)
kdc$(EXEEXT): $(kdc_OBJECTS) $(kdc_DEPENDENCIES)
@rm -f kdc$(EXEEXT)
- $(LINK) $(kdc_OBJECTS) $(kdc_LDADD) $(LIBS)
+ $(kdc_LINK) $(kdc_OBJECTS) $(kdc_LDADD) $(LIBS)
kdc-replay$(EXEEXT): $(kdc_replay_OBJECTS) $(kdc_replay_DEPENDENCIES)
@rm -f kdc-replay$(EXEEXT)
$(LINK) $(kdc_replay_OBJECTS) $(kdc_replay_LDADD) $(LIBS)
@@ -669,149 +792,256 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/default_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest-service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hprop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hpropd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdc-announce.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdc-config.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdc-connect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdc-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdc-replay.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kerberos5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5tgs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kstash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kx509.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mit_dump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkinit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_dbinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string2key.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windc.Plo@am__quote@
+
.c.o:
- $(COMPILE) -c $<
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
- $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
- $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+kdc-connect.o: connect.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-connect.o -MD -MP -MF $(DEPDIR)/kdc-connect.Tpo -c -o kdc-connect.o `test -f 'connect.c' || echo '$(srcdir)/'`connect.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-connect.Tpo $(DEPDIR)/kdc-connect.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='connect.c' object='kdc-connect.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-connect.o `test -f 'connect.c' || echo '$(srcdir)/'`connect.c
+
+kdc-connect.obj: connect.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-connect.obj -MD -MP -MF $(DEPDIR)/kdc-connect.Tpo -c -o kdc-connect.obj `if test -f 'connect.c'; then $(CYGPATH_W) 'connect.c'; else $(CYGPATH_W) '$(srcdir)/connect.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-connect.Tpo $(DEPDIR)/kdc-connect.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='connect.c' object='kdc-connect.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-connect.obj `if test -f 'connect.c'; then $(CYGPATH_W) 'connect.c'; else $(CYGPATH_W) '$(srcdir)/connect.c'; fi`
+
+kdc-config.o: config.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-config.o -MD -MP -MF $(DEPDIR)/kdc-config.Tpo -c -o kdc-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-config.Tpo $(DEPDIR)/kdc-config.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config.c' object='kdc-config.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
+
+kdc-config.obj: config.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-config.obj -MD -MP -MF $(DEPDIR)/kdc-config.Tpo -c -o kdc-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-config.Tpo $(DEPDIR)/kdc-config.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config.c' object='kdc-config.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
+
+kdc-announce.o: announce.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-announce.o -MD -MP -MF $(DEPDIR)/kdc-announce.Tpo -c -o kdc-announce.o `test -f 'announce.c' || echo '$(srcdir)/'`announce.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-announce.Tpo $(DEPDIR)/kdc-announce.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='announce.c' object='kdc-announce.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-announce.o `test -f 'announce.c' || echo '$(srcdir)/'`announce.c
+
+kdc-announce.obj: announce.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-announce.obj -MD -MP -MF $(DEPDIR)/kdc-announce.Tpo -c -o kdc-announce.obj `if test -f 'announce.c'; then $(CYGPATH_W) 'announce.c'; else $(CYGPATH_W) '$(srcdir)/announce.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-announce.Tpo $(DEPDIR)/kdc-announce.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='announce.c' object='kdc-announce.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-announce.obj `if test -f 'announce.c'; then $(CYGPATH_W) 'announce.c'; else $(CYGPATH_W) '$(srcdir)/announce.c'; fi`
+
+kdc-main.o: main.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-main.o -MD -MP -MF $(DEPDIR)/kdc-main.Tpo -c -o kdc-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-main.Tpo $(DEPDIR)/kdc-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='kdc-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+kdc-main.obj: main.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -MT kdc-main.obj -MD -MP -MF $(DEPDIR)/kdc-main.Tpo -c -o kdc-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kdc-main.Tpo $(DEPDIR)/kdc-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='kdc-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kdc_CFLAGS) $(CFLAGS) -c -o kdc-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-install-man8: $(man8_MANS) $(man_MANS)
+install-man8: $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
- @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
- l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
- for i in $$l2; do \
- case "$$i" in \
- *.8*) list="$$list $$i" ;; \
- esac; \
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
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/^.*\\.//'`; \
- case "$$ext" in \
- 8*) ;; \
- *) ext='8' ;; \
- esac; \
- inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
- inst=`echo $$inst | sed -e 's/^.*\///'`; \
- inst=`echo $$inst | sed '$(transform)'`.$$ext; \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
- done
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
uninstall-man8:
@$(NORMAL_UNINSTALL)
- @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
- l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
- for i in $$l2; do \
- case "$$i" in \
- *.8*) list="$$list $$i" ;; \
- esac; \
- done; \
- for i in $$list; do \
- ext=`echo $$i | sed -e 's/^.*\\.//'`; \
- case "$$ext" in \
- 8*) ;; \
- *) ext='8' ;; \
- esac; \
- inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
- inst=`echo $$inst | sed -e 's/^.*\///'`; \
- inst=`echo $$inst | sed '$(transform)'`.$$ext; \
- echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
- rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
- done
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man8dir)" && rm -f $$files; }
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
- @list='$(include_HEADERS)'; for p in $$list; do \
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
- $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
- @list='$(include_HEADERS)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
- rm -f "$(DESTDIR)$(includedir)/$$f"; \
- done
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(includedir)" && rm -f $$files
install-krb5HEADERS: $(krb5_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(krb5dir)" || $(MKDIR_P) "$(DESTDIR)$(krb5dir)"
- @list='$(krb5_HEADERS)'; for p in $$list; do \
+ @list='$(krb5_HEADERS)'; test -n "$(krb5dir)" || list=; \
+ for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(krb5HEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(krb5dir)/$$f'"; \
- $(krb5HEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(krb5dir)/$$f"; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(krb5dir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(krb5dir)" || exit $$?; \
done
uninstall-krb5HEADERS:
@$(NORMAL_UNINSTALL)
- @list='$(krb5_HEADERS)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(krb5dir)/$$f'"; \
- rm -f "$(DESTDIR)$(krb5dir)/$$f"; \
- done
+ @list='$(krb5_HEADERS)'; test -n "$(krb5dir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(krb5dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(krb5dir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
+ set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
+ $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically \`make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -827,13 +1057,17 @@ distdir: $(DISTFILES)
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@@ -871,6 +1105,7 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -882,6 +1117,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -892,6 +1128,8 @@ dvi-am:
html: html-am
+html-am:
+
info: info-am
info-am:
@@ -900,27 +1138,36 @@ install-data-am: install-includeHEADERS install-krb5HEADERS \
install-man
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
-
install-dvi: install-dvi-am
+install-dvi-am:
+
install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \
install-libexecPROGRAMS install-sbinPROGRAMS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
-
install-html: install-html-am
+install-html-am:
+
install-info: install-info-am
+install-info-am:
+
install-man: install-man8
install-pdf: install-pdf-am
+install-pdf-am:
+
install-ps: install-ps-am
+install-ps-am:
+
installcheck-am:
maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -942,11 +1189,10 @@ uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
uninstall-libexecPROGRAMS uninstall-man uninstall-sbinPROGRAMS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
-
uninstall-man: uninstall-man8
-.MAKE: install-am install-data-am install-exec-am install-strip \
- uninstall-am
+.MAKE: check-am install-am install-data-am install-exec-am \
+ install-strip uninstall-am
.PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \
clean clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
@@ -1039,6 +1285,9 @@ check-local::
.x.c:
@cmp -s $< $@ 2> /dev/null || cp $< $@
+
+.hx.h:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
#NROFF_MAN = nroff -man
.1.cat1:
$(NROFF_MAN) $< > $@
@@ -1124,7 +1373,7 @@ uninstall-hook: uninstall-cat-mans
check-valgrind:
tobjdir=`cd $(top_builddir) && pwd` ; \
tsrcdir=`cd $(top_srcdir) && pwd` ; \
- env TESTS_ENVIRONMENT="$${tobjdir}/libtool --mode execute valgrind --leak-check=full --trace-children=yes --quiet -q --num-callers=30 --suppressions=$${tsrcdir}/cf/valgrind-suppressions" make check
+ env TESTS_ENVIRONMENT="$${tsrcdir}/cf/maybe-valgrind.sh -s $${tsrcdir} -o $${tobjdir}" make check
#
# Target to please samba build farm, builds distfiles in-tree.
@@ -1146,6 +1395,7 @@ $(srcdir)/kdc-protos.h:
$(srcdir)/kdc-private.h:
cd $(srcdir) && perl ../cf/make-proto.pl -q -P comment -p kdc-private.h $(libkdc_la_SOURCES) || rm -f kdc-private.h
+
# 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/kdc/announce.c b/crypto/heimdal/kdc/announce.c
new file mode 100644
index 0000000..cf3fdc3
--- /dev/null
+++ b/crypto/heimdal/kdc/announce.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Apple Inc. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Apple Inc. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include "kdc_locl.h"
+
+#if defined(__APPLE__) && defined(HAVE_GCD)
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
+#include <SystemConfiguration/SCDynamicStoreKey.h>
+
+#include <dispatch/dispatch.h>
+
+#include <asl.h>
+#include <resolv.h>
+
+#include <dns_sd.h>
+#include <err.h>
+
+static krb5_kdc_configuration *announce_config;
+static krb5_context announce_context;
+
+struct entry {
+ DNSRecordRef recordRef;
+ char *domain;
+ char *realm;
+#define F_EXISTS 1
+#define F_PUSH 2
+ int flags;
+ struct entry *next;
+};
+
+/* #define REGISTER_SRV_RR */
+
+static struct entry *g_entries = NULL;
+static CFStringRef g_hostname = NULL;
+static DNSServiceRef g_dnsRef = NULL;
+static SCDynamicStoreRef g_store = NULL;
+static dispatch_queue_t g_queue = NULL;
+
+#define LOG(...) asl_log(NULL, NULL, ASL_LEVEL_INFO, __VA_ARGS__)
+
+static void create_dns_sd(void);
+static void destroy_dns_sd(void);
+static void update_all(SCDynamicStoreRef, CFArrayRef, void *);
+
+
+/* parameters */
+static CFStringRef NetworkChangedKey_BackToMyMac = CFSTR("Setup:/Network/BackToMyMac");
+
+
+static char *
+CFString2utf8(CFStringRef string)
+{
+ size_t size;
+ char *str;
+
+ size = 1 + CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8);
+ str = malloc(size);
+ if (str == NULL)
+ return NULL;
+
+ if (CFStringGetCString(string, str, size, kCFStringEncodingUTF8) == false) {
+ free(str);
+ return NULL;
+ }
+ return str;
+}
+
+/*
+ *
+ */
+
+static void
+retry_timer(void)
+{
+ dispatch_source_t s;
+ dispatch_time_t t;
+
+ s = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
+ 0, 0, g_queue);
+ t = dispatch_time(DISPATCH_TIME_NOW, 5ull * NSEC_PER_SEC);
+ dispatch_source_set_timer(s, t, 0, NSEC_PER_SEC);
+ dispatch_source_set_event_handler(s, ^{
+ create_dns_sd();
+ dispatch_release(s);
+ });
+ dispatch_resume(s);
+}
+
+/*
+ *
+ */
+
+static void
+create_dns_sd(void)
+{
+ DNSServiceErrorType error;
+ dispatch_source_t s;
+
+ error = DNSServiceCreateConnection(&g_dnsRef);
+ if (error) {
+ retry_timer();
+ return;
+ }
+
+ dispatch_suspend(g_queue);
+
+ s = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,
+ DNSServiceRefSockFD(g_dnsRef),
+ 0, g_queue);
+
+ dispatch_source_set_event_handler(s, ^{
+ DNSServiceErrorType ret = DNSServiceProcessResult(g_dnsRef);
+ /* on error tear down and set timer to recreate */
+ if (ret != kDNSServiceErr_NoError && ret != kDNSServiceErr_Transient) {
+ dispatch_source_cancel(s);
+ }
+ });
+
+ dispatch_source_set_cancel_handler(s, ^{
+ destroy_dns_sd();
+ retry_timer();
+ dispatch_release(s);
+ });
+
+ dispatch_resume(s);
+
+ /* Do the first update ourself */
+ update_all(g_store, NULL, NULL);
+ dispatch_resume(g_queue);
+}
+
+static void
+domain_add(const char *domain, const char *realm, int flag)
+{
+ struct entry *e;
+
+ for (e = g_entries; e != NULL; e = e->next) {
+ if (strcmp(domain, e->domain) == 0 && strcmp(realm, e->realm) == 0) {
+ e->flags |= flag;
+ return;
+ }
+ }
+
+ LOG("Adding realm %s to domain %s", realm, domain);
+
+ e = calloc(1, sizeof(*e));
+ if (e == NULL)
+ return;
+ e->domain = strdup(domain);
+ e->realm = strdup(realm);
+ if (e->domain == NULL || e->realm == NULL) {
+ free(e->domain);
+ free(e->realm);
+ free(e);
+ return;
+ }
+ e->flags = flag | F_PUSH; /* if we allocate, we push */
+ e->next = g_entries;
+ g_entries = e;
+}
+
+struct addctx {
+ int flags;
+ const char *realm;
+};
+
+static void
+domains_add(const void *key, const void *value, void *context)
+{
+ char *str = CFString2utf8((CFStringRef)value);
+ struct addctx *ctx = context;
+
+ if (str == NULL)
+ return;
+ if (str[0] != '\0')
+ domain_add(str, ctx->realm, F_EXISTS | ctx->flags);
+ free(str);
+}
+
+
+static void
+dnsCallback(DNSServiceRef sdRef __attribute__((unused)),
+ DNSRecordRef RecordRef __attribute__((unused)),
+ DNSServiceFlags flags __attribute__((unused)),
+ DNSServiceErrorType errorCode __attribute__((unused)),
+ void *context __attribute__((unused)))
+{
+}
+
+#ifdef REGISTER_SRV_RR
+
+/*
+ * Register DNS SRV rr for the realm.
+ */
+
+static const char *register_names[2] = {
+ "_kerberos._tcp",
+ "_kerberos._udp"
+};
+
+static struct {
+ DNSRecordRef *val;
+ size_t len;
+} srvRefs = { NULL, 0 };
+
+static void
+register_srv(const char *realm, const char *hostname, int port)
+{
+ unsigned char target[1024];
+ int i;
+ int size;
+
+ /* skip registering LKDC realms */
+ if (strncmp(realm, "LKDC:", 5) == 0)
+ return;
+
+ /* encode SRV-RR */
+ target[0] = 0; /* priority */
+ target[1] = 0; /* priority */
+ target[2] = 0; /* weight */
+ target[3] = 0; /* weigth */
+ target[4] = (port >> 8) & 0xff; /* port */
+ target[5] = (port >> 0) & 0xff; /* port */
+
+ size = dn_comp(hostname, target + 6, sizeof(target) - 6, NULL, NULL);
+ if (size < 0)
+ return;
+
+ size += 6;
+
+ LOG("register SRV rr for realm %s hostname %s:%d", realm, hostname, port);
+
+ for (i = 0; i < sizeof(register_names)/sizeof(register_names[0]); i++) {
+ char name[kDNSServiceMaxDomainName];
+ DNSServiceErrorType error;
+ void *ptr;
+
+ ptr = realloc(srvRefs.val, sizeof(srvRefs.val[0]) * (srvRefs.len + 1));
+ if (ptr == NULL)
+ errx(1, "malloc: out of memory");
+ srvRefs.val = ptr;
+
+ DNSServiceConstructFullName(name, NULL, register_names[i], realm);
+
+ error = DNSServiceRegisterRecord(g_dnsRef,
+ &srvRefs.val[srvRefs.len],
+ kDNSServiceFlagsUnique | kDNSServiceFlagsShareConnection,
+ 0,
+ name,
+ kDNSServiceType_SRV,
+ kDNSServiceClass_IN,
+ size,
+ target,
+ 0,
+ dnsCallback,
+ NULL);
+ if (error) {
+ LOG("Failed to register SRV rr for realm %s: %d", realm, error);
+ } else
+ srvRefs.len++;
+ }
+}
+
+static void
+unregister_srv_realms(void)
+{
+ if (g_dnsRef) {
+ for (i = 0; i < srvRefs.len; i++)
+ DNSServiceRemoveRecord(g_dnsRef, srvRefs.val[i], 0);
+ }
+ free(srvRefs.val);
+ srvRefs.len = 0;
+ srvRefs.val = NULL;
+}
+
+static void
+register_srv_realms(CFStringRef host)
+{
+ krb5_error_code ret;
+ char *hostname;
+ size_t i;
+
+ /* first unregister old names */
+
+ hostname = CFString2utf8(host);
+ if (hostname == NULL)
+ return;
+
+ for(i = 0; i < announce_config->num_db; i++) {
+ char **realms, **r;
+
+ if (announce_config->db[i]->hdb_get_realms == NULL)
+ continue;
+
+ ret = (announce_config->db[i]->hdb_get_realms)(announce_context, &realms);
+ if (ret == 0) {
+ for (r = realms; r && *r; r++)
+ register_srv(*r, hostname, 88);
+ krb5_free_host_realm(announce_context, realms);
+ }
+ }
+
+ free(hostname);
+}
+#endif /* REGISTER_SRV_RR */
+
+static void
+update_dns(void)
+{
+ DNSServiceErrorType error;
+ struct entry **e = &g_entries;
+ char *hostname;
+
+ hostname = CFString2utf8(g_hostname);
+ if (hostname == NULL)
+ return;
+
+ while (*e != NULL) {
+ /* remove if this wasn't updated */
+ if (((*e)->flags & F_EXISTS) == 0) {
+ struct entry *drop = *e;
+ *e = (*e)->next;
+
+ LOG("Deleting realm %s from domain %s",
+ drop->realm, drop->domain);
+
+ if (drop->recordRef && g_dnsRef)
+ DNSServiceRemoveRecord(g_dnsRef, drop->recordRef, 0);
+ free(drop->domain);
+ free(drop->realm);
+ free(drop);
+ continue;
+ }
+ if ((*e)->flags & F_PUSH) {
+ struct entry *update = *e;
+ char *dnsdata, *name;
+ size_t len;
+
+ len = strlen(update->realm);
+ asprintf(&dnsdata, "%c%s", (int)len, update->realm);
+ if (dnsdata == NULL)
+ errx(1, "malloc");
+
+ asprintf(&name, "_kerberos.%s.%s", hostname, update->domain);
+ if (name == NULL)
+ errx(1, "malloc");
+
+ if (update->recordRef)
+ DNSServiceRemoveRecord(g_dnsRef, update->recordRef, 0);
+
+ error = DNSServiceRegisterRecord(g_dnsRef,
+ &update->recordRef,
+ kDNSServiceFlagsShared | kDNSServiceFlagsAllowRemoteQuery,
+ 0,
+ name,
+ kDNSServiceType_TXT,
+ kDNSServiceClass_IN,
+ len+1,
+ dnsdata,
+ 0,
+ dnsCallback,
+ NULL);
+ free(name);
+ free(dnsdata);
+ if (error)
+ errx(1, "failure to update entry for %s/%s",
+ update->domain, update->realm);
+ }
+ e = &(*e)->next;
+ }
+ free(hostname);
+}
+
+static void
+update_entries(SCDynamicStoreRef store, const char *realm, int flags)
+{
+ CFDictionaryRef btmm;
+
+ /* we always announce in the local domain */
+ domain_add("local", realm, F_EXISTS | flags);
+
+ /* announce btmm */
+ btmm = SCDynamicStoreCopyValue(store, NetworkChangedKey_BackToMyMac);
+ if (btmm) {
+ struct addctx addctx;
+
+ addctx.flags = flags;
+ addctx.realm = realm;
+
+ CFDictionaryApplyFunction(btmm, domains_add, &addctx);
+ CFRelease(btmm);
+ }
+}
+
+static void
+update_all(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
+{
+ struct entry *e;
+ CFStringRef host;
+ int i, flags = 0;
+
+ LOG("something changed, running update");
+
+ host = SCDynamicStoreCopyLocalHostName(store);
+ if (host == NULL)
+ return;
+
+ if (g_hostname == NULL || CFStringCompare(host, g_hostname, 0) != kCFCompareEqualTo) {
+ if (g_hostname)
+ CFRelease(g_hostname);
+ g_hostname = CFRetain(host);
+ flags = F_PUSH; /* if hostname has changed, force push */
+
+#ifdef REGISTER_SRV_RR
+ register_srv_realms(g_hostname);
+#endif
+ }
+
+ for (e = g_entries; e != NULL; e = e->next)
+ e->flags &= ~(F_EXISTS|F_PUSH);
+
+ for(i = 0; i < announce_config->num_db; i++) {
+ krb5_error_code ret;
+ char **realms, **r;
+
+ if (announce_config->db[i]->hdb_get_realms == NULL)
+ continue;
+
+ ret = (announce_config->db[i]->hdb_get_realms)(announce_context, announce_config->db[i], &realms);
+ if (ret == 0) {
+ for (r = realms; r && *r; r++)
+ update_entries(store, *r, flags);
+ krb5_free_host_realm(announce_context, realms);
+ }
+ }
+
+ update_dns();
+
+ CFRelease(host);
+}
+
+static void
+delete_all(void)
+{
+ struct entry *e;
+
+ for (e = g_entries; e != NULL; e = e->next)
+ e->flags &= ~(F_EXISTS|F_PUSH);
+
+ update_dns();
+ if (g_entries != NULL)
+ errx(1, "Failed to remove all bonjour entries");
+}
+
+static void
+destroy_dns_sd(void)
+{
+ if (g_dnsRef == NULL)
+ return;
+
+ delete_all();
+#ifdef REGISTER_SRV_RR
+ unregister_srv_realms();
+#endif
+
+ DNSServiceRefDeallocate(g_dnsRef);
+ g_dnsRef = NULL;
+}
+
+
+static SCDynamicStoreRef
+register_notification(void)
+{
+ SCDynamicStoreRef store;
+ CFStringRef computerNameKey;
+ CFMutableArrayRef keys;
+
+ computerNameKey = SCDynamicStoreKeyCreateHostNames(kCFAllocatorDefault);
+
+ store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("Network watcher"),
+ update_all, NULL);
+ if (store == NULL)
+ errx(1, "SCDynamicStoreCreate");
+
+ keys = CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks);
+ if (keys == NULL)
+ errx(1, "CFArrayCreateMutable");
+
+ CFArrayAppendValue(keys, computerNameKey);
+ CFArrayAppendValue(keys, NetworkChangedKey_BackToMyMac);
+
+ if (SCDynamicStoreSetNotificationKeys(store, keys, NULL) == false)
+ errx(1, "SCDynamicStoreSetNotificationKeys");
+
+ CFRelease(computerNameKey);
+ CFRelease(keys);
+
+ if (!SCDynamicStoreSetDispatchQueue(store, g_queue))
+ errx(1, "SCDynamicStoreSetDispatchQueue");
+
+ return store;
+}
+#endif
+
+void
+bonjour_announce(krb5_context context, krb5_kdc_configuration *config)
+{
+#if defined(__APPLE__) && defined(HAVE_GCD)
+ g_queue = dispatch_queue_create("com.apple.kdc_announce", NULL);
+ if (!g_queue)
+ errx(1, "dispatch_queue_create");
+
+ g_store = register_notification();
+ announce_config = config;
+ announce_context = context;
+
+ create_dns_sd();
+#endif
+}
diff --git a/crypto/heimdal/kdc/config.c b/crypto/heimdal/kdc/config.c
index a4d40fc..a437bbd 100644
--- a/crypto/heimdal/kdc/config.c
+++ b/crypto/heimdal/kdc/config.c
@@ -1,43 +1,42 @@
/*
- * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
*
- * All rights reserved.
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
#include <getarg.h>
#include <parse_bytes.h>
-RCSID("$Id: config.c 22248 2007-12-08 23:52:12Z lha $");
-
struct dbinfo {
char *realm;
char *dbname;
@@ -51,10 +50,6 @@ static int require_preauth = -1; /* 1 == require preauth for all principals */
static char *max_request_str; /* `max_request' as a string */
static int disable_des = -1;
-static int enable_v4 = -1;
-static int enable_kaserver = -1;
-static int enable_524 = -1;
-static int enable_v4_cross_realm = -1;
static int builtin_hdb_flag;
static int help_flag;
@@ -62,62 +57,55 @@ static int version_flag;
static struct getarg_strings addresses_str; /* addresses to listen on */
-static char *v4_realm;
+char *runas_string;
+char *chroot_string;
+
static struct getargs args[] = {
- {
- "config-file", 'c', arg_string, &config_file,
- "location of config file", "file"
- },
- {
- "require-preauth", 'p', arg_negative_flag, &require_preauth,
- "don't require pa-data in as-reqs"
- },
- {
- "max-request", 0, arg_string, &max_request,
- "max size for a kdc-request", "size"
- },
- { "enable-http", 'H', arg_flag, &enable_http, "turn on HTTP support" },
- { "524", 0, arg_negative_flag, &enable_524,
- "don't respond to 524 requests"
- },
{
- "kaserver", 'K', arg_flag, &enable_kaserver,
- "enable kaserver support"
+ "config-file", 'c', arg_string, &config_file,
+ "location of config file", "file"
},
- { "kerberos4", 0, arg_flag, &enable_v4,
- "respond to kerberos 4 requests"
- },
- {
- "v4-realm", 'r', arg_string, &v4_realm,
- "realm to serve v4-requests for"
+ {
+ "require-preauth", 'p', arg_negative_flag, &require_preauth,
+ "don't require pa-data in as-reqs", NULL
},
- { "kerberos4-cross-realm", 0, arg_flag,
- &enable_v4_cross_realm,
- "respond to kerberos 4 requests from foreign realms"
+ {
+ "max-request", 0, arg_string, &max_request_str,
+ "max size for a kdc-request", "size"
},
- { "ports", 'P', arg_string, &port_str,
+ { "enable-http", 'H', arg_flag, &enable_http, "turn on HTTP support",
+ NULL },
+ { "ports", 'P', arg_string, rk_UNCONST(&port_str),
"ports to listen to", "portspec"
},
+#ifdef SUPPORT_DETACH
#if DETACH_IS_DEFAULT
{
- "detach", 'D', arg_negative_flag, &detach_from_console,
- "don't detach from console"
+ "detach", 'D', arg_negative_flag, &detach_from_console,
+ "don't detach from console", NULL
},
#else
{
- "detach", 0 , arg_flag, &detach_from_console,
- "detach from console"
+ "detach", 0 , arg_flag, &detach_from_console,
+ "detach from console", NULL
},
#endif
+#endif
{ "addresses", 0, arg_strings, &addresses_str,
"addresses to listen on", "list of addresses" },
{ "disable-des", 0, arg_flag, &disable_des,
- "disable DES" },
+ "disable DES", NULL },
{ "builtin-hdb", 0, arg_flag, &builtin_hdb_flag,
- "list builtin hdb backends"},
- { "help", 'h', arg_flag, &help_flag },
- { "version", 'v', arg_flag, &version_flag }
+ "list builtin hdb backends", NULL},
+ { "runas-user", 0, arg_string, &runas_string,
+ "run as this user when connected to network", NULL
+ },
+ { "chroot", 0, arg_string, &chroot_string,
+ "chroot directory to run in", NULL
+ },
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL },
+ { "version", 'v', arg_flag, &version_flag, NULL, NULL }
};
static int num_args = sizeof(args) / sizeof(args[0]);
@@ -152,7 +140,7 @@ configure(krb5_context context, int argc, char **argv)
krb5_error_code ret;
int optidx = 0;
const char *p;
-
+
while(getarg(args, num_args, argc, argv, &optidx))
warnx("error at argument `%s'", argv[optidx]);
@@ -179,7 +167,7 @@ configure(krb5_context context, int argc, char **argv)
if (argc != 0)
usage(1);
-
+
{
char **files;
@@ -192,10 +180,10 @@ configure(krb5_context context, int argc, char **argv)
ret = krb5_prepend_config_files_default(config_file, &files);
if (ret)
krb5_err(context, 1, ret, "getting configuration files");
-
+
ret = krb5_set_config_files(context, files);
krb5_free_config_files(files);
- if(ret)
+ if(ret)
krb5_err(context, 1, ret, "reading configuration files");
}
@@ -203,25 +191,25 @@ configure(krb5_context context, int argc, char **argv)
if (ret)
krb5_err(context, 1, ret, "krb5_kdc_default_config");
- kdc_openlog(context, config);
+ kdc_openlog(context, "kdc", config);
ret = krb5_kdc_set_dbinfo(context, config);
if (ret)
krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo");
if(max_request_str)
- max_request = parse_bytes(max_request_str, NULL);
+ max_request_tcp = max_request_udp = parse_bytes(max_request_str, NULL);
- if(max_request == 0){
+ if(max_request_tcp == 0){
p = krb5_config_get_string (context,
NULL,
"kdc",
"max-request",
NULL);
if(p)
- max_request = parse_bytes(p, NULL);
+ max_request_tcp = max_request_udp = parse_bytes(p, NULL);
}
-
+
if(require_preauth != -1)
config->require_preauth = require_preauth;
@@ -250,53 +238,39 @@ configure(krb5_context context, int argc, char **argv)
}
}
- if(enable_v4 != -1)
- config->enable_v4 = enable_v4;
-
- if(enable_v4_cross_realm != -1)
- config->enable_v4_cross_realm = enable_v4_cross_realm;
-
- if(enable_524 != -1)
- config->enable_524 = enable_524;
-
if(enable_http == -1)
- enable_http = krb5_config_get_bool(context, NULL, "kdc",
+ enable_http = krb5_config_get_bool(context, NULL, "kdc",
"enable-http", NULL);
if(request_log == NULL)
- request_log = krb5_config_get_string(context, NULL,
- "kdc",
- "kdc-request-log",
+ request_log = krb5_config_get_string(context, NULL,
+ "kdc",
+ "kdc-request-log",
NULL);
- if (krb5_config_get_string(context, NULL, "kdc",
+ if (krb5_config_get_string(context, NULL, "kdc",
"enforce-transited-policy", NULL))
krb5_errx(context, 1, "enforce-transited-policy deprecated, "
"use [kdc]transited-policy instead");
- if (enable_kaserver != -1)
- config->enable_kaserver = enable_kaserver;
-
- if(detach_from_console == -1)
- detach_from_console = krb5_config_get_bool_default(context, NULL,
+#ifdef SUPPORT_DETACH
+ if(detach_from_console == -1)
+ detach_from_console = krb5_config_get_bool_default(context, NULL,
DETACH_IS_DEFAULT,
"kdc",
"detach", NULL);
+#endif /* SUPPORT_DETACH */
- if(max_request == 0)
- max_request = 64 * 1024;
+ if(max_request_tcp == 0)
+ max_request_tcp = 64 * 1024;
+ if(max_request_udp == 0)
+ max_request_udp = 64 * 1024;
if (port_str == NULL)
port_str = "+";
- if (v4_realm)
- config->v4_realm = v4_realm;
-
- if(config->v4_realm == NULL && (config->enable_kaserver || config->enable_v4))
- krb5_errx(context, 1, "Kerberos 4 enabled but no realm configured");
-
if(disable_des == -1)
- disable_des = krb5_config_get_bool_default(context, NULL,
+ disable_des = krb5_config_get_bool_default(context, NULL,
FALSE,
"kdc",
"disable-des", NULL);
@@ -307,16 +281,11 @@ configure(krb5_context context, int argc, char **argv)
krb5_enctype_disable(context, ETYPE_DES_CBC_NONE);
krb5_enctype_disable(context, ETYPE_DES_CFB64_NONE);
krb5_enctype_disable(context, ETYPE_DES_PCBC_NONE);
-
- kdc_log(context, config,
- 0, "DES was disabled, turned off Kerberos V4, 524 "
- "and kaserver");
- config->enable_v4 = 0;
- config->enable_524 = 0;
- config->enable_kaserver = 0;
}
krb5_kdc_windc_init(context);
+ krb5_kdc_pkinit_config(context, config);
+
return config;
}
diff --git a/crypto/heimdal/kdc/connect.c b/crypto/heimdal/kdc/connect.c
index c2df088..8ecf375 100644
--- a/crypto/heimdal/kdc/connect.c
+++ b/crypto/heimdal/kdc/connect.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2005 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: connect.c 22434 2008-01-14 09:21:37Z lha $");
-
/* Should we enable the HTTP hack? */
int enable_http = -1;
@@ -46,7 +44,8 @@ const char *port_str;
krb5_addresses explicit_addresses;
-size_t max_request; /* maximal size of a request */
+size_t max_request_udp;
+size_t max_request_tcp;
/*
* a tuple describing on what to listen
@@ -61,18 +60,18 @@ struct port_desc{
/* the current ones */
static struct port_desc *ports;
-static int num_ports;
+static size_t num_ports;
/*
* add `family, port, protocol' to the list with duplicate suppresion.
*/
static void
-add_port(krb5_context context,
+add_port(krb5_context context,
int family, int port, const char *protocol)
{
int type;
- int i;
+ size_t i;
if(strcmp(protocol, "udp") == 0)
type = SOCK_DGRAM;
@@ -101,7 +100,7 @@ add_port(krb5_context context,
*/
static void
-add_port_service(krb5_context context,
+add_port_service(krb5_context context,
int family, const char *service, int port,
const char *protocol)
{
@@ -115,7 +114,7 @@ add_port_service(krb5_context context,
*/
static void
-add_port_string (krb5_context context,
+add_port_string (krb5_context context,
int family, const char *str, const char *protocol)
{
struct servent *sp;
@@ -139,7 +138,7 @@ add_port_string (krb5_context context,
*/
static void
-add_standard_ports (krb5_context context,
+add_standard_ports (krb5_context context,
krb5_kdc_configuration *config,
int family)
{
@@ -149,16 +148,6 @@ add_standard_ports (krb5_context context,
add_port_service(context, family, "kerberos-sec", 88, "tcp");
if(enable_http)
add_port_service(context, family, "http", 80, "tcp");
- if(config->enable_524) {
- add_port_service(context, family, "krb524", 4444, "udp");
- add_port_service(context, family, "krb524", 4444, "tcp");
- }
- if(config->enable_v4) {
- add_port_service(context, family, "kerberos-iv", 750, "udp");
- add_port_service(context, family, "kerberos-iv", 750, "tcp");
- }
- if (config->enable_kaserver)
- add_port_service(context, family, "afs3-kaserver", 7004, "udp");
if(config->enable_kx509) {
add_port_service(context, family, "kca_service", 9878, "udp");
add_port_service(context, family, "kca_service", 9878, "tcp");
@@ -173,7 +162,7 @@ add_standard_ports (krb5_context context,
*/
static void
-parse_ports(krb5_context context,
+parse_ports(krb5_context context,
krb5_kdc_configuration *config,
const char *str)
{
@@ -205,7 +194,7 @@ parse_ports(krb5_context context,
add_port_string(context, AF_INET, p, "tcp");
}
}
-
+
p = strtok_r(NULL, " \t", &pos);
}
free (str_copy);
@@ -216,7 +205,7 @@ parse_ports(krb5_context context,
*/
struct descr {
- int s;
+ krb5_socket_t s;
int type;
int port;
unsigned char *buf;
@@ -234,7 +223,7 @@ init_descr(struct descr *d)
{
memset(d, 0, sizeof(*d));
d->sa = (struct sockaddr *)&d->__ss;
- d->s = -1;
+ d->s = rk_INVALID_SOCKET;
}
/*
@@ -254,8 +243,8 @@ reinit_descrs (struct descr *d, int n)
* Create the socket (family, type, port) in `d'
*/
-static void
-init_socket(krb5_context context,
+static void
+init_socket(krb5_context context,
krb5_kdc_configuration *config,
struct descr *d, krb5_address *a, int family, int type, int port)
{
@@ -269,8 +258,8 @@ init_socket(krb5_context context,
ret = krb5_addr2sockaddr (context, a, sa, &sa_size, port);
if (ret) {
krb5_warn(context, ret, "krb5_addr2sockaddr");
- close(d->s);
- d->s = -1;
+ rk_closesocket(d->s);
+ d->s = rk_INVALID_SOCKET;
return;
}
@@ -278,9 +267,9 @@ init_socket(krb5_context context,
return;
d->s = socket(family, type, 0);
- if(d->s < 0){
+ if(rk_IS_BAD_SOCKET(d->s)){
krb5_warn(context, errno, "socket(%d, %d, 0)", family, type);
- d->s = -1;
+ d->s = rk_INVALID_SOCKET;
return;
}
#if defined(HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_REUSEADDR)
@@ -292,24 +281,24 @@ init_socket(krb5_context context,
d->type = type;
d->port = port;
- if(bind(d->s, sa, sa_size) < 0){
+ if(rk_IS_SOCKET_ERROR(bind(d->s, sa, sa_size))){
char a_str[256];
size_t len;
krb5_print_address (a, a_str, sizeof(a_str), &len);
krb5_warn(context, errno, "bind %s/%d", a_str, ntohs(port));
- close(d->s);
- d->s = -1;
+ rk_closesocket(d->s);
+ d->s = rk_INVALID_SOCKET;
return;
}
- if(type == SOCK_STREAM && listen(d->s, SOMAXCONN) < 0){
+ if(type == SOCK_STREAM && rk_IS_SOCKET_ERROR(listen(d->s, SOMAXCONN))){
char a_str[256];
size_t len;
krb5_print_address (a, a_str, sizeof(a_str), &len);
krb5_warn(context, errno, "listen %s/%d", a_str, ntohs(port));
- close(d->s);
- d->s = -1;
+ rk_closesocket(d->s);
+ d->s = rk_INVALID_SOCKET;
return;
}
}
@@ -320,12 +309,12 @@ init_socket(krb5_context context,
*/
static int
-init_sockets(krb5_context context,
+init_sockets(krb5_context context,
krb5_kdc_configuration *config,
struct descr **desc)
{
krb5_error_code ret;
- int i, j;
+ size_t i, j;
struct descr *d;
int num = 0;
krb5_addresses addresses;
@@ -347,7 +336,7 @@ init_sockets(krb5_context context,
for (j = 0; j < addresses.len; ++j) {
init_socket(context, config, &d[num], &addresses.val[j],
ports[i].family, ports[i].type, ports[i].port);
- if(d[num].s != -1){
+ if(d[num].s != rk_INVALID_SOCKET){
char a_str[80];
size_t len;
@@ -356,7 +345,7 @@ init_sockets(krb5_context context,
kdc_log(context, config, 5, "listening on %s port %u/%s",
a_str,
- ntohs(ports[i].port),
+ ntohs(ports[i].port),
(ports[i].type == SOCK_STREAM) ? "tcp" : "udp");
/* XXX */
num++;
@@ -388,7 +377,7 @@ descr_type(struct descr *d)
}
static void
-addr_to_string(krb5_context context,
+addr_to_string(krb5_context context,
struct sockaddr *addr, size_t addr_len, char *str, size_t len)
{
krb5_address a;
@@ -407,7 +396,7 @@ addr_to_string(krb5_context context,
*/
static void
-send_reply(krb5_context context,
+send_reply(krb5_context context,
krb5_kdc_configuration *config,
krb5_boolean prependlength,
struct descr *d,
@@ -422,15 +411,16 @@ send_reply(krb5_context context,
l[1] = (reply->length >> 16) & 0xff;
l[2] = (reply->length >> 8) & 0xff;
l[3] = reply->length & 0xff;
- if(sendto(d->s, l, sizeof(l), 0, d->sa, d->sock_len) < 0) {
- kdc_log (context, config,
- 0, "sendto(%s): %s", d->addr_string, strerror(errno));
+ if(rk_IS_SOCKET_ERROR(sendto(d->s, l, sizeof(l), 0, d->sa, d->sock_len))) {
+ kdc_log (context, config,
+ 0, "sendto(%s): %s", d->addr_string,
+ strerror(rk_SOCK_ERRNO));
return;
}
}
- if(sendto(d->s, reply->data, reply->length, 0, d->sa, d->sock_len) < 0) {
- kdc_log (context, config,
- 0, "sendto(%s): %s", d->addr_string, strerror(errno));
+ if(rk_IS_SOCKET_ERROR(sendto(d->s, reply->data, reply->length, 0, d->sa, d->sock_len))) {
+ kdc_log (context, config, 0, "sendto(%s): %s", d->addr_string,
+ strerror(rk_SOCK_ERRNO));
return;
}
}
@@ -440,7 +430,7 @@ send_reply(krb5_context context,
*/
static void
-do_request(krb5_context context,
+do_request(krb5_context context,
krb5_kdc_configuration *config,
void *buf, size_t len, krb5_boolean prependlength,
struct descr *d)
@@ -452,7 +442,7 @@ do_request(krb5_context context,
krb5_kdc_update_time(NULL);
krb5_data_zero(&reply);
- ret = krb5_kdc_process_request(context, config,
+ ret = krb5_kdc_process_request(context, config,
buf, len, &reply, &prependlength,
d->addr_string, d->sa,
datagram_reply);
@@ -463,8 +453,8 @@ do_request(krb5_context context,
krb5_data_free(&reply);
}
if(ret)
- kdc_log(context, config, 0,
- "Failed processing %lu byte request from %s",
+ kdc_log(context, config, 0,
+ "Failed processing %lu byte request from %s",
(unsigned long)len, d->addr_string);
}
@@ -473,27 +463,45 @@ do_request(krb5_context context,
*/
static void
-handle_udp(krb5_context context,
+handle_udp(krb5_context context,
krb5_kdc_configuration *config,
struct descr *d)
{
unsigned char *buf;
- int n;
+ ssize_t n;
- buf = malloc(max_request);
+ buf = malloc(max_request_udp);
if(buf == NULL){
- kdc_log(context, config, 0, "Failed to allocate %lu bytes", (unsigned long)max_request);
+ kdc_log(context, config, 0, "Failed to allocate %lu bytes", (unsigned long)max_request_udp);
return;
}
d->sock_len = sizeof(d->__ss);
- n = recvfrom(d->s, buf, max_request, 0, d->sa, &d->sock_len);
- if(n < 0)
- krb5_warn(context, errno, "recvfrom");
+ n = recvfrom(d->s, buf, max_request_udp, 0, d->sa, &d->sock_len);
+ if(rk_IS_SOCKET_ERROR(n))
+ krb5_warn(context, rk_SOCK_ERRNO, "recvfrom");
else {
addr_to_string (context, d->sa, d->sock_len,
d->addr_string, sizeof(d->addr_string));
- do_request(context, config, buf, n, FALSE, d);
+ if ((size_t)n == max_request_udp) {
+ krb5_data data;
+ krb5_warn(context, errno,
+ "recvfrom: truncated packet from %s, asking for TCP",
+ d->addr_string);
+ krb5_mk_error(context,
+ KRB5KRB_ERR_RESPONSE_TOO_BIG,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &data);
+ send_reply(context, config, FALSE, d, &data);
+ krb5_data_free(&data);
+ } else {
+ do_request(context, config, buf, n, FALSE, d);
+ }
}
free (buf);
}
@@ -504,9 +512,9 @@ clear_descr(struct descr *d)
if(d->buf)
memset(d->buf, 0, d->size);
d->len = 0;
- if(d->s != -1)
- close(d->s);
- d->s = -1;
+ if(d->s != rk_INVALID_SOCKET)
+ rk_closesocket(d->s);
+ d->s = rk_INVALID_SOCKET;
}
@@ -536,32 +544,34 @@ de_http(char *buf)
*/
static void
-add_new_tcp (krb5_context context,
+add_new_tcp (krb5_context context,
krb5_kdc_configuration *config,
struct descr *d, int parent, int child)
{
- int s;
+ krb5_socket_t s;
if (child == -1)
return;
d[child].sock_len = sizeof(d[child].__ss);
s = accept(d[parent].s, d[child].sa, &d[child].sock_len);
- if(s < 0) {
- krb5_warn(context, errno, "accept");
+ if(rk_IS_BAD_SOCKET(s)) {
+ krb5_warn(context, rk_SOCK_ERRNO, "accept");
return;
}
-
+
+#ifdef FD_SETSIZE
if (s >= FD_SETSIZE) {
krb5_warnx(context, "socket FD too large");
- close (s);
+ rk_closesocket (s);
return;
}
+#endif
d[child].s = s;
d[child].timeout = time(NULL) + TCP_TIMEOUT;
d[child].type = SOCK_STREAM;
- addr_to_string (context,
+ addr_to_string (context,
d[child].sa, d[child].sock_len,
d[child].addr_string, sizeof(d[child].addr_string));
}
@@ -572,16 +582,16 @@ add_new_tcp (krb5_context context,
*/
static int
-grow_descr (krb5_context context,
+grow_descr (krb5_context context,
krb5_kdc_configuration *config,
struct descr *d, size_t n)
{
if (d->size - d->len < n) {
unsigned char *tmp;
- size_t grow;
+ size_t grow;
grow = max(1024, d->len + n);
- if (d->size + grow > max_request) {
+ if (d->size + grow > max_request_tcp) {
kdc_log(context, config, 0, "Request exceeds max request size (%lu bytes).",
(unsigned long)d->size + grow);
clear_descr(d);
@@ -606,7 +616,7 @@ grow_descr (krb5_context context,
*/
static int
-handle_vanilla_tcp (krb5_context context,
+handle_vanilla_tcp (krb5_context context,
krb5_kdc_configuration *config,
struct descr *d)
{
@@ -634,7 +644,7 @@ handle_vanilla_tcp (krb5_context context,
*/
static int
-handle_http_tcp (krb5_context context,
+handle_http_tcp (krb5_context context,
krb5_kdc_configuration *config,
struct descr *d)
{
@@ -645,24 +655,26 @@ handle_http_tcp (krb5_context context,
s = (char *)d->buf;
+ /* If its a multi line query, truncate off the first line */
p = strstr(s, "\r\n");
- if (p == NULL) {
- kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string);
- return -1;
- }
- *p = 0;
+ if (p)
+ *p = 0;
p = NULL;
t = strtok_r(s, " \t", &p);
if (t == NULL) {
- kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string);
+ kdc_log(context, config, 0,
+ "Missing HTTP operand (GET) request from %s", d->addr_string);
return -1;
}
+
t = strtok_r(NULL, " \t", &p);
if(t == NULL) {
- kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string);
+ kdc_log(context, config, 0,
+ "Missing HTTP GET data in request from %s", d->addr_string);
return -1;
}
+
data = malloc(strlen(t));
if (data == NULL) {
kdc_log(context, config, 0, "Failed to allocate %lu bytes",
@@ -685,7 +697,7 @@ handle_http_tcp (krb5_context context,
}
len = base64_decode(t, data);
if(len <= 0){
- const char *msg =
+ const char *msg =
" 404 Not found\r\n"
"Server: Heimdal/" VERSION "\r\n"
"Cache-Control: no-cache\r\n"
@@ -699,37 +711,41 @@ handle_http_tcp (krb5_context context,
kdc_log(context, config, 0, "HTTP request from %s is non KDC request", d->addr_string);
kdc_log(context, config, 5, "HTTP request: %s", t);
free(data);
- if (write(d->s, proto, strlen(proto)) < 0) {
- kdc_log(context, config, 0, "HTTP write failed: %s: %s",
- d->addr_string, strerror(errno));
+ if (rk_IS_SOCKET_ERROR(send(d->s, proto, strlen(proto), 0))) {
+ kdc_log(context, config, 0, "HTTP write failed: %s: %s",
+ d->addr_string, strerror(rk_SOCK_ERRNO));
return -1;
}
- if (write(d->s, msg, strlen(msg)) < 0) {
- kdc_log(context, config, 0, "HTTP write failed: %s: %s",
- d->addr_string, strerror(errno));
+ if (rk_IS_SOCKET_ERROR(send(d->s, msg, strlen(msg), 0))) {
+ kdc_log(context, config, 0, "HTTP write failed: %s: %s",
+ d->addr_string, strerror(rk_SOCK_ERRNO));
return -1;
}
return -1;
}
{
- const char *msg =
+ const char *msg =
" 200 OK\r\n"
"Server: Heimdal/" VERSION "\r\n"
"Cache-Control: no-cache\r\n"
"Pragma: no-cache\r\n"
"Content-type: application/octet-stream\r\n"
"Content-transfer-encoding: binary\r\n\r\n";
- if (write(d->s, proto, strlen(proto)) < 0) {
- kdc_log(context, config, 0, "HTTP write failed: %s: %s",
- d->addr_string, strerror(errno));
+ if (rk_IS_SOCKET_ERROR(send(d->s, proto, strlen(proto), 0))) {
+ free(data);
+ kdc_log(context, config, 0, "HTTP write failed: %s: %s",
+ d->addr_string, strerror(rk_SOCK_ERRNO));
return -1;
}
- if (write(d->s, msg, strlen(msg)) < 0) {
- kdc_log(context, config, 0, "HTTP write failed: %s: %s",
- d->addr_string, strerror(errno));
+ if (rk_IS_SOCKET_ERROR(send(d->s, msg, strlen(msg), 0))) {
+ free(data);
+ kdc_log(context, config, 0, "HTTP write failed: %s: %s",
+ d->addr_string, strerror(rk_SOCK_ERRNO));
return -1;
}
}
+ if ((size_t)len > d->len)
+ len = d->len;
memcpy(d->buf, data, len);
d->len = len;
free(data);
@@ -741,7 +757,7 @@ handle_http_tcp (krb5_context context,
*/
static void
-handle_tcp(krb5_context context,
+handle_tcp(krb5_context context,
krb5_kdc_configuration *config,
struct descr *d, int idx, int min_free)
{
@@ -755,15 +771,15 @@ handle_tcp(krb5_context context,
}
n = recvfrom(d[idx].s, buf, sizeof(buf), 0, NULL, NULL);
- if(n < 0){
- krb5_warn(context, errno, "recvfrom failed from %s to %s/%d",
- d[idx].addr_string, descr_type(d + idx),
+ if(rk_IS_SOCKET_ERROR(n)){
+ krb5_warn(context, rk_SOCK_ERRNO, "recvfrom failed from %s to %s/%d",
+ d[idx].addr_string, descr_type(d + idx),
ntohs(d[idx].port));
return;
} else if (n == 0) {
krb5_warnx(context, "connection closed before end of data after %lu "
- "bytes from %s to %s/%d", (unsigned long)d[idx].len,
- d[idx].addr_string, descr_type(d + idx),
+ "bytes from %s to %s/%d", (unsigned long)d[idx].len,
+ d[idx].addr_string, descr_type(d + idx),
ntohs(d[idx].port));
clear_descr (d + idx);
return;
@@ -776,16 +792,20 @@ handle_tcp(krb5_context context,
ret = handle_vanilla_tcp (context, config, &d[idx]);
} else if(enable_http &&
d[idx].len >= 4 &&
- strncmp((char *)d[idx].buf, "GET ", 4) == 0 &&
+ strncmp((char *)d[idx].buf, "GET ", 4) == 0 &&
strncmp((char *)d[idx].buf + d[idx].len - 4,
"\r\n\r\n", 4) == 0) {
+
+ /* remove the trailing \r\n\r\n so the string is NUL terminated */
+ d[idx].buf[d[idx].len - 4] = '\0';
+
ret = handle_http_tcp (context, config, &d[idx]);
if (ret < 0)
clear_descr (d + idx);
} else if (d[idx].len > 4) {
- kdc_log (context, config,
+ kdc_log (context, config,
0, "TCP data of strange type from %s to %s/%d",
- d[idx].addr_string, descr_type(d + idx),
+ d[idx].addr_string, descr_type(d + idx),
ntohs(d[idx].port));
if (d[idx].buf[0] & 0x80) {
krb5_data reply;
@@ -812,18 +832,18 @@ handle_tcp(krb5_context context,
if (ret < 0)
return;
else if (ret == 1) {
- do_request(context, config,
+ do_request(context, config,
d[idx].buf, d[idx].len, TRUE, &d[idx]);
clear_descr(d + idx);
}
}
void
-loop(krb5_context context,
+loop(krb5_context context,
krb5_kdc_configuration *config)
{
struct descr *d;
- int ndescr;
+ unsigned int ndescr;
ndescr = init_sockets(context, config, &d);
if(ndescr <= 0)
@@ -834,25 +854,29 @@ loop(krb5_context context,
fd_set fds;
int min_free = -1;
int max_fd = 0;
- int i;
+ size_t i;
FD_ZERO(&fds);
for(i = 0; i < ndescr; i++) {
- if(d[i].s >= 0){
- if(d[i].type == SOCK_STREAM &&
+ if(!rk_IS_BAD_SOCKET(d[i].s)){
+ if(d[i].type == SOCK_STREAM &&
d[i].timeout && d[i].timeout < time(NULL)) {
- kdc_log(context, config, 1,
+ kdc_log(context, config, 1,
"TCP-connection from %s expired after %lu bytes",
d[i].addr_string, (unsigned long)d[i].len);
clear_descr(&d[i]);
continue;
}
+#ifndef NO_LIMIT_FD_SETSIZE
if(max_fd < d[i].s)
max_fd = d[i].s;
+#ifdef FD_SETSIZE
if (max_fd >= FD_SETSIZE)
krb5_errx(context, 1, "fd too large");
+#endif
+#endif
FD_SET(d[i].s, &fds);
- } else if(min_free < 0 || i < min_free)
+ } else if(min_free < 0 || i < (size_t)min_free)
min_free = i;
}
if(min_free == -1){
@@ -870,7 +894,7 @@ loop(krb5_context context,
ndescr += 4;
}
}
-
+
tmout.tv_sec = TCP_TIMEOUT;
tmout.tv_usec = 0;
switch(select(max_fd + 1, &fds, 0, 0, &tmout)){
@@ -878,11 +902,11 @@ loop(krb5_context context,
break;
case -1:
if (errno != EINTR)
- krb5_warn(context, errno, "select");
+ krb5_warn(context, rk_SOCK_ERRNO, "select");
break;
default:
for(i = 0; i < ndescr; i++)
- if(d[i].s >= 0 && FD_ISSET(d[i].s, &fds)) {
+ if(!rk_IS_BAD_SOCKET(d[i].s) && FD_ISSET(d[i].s, &fds)) {
if(d[i].type == SOCK_DGRAM)
handle_udp(context, config, &d[i]);
else if(d[i].type == SOCK_STREAM)
@@ -890,8 +914,11 @@ loop(krb5_context context,
}
}
}
- if(exit_flag == SIGXCPU)
+ if (0);
+#ifdef SIGXCPU
+ else if(exit_flag == SIGXCPU)
kdc_log(context, config, 0, "CPU time limit exceeded");
+#endif
else if(exit_flag == SIGINT || exit_flag == SIGTERM)
kdc_log(context, config, 0, "Terminated");
else
diff --git a/crypto/heimdal/kdc/default_config.c b/crypto/heimdal/kdc/default_config.c
index 5f336e3..6fbf5fd 100644
--- a/crypto/heimdal/kdc/default_config.c
+++ b/crypto/heimdal/kdc/default_config.c
@@ -1,43 +1,42 @@
/*
- * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
*
- * All rights reserved.
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
#include <getarg.h>
#include <parse_bytes.h>
-RCSID("$Id: default_config.c 21405 2007-07-04 10:35:45Z lha $");
-
krb5_error_code
krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
{
@@ -45,21 +44,21 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c = calloc(1, sizeof(*c));
if (c == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
c->require_preauth = TRUE;
c->kdc_warn_pwexpire = 0;
c->encode_as_rep_as_tgs_rep = FALSE;
+ c->as_use_strongest_session_key = FALSE;
+ c->preauth_use_strongest_session_key = FALSE;
+ c->tgs_use_strongest_session_key = FALSE;
+ c->use_strongest_server_key = TRUE;
c->check_ticket_addresses = TRUE;
c->allow_null_ticket_addresses = TRUE;
c->allow_anonymous = FALSE;
c->trpolicy = TRPOLICY_ALWAYS_CHECK;
- c->enable_v4 = FALSE;
- c->enable_kaserver = FALSE;
- c->enable_524 = FALSE;
- c->enable_v4_cross_realm = FALSE;
c->enable_pkinit = FALSE;
c->pkinit_princ_in_cert = TRUE;
c->pkinit_require_binding = TRUE;
@@ -68,32 +67,20 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->logf = NULL;
c->require_preauth =
- krb5_config_get_bool_default(context, NULL,
+ krb5_config_get_bool_default(context, NULL,
c->require_preauth,
"kdc", "require-preauth", NULL);
- c->enable_v4 =
- krb5_config_get_bool_default(context, NULL,
- c->enable_v4,
- "kdc", "enable-kerberos4", NULL);
- c->enable_v4_cross_realm =
+#ifdef DIGEST
+ c->enable_digest =
krb5_config_get_bool_default(context, NULL,
- c->enable_v4_cross_realm,
- "kdc",
- "enable-kerberos4-cross-realm", NULL);
- c->enable_524 =
- krb5_config_get_bool_default(context, NULL,
- c->enable_v4,
- "kdc", "enable-524", NULL);
- c->enable_digest =
- krb5_config_get_bool_default(context, NULL,
FALSE,
"kdc", "enable-digest", NULL);
{
const char *digests;
- digests = krb5_config_get_string(context, NULL,
- "kdc",
+ digests = krb5_config_get_string(context, NULL,
+ "kdc",
"digests_allowed", NULL);
if (digests == NULL)
digests = "ntlm-v2";
@@ -110,18 +97,20 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->enable_digest = 0;
}
}
+#endif
- c->enable_kx509 =
- krb5_config_get_bool_default(context, NULL,
- FALSE,
+#ifdef KX509
+ c->enable_kx509 =
+ krb5_config_get_bool_default(context, NULL,
+ FALSE,
"kdc", "enable-kx509", NULL);
if (c->enable_kx509) {
c->kx509_template =
- krb5_config_get_string(context, NULL,
+ krb5_config_get_string(context, NULL,
"kdc", "kx509_template", NULL);
c->kx509_ca =
- krb5_config_get_string(context, NULL,
+ krb5_config_get_string(context, NULL,
"kdc", "kx509_ca", NULL);
if (c->kx509_ca == NULL || c->kx509_template == NULL) {
kdc_log(context, c, 0,
@@ -129,27 +118,49 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->enable_kx509 = FALSE;
}
}
+#endif
+
+ c->as_use_strongest_session_key =
+ krb5_config_get_bool_default(context, NULL,
+ c->as_use_strongest_session_key,
+ "kdc",
+ "as-use-strongest-session-key", NULL);
+ c->preauth_use_strongest_session_key =
+ krb5_config_get_bool_default(context, NULL,
+ c->preauth_use_strongest_session_key,
+ "kdc",
+ "preauth-use-strongest-session-key", NULL);
+ c->tgs_use_strongest_session_key =
+ krb5_config_get_bool_default(context, NULL,
+ c->tgs_use_strongest_session_key,
+ "kdc",
+ "tgs-use-strongest-session-key", NULL);
+ c->use_strongest_server_key =
+ krb5_config_get_bool_default(context, NULL,
+ c->use_strongest_server_key,
+ "kdc",
+ "use-strongest-server-key", NULL);
- c->check_ticket_addresses =
- krb5_config_get_bool_default(context, NULL,
- c->check_ticket_addresses,
- "kdc",
+ c->check_ticket_addresses =
+ krb5_config_get_bool_default(context, NULL,
+ c->check_ticket_addresses,
+ "kdc",
"check-ticket-addresses", NULL);
- c->allow_null_ticket_addresses =
- krb5_config_get_bool_default(context, NULL,
- c->allow_null_ticket_addresses,
- "kdc",
+ c->allow_null_ticket_addresses =
+ krb5_config_get_bool_default(context, NULL,
+ c->allow_null_ticket_addresses,
+ "kdc",
"allow-null-ticket-addresses", NULL);
- c->allow_anonymous =
- krb5_config_get_bool_default(context, NULL,
+ c->allow_anonymous =
+ krb5_config_get_bool_default(context, NULL,
c->allow_anonymous,
- "kdc",
+ "kdc",
"allow-anonymous", NULL);
c->max_datagram_reply_length =
- krb5_config_get_int_default(context,
- NULL,
+ krb5_config_get_int_default(context,
+ NULL,
1400,
"kdc",
"max-kdc-datagram-reply-length",
@@ -158,8 +169,8 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
{
const char *trpolicy_str;
- trpolicy_str =
- krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc",
+ trpolicy_str =
+ krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc",
"transited-policy", NULL);
if(strcasecmp(trpolicy_str, "always-check") == 0) {
c->trpolicy = TRPOLICY_ALWAYS_CHECK;
@@ -167,119 +178,110 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
} else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) {
c->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
- } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) {
+ } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) {
/* default */
} else {
kdc_log(context, c, 0,
"unknown transited-policy: %s, "
- "reverting to default (always-check)",
+ "reverting to default (always-check)",
trpolicy_str);
}
}
- {
- const char *p;
- p = krb5_config_get_string (context, NULL,
- "kdc",
- "v4-realm",
- NULL);
- if(p != NULL) {
- c->v4_realm = strdup(p);
- if (c->v4_realm == NULL)
- krb5_errx(context, 1, "out of memory");
- } else {
- c->v4_realm = NULL;
- }
- }
-
- c->enable_kaserver =
- krb5_config_get_bool_default(context,
- NULL,
- c->enable_kaserver,
- "kdc", "enable-kaserver", NULL);
-
-
c->encode_as_rep_as_tgs_rep =
- krb5_config_get_bool_default(context, NULL,
- c->encode_as_rep_as_tgs_rep,
- "kdc",
+ krb5_config_get_bool_default(context, NULL,
+ c->encode_as_rep_as_tgs_rep,
+ "kdc",
"encode_as_rep_as_tgs_rep", NULL);
-
+
c->kdc_warn_pwexpire =
krb5_config_get_time_default (context, NULL,
c->kdc_warn_pwexpire,
"kdc", "kdc_warn_pwexpire", NULL);
-#ifdef PKINIT
- c->enable_pkinit =
- krb5_config_get_bool_default(context,
- NULL,
+ c->enable_pkinit =
+ krb5_config_get_bool_default(context,
+ NULL,
c->enable_pkinit,
"kdc",
"enable-pkinit",
NULL);
- if (c->enable_pkinit) {
- const char *user_id, *anchors, *ocsp_file;
- char **pool_list, **revoke_list;
- user_id =
- krb5_config_get_string(context, NULL,
- "kdc", "pkinit_identity", NULL);
- if (user_id == NULL)
- krb5_errx(context, 1, "pkinit enabled but no identity");
- anchors = krb5_config_get_string(context, NULL,
- "kdc", "pkinit_anchors", NULL);
- if (anchors == NULL)
- krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
-
- pool_list =
- krb5_config_get_strings(context, NULL,
- "kdc", "pkinit_pool", NULL);
-
- revoke_list =
- krb5_config_get_strings(context, NULL,
- "kdc", "pkinit_revoke", NULL);
+ c->pkinit_kdc_identity =
+ krb5_config_get_string(context, NULL,
+ "kdc", "pkinit_identity", NULL);
+ c->pkinit_kdc_anchors =
+ krb5_config_get_string(context, NULL,
+ "kdc", "pkinit_anchors", NULL);
+ c->pkinit_kdc_cert_pool =
+ krb5_config_get_strings(context, NULL,
+ "kdc", "pkinit_pool", NULL);
+ c->pkinit_kdc_revoke =
+ krb5_config_get_strings(context, NULL,
+ "kdc", "pkinit_revoke", NULL);
+ c->pkinit_kdc_ocsp_file =
+ krb5_config_get_string(context, NULL,
+ "kdc", "pkinit_kdc_ocsp", NULL);
+ c->pkinit_kdc_friendly_name =
+ krb5_config_get_string(context, NULL,
+ "kdc", "pkinit_kdc_friendly_name", NULL);
+ c->pkinit_princ_in_cert =
+ krb5_config_get_bool_default(context, NULL,
+ c->pkinit_princ_in_cert,
+ "kdc",
+ "pkinit_principal_in_certificate",
+ NULL);
+ c->pkinit_require_binding =
+ krb5_config_get_bool_default(context, NULL,
+ c->pkinit_require_binding,
+ "kdc",
+ "pkinit_win2k_require_binding",
+ NULL);
+ c->pkinit_dh_min_bits =
+ krb5_config_get_int_default(context, NULL,
+ 0,
+ "kdc", "pkinit_dh_min_bits", NULL);
- ocsp_file =
- krb5_config_get_string(context, NULL,
- "kdc", "pkinit_kdc_ocsp", NULL);
- if (ocsp_file) {
- c->pkinit_kdc_ocsp_file = strdup(ocsp_file);
- if (c->pkinit_kdc_ocsp_file == NULL)
- krb5_errx(context, 1, "out of memory");
- }
+ *config = c;
- _kdc_pk_initialize(context, c, user_id, anchors,
- pool_list, revoke_list);
+ return 0;
+}
- krb5_config_free_strings(pool_list);
- krb5_config_free_strings(revoke_list);
+krb5_error_code
+krb5_kdc_pkinit_config(krb5_context context, krb5_kdc_configuration *config)
+{
+#ifdef PKINIT
+#ifdef __APPLE__
+ config->enable_pkinit = 1;
+
+ if (config->pkinit_kdc_identity == NULL) {
+ if (config->pkinit_kdc_friendly_name == NULL)
+ config->pkinit_kdc_friendly_name =
+ strdup("O=System Identity,CN=com.apple.kerberos.kdc");
+ config->pkinit_kdc_identity = strdup("KEYCHAIN:");
+ }
+ if (config->pkinit_kdc_anchors == NULL)
+ config->pkinit_kdc_anchors = strdup("KEYCHAIN:");
- c->pkinit_princ_in_cert =
- krb5_config_get_bool_default(context, NULL,
- c->pkinit_princ_in_cert,
- "kdc",
- "pkinit_principal_in_certificate",
- NULL);
+#endif /* __APPLE__ */
- c->pkinit_require_binding =
- krb5_config_get_bool_default(context, NULL,
- c->pkinit_require_binding,
- "kdc",
- "pkinit_win2k_require_binding",
- NULL);
- }
+ if (config->enable_pkinit) {
+ if (config->pkinit_kdc_identity == NULL)
+ krb5_errx(context, 1, "pkinit enabled but no identity");
- c->pkinit_dh_min_bits =
- krb5_config_get_int_default(context, NULL,
- 0,
- "kdc", "pkinit_dh_min_bits", NULL);
+ if (config->pkinit_kdc_anchors == NULL)
+ krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
-#endif
+ krb5_kdc_pk_initialize(context, config,
+ config->pkinit_kdc_identity,
+ config->pkinit_kdc_anchors,
+ config->pkinit_kdc_cert_pool,
+ config->pkinit_kdc_revoke);
- *config = c;
+ }
return 0;
+#endif /* PKINIT */
}
diff --git a/crypto/heimdal/kdc/digest-service.c b/crypto/heimdal/kdc/digest-service.c
new file mode 100644
index 0000000..4d339a2
--- /dev/null
+++ b/crypto/heimdal/kdc/digest-service.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. 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.
+ */
+
+#define HC_DEPRECATED_CRYPTO
+
+#include "headers.h"
+#include <digest_asn1.h>
+#include <heimntlm.h>
+#include <heim-ipc.h>
+#include <getarg.h>
+
+typedef struct pk_client_params pk_client_params;
+struct DigestREQ;
+struct Kx509Request;
+#include <kdc-private.h>
+
+krb5_kdc_configuration *config;
+
+static void
+ntlm_service(void *ctx, const heim_idata *req,
+ const heim_icred cred,
+ heim_ipc_complete complete,
+ heim_sipc_call cctx)
+{
+ NTLMRequest2 ntq;
+ unsigned char sessionkey[16];
+ heim_idata rep = { 0, NULL };
+ krb5_context context = ctx;
+ hdb_entry_ex *user = NULL;
+ Key *key = NULL;
+ NTLMReply ntp;
+ size_t size;
+ int ret;
+ const char *domain;
+
+ kdc_log(context, config, 1, "digest-request: uid=%d",
+ (int)heim_ipc_cred_get_uid(cred));
+
+ if (heim_ipc_cred_get_uid(cred) != 0) {
+ (*complete)(cctx, EPERM, NULL);
+ return;
+ }
+
+ ntp.success = 0;
+ ntp.flags = 0;
+ ntp.sessionkey = NULL;
+
+ ret = decode_NTLMRequest2(req->data, req->length, &ntq, NULL);
+ if (ret)
+ goto failed;
+
+ /* XXX forward to NetrLogonSamLogonEx() if not a local domain */
+ if (strcmp(ntq.loginDomainName, "BUILTIN") == 0) {
+ domain = ntq.loginDomainName;
+ } else if (strcmp(ntq.loginDomainName, "") == 0) {
+ domain = "BUILTIN";
+ } else {
+ ret = EINVAL;
+ goto failed;
+ }
+
+ kdc_log(context, config, 1, "digest-request: user=%s/%s",
+ ntq.loginUserName, domain);
+
+ if (ntq.lmchallenge.length != 8)
+ goto failed;
+
+ if (ntq.ntChallengeResponce.length == 0)
+ goto failed;
+
+ {
+ krb5_principal client;
+
+ ret = krb5_make_principal(context, &client, domain,
+ ntq.loginUserName, NULL);
+ if (ret)
+ goto failed;
+
+ krb5_principal_set_type(context, client, KRB5_NT_NTLM);
+
+ ret = _kdc_db_fetch(context, config, client,
+ HDB_F_GET_CLIENT, NULL, NULL, &user);
+ krb5_free_principal(context, client);
+ if (ret)
+ goto failed;
+
+ ret = hdb_enctype2key(context, &user->entry,
+ ETYPE_ARCFOUR_HMAC_MD5, &key);
+ if (ret) {
+ krb5_set_error_message(context, ret, "NTLM missing arcfour key");
+ goto failed;
+ }
+ }
+
+ kdc_log(context, config, 2,
+ "digest-request: found user, processing ntlm request", ret);
+
+ if (ntq.ntChallengeResponce.length != 24) {
+ struct ntlm_buf infotarget, answer;
+
+ answer.length = ntq.ntChallengeResponce.length;
+ answer.data = ntq.ntChallengeResponce.data;
+
+ ret = heim_ntlm_verify_ntlm2(key->key.keyvalue.data,
+ key->key.keyvalue.length,
+ ntq.loginUserName,
+ ntq.loginDomainName,
+ 0,
+ ntq.lmchallenge.data,
+ &answer,
+ &infotarget,
+ sessionkey);
+ if (ret) {
+ goto failed;
+ }
+
+ free(infotarget.data);
+ /* XXX verify info target */
+
+ } else {
+ struct ntlm_buf answer;
+
+ if (ntq.flags & NTLM_NEG_NTLM2_SESSION) {
+ unsigned char sessionhash[MD5_DIGEST_LENGTH];
+ EVP_MD_CTX *md5ctx;
+
+ /* the first first 8 bytes is the challenge, what is the other 16 bytes ? */
+ if (ntq.lmChallengeResponce.length != 24)
+ goto failed;
+
+ md5ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5ctx, ntq.lmchallenge.data, 8);
+ EVP_DigestUpdate(md5ctx, ntq.lmChallengeResponce.data, 8);
+ EVP_DigestFinal_ex(md5ctx, sessionhash, NULL);
+ EVP_MD_CTX_destroy(md5ctx);
+ memcpy(ntq.lmchallenge.data, sessionhash, ntq.lmchallenge.length);
+ }
+
+ ret = heim_ntlm_calculate_ntlm1(key->key.keyvalue.data,
+ key->key.keyvalue.length,
+ ntq.lmchallenge.data, &answer);
+ if (ret)
+ goto failed;
+
+ if (ntq.ntChallengeResponce.length != answer.length ||
+ memcmp(ntq.ntChallengeResponce.data, answer.data, answer.length) != 0) {
+ free(answer.data);
+ ret = EINVAL;
+ goto failed;
+ }
+ free(answer.data);
+
+ {
+ EVP_MD_CTX *ctxp;
+
+ ctxp = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctxp, EVP_md4(), NULL);
+ EVP_DigestUpdate(ctxp, key->key.keyvalue.data, key->key.keyvalue.length);
+ EVP_DigestFinal_ex(ctxp, sessionkey, NULL);
+ EVP_MD_CTX_destroy(ctxp);
+ }
+ }
+
+ ntp.success = 1;
+
+ ASN1_MALLOC_ENCODE(NTLMReply, rep.data, rep.length, &ntp, &size, ret);
+ if (ret)
+ goto failed;
+ if (rep.length != size)
+ abort();
+
+ failed:
+ kdc_log(context, config, 1, "digest-request: %d", ret);
+
+ (*complete)(cctx, ret, &rep);
+
+ free(rep.data);
+
+ free_NTLMRequest2(&ntq);
+ if (user)
+ _kdc_free_ent (context, user);
+}
+
+static int help_flag;
+static int version_flag;
+
+static struct getargs args[] = {
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL },
+ { "version", 'v', arg_flag, &version_flag, NULL, NULL }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ int ret, optidx = 0;
+
+ setprogname(argv[0]);
+
+ if (getarg(args, num_args, argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage(0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ krb5_errx(context, 1, "krb5_init_context");
+
+ ret = krb5_kdc_get_config(context, &config);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_kdc_default_config");
+
+ kdc_openlog(context, "digest-service", config);
+
+ ret = krb5_kdc_set_dbinfo(context, config);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo");
+
+#if __APPLE__
+ {
+ heim_sipc mach;
+ heim_sipc_launchd_mach_init("org.h5l.ntlm-service",
+ ntlm_service, context, &mach);
+ heim_sipc_timeout(60);
+ }
+#endif
+ {
+ heim_sipc un;
+ heim_sipc_service_unix("org.h5l.ntlm-service", ntlm_service, NULL, &un);
+ }
+
+ heim_ipc_main();
+ return 0;
+}
diff --git a/crypto/heimdal/kdc/digest.c b/crypto/heimdal/kdc/digest.c
index b845b0f..5f0d274 100644
--- a/crypto/heimdal/kdc/digest.c
+++ b/crypto/heimdal/kdc/digest.c
@@ -1,40 +1,40 @@
/*
- * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2006 - 2007 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
#include <hex.h>
-RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $");
+#ifdef DIGEST
#define MS_CHAP_V2 0x20
#define CHAP_MD5 0x10
@@ -44,13 +44,13 @@ RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $");
#define NTLM_V1 0x01
const struct units _kdc_digestunits[] = {
- {"ms-chap-v2", 1U << 5},
- {"chap-md5", 1U << 4},
- {"digest-md5", 1U << 3},
- {"ntlm-v2", 1U << 2},
- {"ntlm-v1-session", 1U << 1},
- {"ntlm-v1", 1U << 0},
- {NULL, 0}
+ {"ms-chap-v2", 1U << 5},
+ {"chap-md5", 1U << 4},
+ {"digest-md5", 1U << 3},
+ {"ntlm-v2", 1U << 2},
+ {"ntlm-v1-session", 1U << 1},
+ {"ntlm-v1", 1U << 0},
+ {NULL, 0}
};
@@ -63,7 +63,7 @@ get_digest_key(krb5_context context,
krb5_error_code ret;
krb5_enctype enctype;
Key *key;
-
+
ret = _kdc_get_preferred_key(context,
config,
server,
@@ -115,17 +115,17 @@ fill_targetinfo(krb5_context context,
ti.domainname = targetname;
p = client->entry.principal;
str = krb5_principal_get_comp_string(context, p, 0);
- if (str != NULL &&
- (strcmp("host", str) == 0 ||
+ if (str != NULL &&
+ (strcmp("host", str) == 0 ||
strcmp("ftp", str) == 0 ||
strcmp("imap", str) == 0 ||
strcmp("pop", str) == 0 ||
strcmp("smtp", str)))
- {
- str = krb5_principal_get_comp_string(context, p, 1);
- ti.dnsservername = rk_UNCONST(str);
- }
-
+ {
+ str = krb5_principal_get_comp_string(context, p, 1);
+ ti.dnsservername = rk_UNCONST(str);
+ }
+
ret = heim_ntlm_encode_targetinfo(&ti, 1, &d);
if (ret)
return ret;
@@ -177,7 +177,7 @@ get_password_entry(krb5_context context,
return ret;
ret = _kdc_db_fetch(context, config, clientprincipal,
- HDB_F_GET_CLIENT, &db, &user);
+ HDB_F_GET_CLIENT, NULL, &db, &user);
krb5_free_principal(context, clientprincipal);
if (ret)
return ret;
@@ -186,7 +186,7 @@ get_password_entry(krb5_context context,
if (ret || password == NULL) {
if (ret == 0) {
ret = EINVAL;
- krb5_set_error_string(context, "password missing");
+ krb5_set_error_message(context, ret, "password missing");
}
memset(user, 0, sizeof(*user));
}
@@ -199,9 +199,9 @@ get_password_entry(krb5_context context,
*/
krb5_error_code
-_kdc_do_digest(krb5_context context,
+_kdc_do_digest(krb5_context context,
krb5_kdc_configuration *config,
- const DigestREQ *req, krb5_data *reply,
+ const struct DigestREQ *req, krb5_data *reply,
const char *from, struct sockaddr *addr)
{
krb5_error_code ret = 0;
@@ -223,7 +223,7 @@ _kdc_do_digest(krb5_context context,
krb5_data serverNonce;
if(!config->enable_digest) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Rejected digest request (disabled) from %s", from);
return KRB5KDC_ERR_POLICY;
}
@@ -234,6 +234,7 @@ _kdc_do_digest(krb5_context context,
memset(&ireq, 0, sizeof(ireq));
memset(&r, 0, sizeof(r));
memset(&rep, 0, sizeof(rep));
+ memset(&res, 0, sizeof(res));
kdc_log(context, config, 0, "Digest request from %s", from);
@@ -243,7 +244,7 @@ _kdc_do_digest(krb5_context context,
goto out;
}
- ret = krb5_rd_req(context,
+ ret = krb5_rd_req(context,
&ac,
&req->apReq,
NULL,
@@ -256,14 +257,14 @@ _kdc_do_digest(krb5_context context,
/* check the server principal in the ticket matches digest/R@R */
{
krb5_principal principal = NULL;
- const char *p, *r;
+ const char *p, *rr;
ret = krb5_ticket_get_server(context, ticket, &principal);
if (ret)
goto out;
ret = EINVAL;
- krb5_set_error_string(context, "Wrong digest server principal used");
+ krb5_set_error_message(context, ret, "Wrong digest server principal used");
p = krb5_principal_get_comp_string(context, principal, 0);
if (p == NULL) {
krb5_free_principal(context, principal);
@@ -279,19 +280,19 @@ _kdc_do_digest(krb5_context context,
krb5_free_principal(context, principal);
goto out;
}
- r = krb5_principal_get_realm(context, principal);
- if (r == NULL) {
+ rr = krb5_principal_get_realm(context, principal);
+ if (rr == NULL) {
krb5_free_principal(context, principal);
goto out;
}
- if (strcmp(p, r) != 0) {
+ if (strcmp(p, rr) != 0) {
krb5_free_principal(context, principal);
goto out;
}
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = _kdc_db_fetch(context, config, principal,
- HDB_F_GET_SERVER, NULL, &server);
+ HDB_F_GET_SERVER, NULL, NULL, &server);
if (ret)
goto out;
@@ -313,19 +314,19 @@ _kdc_do_digest(krb5_context context,
}
ret = _kdc_db_fetch(context, config, principal,
- HDB_F_GET_CLIENT, NULL, &client);
+ HDB_F_GET_CLIENT, NULL, NULL, &client);
krb5_free_principal(context, principal);
if (ret)
goto out;
if (client->entry.flags.allow_digest == 0) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Client %s tried to use digest "
- "but is not allowed to",
+ "but is not allowed to",
client_name);
- krb5_set_error_string(context,
- "Client is not permitted to use digest");
ret = KRB5KDC_ERR_POLICY;
+ krb5_set_error_message(context, ret,
+ "Client is not permitted to use digest");
goto out;
}
}
@@ -338,8 +339,8 @@ _kdc_do_digest(krb5_context context,
if (ret)
goto out;
if (key == NULL) {
- krb5_set_error_string(context, "digest: remote subkey not found");
ret = EINVAL;
+ krb5_set_error_message(context, ret, "digest: remote subkey not found");
goto out;
}
@@ -355,15 +356,15 @@ _kdc_do_digest(krb5_context context,
crypto = NULL;
if (ret)
goto out;
-
+
ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL);
krb5_data_free(&buf);
if (ret) {
- krb5_set_error_string(context, "Failed to decode digest inner request");
+ krb5_set_error_message(context, ret, "Failed to decode digest inner request");
goto out;
}
- kdc_log(context, config, 0, "Valid digest request from %s (%s)",
+ kdc_log(context, config, 0, "Valid digest request from %s (%s)",
client_name, from);
/*
@@ -386,20 +387,20 @@ _kdc_do_digest(krb5_context context,
hex_encode(server_nonce, sizeof(server_nonce), &r.u.initReply.nonce);
if (r.u.initReply.nonce == NULL) {
- krb5_set_error_string(context, "Failed to decode server nonce");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "Failed to decode server nonce");
goto out;
}
sp = krb5_storage_emem();
if (sp == NULL) {
ret = ENOMEM;
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
ret = krb5_store_stringz(sp, ireq.u.init.type);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
@@ -410,34 +411,34 @@ _kdc_do_digest(krb5_context context,
ireq.u.init.channel->cb_type,
ireq.u.init.channel->cb_binding);
if (s == NULL) {
- krb5_set_error_string(context, "Failed to allocate "
- "channel binding");
ret = ENOMEM;
+ krb5_set_error_message(context, ret,
+ "Failed to allocate channel binding");
goto out;
}
free(r.u.initReply.nonce);
r.u.initReply.nonce = s;
}
-
+
ret = krb5_store_stringz(sp, r.u.initReply.nonce);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
if (strcasecmp(ireq.u.init.type, "CHAP") == 0) {
- r.u.initReply.identifier =
+ r.u.initReply.identifier =
malloc(sizeof(*r.u.initReply.identifier));
if (r.u.initReply.identifier == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
asprintf(r.u.initReply.identifier, "%02X", identifier & 0xff);
if (*r.u.initReply.identifier == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
@@ -447,14 +448,14 @@ _kdc_do_digest(krb5_context context,
if (ireq.u.init.hostname) {
ret = krb5_store_stringz(sp, *ireq.u.init.hostname);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
}
ret = krb5_storage_to_data(sp, &buf);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
@@ -474,12 +475,12 @@ _kdc_do_digest(krb5_context context,
krb5_data_free(&buf);
if (ret)
goto out;
-
+
ASN1_MALLOC_ENCODE(Checksum, buf.data, buf.length, &res, &size, ret);
free_Checksum(&res);
if (ret) {
- krb5_set_error_string(context, "Failed to encode "
- "checksum in digest request");
+ krb5_set_error_message(context, ret, "Failed to encode "
+ "checksum in digest request");
goto out;
}
if (size != buf.length)
@@ -487,8 +488,9 @@ _kdc_do_digest(krb5_context context,
hex_encode(buf.data, buf.length, &r.u.initReply.opaque);
free(buf.data);
+ krb5_data_zero(&buf);
if (r.u.initReply.opaque == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = ENOMEM;
goto out;
}
@@ -502,12 +504,12 @@ _kdc_do_digest(krb5_context context,
sp = krb5_storage_emem();
if (sp == NULL) {
ret = ENOMEM;
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
ret = krb5_store_stringz(sp, ireq.u.digestRequest.type);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
@@ -516,7 +518,7 @@ _kdc_do_digest(krb5_context context,
if (ireq.u.digestRequest.hostname) {
ret = krb5_store_stringz(sp, *ireq.u.digestRequest.hostname);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
}
@@ -524,52 +526,54 @@ _kdc_do_digest(krb5_context context,
buf.length = strlen(ireq.u.digestRequest.opaque);
buf.data = malloc(buf.length);
if (buf.data == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
ret = hex_decode(ireq.u.digestRequest.opaque, buf.data, buf.length);
if (ret <= 0) {
- krb5_set_error_string(context, "Failed to decode opaque");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "Failed to decode opaque");
goto out;
}
buf.length = ret;
ret = decode_Checksum(buf.data, buf.length, &res, NULL);
free(buf.data);
+ krb5_data_zero(&buf);
if (ret) {
- krb5_set_error_string(context, "Failed to decode digest Checksum");
+ krb5_set_error_message(context, ret,
+ "Failed to decode digest Checksum");
goto out;
}
-
+
ret = krb5_storage_to_data(sp, &buf);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
serverNonce.length = strlen(ireq.u.digestRequest.serverNonce);
serverNonce.data = malloc(serverNonce.length);
if (serverNonce.data == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
-
+
/*
* CHAP does the checksum of the raw nonce, but do it for all
* types, since we need to check the timestamp.
*/
{
ssize_t ssize;
-
- ssize = hex_decode(ireq.u.digestRequest.serverNonce,
+
+ ssize = hex_decode(ireq.u.digestRequest.serverNonce,
serverNonce.data, serverNonce.length);
if (ssize <= 0) {
- krb5_set_error_string(context, "Failed to decode serverNonce");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "Failed to decode serverNonce");
goto out;
}
serverNonce.length = ssize;
@@ -579,9 +583,11 @@ _kdc_do_digest(krb5_context context,
if (ret)
goto out;
- ret = krb5_verify_checksum(context, crypto,
+ ret = krb5_verify_checksum(context, crypto,
KRB5_KU_DIGEST_OPAQUE,
buf.data, buf.length, &res);
+ free_Checksum(&res);
+ krb5_data_free(&buf);
krb5_crypto_destroy(context, crypto);
crypto = NULL;
if (ret)
@@ -591,26 +597,26 @@ _kdc_do_digest(krb5_context context,
{
unsigned char *p = serverNonce.data;
uint32_t t;
-
+
if (serverNonce.length < 4) {
- krb5_set_error_string(context, "server nonce too short");
ret = EINVAL;
+ krb5_set_error_message(context, ret, "server nonce too short");
goto out;
}
t = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
if (abs((kdc_time & 0xffffffff) - t) > context->max_skew) {
- krb5_set_error_string(context, "time screw in server nonce ");
ret = EINVAL;
+ krb5_set_error_message(context, ret, "time screw in server nonce ");
goto out;
}
}
if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
- MD5_CTX ctx;
+ EVP_MD_CTX *ctx;
unsigned char md[MD5_DIGEST_LENGTH];
char *mdx;
- char id;
+ char idx;
if ((config->digests_allowed & CHAP_MD5) == 0) {
kdc_log(context, config, 0, "Digest CHAP MD5 not allowed");
@@ -618,33 +624,37 @@ _kdc_do_digest(krb5_context context,
}
if (ireq.u.digestRequest.identifier == NULL) {
- krb5_set_error_string(context, "Identifier missing "
- "from CHAP request");
ret = EINVAL;
+ krb5_set_error_message(context, ret, "Identifier missing "
+ "from CHAP request");
goto out;
}
-
- if (hex_decode(*ireq.u.digestRequest.identifier, &id, 1) != 1) {
- krb5_set_error_string(context, "failed to decode identifier");
+
+ if (hex_decode(*ireq.u.digestRequest.identifier, &idx, 1) != 1) {
ret = EINVAL;
+ krb5_set_error_message(context, ret, "failed to decode identifier");
goto out;
}
-
- ret = get_password_entry(context, config,
+
+ ret = get_password_entry(context, config,
ireq.u.digestRequest.username,
&password);
if (ret)
goto out;
- MD5_Init(&ctx);
- MD5_Update(&ctx, &id, 1);
- MD5_Update(&ctx, password, strlen(password));
- MD5_Update(&ctx, serverNonce.data, serverNonce.length);
- MD5_Final(md, &ctx);
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, &idx, 1);
+ EVP_DigestUpdate(ctx, password, strlen(password));
+ EVP_DigestUpdate(ctx, serverNonce.data, serverNonce.length);
+ EVP_DigestFinal_ex(ctx, md, NULL);
+
+ EVP_MD_CTX_destroy(ctx);
hex_encode(md, sizeof(md), &mdx);
if (mdx == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = ENOMEM;
goto out;
}
@@ -656,14 +666,14 @@ _kdc_do_digest(krb5_context context,
if (ret == 0) {
r.u.response.success = TRUE;
} else {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"CHAP reply mismatch for %s",
ireq.u.digestRequest.username);
r.u.response.success = FALSE;
}
} else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) {
- MD5_CTX ctx;
+ EVP_MD_CTX *ctx;
unsigned char md[MD5_DIGEST_LENGTH];
char *mdx;
char *A1, *A2;
@@ -673,97 +683,104 @@ _kdc_do_digest(krb5_context context,
goto out;
}
- if (ireq.u.digestRequest.nonceCount == NULL)
+ if (ireq.u.digestRequest.nonceCount == NULL)
goto out;
- if (ireq.u.digestRequest.clientNonce == NULL)
+ if (ireq.u.digestRequest.clientNonce == NULL)
goto out;
- if (ireq.u.digestRequest.qop == NULL)
+ if (ireq.u.digestRequest.qop == NULL)
goto out;
- if (ireq.u.digestRequest.realm == NULL)
+ if (ireq.u.digestRequest.realm == NULL)
goto out;
-
- ret = get_password_entry(context, config,
+
+ ret = get_password_entry(context, config,
ireq.u.digestRequest.username,
&password);
if (ret)
goto failed;
- MD5_Init(&ctx);
- MD5_Update(&ctx, ireq.u.digestRequest.username,
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, ireq.u.digestRequest.username,
strlen(ireq.u.digestRequest.username));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.realm,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.realm,
strlen(*ireq.u.digestRequest.realm));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, password, strlen(password));
- MD5_Final(md, &ctx);
-
- MD5_Init(&ctx);
- MD5_Update(&ctx, md, sizeof(md));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, password, strlen(password));
+ EVP_DigestFinal_ex(ctx, md, NULL);
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, md, sizeof(md));
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, ireq.u.digestRequest.serverNonce,
strlen(ireq.u.digestRequest.serverNonce));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.nonceCount,
strlen(*ireq.u.digestRequest.nonceCount));
if (ireq.u.digestRequest.authid) {
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.authid,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.authid,
strlen(*ireq.u.digestRequest.authid));
}
- MD5_Final(md, &ctx);
+ EVP_DigestFinal_ex(ctx, md, NULL);
hex_encode(md, sizeof(md), &A1);
if (A1 == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
+ EVP_MD_CTX_destroy(ctx);
goto failed;
}
-
- MD5_Init(&ctx);
- MD5_Update(&ctx, "AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.uri,
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx,
+ "AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.uri,
strlen(*ireq.u.digestRequest.uri));
-
+
/* conf|int */
if (strcmp(ireq.u.digestRequest.digest, "clear") != 0) {
static char conf_zeros[] = ":00000000000000000000000000000000";
- MD5_Update(&ctx, conf_zeros, sizeof(conf_zeros) - 1);
+ EVP_DigestUpdate(ctx, conf_zeros, sizeof(conf_zeros) - 1);
}
-
- MD5_Final(md, &ctx);
+
+ EVP_DigestFinal_ex(ctx, md, NULL);
+
hex_encode(md, sizeof(md), &A2);
if (A2 == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
free(A1);
goto failed;
}
- MD5_Init(&ctx);
- MD5_Update(&ctx, A1, strlen(A2));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, A1, strlen(A2));
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, ireq.u.digestRequest.serverNonce,
strlen(ireq.u.digestRequest.serverNonce));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.nonceCount,
strlen(*ireq.u.digestRequest.nonceCount));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.clientNonce,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.clientNonce,
strlen(*ireq.u.digestRequest.clientNonce));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, *ireq.u.digestRequest.qop,
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, *ireq.u.digestRequest.qop,
strlen(*ireq.u.digestRequest.qop));
- MD5_Update(&ctx, ":", 1);
- MD5_Update(&ctx, A2, strlen(A2));
+ EVP_DigestUpdate(ctx, ":", 1);
+ EVP_DigestUpdate(ctx, A2, strlen(A2));
+
+ EVP_DigestFinal_ex(ctx, md, NULL);
- MD5_Final(md, &ctx);
+ EVP_MD_CTX_destroy(ctx);
free(A1);
free(A2);
hex_encode(md, sizeof(md), &mdx);
if (mdx == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = ENOMEM;
goto out;
}
@@ -774,7 +791,7 @@ _kdc_do_digest(krb5_context context,
if (ret == 0) {
r.u.response.success = TRUE;
} else {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"DIGEST-MD5 reply mismatch for %s",
ireq.u.digestRequest.username);
r.u.response.success = FALSE;
@@ -787,7 +804,7 @@ _kdc_do_digest(krb5_context context,
const char *username;
struct ntlm_buf answer;
Key *key = NULL;
- SHA_CTX ctx;
+ EVP_MD_CTX *ctp;
if ((config->digests_allowed & MS_CHAP_V2) == 0) {
kdc_log(context, config, 0, "MS-CHAP-V2 not allowed");
@@ -795,15 +812,15 @@ _kdc_do_digest(krb5_context context,
}
if (ireq.u.digestRequest.clientNonce == NULL) {
- krb5_set_error_string(context,
- "MS-CHAP-V2 clientNonce missing");
ret = EINVAL;
+ krb5_set_error_message(context, ret,
+ "MS-CHAP-V2 clientNonce missing");
goto failed;
- }
+ }
if (serverNonce.length != 16) {
- krb5_set_error_string(context,
- "MS-CHAP-V2 serverNonce wrong length");
ret = EINVAL;
+ krb5_set_error_message(context, ret,
+ "MS-CHAP-V2 serverNonce wrong length");
goto failed;
}
@@ -814,56 +831,64 @@ _kdc_do_digest(krb5_context context,
else
username++;
+ ctp = EVP_MD_CTX_create();
+
/* ChallangeHash */
- SHA1_Init(&ctx);
+ EVP_DigestInit_ex(ctp, EVP_sha1(), NULL);
{
ssize_t ssize;
krb5_data clientNonce;
-
+
clientNonce.length = strlen(*ireq.u.digestRequest.clientNonce);
clientNonce.data = malloc(clientNonce.length);
if (clientNonce.data == NULL) {
ret = ENOMEM;
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ret,
+ "malloc: out of memory");
+ EVP_MD_CTX_destroy(ctp);
goto out;
}
- ssize = hex_decode(*ireq.u.digestRequest.clientNonce,
+ ssize = hex_decode(*ireq.u.digestRequest.clientNonce,
clientNonce.data, clientNonce.length);
if (ssize != 16) {
- krb5_set_error_string(context,
- "Failed to decode clientNonce");
ret = ENOMEM;
+ krb5_set_error_message(context, ret,
+ "Failed to decode clientNonce");
+ EVP_MD_CTX_destroy(ctp);
goto out;
}
- SHA1_Update(&ctx, clientNonce.data, ssize);
+ EVP_DigestUpdate(ctp, clientNonce.data, ssize);
free(clientNonce.data);
}
- SHA1_Update(&ctx, serverNonce.data, serverNonce.length);
- SHA1_Update(&ctx, username, strlen(username));
- SHA1_Final(challange, &ctx);
+ EVP_DigestUpdate(ctp, serverNonce.data, serverNonce.length);
+ EVP_DigestUpdate(ctp, username, strlen(username));
+
+ EVP_DigestFinal_ex(ctp, challange, NULL);
+
+ EVP_MD_CTX_destroy(ctp);
/* NtPasswordHash */
ret = krb5_parse_name(context, username, &clientprincipal);
if (ret)
goto failed;
-
+
ret = _kdc_db_fetch(context, config, clientprincipal,
- HDB_F_GET_CLIENT, NULL, &user);
+ HDB_F_GET_CLIENT, NULL, NULL, &user);
krb5_free_principal(context, clientprincipal);
if (ret) {
- krb5_set_error_string(context,
- "MS-CHAP-V2 user %s not in database",
- username);
+ krb5_set_error_message(context, ret,
+ "MS-CHAP-V2 user %s not in database",
+ username);
goto failed;
}
- ret = hdb_enctype2key(context, &user->entry,
+ ret = hdb_enctype2key(context, &user->entry,
ETYPE_ARCFOUR_HMAC_MD5, &key);
if (ret) {
- krb5_set_error_string(context,
- "MS-CHAP-V2 missing arcfour key %s",
- username);
+ krb5_set_error_message(context, ret,
+ "MS-CHAP-V2 missing arcfour key %s",
+ username);
goto failed;
}
@@ -872,14 +897,14 @@ _kdc_do_digest(krb5_context context,
key->key.keyvalue.length,
challange, &answer);
if (ret) {
- krb5_set_error_string(context, "NTLM missing arcfour key");
+ krb5_set_error_message(context, ret, "NTLM missing arcfour key");
goto failed;
}
-
+
hex_encode(answer.data, answer.length, &mdx);
if (mdx == NULL) {
free(answer.data);
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = ENOMEM;
goto out;
}
@@ -889,7 +914,7 @@ _kdc_do_digest(krb5_context context,
if (ret == 0) {
r.u.response.success = TRUE;
} else {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"MS-CHAP-V2 hash mismatch for %s",
ireq.u.digestRequest.username);
r.u.response.success = FALSE;
@@ -898,34 +923,39 @@ _kdc_do_digest(krb5_context context,
if (r.u.response.success) {
unsigned char hashhash[MD4_DIGEST_LENGTH];
+ EVP_MD_CTX *ctxp;
+
+ ctxp = EVP_MD_CTX_create();
/* hashhash */
{
- MD4_CTX hctx;
-
- MD4_Init(&hctx);
- MD4_Update(&hctx, key->key.keyvalue.data,
- key->key.keyvalue.length);
- MD4_Final(hashhash, &hctx);
+ EVP_DigestInit_ex(ctxp, EVP_md4(), NULL);
+ EVP_DigestUpdate(ctxp,
+ key->key.keyvalue.data,
+ key->key.keyvalue.length);
+ EVP_DigestFinal_ex(ctxp, hashhash, NULL);
}
/* GenerateAuthenticatorResponse */
- SHA1_Init(&ctx);
- SHA1_Update(&ctx, hashhash, sizeof(hashhash));
- SHA1_Update(&ctx, answer.data, answer.length);
- SHA1_Update(&ctx, ms_chap_v2_magic1,sizeof(ms_chap_v2_magic1));
- SHA1_Final(md, &ctx);
-
- SHA1_Init(&ctx);
- SHA1_Update(&ctx, md, sizeof(md));
- SHA1_Update(&ctx, challange, 8);
- SHA1_Update(&ctx, ms_chap_v2_magic2, sizeof(ms_chap_v2_magic2));
- SHA1_Final(md, &ctx);
+ EVP_DigestInit_ex(ctxp, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctxp, hashhash, sizeof(hashhash));
+ EVP_DigestUpdate(ctxp, answer.data, answer.length);
+ EVP_DigestUpdate(ctxp, ms_chap_v2_magic1,
+ sizeof(ms_chap_v2_magic1));
+ EVP_DigestFinal_ex(ctxp, md, NULL);
+
+ EVP_DigestInit_ex(ctxp, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctxp, md, sizeof(md));
+ EVP_DigestUpdate(ctxp, challange, 8);
+ EVP_DigestUpdate(ctxp, ms_chap_v2_magic2,
+ sizeof(ms_chap_v2_magic2));
+ EVP_DigestFinal_ex(ctxp, md, NULL);
r.u.response.rsp = calloc(1, sizeof(*r.u.response.rsp));
if (r.u.response.rsp == NULL) {
free(answer.data);
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
+ EVP_MD_CTX_destroy(ctxp);
ret = ENOMEM;
goto out;
}
@@ -933,42 +963,46 @@ _kdc_do_digest(krb5_context context,
hex_encode(md, sizeof(md), r.u.response.rsp);
if (r.u.response.rsp == NULL) {
free(answer.data);
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
+ EVP_MD_CTX_destroy(ctxp);
ret = ENOMEM;
goto out;
}
/* get_master, rfc 3079 3.4 */
- SHA1_Init(&ctx);
- SHA1_Update(&ctx, hashhash, 16); /* md4(hash) */
- SHA1_Update(&ctx, answer.data, answer.length);
- SHA1_Update(&ctx, ms_rfc3079_magic1, sizeof(ms_rfc3079_magic1));
- SHA1_Final(md, &ctx);
+ EVP_DigestInit_ex(ctxp, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctxp, hashhash, 16);
+ EVP_DigestUpdate(ctxp, answer.data, answer.length);
+ EVP_DigestUpdate(ctxp, ms_rfc3079_magic1,
+ sizeof(ms_rfc3079_magic1));
+ EVP_DigestFinal_ex(ctxp, md, NULL);
free(answer.data);
- r.u.response.session_key =
+ EVP_MD_CTX_destroy(ctxp);
+
+ r.u.response.session_key =
calloc(1, sizeof(*r.u.response.session_key));
if (r.u.response.session_key == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = ENOMEM;
goto out;
}
ret = krb5_data_copy(r.u.response.session_key, md, 16);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
}
} else {
r.element = choice_DigestRepInner_error;
- asprintf(&r.u.error.reason, "Unsupported digest type %s",
+ asprintf(&r.u.error.reason, "Unsupported digest type %s",
ireq.u.digestRequest.type);
if (r.u.error.reason == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
r.u.error.code = EINVAL;
@@ -1002,7 +1036,7 @@ _kdc_do_digest(krb5_context context,
goto failed;
}
- r.u.ntlmInitReply.flags |=
+ r.u.ntlmInitReply.flags |=
NTLM_NEG_TARGET |
NTLM_TARGET_DOMAIN |
NTLM_ENC_128;
@@ -1018,32 +1052,32 @@ _kdc_do_digest(krb5_context context,
#undef ALL
- r.u.ntlmInitReply.targetname =
+ r.u.ntlmInitReply.targetname =
get_ntlm_targetname(context, client);
if (r.u.ntlmInitReply.targetname == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
r.u.ntlmInitReply.challange.data = malloc(8);
if (r.u.ntlmInitReply.challange.data == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
r.u.ntlmInitReply.challange.length = 8;
if (RAND_bytes(r.u.ntlmInitReply.challange.data,
- r.u.ntlmInitReply.challange.length) != 1)
- {
- krb5_set_error_string(context, "out of random error");
- ret = ENOMEM;
- goto out;
- }
+ r.u.ntlmInitReply.challange.length) != 1)
+ {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "out of random error");
+ goto out;
+ }
/* XXX fix targetinfo */
ALLOC(r.u.ntlmInitReply.targetinfo);
if (r.u.ntlmInitReply.targetinfo == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
@@ -1052,37 +1086,37 @@ _kdc_do_digest(krb5_context context,
client,
r.u.ntlmInitReply.targetinfo);
if (ret) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
- /*
+ /*
* Save data encryted in opaque for the second part of the
* ntlm authentication
*/
sp = krb5_storage_emem();
if (sp == NULL) {
ret = ENOMEM;
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
-
+
ret = krb5_storage_write(sp, r.u.ntlmInitReply.challange.data, 8);
if (ret != 8) {
ret = ENOMEM;
- krb5_set_error_string(context, "storage write challange");
+ krb5_set_error_message(context, ret, "storage write challange");
goto out;
}
ret = krb5_store_uint32(sp, r.u.ntlmInitReply.flags);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
ret = krb5_storage_to_data(sp, &buf);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
@@ -1109,7 +1143,7 @@ _kdc_do_digest(krb5_context context,
uint32_t flags;
Key *key = NULL;
int version;
-
+
r.element = choice_DigestRepInner_ntlmResponse;
r.u.ntlmResponse.success = 0;
r.u.ntlmResponse.flags = 0;
@@ -1124,11 +1158,11 @@ _kdc_do_digest(krb5_context context,
goto failed;
ret = _kdc_db_fetch(context, config, clientprincipal,
- HDB_F_GET_CLIENT, NULL, &user);
+ HDB_F_GET_CLIENT, NULL, NULL, &user);
krb5_free_principal(context, clientprincipal);
if (ret) {
- krb5_set_error_string(context, "NTLM user %s not in database",
- ireq.u.ntlmRequest.username);
+ krb5_set_error_message(context, ret, "NTLM user %s not in database",
+ ireq.u.ntlmRequest.username);
goto failed;
}
@@ -1142,7 +1176,7 @@ _kdc_do_digest(krb5_context context,
krb5_crypto_destroy(context, crypto);
crypto = NULL;
if (ret) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Failed to decrypt nonce from %s", from);
goto failed;
}
@@ -1150,33 +1184,35 @@ _kdc_do_digest(krb5_context context,
sp = krb5_storage_from_data(&buf);
if (sp == NULL) {
ret = ENOMEM;
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
-
+
ret = krb5_storage_read(sp, challange, sizeof(challange));
if (ret != sizeof(challange)) {
- krb5_set_error_string(context, "NTLM storage read challange");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "NTLM storage read challange");
goto out;
}
ret = krb5_ret_uint32(sp, &flags);
if (ret) {
- krb5_set_error_string(context, "NTLM storage read flags");
+ krb5_set_error_message(context, ret, "NTLM storage read flags");
goto out;
}
+ krb5_storage_free(sp);
+ sp = NULL;
krb5_data_free(&buf);
if ((flags & NTLM_NEG_NTLM) == 0) {
ret = EINVAL;
- krb5_set_error_string(context, "NTLM not negotiated");
+ krb5_set_error_message(context, ret, "NTLM not negotiated");
goto out;
}
- ret = hdb_enctype2key(context, &user->entry,
+ ret = hdb_enctype2key(context, &user->entry,
ETYPE_ARCFOUR_HMAC_MD5, &key);
if (ret) {
- krb5_set_error_string(context, "NTLM missing arcfour key");
+ krb5_set_error_message(context, ret, "NTLM missing arcfour key");
goto out;
}
@@ -1194,8 +1230,8 @@ _kdc_do_digest(krb5_context context,
targetname = get_ntlm_targetname(context, client);
if (targetname == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
@@ -1213,7 +1249,7 @@ _kdc_do_digest(krb5_context context,
sessionkey);
free(targetname);
if (ret) {
- krb5_set_error_string(context, "NTLM v2 verify failed");
+ krb5_set_error_message(context, ret, "NTLM v2 verify failed");
goto failed;
}
@@ -1229,8 +1265,8 @@ _kdc_do_digest(krb5_context context,
if (flags & NTLM_NEG_NTLM2_SESSION) {
unsigned char sessionhash[MD5_DIGEST_LENGTH];
- MD5_CTX md5ctx;
-
+ EVP_MD_CTX *ctx;
+
if ((config->digests_allowed & NTLM_V1_SESSION) == 0) {
kdc_log(context, config, 0, "NTLM v1-session not allowed");
ret = EINVAL;
@@ -1238,91 +1274,105 @@ _kdc_do_digest(krb5_context context,
}
if (ireq.u.ntlmRequest.lm.length != 24) {
- krb5_set_error_string(context, "LM hash have wrong length "
- "for NTLM session key");
ret = EINVAL;
+ krb5_set_error_message(context, ret, "LM hash have wrong length "
+ "for NTLM session key");
goto failed;
}
-
- MD5_Init(&md5ctx);
- MD5_Update(&md5ctx, challange, sizeof(challange));
- MD5_Update(&md5ctx, ireq.u.ntlmRequest.lm.data, 8);
- MD5_Final(sessionhash, &md5ctx);
+
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+
+ EVP_DigestUpdate(ctx, challange, sizeof(challange));
+ EVP_DigestUpdate(ctx, ireq.u.ntlmRequest.lm.data, 8);
+ EVP_DigestFinal_ex(ctx, sessionhash, NULL);
memcpy(challange, sessionhash, sizeof(challange));
+
+ EVP_MD_CTX_destroy(ctx);
+
} else {
if ((config->digests_allowed & NTLM_V1) == 0) {
kdc_log(context, config, 0, "NTLM v1 not allowed");
goto failed;
}
}
-
+
ret = heim_ntlm_calculate_ntlm1(key->key.keyvalue.data,
key->key.keyvalue.length,
challange, &answer);
if (ret) {
- krb5_set_error_string(context, "NTLM missing arcfour key");
+ krb5_set_error_message(context, ret, "NTLM missing arcfour key");
goto failed;
}
-
+
if (ireq.u.ntlmRequest.ntlm.length != answer.length ||
memcmp(ireq.u.ntlmRequest.ntlm.data, answer.data, answer.length) != 0)
- {
- free(answer.data);
- ret = EINVAL;
- krb5_set_error_string(context, "NTLM hash mismatch");
- goto failed;
- }
+ {
+ free(answer.data);
+ ret = EINVAL;
+ krb5_set_error_message(context, ret, "NTLM hash mismatch");
+ goto failed;
+ }
free(answer.data);
{
- MD4_CTX ctx;
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+
+ EVP_DigestInit_ex(ctx, EVP_md4(), NULL);
+ EVP_DigestUpdate(ctx,
+ key->key.keyvalue.data,
+ key->key.keyvalue.length);
+ EVP_DigestFinal_ex(ctx, sessionkey, NULL);
- MD4_Init(&ctx);
- MD4_Update(&ctx,
- key->key.keyvalue.data, key->key.keyvalue.length);
- MD4_Final(sessionkey, &ctx);
+ EVP_MD_CTX_destroy(ctx);
}
}
if (ireq.u.ntlmRequest.sessionkey) {
unsigned char masterkey[MD4_DIGEST_LENGTH];
- RC4_KEY rc4;
+ EVP_CIPHER_CTX rc4;
size_t len;
-
+
if ((flags & NTLM_NEG_KEYEX) == 0) {
- krb5_set_error_string(context,
- "NTLM client failed to neg key "
- "exchange but still sent key");
ret = EINVAL;
+ krb5_set_error_message(context, ret,
+ "NTLM client failed to neg key "
+ "exchange but still sent key");
goto failed;
}
-
+
len = ireq.u.ntlmRequest.sessionkey->length;
if (len != sizeof(masterkey)){
- krb5_set_error_string(context,
- "NTLM master key wrong length: %lu",
- (unsigned long)len);
+ ret = EINVAL;
+ krb5_set_error_message(context, ret,
+ "NTLM master key wrong length: %lu",
+ (unsigned long)len);
goto failed;
}
-
- RC4_set_key(&rc4, sizeof(sessionkey), sessionkey);
-
- RC4(&rc4, sizeof(masterkey),
- ireq.u.ntlmRequest.sessionkey->data,
- masterkey);
- memset(&rc4, 0, sizeof(rc4));
-
- r.u.ntlmResponse.sessionkey =
+
+
+ EVP_CIPHER_CTX_init(&rc4);
+ EVP_CipherInit_ex(&rc4, EVP_rc4(), NULL, sessionkey, NULL, 1);
+ EVP_Cipher(&rc4,
+ masterkey, ireq.u.ntlmRequest.sessionkey->data,
+ sizeof(masterkey));
+ EVP_CIPHER_CTX_cleanup(&rc4);
+
+ r.u.ntlmResponse.sessionkey =
malloc(sizeof(*r.u.ntlmResponse.sessionkey));
if (r.u.ntlmResponse.sessionkey == NULL) {
- krb5_set_error_string(context, "out of memory");
+ ret = EINVAL;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
-
+
ret = krb5_data_copy(r.u.ntlmResponse.sessionkey,
masterkey, sizeof(masterkey));
if (ret) {
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
}
@@ -1354,26 +1404,26 @@ _kdc_do_digest(krb5_context context,
break;
default: {
- char *s;
- krb5_set_error_string(context, "unknown operation to digest");
+ const char *s;
ret = EINVAL;
+ krb5_set_error_message(context, ret, "unknown operation to digest");
- failed:
+ failed:
s = krb5_get_error_message(context, ret);
if (s == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
-
+
kdc_log(context, config, 0, "Digest failed with: %s", s);
r.element = choice_DigestRepInner_error;
r.u.error.reason = strdup("unknown error");
- krb5_free_error_string(context, s);
+ krb5_free_error_message(context, s);
if (r.u.error.reason == NULL) {
- krb5_set_error_string(context, "out of memory");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
r.u.error.code = EINVAL;
@@ -1383,7 +1433,7 @@ _kdc_do_digest(krb5_context context,
ASN1_MALLOC_ENCODE(DigestRepInner, buf.data, buf.length, &r, &size, ret);
if (ret) {
- krb5_set_error_string(context, "Failed to encode inner digest reply");
+ krb5_set_error_message(context, ret, "Failed to encode inner digest reply");
goto out;
}
if (size != buf.length)
@@ -1408,20 +1458,20 @@ _kdc_do_digest(krb5_context context,
goto out;
}
- ret = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT,
+ ret = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT,
buf.data, buf.length, 0,
&rep.innerRep);
-
+
ASN1_MALLOC_ENCODE(DigestREP, reply->data, reply->length, &rep, &size, ret);
if (ret) {
- krb5_set_error_string(context, "Failed to encode digest reply");
+ krb5_set_error_message(context, ret, "Failed to encode digest reply");
goto out;
}
if (size != reply->length)
krb5_abortx(context, "ASN1 internal error");
-
-out:
+
+ out:
if (ac)
krb5_auth_con_free(context, ac);
if (ret)
@@ -1448,9 +1498,12 @@ out:
free (client_name);
krb5_data_free(&buf);
krb5_data_free(&serverNonce);
+ free_Checksum(&res);
free_DigestREP(&rep);
free_DigestRepInner(&r);
free_DigestReqInner(&ireq);
return ret;
}
+
+#endif /* DIGEST */
diff --git a/crypto/heimdal/kdc/headers.h b/crypto/heimdal/kdc/headers.h
index bdbc156..aced5ce 100644
--- a/crypto/heimdal/kdc/headers.h
+++ b/crypto/heimdal/kdc/headers.h
@@ -1,47 +1,45 @@
/*
- * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997 - 2006 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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: headers.h 19658 2007-01-04 00:15:34Z lha $
- * $FreeBSD$
+/*
+ * $Id$
*/
#ifndef __HEADERS_H__
#define __HEADERS_H__
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
+
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -92,17 +90,24 @@
#include <parse_units.h>
#include <krb5.h>
#include <krb5_locl.h>
+#ifdef DIGEST
#include <digest_asn1.h>
+#endif
+#ifdef KX509
#include <kx509_asn1.h>
+#endif
#include <hdb.h>
#include <hdb_err.h>
#include <der.h>
+#ifndef NO_NTLM
#include <heimntlm.h>
+#endif
+#include <kdc.h>
#include <windc_plugin.h>
#undef ALLOC
-#define ALLOC(X) ((X) = malloc(sizeof(*(X))))
+#define ALLOC(X) ((X) = calloc(1, sizeof(*(X))))
#undef ALLOC_SEQ
#define ALLOC_SEQ(X, N) do { (X)->len = (N); \
(X)->val = calloc((X)->len, sizeof(*(X)->val)); } while(0)
diff --git a/crypto/heimdal/kdc/hprop.8 b/crypto/heimdal/kdc/hprop.8
index 99fc978..973235f 100644
--- a/crypto/heimdal/kdc/hprop.8
+++ b/crypto/heimdal/kdc/hprop.8
@@ -1,35 +1,35 @@
-.\" Copyright (c) 2000 - 2004 Kungliga Tekniska Högskolan
-.\" (Royal Institute of Technology, Stockholm, Sweden).
-.\" All rights reserved.
+.\" Copyright (c) 2000 - 2004 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:
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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: hprop.8 20456 2007-04-19 20:29:42Z lha $
+.\" 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$
.\"
.Dd December 8, 2004
.Dt HPROP 8
@@ -41,37 +41,36 @@
.Nm
.Bk -words
.Oo Fl m Ar file \*(Ba Xo
-.Fl -master-key= Ns Pa file
+.Fl Fl master-key= Ns Pa file
.Xc
.Oc
.Oo Fl d Ar file \*(Ba Xo
-.Fl -database= Ns Pa file
+.Fl Fl database= Ns Pa file
.Xc
.Oc
-.Op Fl -source= Ns Ar heimdal|mit-dump|krb4-dump|kaserver
+.Op Fl Fl source= Ns Ar heimdal|mit-dump
.Oo Fl r Ar string \*(Ba Xo
-.Fl -v4-realm= Ns Ar string
+.Fl Fl v4-realm= Ns Ar string
.Xc
.Oc
.Oo Fl c Ar cell \*(Ba Xo
-.Fl -cell= Ns Ar cell
+.Fl Fl cell= Ns Ar cell
.Xc
.Oc
-.Op Fl S | Fl -kaspecials
.Oo Fl k Ar keytab \*(Ba Xo
-.Fl -keytab= Ns Ar keytab
+.Fl Fl keytab= Ns Ar keytab
.Xc
.Oc
.Oo Fl R Ar string \*(Ba Xo
-.Fl -v5-realm= Ns Ar string
+.Fl Fl v5-realm= Ns Ar string
.Xc
.Oc
-.Op Fl D | Fl -decrypt
-.Op Fl E | Fl -encrypt
-.Op Fl n | Fl -stdout
-.Op Fl v | Fl -verbose
-.Op Fl -version
-.Op Fl h | Fl -help
+.Op Fl D | Fl Fl decrypt
+.Op Fl E | Fl Fl encrypt
+.Op Fl n | Fl Fl stdout
+.Op Fl v | Fl Fl verbose
+.Op Fl Fl version
+.Op Fl h | Fl Fl help
.Op Ar host Ns Op : Ns Ar port
.Ar ...
.Ek
@@ -90,101 +89,42 @@ specified on the command by opening a TCP connection to port 754
.Pp
Supported options:
.Bl -tag -width Ds
-.It Xo
-.Fl m Ar file ,
-.Fl -master-key= Ns Pa file
-.Xc
+.It Fl m Ar file , Fl Fl master-key= Ns Pa file
Where to find the master key to encrypt or decrypt keys with.
-.It Xo
-.Fl d Ar file ,
-.Fl -database= Ns Pa file
-.Xc
+.It Fl d Ar file , Fl Fl database= Ns Pa file
The database to be propagated.
-.It Xo
-.Fl -source= Ns Ar heimdal|mit-dump|krb4-dump|kaserver
-.Xc
+.It Fl Fl source= Ns Ar heimdal|mit-dump|krb4-dump|kaserver
Specifies the type of the source database. Alternatives include:
.Pp
-.Bl -tag -width krb4-dump -compact -offset indent
+.Bl -tag -width mit-dump -compact -offset indent
.It heimdal
a Heimdal database
.It mit-dump
a MIT Kerberos 5 dump file
-.It krb4-dump
-a Kerberos 4 dump file
-.It kaserver
-an AFS kaserver database
.El
-.It Xo
-.Fl k Ar keytab ,
-.Fl -keytab= Ns Ar keytab
-.Xc
++.It Fl k Ar keytab , Fl Fl keytab= Ns Ar keytab
The keytab to use for fetching the key to be used for authenticating
to the propagation daemon(s). The key
-.Pa kadmin/hprop
+.Pa hprop/hostname
is used from this keytab. The default is to fetch the key from the
KDC database.
-.It Xo
-.Fl R Ar string ,
-.Fl -v5-realm= Ns Ar string
-.Xc
+.It Fl R Ar string , Fl Fl v5-realm= Ns Ar string
Local realm override.
-.It Xo
-.Fl D ,
-.Fl -decrypt
-.Xc
+.It Fl D , Fl Fl decrypt
The encryption keys in the database can either be in clear, or
encrypted with a master key. This option transmits the database with
unencrypted keys.
-.It Xo
-.Fl E ,
-.Fl -encrypt
-.Xc
+.It Fl E , Fl Fl encrypt
This option transmits the database with encrypted keys.
-.It Xo
-.Fl n ,
-.Fl -stdout
-.Xc
+.It Fl n , Fl Fl stdout
Dump the database on stdout, in a format that can be fed to hpropd.
.El
-.Pp
-The following options are only valid if
-.Nm hprop
-is compiled with support for Kerberos 4 (kaserver).
-.Bl -tag -width Ds
-.It Xo
-.Fl r Ar string ,
-.Fl -v4-realm= Ns Ar string
-.Xc
-v4 realm to use.
-.It Xo
-.Fl c Ar cell ,
-.Fl -cell= Ns Ar cell
-.Xc
-The AFS cell name, used if reading a kaserver database.
-.It Xo
-.Fl S ,
-.Fl -kaspecials
-.Xc
-Also dump the principals marked as special in the kaserver database.
-.It Xo
-.Fl K ,
-.Fl -ka-db
-.Xc
-Deprecated, identical to
-.Sq --source=kaserver .
-.El
.Sh EXAMPLES
The following will propagate a database to another machine (which
should run
-.Xr hpropd 8 ):
+.Xr hpropd 8 ) :
.Bd -literal -offset indent
$ hprop slave-1 slave-2
.Ed
-.Pp
-Convert a Kerberos 4 dump-file for use with a Heimdal KDC:
-.Bd -literal -offset indent
-$ hprop -n --source=krb4-dump -d /var/kerberos/principal.dump --master-key=/.k | hpropd -n
-.Ed
.Sh SEE ALSO
.Xr hpropd 8
diff --git a/crypto/heimdal/kdc/hprop.c b/crypto/heimdal/kdc/hprop.c
index e5b7fd1..b68f159 100644
--- a/crypto/heimdal/kdc/hprop.c
+++ b/crypto/heimdal/kdc/hprop.c
@@ -1,39 +1,39 @@
/*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997 - 2005 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "hprop.h"
+#define KRB5_DEPRECATED /* uses v4 functions that will die */
-RCSID("$Id: hprop.c 21745 2007-07-31 16:11:25Z lha $");
+#include "hprop.h"
static int version_flag;
static int help_flag;
@@ -48,12 +48,6 @@ static hdb_master_key mkey5;
static char *source_type;
-static char *afs_cell;
-static char *v4_realm;
-
-static int kaspecials_flag;
-static int ka_use_null_salt;
-
static char *local_realm=NULL;
static int
@@ -72,7 +66,7 @@ open_socket(krb5_context context, const char *hostname, const char *port)
warnx ("%s: %s", hostname, gai_strerror(error));
return -1;
}
-
+
for (a = ai; a != NULL; a = a->ai_next) {
int s;
@@ -112,7 +106,7 @@ v5_prop(krb5_context context, HDB *db, hdb_entry_ex *entry, void *appdata)
krb5_warn(context, ret, "hdb_unseal_keys_mkey");
return ret;
}
- }
+ }
ret = hdb_entry2value(context, &entry->entry, &data);
if(ret) {
@@ -123,310 +117,29 @@ v5_prop(krb5_context context, HDB *db, hdb_entry_ex *entry, void *appdata)
if(to_stdout)
ret = krb5_write_message(context, &pd->sock, &data);
else
- ret = krb5_write_priv_message(context, pd->auth_context,
+ ret = krb5_write_priv_message(context, pd->auth_context,
&pd->sock, &data);
krb5_data_free(&data);
return ret;
}
-int
-v4_prop(void *arg, struct v4_principal *p)
-{
- struct prop_data *pd = arg;
- hdb_entry_ex ent;
- krb5_error_code ret;
-
- memset(&ent, 0, sizeof(ent));
-
- ret = krb5_425_conv_principal(pd->context, p->name, p->instance, v4_realm,
- &ent.entry.principal);
- if(ret) {
- krb5_warn(pd->context, ret,
- "krb5_425_conv_principal %s.%s@%s",
- p->name, p->instance, v4_realm);
- return 0;
- }
-
- if(verbose_flag) {
- char *s;
- krb5_unparse_name_short(pd->context, ent.entry.principal, &s);
- krb5_warnx(pd->context, "%s.%s -> %s", p->name, p->instance, s);
- free(s);
- }
-
- ent.entry.kvno = p->kvno;
- ent.entry.keys.len = 3;
- ent.entry.keys.val = malloc(ent.entry.keys.len * sizeof(*ent.entry.keys.val));
- if (ent.entry.keys.val == NULL)
- krb5_errx(pd->context, ENOMEM, "malloc");
- if(p->mkvno != -1) {
- ent.entry.keys.val[0].mkvno = malloc (sizeof(*ent.entry.keys.val[0].mkvno));
- if (ent.entry.keys.val[0].mkvno == NULL)
- krb5_errx(pd->context, ENOMEM, "malloc");
- *(ent.entry.keys.val[0].mkvno) = p->mkvno;
- } else
- ent.entry.keys.val[0].mkvno = NULL;
- ent.entry.keys.val[0].salt = calloc(1, sizeof(*ent.entry.keys.val[0].salt));
- if (ent.entry.keys.val[0].salt == NULL)
- krb5_errx(pd->context, ENOMEM, "calloc");
- ent.entry.keys.val[0].salt->type = KRB5_PADATA_PW_SALT;
- ent.entry.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
- krb5_data_alloc(&ent.entry.keys.val[0].key.keyvalue, DES_KEY_SZ);
- memcpy(ent.entry.keys.val[0].key.keyvalue.data, p->key, 8);
-
- copy_Key(&ent.entry.keys.val[0], &ent.entry.keys.val[1]);
- ent.entry.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
- copy_Key(&ent.entry.keys.val[0], &ent.entry.keys.val[2]);
- ent.entry.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
-
- {
- int life = _krb5_krb_life_to_time(0, p->max_life);
- if(life == NEVERDATE){
- ent.entry.max_life = NULL;
- } else {
- /* clean up lifetime a bit */
- if(life > 86400)
- life = (life + 86399) / 86400 * 86400;
- else if(life > 3600)
- life = (life + 3599) / 3600 * 3600;
- ALLOC(ent.entry.max_life);
- *ent.entry.max_life = life;
- }
- }
-
- ALLOC(ent.entry.valid_end);
- *ent.entry.valid_end = p->exp_date;
-
- ret = krb5_make_principal(pd->context, &ent.entry.created_by.principal,
- v4_realm,
- "kadmin",
- "hprop",
- NULL);
- if(ret){
- krb5_warn(pd->context, ret, "krb5_make_principal");
- ret = 0;
- goto out;
- }
- ent.entry.created_by.time = time(NULL);
- ALLOC(ent.entry.modified_by);
- ret = krb5_425_conv_principal(pd->context, p->mod_name, p->mod_instance,
- v4_realm, &ent.entry.modified_by->principal);
- if(ret){
- krb5_warn(pd->context, ret, "%s.%s@%s", p->name, p->instance, v4_realm);
- ent.entry.modified_by->principal = NULL;
- ret = 0;
- goto out;
- }
- ent.entry.modified_by->time = p->mod_date;
-
- ent.entry.flags.forwardable = 1;
- ent.entry.flags.renewable = 1;
- ent.entry.flags.proxiable = 1;
- ent.entry.flags.postdate = 1;
- ent.entry.flags.client = 1;
- ent.entry.flags.server = 1;
-
- /* special case password changing service */
- if(strcmp(p->name, "changepw") == 0 &&
- strcmp(p->instance, "kerberos") == 0) {
- ent.entry.flags.forwardable = 0;
- ent.entry.flags.renewable = 0;
- ent.entry.flags.proxiable = 0;
- ent.entry.flags.postdate = 0;
- ent.entry.flags.initial = 1;
- ent.entry.flags.change_pw = 1;
- }
-
- ret = v5_prop(pd->context, NULL, &ent, pd);
-
- if (strcmp (p->name, "krbtgt") == 0
- && strcmp (v4_realm, p->instance) != 0) {
- krb5_free_principal (pd->context, ent.entry.principal);
- ret = krb5_425_conv_principal (pd->context, p->name,
- v4_realm, p->instance,
- &ent.entry.principal);
- if (ret == 0)
- ret = v5_prop (pd->context, NULL, &ent, pd);
- }
-
- out:
- hdb_free_entry(pd->context, &ent);
- return ret;
-}
-
-#include "kadb.h"
-
-/* read a `ka_entry' from `fd' at offset `pos' */
-static void
-read_block(krb5_context context, int fd, int32_t pos, void *buf, size_t len)
-{
- krb5_error_code ret;
-#ifdef HAVE_PREAD
- if((ret = pread(fd, buf, len, 64 + pos)) < 0)
- krb5_err(context, 1, errno, "pread(%u)", 64 + pos);
-#else
- if(lseek(fd, 64 + pos, SEEK_SET) == (off_t)-1)
- krb5_err(context, 1, errno, "lseek(%u)", 64 + pos);
- ret = read(fd, buf, len);
- if(ret < 0)
- krb5_err(context, 1, errno, "read(%lu)", (unsigned long)len);
-#endif
- if(ret != len)
- krb5_errx(context, 1, "read(%lu) = %u", (unsigned long)len, ret);
-}
-
-static int
-ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent)
-{
- int32_t flags = ntohl(ent->flags);
- krb5_error_code ret;
- hdb_entry_ex hdb;
-
- if(!kaspecials_flag
- && (flags & KAFNORMAL) == 0) /* remove special entries */
- return 0;
- memset(&hdb, 0, sizeof(hdb));
- ret = krb5_425_conv_principal(pd->context, ent->name, ent->instance,
- v4_realm, &hdb.entry.principal);
- if(ret) {
- krb5_warn(pd->context, ret,
- "krb5_425_conv_principal (%s.%s@%s)",
- ent->name, ent->instance, v4_realm);
- return 0;
- }
- hdb.entry.kvno = ntohl(ent->kvno);
- hdb.entry.keys.len = 3;
- hdb.entry.keys.val =
- malloc(hdb.entry.keys.len * sizeof(*hdb.entry.keys.val));
- if (hdb.entry.keys.val == NULL)
- krb5_errx(pd->context, ENOMEM, "malloc");
- hdb.entry.keys.val[0].mkvno = NULL;
- hdb.entry.keys.val[0].salt = calloc(1, sizeof(*hdb.entry.keys.val[0].salt));
- if (hdb.entry.keys.val[0].salt == NULL)
- krb5_errx(pd->context, ENOMEM, "calloc");
- if (ka_use_null_salt) {
- hdb.entry.keys.val[0].salt->type = hdb_pw_salt;
- hdb.entry.keys.val[0].salt->salt.data = NULL;
- hdb.entry.keys.val[0].salt->salt.length = 0;
- } else {
- hdb.entry.keys.val[0].salt->type = hdb_afs3_salt;
- hdb.entry.keys.val[0].salt->salt.data = strdup(afs_cell);
- if (hdb.entry.keys.val[0].salt->salt.data == NULL)
- krb5_errx(pd->context, ENOMEM, "strdup");
- hdb.entry.keys.val[0].salt->salt.length = strlen(afs_cell);
- }
-
- hdb.entry.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
- krb5_data_copy(&hdb.entry.keys.val[0].key.keyvalue,
- ent->key,
- sizeof(ent->key));
- copy_Key(&hdb.entry.keys.val[0], &hdb.entry.keys.val[1]);
- hdb.entry.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
- copy_Key(&hdb.entry.keys.val[0], &hdb.entry.keys.val[2]);
- hdb.entry.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
-
- ALLOC(hdb.entry.max_life);
- *hdb.entry.max_life = ntohl(ent->max_life);
-
- if(ntohl(ent->valid_end) != NEVERDATE && ntohl(ent->valid_end) != 0xffffffff) {
- ALLOC(hdb.entry.valid_end);
- *hdb.entry.valid_end = ntohl(ent->valid_end);
- }
-
- if (ntohl(ent->pw_change) != NEVERDATE &&
- ent->pw_expire != 255 &&
- ent->pw_expire != 0) {
- ALLOC(hdb.entry.pw_end);
- *hdb.entry.pw_end = ntohl(ent->pw_change)
- + 24 * 60 * 60 * ent->pw_expire;
- }
-
- ret = krb5_make_principal(pd->context, &hdb.entry.created_by.principal,
- v4_realm,
- "kadmin",
- "hprop",
- NULL);
- hdb.entry.created_by.time = time(NULL);
-
- if(ent->mod_ptr){
- struct ka_entry mod;
- ALLOC(hdb.entry.modified_by);
- read_block(pd->context, fd, ntohl(ent->mod_ptr), &mod, sizeof(mod));
-
- krb5_425_conv_principal(pd->context, mod.name, mod.instance, v4_realm,
- &hdb.entry.modified_by->principal);
- hdb.entry.modified_by->time = ntohl(ent->mod_time);
- memset(&mod, 0, sizeof(mod));
- }
-
- hdb.entry.flags.forwardable = 1;
- hdb.entry.flags.renewable = 1;
- hdb.entry.flags.proxiable = 1;
- hdb.entry.flags.postdate = 1;
- /* XXX - AFS 3.4a creates krbtgt.REALMOFCELL as NOTGS+NOSEAL */
- if (strcmp(ent->name, "krbtgt") == 0 &&
- (flags & (KAFNOTGS|KAFNOSEAL)) == (KAFNOTGS|KAFNOSEAL))
- flags &= ~(KAFNOTGS|KAFNOSEAL);
-
- hdb.entry.flags.client = (flags & KAFNOTGS) == 0;
- hdb.entry.flags.server = (flags & KAFNOSEAL) == 0;
-
- ret = v5_prop(pd->context, NULL, &hdb, pd);
- hdb_free_entry(pd->context, &hdb);
- return ret;
-}
-
-static int
-ka_dump(struct prop_data *pd, const char *file)
-{
- struct ka_header header;
- int i;
- int fd = open(file, O_RDONLY);
-
- if(fd < 0)
- krb5_err(pd->context, 1, errno, "open(%s)", file);
- read_block(pd->context, fd, 0, &header, sizeof(header));
- if(header.version1 != header.version2)
- krb5_errx(pd->context, 1, "Version mismatch in header: %ld/%ld",
- (long)ntohl(header.version1), (long)ntohl(header.version2));
- if(ntohl(header.version1) != 5)
- krb5_errx(pd->context, 1, "Unknown database version %ld (expected 5)",
- (long)ntohl(header.version1));
- for(i = 0; i < ntohl(header.hashsize); i++){
- int32_t pos = ntohl(header.hash[i]);
- while(pos){
- struct ka_entry ent;
- read_block(pd->context, fd, pos, &ent, sizeof(ent));
- ka_convert(pd, fd, &ent);
- pos = ntohl(ent.next);
- }
- }
- return 0;
-}
-
-
-
struct getargs args[] = {
{ "master-key", 'm', arg_string, &mkeyfile, "v5 master key file", "file" },
- { "database", 'd', arg_string, &database, "database", "file" },
- { "source", 0, arg_string, &source_type, "type of database to read",
+ { "database", 'd', arg_string, rk_UNCONST(&database), "database", "file" },
+ { "source", 0, arg_string, &source_type, "type of database to read",
"heimdal"
"|mit-dump"
- "|krb4-dump"
- "|kaserver"
},
-
- { "v4-realm", 'r', arg_string, &v4_realm, "v4 realm to use" },
- { "cell", 'c', arg_string, &afs_cell, "name of AFS cell" },
- { "kaspecials", 'S', arg_flag, &kaspecials_flag, "dump KASPECIAL keys"},
- { "keytab", 'k', arg_string, &ktname, "keytab to use for authentication", "keytab" },
- { "v5-realm", 'R', arg_string, &local_realm, "v5 realm to use" },
- { "decrypt", 'D', arg_flag, &decrypt_flag, "decrypt keys" },
- { "encrypt", 'E', arg_flag, &encrypt_flag, "encrypt keys" },
- { "stdout", 'n', arg_flag, &to_stdout, "dump to stdout" },
- { "verbose", 'v', arg_flag, &verbose_flag },
- { "version", 0, arg_flag, &version_flag },
- { "help", 'h', arg_flag, &help_flag }
+
+ { "keytab", 'k', arg_string, rk_UNCONST(&ktname),
+ "keytab to use for authentication", "keytab" },
+ { "v5-realm", 'R', arg_string, &local_realm, "v5 realm to use", NULL },
+ { "decrypt", 'D', arg_flag, &decrypt_flag, "decrypt keys", NULL },
+ { "encrypt", 'E', arg_flag, &encrypt_flag, "encrypt keys", NULL },
+ { "stdout", 'n', arg_flag, &to_stdout, "dump to stdout", NULL },
+ { "verbose", 'v', arg_flag, &verbose_flag, NULL, NULL },
+ { "version", 0, arg_flag, &version_flag, NULL, NULL },
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL }
};
static int num_args = sizeof(args) / sizeof(args[0]);
@@ -447,14 +160,14 @@ get_creds(krb5_context context, krb5_ccache *cache)
krb5_get_init_creds_opt *init_opts;
krb5_preauthtype preauth = KRB5_PADATA_ENC_TIMESTAMP;
krb5_creds creds;
-
+
ret = krb5_kt_register(context, &hdb_kt_ops);
if(ret) krb5_err(context, 1, ret, "krb5_kt_register");
ret = krb5_kt_resolve(context, ktname, &keytab);
if(ret) krb5_err(context, 1, ret, "krb5_kt_resolve");
-
- ret = krb5_make_principal(context, &client, NULL,
+
+ ret = krb5_make_principal(context, &client, NULL,
"kadmin", HPROP_NAME, NULL);
if(ret) krb5_err(context, 1, ret, "krb5_make_principal");
@@ -466,12 +179,12 @@ get_creds(krb5_context context, krb5_ccache *cache)
if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");
krb5_get_init_creds_opt_free(context, init_opts);
-
+
ret = krb5_kt_close(context, keytab);
if(ret) krb5_err(context, 1, ret, "krb5_kt_close");
-
- ret = krb5_cc_gen_new(context, &krb5_mcc_ops, cache);
- if(ret) krb5_err(context, 1, ret, "krb5_cc_gen_new");
+
+ ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, cache);
+ if(ret) krb5_err(context, 1, ret, "krb5_cc_new_unique");
ret = krb5_cc_initialize(context, *cache, client);
if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");
@@ -486,27 +199,21 @@ get_creds(krb5_context context, krb5_ccache *cache)
enum hprop_source {
HPROP_HEIMDAL = 1,
- HPROP_KRB4_DUMP,
- HPROP_KASERVER,
HPROP_MIT_DUMP
};
-#define IS_TYPE_V4(X) ((X) == HPROP_KRB4_DUMP || (X) == HPROP_KASERVER)
-
struct {
int type;
const char *name;
} types[] = {
{ HPROP_HEIMDAL, "heimdal" },
- { HPROP_KRB4_DUMP, "krb4-dump" },
- { HPROP_KASERVER, "kaserver" },
{ HPROP_MIT_DUMP, "mit-dump" }
};
static int
parse_source_type(const char *s)
{
- int i;
+ size_t i;
for(i = 0; i < sizeof(types) / sizeof(types[0]); i++) {
if(strstr(types[i].name, s) == types[i].name)
return types[i].type;
@@ -524,22 +231,10 @@ iterate (krb5_context context,
int ret;
switch(type) {
- case HPROP_KRB4_DUMP:
- ret = v4_prop_dump(pd, database_name);
- if(ret)
- krb5_warnx(context, "v4_prop_dump: %s",
- krb5_get_err_text(context, ret));
- break;
- case HPROP_KASERVER:
- ret = ka_dump(pd, database_name);
- if(ret)
- krb5_warn(context, ret, "ka_dump");
- break;
case HPROP_MIT_DUMP:
ret = mit_prop_dump(pd, database_name);
if (ret)
- krb5_warnx(context, "mit_prop_dump: %s",
- krb5_get_err_text(context, ret));
+ krb5_warn(context, ret, "mit_prop_dump");
break;
case HPROP_HEIMDAL:
ret = hdb_foreach(context, db, HDB_F_DECRYPT, v5_prop, pd);
@@ -563,7 +258,7 @@ dump_database (krb5_context context, int type,
pd.context = context;
pd.auth_context = NULL;
pd.sock = STDOUT_FILENO;
-
+
ret = iterate (context, database_name, db, type, &pd);
if (ret)
krb5_errx(context, 1, "iterate failure");
@@ -577,7 +272,7 @@ dump_database (krb5_context context, int type,
static int
propagate_database (krb5_context context, int type,
- const char *database_name,
+ const char *database_name,
HDB *db, krb5_ccache ccache,
int optidx, int argc, char **argv)
{
@@ -596,8 +291,8 @@ propagate_database (krb5_context context, int type,
port = strchr(host, ':');
if(port == NULL) {
- snprintf(portstr, sizeof(portstr), "%u",
- ntohs(krb5_getportbyname (context, "hprop", "tcp",
+ snprintf(portstr, sizeof(portstr), "%u",
+ ntohs(krb5_getportbyname (context, "hprop", "tcp",
HPROP_PORT)));
port = portstr;
} else
@@ -622,11 +317,10 @@ propagate_database (krb5_context context, int type,
if (local_realm) {
krb5_realm my_realm;
krb5_get_default_realm(context,&my_realm);
-
- free (*krb5_princ_realm(context, server));
- krb5_princ_set_realm(context,server,&my_realm);
+ krb5_principal_set_realm(context,server,my_realm);
+ krb5_xfree(my_realm);
}
-
+
auth_context = NULL;
ret = krb5_sendauth(context,
&auth_context,
@@ -650,7 +344,7 @@ propagate_database (krb5_context context, int type,
close(fd);
goto next_host;
}
-
+
pd.context = context;
pd.auth_context = auth_context;
pd.sock = fd;
@@ -677,7 +371,7 @@ propagate_database (krb5_context context, int type,
goto next_host;
} else
krb5_data_free (&data);
-
+
next_host:
krb5_auth_con_free(context, auth_context);
close(fd);
@@ -705,7 +399,7 @@ main(int argc, char **argv)
if(help_flag)
usage(0);
-
+
if(version_flag){
print_version(NULL);
exit(0);
@@ -715,25 +409,16 @@ main(int argc, char **argv)
if(ret)
exit(1);
+ /* We may be reading an old database encrypted with a DES master key. */
+ ret = krb5_allow_weak_crypto(context, 1);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_allow_weak_crypto");
+
if(local_realm)
krb5_set_default_realm(context, local_realm);
- if(v4_realm == NULL) {
- ret = krb5_get_default_realm(context, &v4_realm);
- if(ret)
- krb5_err(context, 1, ret, "krb5_get_default_realm");
- }
-
- if(afs_cell == NULL) {
- afs_cell = strdup(v4_realm);
- if(afs_cell == NULL)
- krb5_errx(context, 1, "out of memory");
- strlwr(afs_cell);
- }
-
-
if(encrypt_flag && decrypt_flag)
- krb5_errx(context, 1,
+ krb5_errx(context, 1,
"only one of `--encrypt' and `--decrypt' is meaningful");
if(source_type != NULL) {
@@ -745,7 +430,7 @@ main(int argc, char **argv)
if(!to_stdout)
get_creds(context, &ccache);
-
+
if(decrypt_flag || encrypt_flag) {
ret = hdb_read_master_key(context, mkeyfile, &mkey5);
if(ret && ret != ENOENT)
@@ -753,26 +438,8 @@ main(int argc, char **argv)
if(ret)
krb5_errx(context, 1, "No master key file found");
}
-
- if (IS_TYPE_V4(type) && v4_realm == NULL)
- krb5_errx(context, 1, "Its a Kerberos 4 database "
- "but no realm configured");
switch(type) {
- case HPROP_KASERVER:
- if (database == NULL)
- database = DEFAULT_DATABASE;
- ka_use_null_salt = krb5_config_get_bool_default(context, NULL, FALSE,
- "hprop",
- "afs_uses_null_salt",
- NULL);
-
- break;
- case HPROP_KRB4_DUMP:
- if (database == NULL)
- krb5_errx(context, 1, "no dump file specified");
-
- break;
case HPROP_MIT_DUMP:
if (database == NULL)
krb5_errx(context, 1, "no dump file specified");
@@ -793,12 +460,12 @@ main(int argc, char **argv)
if (to_stdout)
exit_code = dump_database (context, type, database, db);
else
- exit_code = propagate_database (context, type, database,
+ exit_code = propagate_database (context, type, database,
db, ccache, optidx, argc, argv);
if(ccache != NULL)
krb5_cc_destroy(context, ccache);
-
+
if(db != NULL)
(*db->hdb_destroy)(context, db);
diff --git a/crypto/heimdal/kdc/hprop.h b/crypto/heimdal/kdc/hprop.h
index d43d04c..59fe8bc 100644
--- a/crypto/heimdal/kdc/hprop.h
+++ b/crypto/heimdal/kdc/hprop.h
@@ -1,37 +1,37 @@
/*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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: hprop.h 16378 2005-12-12 12:40:12Z lha $ */
+/* $Id$ */
#ifndef __HPROP_H__
#define __HPROP_H__
diff --git a/crypto/heimdal/kdc/hpropd.8 b/crypto/heimdal/kdc/hpropd.8
index 74a3dad..31b44e2 100644
--- a/crypto/heimdal/kdc/hpropd.8
+++ b/crypto/heimdal/kdc/hpropd.8
@@ -1,35 +1,35 @@
-.\" Copyright (c) 1997, 2000 - 2003 Kungliga Tekniska Högskolan
-.\" (Royal Institute of Technology, Stockholm, Sweden).
-.\" All rights reserved.
+.\" Copyright (c) 1997, 2000 - 2003 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:
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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: hpropd.8 14381 2004-12-10 09:44:05Z lha $
+.\" 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$
.\"
.Dd August 27, 1997
.Dt HPROPD 8
@@ -41,17 +41,17 @@
.Nm
.Bk -words
.Oo Fl d Ar file \*(Ba Xo
-.Fl -database= Ns Ar file
+.Fl Fl database= Ns Ar file
.Xc
.Oc
-.Op Fl n | Fl -stdin
-.Op Fl -print
-.Op Fl i | Fl -no-inetd
+.Op Fl n | Fl Fl stdin
+.Op Fl Fl print
+.Op Fl i | Fl Fl no-inetd
.Oo Fl k Ar keytab \*(Ba Xo
-.Fl -keytab= Ns Ar keytab
+.Fl Fl keytab= Ns Ar keytab
.Xc
.Oc
-.Op Fl 4 | Fl -v4dump
+.Op Fl 4 | Fl Fl v4dump
.Ek
.Sh DESCRIPTION
.Nm
@@ -73,34 +73,17 @@ are accepted.
.Pp
Options supported:
.Bl -tag -width Ds
-.It Xo
-.Fl d Ar file ,
-.Fl -database= Ns Ar file
-.Xc
+.It Fl d Ar file , Fl Fl database= Ns Ar file
database
-.It Xo
-.Fl n ,
-.Fl -stdin
-.Xc
+.It Fl n , Fl Fl stdin
read from stdin
-.It Xo
-.Fl -print
-.Xc
+.It Fl Fl print
print dump to stdout
-.It Xo
-.Fl i ,
-.Fl -no-inetd
-.Xc
+.It Fl i , Fl Fl no-inetd
not started from inetd
-.It Xo
-.Fl k Ar keytab ,
-.Fl -keytab= Ns Ar keytab
-.Xc
+.It Fl k Ar keytab , Fl Fl keytab= Ns Ar keytab
keytab to use for authentication
-.It Xo
-.Fl 4 ,
-.Fl -v4dump
-.Xc
+.It Fl 4 , Fl Fl v4dump
create v4 type DB
.El
.Sh SEE ALSO
diff --git a/crypto/heimdal/kdc/hpropd.c b/crypto/heimdal/kdc/hpropd.c
index 12a9766..75b26a1 100644
--- a/crypto/heimdal/kdc/hpropd.c
+++ b/crypto/heimdal/kdc/hpropd.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2006 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "hprop.h"
-RCSID("$Id: hpropd.c 22245 2007-12-08 23:48:52Z lha $");
-
static int inetd_flag = -1;
static int help_flag;
static int version_flag;
@@ -45,18 +43,21 @@ static char *local_realm;
static char *ktname = NULL;
struct getargs args[] = {
- { "database", 'd', arg_string, &database, "database", "file" },
- { "stdin", 'n', arg_flag, &from_stdin, "read from stdin" },
- { "print", 0, arg_flag, &print_dump, "print dump to stdout" },
+ { "database", 'd', arg_string, rk_UNCONST(&database), "database", "file" },
+ { "stdin", 'n', arg_flag, &from_stdin, "read from stdin", NULL },
+ { "print", 0, arg_flag, &print_dump, "print dump to stdout", NULL },
+#ifdef SUPPORT_INETD
{ "inetd", 'i', arg_negative_flag, &inetd_flag,
- "Not started from inetd" },
+ "Not started from inetd", NULL },
+#endif
{ "keytab", 'k', arg_string, &ktname, "keytab to use for authentication", "keytab" },
- { "realm", 'r', arg_string, &local_realm, "realm to use" },
+ { "realm", 'r', arg_string, &local_realm, "realm to use", NULL },
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
{ "help", 'h', arg_flag, &help_flag, NULL, NULL}
};
static int num_args = sizeof(args) / sizeof(args[0]);
+static char unparseable_name[] = "unparseable name";
static void
usage(int ret)
@@ -74,8 +75,8 @@ main(int argc, char **argv)
krb5_principal c1, c2;
krb5_authenticator authent;
krb5_keytab keytab;
- int fd;
- HDB *db;
+ krb5_socket_t sock = rk_INVALID_SOCKET;
+ HDB *db = NULL;
int optidx = 0;
char *tmp_db;
krb5_log_facility *fac;
@@ -89,22 +90,22 @@ main(int argc, char **argv)
ret = krb5_openlog(context, "hpropd", &fac);
if(ret)
- ;
+ errx(1, "krb5_openlog");
krb5_set_warn_dest(context, fac);
-
+
if(getarg(args, num_args, argc, argv, &optidx))
usage(1);
if(local_realm != NULL)
krb5_set_default_realm(context, local_realm);
-
+
if(help_flag)
usage(0);
if(version_flag) {
print_version(NULL);
exit(0);
}
-
+
argc -= optidx;
argv += optidx;
@@ -114,9 +115,9 @@ main(int argc, char **argv)
if (database == NULL)
database = hdb_default_db(context);
- if(from_stdin)
- fd = STDIN_FILENO;
- else {
+ if(from_stdin) {
+ sock = STDIN_FILENO;
+ } else {
struct sockaddr_storage ss;
struct sockaddr *sa = (struct sockaddr *)&ss;
socklen_t sin_len = sizeof(ss);
@@ -124,19 +125,24 @@ main(int argc, char **argv)
krb5_ticket *ticket;
char *server;
- fd = STDIN_FILENO;
+ sock = STDIN_FILENO;
+#ifdef SUPPORT_INETD
if (inetd_flag == -1) {
- if (getpeername (fd, sa, &sin_len) < 0)
+ if (getpeername (sock, sa, &sin_len) < 0) {
inetd_flag = 0;
- else
+ } else {
inetd_flag = 1;
+ }
}
+#else
+ inetd_flag = 0;
+#endif
if (!inetd_flag) {
mini_inetd (krb5_getportbyname (context, "hprop", "tcp",
- HPROP_PORT));
+ HPROP_PORT), &sock);
}
sin_len = sizeof(ss);
- if(getpeername(fd, sa, &sin_len) < 0)
+ if(getpeername(sock, sa, &sin_len) < 0)
krb5_err(context, 1, errno, "getpeername");
if (inet_ntop(sa->sa_family,
@@ -147,7 +153,7 @@ main(int argc, char **argv)
sizeof(addr_name));
krb5_log(context, fac, 0, "Connection from %s", addr_name);
-
+
ret = krb5_kt_register(context, &hdb_kt_ops);
if(ret)
krb5_err(context, 1, ret, "krb5_kt_register");
@@ -162,11 +168,11 @@ main(int argc, char **argv)
krb5_err (context, 1, ret, "krb5_kt_default");
}
- ret = krb5_recvauth(context, &ac, &fd, HPROP_VERSION, NULL,
+ ret = krb5_recvauth(context, &ac, &sock, HPROP_VERSION, NULL,
0, keytab, &ticket);
if(ret)
krb5_err(context, 1, ret, "krb5_recvauth");
-
+
ret = krb5_unparse_name(context, ticket->server, &server);
if (ret)
krb5_err(context, 1, ret, "krb5_unparse_name");
@@ -179,17 +185,17 @@ main(int argc, char **argv)
ret = krb5_auth_con_getauthenticator(context, ac, &authent);
if(ret)
krb5_err(context, 1, ret, "krb5_auth_con_getauthenticator");
-
+
ret = krb5_make_principal(context, &c1, NULL, "kadmin", "hprop", NULL);
if(ret)
krb5_err(context, 1, ret, "krb5_make_principal");
- _krb5_principalname2krb5_principal(context, &c2,
+ _krb5_principalname2krb5_principal(context, &c2,
authent->cname, authent->crealm);
if(!krb5_principal_compare(context, c1, c2)) {
char *s;
ret = krb5_unparse_name(context, c2, &s);
if (ret)
- s = "unparseable name";
+ s = unparseable_name;
krb5_errx(context, 1, "Unauthorized connection from %s", s);
}
krb5_free_principal(context, c1);
@@ -199,7 +205,7 @@ main(int argc, char **argv)
if(ret)
krb5_err(context, 1, ret, "krb5_kt_close");
}
-
+
if(!print_dump) {
asprintf(&tmp_db, "%s~", database);
@@ -217,11 +223,11 @@ main(int argc, char **argv)
hdb_entry_ex entry;
if(from_stdin) {
- ret = krb5_read_message(context, &fd, &data);
+ ret = krb5_read_message(context, &sock, &data);
if(ret != 0 && ret != HEIM_ERR_EOF)
krb5_err(context, 1, ret, "krb5_read_message");
} else {
- ret = krb5_read_priv_message(context, ac, &fd, &data);
+ ret = krb5_read_priv_message(context, ac, &sock, &data);
if(ret)
krb5_err(context, 1, ret, "krb5_read_priv_message");
}
@@ -230,15 +236,15 @@ main(int argc, char **argv)
if(!from_stdin) {
data.data = NULL;
data.length = 0;
- krb5_write_priv_message(context, ac, &fd, &data);
+ krb5_write_priv_message(context, ac, &sock, &data);
}
if(!print_dump) {
- ret = db->hdb_rename(context, db, database);
- if(ret)
- krb5_err(context, 1, ret, "db_rename");
ret = db->hdb_close(context, db);
if(ret)
krb5_err(context, 1, ret, "db_close");
+ ret = db->hdb_rename(context, db, database);
+ if(ret)
+ krb5_err(context, 1, ret, "db_rename");
}
break;
}
@@ -255,10 +261,10 @@ main(int argc, char **argv)
char *s;
ret = krb5_unparse_name(context, entry.entry.principal, &s);
if (ret)
- s = strdup("unparseable name");
+ s = strdup(unparseable_name);
krb5_warnx(context, "Entry exists: %s", s);
free(s);
- } else if(ret)
+ } else if(ret)
krb5_err(context, 1, ret, "db_store");
else
nprincs++;
@@ -267,5 +273,9 @@ main(int argc, char **argv)
}
if (!print_dump)
krb5_log(context, fac, 0, "Received %d principals", nprincs);
+
+ if (inetd_flag == 0)
+ rk_closesocket(sock);
+
exit(0);
}
diff --git a/crypto/heimdal/kdc/kadb.h b/crypto/heimdal/kdc/kadb.h
deleted file mode 100644
index 4b59abe..0000000
--- a/crypto/heimdal/kdc/kadb.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 1998 - 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.
- */
-
-/* $Id: kadb.h 7997 2000-03-03 12:36:26Z assar $ */
-
-#ifndef __kadb_h__
-#define __kadb_h__
-
-#define HASHSIZE 8191
-
-struct ka_header {
- int32_t version1; /* file format version, should
- match version2 */
- int32_t size;
- int32_t free_ptr;
- int32_t eof_ptr;
- int32_t kvno_ptr;
- int32_t stats[8];
- int32_t admin_accounts;
- int32_t special_keys_version;
- int32_t hashsize; /* allocated size of hash */
- int32_t hash[HASHSIZE];
- int32_t version2;
-};
-
-struct ka_entry {
- int32_t flags; /* see below */
- int32_t next; /* next in hash list */
- int32_t valid_end; /* expiration date */
- int32_t mod_time; /* time last modified */
- int32_t mod_ptr; /* pointer to modifier */
- int32_t pw_change; /* last pw change */
- int32_t max_life; /* max ticket life */
- int32_t kvno;
- int32_t foo2[2]; /* huh? */
- char name[64];
- char instance[64];
- char key[8];
- u_char pw_expire; /* # days before password expires */
- u_char spare;
- u_char attempts;
- u_char locktime;
-};
-
-#define KAFNORMAL (1<<0)
-#define KAFADMIN (1<<2) /* an administrator */
-#define KAFNOTGS (1<<3) /* ! allow principal to get or use TGT */
-#define KAFNOSEAL (1<<5) /* ! allow principal as server in GetTicket */
-#define KAFNOCPW (1<<6) /* ! allow principal to change its own key */
-#define KAFSPECIAL (1<<8) /* set if special AuthServer principal */
-
-#define DEFAULT_DATABASE "/usr/afs/db/kaserver.DB0"
-
-#endif /* __kadb_h__ */
diff --git a/crypto/heimdal/kdc/kaserver.c b/crypto/heimdal/kdc/kaserver.c
deleted file mode 100644
index 27f497e..0000000
--- a/crypto/heimdal/kdc/kaserver.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * Copyright (c) 1997 - 2005 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 "kdc_locl.h"
-
-RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $");
-
-#include <krb5-v4compat.h>
-#include <rx.h>
-
-#define KA_AUTHENTICATION_SERVICE 731
-#define KA_TICKET_GRANTING_SERVICE 732
-#define KA_MAINTENANCE_SERVICE 733
-
-#define AUTHENTICATE_OLD 1
-#define CHANGEPASSWORD 2
-#define GETTICKET_OLD 3
-#define SETPASSWORD 4
-#define SETFIELDS 5
-#define CREATEUSER 6
-#define DELETEUSER 7
-#define GETENTRY 8
-#define LISTENTRY 9
-#define GETSTATS 10
-#define DEBUG 11
-#define GETPASSWORD 12
-#define GETRANDOMKEY 13
-#define AUTHENTICATE 21
-#define AUTHENTICATE_V2 22
-#define GETTICKET 23
-
-/* XXX - Where do we get these? */
-
-#define RXGEN_OPCODE (-455)
-
-#define KADATABASEINCONSISTENT (180480L)
-#define KAEXIST (180481L)
-#define KAIO (180482L)
-#define KACREATEFAIL (180483L)
-#define KANOENT (180484L)
-#define KAEMPTY (180485L)
-#define KABADNAME (180486L)
-#define KABADINDEX (180487L)
-#define KANOAUTH (180488L)
-#define KAANSWERTOOLONG (180489L)
-#define KABADREQUEST (180490L)
-#define KAOLDINTERFACE (180491L)
-#define KABADARGUMENT (180492L)
-#define KABADCMD (180493L)
-#define KANOKEYS (180494L)
-#define KAREADPW (180495L)
-#define KABADKEY (180496L)
-#define KAUBIKINIT (180497L)
-#define KAUBIKCALL (180498L)
-#define KABADPROTOCOL (180499L)
-#define KANOCELLS (180500L)
-#define KANOCELL (180501L)
-#define KATOOMANYUBIKS (180502L)
-#define KATOOMANYKEYS (180503L)
-#define KABADTICKET (180504L)
-#define KAUNKNOWNKEY (180505L)
-#define KAKEYCACHEINVALID (180506L)
-#define KABADSERVER (180507L)
-#define KABADUSER (180508L)
-#define KABADCPW (180509L)
-#define KABADCREATE (180510L)
-#define KANOTICKET (180511L)
-#define KAASSOCUSER (180512L)
-#define KANOTSPECIAL (180513L)
-#define KACLOCKSKEW (180514L)
-#define KANORECURSE (180515L)
-#define KARXFAIL (180516L)
-#define KANULLPASSWORD (180517L)
-#define KAINTERNALERROR (180518L)
-#define KAPWEXPIRED (180519L)
-#define KAREUSED (180520L)
-#define KATOOSOON (180521L)
-#define KALOCKED (180522L)
-
-
-static krb5_error_code
-decode_rx_header (krb5_storage *sp,
- struct rx_header *h)
-{
- krb5_error_code ret;
-
- ret = krb5_ret_uint32(sp, &h->epoch);
- if (ret) return ret;
- ret = krb5_ret_uint32(sp, &h->connid);
- if (ret) return ret;
- ret = krb5_ret_uint32(sp, &h->callid);
- if (ret) return ret;
- ret = krb5_ret_uint32(sp, &h->seqno);
- if (ret) return ret;
- ret = krb5_ret_uint32(sp, &h->serialno);
- if (ret) return ret;
- ret = krb5_ret_uint8(sp, &h->type);
- if (ret) return ret;
- ret = krb5_ret_uint8(sp, &h->flags);
- if (ret) return ret;
- ret = krb5_ret_uint8(sp, &h->status);
- if (ret) return ret;
- ret = krb5_ret_uint8(sp, &h->secindex);
- if (ret) return ret;
- ret = krb5_ret_uint16(sp, &h->reserved);
- if (ret) return ret;
- ret = krb5_ret_uint16(sp, &h->serviceid);
- if (ret) return ret;
-
- return 0;
-}
-
-static krb5_error_code
-encode_rx_header (struct rx_header *h,
- krb5_storage *sp)
-{
- krb5_error_code ret;
-
- ret = krb5_store_uint32(sp, h->epoch);
- if (ret) return ret;
- ret = krb5_store_uint32(sp, h->connid);
- if (ret) return ret;
- ret = krb5_store_uint32(sp, h->callid);
- if (ret) return ret;
- ret = krb5_store_uint32(sp, h->seqno);
- if (ret) return ret;
- ret = krb5_store_uint32(sp, h->serialno);
- if (ret) return ret;
- ret = krb5_store_uint8(sp, h->type);
- if (ret) return ret;
- ret = krb5_store_uint8(sp, h->flags);
- if (ret) return ret;
- ret = krb5_store_uint8(sp, h->status);
- if (ret) return ret;
- ret = krb5_store_uint8(sp, h->secindex);
- if (ret) return ret;
- ret = krb5_store_uint16(sp, h->reserved);
- if (ret) return ret;
- ret = krb5_store_uint16(sp, h->serviceid);
- if (ret) return ret;
-
- return 0;
-}
-
-static void
-init_reply_header (struct rx_header *hdr,
- struct rx_header *reply_hdr,
- u_char type,
- u_char flags)
-{
- reply_hdr->epoch = hdr->epoch;
- reply_hdr->connid = hdr->connid;
- reply_hdr->callid = hdr->callid;
- reply_hdr->seqno = 1;
- reply_hdr->serialno = 1;
- reply_hdr->type = type;
- reply_hdr->flags = flags;
- reply_hdr->status = 0;
- reply_hdr->secindex = 0;
- reply_hdr->reserved = 0;
- reply_hdr->serviceid = hdr->serviceid;
-}
-
-/*
- * Create an error `reply´ using for the packet `hdr' with the error
- * `error´ code.
- */
-static void
-make_error_reply (struct rx_header *hdr,
- uint32_t error,
- krb5_data *reply)
-
-{
- struct rx_header reply_hdr;
- krb5_error_code ret;
- krb5_storage *sp;
-
- init_reply_header (hdr, &reply_hdr, HT_ABORT, HF_LAST);
- sp = krb5_storage_emem();
- if (sp == NULL)
- return;
- ret = encode_rx_header (&reply_hdr, sp);
- if (ret)
- return;
- krb5_store_int32(sp, error);
- krb5_storage_to_data (sp, reply);
- krb5_storage_free (sp);
-}
-
-static krb5_error_code
-krb5_ret_xdr_data(krb5_storage *sp,
- krb5_data *data)
-{
- int ret;
- int size;
- ret = krb5_ret_int32(sp, &size);
- if(ret)
- return ret;
- if(size < 0)
- return ERANGE;
- data->length = size;
- if (size) {
- u_char foo[4];
- size_t pad = (4 - size % 4) % 4;
-
- data->data = malloc(size);
- if (data->data == NULL)
- return ENOMEM;
- ret = krb5_storage_read(sp, data->data, size);
- if(ret != size)
- return (ret < 0)? errno : KRB5_CC_END;
- if (pad) {
- ret = krb5_storage_read(sp, foo, pad);
- if (ret != pad)
- return (ret < 0)? errno : KRB5_CC_END;
- }
- } else
- data->data = NULL;
- return 0;
-}
-
-static krb5_error_code
-krb5_store_xdr_data(krb5_storage *sp,
- krb5_data data)
-{
- u_char zero[4] = {0, 0, 0, 0};
- int ret;
- size_t pad;
-
- ret = krb5_store_int32(sp, data.length);
- if(ret < 0)
- return ret;
- ret = krb5_storage_write(sp, data.data, data.length);
- if(ret != data.length){
- if(ret < 0)
- return errno;
- return KRB5_CC_END;
- }
- pad = (4 - data.length % 4) % 4;
- if (pad) {
- ret = krb5_storage_write(sp, zero, pad);
- if (ret != pad) {
- if (ret < 0)
- return errno;
- return KRB5_CC_END;
- }
- }
- return 0;
-}
-
-
-static krb5_error_code
-create_reply_ticket (krb5_context context,
- struct rx_header *hdr,
- Key *skey,
- char *name, char *instance, char *realm,
- struct sockaddr_in *addr,
- int life,
- int kvno,
- int32_t max_seq_len,
- const char *sname, const char *sinstance,
- uint32_t challenge,
- const char *label,
- krb5_keyblock *key,
- krb5_data *reply)
-{
- krb5_error_code ret;
- krb5_data ticket;
- krb5_keyblock session;
- krb5_storage *sp;
- krb5_data enc_data;
- struct rx_header reply_hdr;
- char zero[8];
- size_t pad;
- unsigned fyrtiosjuelva;
-
- /* create the ticket */
-
- krb5_generate_random_keyblock(context, ETYPE_DES_PCBC_NONE, &session);
-
- _krb5_krb_create_ticket(context,
- 0,
- name,
- instance,
- realm,
- addr->sin_addr.s_addr,
- &session,
- life,
- kdc_time,
- sname,
- sinstance,
- &skey->key,
- &ticket);
-
- /* create the encrypted part of the reply */
- sp = krb5_storage_emem ();
- krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva));
- fyrtiosjuelva &= 0xffffffff;
- krb5_store_int32 (sp, fyrtiosjuelva);
- krb5_store_int32 (sp, challenge);
- krb5_storage_write (sp, session.keyvalue.data, 8);
- krb5_free_keyblock_contents(context, &session);
- krb5_store_int32 (sp, kdc_time);
- krb5_store_int32 (sp, kdc_time + _krb5_krb_life_to_time (0, life));
- krb5_store_int32 (sp, kvno);
- krb5_store_int32 (sp, ticket.length);
- krb5_store_stringz (sp, name);
- krb5_store_stringz (sp, instance);
-#if 1 /* XXX - Why shouldn't the realm go here? */
- krb5_store_stringz (sp, "");
-#else
- krb5_store_stringz (sp, realm);
-#endif
- krb5_store_stringz (sp, sname);
- krb5_store_stringz (sp, sinstance);
- krb5_storage_write (sp, ticket.data, ticket.length);
- krb5_storage_write (sp, label, strlen(label));
-
- /* pad to DES block */
- memset (zero, 0, sizeof(zero));
- pad = (8 - krb5_storage_seek (sp, 0, SEEK_CUR) % 8) % 8;
- krb5_storage_write (sp, zero, pad);
-
- krb5_storage_to_data (sp, &enc_data);
- krb5_storage_free (sp);
-
- if (enc_data.length > max_seq_len) {
- krb5_data_free (&enc_data);
- make_error_reply (hdr, KAANSWERTOOLONG, reply);
- return 0;
- }
-
- /* encrypt it */
- {
- DES_key_schedule schedule;
- DES_cblock deskey;
-
- memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
- DES_set_key (&deskey, &schedule);
- DES_pcbc_encrypt (enc_data.data,
- enc_data.data,
- enc_data.length,
- &schedule,
- &deskey,
- DES_ENCRYPT);
- memset (&schedule, 0, sizeof(schedule));
- memset (&deskey, 0, sizeof(deskey));
- }
-
- /* create the reply packet */
- init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST);
- sp = krb5_storage_emem ();
- ret = encode_rx_header (&reply_hdr, sp);
- krb5_store_int32 (sp, max_seq_len);
- krb5_store_xdr_data (sp, enc_data);
- krb5_data_free (&enc_data);
- krb5_storage_to_data (sp, reply);
- krb5_storage_free (sp);
- return 0;
-}
-
-static krb5_error_code
-unparse_auth_args (krb5_storage *sp,
- char **name,
- char **instance,
- time_t *start_time,
- time_t *end_time,
- krb5_data *request,
- int32_t *max_seq_len)
-{
- krb5_data data;
- int32_t tmp;
-
- krb5_ret_xdr_data (sp, &data);
- *name = malloc(data.length + 1);
- if (*name == NULL)
- return ENOMEM;
- memcpy (*name, data.data, data.length);
- (*name)[data.length] = '\0';
- krb5_data_free (&data);
-
- krb5_ret_xdr_data (sp, &data);
- *instance = malloc(data.length + 1);
- if (*instance == NULL) {
- free (*name);
- return ENOMEM;
- }
- memcpy (*instance, data.data, data.length);
- (*instance)[data.length] = '\0';
- krb5_data_free (&data);
-
- krb5_ret_int32 (sp, &tmp);
- *start_time = tmp;
- krb5_ret_int32 (sp, &tmp);
- *end_time = tmp;
- krb5_ret_xdr_data (sp, request);
- krb5_ret_int32 (sp, max_seq_len);
- /* ignore the rest */
- return 0;
-}
-
-static void
-do_authenticate (krb5_context context,
- krb5_kdc_configuration *config,
- struct rx_header *hdr,
- krb5_storage *sp,
- struct sockaddr_in *addr,
- const char *from,
- krb5_data *reply)
-{
- krb5_error_code ret;
- char *name = NULL;
- char *instance = NULL;
- time_t start_time;
- time_t end_time;
- krb5_data request;
- int32_t max_seq_len;
- hdb_entry_ex *client_entry = NULL;
- hdb_entry_ex *server_entry = NULL;
- Key *ckey = NULL;
- Key *skey = NULL;
- krb5_storage *reply_sp;
- time_t max_life;
- uint8_t life;
- int32_t chal;
- char client_name[256];
- char server_name[256];
-
- krb5_data_zero (&request);
-
- ret = unparse_auth_args (sp, &name, &instance, &start_time, &end_time,
- &request, &max_seq_len);
- if (ret != 0 || request.length < 8) {
- make_error_reply (hdr, KABADREQUEST, reply);
- goto out;
- }
-
- snprintf (client_name, sizeof(client_name), "%s.%s@%s",
- name, instance, config->v4_realm);
- snprintf (server_name, sizeof(server_name), "%s.%s@%s",
- "krbtgt", config->v4_realm, config->v4_realm);
-
- kdc_log(context, config, 0, "AS-REQ (kaserver) %s from %s for %s",
- client_name, from, server_name);
-
- ret = _kdc_db_fetch4 (context, config, name, instance,
- config->v4_realm, HDB_F_GET_CLIENT,
- &client_entry);
- if (ret) {
- kdc_log(context, config, 0, "Client not found in database: %s: %s",
- client_name, krb5_get_err_text(context, ret));
- make_error_reply (hdr, KANOENT, reply);
- goto out;
- }
-
- ret = _kdc_db_fetch4 (context, config, "krbtgt",
- config->v4_realm, config->v4_realm,
- HDB_F_GET_KRBTGT, &server_entry);
- if (ret) {
- kdc_log(context, config, 0, "Server not found in database: %s: %s",
- server_name, krb5_get_err_text(context, ret));
- make_error_reply (hdr, KANOENT, reply);
- goto out;
- }
-
- ret = _kdc_check_flags (context, config,
- client_entry, client_name,
- server_entry, server_name,
- TRUE);
- if (ret) {
- make_error_reply (hdr, KAPWEXPIRED, reply);
- goto out;
- }
-
- /* find a DES key */
- ret = _kdc_get_des_key(context, client_entry, FALSE, TRUE, &ckey);
- if(ret){
- kdc_log(context, config, 0, "no suitable DES key for client");
- make_error_reply (hdr, KANOKEYS, reply);
- goto out;
- }
-
- /* find a DES key */
- ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey);
- if(ret){
- kdc_log(context, config, 0, "no suitable DES key for server");
- make_error_reply (hdr, KANOKEYS, reply);
- goto out;
- }
-
- {
- DES_cblock key;
- DES_key_schedule schedule;
-
- /* try to decode the `request' */
- memcpy (&key, ckey->key.keyvalue.data, sizeof(key));
- DES_set_key (&key, &schedule);
- DES_pcbc_encrypt (request.data,
- request.data,
- request.length,
- &schedule,
- &key,
- DES_DECRYPT);
- memset (&schedule, 0, sizeof(schedule));
- memset (&key, 0, sizeof(key));
- }
-
- /* check for the magic label */
- if (memcmp ((char *)request.data + 4, "gTGS", 4) != 0) {
- kdc_log(context, config, 0, "preauth failed for %s", client_name);
- make_error_reply (hdr, KABADREQUEST, reply);
- goto out;
- }
-
- reply_sp = krb5_storage_from_mem (request.data, 4);
- krb5_ret_int32 (reply_sp, &chal);
- krb5_storage_free (reply_sp);
-
- if (abs(chal - kdc_time) > context->max_skew) {
- make_error_reply (hdr, KACLOCKSKEW, reply);
- goto out;
- }
-
- /* life */
- max_life = end_time - kdc_time;
- /* end_time - kdc_time can sometimes be non-positive due to slight
- time skew between client and server. Let's make sure it is postive */
- if(max_life < 1)
- max_life = 1;
- if (client_entry->entry.max_life)
- max_life = min(max_life, *client_entry->entry.max_life);
- if (server_entry->entry.max_life)
- max_life = min(max_life, *server_entry->entry.max_life);
-
- life = krb_time_to_life(kdc_time, kdc_time + max_life);
-
- create_reply_ticket (context,
- hdr, skey,
- name, instance, config->v4_realm,
- addr, life, server_entry->entry.kvno,
- max_seq_len,
- "krbtgt", config->v4_realm,
- chal + 1, "tgsT",
- &ckey->key, reply);
-
- out:
- if (request.length) {
- memset (request.data, 0, request.length);
- krb5_data_free (&request);
- }
- if (name)
- free (name);
- if (instance)
- free (instance);
- if (client_entry)
- _kdc_free_ent (context, client_entry);
- if (server_entry)
- _kdc_free_ent (context, server_entry);
-}
-
-static krb5_error_code
-unparse_getticket_args (krb5_storage *sp,
- int *kvno,
- char **auth_domain,
- krb5_data *ticket,
- char **name,
- char **instance,
- krb5_data *times,
- int32_t *max_seq_len)
-{
- krb5_data data;
- int32_t tmp;
-
- krb5_ret_int32 (sp, &tmp);
- *kvno = tmp;
-
- krb5_ret_xdr_data (sp, &data);
- *auth_domain = malloc(data.length + 1);
- if (*auth_domain == NULL)
- return ENOMEM;
- memcpy (*auth_domain, data.data, data.length);
- (*auth_domain)[data.length] = '\0';
- krb5_data_free (&data);
-
- krb5_ret_xdr_data (sp, ticket);
-
- krb5_ret_xdr_data (sp, &data);
- *name = malloc(data.length + 1);
- if (*name == NULL) {
- free (*auth_domain);
- return ENOMEM;
- }
- memcpy (*name, data.data, data.length);
- (*name)[data.length] = '\0';
- krb5_data_free (&data);
-
- krb5_ret_xdr_data (sp, &data);
- *instance = malloc(data.length + 1);
- if (*instance == NULL) {
- free (*auth_domain);
- free (*name);
- return ENOMEM;
- }
- memcpy (*instance, data.data, data.length);
- (*instance)[data.length] = '\0';
- krb5_data_free (&data);
-
- krb5_ret_xdr_data (sp, times);
-
- krb5_ret_int32 (sp, max_seq_len);
- /* ignore the rest */
- return 0;
-}
-
-static void
-do_getticket (krb5_context context,
- krb5_kdc_configuration *config,
- struct rx_header *hdr,
- krb5_storage *sp,
- struct sockaddr_in *addr,
- const char *from,
- krb5_data *reply)
-{
- krb5_error_code ret;
- int kvno;
- char *auth_domain = NULL;
- krb5_data aticket;
- char *name = NULL;
- char *instance = NULL;
- krb5_data times;
- int32_t max_seq_len;
- hdb_entry_ex *server_entry = NULL;
- hdb_entry_ex *client_entry = NULL;
- hdb_entry_ex *krbtgt_entry = NULL;
- Key *kkey = NULL;
- Key *skey = NULL;
- DES_cblock key;
- DES_key_schedule schedule;
- DES_cblock session;
- time_t max_life;
- int8_t life;
- time_t start_time, end_time;
- char server_name[256];
- char client_name[256];
- struct _krb5_krb_auth_data ad;
-
- krb5_data_zero (&aticket);
- krb5_data_zero (&times);
-
- memset(&ad, 0, sizeof(ad));
-
- unparse_getticket_args (sp, &kvno, &auth_domain, &aticket,
- &name, &instance, &times, &max_seq_len);
- if (times.length < 8) {
- make_error_reply (hdr, KABADREQUEST, reply);
- goto out;
-
- }
-
- snprintf (server_name, sizeof(server_name),
- "%s.%s@%s", name, instance, config->v4_realm);
-
- ret = _kdc_db_fetch4 (context, config, name, instance,
- config->v4_realm, HDB_F_GET_SERVER, &server_entry);
- if (ret) {
- kdc_log(context, config, 0, "Server not found in database: %s: %s",
- server_name, krb5_get_err_text(context, ret));
- make_error_reply (hdr, KANOENT, reply);
- goto out;
- }
-
- ret = _kdc_db_fetch4 (context, config, "krbtgt",
- config->v4_realm, config->v4_realm, HDB_F_GET_KRBTGT, &krbtgt_entry);
- if (ret) {
- kdc_log(context, config, 0,
- "Server not found in database: %s.%s@%s: %s",
- "krbtgt", config->v4_realm, config->v4_realm,
- krb5_get_err_text(context, ret));
- make_error_reply (hdr, KANOENT, reply);
- goto out;
- }
-
- /* find a DES key */
- ret = _kdc_get_des_key(context, krbtgt_entry, TRUE, TRUE, &kkey);
- if(ret){
- kdc_log(context, config, 0, "no suitable DES key for krbtgt");
- make_error_reply (hdr, KANOKEYS, reply);
- goto out;
- }
-
- /* find a DES key */
- ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey);
- if(ret){
- kdc_log(context, config, 0, "no suitable DES key for server");
- make_error_reply (hdr, KANOKEYS, reply);
- goto out;
- }
-
- /* decrypt the incoming ticket */
- memcpy (&key, kkey->key.keyvalue.data, sizeof(key));
-
- /* unpack the ticket */
- {
- char *sname = NULL;
- char *sinstance = NULL;
-
- ret = _krb5_krb_decomp_ticket(context, &aticket, &kkey->key,
- config->v4_realm, &sname,
- &sinstance, &ad);
- if (ret) {
- kdc_log(context, config, 0,
- "kaserver: decomp failed for %s.%s with %d",
- sname, sinstance, ret);
- make_error_reply (hdr, KABADTICKET, reply);
- goto out;
- }
-
- if (strcmp (sname, "krbtgt") != 0
- || strcmp (sinstance, config->v4_realm) != 0) {
- kdc_log(context, config, 0, "no TGT: %s.%s for %s.%s@%s",
- sname, sinstance,
- ad.pname, ad.pinst, ad.prealm);
- make_error_reply (hdr, KABADTICKET, reply);
- free(sname);
- free(sinstance);
- goto out;
- }
- free(sname);
- free(sinstance);
-
- if (kdc_time > _krb5_krb_life_to_time(ad.time_sec, ad.life)) {
- kdc_log(context, config, 0, "TGT expired: %s.%s@%s",
- ad.pname, ad.pinst, ad.prealm);
- make_error_reply (hdr, KABADTICKET, reply);
- goto out;
- }
- }
-
- snprintf (client_name, sizeof(client_name),
- "%s.%s@%s", ad.pname, ad.pinst, ad.prealm);
-
- kdc_log(context, config, 0, "TGS-REQ (kaserver) %s from %s for %s",
- client_name, from, server_name);
-
- ret = _kdc_db_fetch4 (context, config,
- ad.pname, ad.pinst, ad.prealm, HDB_F_GET_CLIENT,
- &client_entry);
- if(ret && ret != HDB_ERR_NOENTRY) {
- kdc_log(context, config, 0,
- "Client not found in database: (krb4) %s: %s",
- client_name, krb5_get_err_text(context, ret));
- make_error_reply (hdr, KANOENT, reply);
- goto out;
- }
- if (client_entry == NULL && strcmp(ad.prealm, config->v4_realm) == 0) {
- kdc_log(context, config, 0,
- "Local client not found in database: (krb4) "
- "%s", client_name);
- make_error_reply (hdr, KANOENT, reply);
- goto out;
- }
-
- ret = _kdc_check_flags (context, config,
- client_entry, client_name,
- server_entry, server_name,
- FALSE);
- if (ret) {
- make_error_reply (hdr, KAPWEXPIRED, reply);
- goto out;
- }
-
- /* decrypt the times */
- memcpy(&session, ad.session.keyvalue.data, sizeof(session));
- DES_set_key (&session, &schedule);
- DES_ecb_encrypt (times.data,
- times.data,
- &schedule,
- DES_DECRYPT);
- memset (&schedule, 0, sizeof(schedule));
- memset (&session, 0, sizeof(session));
-
- /* and extract them */
- {
- krb5_storage *tsp;
- int32_t tmp;
-
- tsp = krb5_storage_from_mem (times.data, times.length);
- krb5_ret_int32 (tsp, &tmp);
- start_time = tmp;
- krb5_ret_int32 (tsp, &tmp);
- end_time = tmp;
- krb5_storage_free (tsp);
- }
-
- /* life */
- max_life = end_time - kdc_time;
- /* end_time - kdc_time can sometimes be non-positive due to slight
- time skew between client and server. Let's make sure it is postive */
- if(max_life < 1)
- max_life = 1;
- if (krbtgt_entry->entry.max_life)
- max_life = min(max_life, *krbtgt_entry->entry.max_life);
- if (server_entry->entry.max_life)
- max_life = min(max_life, *server_entry->entry.max_life);
- /* if this is a cross realm request, the client_entry will likely
- be NULL */
- if (client_entry && client_entry->entry.max_life)
- max_life = min(max_life, *client_entry->entry.max_life);
-
- life = _krb5_krb_time_to_life(kdc_time, kdc_time + max_life);
-
- create_reply_ticket (context,
- hdr, skey,
- ad.pname, ad.pinst, ad.prealm,
- addr, life, server_entry->entry.kvno,
- max_seq_len,
- name, instance,
- 0, "gtkt",
- &ad.session, reply);
-
- out:
- _krb5_krb_free_auth_data(context, &ad);
- if (aticket.length) {
- memset (aticket.data, 0, aticket.length);
- krb5_data_free (&aticket);
- }
- if (times.length) {
- memset (times.data, 0, times.length);
- krb5_data_free (&times);
- }
- if (auth_domain)
- free (auth_domain);
- if (name)
- free (name);
- if (instance)
- free (instance);
- if (krbtgt_entry)
- _kdc_free_ent (context, krbtgt_entry);
- if (server_entry)
- _kdc_free_ent (context, server_entry);
-}
-
-krb5_error_code
-_kdc_do_kaserver(krb5_context context,
- krb5_kdc_configuration *config,
- unsigned char *buf,
- size_t len,
- krb5_data *reply,
- const char *from,
- struct sockaddr_in *addr)
-{
- krb5_error_code ret = 0;
- struct rx_header hdr;
- uint32_t op;
- krb5_storage *sp;
-
- if (len < RX_HEADER_SIZE)
- return -1;
- sp = krb5_storage_from_mem (buf, len);
-
- ret = decode_rx_header (sp, &hdr);
- if (ret)
- goto out;
- buf += RX_HEADER_SIZE;
- len -= RX_HEADER_SIZE;
-
- switch (hdr.type) {
- case HT_DATA :
- break;
- case HT_ACK :
- case HT_BUSY :
- case HT_ABORT :
- case HT_ACKALL :
- case HT_CHAL :
- case HT_RESP :
- case HT_DEBUG :
- default:
- /* drop */
- goto out;
- }
-
-
- if (hdr.serviceid != KA_AUTHENTICATION_SERVICE
- && hdr.serviceid != KA_TICKET_GRANTING_SERVICE) {
- ret = -1;
- goto out;
- }
-
- ret = krb5_ret_uint32(sp, &op);
- if (ret)
- goto out;
- switch (op) {
- case AUTHENTICATE :
- case AUTHENTICATE_V2 :
- do_authenticate (context, config, &hdr, sp, addr, from, reply);
- break;
- case GETTICKET :
- do_getticket (context, config, &hdr, sp, addr, from, reply);
- break;
- case AUTHENTICATE_OLD :
- case CHANGEPASSWORD :
- case GETTICKET_OLD :
- case SETPASSWORD :
- case SETFIELDS :
- case CREATEUSER :
- case DELETEUSER :
- case GETENTRY :
- case LISTENTRY :
- case GETSTATS :
- case DEBUG :
- case GETPASSWORD :
- case GETRANDOMKEY :
- default :
- make_error_reply (&hdr, RXGEN_OPCODE, reply);
- break;
- }
-
-out:
- krb5_storage_free (sp);
- return ret;
-}
diff --git a/crypto/heimdal/kdc/kdc-private.h b/crypto/heimdal/kdc/kdc-private.h
index 030be9a..aef929b 100644
--- a/crypto/heimdal/kdc/kdc-private.h
+++ b/crypto/heimdal/kdc/kdc-private.h
@@ -10,15 +10,16 @@ _kdc_add_KRB5SignedPath (
krb5_kdc_configuration */*config*/,
hdb_entry_ex */*krbtgt*/,
krb5_enctype /*enctype*/,
+ krb5_principal /*client*/,
krb5_const_principal /*server*/,
- KRB5SignedPathPrincipals */*principals*/,
+ krb5_principals /*principals*/,
EncTicketPart */*tkt*/);
krb5_error_code
_kdc_add_inital_verified_cas (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
- pk_client_params */*params*/,
+ pk_client_params */*cp*/,
EncTicketPart */*tkt*/);
krb5_error_code
@@ -32,22 +33,23 @@ _kdc_as_rep (
struct sockaddr */*from_addr*/,
int /*datagram_reply*/);
-krb5_boolean
-_kdc_check_addresses (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- HostAddresses */*addresses*/,
- const struct sockaddr */*from*/);
-
krb5_error_code
-_kdc_check_flags (
+_kdc_check_access (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
hdb_entry_ex */*client_ex*/,
const char */*client_name*/,
hdb_entry_ex */*server_ex*/,
const char */*server_name*/,
- krb5_boolean /*is_as_req*/);
+ KDC_REQ */*req*/,
+ krb5_data */*e_data*/);
+
+krb5_boolean
+_kdc_check_addresses (
+ krb5_context /*context*/,
+ krb5_kdc_configuration */*config*/,
+ HostAddresses */*addresses*/,
+ const struct sockaddr */*from*/);
krb5_error_code
_kdc_db_fetch (
@@ -55,67 +57,29 @@ _kdc_db_fetch (
krb5_kdc_configuration */*config*/,
krb5_const_principal /*principal*/,
unsigned /*flags*/,
+ krb5uint32 */*kvno_ptr*/,
HDB **/*db*/,
hdb_entry_ex **/*h*/);
krb5_error_code
-_kdc_db_fetch4 (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- const char */*name*/,
- const char */*instance*/,
- const char */*realm*/,
- unsigned /*flags*/,
- hdb_entry_ex **/*ent*/);
-
-krb5_error_code
-_kdc_do_524 (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- const Ticket */*t*/,
- krb5_data */*reply*/,
- const char */*from*/,
- struct sockaddr */*addr*/);
-
-krb5_error_code
_kdc_do_digest (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
- const DigestREQ */*req*/,
+ const struct DigestREQ */*req*/,
krb5_data */*reply*/,
const char */*from*/,
struct sockaddr */*addr*/);
krb5_error_code
-_kdc_do_kaserver (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- unsigned char */*buf*/,
- size_t /*len*/,
- krb5_data */*reply*/,
- const char */*from*/,
- struct sockaddr_in */*addr*/);
-
-krb5_error_code
_kdc_do_kx509 (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
- const Kx509Request */*req*/,
+ const struct Kx509Request */*req*/,
krb5_data */*reply*/,
const char */*from*/,
struct sockaddr */*addr*/);
krb5_error_code
-_kdc_do_version4 (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- unsigned char */*buf*/,
- size_t /*len*/,
- krb5_data */*reply*/,
- const char */*from*/,
- struct sockaddr_in */*addr*/);
-
-krb5_error_code
_kdc_encode_reply (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
@@ -126,28 +90,21 @@ _kdc_encode_reply (
int /*skvno*/,
const EncryptionKey */*skey*/,
int /*ckvno*/,
- const EncryptionKey */*ckey*/,
+ const EncryptionKey */*reply_key*/,
+ int /*rk_is_subkey*/,
const char **/*e_text*/,
krb5_data */*reply*/);
krb5_error_code
-_kdc_encode_v4_ticket (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- void */*buf*/,
- size_t /*len*/,
- const EncTicketPart */*et*/,
- const PrincipalName */*service*/,
- size_t */*size*/);
-
-krb5_error_code
_kdc_find_etype (
krb5_context /*context*/,
- const hdb_entry_ex */*princ*/,
+ krb5_boolean /*use_strongest_session_key*/,
+ krb5_boolean /*is_preauth*/,
+ hdb_entry_ex */*princ*/,
krb5_enctype */*etypes*/,
unsigned /*len*/,
- Key **/*ret_key*/,
- krb5_enctype */*ret_etype*/);
+ krb5_enctype */*ret_enctype*/,
+ Key **/*ret_key*/);
const PA_DATA*
_kdc_find_padata (
@@ -164,14 +121,6 @@ _kdc_free_ent (
hdb_entry_ex */*ent*/);
krb5_error_code
-_kdc_get_des_key (
- krb5_context /*context*/,
- hdb_entry_ex */*principal*/,
- krb5_boolean /*is_server*/,
- krb5_boolean /*prefer_afs_key*/,
- Key **/*ret_key*/);
-
-krb5_error_code
_kdc_get_preferred_key (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
@@ -180,6 +129,16 @@ _kdc_get_preferred_key (
krb5_enctype */*enctype*/,
Key **/*key*/);
+krb5_boolean
+_kdc_is_anonymous (
+ krb5_context /*context*/,
+ krb5_principal /*principal*/);
+
+krb5_boolean
+_kdc_is_weak_exception (
+ krb5_principal /*principal*/,
+ krb5_enctype /*etype*/);
+
void
_kdc_log_timestamp (
krb5_context /*context*/,
@@ -193,11 +152,6 @@ _kdc_log_timestamp (
krb5_error_code
_kdc_make_anonymous_principalname (PrincipalName */*pn*/);
-int
-_kdc_maybe_version4 (
- unsigned char */*buf*/,
- int /*len*/);
-
krb5_error_code
_kdc_pac_generate (
krb5_context /*context*/,
@@ -208,41 +162,38 @@ krb5_error_code
_kdc_pac_verify (
krb5_context /*context*/,
const krb5_principal /*client_principal*/,
+ const krb5_principal /*delegated_proxy_principal*/,
hdb_entry_ex */*client*/,
hdb_entry_ex */*server*/,
- krb5_pac */*pac*/);
+ hdb_entry_ex */*krbtgt*/,
+ krb5_pac */*pac*/,
+ int */*verified*/);
krb5_error_code
_kdc_pk_check_client (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
- const hdb_entry_ex */*client*/,
- pk_client_params */*client_params*/,
+ HDB */*clientdb*/,
+ hdb_entry_ex */*client*/,
+ pk_client_params */*cp*/,
char **/*subject_name*/);
void
_kdc_pk_free_client_param (
krb5_context /*context*/,
- pk_client_params */*client_params*/);
-
-krb5_error_code
-_kdc_pk_initialize (
- krb5_context /*context*/,
- krb5_kdc_configuration */*config*/,
- const char */*user_id*/,
- const char */*anchors*/,
- char **/*pool*/,
- char **/*revoke_list*/);
+ pk_client_params */*cp*/);
krb5_error_code
_kdc_pk_mk_pa_reply (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
- pk_client_params */*client_params*/,
+ pk_client_params */*cp*/,
const hdb_entry_ex */*client*/,
+ krb5_enctype /*sessionetype*/,
const KDC_REQ */*req*/,
const krb5_data */*req_buffer*/,
krb5_keyblock **/*reply_key*/,
+ krb5_keyblock */*sessionkey*/,
METHOD_DATA */*md*/);
krb5_error_code
@@ -251,6 +202,7 @@ _kdc_pk_rd_padata (
krb5_kdc_configuration */*config*/,
const KDC_REQ */*req*/,
const PA_DATA */*pa*/,
+ hdb_entry_ex */*client*/,
pk_client_params **/*ret_params*/);
krb5_error_code
@@ -274,13 +226,7 @@ krb5_error_code
_kdc_try_kx509_request (
void */*ptr*/,
size_t /*len*/,
- Kx509Request */*req*/,
+ struct Kx509Request */*req*/,
size_t */*size*/);
-krb5_error_code
-_kdc_windc_client_access (
- krb5_context /*context*/,
- struct hdb_entry_ex */*client*/,
- KDC_REQ */*req*/);
-
#endif /* __kdc_private_h__ */
diff --git a/crypto/heimdal/kdc/kdc-protos.h b/crypto/heimdal/kdc/kdc-protos.h
index 15e8c29..a46993b 100644
--- a/crypto/heimdal/kdc/kdc-protos.h
+++ b/crypto/heimdal/kdc/kdc-protos.h
@@ -8,6 +8,16 @@
extern "C" {
#endif
+krb5_error_code
+kdc_check_flags (
+ krb5_context /*context*/,
+ krb5_kdc_configuration */*config*/,
+ hdb_entry_ex */*client_ex*/,
+ const char */*client_name*/,
+ hdb_entry_ex */*server_ex*/,
+ const char */*server_name*/,
+ krb5_boolean /*is_as_req*/);
+
void
kdc_log (
krb5_context /*context*/,
@@ -35,6 +45,7 @@ kdc_log_msg_va (
void
kdc_openlog (
krb5_context /*context*/,
+ const char */*service*/,
krb5_kdc_configuration */*config*/);
krb5_error_code
@@ -42,6 +53,20 @@ krb5_kdc_get_config (
krb5_context /*context*/,
krb5_kdc_configuration **/*config*/);
+krb5_error_code
+krb5_kdc_pk_initialize (
+ krb5_context /*context*/,
+ krb5_kdc_configuration */*config*/,
+ const char */*user_id*/,
+ const char */*anchors*/,
+ char **/*pool*/,
+ char **/*revoke_list*/);
+
+krb5_error_code
+krb5_kdc_pkinit_config (
+ krb5_context /*context*/,
+ krb5_kdc_configuration */*config*/);
+
int
krb5_kdc_process_krb5_request (
krb5_context /*context*/,
diff --git a/crypto/heimdal/kdc/kdc-replay.c b/crypto/heimdal/kdc/kdc-replay.c
index 966831d..b0510f4 100644
--- a/crypto/heimdal/kdc/kdc-replay.c
+++ b/crypto/heimdal/kdc/kdc-replay.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2007 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: kdc-replay.c 21945 2007-10-03 21:52:24Z lha $");
-
static int version_flag;
static int help_flag;
@@ -62,13 +60,13 @@ main(int argc, char **argv)
int fd, optidx = 0;
setprogname(argv[0]);
-
+
if(getarg(args, num_args, argc, argv, &optidx))
usage(1);
if(help_flag)
usage(0);
-
+
if(version_flag){
print_version(NULL);
exit(0);
@@ -82,12 +80,29 @@ main(int argc, char **argv)
if (ret)
krb5_err(context, 1, ret, "krb5_kdc_default_config");
- kdc_openlog(context, config);
+ kdc_openlog(context, "kdc-replay", config);
ret = krb5_kdc_set_dbinfo(context, config);
if (ret)
krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo");
+#ifdef PKINIT
+ if (config->enable_pkinit) {
+ if (config->pkinit_kdc_identity == NULL)
+ krb5_errx(context, 1, "pkinit enabled but no identity");
+
+ if (config->pkinit_kdc_anchors == NULL)
+ krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
+
+ krb5_kdc_pk_initialize(context, config,
+ config->pkinit_kdc_identity,
+ config->pkinit_kdc_anchors,
+ config->pkinit_kdc_cert_pool,
+ config->pkinit_kdc_revoke);
+
+ }
+#endif /* PKINIT */
+
if (argc != 2)
errx(1, "argc != 2");
@@ -145,7 +160,7 @@ main(int argc, char **argv)
if (ret)
krb5_err(context, 1, ret, "krb5_print_address");
- printf("processing request from %s, %lu bytes\n",
+ printf("processing request from %s, %lu bytes\n",
astr, (unsigned long)d.length);
r.length = 0;
diff --git a/crypto/heimdal/kdc/kdc.8 b/crypto/heimdal/kdc/kdc.8
index 331682f..4a69bda 100644
--- a/crypto/heimdal/kdc/kdc.8
+++ b/crypto/heimdal/kdc/kdc.8
@@ -1,35 +1,35 @@
-.\" Copyright (c) 2003 - 2004 Kungliga Tekniska Högskolan
-.\" (Royal Institute of Technology, Stockholm, Sweden).
-.\" All rights reserved.
+.\" Copyright (c) 2003 - 2004 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:
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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: kdc.8 18419 2006-10-12 10:05:57Z lha $
+.\" $Id$
.\"
.Dd August 24, 2006
.Dt KDC 8
@@ -41,27 +41,27 @@
.Nm
.Bk -words
.Oo Fl c Ar file \*(Ba Xo
-.Fl -config-file= Ns Ar file
+.Fl Fl config-file= Ns Ar file
.Xc
.Oc
-.Op Fl p | Fl -no-require-preauth
-.Op Fl -max-request= Ns Ar size
-.Op Fl H | Fl -enable-http
-.Op Fl -no-524
-.Op Fl -kerberos4
-.Op Fl -kerberos4-cross-realm
+.Op Fl p | Fl Fl no-require-preauth
+.Op Fl Fl max-request= Ns Ar size
+.Op Fl H | Fl Fl enable-http
+.Op Fl Fl no-524
+.Op Fl Fl kerberos4
+.Op Fl Fl kerberos4-cross-realm
.Oo Fl r Ar string \*(Ba Xo
-.Fl -v4-realm= Ns Ar string
+.Fl Fl v4-realm= Ns Ar string
.Xc
.Oc
-.Op Fl K | Fl -kaserver
+.Op Fl K | Fl Fl kaserver
.Oo Fl P Ar portspec \*(Ba Xo
-.Fl -ports= Ns Ar portspec
+.Fl Fl ports= Ns Ar portspec
.Xc
.Oc
-.Op Fl -detach
-.Op Fl -disable-DES
-.Op Fl -addresses= Ns Ar list of addresses
+.Op Fl Fl detach
+.Op Fl Fl disable-des
+.Op Fl Fl addresses= Ns Ar list of addresses
.Ek
.Sh DESCRIPTION
.Nm
@@ -72,17 +72,11 @@ or from a default compiled-in value.
.Pp
Options supported:
.Bl -tag -width Ds
-.It Xo
-.Fl c Ar file ,
-.Fl -config-file= Ns Ar file
-.Xc
+.It Fl c Ar file , Fl Fl config-file= Ns Ar file
Specifies the location of the config file, the default is
.Pa /var/heimdal/kdc.conf .
This is the only value that can't be specified in the config file.
-.It Xo
-.Fl p ,
-.Fl -no-require-preauth
-.Xc
+.It Fl p , Fl Fl no-require-preauth
Turn off the requirement for pre-autentication in the initial AS-REQ
for all principals.
The use of pre-authentication makes it more difficult to do offline
@@ -95,34 +89,20 @@ pre-athentication.
The default is to require pre-authentication.
Adding the require-preauth per principal is a more flexible way of
handling this.
-.It Xo
-.Fl -max-request= Ns Ar size
-.Xc
+.It Fl Fl max-request= Ns Ar size
Gives an upper limit on the size of the requests that the kdc is
willing to handle.
-.It Xo
-.Fl H ,
-.Fl -enable-http
-.Xc
+.It Fl H , Fl Fl enable-http
Makes the kdc listen on port 80 and handle requests encapsulated in HTTP.
-.It Xo
-.Fl -no-524
-.Xc
+.It Fl Fl no-524
don't respond to 524 requests
-.It Xo
-.Fl -kerberos4
-.Xc
+.It Fl Fl kerberos4
respond to Kerberos 4 requests
-.It Xo
-.Fl -kerberos4-cross-realm
-.Xc
+.It Fl Fl kerberos4-cross-realm
respond to Kerberos 4 requests from foreign realms.
This is a known security hole and should not be enabled unless you
understand the consequences and are willing to live with them.
-.It Xo
-.Fl r Ar string ,
-.Fl -v4-realm= Ns Ar string
-.Xc
+.It Fl r Ar string , Fl Fl v4-realm= Ns Ar string
What realm this server should act as when dealing with version 4
requests.
The database can contain any number of realms, but since the version 4
@@ -130,29 +110,23 @@ protocol doesn't contain a realm for the server, it must be explicitly
specified.
The default is whatever is returned by
.Fn krb_get_lrealm .
-This option is only availabe if the KDC has been compiled with version
+This option is only available if the KDC has been compiled with version
4 support.
-.It Xo
-.Fl K ,
-.Fl -kaserver
-.Xc
+.It Fl K , Fl Fl kaserver
Enable kaserver emulation (in case it's compiled in).
-.It Xo
-.Fl P Ar portspec ,
-.Fl -ports= Ns Ar portspec
-.Xc
+.It Fl P Ar portspec , Fl Fl ports= Ns Ar portspec
Specifies the set of ports the KDC should listen on.
It is given as a
white-space separated list of services or port numbers.
-.It Fl -addresses= Ns Ar list of addresses
+.It Fl Fl addresses= Ns Ar list of addresses
The list of addresses to listen for requests on.
By default, the kdc will listen on all the locally configured
addresses.
If only a subset is desired, or the automatic detection fails, this
option might be used.
-.It Fl -detach
+.It Fl Fl detach
detach from pty and run as a daemon.
-.It Fl -disable-DES
+.It Fl Fl disable-des
disable add des encryption types, makes the kdc not use them.
.El
.Pp
@@ -163,13 +137,13 @@ and
The entity used for logging is
.Nm kdc .
.Sh CONFIGURATION FILE
-The configuration file has the same syntax as
+The configuration file has the same syntax as
.Xr krb5.conf 5 ,
-but will be read before
+but will be read before
.Pa /etc/krb5.conf ,
so it may override settings found there.
Options specific to the KDC only are found in the
-.Dq [kdc]
+.Dq [kdc]
section.
All the command-line options can preferably be added in the
configuration file.
@@ -179,7 +153,7 @@ specified as:
.Dl require-preauth = no
.Pp
(in fact you can specify the option as
-.Fl -require-preauth=no ) .
+.Fl Fl require-preauth=no ) .
.Pp
And there are some configuration options which do not have
command-line equivalents:
@@ -198,11 +172,8 @@ Permit anonymous tickets with no addresses.
.It Li max-kdc-datagram-reply-length = Va number
Maximum packet size the UDP rely that the KDC will transmit, instead
the KDC sends back a reply telling the client to use TCP instead.
-.It Li transited-policy = Xo
-.Li always-check \*(Ba
-.Li allow-per-principal |
-.Li always-honour-request
-.Xc
+.It Li transited-policy = Li always-check \*(Ba \
+Li allow-per-principal | Li always-honour-request
This controls how KDC requests with the
.Li disable-transited-check
flag are handled. It can be one of:
@@ -227,7 +198,7 @@ How long before password/principal expiration the KDC should start
sending out warning messages.
.El
.Pp
-The configuration file is only read when the
+The configuration file is only read when the
.Nm
is started.
If changes made to the configuration file are to take effect, the
@@ -252,7 +223,7 @@ addresses, the best option is probably to listen to a wildcarded TCP
socket, and make sure your clients use TCP to connect.
For instance, this will listen to IPv4 TCP port 88 only:
.Bd -literal -offset indent
-kdc --addresses=0.0.0.0 --ports="88/tcp"
+kdc --addresses=0.0.0.0 --ports="88/tcp"
.Ed
.Pp
There should be a way to specify protocol, port, and address triplets,
diff --git a/crypto/heimdal/kdc/kdc.h b/crypto/heimdal/kdc/kdc.h
index 6c129f3..9d52fd4 100644
--- a/crypto/heimdal/kdc/kdc.h
+++ b/crypto/heimdal/kdc/kdc.h
@@ -1,51 +1,52 @@
/*
- * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
*
* Copyright (c) 2005 Andrew Bartlett <abartlet@samba.org>
- *
- * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * All rights reserved.
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 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.
+ * 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.
*
- * 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.
+ * 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: kdc.h 21287 2007-06-25 14:09:03Z lha $
+/*
+ * $Id$
*/
#ifndef __KDC_H__
#define __KDC_H__
+#include <hdb.h>
#include <krb5.h>
enum krb5_kdc_trpolicy {
TRPOLICY_ALWAYS_CHECK,
- TRPOLICY_ALLOW_PER_PRINCIPAL,
+ TRPOLICY_ALLOW_PER_PRINCIPAL,
TRPOLICY_ALWAYS_HONOUR_REQUEST
};
@@ -57,26 +58,28 @@ typedef struct krb5_kdc_configuration {
int num_db;
krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */
-
+
+ krb5_boolean as_use_strongest_session_key;
+ krb5_boolean preauth_use_strongest_session_key;
+ krb5_boolean tgs_use_strongest_session_key;
+ krb5_boolean use_strongest_server_key;
+
krb5_boolean check_ticket_addresses;
krb5_boolean allow_null_ticket_addresses;
krb5_boolean allow_anonymous;
enum krb5_kdc_trpolicy trpolicy;
- char *v4_realm;
- krb5_boolean enable_v4;
- krb5_boolean enable_v4_cross_realm;
- krb5_boolean enable_v4_per_principal;
-
- krb5_boolean enable_kaserver;
-
- krb5_boolean enable_524;
-
krb5_boolean enable_pkinit;
krb5_boolean pkinit_princ_in_cert;
- char *pkinit_kdc_ocsp_file;
+ const char *pkinit_kdc_identity;
+ const char *pkinit_kdc_anchors;
+ const char *pkinit_kdc_friendly_name;
+ const char *pkinit_kdc_ocsp_file;
+ char **pkinit_kdc_cert_pool;
+ char **pkinit_kdc_revoke;
int pkinit_dh_min_bits;
int pkinit_require_binding;
+ int pkinit_allow_proxy_certs;
krb5_log_facility *logf;
@@ -91,6 +94,20 @@ typedef struct krb5_kdc_configuration {
} krb5_kdc_configuration;
+struct krb5_kdc_service {
+ unsigned int flags;
+#define KS_KRB5 1
+#define KS_NO_LENGTH 2
+ krb5_error_code (*process)(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_data *req_buffer,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *addr,
+ int datagram_reply,
+ int *claim);
+};
+
#include <kdc-protos.h>
#endif
diff --git a/crypto/heimdal/kdc/kdc_locl.h b/crypto/heimdal/kdc/kdc_locl.h
index fe05236..36d694d 100644
--- a/crypto/heimdal/kdc/kdc_locl.h
+++ b/crypto/heimdal/kdc/kdc_locl.h
@@ -1,60 +1,65 @@
/*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2005 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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: kdc_locl.h 22247 2007-12-08 23:49:41Z lha $
+/*
+ * $Id$
*/
#ifndef __KDC_LOCL_H__
#define __KDC_LOCL_H__
#include "headers.h"
-#include "kdc.h"
typedef struct pk_client_params pk_client_params;
+struct DigestREQ;
+struct Kx509Request;
#include <kdc-private.h>
extern sig_atomic_t exit_flag;
-extern size_t max_request;
+extern size_t max_request_udp;
+extern size_t max_request_tcp;
extern const char *request_log;
extern const char *port_str;
extern krb5_addresses explicit_addresses;
extern int enable_http;
+#ifdef SUPPORT_DETACH
+
#define DETACH_IS_DEFAULT FALSE
extern int detach_from_console;
+#endif
extern const struct units _kdc_digestunits[];
@@ -63,10 +68,17 @@ extern const struct units _kdc_digestunits[];
extern struct timeval _kdc_now;
#define kdc_time (_kdc_now.tv_sec)
+extern char *runas_string;
+extern char *chroot_string;
+
void
loop(krb5_context context, krb5_kdc_configuration *config);
krb5_kdc_configuration *
configure(krb5_context context, int argc, char **argv);
+#ifdef __APPLE__
+void bonjour_announce(krb5_context, krb5_kdc_configuration *);
+#endif
+
#endif /* __KDC_LOCL_H__ */
diff --git a/crypto/heimdal/kdc/kerberos4.c b/crypto/heimdal/kdc/kerberos4.c
deleted file mode 100644
index cbba649..0000000
--- a/crypto/heimdal/kdc/kerberos4.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Copyright (c) 1997 - 2006 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 "kdc_locl.h"
-
-#include <krb5-v4compat.h>
-
-RCSID("$Id: kerberos4.c 21577 2007-07-16 08:14:06Z lha $");
-
-#ifndef swap32
-static uint32_t
-swap32(uint32_t x)
-{
- return ((x << 24) & 0xff000000) |
- ((x << 8) & 0xff0000) |
- ((x >> 8) & 0xff00) |
- ((x >> 24) & 0xff);
-}
-#endif /* swap32 */
-
-int
-_kdc_maybe_version4(unsigned char *buf, int len)
-{
- return len > 0 && *buf == 4;
-}
-
-static void
-make_err_reply(krb5_context context, krb5_data *reply,
- int code, const char *msg)
-{
- _krb5_krb_cr_err_reply(context, "", "", "",
- kdc_time, code, msg, reply);
-}
-
-struct valid_princ_ctx {
- krb5_kdc_configuration *config;
- unsigned flags;
-};
-
-static krb5_boolean
-valid_princ(krb5_context context,
- void *funcctx,
- krb5_principal princ)
-{
- struct valid_princ_ctx *ctx = funcctx;
- krb5_error_code ret;
- char *s;
- hdb_entry_ex *ent;
-
- ret = krb5_unparse_name(context, princ, &s);
- if (ret)
- return FALSE;
- ret = _kdc_db_fetch(context, ctx->config, princ, ctx->flags, NULL, &ent);
- if (ret) {
- kdc_log(context, ctx->config, 7, "Lookup %s failed: %s", s,
- krb5_get_err_text (context, ret));
- free(s);
- return FALSE;
- }
- kdc_log(context, ctx->config, 7, "Lookup %s succeeded", s);
- free(s);
- _kdc_free_ent(context, ent);
- return TRUE;
-}
-
-krb5_error_code
-_kdc_db_fetch4(krb5_context context,
- krb5_kdc_configuration *config,
- const char *name, const char *instance, const char *realm,
- unsigned flags,
- hdb_entry_ex **ent)
-{
- krb5_principal p;
- krb5_error_code ret;
- struct valid_princ_ctx ctx;
-
- ctx.config = config;
- ctx.flags = flags;
-
- ret = krb5_425_conv_principal_ext2(context, name, instance, realm,
- valid_princ, &ctx, 0, &p);
- if(ret)
- return ret;
- ret = _kdc_db_fetch(context, config, p, flags, NULL, ent);
- krb5_free_principal(context, p);
- return ret;
-}
-
-#define RCHECK(X, L) if(X){make_err_reply(context, reply, KFAILURE, "Packet too short"); goto L;}
-
-/*
- * Process the v4 request in `buf, len' (received from `addr'
- * (with string `from').
- * Return an error code and a reply in `reply'.
- */
-
-krb5_error_code
-_kdc_do_version4(krb5_context context,
- krb5_kdc_configuration *config,
- unsigned char *buf,
- size_t len,
- krb5_data *reply,
- const char *from,
- struct sockaddr_in *addr)
-{
- krb5_storage *sp;
- krb5_error_code ret;
- hdb_entry_ex *client = NULL, *server = NULL;
- Key *ckey, *skey;
- int8_t pvno;
- int8_t msg_type;
- int lsb;
- char *name = NULL, *inst = NULL, *realm = NULL;
- char *sname = NULL, *sinst = NULL;
- int32_t req_time;
- time_t max_life;
- uint8_t life;
- char client_name[256];
- char server_name[256];
-
- if(!config->enable_v4) {
- kdc_log(context, config, 0,
- "Rejected version 4 request from %s", from);
- make_err_reply(context, reply, KRB4ET_KDC_GEN_ERR,
- "Function not enabled");
- return 0;
- }
-
- sp = krb5_storage_from_mem(buf, len);
- RCHECK(krb5_ret_int8(sp, &pvno), out);
- if(pvno != 4){
- kdc_log(context, config, 0,
- "Protocol version mismatch (krb4) (%d)", pvno);
- make_err_reply(context, reply, KRB4ET_KDC_PKT_VER, "protocol mismatch");
- goto out;
- }
- RCHECK(krb5_ret_int8(sp, &msg_type), out);
- lsb = msg_type & 1;
- msg_type &= ~1;
- switch(msg_type){
- case AUTH_MSG_KDC_REQUEST: {
- krb5_data ticket, cipher;
- krb5_keyblock session;
-
- krb5_data_zero(&ticket);
- krb5_data_zero(&cipher);
-
- RCHECK(krb5_ret_stringz(sp, &name), out1);
- RCHECK(krb5_ret_stringz(sp, &inst), out1);
- RCHECK(krb5_ret_stringz(sp, &realm), out1);
- RCHECK(krb5_ret_int32(sp, &req_time), out1);
- if(lsb)
- req_time = swap32(req_time);
- RCHECK(krb5_ret_uint8(sp, &life), out1);
- RCHECK(krb5_ret_stringz(sp, &sname), out1);
- RCHECK(krb5_ret_stringz(sp, &sinst), out1);
- snprintf (client_name, sizeof(client_name),
- "%s.%s@%s", name, inst, realm);
- snprintf (server_name, sizeof(server_name),
- "%s.%s@%s", sname, sinst, config->v4_realm);
-
- kdc_log(context, config, 0, "AS-REQ (krb4) %s from %s for %s",
- client_name, from, server_name);
-
- ret = _kdc_db_fetch4(context, config, name, inst, realm,
- HDB_F_GET_CLIENT, &client);
- if(ret) {
- kdc_log(context, config, 0, "Client not found in database: %s: %s",
- client_name, krb5_get_err_text(context, ret));
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
- "principal unknown");
- goto out1;
- }
- ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
- HDB_F_GET_SERVER, &server);
- if(ret){
- kdc_log(context, config, 0, "Server not found in database: %s: %s",
- server_name, krb5_get_err_text(context, ret));
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
- "principal unknown");
- goto out1;
- }
-
- ret = _kdc_check_flags (context, config,
- client, client_name,
- server, server_name,
- TRUE);
- if (ret) {
- /* good error code? */
- make_err_reply(context, reply, KRB4ET_KDC_NAME_EXP,
- "operation not allowed");
- goto out1;
- }
-
- if (config->enable_v4_per_principal &&
- client->entry.flags.allow_kerberos4 == 0)
- {
- kdc_log(context, config, 0,
- "Per principal Kerberos 4 flag not turned on for %s",
- client_name);
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "allow kerberos4 flag required");
- goto out1;
- }
-
- /*
- * There's no way to do pre-authentication in v4 and thus no
- * good error code to return if preauthentication is required.
- */
-
- if (config->require_preauth
- || client->entry.flags.require_preauth
- || server->entry.flags.require_preauth) {
- kdc_log(context, config, 0,
- "Pre-authentication required for v4-request: "
- "%s for %s",
- client_name, server_name);
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "preauth required");
- goto out1;
- }
-
- ret = _kdc_get_des_key(context, client, FALSE, FALSE, &ckey);
- if(ret){
- kdc_log(context, config, 0, "no suitable DES key for client");
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "no suitable DES key for client");
- goto out1;
- }
-
-#if 0
- /* this is not necessary with the new code in libkrb */
- /* find a properly salted key */
- while(ckey->salt == NULL || ckey->salt->salt.length != 0)
- ret = hdb_next_keytype2key(context, &client->entry, KEYTYPE_DES, &ckey);
- if(ret){
- kdc_log(context, config, 0, "No version-4 salted key in database -- %s.%s@%s",
- name, inst, realm);
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "No version-4 salted key in database");
- goto out1;
- }
-#endif
-
- ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
- if(ret){
- kdc_log(context, config, 0, "no suitable DES key for server");
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "no suitable DES key for server");
- goto out1;
- }
-
- max_life = _krb5_krb_life_to_time(0, life);
- if(client->entry.max_life)
- max_life = min(max_life, *client->entry.max_life);
- if(server->entry.max_life)
- max_life = min(max_life, *server->entry.max_life);
-
- life = krb_time_to_life(kdc_time, kdc_time + max_life);
-
- ret = krb5_generate_random_keyblock(context,
- ETYPE_DES_PCBC_NONE,
- &session);
- if (ret) {
- make_err_reply(context, reply, KFAILURE,
- "Not enough random i KDC");
- goto out1;
- }
-
- ret = _krb5_krb_create_ticket(context,
- 0,
- name,
- inst,
- config->v4_realm,
- addr->sin_addr.s_addr,
- &session,
- life,
- kdc_time,
- sname,
- sinst,
- &skey->key,
- &ticket);
- if (ret) {
- krb5_free_keyblock_contents(context, &session);
- make_err_reply(context, reply, KFAILURE,
- "failed to create v4 ticket");
- goto out1;
- }
-
- ret = _krb5_krb_create_ciph(context,
- &session,
- sname,
- sinst,
- config->v4_realm,
- life,
- server->entry.kvno % 255,
- &ticket,
- kdc_time,
- &ckey->key,
- &cipher);
- krb5_free_keyblock_contents(context, &session);
- krb5_data_free(&ticket);
- if (ret) {
- make_err_reply(context, reply, KFAILURE,
- "Failed to create v4 cipher");
- goto out1;
- }
-
- ret = _krb5_krb_create_auth_reply(context,
- name,
- inst,
- realm,
- req_time,
- 0,
- client->entry.pw_end ? *client->entry.pw_end : 0,
- client->entry.kvno % 256,
- &cipher,
- reply);
- krb5_data_free(&cipher);
-
- out1:
- break;
- }
- case AUTH_MSG_APPL_REQUEST: {
- struct _krb5_krb_auth_data ad;
- int8_t kvno;
- int8_t ticket_len;
- int8_t req_len;
- krb5_data auth;
- int32_t address;
- size_t pos;
- krb5_principal tgt_princ = NULL;
- hdb_entry_ex *tgt = NULL;
- Key *tkey;
- time_t max_end, actual_end, issue_time;
-
- memset(&ad, 0, sizeof(ad));
- krb5_data_zero(&auth);
-
- RCHECK(krb5_ret_int8(sp, &kvno), out2);
- RCHECK(krb5_ret_stringz(sp, &realm), out2);
-
- ret = krb5_425_conv_principal(context, "krbtgt", realm,
- config->v4_realm,
- &tgt_princ);
- if(ret){
- kdc_log(context, config, 0,
- "Converting krbtgt principal (krb4): %s",
- krb5_get_err_text(context, ret));
- make_err_reply(context, reply, KFAILURE,
- "Failed to convert v4 principal (krbtgt)");
- goto out2;
- }
-
- ret = _kdc_db_fetch(context, config, tgt_princ,
- HDB_F_GET_KRBTGT, NULL, &tgt);
- if(ret){
- char *s;
- s = kdc_log_msg(context, config, 0, "Ticket-granting ticket not "
- "found in database (krb4): krbtgt.%s@%s: %s",
- realm, config->v4_realm,
- krb5_get_err_text(context, ret));
- make_err_reply(context, reply, KFAILURE, s);
- free(s);
- goto out2;
- }
-
- if(tgt->entry.kvno % 256 != kvno){
- kdc_log(context, config, 0,
- "tgs-req (krb4) with old kvno %d (current %d) for "
- "krbtgt.%s@%s", kvno, tgt->entry.kvno % 256,
- realm, config->v4_realm);
- make_err_reply(context, reply, KRB4ET_KDC_AUTH_EXP,
- "old krbtgt kvno used");
- goto out2;
- }
-
- ret = _kdc_get_des_key(context, tgt, TRUE, FALSE, &tkey);
- if(ret){
- kdc_log(context, config, 0,
- "no suitable DES key for krbtgt (krb4)");
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "no suitable DES key for krbtgt");
- goto out2;
- }
-
- RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
- RCHECK(krb5_ret_int8(sp, &req_len), out2);
-
- pos = krb5_storage_seek(sp, ticket_len + req_len, SEEK_CUR);
-
- auth.data = buf;
- auth.length = pos;
-
- if (config->check_ticket_addresses)
- address = addr->sin_addr.s_addr;
- else
- address = 0;
-
- ret = _krb5_krb_rd_req(context, &auth, "krbtgt", realm,
- config->v4_realm,
- address, &tkey->key, &ad);
- if(ret){
- kdc_log(context, config, 0, "krb_rd_req: %d", ret);
- make_err_reply(context, reply, ret, "failed to parse request");
- goto out2;
- }
-
- RCHECK(krb5_ret_int32(sp, &req_time), out2);
- if(lsb)
- req_time = swap32(req_time);
- RCHECK(krb5_ret_uint8(sp, &life), out2);
- RCHECK(krb5_ret_stringz(sp, &sname), out2);
- RCHECK(krb5_ret_stringz(sp, &sinst), out2);
- snprintf (server_name, sizeof(server_name),
- "%s.%s@%s",
- sname, sinst, config->v4_realm);
- snprintf (client_name, sizeof(client_name),
- "%s.%s@%s",
- ad.pname, ad.pinst, ad.prealm);
-
- kdc_log(context, config, 0, "TGS-REQ (krb4) %s from %s for %s",
- client_name, from, server_name);
-
- if(strcmp(ad.prealm, realm)){
- kdc_log(context, config, 0,
- "Can't hop realms (krb4) %s -> %s", realm, ad.prealm);
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
- "Can't hop realms");
- goto out2;
- }
-
- if (!config->enable_v4_cross_realm && strcmp(realm, config->v4_realm) != 0) {
- kdc_log(context, config, 0,
- "krb4 Cross-realm %s -> %s disabled",
- realm, config->v4_realm);
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
- "Can't hop realms");
- goto out2;
- }
-
- if(strcmp(sname, "changepw") == 0){
- kdc_log(context, config, 0,
- "Bad request for changepw ticket (krb4)");
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
- "Can't authorize password change based on TGT");
- goto out2;
- }
-
- ret = _kdc_db_fetch4(context, config, ad.pname, ad.pinst, ad.prealm,
- HDB_F_GET_CLIENT, &client);
- if(ret && ret != HDB_ERR_NOENTRY) {
- char *s;
- s = kdc_log_msg(context, config, 0,
- "Client not found in database: (krb4) %s: %s",
- client_name, krb5_get_err_text(context, ret));
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
- free(s);
- goto out2;
- }
- if (client == NULL && strcmp(ad.prealm, config->v4_realm) == 0) {
- char *s;
- s = kdc_log_msg(context, config, 0,
- "Local client not found in database: (krb4) "
- "%s", client_name);
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
- free(s);
- goto out2;
- }
-
- ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
- HDB_F_GET_SERVER, &server);
- if(ret){
- char *s;
- s = kdc_log_msg(context, config, 0,
- "Server not found in database (krb4): %s: %s",
- server_name, krb5_get_err_text(context, ret));
- make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
- free(s);
- goto out2;
- }
-
- ret = _kdc_check_flags (context, config,
- client, client_name,
- server, server_name,
- FALSE);
- if (ret) {
- make_err_reply(context, reply, KRB4ET_KDC_NAME_EXP,
- "operation not allowed");
- goto out2;
- }
-
- ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
- if(ret){
- kdc_log(context, config, 0,
- "no suitable DES key for server (krb4)");
- make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
- "no suitable DES key for server");
- goto out2;
- }
-
- max_end = _krb5_krb_life_to_time(ad.time_sec, ad.life);
- max_end = min(max_end, _krb5_krb_life_to_time(kdc_time, life));
- if(server->entry.max_life)
- max_end = min(max_end, kdc_time + *server->entry.max_life);
- if(client && client->entry.max_life)
- max_end = min(max_end, kdc_time + *client->entry.max_life);
- life = min(life, krb_time_to_life(kdc_time, max_end));
-
- issue_time = kdc_time;
- actual_end = _krb5_krb_life_to_time(issue_time, life);
- while (actual_end > max_end && life > 1) {
- /* move them into the next earlier lifetime bracket */
- life--;
- actual_end = _krb5_krb_life_to_time(issue_time, life);
- }
- if (actual_end > max_end) {
- /* if life <= 1 and it's still too long, backdate the ticket */
- issue_time -= actual_end - max_end;
- }
-
- {
- krb5_data ticket, cipher;
- krb5_keyblock session;
-
- krb5_data_zero(&ticket);
- krb5_data_zero(&cipher);
-
- ret = krb5_generate_random_keyblock(context,
- ETYPE_DES_PCBC_NONE,
- &session);
- if (ret) {
- make_err_reply(context, reply, KFAILURE,
- "Not enough random i KDC");
- goto out2;
- }
-
- ret = _krb5_krb_create_ticket(context,
- 0,
- ad.pname,
- ad.pinst,
- ad.prealm,
- addr->sin_addr.s_addr,
- &session,
- life,
- issue_time,
- sname,
- sinst,
- &skey->key,
- &ticket);
- if (ret) {
- krb5_free_keyblock_contents(context, &session);
- make_err_reply(context, reply, KFAILURE,
- "failed to create v4 ticket");
- goto out2;
- }
-
- ret = _krb5_krb_create_ciph(context,
- &session,
- sname,
- sinst,
- config->v4_realm,
- life,
- server->entry.kvno % 255,
- &ticket,
- issue_time,
- &ad.session,
- &cipher);
- krb5_free_keyblock_contents(context, &session);
- if (ret) {
- make_err_reply(context, reply, KFAILURE,
- "failed to create v4 cipher");
- goto out2;
- }
-
- ret = _krb5_krb_create_auth_reply(context,
- ad.pname,
- ad.pinst,
- ad.prealm,
- req_time,
- 0,
- 0,
- 0,
- &cipher,
- reply);
- krb5_data_free(&cipher);
- }
- out2:
- _krb5_krb_free_auth_data(context, &ad);
- if(tgt_princ)
- krb5_free_principal(context, tgt_princ);
- if(tgt)
- _kdc_free_ent(context, tgt);
- break;
- }
- case AUTH_MSG_ERR_REPLY:
- break;
- default:
- kdc_log(context, config, 0, "Unknown message type (krb4): %d from %s",
- msg_type, from);
-
- make_err_reply(context, reply, KFAILURE, "Unknown message type");
- }
- out:
- if(name)
- free(name);
- if(inst)
- free(inst);
- if(realm)
- free(realm);
- if(sname)
- free(sname);
- if(sinst)
- free(sinst);
- if(client)
- _kdc_free_ent(context, client);
- if(server)
- _kdc_free_ent(context, server);
- krb5_storage_free(sp);
- return 0;
-}
-
-krb5_error_code
-_kdc_encode_v4_ticket(krb5_context context,
- krb5_kdc_configuration *config,
- void *buf, size_t len, const EncTicketPart *et,
- const PrincipalName *service, size_t *size)
-{
- krb5_storage *sp;
- krb5_error_code ret;
- char name[40], inst[40], realm[40];
- char sname[40], sinst[40];
-
- {
- krb5_principal princ;
- _krb5_principalname2krb5_principal(context,
- &princ,
- *service,
- et->crealm);
- ret = krb5_524_conv_principal(context,
- princ,
- sname,
- sinst,
- realm);
- krb5_free_principal(context, princ);
- if(ret)
- return ret;
-
- _krb5_principalname2krb5_principal(context,
- &princ,
- et->cname,
- et->crealm);
-
- ret = krb5_524_conv_principal(context,
- princ,
- name,
- inst,
- realm);
- krb5_free_principal(context, princ);
- }
- if(ret)
- return ret;
-
- sp = krb5_storage_emem();
-
- krb5_store_int8(sp, 0); /* flags */
- krb5_store_stringz(sp, name);
- krb5_store_stringz(sp, inst);
- krb5_store_stringz(sp, realm);
- {
- unsigned char tmp[4] = { 0, 0, 0, 0 };
- int i;
- if(et->caddr){
- for(i = 0; i < et->caddr->len; i++)
- if(et->caddr->val[i].addr_type == AF_INET &&
- et->caddr->val[i].address.length == 4){
- memcpy(tmp, et->caddr->val[i].address.data, 4);
- break;
- }
- }
- krb5_storage_write(sp, tmp, sizeof(tmp));
- }
-
- if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
- et->key.keytype != ETYPE_DES_CBC_MD4 &&
- et->key.keytype != ETYPE_DES_CBC_CRC) ||
- et->key.keyvalue.length != 8)
- return -1;
- krb5_storage_write(sp, et->key.keyvalue.data, 8);
-
- {
- time_t start = et->starttime ? *et->starttime : et->authtime;
- krb5_store_int8(sp, krb_time_to_life(start, et->endtime));
- krb5_store_int32(sp, start);
- }
-
- krb5_store_stringz(sp, sname);
- krb5_store_stringz(sp, sinst);
-
- {
- krb5_data data;
- krb5_storage_to_data(sp, &data);
- krb5_storage_free(sp);
- *size = (data.length + 7) & ~7; /* pad to 8 bytes */
- if(*size > len)
- return -1;
- memset((unsigned char*)buf - *size + 1, 0, *size);
- memcpy((unsigned char*)buf - *size + 1, data.data, data.length);
- krb5_data_free(&data);
- }
- return 0;
-}
-
-krb5_error_code
-_kdc_get_des_key(krb5_context context,
- hdb_entry_ex *principal, krb5_boolean is_server,
- krb5_boolean prefer_afs_key, Key **ret_key)
-{
- Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL, *server_key = NULL;
- int i;
- krb5_enctype etypes[] = { ETYPE_DES_CBC_MD5,
- ETYPE_DES_CBC_MD4,
- ETYPE_DES_CBC_CRC };
-
- for(i = 0;
- i < sizeof(etypes)/sizeof(etypes[0])
- && (v5_key == NULL || v4_key == NULL ||
- afs_key == NULL || server_key == NULL);
- ++i) {
- Key *key = NULL;
- while(hdb_next_enctype2key(context, &principal->entry, etypes[i], &key) == 0) {
- if(key->salt == NULL) {
- if(v5_key == NULL)
- v5_key = key;
- } else if(key->salt->type == hdb_pw_salt &&
- key->salt->salt.length == 0) {
- if(v4_key == NULL)
- v4_key = key;
- } else if(key->salt->type == hdb_afs3_salt) {
- if(afs_key == NULL)
- afs_key = key;
- } else if(server_key == NULL)
- server_key = key;
- }
- }
-
- if(prefer_afs_key) {
- if(afs_key)
- *ret_key = afs_key;
- else if(v4_key)
- *ret_key = v4_key;
- else if(v5_key)
- *ret_key = v5_key;
- else if(is_server && server_key)
- *ret_key = server_key;
- else
- return KRB4ET_KDC_NULL_KEY;
- } else {
- if(v4_key)
- *ret_key = v4_key;
- else if(afs_key)
- *ret_key = afs_key;
- else if(v5_key)
- *ret_key = v5_key;
- else if(is_server && server_key)
- *ret_key = server_key;
- else
- return KRB4ET_KDC_NULL_KEY;
- }
-
- if((*ret_key)->key.keyvalue.length == 0)
- return KRB4ET_KDC_NULL_KEY;
- return 0;
-}
-
diff --git a/crypto/heimdal/kdc/kerberos5.c b/crypto/heimdal/kdc/kerberos5.c
index 9582cd8..c13abb7 100644
--- a/crypto/heimdal/kdc/kerberos5.c
+++ b/crypto/heimdal/kdc/kerberos5.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2007 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $");
-
#define MAX_TIME ((time_t)((1U << 31) - 1))
void
@@ -60,13 +58,13 @@ realloc_method_data(METHOD_DATA *md)
}
static void
-set_salt_padata (METHOD_DATA *md, Salt *salt)
+set_salt_padata(METHOD_DATA *md, Salt *salt)
{
if (salt) {
- realloc_method_data(md);
- md->val[md->len - 1].padata_type = salt->type;
- der_copy_octet_string(&salt->salt,
- &md->val[md->len - 1].padata_value);
+ realloc_method_data(md);
+ md->val[md->len - 1].padata_type = salt->type;
+ der_copy_octet_string(&salt->salt,
+ &md->val[md->len - 1].padata_value);
}
}
@@ -76,15 +74,33 @@ _kdc_find_padata(const KDC_REQ *req, int *start, int type)
if (req->padata == NULL)
return NULL;
- while(*start < req->padata->len){
+ while((size_t)*start < req->padata->len){
(*start)++;
- if(req->padata->val[*start - 1].padata_type == type)
+ if(req->padata->val[*start - 1].padata_type == (unsigned)type)
return &req->padata->val[*start - 1];
}
return NULL;
}
/*
+ * This is a hack to allow predefined weak services, like afs to
+ * still use weak types
+ */
+
+krb5_boolean
+_kdc_is_weak_exception(krb5_principal principal, krb5_enctype etype)
+{
+ if (principal->name.name_string.len > 0 &&
+ strcmp(principal->name.name_string.val[0], "afs") == 0 &&
+ (etype == ETYPE_DES_CBC_CRC
+ || etype == ETYPE_DES_CBC_MD4
+ || etype == ETYPE_DES_CBC_MD5))
+ return TRUE;
+ return FALSE;
+}
+
+
+/*
* Detect if `key' is the using the the precomputed `default_salt'.
*/
@@ -107,36 +123,103 @@ is_default_salt_p(const krb5_salt *default_salt, const Key *key)
*/
krb5_error_code
-_kdc_find_etype(krb5_context context, const hdb_entry_ex *princ,
- krb5_enctype *etypes, unsigned len,
- Key **ret_key, krb5_enctype *ret_etype)
+_kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key,
+ krb5_boolean is_preauth, hdb_entry_ex *princ,
+ krb5_enctype *etypes, unsigned len,
+ krb5_enctype *ret_enctype, Key **ret_key)
{
- int i;
- krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP;
+ krb5_error_code ret;
krb5_salt def_salt;
+ krb5_enctype enctype = ETYPE_NULL;
+ Key *key;
+ int i;
- krb5_get_pw_salt (context, princ->entry.principal, &def_salt);
+ /* We'll want to avoid keys with v4 salted keys in the pre-auth case... */
+ ret = krb5_get_pw_salt(context, princ->entry.principal, &def_salt);
+ if (ret)
+ return ret;
- for(i = 0; ret != 0 && i < len ; i++) {
- Key *key = NULL;
+ ret = KRB5KDC_ERR_ETYPE_NOSUPP;
- if (krb5_enctype_valid(context, etypes[i]) != 0)
- continue;
+ if (use_strongest_session_key) {
+ const krb5_enctype *p;
+ krb5_enctype clientbest = ETYPE_NULL;
+ int j;
+
+ /*
+ * Pick the strongest key that the KDC, target service, and
+ * client all support, using the local cryptosystem enctype
+ * list in strongest-to-weakest order to drive the search.
+ *
+ * This is not what RFC4120 says to do, but it encourages
+ * adoption of stronger enctypes. This doesn't play well with
+ * clients that have multiple Kerberos client implementations
+ * available with different supported enctype lists.
+ */
- while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
- if (key->key.keyvalue.length == 0) {
- ret = KRB5KDC_ERR_NULL_KEY;
+ /* drive the search with local supported enctypes list */
+ p = krb5_kerberos_enctypes(context);
+ for (i = 0; p[i] != ETYPE_NULL && enctype == ETYPE_NULL; i++) {
+ if (krb5_enctype_valid(context, p[i]) != 0)
continue;
+
+ /* check that the client supports it too */
+ for (j = 0; j < len && enctype == ETYPE_NULL; j++) {
+ if (p[i] != etypes[j])
+ continue;
+ /* save best of union of { client, crypto system } */
+ if (clientbest == ETYPE_NULL)
+ clientbest = p[i];
+ /* check target princ support */
+ ret = hdb_enctype2key(context, &princ->entry, p[i], &key);
+ if (ret)
+ continue;
+ if (is_preauth && !is_default_salt_p(&def_salt, key))
+ continue;
+ enctype = p[i];
}
- *ret_key = key;
- *ret_etype = etypes[i];
- ret = 0;
- if (is_default_salt_p(&def_salt, key)) {
- krb5_free_salt (context, def_salt);
- return ret;
+ }
+ if (clientbest != ETYPE_NULL && enctype == ETYPE_NULL)
+ enctype = clientbest;
+ else if (enctype == ETYPE_NULL)
+ ret = KRB5KDC_ERR_ETYPE_NOSUPP;
+ if (ret == 0 && ret_enctype != NULL)
+ *ret_enctype = enctype;
+ if (ret == 0 && ret_key != NULL)
+ *ret_key = key;
+ } else {
+ /*
+ * Pick the first key from the client's enctype list that is
+ * supported by the cryptosystem and by the given principal.
+ *
+ * RFC4120 says we SHOULD pick the first _strong_ key from the
+ * client's list... not the first key... If the admin disallows
+ * weak enctypes in krb5.conf and selects this key selection
+ * algorithm, then we get exactly what RFC4120 says.
+ */
+ for(key = NULL, i = 0; ret != 0 && i < len; i++, key = NULL) {
+
+ if (krb5_enctype_valid(context, etypes[i]) != 0 &&
+ !_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
+ continue;
+
+ while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
+ if (key->key.keyvalue.length == 0) {
+ ret = KRB5KDC_ERR_NULL_KEY;
+ continue;
+ }
+ if (ret_key != NULL)
+ *ret_key = key;
+ if (ret_enctype != NULL)
+ *ret_enctype = etypes[i];
+ ret = 0;
+ if (is_preauth && is_default_salt_p(&def_salt, key))
+ goto out;
}
}
}
+
+out:
krb5_free_salt (context, def_salt);
return ret;
}
@@ -159,44 +242,44 @@ _kdc_make_anonymous_principalname (PrincipalName *pn)
}
void
-_kdc_log_timestamp(krb5_context context,
+_kdc_log_timestamp(krb5_context context,
krb5_kdc_configuration *config,
const char *type,
- KerberosTime authtime, KerberosTime *starttime,
+ KerberosTime authtime, KerberosTime *starttime,
KerberosTime endtime, KerberosTime *renew_till)
{
- char authtime_str[100], starttime_str[100],
+ char authtime_str[100], starttime_str[100],
endtime_str[100], renewtime_str[100];
-
- krb5_format_time(context, authtime,
- authtime_str, sizeof(authtime_str), TRUE);
+
+ krb5_format_time(context, authtime,
+ authtime_str, sizeof(authtime_str), TRUE);
if (starttime)
- krb5_format_time(context, *starttime,
- starttime_str, sizeof(starttime_str), TRUE);
+ krb5_format_time(context, *starttime,
+ starttime_str, sizeof(starttime_str), TRUE);
else
strlcpy(starttime_str, "unset", sizeof(starttime_str));
- krb5_format_time(context, endtime,
- endtime_str, sizeof(endtime_str), TRUE);
+ krb5_format_time(context, endtime,
+ endtime_str, sizeof(endtime_str), TRUE);
if (renew_till)
- krb5_format_time(context, *renew_till,
- renewtime_str, sizeof(renewtime_str), TRUE);
+ krb5_format_time(context, *renew_till,
+ renewtime_str, sizeof(renewtime_str), TRUE);
else
strlcpy(renewtime_str, "unset", sizeof(renewtime_str));
-
+
kdc_log(context, config, 5,
"%s authtime: %s starttime: %s endtime: %s renew till: %s",
type, authtime_str, starttime_str, endtime_str, renewtime_str);
}
static void
-log_patypes(krb5_context context,
+log_patypes(krb5_context context,
krb5_kdc_configuration *config,
METHOD_DATA *padata)
{
struct rk_strpool *p = NULL;
char *str;
- int i;
-
+ size_t i;
+
for (i = 0; i < padata->len; i++) {
switch(padata->val[i].padata_type) {
case KRB5_PADATA_PK_AS_REQ:
@@ -224,7 +307,7 @@ log_patypes(krb5_context context,
}
if (p == NULL)
p = rk_strpoolprintf(p, "none");
-
+
str = rk_strpoolcollect(p);
kdc_log(context, config, 0, "Client sent patypes: %s", str);
free(str);
@@ -238,23 +321,25 @@ log_patypes(krb5_context context,
krb5_error_code
_kdc_encode_reply(krb5_context context,
krb5_kdc_configuration *config,
- KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek,
- krb5_enctype etype,
+ KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek,
+ krb5_enctype etype,
int skvno, const EncryptionKey *skey,
- int ckvno, const EncryptionKey *ckey,
+ int ckvno, const EncryptionKey *reply_key,
+ int rk_is_subkey,
const char **e_text,
krb5_data *reply)
{
unsigned char *buf;
size_t buf_size;
- size_t len;
+ size_t len = 0;
krb5_error_code ret;
krb5_crypto crypto;
ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
if(ret) {
- kdc_log(context, config, 0, "Failed to encode ticket: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to encode ticket: %s", msg);
+ krb5_free_error_message(context, msg);
return ret;
}
if(buf_size != len) {
@@ -266,13 +351,15 @@ _kdc_encode_reply(krb5_context context,
ret = krb5_crypto_init(context, skey, etype, &crypto);
if (ret) {
+ const char *msg;
free(buf);
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
+ msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+ krb5_free_error_message(context, msg);
return ret;
}
- ret = krb5_encrypt_EncryptedData(context,
+ ret = krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TICKET,
buf,
@@ -282,18 +369,20 @@ _kdc_encode_reply(krb5_context context,
free(buf);
krb5_crypto_destroy(context, crypto);
if(ret) {
- kdc_log(context, config, 0, "Failed to encrypt data: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to encrypt data: %s", msg);
+ krb5_free_error_message(context, msg);
return ret;
}
-
+
if(rep->msg_type == krb_as_rep && !config->encode_as_rep_as_tgs_rep)
ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);
else
ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
if(ret) {
- kdc_log(context, config, 0, "Failed to encode KDC-REP: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
+ krb5_free_error_message(context, msg);
return ret;
}
if(buf_size != len) {
@@ -302,11 +391,12 @@ _kdc_encode_reply(krb5_context context,
*e_text = "KDC internal error";
return KRB5KRB_ERR_GENERIC;
}
- ret = krb5_crypto_init(context, ckey, 0, &crypto);
+ ret = krb5_crypto_init(context, reply_key, 0, &crypto);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
free(buf);
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
+ kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+ krb5_free_error_message(context, msg);
return ret;
}
if(rep->msg_type == krb_as_rep) {
@@ -322,7 +412,7 @@ _kdc_encode_reply(krb5_context context,
} else {
krb5_encrypt_EncryptedData(context,
crypto,
- KRB5_KU_TGS_REP_ENC_PART_SESSION,
+ rk_is_subkey ? KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : KRB5_KU_TGS_REP_ENC_PART_SESSION,
buf,
len,
ckvno,
@@ -332,8 +422,9 @@ _kdc_encode_reply(krb5_context context,
}
krb5_crypto_destroy(context, crypto);
if(ret) {
- kdc_log(context, config, 0, "Failed to encode KDC-REP: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", msg);
+ krb5_free_error_message(context, msg);
return ret;
}
if(buf_size != len) {
@@ -362,7 +453,7 @@ older_enctype(krb5_enctype enctype)
case ETYPE_DES3_CBC_SHA1:
case ETYPE_ARCFOUR_HMAC_MD5:
case ETYPE_ARCFOUR_HMAC_MD5_56:
- /*
+ /*
* The following three is "old" windows enctypes and is needed for
* windows 2000 hosts.
*/
@@ -375,18 +466,6 @@ older_enctype(krb5_enctype enctype)
}
}
-static int
-only_older_enctype_p(const KDC_REQ *req)
-{
- int i;
-
- for(i = 0; i < req->req_body.etype.len; i++) {
- if (!older_enctype(req->req_body.etype.val[i]))
- return 0;
- }
- return 1;
-}
-
/*
*
*/
@@ -404,7 +483,7 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
else if(key->salt->type == hdb_afs3_salt)
*ent->salttype = 2;
else {
- kdc_log(context, config, 0, "unknown salt-type: %d",
+ kdc_log(context, config, 0, "unknown salt-type: %d",
key->salt->type);
return KRB5KRB_ERR_GENERIC;
}
@@ -417,7 +496,7 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
ALLOC(ent->salttype);
*ent->salttype = key->salt->type;
#else
- /*
+ /*
* We shouldn't sent salttype since it is incompatible with the
* specification and it breaks windows clients. The afs
* salting problem is solved by using KRB5-PADATA-AFS3-SALT
@@ -440,74 +519,25 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
}
static krb5_error_code
-get_pa_etype_info(krb5_context context,
+get_pa_etype_info(krb5_context context,
krb5_kdc_configuration *config,
- METHOD_DATA *md, hdb_entry *client,
- ENCTYPE *etypes, unsigned int etypes_len)
+ METHOD_DATA *md, Key *ckey)
{
krb5_error_code ret = 0;
- int i, j;
- unsigned int n = 0;
ETYPE_INFO pa;
unsigned char *buf;
size_t len;
-
- pa.len = client->keys.len;
- if(pa.len > UINT_MAX/sizeof(*pa.val))
- return ERANGE;
- pa.val = malloc(pa.len * sizeof(*pa.val));
+
+ pa.len = 1;
+ pa.val = calloc(1, sizeof(pa.val[0]));
if(pa.val == NULL)
return ENOMEM;
- memset(pa.val, 0, pa.len * sizeof(*pa.val));
-
- for(i = 0; i < client->keys.len; i++) {
- for (j = 0; j < n; j++)
- if (pa.val[j].etype == client->keys.val[i].key.keytype)
- goto skip1;
- for(j = 0; j < etypes_len; j++) {
- if(client->keys.val[i].key.keytype == etypes[j]) {
- if (krb5_enctype_valid(context, etypes[j]) != 0)
- continue;
- if (!older_enctype(etypes[j]))
- continue;
- if (n >= pa.len)
- krb5_abortx(context, "internal error: n >= p.len");
- if((ret = make_etype_info_entry(context,
- &pa.val[n++],
- &client->keys.val[i])) != 0) {
- free_ETYPE_INFO(&pa);
- return ret;
- }
- break;
- }
- }
- skip1:;
- }
- for(i = 0; i < client->keys.len; i++) {
- /* already added? */
- for(j = 0; j < etypes_len; j++) {
- if(client->keys.val[i].key.keytype == etypes[j])
- goto skip2;
- }
- if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
- continue;
- if (!older_enctype(etypes[j]))
- continue;
- if (n >= pa.len)
- krb5_abortx(context, "internal error: n >= p.len");
- if((ret = make_etype_info_entry(context,
- &pa.val[n++],
- &client->keys.val[i])) != 0) {
- free_ETYPE_INFO(&pa);
- return ret;
- }
- skip2:;
- }
-
- if(n < pa.len) {
- /* stripped out dups, newer enctypes, and not valid enctypes */
- pa.len = n;
+
+ ret = make_etype_info_entry(context, &pa.val[0], ckey);
+ if (ret) {
+ free_ETYPE_INFO(&pa);
+ return ret;
}
ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
@@ -565,8 +595,8 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
ent->s2kparams = NULL;
return ENOMEM;
}
- _krb5_put_int(ent->s2kparams->data,
- _krb5_AES_string_to_default_iterator,
+ _krb5_put_int(ent->s2kparams->data,
+ _krb5_AES_string_to_default_iterator,
ent->s2kparams->length);
break;
case ETYPE_DES_CBC_CRC:
@@ -584,7 +614,7 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
ent->s2kparams = NULL;
return ENOMEM;
}
- _krb5_put_int(ent->s2kparams->data,
+ _krb5_put_int(ent->s2kparams->data,
1,
ent->s2kparams->length);
}
@@ -602,68 +632,24 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
*/
static krb5_error_code
-get_pa_etype_info2(krb5_context context,
+get_pa_etype_info2(krb5_context context,
krb5_kdc_configuration *config,
- METHOD_DATA *md, hdb_entry *client,
- ENCTYPE *etypes, unsigned int etypes_len)
+ METHOD_DATA *md, Key *ckey)
{
krb5_error_code ret = 0;
- int i, j;
- unsigned int n = 0;
ETYPE_INFO2 pa;
unsigned char *buf;
size_t len;
- pa.len = client->keys.len;
- if(pa.len > UINT_MAX/sizeof(*pa.val))
- return ERANGE;
- pa.val = malloc(pa.len * sizeof(*pa.val));
+ pa.len = 1;
+ pa.val = calloc(1, sizeof(pa.val[0]));
if(pa.val == NULL)
return ENOMEM;
- memset(pa.val, 0, pa.len * sizeof(*pa.val));
-
- for(i = 0; i < client->keys.len; i++) {
- for (j = 0; j < n; j++)
- if (pa.val[j].etype == client->keys.val[i].key.keytype)
- goto skip1;
- for(j = 0; j < etypes_len; j++) {
- if(client->keys.val[i].key.keytype == etypes[j]) {
- if (krb5_enctype_valid(context, etypes[j]) != 0)
- continue;
- if (n >= pa.len)
- krb5_abortx(context, "internal error: n >= p.len");
- if((ret = make_etype_info2_entry(&pa.val[n++],
- &client->keys.val[i])) != 0) {
- free_ETYPE_INFO2(&pa);
- return ret;
- }
- break;
- }
- }
- skip1:;
- }
- /* send enctypes that the client doesn't know about too */
- for(i = 0; i < client->keys.len; i++) {
- /* already added? */
- for(j = 0; j < etypes_len; j++) {
- if(client->keys.val[i].key.keytype == etypes[j])
- goto skip2;
- }
- if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
- continue;
- if (n >= pa.len)
- krb5_abortx(context, "internal error: n >= p.len");
- if((ret = make_etype_info2_entry(&pa.val[n++],
- &client->keys.val[i])) != 0) {
- free_ETYPE_INFO2(&pa);
- return ret;
- }
- skip2:;
- }
-
- if(n < pa.len) {
- /* stripped out dups, and not valid enctypes */
- pa.len = n;
+
+ ret = make_etype_info2_entry(&pa.val[0], ckey);
+ if (ret) {
+ free_ETYPE_INFO2(&pa);
+ return ret;
}
ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
@@ -693,10 +679,12 @@ log_as_req(krb5_context context,
const KDC_REQ_BODY *b)
{
krb5_error_code ret;
- struct rk_strpool *p = NULL;
+ struct rk_strpool *p;
char *str;
- int i;
-
+ size_t i;
+
+ p = rk_strpoolprintf(NULL, "%s", "Client supported enctypes: ");
+
for (i = 0; i < b->etype.len; i++) {
ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
if (ret == 0) {
@@ -713,10 +701,6 @@ log_as_req(krb5_context context,
}
if (p == NULL)
p = rk_strpoolprintf(p, "no encryption types");
-
- str = rk_strpoolcollect(p);
- kdc_log(context, config, 0, "Client supported enctypes: %s", str);
- free(str);
{
char *cet;
@@ -726,21 +710,26 @@ log_as_req(krb5_context context,
if(ret == 0) {
ret = krb5_enctype_to_string(context, setype, &set);
if (ret == 0) {
- kdc_log(context, config, 5, "Using %s/%s", cet, set);
+ p = rk_strpoolprintf(p, ", using %s/%s", cet, set);
free(set);
}
free(cet);
}
if (ret != 0)
- kdc_log(context, config, 5, "Using e-types %d/%d", cetype, setype);
+ p = rk_strpoolprintf(p, ", using enctypes %d/%d",
+ cetype, setype);
}
-
+
+ str = rk_strpoolcollect(p);
+ kdc_log(context, config, 0, "%s", str);
+ free(str);
+
{
char fixedstr[128];
- unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(),
+ unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(),
fixedstr, sizeof(fixedstr));
if(*fixedstr)
- kdc_log(context, config, 2, "Requested flags: %s", fixedstr);
+ kdc_log(context, config, 0, "Requested flags: %s", fixedstr);
}
}
@@ -751,65 +740,76 @@ log_as_req(krb5_context context,
*/
krb5_error_code
-_kdc_check_flags(krb5_context context,
- krb5_kdc_configuration *config,
- hdb_entry_ex *client_ex, const char *client_name,
- hdb_entry_ex *server_ex, const char *server_name,
- krb5_boolean is_as_req)
+kdc_check_flags(krb5_context context,
+ krb5_kdc_configuration *config,
+ hdb_entry_ex *client_ex, const char *client_name,
+ hdb_entry_ex *server_ex, const char *server_name,
+ krb5_boolean is_as_req)
{
if(client_ex != NULL) {
hdb_entry *client = &client_ex->entry;
/* check client */
+ if (client->flags.locked_out) {
+ kdc_log(context, config, 0,
+ "Client (%s) is locked out", client_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
if (client->flags.invalid) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Client (%s) has invalid bit set", client_name);
return KRB5KDC_ERR_POLICY;
}
-
+
if(!client->flags.client){
kdc_log(context, config, 0,
"Principal may not act as client -- %s", client_name);
return KRB5KDC_ERR_POLICY;
}
-
+
if (client->valid_start && *client->valid_start > kdc_time) {
char starttime_str[100];
- krb5_format_time(context, *client->valid_start,
- starttime_str, sizeof(starttime_str), TRUE);
+ krb5_format_time(context, *client->valid_start,
+ starttime_str, sizeof(starttime_str), TRUE);
kdc_log(context, config, 0,
- "Client not yet valid until %s -- %s",
+ "Client not yet valid until %s -- %s",
starttime_str, client_name);
return KRB5KDC_ERR_CLIENT_NOTYET;
}
-
+
if (client->valid_end && *client->valid_end < kdc_time) {
char endtime_str[100];
- krb5_format_time(context, *client->valid_end,
- endtime_str, sizeof(endtime_str), TRUE);
+ krb5_format_time(context, *client->valid_end,
+ endtime_str, sizeof(endtime_str), TRUE);
kdc_log(context, config, 0,
"Client expired at %s -- %s",
endtime_str, client_name);
return KRB5KDC_ERR_NAME_EXP;
}
-
- if (client->pw_end && *client->pw_end < kdc_time
+
+ if (client->pw_end && *client->pw_end < kdc_time
&& (server_ex == NULL || !server_ex->entry.flags.change_pw)) {
char pwend_str[100];
- krb5_format_time(context, *client->pw_end,
- pwend_str, sizeof(pwend_str), TRUE);
+ krb5_format_time(context, *client->pw_end,
+ pwend_str, sizeof(pwend_str), TRUE);
kdc_log(context, config, 0,
- "Client's key has expired at %s -- %s",
+ "Client's key has expired at %s -- %s",
pwend_str, client_name);
return KRB5KDC_ERR_KEY_EXPIRED;
}
}
/* check server */
-
+
if (server_ex != NULL) {
hdb_entry *server = &server_ex->entry;
+ if (server->flags.locked_out) {
+ kdc_log(context, config, 0,
+ "Client server locked out -- %s", server_name);
+ return KRB5KDC_ERR_POLICY;
+ }
if (server->flags.invalid) {
kdc_log(context, config, 0,
"Server has invalid flag set -- %s", server_name);
@@ -830,8 +830,8 @@ _kdc_check_flags(krb5_context context,
if (server->valid_start && *server->valid_start > kdc_time) {
char starttime_str[100];
- krb5_format_time(context, *server->valid_start,
- starttime_str, sizeof(starttime_str), TRUE);
+ krb5_format_time(context, *server->valid_start,
+ starttime_str, sizeof(starttime_str), TRUE);
kdc_log(context, config, 0,
"Server not yet valid until %s -- %s",
starttime_str, server_name);
@@ -840,20 +840,20 @@ _kdc_check_flags(krb5_context context,
if (server->valid_end && *server->valid_end < kdc_time) {
char endtime_str[100];
- krb5_format_time(context, *server->valid_end,
- endtime_str, sizeof(endtime_str), TRUE);
+ krb5_format_time(context, *server->valid_end,
+ endtime_str, sizeof(endtime_str), TRUE);
kdc_log(context, config, 0,
- "Server expired at %s -- %s",
+ "Server expired at %s -- %s",
endtime_str, server_name);
return KRB5KDC_ERR_SERVICE_EXP;
}
if (server->pw_end && *server->pw_end < kdc_time) {
char pwend_str[100];
- krb5_format_time(context, *server->pw_end,
- pwend_str, sizeof(pwend_str), TRUE);
+ krb5_format_time(context, *server->pw_end,
+ pwend_str, sizeof(pwend_str), TRUE);
kdc_log(context, config, 0,
- "Server's key has expired at -- %s",
+ "Server's key has expired at -- %s",
pwend_str, server_name);
return KRB5KDC_ERR_KEY_EXPIRED;
}
@@ -868,7 +868,7 @@ _kdc_check_flags(krb5_context context,
*/
krb5_boolean
-_kdc_check_addresses(krb5_context context,
+_kdc_check_addresses(krb5_context context,
krb5_kdc_configuration *config,
HostAddresses *addresses, const struct sockaddr *from)
{
@@ -876,14 +876,14 @@ _kdc_check_addresses(krb5_context context,
krb5_address addr;
krb5_boolean result;
krb5_boolean only_netbios = TRUE;
- int i;
-
+ size_t i;
+
if(config->check_ticket_addresses == 0)
return TRUE;
if(addresses == NULL)
return config->allow_null_ticket_addresses;
-
+
for (i = 0; i < addresses->len; ++i) {
if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
only_netbios = FALSE;
@@ -919,7 +919,7 @@ send_pac_p(krb5_context context, KDC_REQ *req)
PA_PAC_REQUEST pacreq;
const PA_DATA *pa;
int i = 0;
-
+
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
if (pa == NULL)
return TRUE;
@@ -937,15 +937,26 @@ send_pac_p(krb5_context context, KDC_REQ *req)
return TRUE;
}
+krb5_boolean
+_kdc_is_anonymous(krb5_context context, krb5_principal principal)
+{
+ if (principal->name.name_type != KRB5_NT_WELLKNOWN ||
+ principal->name.name_string.len != 2 ||
+ strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
+ strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
+ return 0;
+ return 1;
+}
+
/*
*
*/
krb5_error_code
-_kdc_as_rep(krb5_context context,
+_kdc_as_rep(krb5_context context,
krb5_kdc_configuration *config,
- KDC_REQ *req,
- const krb5_data *req_buffer,
+ KDC_REQ *req,
+ const krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *from_addr,
@@ -955,7 +966,8 @@ _kdc_as_rep(krb5_context context,
AS_REP rep;
KDCOptions f = b->kdc_options;
hdb_entry_ex *client = NULL, *server = NULL;
- krb5_enctype cetype, setype, sessionetype;
+ HDB *clientdb;
+ krb5_enctype setype, sessionetype;
krb5_data e_data;
EncTicketPart et;
EncKDCRepPart ek;
@@ -965,15 +977,20 @@ _kdc_as_rep(krb5_context context,
const char *e_text = NULL;
krb5_crypto crypto;
Key *ckey, *skey;
- EncryptionKey *reply_key;
- int flags = 0;
+ EncryptionKey *reply_key = NULL, session_key;
+ int flags = HDB_F_FOR_AS_REQ;
#ifdef PKINIT
pk_client_params *pkp = NULL;
#endif
memset(&rep, 0, sizeof(rep));
+ memset(&session_key, 0, sizeof(session_key));
krb5_data_zero(&e_data);
+ ALLOC(rep.padata);
+ rep.padata->len = 0;
+ rep.padata->val = NULL;
+
if (f.canonicalize)
flags |= HDB_F_CANON;
@@ -989,37 +1006,21 @@ _kdc_as_rep(krb5_context context,
ret = krb5_unparse_name(context, server_princ, &server_name);
}
if (ret) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"AS-REQ malformed server name from %s", from);
goto out;
}
-
if(b->cname == NULL){
ret = KRB5KRB_ERR_GENERIC;
e_text = "No client in request";
} else {
+ ret = _krb5_principalname2krb5_principal (context,
+ &client_princ,
+ *(b->cname),
+ b->realm);
+ if (ret)
+ goto out;
- if (b->cname->name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
- if (b->cname->name_string.len != 1) {
- kdc_log(context, config, 0,
- "AS-REQ malformed canon request from %s, "
- "enterprise name with %d name components",
- from, b->cname->name_string.len);
- ret = KRB5_PARSE_MALFORMED;
- goto out;
- }
- ret = krb5_parse_name(context, b->cname->name_string.val[0],
- &client_princ);
- if (ret)
- goto out;
- } else {
- ret = _krb5_principalname2krb5_principal (context,
- &client_princ,
- *(b->cname),
- b->realm);
- if (ret)
- goto out;
- }
ret = krb5_unparse_name(context, client_princ, &client_name);
}
if (ret) {
@@ -1028,41 +1029,91 @@ _kdc_as_rep(krb5_context context,
goto out;
}
- kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
+ kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
client_name, from, server_name);
- ret = _kdc_db_fetch(context, config, client_princ,
- HDB_F_GET_CLIENT | flags, NULL, &client);
- if(ret){
- kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
- krb5_get_err_text(context, ret));
+ /*
+ *
+ */
+
+ if (_kdc_is_anonymous(context, client_princ)) {
+ if (!b->kdc_options.request_anonymous) {
+ kdc_log(context, config, 0, "Anonymous ticket w/o anonymous flag");
+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
+ } else if (b->kdc_options.request_anonymous) {
+ kdc_log(context, config, 0,
+ "Request for a anonymous ticket with non "
+ "anonymous client name: %s", client_name);
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
goto out;
}
+ /*
+ *
+ */
+
+ ret = _kdc_db_fetch(context, config, client_princ,
+ HDB_F_GET_CLIENT | flags, NULL,
+ &clientdb, &client);
+ if(ret == HDB_ERR_NOT_FOUND_HERE) {
+ kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy", client_name);
+ goto out;
+ } else if(ret){
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, msg);
+ krb5_free_error_message(context, msg);
+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+ goto out;
+ }
ret = _kdc_db_fetch(context, config, server_princ,
- HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
- NULL, &server);
- if(ret){
- kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name,
- krb5_get_err_text(context, ret));
+ HDB_F_GET_SERVER|HDB_F_GET_KRBTGT | flags,
+ NULL, NULL, &server);
+ if(ret == HDB_ERR_NOT_FOUND_HERE) {
+ kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", server_name);
+ goto out;
+ } else if(ret){
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name, msg);
+ krb5_free_error_message(context, msg);
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out;
}
- ret = _kdc_windc_client_access(context, client, req);
- if(ret)
- goto out;
+ memset(&et, 0, sizeof(et));
+ memset(&ek, 0, sizeof(ek));
- ret = _kdc_check_flags(context, config,
- client, client_name,
- server, server_name,
- TRUE);
- if(ret)
+ /*
+ * Select a session enctype from the list of the crypto system
+ * supported enctypes that is supported by the client and is one of
+ * the enctype of the enctype of the service (likely krbtgt).
+ *
+ * The latter is used as a hint of what enctypes all KDC support,
+ * to make sure a newer version of KDC won't generate a session
+ * enctype that an older version of a KDC in the same realm can't
+ * decrypt.
+ */
+ ret = _kdc_find_etype(context, config->as_use_strongest_session_key, FALSE,
+ client, b->etype.val, b->etype.len, &sessionetype,
+ NULL);
+ if (ret) {
+ kdc_log(context, config, 0,
+ "Client (%s) from %s has no common enctypes with KDC "
+ "to use for the session key",
+ client_name, from);
goto out;
+ }
+ /*
+ * But if the KDC admin is paranoid and doesn't want to have "not
+ * the best" enctypes on the krbtgt, lets save the best pick from
+ * the client list and hope that that will work for any other
+ * KDCs.
+ */
- memset(&et, 0, sizeof(et));
- memset(&ek, 0, sizeof(ek));
+ /*
+ * Pre-auth processing
+ */
if(req->padata){
int i;
@@ -1072,27 +1123,25 @@ _kdc_as_rep(krb5_context context,
log_patypes(context, config, req->padata);
#ifdef PKINIT
- kdc_log(context, config, 5,
+ kdc_log(context, config, 5,
"Looking for PKINIT pa-data -- %s", client_name);
e_text = "No PKINIT PA found";
i = 0;
- if ((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))
- ;
+ pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ);
if (pa == NULL) {
i = 0;
- if((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))
- ;
+ pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN);
}
if (pa) {
char *client_cert = NULL;
- ret = _kdc_pk_rd_padata(context, config, req, pa, &pkp);
+ ret = _kdc_pk_rd_padata(context, config, req, pa, client, &pkp);
if (ret) {
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- kdc_log(context, config, 5,
- "Failed to decode PKINIT PA-DATA -- %s",
+ kdc_log(context, config, 5,
+ "Failed to decode PKINIT PA-DATA -- %s",
client_name);
goto ts_enc;
}
@@ -1101,6 +1150,7 @@ _kdc_as_rep(krb5_context context,
ret = _kdc_pk_check_client(context,
config,
+ clientdb,
client,
pkp,
&client_cert);
@@ -1113,10 +1163,11 @@ _kdc_as_rep(krb5_context context,
pkp = NULL;
goto out;
}
+
found_pa = 1;
et.flags.pre_authent = 1;
kdc_log(context, config, 0,
- "PKINIT pre-authentication succeeded -- %s using %s",
+ "PKINIT pre-authentication succeeded -- %s using %s",
client_name, client_cert);
free(client_cert);
if (pkp)
@@ -1124,7 +1175,7 @@ _kdc_as_rep(krb5_context context,
}
ts_enc:
#endif
- kdc_log(context, config, 5, "Looking for ENC-TS pa-data -- %s",
+ kdc_log(context, config, 5, "Looking for ENC-TS pa-data -- %s",
client_name);
i = 0;
@@ -1136,21 +1187,27 @@ _kdc_as_rep(krb5_context context,
EncryptedData enc_data;
Key *pa_key;
char *str;
-
+
found_pa = 1;
-
+
+ if (b->kdc_options.request_anonymous) {
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ kdc_log(context, config, 0, "ENC-TS doesn't support anon");
+ goto out;
+ }
+
ret = decode_EncryptedData(pa->padata_value.data,
pa->padata_value.length,
&enc_data,
&len);
if (ret) {
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- kdc_log(context, config, 5, "Failed to decode PA-DATA -- %s",
+ kdc_log(context, config, 5, "Failed to decode PA-DATA -- %s",
client_name);
goto out;
}
-
- ret = hdb_enctype2key(context, &client->entry,
+
+ ret = hdb_enctype2key(context, &client->entry,
enc_data.etype, &pa_key);
if(ret){
char *estr;
@@ -1159,24 +1216,25 @@ _kdc_as_rep(krb5_context context,
if(krb5_enctype_to_string(context, enc_data.etype, &estr))
estr = NULL;
if(estr == NULL)
- kdc_log(context, config, 5,
- "No client key matching pa-data (%d) -- %s",
+ kdc_log(context, config, 5,
+ "No client key matching pa-data (%d) -- %s",
enc_data.etype, client_name);
else
kdc_log(context, config, 5,
- "No client key matching pa-data (%s) -- %s",
+ "No client key matching pa-data (%s) -- %s",
estr, client_name);
free(estr);
-
free_EncryptedData(&enc_data);
+
continue;
}
try_next_key:
ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);
if (ret) {
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+ krb5_free_error_message(context, msg);
free_EncryptedData(&enc_data);
continue;
}
@@ -1187,26 +1245,36 @@ _kdc_as_rep(krb5_context context,
&enc_data,
&ts_data);
krb5_crypto_destroy(context, crypto);
+ /*
+ * Since the user might have several keys with the same
+ * enctype but with diffrent salting, we need to try all
+ * the keys with the same enctype.
+ */
if(ret){
krb5_error_code ret2;
- ret2 = krb5_enctype_to_string(context,
+ const char *msg = krb5_get_error_message(context, ret);
+
+ ret2 = krb5_enctype_to_string(context,
pa_key->key.keytype, &str);
if (ret2)
str = NULL;
- kdc_log(context, config, 5,
+ kdc_log(context, config, 5,
"Failed to decrypt PA-DATA -- %s "
"(enctype %s) error %s",
- client_name,
- str ? str : "unknown enctype",
- krb5_get_err_text(context, ret));
+ client_name, str ? str : "unknown enctype", msg);
+ krb5_free_error_message(context, msg);
free(str);
- if(hdb_next_enctype2key(context, &client->entry,
+ if(hdb_next_enctype2key(context, &client->entry,
enc_data.etype, &pa_key) == 0)
goto try_next_key;
e_text = "Failed to decrypt PA-DATA";
free_EncryptedData(&enc_data);
+
+ if (clientdb->hdb_auth_status)
+ (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD);
+
ret = KRB5KDC_ERR_PREAUTH_FAILED;
continue;
}
@@ -1219,7 +1287,7 @@ _kdc_as_rep(krb5_context context,
if(ret){
e_text = "Failed to decode PA-ENC-TS-ENC";
ret = KRB5KDC_ERR_PREAUTH_FAILED;
- kdc_log(context, config,
+ kdc_log(context, config,
5, "Failed to decode PA-ENC-TS_ENC -- %s",
client_name);
continue;
@@ -1227,41 +1295,39 @@ _kdc_as_rep(krb5_context context,
free_PA_ENC_TS_ENC(&p);
if (abs(kdc_time - p.patimestamp) > context->max_skew) {
char client_time[100];
-
- krb5_format_time(context, p.patimestamp,
- client_time, sizeof(client_time), TRUE);
+
+ krb5_format_time(context, p.patimestamp,
+ client_time, sizeof(client_time), TRUE);
ret = KRB5KRB_AP_ERR_SKEW;
kdc_log(context, config, 0,
"Too large time skew, "
- "client time %s is out by %u > %u seconds -- %s",
- client_time,
- (unsigned)abs(kdc_time - p.patimestamp),
+ "client time %s is out by %u > %u seconds -- %s",
+ client_time,
+ (unsigned)abs(kdc_time - p.patimestamp),
context->max_skew,
client_name);
-#if 0
- /* This code is from samba, needs testing */
- /*
- * the following is needed to make windows clients
- * to retry using the timestamp in the error message
- *
- * this is maybe a bug in windows to not trying when e_text
- * is present...
+
+ /*
+ * The following is needed to make windows clients to
+ * retry using the timestamp in the error message, if
+ * there is a e_text, they become unhappy.
*/
e_text = NULL;
-#else
- e_text = "Too large time skew";
-#endif
goto out;
}
et.flags.pre_authent = 1;
- ret = krb5_enctype_to_string(context,pa_key->key.keytype, &str);
+ set_salt_padata(rep.padata, pa_key->salt);
+
+ reply_key = &pa_key->key;
+
+ ret = krb5_enctype_to_string(context, pa_key->key.keytype, &str);
if (ret)
str = NULL;
kdc_log(context, config, 2,
- "ENC-TS Pre-authentication succeeded -- %s using %s",
+ "ENC-TS Pre-authentication succeeded -- %s using %s",
client_name, str ? str : "unknown enctype");
free(str);
break;
@@ -1279,6 +1345,7 @@ _kdc_as_rep(krb5_context context,
goto out;
}
}else if (config->require_preauth
+ || b->kdc_options.request_anonymous /* hack to force anon */
|| client->entry.flags.require_preauth
|| server->entry.flags.require_preauth) {
METHOD_DATA method_data;
@@ -1286,11 +1353,15 @@ _kdc_as_rep(krb5_context context,
unsigned char *buf;
size_t len;
- use_pa:
+ use_pa:
method_data.len = 0;
method_data.val = NULL;
ret = realloc_method_data(&method_data);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ goto out;
+ }
pa = &method_data.val[method_data.len-1];
pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
pa->padata_value.length = 0;
@@ -1298,36 +1369,62 @@ _kdc_as_rep(krb5_context context,
#ifdef PKINIT
ret = realloc_method_data(&method_data);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ goto out;
+ }
pa = &method_data.val[method_data.len-1];
pa->padata_type = KRB5_PADATA_PK_AS_REQ;
pa->padata_value.length = 0;
pa->padata_value.data = NULL;
ret = realloc_method_data(&method_data);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ goto out;
+ }
pa = &method_data.val[method_data.len-1];
pa->padata_type = KRB5_PADATA_PK_AS_REQ_WIN;
pa->padata_value.length = 0;
pa->padata_value.data = NULL;
#endif
- /*
- * RFC4120 requires:
- * - If the client only knows about old enctypes, then send
- * both info replies (we send 'info' first in the list).
- * - If the client is 'modern', because it knows about 'new'
- * enctype types, then only send the 'info2' reply.
+ /*
+ * If there is a client key, send ETYPE_INFO{,2}
*/
+ ret = _kdc_find_etype(context,
+ config->preauth_use_strongest_session_key, TRUE,
+ client, b->etype.val, b->etype.len, NULL, &ckey);
+ if (ret == 0) {
- /* XXX check ret */
- if (only_older_enctype_p(req))
- ret = get_pa_etype_info(context, config,
- &method_data, &client->entry,
- b->etype.val, b->etype.len);
- /* XXX check ret */
- ret = get_pa_etype_info2(context, config, &method_data,
- &client->entry, b->etype.val, b->etype.len);
+ /*
+ * RFC4120 requires:
+ * - If the client only knows about old enctypes, then send
+ * both info replies (we send 'info' first in the list).
+ * - If the client is 'modern', because it knows about 'new'
+ * enctype types, then only send the 'info2' reply.
+ *
+ * Before we send the full list of etype-info data, we pick
+ * the client key we would have used anyway below, just pick
+ * that instead.
+ */
+
+ if (older_enctype(ckey->key.keytype)) {
+ ret = get_pa_etype_info(context, config,
+ &method_data, ckey);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ goto out;
+ }
+ }
+ ret = get_pa_etype_info2(context, config,
+ &method_data, ckey);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ goto out;
+ }
+ }
-
ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
free_METHOD_DATA(&method_data);
@@ -1342,103 +1439,54 @@ _kdc_as_rep(krb5_context context,
client_name);
goto out;
}
-
+
+ if (clientdb->hdb_auth_status)
+ (clientdb->hdb_auth_status)(context, clientdb, client,
+ HDB_AUTH_SUCCESS);
+
/*
- * Find the client key (for preauth ENC-TS verification and reply
- * encryption). Then the best encryption type for the KDC and
- * last the best session key that shared between the client and
- * KDC runtime enctypes.
+ * Verify flags after the user been required to prove its identity
+ * with in a preauth mech.
*/
- ret = _kdc_find_etype(context, client, b->etype.val, b->etype.len,
- &ckey, &cetype);
- if (ret) {
- kdc_log(context, config, 0,
- "Client (%s) has no support for etypes", client_name);
+ ret = _kdc_check_access(context, config, client, client_name,
+ server, server_name,
+ req, &e_data);
+ if(ret)
goto out;
- }
-
+
+ /*
+ * Selelct the best encryption type for the KDC with out regard to
+ * the client since the client never needs to read that data.
+ */
+
ret = _kdc_get_preferred_key(context, config,
server, server_name,
&setype, &skey);
if(ret)
goto out;
- /*
- * Select a session enctype from the list of the crypto systems
- * supported enctype, is supported by the client and is one of the
- * enctype of the enctype of the krbtgt.
- *
- * The later is used as a hint what enctype all KDC are supporting
- * to make sure a newer version of KDC wont generate a session
- * enctype that and older version of a KDC in the same realm can't
- * decrypt.
- *
- * But if the KDC admin is paranoid and doesn't want to have "no
- * the best" enctypes on the krbtgt, lets save the best pick from
- * the client list and hope that that will work for any other
- * KDCs.
- */
- {
- const krb5_enctype *p;
- krb5_enctype clientbest = ETYPE_NULL;
- int i, j;
-
- p = krb5_kerberos_enctypes(context);
-
- sessionetype = ETYPE_NULL;
-
- for (i = 0; p[i] != ETYPE_NULL && sessionetype == ETYPE_NULL; i++) {
- if (krb5_enctype_valid(context, p[i]) != 0)
- continue;
-
- for (j = 0; j < b->etype.len && sessionetype == ETYPE_NULL; j++) {
- Key *dummy;
- /* check with client */
- if (p[i] != b->etype.val[j])
- continue;
- /* save best of union of { client, crypto system } */
- if (clientbest == ETYPE_NULL)
- clientbest = p[i];
- /* check with krbtgt */
- ret = hdb_enctype2key(context, &server->entry, p[i], &dummy);
- if (ret)
- continue;
- sessionetype = p[i];
- }
- }
- /* if krbtgt had no shared keys with client, pick clients best */
- if (clientbest != ETYPE_NULL && sessionetype == ETYPE_NULL) {
- sessionetype = clientbest;
- } else if (sessionetype == ETYPE_NULL) {
- kdc_log(context, config, 0,
- "Client (%s) from %s has no common enctypes with KDC"
- "to use for the session key",
- client_name, from);
- goto out;
- }
- }
-
- log_as_req(context, config, cetype, setype, b);
-
if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
|| (f.request_anonymous && !config->allow_anonymous)) {
ret = KRB5KDC_ERR_BADOPTION;
+ e_text = "Bad KDC options";
kdc_log(context, config, 0, "Bad KDC options -- %s", client_name);
goto out;
}
-
+
rep.pvno = 5;
rep.msg_type = krb_as_rep;
- copy_Realm(&client->entry.principal->realm, &rep.crealm);
- if (f.request_anonymous)
- _kdc_make_anonymous_principalname (&rep.cname);
- else
- _krb5_principal2principalname(&rep.cname,
- client->entry.principal);
+
+ ret = copy_Realm(&client->entry.principal->realm, &rep.crealm);
+ if (ret)
+ goto out;
+ ret = _krb5_principal2principalname(&rep.cname, client->entry.principal);
+ if (ret)
+ goto out;
+
rep.ticket.tkt_vno = 5;
copy_Realm(&server->entry.principal->realm, &rep.ticket.realm);
- _krb5_principal2principalname(&rep.ticket.sname,
+ _krb5_principal2principalname(&rep.ticket.sname,
server->entry.principal);
/* java 1.6 expects the name to be the same type, lets allow that
* uncomplicated name-types. */
@@ -1451,6 +1499,7 @@ _kdc_as_rep(krb5_context context,
if(client->entry.flags.forwardable && server->entry.flags.forwardable)
et.flags.forwardable = f.forwardable;
else if (f.forwardable) {
+ e_text = "Ticket may not be forwardable";
ret = KRB5KDC_ERR_POLICY;
kdc_log(context, config, 0,
"Ticket may not be forwardable -- %s", client_name);
@@ -1459,14 +1508,16 @@ _kdc_as_rep(krb5_context context,
if(client->entry.flags.proxiable && server->entry.flags.proxiable)
et.flags.proxiable = f.proxiable;
else if (f.proxiable) {
+ e_text = "Ticket may not be proxiable";
ret = KRB5KDC_ERR_POLICY;
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Ticket may not be proxiable -- %s", client_name);
goto out;
}
if(client->entry.flags.postdate && server->entry.flags.postdate)
et.flags.may_postdate = f.allow_postdate;
else if (f.allow_postdate){
+ e_text = "Ticket may not be postdate";
ret = KRB5KDC_ERR_POLICY;
kdc_log(context, config, 0,
"Ticket may not be postdatable -- %s", client_name);
@@ -1475,24 +1526,26 @@ _kdc_as_rep(krb5_context context,
/* check for valid set of addresses */
if(!_kdc_check_addresses(context, config, b->addresses, from_addr)) {
+ e_text = "Bad address list in requested";
ret = KRB5KRB_AP_ERR_BADADDR;
kdc_log(context, config, 0,
"Bad address list requested -- %s", client_name);
goto out;
}
- ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
+ ret = copy_PrincipalName(&rep.cname, &et.cname);
if (ret)
goto out;
- copy_PrincipalName(&rep.cname, &et.cname);
- copy_Realm(&rep.crealm, &et.crealm);
-
+ ret = copy_Realm(&rep.crealm, &et.crealm);
+ if (ret)
+ goto out;
+
{
time_t start;
time_t t;
-
+
start = et.authtime = kdc_time;
-
+
if(f.postdated && req->req_body.from){
ALLOC(et.starttime);
start = *et.starttime = *req->req_body.from;
@@ -1540,16 +1593,14 @@ _kdc_as_rep(krb5_context context,
if (f.request_anonymous)
et.flags.anonymous = 1;
-
+
if(b->addresses){
ALLOC(et.caddr);
copy_HostAddresses(b->addresses, et.caddr);
}
-
+
et.transited.tr_type = DOMAIN_X500_COMPRESS;
- krb5_data_zero(&et.transited.contents);
-
- copy_EncryptionKey(&et.key, &ek.key);
+ krb5_data_zero(&et.transited.contents);
/* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
* as 0 and as 0x80 (meaning indefinite length) apart, and is thus
@@ -1588,7 +1639,7 @@ _kdc_as_rep(krb5_context context,
ALLOC(ek.key_expiration);
if (client->entry.valid_end) {
if (client->entry.pw_end)
- *ek.key_expiration = min(*client->entry.valid_end,
+ *ek.key_expiration = min(*client->entry.valid_end,
*client->entry.pw_end);
else
*ek.key_expiration = *client->entry.valid_end;
@@ -1614,16 +1665,12 @@ _kdc_as_rep(krb5_context context,
copy_HostAddresses(et.caddr, ek.caddr);
}
- ALLOC(rep.padata);
- rep.padata->len = 0;
- rep.padata->val = NULL;
-
- reply_key = &ckey->key;
#if PKINIT
if (pkp) {
- ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
- req, req_buffer,
- &reply_key, rep.padata);
+ e_text = "Failed to build PK-INIT reply";
+ ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
+ sessionetype, req, req_buffer,
+ &reply_key, &et.key, rep.padata);
if (ret)
goto out;
ret = _kdc_add_inital_verified_cas(context,
@@ -1632,51 +1679,65 @@ _kdc_as_rep(krb5_context context,
&et);
if (ret)
goto out;
- }
+
+ } else
#endif
+ {
+ ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
+ if (ret)
+ goto out;
+ }
- set_salt_padata (rep.padata, ckey->salt);
+ if (reply_key == NULL) {
+ e_text = "Client have no reply key";
+ ret = KRB5KDC_ERR_CLIENT_NOTYET;
+ goto out;
+ }
+
+ ret = copy_EncryptionKey(&et.key, &ek.key);
+ if (ret)
+ goto out;
/* Add signing of alias referral */
if (f.canonicalize) {
PA_ClientCanonicalized canon;
krb5_data data;
PA_DATA pa;
- krb5_crypto crypto;
- size_t len;
+ krb5_crypto cryptox;
+ size_t len = 0;
memset(&canon, 0, sizeof(canon));
canon.names.requested_name = *b->cname;
- canon.names.real_name = client->entry.principal->name;
+ canon.names.mapped_name = client->entry.principal->name;
ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
&canon.names, &len, ret);
- if (ret)
+ if (ret)
goto out;
if (data.length != len)
krb5_abortx(context, "internal asn.1 error");
/* sign using "returned session key" */
- ret = krb5_crypto_init(context, &et.key, 0, &crypto);
+ ret = krb5_crypto_init(context, &et.key, 0, &cryptox);
if (ret) {
free(data.data);
goto out;
}
- ret = krb5_create_checksum(context, crypto,
+ ret = krb5_create_checksum(context, cryptox,
KRB5_KU_CANONICALIZED_NAMES, 0,
data.data, data.length,
&canon.canon_checksum);
free(data.data);
- krb5_crypto_destroy(context, crypto);
+ krb5_crypto_destroy(context, cryptox);
if (ret)
goto out;
-
+
ASN1_MALLOC_ENCODE(PA_ClientCanonicalized, data.data, data.length,
&canon, &len, ret);
free_Checksum(&canon.canon_checksum);
- if (ret)
+ if (ret)
goto out;
if (data.length != len)
krb5_abortx(context, "internal asn.1 error");
@@ -1701,19 +1762,19 @@ _kdc_as_rep(krb5_context context,
ret = _kdc_pac_generate(context, client, &p);
if (ret) {
- kdc_log(context, config, 0, "PAC generation failed for -- %s",
+ kdc_log(context, config, 0, "PAC generation failed for -- %s",
client_name);
goto out;
}
if (p != NULL) {
ret = _krb5_pac_sign(context, p, et.authtime,
client->entry.principal,
- &skey->key, /* Server key */
+ &skey->key, /* Server key */
&skey->key, /* FIXME: should be krbtgt key */
&data);
krb5_pac_free(context, p);
if (ret) {
- kdc_log(context, config, 0, "PAC signing failed for -- %s",
+ kdc_log(context, config, 0, "PAC signing failed for -- %s",
client_name);
goto out;
}
@@ -1727,7 +1788,7 @@ _kdc_as_rep(krb5_context context,
}
}
- _kdc_log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime,
+ _kdc_log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime,
et.endtime, et.renew_till);
/* do this as the last thing since this signs the EncTicketPart */
@@ -1735,16 +1796,19 @@ _kdc_as_rep(krb5_context context,
config,
server,
setype,
+ client->entry.principal,
NULL,
NULL,
&et);
if (ret)
goto out;
- ret = _kdc_encode_reply(context, config,
- &rep, &et, &ek, setype, server->entry.kvno,
- &skey->key, client->entry.kvno,
- reply_key, &e_text, reply);
+ log_as_req(context, config, reply_key->keytype, setype, b);
+
+ ret = _kdc_encode_reply(context, config,
+ &rep, &et, &ek, setype, server->entry.kvno,
+ &skey->key, client->entry.kvno,
+ reply_key, 0, &e_text, reply);
free_EncTicketPart(&et);
free_EncKDCRepPart(&ek);
if (ret)
@@ -1759,7 +1823,7 @@ _kdc_as_rep(krb5_context context,
out:
free_AS_REP(&rep);
- if(ret){
+ if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE){
krb5_mk_error(context,
ret,
e_text,
@@ -1791,8 +1855,8 @@ out:
}
/*
- * Add the AuthorizationData `data´ of `type´ to the last element in
- * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT
+ * Add the AuthorizationData `data´ of `type´ to the last element in
+ * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT
*/
krb5_error_code
@@ -1802,16 +1866,16 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
const krb5_data *data)
{
krb5_error_code ret;
- size_t size;
+ size_t size = 0;
if (tkt->authorization_data == NULL) {
tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data));
if (tkt->authorization_data == NULL) {
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ENOMEM, "out of memory");
return ENOMEM;
}
}
-
+
/* add the entry to the last element */
{
AuthorizationData ad = { 0, NULL };
@@ -1822,28 +1886,28 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
ret = add_AuthorizationData(&ad, &ade);
if (ret) {
- krb5_set_error_string(context, "add AuthorizationData failed");
+ krb5_set_error_message(context, ret, "add AuthorizationData failed");
return ret;
}
ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT;
- ASN1_MALLOC_ENCODE(AuthorizationData,
- ade.ad_data.data, ade.ad_data.length,
+ ASN1_MALLOC_ENCODE(AuthorizationData,
+ ade.ad_data.data, ade.ad_data.length,
&ad, &size, ret);
free_AuthorizationData(&ad);
if (ret) {
- krb5_set_error_string(context, "ASN.1 encode of "
- "AuthorizationData failed");
+ krb5_set_error_message(context, ret, "ASN.1 encode of "
+ "AuthorizationData failed");
return ret;
}
if (ade.ad_data.length != size)
krb5_abortx(context, "internal asn.1 encoder error");
-
+
ret = add_AuthorizationData(tkt->authorization_data, &ade);
der_free_octet_string(&ade.ad_data);
if (ret) {
- krb5_set_error_string(context, "add AuthorizationData failed");
+ krb5_set_error_message(context, ret, "add AuthorizationData failed");
return ret;
}
}
diff --git a/crypto/heimdal/kdc/krb5tgs.c b/crypto/heimdal/kdc/krb5tgs.c
index 32bdee9..5bf68cd 100644
--- a/crypto/heimdal/kdc/krb5tgs.c
+++ b/crypto/heimdal/kdc/krb5tgs.c
@@ -1,45 +1,43 @@
/*
- * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2008 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $");
-
/*
* return the realm of a krbtgt-ticket or NULL
*/
-static Realm
+static Realm
get_krbtgt_realm(const PrincipalName *p)
{
if(p->name_string.len == 2
@@ -66,7 +64,7 @@ find_KRB5SignedPath(krb5_context context,
AuthorizationData child;
krb5_error_code ret;
int pos;
-
+
if (ad == NULL || ad->len == 0)
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
@@ -80,8 +78,8 @@ find_KRB5SignedPath(krb5_context context,
&child,
NULL);
if (ret) {
- krb5_set_error_string(context, "Failed to decode "
- "IF_RELEVANT with %d", ret);
+ krb5_set_error_message(context, ret, "Failed to decode "
+ "IF_RELEVANT with %d", ret);
return ret;
}
@@ -106,28 +104,31 @@ _kdc_add_KRB5SignedPath(krb5_context context,
krb5_kdc_configuration *config,
hdb_entry_ex *krbtgt,
krb5_enctype enctype,
+ krb5_principal client,
krb5_const_principal server,
- KRB5SignedPathPrincipals *principals,
+ krb5_principals principals,
EncTicketPart *tkt)
{
krb5_error_code ret;
KRB5SignedPath sp;
krb5_data data;
krb5_crypto crypto = NULL;
- size_t size;
+ size_t size = 0;
if (server && principals) {
- ret = add_KRB5SignedPathPrincipals(principals, server);
+ ret = add_Principals(principals, server);
if (ret)
return ret;
}
{
KRB5SignedPathData spd;
-
- spd.encticket = *tkt;
+
+ spd.client = client;
+ spd.authtime = tkt->authtime;
spd.delegated = principals;
-
+ spd.method_data = NULL;
+
ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
&spd, &size, ret);
if (ret)
@@ -153,6 +154,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
sp.etype = enctype;
sp.delegated = principals;
+ sp.method_data = NULL;
ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0,
data.data, data.length, &sp.cksum);
@@ -168,7 +170,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
if (data.length != size)
krb5_abortx(context, "internal asn.1 encoder error");
-
+
/*
* Add IF-RELEVANT(KRB5SignedPath) to the last slot in
* authorization data field.
@@ -185,39 +187,36 @@ static krb5_error_code
check_KRB5SignedPath(krb5_context context,
krb5_kdc_configuration *config,
hdb_entry_ex *krbtgt,
+ krb5_principal cp,
EncTicketPart *tkt,
- KRB5SignedPathPrincipals **delegated,
- int require_signedpath)
+ krb5_principals *delegated,
+ int *signedpath)
{
krb5_error_code ret;
krb5_data data;
krb5_crypto crypto = NULL;
- *delegated = NULL;
+ if (delegated)
+ *delegated = NULL;
ret = find_KRB5SignedPath(context, tkt->authorization_data, &data);
if (ret == 0) {
KRB5SignedPathData spd;
KRB5SignedPath sp;
- AuthorizationData *ad;
- size_t size;
+ size_t size = 0;
ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL);
krb5_data_free(&data);
if (ret)
return ret;
- spd.encticket = *tkt;
- /* the KRB5SignedPath is the last entry */
- ad = spd.encticket.authorization_data;
- if (--ad->len == 0)
- spd.encticket.authorization_data = NULL;
+ spd.client = cp;
+ spd.authtime = tkt->authtime;
spd.delegated = sp.delegated;
+ spd.method_data = sp.method_data;
ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length,
&spd, &size, ret);
- ad->len++;
- spd.encticket.authorization_data = ad;
if (ret) {
free_KRB5SignedPath(&sp);
return ret;
@@ -236,17 +235,19 @@ check_KRB5SignedPath(krb5_context context,
return ret;
}
}
- ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH,
- data.data, data.length,
+ ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH,
+ data.data, data.length,
&sp.cksum);
krb5_crypto_destroy(context, crypto);
free(data.data);
if (ret) {
free_KRB5SignedPath(&sp);
- return ret;
+ kdc_log(context, config, 5,
+ "KRB5SignedPath not signed correctly, not marking as signed");
+ return 0;
}
- if (sp.delegated) {
+ if (delegated && sp.delegated) {
*delegated = malloc(sizeof(*sp.delegated));
if (*delegated == NULL) {
@@ -254,7 +255,7 @@ check_KRB5SignedPath(krb5_context context,
return ENOMEM;
}
- ret = copy_KRB5SignedPathPrincipals(*delegated, sp.delegated);
+ ret = copy_Principals(*delegated, sp.delegated);
if (ret) {
free_KRB5SignedPath(&sp);
free(*delegated);
@@ -263,10 +264,8 @@ check_KRB5SignedPath(krb5_context context,
}
}
free_KRB5SignedPath(&sp);
-
- } else {
- if (require_signedpath)
- return KRB5KDC_ERR_BADOPTION;
+
+ *signedpath = 1;
}
return 0;
@@ -280,13 +279,17 @@ static krb5_error_code
check_PAC(krb5_context context,
krb5_kdc_configuration *config,
const krb5_principal client_principal,
+ const krb5_principal delegated_proxy_principal,
hdb_entry_ex *client,
hdb_entry_ex *server,
- const EncryptionKey *server_key,
- const EncryptionKey *krbtgt_key,
+ hdb_entry_ex *krbtgt,
+ const EncryptionKey *server_check_key,
+ const EncryptionKey *krbtgt_check_key,
+ const EncryptionKey *server_sign_key,
+ const EncryptionKey *krbtgt_sign_key,
EncTicketPart *tkt,
krb5_data *rspac,
- int *require_signedpath)
+ int *signedpath)
{
AuthorizationData *ad = tkt->authorization_data;
unsigned i, j;
@@ -306,13 +309,14 @@ check_PAC(krb5_context context,
&child,
NULL);
if (ret) {
- krb5_set_error_string(context, "Failed to decode "
- "IF_RELEVANT with %d", ret);
+ krb5_set_error_message(context, ret, "Failed to decode "
+ "IF_RELEVANT with %d", ret);
return ret;
}
for (j = 0; j < child.len; j++) {
if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) {
+ int signed_pac = 0;
krb5_pac pac;
/* Found PAC */
@@ -324,26 +328,34 @@ check_PAC(krb5_context context,
if (ret)
return ret;
- ret = krb5_pac_verify(context, pac, tkt->authtime,
+ ret = krb5_pac_verify(context, pac, tkt->authtime,
client_principal,
- krbtgt_key, NULL);
+ server_check_key, krbtgt_check_key);
if (ret) {
krb5_pac_free(context, pac);
return ret;
}
- ret = _kdc_pac_verify(context, client_principal,
- client, server, &pac);
+ ret = _kdc_pac_verify(context, client_principal,
+ delegated_proxy_principal,
+ client, server, krbtgt, &pac, &signed_pac);
if (ret) {
krb5_pac_free(context, pac);
return ret;
}
- *require_signedpath = 0;
-
- ret = _krb5_pac_sign(context, pac, tkt->authtime,
- client_principal,
- server_key, krbtgt_key, rspac);
+ /*
+ * Only re-sign PAC if we could verify it with the PAC
+ * function. The no-verify case happens when we get in
+ * a PAC from cross realm from a Windows domain and
+ * that there is no PAC verification function.
+ */
+ if (signed_pac) {
+ *signedpath = 1;
+ ret = _krb5_pac_sign(context, pac, tkt->authtime,
+ client_principal,
+ server_sign_key, krbtgt_sign_key, rspac);
+ }
krb5_pac_free(context, pac);
return ret;
@@ -359,12 +371,12 @@ check_PAC(krb5_context context,
*/
static krb5_error_code
-check_tgs_flags(krb5_context context,
+check_tgs_flags(krb5_context context,
krb5_kdc_configuration *config,
KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et)
{
KDCOptions f = b->kdc_options;
-
+
if(f.validate){
if(!tgt->flags.invalid || tgt->starttime == NULL){
kdc_log(context, config, 0,
@@ -379,7 +391,7 @@ check_tgs_flags(krb5_context context,
/* XXX tkt = tgt */
et->flags.invalid = 0;
}else if(tgt->flags.invalid){
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Ticket-granting ticket has INVALID flag set");
return KRB5KRB_AP_ERR_TKT_INVALID;
}
@@ -403,7 +415,7 @@ check_tgs_flags(krb5_context context,
}
if(tgt->flags.forwarded)
et->flags.forwarded = 1;
-
+
if(f.proxiable){
if(!tgt->flags.proxiable){
kdc_log(context, config, 0,
@@ -448,7 +460,7 @@ check_tgs_flags(krb5_context context,
}
if(f.renewable){
- if(!tgt->flags.renewable){
+ if(!tgt->flags.renewable || tgt->renew_till == NULL){
kdc_log(context, config, 0,
"Bad request for renewable ticket");
return KRB5KDC_ERR_BADOPTION;
@@ -473,8 +485,8 @@ check_tgs_flags(krb5_context context,
et->endtime = *et->starttime + old_life;
if (et->renew_till != NULL)
et->endtime = min(*et->renew_till, et->endtime);
- }
-
+ }
+
#if 0
/* checks for excess flags */
if(f.request_anonymous && !config->allow_anonymous){
@@ -487,42 +499,98 @@ check_tgs_flags(krb5_context context,
}
/*
- *
+ * Determine if constrained delegation is allowed from this client to this server
*/
static krb5_error_code
-check_constrained_delegation(krb5_context context,
+check_constrained_delegation(krb5_context context,
krb5_kdc_configuration *config,
+ HDB *clientdb,
hdb_entry_ex *client,
- krb5_const_principal server)
+ hdb_entry_ex *server,
+ krb5_const_principal target)
{
const HDB_Ext_Constrained_delegation_acl *acl;
krb5_error_code ret;
- int i;
+ size_t i;
- ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
- if (ret) {
- krb5_clear_error_string(context);
+ /*
+ * constrained_delegation (S4U2Proxy) only works within
+ * the same realm. We use the already canonicalized version
+ * of the principals here, while "target" is the principal
+ * provided by the client.
+ */
+ if(!krb5_realm_compare(context, client->entry.principal, server->entry.principal)) {
+ ret = KRB5KDC_ERR_BADOPTION;
+ kdc_log(context, config, 0,
+ "Bad request for constrained delegation");
return ret;
}
- if (acl) {
- for (i = 0; i < acl->len; i++) {
- if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
- return 0;
+ if (clientdb->hdb_check_constrained_delegation) {
+ ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, target);
+ if (ret == 0)
+ return 0;
+ } else {
+ /* if client delegates to itself, that ok */
+ if (krb5_principal_compare(context, client->entry.principal, server->entry.principal) == TRUE)
+ return 0;
+
+ ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
+ if (ret) {
+ krb5_clear_error_message(context);
+ return ret;
}
+
+ if (acl) {
+ for (i = 0; i < acl->len; i++) {
+ if (krb5_principal_compare(context, target, &acl->val[i]) == TRUE)
+ return 0;
+ }
+ }
+ ret = KRB5KDC_ERR_BADOPTION;
}
kdc_log(context, config, 0,
"Bad request for constrained delegation");
- return KRB5KDC_ERR_BADOPTION;
+ return ret;
}
/*
+ * Determine if s4u2self is allowed from this client to this server
*
+ * For example, regardless of the principal being impersonated, if the
+ * 'client' and 'server' are the same, then it's safe.
*/
static krb5_error_code
-verify_flags (krb5_context context,
+check_s4u2self(krb5_context context,
+ krb5_kdc_configuration *config,
+ HDB *clientdb,
+ hdb_entry_ex *client,
+ krb5_const_principal server)
+{
+ krb5_error_code ret;
+
+ /* if client does a s4u2self to itself, that ok */
+ if (krb5_principal_compare(context, client->entry.principal, server) == TRUE)
+ return 0;
+
+ if (clientdb->hdb_check_s4u2self) {
+ ret = clientdb->hdb_check_s4u2self(context, clientdb, client, server);
+ if (ret == 0)
+ return 0;
+ } else {
+ ret = KRB5KDC_ERR_BADOPTION;
+ }
+ return ret;
+}
+
+/*
+ *
+ */
+
+static krb5_error_code
+verify_flags (krb5_context context,
krb5_kdc_configuration *config,
const EncTicketPart *et,
const char *pstr)
@@ -543,19 +611,19 @@ verify_flags (krb5_context context,
*/
static krb5_error_code
-fix_transited_encoding(krb5_context context,
+fix_transited_encoding(krb5_context context,
krb5_kdc_configuration *config,
krb5_boolean check_policy,
- const TransitedEncoding *tr,
- EncTicketPart *et,
- const char *client_realm,
- const char *server_realm,
+ const TransitedEncoding *tr,
+ EncTicketPart *et,
+ const char *client_realm,
+ const char *server_realm,
const char *tgt_realm)
{
krb5_error_code ret = 0;
char **realms, **tmp;
- int num_realms;
- int i;
+ unsigned int num_realms;
+ size_t i;
switch (tr->tr_type) {
case DOMAIN_X500_COMPRESS:
@@ -576,9 +644,9 @@ fix_transited_encoding(krb5_context context,
return KRB5KDC_ERR_TRTYPE_NOSUPP;
}
- ret = krb5_domain_x500_decode(context,
+ ret = krb5_domain_x500_decode(context,
tr->contents,
- &realms,
+ &realms,
&num_realms,
client_realm,
server_realm);
@@ -589,7 +657,7 @@ fix_transited_encoding(krb5_context context,
}
if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
/* not us, so add the previous realm to transited set */
- if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
+ if (num_realms + 1 > UINT_MAX/sizeof(*realms)) {
ret = ERANGE;
goto free_realms;
}
@@ -607,7 +675,7 @@ fix_transited_encoding(krb5_context context,
num_realms++;
}
if(num_realms == 0) {
- if(strcmp(client_realm, server_realm))
+ if(strcmp(client_realm, server_realm))
kdc_log(context, config, 0,
"cross-realm %s -> %s", client_realm, server_realm);
} else {
@@ -630,11 +698,11 @@ fix_transited_encoding(krb5_context context,
}
}
if(check_policy) {
- ret = krb5_check_transited(context, client_realm,
- server_realm,
+ ret = krb5_check_transited(context, client_realm,
+ server_realm,
realms, num_realms, NULL);
if(ret) {
- krb5_warn(context, ret, "cross-realm %s -> %s",
+ krb5_warn(context, ret, "cross-realm %s -> %s",
client_realm, server_realm);
goto free_realms;
}
@@ -653,23 +721,27 @@ fix_transited_encoding(krb5_context context,
static krb5_error_code
-tgs_make_reply(krb5_context context,
+tgs_make_reply(krb5_context context,
krb5_kdc_configuration *config,
- KDC_REQ_BODY *b,
+ KDC_REQ_BODY *b,
krb5_const_principal tgt_name,
- const EncTicketPart *tgt,
+ const EncTicketPart *tgt,
+ const krb5_keyblock *replykey,
+ int rk_is_subkey,
const EncryptionKey *serverkey,
const krb5_keyblock *sessionkey,
krb5_kvno kvno,
AuthorizationData *auth_data,
- hdb_entry_ex *server,
- const char *server_name,
- hdb_entry_ex *client,
- krb5_principal client_principal,
+ hdb_entry_ex *server,
+ krb5_principal server_principal,
+ const char *server_name,
+ hdb_entry_ex *client,
+ krb5_principal client_principal,
hdb_entry_ex *krbtgt,
krb5_enctype krbtgt_etype,
- KRB5SignedPathPrincipals *spp,
+ krb5_principals spp,
const krb5_data *rspac,
+ const METHOD_DATA *enc_pa_data,
const char **e_text,
krb5_data *reply)
{
@@ -678,11 +750,12 @@ tgs_make_reply(krb5_context context,
EncTicketPart et;
KDCOptions f = b->kdc_options;
krb5_error_code ret;
-
+ int is_weak = 0;
+
memset(&rep, 0, sizeof(rep));
memset(&et, 0, sizeof(et));
memset(&ek, 0, sizeof(ek));
-
+
rep.pvno = 5;
rep.msg_type = krb_tgs_rep;
@@ -691,7 +764,7 @@ tgs_make_reply(krb5_context context,
et.endtime = min(tgt->endtime, *b->till);
ALLOC(et.starttime);
*et.starttime = kdc_time;
-
+
ret = check_tgs_flags(context, config, b, tgt, &et);
if(ret)
goto out;
@@ -715,23 +788,22 @@ tgs_make_reply(krb5_context context,
#define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
#define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
- ret = fix_transited_encoding(context, config,
+ ret = fix_transited_encoding(context, config,
!f.disable_transited_check ||
GLOBAL_FORCE_TRANSITED_CHECK ||
PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
- !((GLOBAL_ALLOW_PER_PRINCIPAL &&
+ !((GLOBAL_ALLOW_PER_PRINCIPAL &&
PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
&tgt->transited, &et,
- *krb5_princ_realm(context, client_principal),
- *krb5_princ_realm(context, server->entry.principal),
- *krb5_princ_realm(context, krbtgt->entry.principal));
+ krb5_principal_get_realm(context, client_principal),
+ krb5_principal_get_realm(context, server->entry.principal),
+ krb5_principal_get_realm(context, krbtgt->entry.principal));
if(ret)
goto out;
- copy_Realm(krb5_princ_realm(context, server->entry.principal),
- &rep.ticket.realm);
- _krb5_principal2principalname(&rep.ticket.sname, server->entry.principal);
+ copy_Realm(&server_principal->realm, &rep.ticket.realm);
+ _krb5_principal2principalname(&rep.ticket.sname, server_principal);
copy_Realm(&tgt_name->realm, &rep.crealm);
/*
if (f.request_anonymous)
@@ -754,8 +826,10 @@ tgs_make_reply(krb5_context context,
life = min(life, *server->entry.max_life);
et.endtime = *et.starttime + life;
}
- if(f.renewable_ok && tgt->flags.renewable &&
- et.renew_till == NULL && et.endtime < *b->till){
+ if(f.renewable_ok && tgt->flags.renewable &&
+ et.renew_till == NULL && et.endtime < *b->till &&
+ tgt->renew_till != NULL)
+ {
et.flags.renewable = 1;
ALLOC(et.renew_till);
*et.renew_till = *b->till;
@@ -769,13 +843,13 @@ tgs_make_reply(krb5_context context,
renew = min(renew, *server->entry.max_renew);
*et.renew_till = et.authtime + renew;
}
-
+
if(et.renew_till){
*et.renew_till = min(*et.renew_till, *tgt->renew_till);
*et.starttime = min(*et.starttime, *et.renew_till);
et.endtime = min(et.endtime, *et.renew_till);
}
-
+
*et.starttime = min(*et.starttime, et.endtime);
if(*et.starttime == et.endtime){
@@ -787,22 +861,43 @@ tgs_make_reply(krb5_context context,
et.renew_till = NULL;
et.flags.renewable = 0;
}
-
+
et.flags.pre_authent = tgt->flags.pre_authent;
et.flags.hw_authent = tgt->flags.hw_authent;
et.flags.anonymous = tgt->flags.anonymous;
et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
-
+
+ if(rspac->length) {
+ /*
+ * No not need to filter out the any PAC from the
+ * auth_data since it's signed by the KDC.
+ */
+ ret = _kdc_tkt_add_if_relevant_ad(context, &et,
+ KRB5_AUTHDATA_WIN2K_PAC, rspac);
+ if (ret)
+ goto out;
+ }
+
if (auth_data) {
- /* XXX Check enc-authorization-data */
- et.authorization_data = calloc(1, sizeof(*et.authorization_data));
+ unsigned int i = 0;
+
+ /* XXX check authdata */
+
if (et.authorization_data == NULL) {
- ret = ENOMEM;
- goto out;
+ et.authorization_data = calloc(1, sizeof(*et.authorization_data));
+ if (et.authorization_data == NULL) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
+ goto out;
+ }
+ }
+ for(i = 0; i < auth_data->len ; i++) {
+ ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]);
+ if (ret) {
+ krb5_set_error_message(context, ret, "malloc: out of memory");
+ goto out;
+ }
}
- ret = copy_AuthorizationData(auth_data, et.authorization_data);
- if (ret)
- goto out;
/* Filter out type KRB5SignedPath */
ret = find_KRB5SignedPath(context, et.authorization_data, NULL);
@@ -819,24 +914,12 @@ tgs_make_reply(krb5_context context,
}
}
- if(rspac->length) {
- /*
- * No not need to filter out the any PAC from the
- * auth_data since it's signed by the KDC.
- */
- ret = _kdc_tkt_add_if_relevant_ad(context, &et,
- KRB5_AUTHDATA_WIN2K_PAC,
- rspac);
- if (ret)
- goto out;
- }
-
ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key);
if (ret)
goto out;
- et.crealm = tgt->crealm;
+ et.crealm = tgt_name->realm;
et.cname = tgt_name->name;
-
+
ek.key = et.key;
/* MIT must have at least one last_req */
ek.last_req.len = 1;
@@ -853,8 +936,8 @@ tgs_make_reply(krb5_context context,
ek.renew_till = et.renew_till;
ek.srealm = rep.ticket.realm;
ek.sname = rep.ticket.sname;
-
- _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime,
+
+ _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime,
et.endtime, et.renew_till);
/* Don't sign cross realm tickets, they can't be checked anyway */
@@ -866,6 +949,7 @@ tgs_make_reply(krb5_context context,
config,
krbtgt,
krbtgt_etype,
+ client_principal,
NULL,
spp,
&et);
@@ -874,6 +958,25 @@ tgs_make_reply(krb5_context context,
}
}
+ if (enc_pa_data->len) {
+ rep.padata = calloc(1, sizeof(*rep.padata));
+ if (rep.padata == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = copy_METHOD_DATA(enc_pa_data, rep.padata);
+ if (ret)
+ goto out;
+ }
+
+ if (krb5_enctype_valid(context, et.key.keytype) != 0
+ && _kdc_is_weak_exception(server->entry.principal, et.key.keytype))
+ {
+ krb5_enctype_enable(context, et.key.keytype);
+ is_weak = 1;
+ }
+
+
/* It is somewhat unclear where the etype in the following
encryption should come from. What we have is a session
key in the passed tgt, and a list of preferred etypes
@@ -884,10 +987,14 @@ tgs_make_reply(krb5_context context,
CAST session key. Should the DES3 etype be added to the
etype list, even if we don't want a session key with
DES3? */
- ret = _kdc_encode_reply(context, config,
+ ret = _kdc_encode_reply(context, config,
&rep, &et, &ek, et.key.keytype,
- kvno,
- serverkey, 0, &tgt->key, e_text, reply);
+ kvno,
+ serverkey, 0, replykey, rk_is_subkey,
+ e_text, reply);
+ if (is_weak)
+ krb5_enctype_disable(context, et.key.keytype);
+
out:
free_TGS_REP(&rep);
free_TransitedEncoding(&et.transited);
@@ -906,20 +1013,20 @@ out:
}
static krb5_error_code
-tgs_check_authenticator(krb5_context context,
+tgs_check_authenticator(krb5_context context,
krb5_kdc_configuration *config,
krb5_auth_context ac,
- KDC_REQ_BODY *b,
+ KDC_REQ_BODY *b,
const char **e_text,
krb5_keyblock *key)
{
krb5_authenticator auth;
- size_t len;
+ size_t len = 0;
unsigned char *buf;
size_t buf_size;
krb5_error_code ret;
krb5_crypto crypto;
-
+
krb5_auth_con_getauthenticator(context, ac, &auth);
if(auth->cksum == NULL){
kdc_log(context, config, 0, "No authenticator in request");
@@ -936,17 +1043,18 @@ tgs_check_authenticator(krb5_context context,
||
#endif
!krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
- kdc_log(context, config, 0, "Bad checksum type in authenticator: %d",
+ kdc_log(context, config, 0, "Bad checksum type in authenticator: %d",
auth->cksum->cksumtype);
ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
goto out;
}
-
+
/* XXX should not re-encode this */
ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
if(ret){
- kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
if(buf_size != len) {
@@ -958,23 +1066,25 @@ tgs_check_authenticator(krb5_context context,
}
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
free(buf);
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
+ kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
ret = krb5_verify_checksum(context,
crypto,
KRB5_KU_TGS_REQ_AUTH_CKSUM,
- buf,
+ buf,
len,
auth->cksum);
free(buf);
krb5_crypto_destroy(context, crypto);
if(ret){
+ const char *msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 0,
- "Failed to verify authenticator checksum: %s",
- krb5_get_err_text(context, ret));
+ "Failed to verify authenticator checksum: %s", msg);
+ krb5_free_error_message(context, msg);
}
out:
free_Authenticator(auth);
@@ -991,27 +1101,38 @@ find_rpath(krb5_context context, Realm crealm, Realm srealm)
{
const char *new_realm = krb5_config_get_string(context,
NULL,
- "capaths",
+ "capaths",
crealm,
srealm,
NULL);
return new_realm;
}
-
+
static krb5_boolean
-need_referral(krb5_context context, krb5_principal server, krb5_realm **realms)
+need_referral(krb5_context context, krb5_kdc_configuration *config,
+ const KDCOptions * const options, krb5_principal server,
+ krb5_realm **realms)
{
- if(server->name.name_type != KRB5_NT_SRV_INST ||
- server->name.name_string.len != 2)
+ const char *name;
+
+ if(!options->canonicalize && server->name.name_type != KRB5_NT_SRV_INST)
return FALSE;
-
- return _krb5_get_host_realm_int(context, server->name.name_string.val[1],
- FALSE, realms) == 0;
+
+ if (server->name.name_string.len == 1)
+ name = server->name.name_string.val[0];
+ else if (server->name.name_string.len > 1)
+ name = server->name.name_string.val[1];
+ else
+ return FALSE;
+
+ kdc_log(context, config, 0, "Searching referral for %s", name);
+
+ return _krb5_get_host_realm_int(context, name, FALSE, realms) == 0;
}
static krb5_error_code
-tgs_parse_request(krb5_context context,
+tgs_parse_request(krb5_context context,
krb5_kdc_configuration *config,
KDC_REQ_BODY *b,
const PA_DATA *tgs_req,
@@ -1023,8 +1144,11 @@ tgs_parse_request(krb5_context context,
const struct sockaddr *from_addr,
time_t **csec,
int **cusec,
- AuthorizationData **auth_data)
+ AuthorizationData **auth_data,
+ krb5_keyblock **replykey,
+ int *rk_is_subkey)
{
+ static char failed[] = "<unparse_name failed>";
krb5_ap_req ap_req;
krb5_error_code ret;
krb5_principal princ;
@@ -1033,16 +1157,20 @@ tgs_parse_request(krb5_context context,
krb5_flags verify_ap_req_flags;
krb5_crypto crypto;
Key *tkey;
+ krb5_keyblock *subkey = NULL;
+ unsigned usage;
*auth_data = NULL;
*csec = NULL;
*cusec = NULL;
+ *replykey = NULL;
memset(&ap_req, 0, sizeof(ap_req));
ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
if(ret){
- kdc_log(context, config, 0, "Failed to decode AP-REQ: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
@@ -1052,39 +1180,51 @@ tgs_parse_request(krb5_context context,
ret = KRB5KDC_ERR_POLICY; /* ? */
goto out;
}
-
+
_krb5_principalname2krb5_principal(context,
&princ,
ap_req.ticket.sname,
ap_req.ticket.realm);
-
- ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, NULL, krbtgt);
- if(ret) {
+ ret = _kdc_db_fetch(context, config, princ, HDB_F_GET_KRBTGT, ap_req.ticket.enc_part.kvno, NULL, krbtgt);
+
+ if(ret == HDB_ERR_NOT_FOUND_HERE) {
+ char *p;
+ ret = krb5_unparse_name(context, princ, &p);
+ if (ret != 0)
+ p = failed;
+ krb5_free_principal(context, princ);
+ kdc_log(context, config, 5, "Ticket-granting ticket account %s does not have secrets at this KDC, need to proxy", p);
+ if (ret == 0)
+ free(p);
+ ret = HDB_ERR_NOT_FOUND_HERE;
+ goto out;
+ } else if(ret){
+ const char *msg = krb5_get_error_message(context, ret);
char *p;
ret = krb5_unparse_name(context, princ, &p);
if (ret != 0)
- p = "<unparse_name failed>";
+ p = failed;
krb5_free_principal(context, princ);
kdc_log(context, config, 0,
- "Ticket-granting ticket not found in database: %s: %s",
- p, krb5_get_err_text(context, ret));
+ "Ticket-granting ticket not found in database: %s", msg);
+ krb5_free_error_message(context, msg);
if (ret == 0)
free(p);
ret = KRB5KRB_AP_ERR_NOT_US;
goto out;
}
-
- if(ap_req.ticket.enc_part.kvno &&
+
+ if(ap_req.ticket.enc_part.kvno &&
*ap_req.ticket.enc_part.kvno != (*krbtgt)->entry.kvno){
char *p;
ret = krb5_unparse_name (context, princ, &p);
krb5_free_principal(context, princ);
if (ret != 0)
- p = "<unparse_name failed>";
+ p = failed;
kdc_log(context, config, 0,
- "Ticket kvno = %d, DB kvno = %d (%s)",
+ "Ticket kvno = %d, DB kvno = %d (%s)",
*ap_req.ticket.enc_part.kvno,
(*krbtgt)->entry.kvno,
p);
@@ -1096,7 +1236,7 @@ tgs_parse_request(krb5_context context,
*krbtgt_etype = ap_req.ticket.enc_part.etype;
- ret = hdb_enctype2key(context, &(*krbtgt)->entry,
+ ret = hdb_enctype2key(context, &(*krbtgt)->entry,
ap_req.ticket.enc_part.etype, &tkey);
if(ret){
char *str = NULL, *p = NULL;
@@ -1112,7 +1252,7 @@ tgs_parse_request(krb5_context context,
ret = KRB5KRB_AP_ERR_BADKEYVER;
goto out;
}
-
+
if (b->kdc_options.validate)
verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
else
@@ -1127,11 +1267,12 @@ tgs_parse_request(krb5_context context,
&ap_req_options,
ticket,
KRB5_KU_TGS_REQ_AUTH);
-
+
krb5_free_principal(context, princ);
if(ret) {
- kdc_log(context, config, 0, "Failed to verify AP-REQ: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
@@ -1158,49 +1299,56 @@ tgs_parse_request(krb5_context context,
}
}
- ret = tgs_check_authenticator(context, config,
+ ret = tgs_check_authenticator(context, config,
ac, b, e_text, &(*ticket)->ticket.key);
if (ret) {
krb5_auth_con_free(context, ac);
goto out;
}
- if (b->enc_authorization_data) {
- unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
- krb5_keyblock *subkey;
- krb5_data ad;
+ usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
+ *rk_is_subkey = 1;
- ret = krb5_auth_con_getremotesubkey(context,
- ac,
- &subkey);
- if(ret){
- krb5_auth_con_free(context, ac);
- kdc_log(context, config, 0, "Failed to get remote subkey: %s",
- krb5_get_err_text(context, ret));
- goto out;
- }
- if(subkey == NULL){
- usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
- ret = krb5_auth_con_getkey(context, ac, &subkey);
- if(ret) {
- krb5_auth_con_free(context, ac);
- kdc_log(context, config, 0, "Failed to get session key: %s",
- krb5_get_err_text(context, ret));
- goto out;
- }
- }
- if(subkey == NULL){
+ ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
+ if(ret){
+ const char *msg = krb5_get_error_message(context, ret);
+ krb5_auth_con_free(context, ac);
+ kdc_log(context, config, 0, "Failed to get remote subkey: %s", msg);
+ krb5_free_error_message(context, msg);
+ goto out;
+ }
+ if(subkey == NULL){
+ usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
+ *rk_is_subkey = 0;
+
+ ret = krb5_auth_con_getkey(context, ac, &subkey);
+ if(ret) {
+ const char *msg = krb5_get_error_message(context, ret);
krb5_auth_con_free(context, ac);
- kdc_log(context, config, 0,
- "Failed to get key for enc-authorization-data");
- ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+ kdc_log(context, config, 0, "Failed to get session key: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
+ }
+ if(subkey == NULL){
+ krb5_auth_con_free(context, ac);
+ kdc_log(context, config, 0,
+ "Failed to get key for enc-authorization-data");
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
+ goto out;
+ }
+
+ *replykey = subkey;
+
+ if (b->enc_authorization_data) {
+ krb5_data ad;
+
ret = krb5_crypto_init(context, subkey, 0, &crypto);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
krb5_auth_con_free(context, ac);
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
+ kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
ret = krb5_decrypt_EncryptedData (context,
@@ -1211,12 +1359,11 @@ tgs_parse_request(krb5_context context,
krb5_crypto_destroy(context, crypto);
if(ret){
krb5_auth_con_free(context, ac);
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Failed to decrypt enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
- krb5_free_keyblock(context, subkey);
ALLOC(*auth_data);
if (*auth_data == NULL) {
krb5_auth_con_free(context, ac);
@@ -1235,62 +1382,154 @@ tgs_parse_request(krb5_context context,
}
krb5_auth_con_free(context, ac);
-
+
out:
free_AP_REQ(&ap_req);
-
+
return ret;
}
static krb5_error_code
-tgs_build_reply(krb5_context context,
+build_server_referral(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_crypto session,
+ krb5_const_realm referred_realm,
+ const PrincipalName *true_principal_name,
+ const PrincipalName *requested_principal,
+ krb5_data *outdata)
+{
+ PA_ServerReferralData ref;
+ krb5_error_code ret;
+ EncryptedData ed;
+ krb5_data data;
+ size_t size = 0;
+
+ memset(&ref, 0, sizeof(ref));
+
+ if (referred_realm) {
+ ALLOC(ref.referred_realm);
+ if (ref.referred_realm == NULL)
+ goto eout;
+ *ref.referred_realm = strdup(referred_realm);
+ if (*ref.referred_realm == NULL)
+ goto eout;
+ }
+ if (true_principal_name) {
+ ALLOC(ref.true_principal_name);
+ if (ref.true_principal_name == NULL)
+ goto eout;
+ ret = copy_PrincipalName(true_principal_name, ref.true_principal_name);
+ if (ret)
+ goto eout;
+ }
+ if (requested_principal) {
+ ALLOC(ref.requested_principal_name);
+ if (ref.requested_principal_name == NULL)
+ goto eout;
+ ret = copy_PrincipalName(requested_principal,
+ ref.requested_principal_name);
+ if (ret)
+ goto eout;
+ }
+
+ ASN1_MALLOC_ENCODE(PA_ServerReferralData,
+ data.data, data.length,
+ &ref, &size, ret);
+ free_PA_ServerReferralData(&ref);
+ if (ret)
+ return ret;
+ if (data.length != size)
+ krb5_abortx(context, "internal asn.1 encoder error");
+
+ ret = krb5_encrypt_EncryptedData(context, session,
+ KRB5_KU_PA_SERVER_REFERRAL,
+ data.data, data.length,
+ 0 /* kvno */, &ed);
+ free(data.data);
+ if (ret)
+ return ret;
+
+ ASN1_MALLOC_ENCODE(EncryptedData,
+ outdata->data, outdata->length,
+ &ed, &size, ret);
+ free_EncryptedData(&ed);
+ if (ret)
+ return ret;
+ if (outdata->length != size)
+ krb5_abortx(context, "internal asn.1 encoder error");
+
+ return 0;
+eout:
+ free_PA_ServerReferralData(&ref);
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+ return ENOMEM;
+}
+
+static krb5_error_code
+tgs_build_reply(krb5_context context,
krb5_kdc_configuration *config,
- KDC_REQ *req,
+ KDC_REQ *req,
KDC_REQ_BODY *b,
hdb_entry_ex *krbtgt,
krb5_enctype krbtgt_etype,
+ const krb5_keyblock *replykey,
+ int rk_is_subkey,
krb5_ticket *ticket,
krb5_data *reply,
const char *from,
const char **e_text,
- AuthorizationData *auth_data,
- const struct sockaddr *from_addr,
- int datagram_reply)
+ AuthorizationData **auth_data,
+ const struct sockaddr *from_addr)
{
krb5_error_code ret;
- krb5_principal cp = NULL, sp = NULL;
- krb5_principal client_principal = NULL;
- char *spn = NULL, *cpn = NULL;
- hdb_entry_ex *server = NULL, *client = NULL;
+ krb5_principal cp = NULL, sp = NULL, rsp = NULL, tp = NULL, dp = NULL;
+ krb5_principal krbtgt_principal = NULL;
+ char *spn = NULL, *cpn = NULL, *tpn = NULL, *dpn = NULL;
+ hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL;
+ HDB *clientdb, *s4u2self_impersonated_clientdb;
+ krb5_realm ref_realm = NULL;
EncTicketPart *tgt = &ticket->ticket;
- KRB5SignedPathPrincipals *spp = NULL;
+ krb5_principals spp = NULL;
const EncryptionKey *ekey;
krb5_keyblock sessionkey;
krb5_kvno kvno;
krb5_data rspac;
- int cross_realm = 0;
+
+ hdb_entry_ex *krbtgt_out = NULL;
+
+ METHOD_DATA enc_pa_data;
PrincipalName *s;
Realm r;
int nloop = 0;
EncTicketPart adtkt;
char opt_str[128];
- int require_signedpath = 0;
+ int signedpath = 0;
+
+ Key *tkey_check;
+ Key *tkey_sign;
+ int flags = HDB_F_FOR_TGS_REQ;
memset(&sessionkey, 0, sizeof(sessionkey));
memset(&adtkt, 0, sizeof(adtkt));
krb5_data_zero(&rspac);
+ memset(&enc_pa_data, 0, sizeof(enc_pa_data));
s = b->sname;
r = b->realm;
+ /*
+ * Always to do CANON, see comment below about returned server principal (rsp).
+ */
+ flags |= HDB_F_CANON;
+
if(b->kdc_options.enc_tkt_in_skey){
Ticket *t;
hdb_entry_ex *uu;
krb5_principal p;
Key *uukey;
-
- if(b->additional_tickets == NULL ||
+
+ if(b->additional_tickets == NULL ||
b->additional_tickets->len == 0){
ret = KRB5KDC_ERR_BADOPTION; /* ? */
kdc_log(context, config, 0,
@@ -1305,8 +1544,8 @@ tgs_build_reply(krb5_context context,
goto out;
}
_krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
- ret = _kdc_db_fetch(context, config, p,
- HDB_F_GET_CLIENT|HDB_F_GET_SERVER,
+ ret = _kdc_db_fetch(context, config, p,
+ HDB_F_GET_KRBTGT, t->enc_part.kvno,
NULL, &uu);
krb5_free_principal(context, p);
if(ret){
@@ -1314,7 +1553,7 @@ tgs_build_reply(krb5_context context,
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out;
}
- ret = hdb_enctype2key(context, &uu->entry,
+ ret = hdb_enctype2key(context, &uu->entry,
t->enc_part.etype, &uukey);
if(ret){
_kdc_free_ent(context, uu);
@@ -1335,7 +1574,7 @@ tgs_build_reply(krb5_context context,
}
_krb5_principalname2krb5_principal(context, &sp, *s, r);
- ret = krb5_unparse_name(context, sp, &spn);
+ ret = krb5_unparse_name(context, sp, &spn);
if (ret)
goto out;
_krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm);
@@ -1347,7 +1586,7 @@ tgs_build_reply(krb5_context context,
opt_str, sizeof(opt_str));
if(*opt_str)
kdc_log(context, config, 0,
- "TGS-REQ %s from %s for %s [%s]",
+ "TGS-REQ %s from %s for %s [%s]",
cpn, from, spn, opt_str);
else
kdc_log(context, config, 0,
@@ -1358,10 +1597,14 @@ tgs_build_reply(krb5_context context,
*/
server_lookup:
- ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER, NULL, &server);
+ ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | flags,
+ NULL, NULL, &server);
- if(ret){
- const char *new_rlm;
+ if(ret == HDB_ERR_NOT_FOUND_HERE) {
+ kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp);
+ goto out;
+ } else if(ret){
+ const char *new_rlm, *msg;
Realm req_rlm;
krb5_realm *realms;
@@ -1370,20 +1613,23 @@ server_lookup:
new_rlm = find_rpath(context, tgt->crealm, req_rlm);
if(new_rlm) {
kdc_log(context, config, 5, "krbtgt for realm %s "
- "not found, trying %s",
+ "not found, trying %s",
req_rlm, new_rlm);
krb5_free_principal(context, sp);
free(spn);
- krb5_make_principal(context, &sp, r,
+ krb5_make_principal(context, &sp, r,
KRB5_TGS_NAME, new_rlm, NULL);
- ret = krb5_unparse_name(context, sp, &spn);
+ ret = krb5_unparse_name(context, sp, &spn);
if (ret)
goto out;
- auth_data = NULL; /* ms don't handle AD in referals */
+
+ if (ref_realm)
+ free(ref_realm);
+ ref_realm = strdup(new_rlm);
goto server_lookup;
}
}
- } else if(need_referral(context, sp, &realms)) {
+ } else if(need_referral(context, config, &b->kdc_options, sp, &realms)) {
if (strcmp(realms[0], sp->realm) != 0) {
kdc_log(context, config, 5,
"Returning a referral to realm %s for "
@@ -1396,23 +1642,167 @@ server_lookup:
ret = krb5_unparse_name(context, sp, &spn);
if (ret)
goto out;
+
+ if (ref_realm)
+ free(ref_realm);
+ ref_realm = strdup(realms[0]);
+
krb5_free_host_realm(context, realms);
- auth_data = NULL; /* ms don't handle AD in referals */
goto server_lookup;
}
krb5_free_host_realm(context, realms);
}
+ msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 0,
- "Server not found in database: %s: %s", spn,
- krb5_get_err_text(context, ret));
+ "Server not found in database: %s: %s", spn, msg);
+ krb5_free_error_message(context, msg);
if (ret == HDB_ERR_NOENTRY)
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out;
}
- ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, NULL, &client);
+ /* the name returned to the client depend on what was asked for,
+ * return canonical name if kdc_options.canonicalize was set, the
+ * client wants the true name of the principal, if not it just
+ * wants the name its asked for.
+ */
+
+ if (b->kdc_options.canonicalize)
+ rsp = server->entry.principal;
+ else
+ rsp = sp;
+
+
+ /*
+ * Select enctype, return key and kvno.
+ */
+
+ {
+ krb5_enctype etype;
+
+ if(b->kdc_options.enc_tkt_in_skey) {
+ size_t i;
+ ekey = &adtkt.key;
+ for(i = 0; i < b->etype.len; i++)
+ if (b->etype.val[i] == adtkt.key.keytype)
+ break;
+ if(i == b->etype.len) {
+ kdc_log(context, config, 0,
+ "Addition ticket have not matching etypes");
+ krb5_clear_error_message(context);
+ ret = KRB5KDC_ERR_ETYPE_NOSUPP;
+ goto out;
+ }
+ etype = b->etype.val[i];
+ kvno = 0;
+ } else {
+ Key *skey;
+
+ ret = _kdc_find_etype(context,
+ config->tgs_use_strongest_session_key, FALSE,
+ server, b->etype.val, b->etype.len, NULL,
+ &skey);
+ if(ret) {
+ kdc_log(context, config, 0,
+ "Server (%s) has no support for etypes", spn);
+ goto out;
+ }
+ ekey = &skey->key;
+ etype = skey->key.keytype;
+ kvno = server->entry.kvno;
+ }
+
+ ret = krb5_generate_random_keyblock(context, etype, &sessionkey);
+ if (ret)
+ goto out;
+ }
+
+ /*
+ * Check that service is in the same realm as the krbtgt. If it's
+ * not the same, it's someone that is using a uni-directional trust
+ * backward.
+ */
+
+ /*
+ * Validate authoriation data
+ */
+
+ ret = hdb_enctype2key(context, &krbtgt->entry,
+ krbtgt_etype, &tkey_check);
if(ret) {
- const char *krbtgt_realm;
+ kdc_log(context, config, 0,
+ "Failed to find key for krbtgt PAC check");
+ goto out;
+ }
+
+ /* Now refetch the primary krbtgt, and get the current kvno (the
+ * sign check may have been on an old kvno, and the server may
+ * have been an incoming trust) */
+ ret = krb5_make_principal(context, &krbtgt_principal,
+ krb5_principal_get_comp_string(context,
+ krbtgt->entry.principal,
+ 1),
+ KRB5_TGS_NAME,
+ krb5_principal_get_comp_string(context,
+ krbtgt->entry.principal,
+ 1), NULL);
+ if(ret) {
+ kdc_log(context, config, 0,
+ "Failed to generate krbtgt principal");
+ goto out;
+ }
+
+ ret = _kdc_db_fetch(context, config, krbtgt_principal, HDB_F_GET_KRBTGT, NULL, NULL, &krbtgt_out);
+ krb5_free_principal(context, krbtgt_principal);
+ if (ret) {
+ krb5_error_code ret2;
+ char *ktpn, *ktpn2;
+ ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn);
+ ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2);
+ kdc_log(context, config, 0,
+ "Request with wrong krbtgt: %s, %s not found in our database",
+ (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>");
+ if(ret == 0)
+ free(ktpn);
+ if(ret2 == 0)
+ free(ktpn2);
+ ret = KRB5KRB_AP_ERR_NOT_US;
+ goto out;
+ }
+
+ /* The first realm is the realm of the service, the second is
+ * krbtgt/<this>/@REALM component of the krbtgt DN the request was
+ * encrypted to. The redirection via the krbtgt_out entry allows
+ * the DB to possibly correct the case of the realm (Samba4 does
+ * this) before the strcmp() */
+ if (strcmp(krb5_principal_get_realm(context, server->entry.principal),
+ krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) {
+ char *ktpn;
+ ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &ktpn);
+ kdc_log(context, config, 0,
+ "Request with wrong krbtgt: %s",
+ (ret == 0) ? ktpn : "<unknown>");
+ if(ret == 0)
+ free(ktpn);
+ ret = KRB5KRB_AP_ERR_NOT_US;
+ }
+
+ ret = hdb_enctype2key(context, &krbtgt_out->entry,
+ krbtgt_etype, &tkey_sign);
+ if(ret) {
+ kdc_log(context, config, 0,
+ "Failed to find key for krbtgt PAC signature");
+ goto out;
+ }
+
+ ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags,
+ NULL, &clientdb, &client);
+ if(ret == HDB_ERR_NOT_FOUND_HERE) {
+ /* This is OK, we are just trying to find out if they have
+ * been disabled or deleted in the meantime, missing secrets
+ * is OK */
+ } else if(ret){
+ const char *krbtgt_realm, *msg;
/*
* If the client belongs to the same realm as our krbtgt, it
@@ -1420,9 +1810,7 @@ server_lookup:
*
*/
- krbtgt_realm =
- krb5_principal_get_comp_string(context,
- krbtgt->entry.principal, 1);
+ krbtgt_realm = krb5_principal_get_realm(context, krbtgt_out->entry.principal);
if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {
if (ret == HDB_ERR_NOENTRY)
@@ -1431,53 +1819,63 @@ server_lookup:
cpn);
goto out;
}
-
- kdc_log(context, config, 1, "Client not found in database: %s: %s",
- cpn, krb5_get_err_text(context, ret));
- cross_realm = 1;
+ msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 1, "Client not found in database: %s", msg);
+ krb5_free_error_message(context, msg);
}
-
- /*
- * Check that service is in the same realm as the krbtgt. If it's
- * not the same, it's someone that is using a uni-directional trust
- * backward.
- */
-
- if (strcmp(krb5_principal_get_realm(context, sp),
- krb5_principal_get_comp_string(context,
- krbtgt->entry.principal,
- 1)) != 0) {
- char *tpn;
- ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
+
+ ret = check_PAC(context, config, cp, NULL,
+ client, server, krbtgt,
+ &tkey_check->key, &tkey_check->key,
+ ekey, &tkey_sign->key,
+ tgt, &rspac, &signedpath);
+ if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 0,
- "Request with wrong krbtgt: %s",
- (ret == 0) ? tpn : "<unknown>");
- if(ret == 0)
- free(tpn);
- ret = KRB5KRB_AP_ERR_NOT_US;
+ "Verify PAC failed for %s (%s) from %s with %s",
+ spn, cpn, from, msg);
+ krb5_free_error_message(context, msg);
+ goto out;
+ }
+
+ /* also check the krbtgt for signature */
+ ret = check_KRB5SignedPath(context,
+ config,
+ krbtgt,
+ cp,
+ tgt,
+ &spp,
+ &signedpath);
+ if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0,
+ "KRB5SignedPath check failed for %s (%s) from %s with %s",
+ spn, cpn, from, msg);
+ krb5_free_error_message(context, msg);
goto out;
}
/*
- *
+ * Process request
*/
- client_principal = cp;
+ /* by default the tgt principal matches the client principal */
+ tp = cp;
+ tpn = cpn;
if (client) {
const PA_DATA *sdata;
int i = 0;
- sdata = _kdc_find_padata(req, &i, KRB5_PADATA_S4U2SELF);
+ sdata = _kdc_find_padata(req, &i, KRB5_PADATA_FOR_USER);
if (sdata) {
krb5_crypto crypto;
krb5_data datack;
PA_S4U2Self self;
- char *selfcpn = NULL;
const char *str;
- ret = decode_PA_S4U2Self(sdata->padata_value.data,
+ ret = decode_PA_S4U2Self(sdata->padata_value.data,
sdata->padata_value.length,
&self, NULL);
if (ret) {
@@ -1491,52 +1889,97 @@ server_lookup:
ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
free_PA_S4U2Self(&self);
krb5_data_free(&datack);
- kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
- krb5_get_err_text(context, ret));
+ kdc_log(context, config, 0, "krb5_crypto_init failed: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
ret = krb5_verify_checksum(context,
crypto,
KRB5_KU_OTHER_CKSUM,
- datack.data,
- datack.length,
+ datack.data,
+ datack.length,
&self.cksum);
krb5_data_free(&datack);
krb5_crypto_destroy(context, crypto);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
free_PA_S4U2Self(&self);
- kdc_log(context, config, 0,
- "krb5_verify_checksum failed for S4U2Self: %s",
- krb5_get_err_text(context, ret));
+ kdc_log(context, config, 0,
+ "krb5_verify_checksum failed for S4U2Self: %s", msg);
+ krb5_free_error_message(context, msg);
goto out;
}
ret = _krb5_principalname2krb5_principal(context,
- &client_principal,
+ &tp,
self.name,
self.realm);
free_PA_S4U2Self(&self);
if (ret)
goto out;
- ret = krb5_unparse_name(context, client_principal, &selfcpn);
+ ret = krb5_unparse_name(context, tp, &tpn);
if (ret)
goto out;
+ /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */
+ if(rspac.data) {
+ krb5_pac p = NULL;
+ krb5_data_free(&rspac);
+ ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
+ NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
+ if (ret) {
+ const char *msg;
+
+ /*
+ * If the client belongs to the same realm as our krbtgt, it
+ * should exist in the local database.
+ *
+ */
+
+ if (ret == HDB_ERR_NOENTRY)
+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+ msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 1,
+ "S2U4Self principal to impersonate %s not found in database: %s",
+ tpn, msg);
+ krb5_free_error_message(context, msg);
+ goto out;
+ }
+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p);
+ if (ret) {
+ kdc_log(context, config, 0, "PAC generation failed for -- %s",
+ tpn);
+ goto out;
+ }
+ if (p != NULL) {
+ ret = _krb5_pac_sign(context, p, ticket->ticket.authtime,
+ s4u2self_impersonated_client->entry.principal,
+ ekey, &tkey_sign->key,
+ &rspac);
+ krb5_pac_free(context, p);
+ if (ret) {
+ kdc_log(context, config, 0, "PAC signing failed for -- %s",
+ tpn);
+ goto out;
+ }
+ }
+ }
+
/*
* Check that service doing the impersonating is
* requesting a ticket to it-self.
*/
- if (krb5_principal_compare(context, cp, sp) != TRUE) {
+ ret = check_s4u2self(context, config, clientdb, client, sp);
+ if (ret) {
kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
- "to impersonate some other user "
+ "to impersonate to service "
"(tried for user %s to service %s)",
- cpn, selfcpn, spn);
- free(selfcpn);
- ret = KRB5KDC_ERR_BADOPTION; /* ? */
+ cpn, tpn, spn);
goto out;
}
@@ -1552,8 +1995,7 @@ server_lookup:
str = "";
}
kdc_log(context, config, 0, "s4u2self %s impersonating %s to "
- "service %s %s", cpn, selfcpn, spn, str);
- free(selfcpn);
+ "service %s %s", cpn, tpn, spn, str);
}
}
@@ -1566,13 +2008,25 @@ server_lookup:
&& b->additional_tickets->len != 0
&& b->kdc_options.enc_tkt_in_skey == 0)
{
+ int ad_signedpath = 0;
Key *clientkey;
Ticket *t;
- char *str;
+
+ /*
+ * Require that the KDC have issued the service's krbtgt (not
+ * self-issued ticket with kimpersonate(1).
+ */
+ if (!signedpath) {
+ ret = KRB5KDC_ERR_BADOPTION;
+ kdc_log(context, config, 0,
+ "Constrained delegation done on service ticket %s/%s",
+ cpn, spn);
+ goto out;
+ }
t = &b->additional_tickets->val[0];
- ret = hdb_enctype2key(context, &client->entry,
+ ret = hdb_enctype2key(context, &client->entry,
t->enc_part.etype, &clientkey);
if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
@@ -1583,90 +2037,127 @@ server_lookup:
if (ret) {
kdc_log(context, config, 0,
"failed to decrypt ticket for "
- "constrained delegation from %s to %s ", spn, cpn);
+ "constrained delegation from %s to %s ", cpn, spn);
goto out;
}
- /* check that ticket is valid */
+ ret = _krb5_principalname2krb5_principal(context,
+ &tp,
+ adtkt.cname,
+ adtkt.crealm);
+ if (ret)
+ goto out;
+
+ ret = krb5_unparse_name(context, tp, &tpn);
+ if (ret)
+ goto out;
+
+ ret = _krb5_principalname2krb5_principal(context,
+ &dp,
+ t->sname,
+ t->realm);
+ if (ret)
+ goto out;
+
+ ret = krb5_unparse_name(context, dp, &dpn);
+ if (ret)
+ goto out;
+ /* check that ticket is valid */
if (adtkt.flags.forwardable == 0) {
kdc_log(context, config, 0,
"Missing forwardable flag on ticket for "
- "constrained delegation from %s to %s ", spn, cpn);
- ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
+ "constrained delegation from %s (%s) as %s to %s ",
+ cpn, dpn, tpn, spn);
+ ret = KRB5KDC_ERR_BADOPTION;
goto out;
}
- ret = check_constrained_delegation(context, config, client, sp);
+ ret = check_constrained_delegation(context, config, clientdb,
+ client, server, sp);
if (ret) {
kdc_log(context, config, 0,
- "constrained delegation from %s to %s not allowed",
- spn, cpn);
+ "constrained delegation from %s (%s) as %s to %s not allowed",
+ cpn, dpn, tpn, spn);
goto out;
}
- ret = _krb5_principalname2krb5_principal(context,
- &client_principal,
- adtkt.cname,
- adtkt.crealm);
- if (ret)
+ ret = verify_flags(context, config, &adtkt, tpn);
+ if (ret) {
goto out;
+ }
- ret = krb5_unparse_name(context, client_principal, &str);
- if (ret)
- goto out;
+ krb5_data_free(&rspac);
- ret = verify_flags(context, config, &adtkt, str);
+ /*
+ * generate the PAC for the user.
+ *
+ * TODO: pass in t->sname and t->realm and build
+ * a S4U_DELEGATION_INFO blob to the PAC.
+ */
+ ret = check_PAC(context, config, tp, dp,
+ client, server, krbtgt,
+ &clientkey->key, &tkey_check->key,
+ ekey, &tkey_sign->key,
+ &adtkt, &rspac, &ad_signedpath);
if (ret) {
- free(str);
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0,
+ "Verify delegated PAC failed to %s for client"
+ "%s (%s) as %s from %s with %s",
+ spn, cpn, dpn, tpn, from, msg);
+ krb5_free_error_message(context, msg);
goto out;
}
/*
- * Check KRB5SignedPath in authorization data and add new entry to
- * make sure servers can't fake a ticket to us.
+ * Check that the KDC issued the user's ticket.
*/
-
ret = check_KRB5SignedPath(context,
config,
krbtgt,
+ cp,
&adtkt,
- &spp,
- 1);
+ NULL,
+ &ad_signedpath);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 0,
"KRB5SignedPath check from service %s failed "
- "for delegation to %s for client %s "
+ "for delegation to %s for client %s (%s)"
"from %s failed with %s",
- spn, str, cpn, from, krb5_get_err_text(context, ret));
- free(str);
+ spn, tpn, dpn, cpn, from, msg);
+ krb5_free_error_message(context, msg);
goto out;
}
- kdc_log(context, config, 0, "constrained delegation for %s "
- "from %s to %s", str, cpn, spn);
- free(str);
+ if (!ad_signedpath) {
+ ret = KRB5KDC_ERR_BADOPTION;
+ kdc_log(context, config, 0,
+ "Ticket not signed with PAC nor SignedPath service %s failed "
+ "for delegation to %s for client %s (%s)"
+ "from %s",
+ spn, tpn, dpn, cpn, from);
+ goto out;
+ }
- /*
- * Also require that the KDC have issue the service's krbtgt
- * used to do the request.
- */
- require_signedpath = 1;
+ kdc_log(context, config, 0, "constrained delegation for %s "
+ "from %s (%s) to %s", tpn, cpn, dpn, spn);
}
/*
* Check flags
*/
- ret = _kdc_check_flags(context, config,
- client, cpn,
- server, spn,
- FALSE);
+ ret = kdc_check_flags(context, config,
+ client, cpn,
+ server, spn,
+ FALSE);
if(ret)
goto out;
- if((b->kdc_options.validate || b->kdc_options.renew) &&
- !krb5_principal_compare(context,
+ if((b->kdc_options.validate || b->kdc_options.renew) &&
+ !krb5_principal_compare(context,
krbtgt->entry.principal,
server->entry.principal)){
kdc_log(context, config, 0, "Inconsistent request.");
@@ -1680,123 +2171,99 @@ server_lookup:
kdc_log(context, config, 0, "Request from wrong address");
goto out;
}
-
+
/*
- * Select enctype, return key and kvno.
+ * If this is an referral, add server referral data to the
+ * auth_data reply .
*/
+ if (ref_realm) {
+ PA_DATA pa;
+ krb5_crypto crypto;
- {
- krb5_enctype etype;
+ kdc_log(context, config, 0,
+ "Adding server referral to %s", ref_realm);
- if(b->kdc_options.enc_tkt_in_skey) {
- int i;
- ekey = &adtkt.key;
- for(i = 0; i < b->etype.len; i++)
- if (b->etype.val[i] == adtkt.key.keytype)
- break;
- if(i == b->etype.len) {
- krb5_clear_error_string(context);
- return KRB5KDC_ERR_ETYPE_NOSUPP;
- }
- etype = b->etype.val[i];
- kvno = 0;
- } else {
- Key *skey;
-
- ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,
- &skey, &etype);
- if(ret) {
- kdc_log(context, config, 0,
- "Server (%s) has no support for etypes", spp);
- return ret;
- }
- ekey = &skey->key;
- kvno = server->entry.kvno;
- }
-
- ret = krb5_generate_random_keyblock(context, etype, &sessionkey);
+ ret = krb5_crypto_init(context, &sessionkey, 0, &crypto);
if (ret)
goto out;
- }
-
- /* check PAC if not cross realm and if there is one */
- if (!cross_realm) {
- Key *tkey;
- ret = hdb_enctype2key(context, &krbtgt->entry,
- krbtgt_etype, &tkey);
- if(ret) {
+ ret = build_server_referral(context, config, crypto, ref_realm,
+ NULL, s, &pa.padata_value);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
kdc_log(context, config, 0,
- "Failed to find key for krbtgt PAC check");
+ "Failed building server referral");
goto out;
}
+ pa.padata_type = KRB5_PADATA_SERVER_REFERRAL;
- ret = check_PAC(context, config, client_principal,
- client, server, ekey, &tkey->key,
- tgt, &rspac, &require_signedpath);
+ ret = add_METHOD_DATA(&enc_pa_data, &pa);
+ krb5_data_free(&pa.padata_value);
if (ret) {
kdc_log(context, config, 0,
- "Verify PAC failed for %s (%s) from %s with %s",
- spn, cpn, from, krb5_get_err_text(context, ret));
+ "Add server referral METHOD-DATA failed");
goto out;
}
}
- /* also check the krbtgt for signature */
- ret = check_KRB5SignedPath(context,
- config,
- krbtgt,
- tgt,
- &spp,
- require_signedpath);
- if (ret) {
- kdc_log(context, config, 0,
- "KRB5SignedPath check failed for %s (%s) from %s with %s",
- spn, cpn, from, krb5_get_err_text(context, ret));
- goto out;
- }
-
/*
*
*/
ret = tgs_make_reply(context,
- config,
- b,
- client_principal,
- tgt,
+ config,
+ b,
+ tp,
+ tgt,
+ replykey,
+ rk_is_subkey,
ekey,
&sessionkey,
kvno,
- auth_data,
- server,
+ *auth_data,
+ server,
+ rsp,
spn,
- client,
- cp,
- krbtgt,
+ client,
+ cp,
+ krbtgt_out,
krbtgt_etype,
spp,
&rspac,
+ &enc_pa_data,
e_text,
reply);
-
+
out:
+ if (tpn != cpn)
+ free(tpn);
free(spn);
free(cpn);
-
+ if (dpn)
+ free(dpn);
+
krb5_data_free(&rspac);
krb5_free_keyblock_contents(context, &sessionkey);
+ if(krbtgt_out)
+ _kdc_free_ent(context, krbtgt_out);
if(server)
_kdc_free_ent(context, server);
if(client)
_kdc_free_ent(context, client);
+ if(s4u2self_impersonated_client)
+ _kdc_free_ent(context, s4u2self_impersonated_client);
- if (client_principal && client_principal != cp)
- krb5_free_principal(context, client_principal);
+ if (tp && tp != cp)
+ krb5_free_principal(context, tp);
if (cp)
krb5_free_principal(context, cp);
+ if (dp)
+ krb5_free_principal(context, dp);
if (sp)
krb5_free_principal(context, sp);
+ if (ref_realm)
+ free(ref_realm);
+ free_METHOD_DATA(&enc_pa_data);
free_EncTicketPart(&adtkt);
@@ -1808,9 +2275,9 @@ out:
*/
krb5_error_code
-_kdc_tgs_rep(krb5_context context,
+_kdc_tgs_rep(krb5_context context,
krb5_kdc_configuration *config,
- KDC_REQ *req,
+ KDC_REQ *req,
krb5_data *data,
const char *from,
struct sockaddr *from_addr,
@@ -1826,6 +2293,8 @@ _kdc_tgs_rep(krb5_context context,
const char *e_text = NULL;
krb5_enctype krbtgt_etype = ETYPE_NULL;
+ krb5_keyblock *replykey = NULL;
+ int rk_is_subkey = 0;
time_t *csec = NULL;
int *cusec = NULL;
@@ -1835,17 +2304,17 @@ _kdc_tgs_rep(krb5_context context,
"TGS-REQ from %s without PA-DATA", from);
goto out;
}
-
+
tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ);
if(tgs_req == NULL){
ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
-
- kdc_log(context, config, 0,
+
+ kdc_log(context, config, 0,
"TGS-REQ from %s without PA-TGS-REQ", from);
goto out;
}
- ret = tgs_parse_request(context, config,
+ ret = tgs_parse_request(context, config,
&req->req_body, tgs_req,
&krbtgt,
&krbtgt_etype,
@@ -1853,9 +2322,15 @@ _kdc_tgs_rep(krb5_context context,
&e_text,
from, from_addr,
&csec, &cusec,
- &auth_data);
+ &auth_data,
+ &replykey,
+ &rk_is_subkey);
+ if (ret == HDB_ERR_NOT_FOUND_HERE) {
+ /* kdc_log() is called in tgs_parse_request() */
+ goto out;
+ }
if (ret) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Failed parsing TGS-REQ from %s", from);
goto out;
}
@@ -1866,15 +2341,16 @@ _kdc_tgs_rep(krb5_context context,
&req->req_body,
krbtgt,
krbtgt_etype,
+ replykey,
+ rk_is_subkey,
ticket,
data,
from,
&e_text,
- auth_data,
- from_addr,
- datagram_reply);
+ &auth_data,
+ from_addr);
if (ret) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Failed building TGS-REP to %s", from);
goto out;
}
@@ -1887,7 +2363,9 @@ _kdc_tgs_rep(krb5_context context,
}
out:
- if(ret && data->data == NULL){
+ if (replykey)
+ krb5_free_keyblock(context, replykey);
+ if(ret && ret != HDB_ERR_NOT_FOUND_HERE && data->data == NULL){
krb5_mk_error(context,
ret,
NULL,
@@ -1897,6 +2375,7 @@ out:
csec,
cusec,
data);
+ ret = 0;
}
free(csec);
free(cusec);
@@ -1910,5 +2389,5 @@ out:
free(auth_data);
}
- return 0;
+ return ret;
}
diff --git a/crypto/heimdal/kdc/kstash.8 b/crypto/heimdal/kdc/kstash.8
index f30eac6..615132b 100644
--- a/crypto/heimdal/kdc/kstash.8
+++ b/crypto/heimdal/kdc/kstash.8
@@ -1,35 +1,35 @@
-.\" Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
-.\" (Royal Institute of Technology, Stockholm, Sweden).
-.\" All rights reserved.
+.\" Copyright (c) 1997 - 2004 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:
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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: kstash.8 20316 2007-04-11 11:53:20Z lha $
+.\" $Id$
.\"
.Dd April 10, 2007
.Dt KSTASH 8
@@ -41,19 +41,19 @@
.Nm
.Bk -words
.Oo Fl e Ar string \*(Ba Xo
-.Fl -enctype= Ns Ar string
+.Fl Fl enctype= Ns Ar string
.Xc
.Oc
.Oo Fl k Ar file \*(Ba Xo
-.Fl -key-file= Ns Ar file
+.Fl Fl key-file= Ns Ar file
.Xc
.Oc
-.Op Fl -convert-file
-.Op Fl -random-key
-.Op Fl -master-key-fd= Ns Ar fd
-.Op Fl -random-key
-.Op Fl h | Fl -help
-.Op Fl -version
+.Op Fl Fl convert-file
+.Op Fl Fl random-key
+.Op Fl Fl master-key-fd= Ns Ar fd
+.Op Fl Fl random-key
+.Op Fl h | Fl Fl help
+.Op Fl Fl version
.Ek
.Sh DESCRIPTION
.Nm
@@ -62,28 +62,16 @@ used by the KDC.
.Pp
Supported options:
.Bl -tag -width Ds
-.It Xo
-.Fl e Ar string ,
-.Fl -enctype= Ns Ar string
-.Xc
+.It Fl e Ar string , Fl Fl enctype= Ns Ar string
the encryption type to use, defaults to DES3-CBC-SHA1.
-.It Xo
-.Fl k Ar file ,
-.Fl -key-file= Ns Ar file
-.Xc
+.It Fl k Ar file , Fl Fl key-file= Ns Ar file
the name of the master key file.
-.It Xo
-.Fl -convert-file
-.Xc
+.It Fl Fl convert-file
don't ask for a new master key, just read an old master key file, and
write it back in the new keyfile format.
-.It Xo
-.Fl -random-key
-.Xc
+.It Fl Fl random-key
generate a random master key.
-.It Xo
-.Fl -master-key-fd= Ns Ar fd
-.Xc
+.It Fl Fl master-key-fd= Ns Ar fd
filedescriptor to read passphrase from, if not specified the
passphrase will be read from the terminal.
.El
diff --git a/crypto/heimdal/kdc/kstash.c b/crypto/heimdal/kdc/kstash.c
index 9e499a1..0b75fb8 100644
--- a/crypto/heimdal/kdc/kstash.c
+++ b/crypto/heimdal/kdc/kstash.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2004 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "headers.h"
-RCSID("$Id: kstash.c 22244 2007-12-08 23:47:42Z lha $");
-
krb5_context context;
static char *keyfile;
@@ -48,15 +46,17 @@ static int random_key_flag;
static const char *enctype_str = "des3-cbc-sha1";
static struct getargs args[] = {
- { "enctype", 'e', arg_string, &enctype_str, "encryption type" },
+ { "enctype", 'e', arg_string, rk_UNCONST(&enctype_str), "encryption type",
+ NULL },
{ "key-file", 'k', arg_string, &keyfile, "master key file", "file" },
- { "convert-file", 0, arg_flag, &convert_flag,
- "just convert keyfile to new format" },
- { "master-key-fd", 0, arg_integer, &master_key_fd,
+ { "convert-file", 0, arg_flag, &convert_flag,
+ "just convert keyfile to new format", NULL },
+ { "master-key-fd", 0, arg_integer, &master_key_fd,
"filedescriptor to read passphrase from", "fd" },
- { "random-key", 0, arg_flag, &random_key_flag, "generate a random master key" },
- { "help", 'h', arg_flag, &help_flag },
- { "version", 0, arg_flag, &version_flag }
+ { "random-key", 0, arg_flag, &random_key_flag,
+ "generate a random master key", NULL },
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL },
+ { "version", 0, arg_flag, &version_flag, NULL, NULL }
};
int num_args = sizeof(args) / sizeof(args[0]);
@@ -66,11 +66,11 @@ main(int argc, char **argv)
{
char buf[1024];
krb5_error_code ret;
-
+
krb5_enctype enctype;
hdb_master_key mkey;
-
+
krb5_program_setup(&context, argc, argv, args, num_args, NULL);
if(help_flag)
@@ -118,7 +118,7 @@ main(int argc, char **argv)
krb5_err(context, 1, errno, "failed to read passphrase");
buf[n] = '\0';
buf[strcspn(buf, "\r\n")] = '\0';
-
+
} else {
if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ", 1))
exit(1);
@@ -126,11 +126,11 @@ main(int argc, char **argv)
krb5_string_to_key_salt(context, enctype, buf, salt, &key);
}
ret = hdb_add_master_key(context, &key, &mkey);
-
+
krb5_free_keyblock_contents(context, &key);
}
-
+
{
char *new, *old;
asprintf(&old, "%s.old", keyfile);
@@ -144,13 +144,19 @@ main(int argc, char **argv)
if(ret)
unlink(new);
else {
+#ifndef NO_POSIX_LINKS
unlink(old);
if(link(keyfile, old) < 0 && errno != ENOENT) {
ret = errno;
unlink(new);
- } else if(rename(new, keyfile) < 0) {
- ret = errno;
+ } else {
+#endif
+ if(rename(new, keyfile) < 0) {
+ ret = errno;
+ }
+#ifndef NO_POSIX_LINKS
}
+#endif
}
out:
free(old);
diff --git a/crypto/heimdal/kdc/kx509.c b/crypto/heimdal/kdc/kx509.c
index b1b861e..8d683d5 100644
--- a/crypto/heimdal/kdc/kx509.c
+++ b/crypto/heimdal/kdc/kx509.c
@@ -1,34 +1,34 @@
/*
- * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2006 - 2007 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
@@ -36,14 +36,14 @@
#include <rfc2459_asn1.h>
#include <hx509.h>
-RCSID("$Id: kx509.c 21607 2007-07-17 07:04:52Z lha $");
+#ifdef KX509
/*
*
*/
krb5_error_code
-_kdc_try_kx509_request(void *ptr, size_t len, Kx509Request *req, size_t *size)
+_kdc_try_kx509_request(void *ptr, size_t len, struct Kx509Request *req, size_t *size)
{
if (len < 4)
return -1;
@@ -59,22 +59,23 @@ _kdc_try_kx509_request(void *ptr, size_t len, Kx509Request *req, size_t *size)
static const unsigned char version_2_0[4] = {0 , 0, 2, 0};
static krb5_error_code
-verify_req_hash(krb5_context context,
+verify_req_hash(krb5_context context,
const Kx509Request *req,
krb5_keyblock *key)
{
unsigned char digest[SHA_DIGEST_LENGTH];
HMAC_CTX ctx;
-
+
if (req->pk_hash.length != sizeof(digest)) {
- krb5_set_error_string(context, "pk-hash have wrong length: %lu",
- (unsigned long)req->pk_hash.length);
+ krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+ "pk-hash have wrong length: %lu",
+ (unsigned long)req->pk_hash.length);
return KRB5KDC_ERR_PREAUTH_FAILED;
}
HMAC_CTX_init(&ctx);
- HMAC_Init_ex(&ctx,
- key->keyvalue.data, key->keyvalue.length,
+ HMAC_Init_ex(&ctx,
+ key->keyvalue.data, key->keyvalue.length,
EVP_sha1(), NULL);
if (sizeof(digest) != HMAC_size(&ctx))
krb5_abortx(context, "runtime error, hmac buffer wrong size in kx509");
@@ -84,7 +85,8 @@ verify_req_hash(krb5_context context,
HMAC_CTX_cleanup(&ctx);
if (memcmp(req->pk_hash.data, digest, sizeof(digest)) != 0) {
- krb5_set_error_string(context, "pk-hash is not correct");
+ krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+ "pk-hash is not correct");
return KRB5KDC_ERR_PREAUTH_FAILED;
}
return 0;
@@ -95,18 +97,17 @@ calculate_reply_hash(krb5_context context,
krb5_keyblock *key,
Kx509Response *rep)
{
+ krb5_error_code ret;
HMAC_CTX ctx;
-
+
HMAC_CTX_init(&ctx);
- HMAC_Init_ex(&ctx,
- key->keyvalue.data, key->keyvalue.length,
+ HMAC_Init_ex(&ctx, key->keyvalue.data, key->keyvalue.length,
EVP_sha1(), NULL);
- rep->hash->length = HMAC_size(&ctx);
- rep->hash->data = malloc(rep->hash->length);
- if (rep->hash->data == NULL) {
+ ret = krb5_data_alloc(rep->hash, HMAC_size(&ctx));
+ if (ret) {
HMAC_CTX_cleanup(&ctx);
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
@@ -131,18 +132,17 @@ calculate_reply_hash(krb5_context context,
}
/*
- * Build a certifate for `principal´ that will expire at `endtime´.
+ * Build a certifate for `principal´ that will expire at `endtime´.
*/
static krb5_error_code
-build_certificate(krb5_context context,
+build_certificate(krb5_context context,
krb5_kdc_configuration *config,
const krb5_data *key,
time_t endtime,
krb5_principal principal,
krb5_data *certificate)
{
- hx509_context hxctx = NULL;
hx509_ca_tbs tbs = NULL;
hx509_env env = NULL;
hx509_cert cert = NULL;
@@ -154,15 +154,7 @@ build_certificate(krb5_context context,
return EINVAL;
}
- ret = hx509_context_init(&hxctx);
- if (ret)
- goto out;
-
- ret = hx509_env_init(hxctx, &env);
- if (ret)
- goto out;
-
- ret = hx509_env_add(hxctx, env, "principal-name",
+ ret = hx509_env_add(context->hx509ctx, &env, "principal-name",
krb5_principal_get_comp_string(context, principal, 0));
if (ret)
goto out;
@@ -171,14 +163,14 @@ build_certificate(krb5_context context,
hx509_certs certs;
hx509_query *q;
- ret = hx509_certs_init(hxctx, config->kx509_ca, 0,
+ ret = hx509_certs_init(context->hx509ctx, config->kx509_ca, 0,
NULL, &certs);
if (ret) {
kdc_log(context, config, 0, "Failed to load CA %s",
config->kx509_ca);
goto out;
}
- ret = hx509_query_alloc(hxctx, &q);
+ ret = hx509_query_alloc(context->hx509ctx, &q);
if (ret) {
hx509_certs_free(&certs);
goto out;
@@ -187,8 +179,8 @@ build_certificate(krb5_context context,
hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
hx509_query_match_option(q, HX509_QUERY_OPTION_KU_KEYCERTSIGN);
- ret = hx509_certs_find(hxctx, certs, q, &signer);
- hx509_query_free(hxctx, q);
+ ret = hx509_certs_find(context->hx509ctx, certs, q, &signer);
+ hx509_query_free(context->hx509ctx, q);
hx509_certs_free(&certs);
if (ret) {
kdc_log(context, config, 0, "Failed to find a CA in %s",
@@ -197,7 +189,7 @@ build_certificate(krb5_context context,
}
}
- ret = hx509_ca_tbs_init(hxctx, &tbs);
+ ret = hx509_ca_tbs_init(context->hx509ctx, &tbs);
if (ret)
goto out;
@@ -210,14 +202,14 @@ build_certificate(krb5_context context,
spki.subjectPublicKey.data = key->data;
spki.subjectPublicKey.length = key->length * 8;
- ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(),
+ ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption,
&spki.algorithm.algorithm);
any.data = "\x05\x00";
any.length = 2;
spki.algorithm.parameters = &any;
- ret = hx509_ca_tbs_set_spki(hxctx, tbs, &spki);
+ ret = hx509_ca_tbs_set_spki(context->hx509ctx, tbs, &spki);
der_free_oid(&spki.algorithm.algorithm);
if (ret)
goto out;
@@ -227,21 +219,21 @@ build_certificate(krb5_context context,
hx509_certs certs;
hx509_cert template;
- ret = hx509_certs_init(hxctx, config->kx509_template, 0,
+ ret = hx509_certs_init(context->hx509ctx, config->kx509_template, 0,
NULL, &certs);
if (ret) {
kdc_log(context, config, 0, "Failed to load template %s",
config->kx509_template);
goto out;
}
- ret = hx509_get_one_cert(hxctx, certs, &template);
+ ret = hx509_get_one_cert(context->hx509ctx, certs, &template);
hx509_certs_free(&certs);
if (ret) {
kdc_log(context, config, 0, "Failed to find template in %s",
config->kx509_template);
goto out;
}
- ret = hx509_ca_tbs_set_template(hxctx, tbs,
+ ret = hx509_ca_tbs_set_template(context->hx509ctx, tbs,
HX509_CA_TEMPLATE_SUBJECT|
HX509_CA_TEMPLATE_KU|
HX509_CA_TEMPLATE_EKU,
@@ -251,24 +243,22 @@ build_certificate(krb5_context context,
goto out;
}
- hx509_ca_tbs_set_notAfter(hxctx, tbs, endtime);
+ hx509_ca_tbs_set_notAfter(context->hx509ctx, tbs, endtime);
- hx509_ca_tbs_subject_expand(hxctx, tbs, env);
+ hx509_ca_tbs_subject_expand(context->hx509ctx, tbs, env);
hx509_env_free(&env);
- ret = hx509_ca_sign(hxctx, tbs, signer, &cert);
+ ret = hx509_ca_sign(context->hx509ctx, tbs, signer, &cert);
hx509_cert_free(signer);
if (ret)
goto out;
hx509_ca_tbs_free(&tbs);
- ret = hx509_cert_binary(hxctx, cert, certificate);
+ ret = hx509_cert_binary(context->hx509ctx, cert, certificate);
hx509_cert_free(cert);
if (ret)
goto out;
-
- hx509_context_free(&hxctx);
return 0;
out:
@@ -278,9 +268,7 @@ out:
hx509_ca_tbs_free(&tbs);
if (signer)
hx509_cert_free(signer);
- if (hxctx)
- hx509_context_free(&hxctx);
- krb5_set_error_string(context, "cert creation failed");
+ krb5_set_error_message(context, ret, "cert creation failed");
return ret;
}
@@ -289,9 +277,9 @@ out:
*/
krb5_error_code
-_kdc_do_kx509(krb5_context context,
+_kdc_do_kx509(krb5_context context,
krb5_kdc_configuration *config,
- const Kx509Request *req, krb5_data *reply,
+ const struct Kx509Request *req, krb5_data *reply,
const char *from, struct sockaddr *addr)
{
krb5_error_code ret;
@@ -309,7 +297,7 @@ _kdc_do_kx509(krb5_context context,
memset(&rep, 0, sizeof(rep));
if(!config->enable_kx509) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"Rejected kx509 request (disabled) from %s", from);
return KRB5KDC_ERR_POLICY;
}
@@ -322,7 +310,7 @@ _kdc_do_kx509(krb5_context context,
goto out;
}
- ret = krb5_rd_req(context,
+ ret = krb5_rd_req(context,
&ac,
&req->authenticator,
NULL,
@@ -339,7 +327,7 @@ _kdc_do_kx509(krb5_context context,
ret = krb5_unparse_name(context, cprincipal, &cname);
if (ret)
goto out;
-
+
/* verify server principal */
ret = krb5_sname_to_principal(context, NULL, "kca_service",
@@ -357,20 +345,36 @@ _kdc_do_kx509(krb5_context context,
ret = krb5_principal_compare(context, sprincipal, principal);
krb5_free_principal(context, principal);
if (ret != TRUE) {
+ char *expected, *used;
+
+ ret = krb5_unparse_name(context, sprincipal, &expected);
+ if (ret)
+ goto out;
+ ret = krb5_unparse_name(context, principal, &used);
+ if (ret) {
+ krb5_xfree(expected);
+ goto out;
+ }
+
ret = KRB5KDC_ERR_SERVER_NOMATCH;
- krb5_set_error_string(context,
- "User %s used wrong Kx509 service principal",
- cname);
+ krb5_set_error_message(context, ret,
+ "User %s used wrong Kx509 service "
+ "principal, expected: %s, used %s",
+ cname, expected, used);
+ krb5_xfree(expected);
+ krb5_xfree(used);
goto out;
}
}
-
+
ret = krb5_auth_con_getkey(context, ac, &key);
- if (ret || key == NULL) {
- krb5_set_error_string(context, "Kx509 can't get session key");
+ if (ret == 0 && key == NULL)
+ ret = KRB5KDC_ERR_NULL_KEY;
+ if (ret) {
+ krb5_set_error_message(context, ret, "Kx509 can't get session key");
goto out;
}
-
+
ret = verify_req_hash(context, req, key);
if (ret)
goto out;
@@ -385,8 +389,10 @@ _kdc_do_kx509(krb5_context context,
if (ret)
goto out;
free_RSAPublicKey(&key);
- if (size != req->pk_key.length)
- ;
+ if (size != req->pk_key.length) {
+ ret = ASN1_EXTRA_DATA;
+ goto out;
+ }
}
ALLOC(rep.certificate);
@@ -398,7 +404,7 @@ _kdc_do_kx509(krb5_context context,
goto out;
krb5_data_zero(rep.hash);
- ret = build_certificate(context, config, &req->pk_key,
+ ret = build_certificate(context, config, &req->pk_key,
krb5_ticket_get_endtime(context, ticket),
cprincipal, rep.certificate);
if (ret)
@@ -418,7 +424,7 @@ _kdc_do_kx509(krb5_context context,
ASN1_MALLOC_ENCODE(Kx509Response, data.data, data.length, &rep,
&size, ret);
if (ret) {
- krb5_set_error_string(context, "Failed to encode kx509 reply");
+ krb5_set_error_message(context, ret, "Failed to encode kx509 reply");
goto out;
}
if (size != data.length)
@@ -458,3 +464,5 @@ out:
return 0;
}
+
+#endif /* KX509 */
diff --git a/crypto/heimdal/kdc/log.c b/crypto/heimdal/kdc/log.c
index 8cf967f..6d85729 100644
--- a/crypto/heimdal/kdc/log.c
+++ b/crypto/heimdal/kdc/log.c
@@ -1,63 +1,67 @@
/*
- * Copyright (c) 1997, 1998, 2002 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997, 1998, 2002 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:
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 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.
+ * 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.
*
- * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: log.c 22254 2007-12-09 06:01:05Z lha $");
void
-kdc_openlog(krb5_context context,
+kdc_openlog(krb5_context context,
+ const char *service,
krb5_kdc_configuration *config)
{
char **s = NULL, **p;
krb5_initlog(context, "kdc", &config->logf);
- s = krb5_config_get_strings(context, NULL, "kdc", "logging", NULL);
+ s = krb5_config_get_strings(context, NULL, service, "logging", NULL);
if(s == NULL)
- s = krb5_config_get_strings(context, NULL, "logging", "kdc", NULL);
+ s = krb5_config_get_strings(context, NULL, "logging", service, NULL);
if(s){
for(p = s; *p; p++)
krb5_addlog_dest(context, config->logf, *p);
krb5_config_free_strings(s);
}else {
- char *s;
- asprintf(&s, "0-1/FILE:%s/%s", hdb_db_dir(context), KDC_LOG_FILE);
- krb5_addlog_dest(context, config->logf, s);
- free(s);
+ char *ss;
+ if (asprintf(&ss, "0-1/FILE:%s/%s", hdb_db_dir(context),
+ KDC_LOG_FILE) < 0)
+ err(1, NULL);
+ krb5_addlog_dest(context, config->logf, ss);
+ free(ss);
}
krb5_set_warn_dest(context, config->logf);
}
char*
-kdc_log_msg_va(krb5_context context,
+kdc_log_msg_va(krb5_context context,
krb5_kdc_configuration *config,
int level, const char *fmt, va_list ap)
{
@@ -67,7 +71,7 @@ kdc_log_msg_va(krb5_context context,
}
char*
-kdc_log_msg(krb5_context context,
+kdc_log_msg(krb5_context context,
krb5_kdc_configuration *config,
int level, const char *fmt, ...)
{
@@ -80,7 +84,7 @@ kdc_log_msg(krb5_context context,
}
void
-kdc_log(krb5_context context,
+kdc_log(krb5_context context,
krb5_kdc_configuration *config,
int level, const char *fmt, ...)
{
diff --git a/crypto/heimdal/kdc/main.c b/crypto/heimdal/kdc/main.c
index 9195b04..fc42e9d 100644
--- a/crypto/heimdal/kdc/main.c
+++ b/crypto/heimdal/kdc/main.c
@@ -1,34 +1,36 @@
/*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2005 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:
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 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.
+ * 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.
*
- * 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.
+ * 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 "kdc_locl.h"
@@ -36,11 +38,15 @@
#include <util.h>
#endif
-RCSID("$Id: main.c 20454 2007-04-19 20:21:51Z lha $");
+#ifdef HAVE_CAPNG
+#include <cap-ng.h>
+#endif
sig_atomic_t exit_flag = 0;
+#ifdef SUPPORT_DETACH
int detach_from_console = -1;
+#endif
static RETSIGTYPE
sigterm(int sig)
@@ -48,6 +54,54 @@ sigterm(int sig)
exit_flag = sig;
}
+/*
+ * Allow dropping root bit, since heimdal reopens the database all the
+ * time the database needs to be owned by the user you are switched
+ * too. A better solution is to split the kdc in to more processes and
+ * run the network facing part with very low privilege.
+ */
+
+static void
+switch_environment(void)
+{
+#ifdef HAVE_GETEUID
+ if ((runas_string || chroot_string) && geteuid() != 0)
+ errx(1, "no running as root, can't switch user/chroot");
+
+ if (chroot_string && chroot(chroot_string) != 0)
+ errx(1, "chroot(%s)", "chroot_string failed");
+
+ if (runas_string) {
+ struct passwd *pw;
+
+ pw = getpwnam(runas_string);
+ if (pw == NULL)
+ errx(1, "unknown user %s", runas_string);
+
+ if (initgroups(pw->pw_name, pw->pw_gid) < 0)
+ err(1, "initgroups failed");
+
+#ifndef HAVE_CAPNG
+ if (setgid(pw->pw_gid) < 0)
+ err(1, "setgid(%s) failed", runas_string);
+
+ if (setuid(pw->pw_uid) < 0)
+ err(1, "setuid(%s)", runas_string);
+#else
+ capng_clear (CAPNG_EFFECTIVE | CAPNG_PERMITTED);
+ if (capng_updatev (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
+ CAP_NET_BIND_SERVICE, CAP_SETPCAP, -1) < 0)
+ err(1, "capng_updateev");
+
+ if (capng_change_id(pw->pw_uid, pw->pw_gid,
+ CAPNG_CLEAR_BOUNDING) < 0)
+ err(1, "capng_change_id(%s)", runas_string);
+#endif
+ }
+#endif
+}
+
+
int
main(int argc, char **argv)
{
@@ -56,7 +110,7 @@ main(int argc, char **argv)
krb5_kdc_configuration *config;
setprogname(argv[0]);
-
+
ret = krb5_init_context(&context);
if (ret == KRB5_CONFIG_BADFORMAT)
errx (1, "krb5_init_context failed to parse configuration file");
@@ -79,20 +133,36 @@ main(int argc, char **argv)
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
+#ifdef SIGXCPU
sigaction(SIGXCPU, &sa, NULL);
+#endif
sa.sa_handler = SIG_IGN;
+#ifdef SIGPIPE
sigaction(SIGPIPE, &sa, NULL);
+#endif
}
#else
signal(SIGINT, sigterm);
signal(SIGTERM, sigterm);
+#ifdef SIGXCPU
signal(SIGXCPU, sigterm);
+#endif
+#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
+#endif
+#ifdef SUPPORT_DETACH
if (detach_from_console)
daemon(0, 0);
+#endif
+#ifdef __APPLE__
+ bonjour_announce(context, config);
+#endif
pidfile(NULL);
+
+ switch_environment();
+
loop(context, config);
krb5_free_context(context);
return 0;
diff --git a/crypto/heimdal/kdc/misc.c b/crypto/heimdal/kdc/misc.c
index 072df44..1b2c440 100644
--- a/crypto/heimdal/kdc/misc.c
+++ b/crypto/heimdal/kdc/misc.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997 - 2001 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: misc.c 21106 2007-06-18 10:18:11Z lha $");
-
struct timeval _kdc_now;
krb5_error_code
@@ -42,31 +40,66 @@ _kdc_db_fetch(krb5_context context,
krb5_kdc_configuration *config,
krb5_const_principal principal,
unsigned flags,
+ krb5uint32 *kvno_ptr,
HDB **db,
hdb_entry_ex **h)
{
hdb_entry_ex *ent;
- krb5_error_code ret;
+ krb5_error_code ret = HDB_ERR_NOENTRY;
int i;
+ unsigned kvno = 0;
+
+ if (kvno_ptr) {
+ kvno = *kvno_ptr;
+ flags |= HDB_F_KVNO_SPECIFIED;
+ }
ent = calloc (1, sizeof (*ent));
if (ent == NULL) {
- krb5_set_error_string(context, "out of memory");
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
for(i = 0; i < config->num_db; i++) {
+ krb5_principal enterprise_principal = NULL;
+ if (!(config->db[i]->hdb_capability_flags & HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL)
+ && principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
+ if (principal->name.name_string.len != 1) {
+ ret = KRB5_PARSE_MALFORMED;
+ krb5_set_error_message(context, ret,
+ "malformed request: "
+ "enterprise name with %d name components",
+ principal->name.name_string.len);
+ free(ent);
+ return ret;
+ }
+ ret = krb5_parse_name(context, principal->name.name_string.val[0],
+ &enterprise_principal);
+ if (ret) {
+ free(ent);
+ return ret;
+ }
+
+ principal = enterprise_principal;
+ }
+
ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0);
if (ret) {
- kdc_log(context, config, 0, "Failed to open database: %s",
- krb5_get_err_text(context, ret));
+ const char *msg = krb5_get_error_message(context, ret);
+ kdc_log(context, config, 0, "Failed to open database: %s", msg);
+ krb5_free_error_message(context, msg);
continue;
}
- ret = config->db[i]->hdb_fetch(context,
- config->db[i],
- principal,
- flags | HDB_F_DECRYPT,
- ent);
+
+ ret = config->db[i]->hdb_fetch_kvno(context,
+ config->db[i],
+ principal,
+ flags | HDB_F_DECRYPT,
+ kvno,
+ ent);
+
+ krb5_free_principal(context, enterprise_principal);
+
config->db[i]->hdb_close(context, config->db[i]);
if(ret == 0) {
if (db)
@@ -76,8 +109,9 @@ _kdc_db_fetch(krb5_context context,
}
}
free(ent);
- krb5_set_error_string(context, "no such entry found in hdb");
- return HDB_ERR_NOENTRY;
+ krb5_set_error_message(context, ret,
+ "no such entry found in hdb");
+ return ret;
}
void
@@ -100,23 +134,41 @@ _kdc_get_preferred_key(krb5_context context,
krb5_enctype *enctype,
Key **key)
{
- const krb5_enctype *p;
krb5_error_code ret;
int i;
- p = krb5_kerberos_enctypes(context);
+ if (config->use_strongest_server_key) {
+ const krb5_enctype *p = krb5_kerberos_enctypes(context);
- for (i = 0; p[i] != ETYPE_NULL; i++) {
- if (krb5_enctype_valid(context, p[i]) != 0)
- continue;
- ret = hdb_enctype2key(context, &h->entry, p[i], key);
- if (ret == 0) {
- *enctype = p[i];
+ for (i = 0; p[i] != ETYPE_NULL; i++) {
+ if (krb5_enctype_valid(context, p[i]) != 0)
+ continue;
+ ret = hdb_enctype2key(context, &h->entry, p[i], key);
+ if (ret != 0)
+ continue;
+ if (enctype != NULL)
+ *enctype = p[i];
+ return 0;
+ }
+ } else {
+ *key = NULL;
+
+ for (i = 0; i < h->entry.keys.len; i++) {
+ if (krb5_enctype_valid(context, h->entry.keys.val[i].key.keytype)
+ != 0)
+ continue;
+ ret = hdb_enctype2key(context, &h->entry,
+ h->entry.keys.val[i].key.keytype, key);
+ if (ret != 0)
+ continue;
+ if (enctype != NULL)
+ *enctype = (*key)->key.keytype;
return 0;
}
}
- krb5_set_error_string(context, "No valid kerberos key found for %s", name);
- return EINVAL;
+ krb5_set_error_message(context, EINVAL,
+ "No valid kerberos key found for %s", name);
+ return EINVAL; /* XXX */
}
diff --git a/crypto/heimdal/kdc/mit_dump.c b/crypto/heimdal/kdc/mit_dump.c
index dd2f5d7..f28e932 100644
--- a/crypto/heimdal/kdc/mit_dump.c
+++ b/crypto/heimdal/kdc/mit_dump.c
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 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
@@ -33,8 +33,6 @@
#include "hprop.h"
-RCSID("$Id: mit_dump.c 21745 2007-07-31 16:11:25Z lha $");
-
/*
can have any number of princ stanzas.
format is as follows (only \n indicates newlines)
@@ -42,13 +40,13 @@ princ\t%d\t (%d is KRB5_KDB_V1_BASE_LENGTH, always 38)
%d\t (strlen of principal e.g. shadow/foo@ANDREW.CMU.EDU)
%d\t (number of tl_data)
%d\t (number of key data, e.g. how many keys for this user)
-%d\t (extra data length)
+%d\t (extra data length)
%s\t (principal name)
%d\t (attributes)
%d\t (max lifetime, seconds)
%d\t (max renewable life, seconds)
%d\t (expiration, seconds since epoch or 2145830400 for never)
-%d\t (password expiration, seconds, 0 for never)
+%d\t (password expiration, seconds, 0 for never)
%d\t (last successful auth, seconds since epoch)
%d\t (last failed auth, per above)
%d\t (failed auth count)
@@ -67,7 +65,7 @@ foreach key 0 to number of keys - 1 as above
%02x (key data contents[element n])
except if key_data length is 0
%d (always -1)
- \t
+ \t
foreach extra data length 0 to length - 1
%02x (extra data part)
unless no extra data
@@ -79,7 +77,7 @@ unless no extra data
static int
hex_to_octet_string(const char *ptr, krb5_data *data)
{
- int i;
+ size_t i;
unsigned int v;
for(i = 0; i < data->length; i++) {
if(sscanf(ptr + 2 * i, "%02x", &v) != 1)
@@ -137,7 +135,7 @@ attr_to_flags(unsigned attr, HDBFlags *flags)
/* DUP_SKEY */
flags->invalid = !!(attr & KRB5_KDB_DISALLOW_ALL_TIX);
flags->require_preauth = !!(attr & KRB5_KDB_REQUIRES_PRE_AUTH);
- /* HW_AUTH */
+ flags->require_hwauth = !!(attr & KRB5_KDB_REQUIRES_HW_AUTH);
flags->server = !(attr & KRB5_KDB_DISALLOW_SVR);
flags->change_pw = !!(attr & KRB5_KDB_PWCHANGE_SERVICE);
flags->client = 1; /* XXX */
@@ -167,9 +165,9 @@ fix_salt(krb5_context context, hdb_entry *ent, int key_num)
case KRB5_KDB_SALTTYPE_NOREALM:
{
size_t len;
- int i;
+ size_t i;
char *p;
-
+
len = 0;
for (i = 0; i < ent->principal->name.name_string.len; ++i)
len += strlen(ent->principal->name.name_string.val[i]);
@@ -189,8 +187,8 @@ fix_salt(krb5_context context, hdb_entry *ent, int key_num)
}
case KRB5_KDB_SALTTYPE_ONLYREALM:
krb5_data_free(&salt->salt);
- ret = krb5_data_copy(&salt->salt,
- ent->principal->realm,
+ ret = krb5_data_copy(&salt->salt,
+ ent->principal->realm,
strlen(ent->principal->realm));
if(ret)
return ret;
@@ -201,8 +199,8 @@ fix_salt(krb5_context context, hdb_entry *ent, int key_num)
break;
case KRB5_KDB_SALTTYPE_AFS3:
krb5_data_free(&salt->salt);
- ret = krb5_data_copy(&salt->salt,
- ent->principal->realm,
+ ret = krb5_data_copy(&salt->salt,
+ ent->principal->realm,
strlen(ent->principal->realm));
if(ret)
return ret;
@@ -228,7 +226,7 @@ mit_prop_dump(void *arg, const char *file)
f = fopen(file, "r");
if(f == NULL)
return errno;
-
+
while(fgets(line, sizeof(line), f)) {
char *p = line, *q;
@@ -236,7 +234,7 @@ mit_prop_dump(void *arg, const char *file)
int num_tl_data;
int num_key_data;
- int extra_data_length;
+ int high_kvno;
int attributes;
int tmp;
@@ -257,8 +255,11 @@ mit_prop_dump(void *arg, const char *file)
q = nexttoken(&p); /* x.0 */
if(sscanf(q, "%d", &major) != 1)
errx(1, "line %d: unknown version", lineno);
- if(major != 4)
- errx(1, "unknown dump file format, got %d, expected 4", major);
+ if(major != 4 && major != 5 && major != 6)
+ errx(1, "unknown dump file format, got %d, expected 4-6",
+ major);
+ continue;
+ } else if(strcmp(q, "policy") == 0) {
continue;
} else if(strcmp(q, "princ") != 0) {
warnx("line %d: not a principal", lineno);
@@ -269,10 +270,10 @@ mit_prop_dump(void *arg, const char *file)
warnx("line %d: bad base length %d != 38", lineno, tmp);
continue;
}
- q = nexttoken(&p); /* length of principal */
+ nexttoken(&p); /* length of principal */
num_tl_data = getint(&p); /* number of tl-data */
num_key_data = getint(&p); /* number of key-data */
- extra_data_length = getint(&p); /* length of extra data */
+ getint(&p); /* length of extra data */
q = nexttoken(&p); /* principal name */
krb5_parse_name(pd->context, q, &ent.entry.principal);
attributes = getint(&p); /* attributes */
@@ -297,9 +298,9 @@ mit_prop_dump(void *arg, const char *file)
ALLOC(ent.entry.pw_end);
*ent.entry.pw_end = tmp;
}
- q = nexttoken(&p); /* last auth */
- q = nexttoken(&p); /* last failed auth */
- q = nexttoken(&p); /* fail auth count */
+ nexttoken(&p); /* last auth */
+ nexttoken(&p); /* last failed auth */
+ nexttoken(&p); /* fail auth count */
for(i = 0; i < num_tl_data; i++) {
unsigned long val;
int tl_type, tl_length;
@@ -312,6 +313,20 @@ mit_prop_dump(void *arg, const char *file)
#define mit_KRB5_TL_LAST_PWD_CHANGE 1
#define mit_KRB5_TL_MOD_PRINC 2
switch(tl_type) {
+ case mit_KRB5_TL_LAST_PWD_CHANGE:
+ buf = malloc(tl_length);
+ if (buf == NULL)
+ errx(ENOMEM, "malloc");
+ getdata(&p, buf, tl_length); /* data itself */
+ val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ free(buf);
+ ALLOC(ent.entry.extensions);
+ ALLOC_SEQ(ent.entry.extensions, 1);
+ ent.entry.extensions->val[0].mandatory = 0;
+ ent.entry.extensions->val[0].data.element
+ = choice_HDB_extension_data_last_pw_change;
+ ent.entry.extensions->val[0].data.u.last_pw_change = val;
+ break;
case mit_KRB5_TL_MOD_PRINC:
buf = malloc(tl_length);
if (buf == NULL)
@@ -319,6 +334,9 @@ mit_prop_dump(void *arg, const char *file)
getdata(&p, buf, tl_length); /* data itself */
val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
ret = krb5_parse_name(pd->context, (char *)buf + 4, &princ);
+ if (ret)
+ krb5_err(pd->context, 1, ret,
+ "parse_name: %s", (char *)buf + 4);
free(buf);
ALLOC(ent.entry.modified_by);
ent.entry.modified_by->time = val;
@@ -330,14 +348,40 @@ mit_prop_dump(void *arg, const char *file)
}
}
ALLOC_SEQ(&ent.entry.keys, num_key_data);
+ high_kvno = -1;
for(i = 0; i < num_key_data; i++) {
int key_versions;
+ int kvno;
key_versions = getint(&p); /* key data version */
- ent.entry.kvno = getint(&p); /* XXX kvno */
-
+ kvno = getint(&p);
+
+ /*
+ * An MIT dump file may contain multiple sets of keys with
+ * different kvnos. Since the Heimdal database can only represent
+ * one kvno per principal, we only want the highest set. Assume
+ * that set will be given first, and discard all keys with lower
+ * kvnos.
+ */
+ if (kvno > high_kvno && high_kvno != -1)
+ errx(1, "line %d: high kvno keys given after low kvno keys",
+ lineno);
+ else if (kvno < high_kvno) {
+ nexttoken(&p); /* key type */
+ nexttoken(&p); /* key length */
+ nexttoken(&p); /* key */
+ if (key_versions > 1) {
+ nexttoken(&p); /* salt type */
+ nexttoken(&p); /* salt length */
+ nexttoken(&p); /* salt */
+ }
+ ent.entry.keys.len--;
+ continue;
+ }
+ ent.entry.kvno = kvno;
+ high_kvno = kvno;
ALLOC(ent.entry.keys.val[i].mkvno);
- *ent.entry.keys.val[i].mkvno = 0;
-
+ *ent.entry.keys.val[i].mkvno = 1;
+
/* key version 0 -- actual key */
ent.entry.keys.val[i].key.keytype = getint(&p); /* key type */
tmp = getint(&p); /* key length */
@@ -360,12 +404,12 @@ mit_prop_dump(void *arg, const char *file)
} else {
ent.entry.keys.val[i].salt->salt.length = 0;
ent.entry.keys.val[i].salt->salt.data = NULL;
- tmp = getint(&p); /* -1, if no data. */
+ getint(&p); /* -1, if no data. */
}
fix_salt(pd->context, &ent.entry, i);
}
}
- q = nexttoken(&p); /* extra data */
+ nexttoken(&p); /* extra data */
v5_prop(pd->context, NULL, &ent, arg);
}
fclose(f);
diff --git a/crypto/heimdal/kdc/pkinit.c b/crypto/heimdal/kdc/pkinit.c
index bf248af..d85b156 100644
--- a/crypto/heimdal/kdc/pkinit.c
+++ b/crypto/heimdal/kdc/pkinit.c
@@ -1,40 +1,40 @@
/*
- * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2003 - 2008 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:
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 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.
+ * 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.
*
- * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $");
-
#ifdef PKINIT
#include <heim_asn1.h>
@@ -45,31 +45,28 @@ RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $");
#include <hx509.h>
#include "crypto-headers.h"
-/* XXX copied from lib/krb5/pkinit.c */
-struct krb5_pk_identity {
- hx509_context hx509ctx;
- hx509_verify_ctx verify_ctx;
- hx509_certs certs;
- hx509_certs anchors;
- hx509_certs certpool;
- hx509_revoke_ctx revoke;
-};
-
-enum pkinit_type {
- PKINIT_COMPAT_WIN2K = 1,
- PKINIT_COMPAT_27 = 3
-};
-
struct pk_client_params {
- enum pkinit_type type;
- BIGNUM *dh_public_key;
+ enum krb5_pk_type type;
+ enum { USE_RSA, USE_DH, USE_ECDH } keyex;
+ union {
+ struct {
+ BIGNUM *public_key;
+ DH *key;
+ } dh;
+#ifdef HAVE_OPENSSL
+ struct {
+ EC_KEY *public_key;
+ EC_KEY *key;
+ } ecdh;
+#endif
+ } u;
hx509_cert cert;
unsigned nonce;
- DH *dh;
EncryptionKey reply_key;
char *dh_group_name;
hx509_peer_info peer;
hx509_certs client_anchors;
+ hx509_verify_ctx verify_ctx;
};
struct pk_principal_mapping {
@@ -105,7 +102,7 @@ pk_check_pkauthenticator_win2k(krb5_context context,
/* XXX cusec */
if (a->ctime == 0 || abs(a->ctime - now) > context->max_skew) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return KRB5KRB_AP_ERR_SKEW;
}
return 0;
@@ -119,7 +116,7 @@ pk_check_pkauthenticator(krb5_context context,
u_char *buf = NULL;
size_t buf_size;
krb5_error_code ret;
- size_t len;
+ size_t len = 0;
krb5_timestamp now;
Checksum checksum;
@@ -127,13 +124,13 @@ pk_check_pkauthenticator(krb5_context context,
/* XXX cusec */
if (a->ctime == 0 || abs(a->ctime - now) > context->max_skew) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return KRB5KRB_AP_ERR_SKEW;
}
ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, &req->req_body, &len, ret);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return ret;
}
if (buf_size != len)
@@ -148,18 +145,18 @@ pk_check_pkauthenticator(krb5_context context,
&checksum);
free(buf);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return ret;
}
-
+
if (a->paChecksum == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = KRB5_KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED;
goto out;
}
if (der_heim_octet_string_cmp(a->paChecksum, &checksum.checksum) != 0) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
ret = KRB5KRB_ERR_GENERIC;
}
@@ -170,29 +167,43 @@ out:
}
void
-_kdc_pk_free_client_param(krb5_context context,
- pk_client_params *client_params)
+_kdc_pk_free_client_param(krb5_context context, pk_client_params *cp)
{
- if (client_params->cert)
- hx509_cert_free(client_params->cert);
- if (client_params->dh)
- DH_free(client_params->dh);
- if (client_params->dh_public_key)
- BN_free(client_params->dh_public_key);
- krb5_free_keyblock_contents(context, &client_params->reply_key);
- if (client_params->dh_group_name)
- free(client_params->dh_group_name);
- if (client_params->peer)
- hx509_peer_info_free(client_params->peer);
- if (client_params->client_anchors)
- hx509_certs_free(&client_params->client_anchors);
- memset(client_params, 0, sizeof(*client_params));
- free(client_params);
+ if (cp == NULL)
+ return;
+ if (cp->cert)
+ hx509_cert_free(cp->cert);
+ if (cp->verify_ctx)
+ hx509_verify_destroy_ctx(cp->verify_ctx);
+ if (cp->keyex == USE_DH) {
+ if (cp->u.dh.key)
+ DH_free(cp->u.dh.key);
+ if (cp->u.dh.public_key)
+ BN_free(cp->u.dh.public_key);
+ }
+#ifdef HAVE_OPENSSL
+ if (cp->keyex == USE_ECDH) {
+ if (cp->u.ecdh.key)
+ EC_KEY_free(cp->u.ecdh.key);
+ if (cp->u.ecdh.public_key)
+ EC_KEY_free(cp->u.ecdh.public_key);
+ }
+#endif
+ krb5_free_keyblock_contents(context, &cp->reply_key);
+ if (cp->dh_group_name)
+ free(cp->dh_group_name);
+ if (cp->peer)
+ hx509_peer_info_free(cp->peer);
+ if (cp->client_anchors)
+ hx509_certs_free(&cp->client_anchors);
+ memset(cp, 0, sizeof(*cp));
+ free(cp);
}
static krb5_error_code
-generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
- krb5_enctype enctype, krb5_keyblock *reply_key)
+generate_dh_keyblock(krb5_context context,
+ pk_client_params *client_params,
+ krb5_enctype enctype)
{
unsigned char *dh_gen_key = NULL;
krb5_keyblock key;
@@ -201,36 +212,84 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
memset(&key, 0, sizeof(key));
- if (!DH_generate_key(client_params->dh)) {
- krb5_set_error_string(context, "Can't generate Diffie-Hellman keys");
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
- if (client_params->dh_public_key == NULL) {
- krb5_set_error_string(context, "dh_public_key");
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
+ if (client_params->keyex == USE_DH) {
- dh_gen_keylen = DH_size(client_params->dh);
- size = BN_num_bytes(client_params->dh->p);
- if (size < dh_gen_keylen)
- size = dh_gen_keylen;
+ if (client_params->u.dh.public_key == NULL) {
+ ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret, "public_key");
+ goto out;
+ }
- dh_gen_key = malloc(size);
- if (dh_gen_key == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- ret = ENOMEM;
- goto out;
- }
- memset(dh_gen_key, 0, size - dh_gen_keylen);
+ if (!DH_generate_key(client_params->u.dh.key)) {
+ ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "Can't generate Diffie-Hellman keys");
+ goto out;
+ }
- dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
- client_params->dh_public_key,
- client_params->dh);
- if (dh_gen_keylen == -1) {
- krb5_set_error_string(context, "Can't compute Diffie-Hellman key");
+ size = DH_size(client_params->u.dh.key);
+
+ dh_gen_key = malloc(size);
+ if (dh_gen_key == NULL) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
+ goto out;
+ }
+
+ dh_gen_keylen = DH_compute_key(dh_gen_key,client_params->u.dh.public_key, client_params->u.dh.key);
+ if (dh_gen_keylen == (size_t)-1) {
+ ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "Can't compute Diffie-Hellman key");
+ goto out;
+ }
+ if (dh_gen_keylen < size) {
+ size -= dh_gen_keylen;
+ memmove(dh_gen_key + size, dh_gen_key, dh_gen_keylen);
+ memset(dh_gen_key, 0, size);
+ }
+
+ ret = 0;
+#ifdef HAVE_OPENSSL
+ } else if (client_params->keyex == USE_ECDH) {
+
+ if (client_params->u.ecdh.public_key == NULL) {
+ ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret, "public_key");
+ goto out;
+ }
+
+ client_params->u.ecdh.key = EC_KEY_new();
+ if (client_params->u.ecdh.key == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ EC_KEY_set_group(client_params->u.ecdh.key,
+ EC_KEY_get0_group(client_params->u.ecdh.public_key));
+
+ if (EC_KEY_generate_key(client_params->u.ecdh.key) != 1) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ size = (EC_GROUP_get_degree(EC_KEY_get0_group(client_params->u.ecdh.key)) + 7) / 8;
+ dh_gen_key = malloc(size);
+ if (dh_gen_key == NULL) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret,
+ N_("malloc: out of memory", ""));
+ goto out;
+ }
+
+ dh_gen_keylen = ECDH_compute_key(dh_gen_key, size,
+ EC_KEY_get0_public_key(client_params->u.ecdh.public_key),
+ client_params->u.ecdh.key, NULL);
+
+#endif /* HAVE_OPENSSL */
+ } else {
ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "Diffie-Hellman not selected keys");
goto out;
}
@@ -238,7 +297,7 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
enctype,
dh_gen_key, dh_gen_keylen,
NULL, NULL,
- reply_key);
+ &client_params->reply_key);
out:
if (dh_gen_key)
@@ -256,7 +315,8 @@ integer_to_BN(krb5_context context, const char *field, heim_integer *f)
bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL);
if (bn == NULL) {
- krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field);
+ krb5_set_error_message(context, KRB5_BADMSGTYPE,
+ "PKINIT: parsing BN failed %s", field);
return NULL;
}
BN_set_negative(bn, f->negative);
@@ -275,14 +335,17 @@ get_dh_param(krb5_context context,
memset(&dhparam, 0, sizeof(dhparam));
- if (der_heim_oid_cmp(&dh_key_info->algorithm.algorithm, oid_id_dhpublicnumber())) {
- krb5_set_error_string(context,
- "PKINIT invalid oid in clientPublicValue");
- return KRB5_BADMSGTYPE;
+ if ((dh_key_info->subjectPublicKey.length % 8) != 0) {
+ ret = KRB5_BADMSGTYPE;
+ krb5_set_error_message(context, ret,
+ "PKINIT: subjectPublicKey not aligned "
+ "to 8 bit boundary");
+ goto out;
}
if (dh_key_info->algorithm.parameters == NULL) {
- krb5_set_error_string(context, "PKINIT missing algorithm parameter "
+ krb5_set_error_message(context, KRB5_BADMSGTYPE,
+ "PKINIT missing algorithm parameter "
"in clientPublicValue");
return KRB5_BADMSGTYPE;
}
@@ -292,20 +355,12 @@ get_dh_param(krb5_context context,
&dhparam,
NULL);
if (ret) {
- krb5_set_error_string(context, "Can't decode algorithm "
- "parameters in clientPublicValue");
- goto out;
- }
-
- if ((dh_key_info->subjectPublicKey.length % 8) != 0) {
- ret = KRB5_BADMSGTYPE;
- krb5_set_error_string(context, "PKINIT: subjectPublicKey not aligned "
- "to 8 bit boundary");
+ krb5_set_error_message(context, ret, "Can't decode algorithm "
+ "parameters in clientPublicValue");
goto out;
}
-
- ret = _krb5_dh_group_ok(context, config->pkinit_dh_min_bits,
+ ret = _krb5_dh_group_ok(context, config->pkinit_dh_min_bits,
&dhparam.p, &dhparam.g, &dhparam.q, moduli,
&client_params->dh_group_name);
if (ret) {
@@ -315,8 +370,8 @@ get_dh_param(krb5_context context,
dh = DH_new();
if (dh == NULL) {
- krb5_set_error_string(context, "Cannot create DH structure");
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "Cannot create DH structure");
goto out;
}
ret = KRB5_BADMSGTYPE;
@@ -339,22 +394,24 @@ get_dh_param(krb5_context context,
&glue,
&size);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return ret;
}
- client_params->dh_public_key = integer_to_BN(context,
- "subjectPublicKey",
- &glue);
+ client_params->u.dh.public_key = integer_to_BN(context,
+ "subjectPublicKey",
+ &glue);
der_free_heim_integer(&glue);
- if (client_params->dh_public_key == NULL)
+ if (client_params->u.dh.public_key == NULL) {
+ ret = KRB5_BADMSGTYPE;
goto out;
+ }
}
- client_params->dh = dh;
+ client_params->u.dh.key = dh;
dh = NULL;
ret = 0;
-
+
out:
if (dh)
DH_free(dh);
@@ -362,60 +419,182 @@ get_dh_param(krb5_context context,
return ret;
}
+#ifdef HAVE_OPENSSL
+
+static krb5_error_code
+get_ecdh_param(krb5_context context,
+ krb5_kdc_configuration *config,
+ SubjectPublicKeyInfo *dh_key_info,
+ pk_client_params *client_params)
+{
+ ECParameters ecp;
+ EC_KEY *public = NULL;
+ krb5_error_code ret;
+ const unsigned char *p;
+ size_t len;
+ int nid;
+
+ if (dh_key_info->algorithm.parameters == NULL) {
+ krb5_set_error_message(context, KRB5_BADMSGTYPE,
+ "PKINIT missing algorithm parameter "
+ "in clientPublicValue");
+ return KRB5_BADMSGTYPE;
+ }
+
+ memset(&ecp, 0, sizeof(ecp));
+
+ ret = decode_ECParameters(dh_key_info->algorithm.parameters->data,
+ dh_key_info->algorithm.parameters->length, &ecp, &len);
+ if (ret)
+ goto out;
+
+ if (ecp.element != choice_ECParameters_namedCurve) {
+ ret = KRB5_BADMSGTYPE;
+ goto out;
+ }
+
+ if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0)
+ nid = NID_X9_62_prime256v1;
+ else {
+ ret = KRB5_BADMSGTYPE;
+ goto out;
+ }
+
+ /* XXX verify group is ok */
+
+ public = EC_KEY_new_by_curve_name(nid);
+
+ p = dh_key_info->subjectPublicKey.data;
+ len = dh_key_info->subjectPublicKey.length / 8;
+ if (o2i_ECPublicKey(&public, &p, len) == NULL) {
+ ret = KRB5_BADMSGTYPE;
+ krb5_set_error_message(context, ret,
+ "PKINIT failed to decode ECDH key");
+ goto out;
+ }
+ client_params->u.ecdh.public_key = public;
+ public = NULL;
+
+ out:
+ if (public)
+ EC_KEY_free(public);
+ free_ECParameters(&ecp);
+ return ret;
+}
+
+#endif /* HAVE_OPENSSL */
+
krb5_error_code
_kdc_pk_rd_padata(krb5_context context,
krb5_kdc_configuration *config,
const KDC_REQ *req,
const PA_DATA *pa,
+ hdb_entry_ex *client,
pk_client_params **ret_params)
{
- pk_client_params *client_params;
+ pk_client_params *cp;
krb5_error_code ret;
heim_oid eContentType = { 0, NULL }, contentInfoOid = { 0, NULL };
krb5_data eContent = { 0, NULL };
krb5_data signed_content = { 0, NULL };
const char *type = "unknown type";
+ hx509_certs trust_anchors;
int have_data = 0;
+ const HDB_Ext_PKINIT_cert *pc;
*ret_params = NULL;
-
+
if (!config->enable_pkinit) {
kdc_log(context, config, 0, "PK-INIT request but PK-INIT not enabled");
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return 0;
}
- hx509_verify_set_time(kdc_identity->verify_ctx, _kdc_now.tv_sec);
-
- client_params = calloc(1, sizeof(*client_params));
- if (client_params == NULL) {
- krb5_clear_error_string(context);
+ cp = calloc(1, sizeof(*cp));
+ if (cp == NULL) {
+ krb5_clear_error_message(context);
ret = ENOMEM;
goto out;
}
+ ret = hx509_certs_init(context->hx509ctx,
+ "MEMORY:trust-anchors",
+ 0, NULL, &trust_anchors);
+ if (ret) {
+ krb5_set_error_message(context, ret, "failed to create trust anchors");
+ goto out;
+ }
+
+ ret = hx509_certs_merge(context->hx509ctx, trust_anchors,
+ kdc_identity->anchors);
+ if (ret) {
+ hx509_certs_free(&trust_anchors);
+ krb5_set_error_message(context, ret, "failed to create verify context");
+ goto out;
+ }
+
+ /* Add any registered certificates for this client as trust anchors */
+ ret = hdb_entry_get_pkinit_cert(&client->entry, &pc);
+ if (ret == 0 && pc != NULL) {
+ hx509_cert cert;
+ unsigned int i;
+
+ for (i = 0; i < pc->len; i++) {
+ ret = hx509_cert_init_data(context->hx509ctx,
+ pc->val[i].cert.data,
+ pc->val[i].cert.length,
+ &cert);
+ if (ret)
+ continue;
+ hx509_certs_add(context->hx509ctx, trust_anchors, cert);
+ hx509_cert_free(cert);
+ }
+ }
+
+ ret = hx509_verify_init_ctx(context->hx509ctx, &cp->verify_ctx);
+ if (ret) {
+ hx509_certs_free(&trust_anchors);
+ krb5_set_error_message(context, ret, "failed to create verify context");
+ goto out;
+ }
+
+ hx509_verify_set_time(cp->verify_ctx, kdc_time);
+ hx509_verify_attach_anchors(cp->verify_ctx, trust_anchors);
+ hx509_certs_free(&trust_anchors);
+
+ if (config->pkinit_allow_proxy_certs)
+ hx509_verify_set_proxy_certificate(cp->verify_ctx, 1);
+
if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {
PA_PK_AS_REQ_Win2k r;
type = "PK-INIT-Win2k";
+ if (req->req_body.kdc_options.request_anonymous) {
+ ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
+ krb5_set_error_message(context, ret,
+ "Anon not supported in RSA mode");
+ goto out;
+ }
+
ret = decode_PA_PK_AS_REQ_Win2k(pa->padata_value.data,
pa->padata_value.length,
&r,
NULL);
if (ret) {
- krb5_set_error_string(context, "Can't decode "
- "PK-AS-REQ-Win2k: %d", ret);
+ krb5_set_error_message(context, ret, "Can't decode "
+ "PK-AS-REQ-Win2k: %d", ret);
goto out;
}
-
+
ret = hx509_cms_unwrap_ContentInfo(&r.signed_auth_pack,
&contentInfoOid,
&signed_content,
&have_data);
free_PA_PK_AS_REQ_Win2k(&r);
if (ret) {
- krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret);
+ krb5_set_error_message(context, ret,
+ "Can't unwrap ContentInfo(win): %d", ret);
goto out;
}
@@ -429,25 +608,35 @@ _kdc_pk_rd_padata(krb5_context context,
&r,
NULL);
if (ret) {
- krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret);
+ krb5_set_error_message(context, ret,
+ "Can't decode PK-AS-REQ: %d", ret);
goto out;
}
-
+
/* XXX look at r.kdcPkId */
if (r.trustedCertifiers) {
ExternalPrincipalIdentifiers *edi = r.trustedCertifiers;
- unsigned int i;
+ unsigned int i, maxedi;
- ret = hx509_certs_init(kdc_identity->hx509ctx,
+ ret = hx509_certs_init(context->hx509ctx,
"MEMORY:client-anchors",
0, NULL,
- &client_params->client_anchors);
+ &cp->client_anchors);
if (ret) {
- krb5_set_error_string(context, "Can't allocate client anchors: %d", ret);
+ krb5_set_error_message(context, ret,
+ "Can't allocate client anchors: %d",
+ ret);
goto out;
}
- for (i = 0; i < edi->len; i++) {
+ /*
+ * If the client sent more then 10 EDI, don't bother
+ * looking more then 10 of performance reasons.
+ */
+ maxedi = edi->len;
+ if (maxedi > 10)
+ maxedi = 10;
+ for (i = 0; i < maxedi; i++) {
IssuerAndSerialNumber iasn;
hx509_query *q;
hx509_cert cert;
@@ -456,35 +645,37 @@ _kdc_pk_rd_padata(krb5_context context,
if (edi->val[i].issuerAndSerialNumber == NULL)
continue;
- ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+ ret = hx509_query_alloc(context->hx509ctx, &q);
if (ret) {
- krb5_set_error_string(context,
+ krb5_set_error_message(context, ret,
"Failed to allocate hx509_query");
goto out;
}
-
+
ret = decode_IssuerAndSerialNumber(edi->val[i].issuerAndSerialNumber->data,
edi->val[i].issuerAndSerialNumber->length,
&iasn,
&size);
if (ret) {
- hx509_query_free(kdc_identity->hx509ctx, q);
+ hx509_query_free(context->hx509ctx, q);
continue;
}
ret = hx509_query_match_issuer_serial(q, &iasn.issuer, &iasn.serialNumber);
free_IssuerAndSerialNumber(&iasn);
- if (ret)
+ if (ret) {
+ hx509_query_free(context->hx509ctx, q);
continue;
+ }
- ret = hx509_certs_find(kdc_identity->hx509ctx,
+ ret = hx509_certs_find(context->hx509ctx,
kdc_identity->certs,
q,
&cert);
- hx509_query_free(kdc_identity->hx509ctx, q);
+ hx509_query_free(context->hx509ctx, q);
if (ret)
continue;
- hx509_certs_add(kdc_identity->hx509ctx,
- client_params->client_anchors, cert);
+ hx509_certs_add(context->hx509ctx,
+ cp->client_anchors, cert);
hx509_cert_free(cert);
}
}
@@ -495,36 +686,42 @@ _kdc_pk_rd_padata(krb5_context context,
&have_data);
free_PA_PK_AS_REQ(&r);
if (ret) {
- krb5_set_error_string(context, "Can't unwrap ContentInfo: %d", ret);
+ krb5_set_error_message(context, ret,
+ "Can't unwrap ContentInfo: %d", ret);
goto out;
}
- } else {
- krb5_clear_error_string(context);
+ } else {
+ krb5_clear_error_message(context);
ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
goto out;
}
- ret = der_heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData());
+ ret = der_heim_oid_cmp(&contentInfoOid, &asn1_oid_id_pkcs7_signedData);
if (ret != 0) {
- krb5_set_error_string(context, "PK-AS-REQ-Win2k invalid content "
- "type oid");
ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "PK-AS-REQ-Win2k invalid content type oid");
goto out;
}
-
+
if (!have_data) {
- krb5_set_error_string(context,
- "PK-AS-REQ-Win2k no signed auth pack");
ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "PK-AS-REQ-Win2k no signed auth pack");
goto out;
}
{
hx509_certs signer_certs;
+ int flags = HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH; /* BTMM */
+
+ if (req->req_body.kdc_options.request_anonymous)
+ flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER;
- ret = hx509_cms_verify_signed(kdc_identity->hx509ctx,
- kdc_identity->verify_ctx,
+ ret = hx509_cms_verify_signed(context->hx509ctx,
+ cp->verify_ctx,
+ flags,
signed_content.data,
signed_content.length,
NULL,
@@ -533,26 +730,28 @@ _kdc_pk_rd_padata(krb5_context context,
&eContent,
&signer_certs);
if (ret) {
- char *s = hx509_get_error_string(kdc_identity->hx509ctx, ret);
+ char *s = hx509_get_error_string(context->hx509ctx, ret);
krb5_warnx(context, "PKINIT: failed to verify signature: %s: %d",
s, ret);
free(s);
goto out;
}
- ret = hx509_get_one_cert(kdc_identity->hx509ctx, signer_certs,
- &client_params->cert);
- hx509_certs_free(&signer_certs);
+ if (signer_certs) {
+ ret = hx509_get_one_cert(context->hx509ctx, signer_certs,
+ &cp->cert);
+ hx509_certs_free(&signer_certs);
+ }
if (ret)
goto out;
}
/* Signature is correct, now verify the signed message */
- if (der_heim_oid_cmp(&eContentType, oid_id_pkcs7_data()) != 0 &&
- der_heim_oid_cmp(&eContentType, oid_id_pkauthdata()) != 0)
+ if (der_heim_oid_cmp(&eContentType, &asn1_oid_id_pkcs7_data) != 0 &&
+ der_heim_oid_cmp(&eContentType, &asn1_oid_id_pkauthdata) != 0)
{
- krb5_set_error_string(context, "got wrong oid for pkauthdata");
ret = KRB5_BADMSGTYPE;
+ krb5_set_error_message(context, ret, "got wrong oid for pkauthdata");
goto out;
}
@@ -564,11 +763,12 @@ _kdc_pk_rd_padata(krb5_context context,
&ap,
NULL);
if (ret) {
- krb5_set_error_string(context, "can't decode AuthPack: %d", ret);
+ krb5_set_error_message(context, ret,
+ "Can't decode AuthPack: %d", ret);
goto out;
}
-
- ret = pk_check_pkauthenticator_win2k(context,
+
+ ret = pk_check_pkauthenticator_win2k(context,
&ap.pkAuthenticator,
req);
if (ret) {
@@ -576,12 +776,13 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- client_params->type = PKINIT_COMPAT_WIN2K;
- client_params->nonce = ap.pkAuthenticator.nonce;
+ cp->type = PKINIT_WIN2K;
+ cp->nonce = ap.pkAuthenticator.nonce;
if (ap.clientPublicValue) {
- krb5_set_error_string(context, "DH not supported for windows");
ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "DH not supported for windows");
goto out;
}
free_AuthPack_Win2k(&ap);
@@ -594,12 +795,22 @@ _kdc_pk_rd_padata(krb5_context context,
&ap,
NULL);
if (ret) {
- krb5_set_error_string(context, "can't decode AuthPack: %d", ret);
+ krb5_set_error_message(context, ret,
+ "Can't decode AuthPack: %d", ret);
+ free_AuthPack(&ap);
+ goto out;
+ }
+
+ if (req->req_body.kdc_options.request_anonymous &&
+ ap.clientPublicValue == NULL) {
free_AuthPack(&ap);
+ ret = KRB5_KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED;
+ krb5_set_error_message(context, ret,
+ "Anon not supported in RSA mode");
goto out;
}
-
- ret = pk_check_pkauthenticator(context,
+
+ ret = pk_check_pkauthenticator(context,
&ap.pkAuthenticator,
req);
if (ret) {
@@ -607,33 +818,55 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- client_params->type = PKINIT_COMPAT_27;
- client_params->nonce = ap.pkAuthenticator.nonce;
+ cp->type = PKINIT_27;
+ cp->nonce = ap.pkAuthenticator.nonce;
if (ap.clientPublicValue) {
- ret = get_dh_param(context, config,
- ap.clientPublicValue, client_params);
+ if (der_heim_oid_cmp(&ap.clientPublicValue->algorithm.algorithm, &asn1_oid_id_dhpublicnumber) == 0) {
+ cp->keyex = USE_DH;
+ ret = get_dh_param(context, config,
+ ap.clientPublicValue, cp);
+#ifdef HAVE_OPENSSL
+ } else if (der_heim_oid_cmp(&ap.clientPublicValue->algorithm.algorithm, &asn1_oid_id_ecPublicKey) == 0) {
+ cp->keyex = USE_ECDH;
+ ret = get_ecdh_param(context, config,
+ ap.clientPublicValue, cp);
+#endif /* HAVE_OPENSSL */
+ } else {
+ ret = KRB5_BADMSGTYPE;
+ krb5_set_error_message(context, ret, "PKINIT unknown DH mechanism");
+ }
if (ret) {
free_AuthPack(&ap);
goto out;
}
+ } else
+ cp->keyex = USE_RSA;
+
+ ret = hx509_peer_info_alloc(context->hx509ctx,
+ &cp->peer);
+ if (ret) {
+ free_AuthPack(&ap);
+ goto out;
}
if (ap.supportedCMSTypes) {
- ret = hx509_peer_info_alloc(kdc_identity->hx509ctx,
- &client_params->peer);
- if (ret) {
- free_AuthPack(&ap);
- goto out;
- }
- ret = hx509_peer_info_set_cms_algs(kdc_identity->hx509ctx,
- client_params->peer,
+ ret = hx509_peer_info_set_cms_algs(context->hx509ctx,
+ cp->peer,
ap.supportedCMSTypes->val,
ap.supportedCMSTypes->len);
if (ret) {
free_AuthPack(&ap);
goto out;
}
+ } else {
+ /* assume old client */
+ hx509_peer_info_add_cms_alg(context->hx509ctx, cp->peer,
+ hx509_crypto_des_rsdi_ede3_cbc());
+ hx509_peer_info_add_cms_alg(context->hx509ctx, cp->peer,
+ hx509_signature_rsa_with_sha1());
+ hx509_peer_info_add_cms_alg(context->hx509ctx, cp->peer,
+ hx509_signature_sha1());
}
free_AuthPack(&ap);
} else
@@ -650,10 +883,10 @@ out:
krb5_data_free(&eContent);
der_free_oid(&eContentType);
der_free_oid(&contentInfoOid);
- if (ret)
- _kdc_pk_free_client_param(context, client_params);
- else
- *ret_params = client_params;
+ if (ret) {
+ _kdc_pk_free_client_param(context, cp);
+ } else
+ *ret_params = cp;
return ret;
}
@@ -667,7 +900,7 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
integer->length = BN_num_bytes(bn);
integer->data = malloc(integer->length);
if (integer->data == NULL) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return ENOMEM;
}
BN_bn2bin(bn, integer->data);
@@ -678,58 +911,63 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
static krb5_error_code
pk_mk_pa_reply_enckey(krb5_context context,
krb5_kdc_configuration *config,
- pk_client_params *client_params,
+ pk_client_params *cp,
const KDC_REQ *req,
const krb5_data *req_buffer,
krb5_keyblock *reply_key,
- ContentInfo *content_info)
+ ContentInfo *content_info,
+ hx509_cert *kdc_cert)
{
- const heim_oid *envelopedAlg = NULL, *sdAlg = NULL;
+ const heim_oid *envelopedAlg = NULL, *sdAlg = NULL, *evAlg = NULL;
krb5_error_code ret;
krb5_data buf, signed_data;
- size_t size;
+ size_t size = 0;
int do_win2k = 0;
krb5_data_zero(&buf);
krb5_data_zero(&signed_data);
+ *kdc_cert = NULL;
+
/*
* If the message client is a win2k-type but it send pa data
* 09-binding it expects a IETF (checksum) reply so there can be
* no replay attacks.
*/
- switch (client_params->type) {
- case PKINIT_COMPAT_WIN2K: {
+ switch (cp->type) {
+ case PKINIT_WIN2K: {
int i = 0;
if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL
&& config->pkinit_require_binding == 0)
{
do_win2k = 1;
}
+ sdAlg = &asn1_oid_id_pkcs7_data;
+ evAlg = &asn1_oid_id_pkcs7_data;
+ envelopedAlg = &asn1_oid_id_rsadsi_des_ede3_cbc;
break;
}
- case PKINIT_COMPAT_27:
+ case PKINIT_27:
+ sdAlg = &asn1_oid_id_pkrkeydata;
+ evAlg = &asn1_oid_id_pkcs7_signedData;
break;
default:
krb5_abortx(context, "internal pkinit error");
- }
+ }
if (do_win2k) {
ReplyKeyPack_Win2k kp;
memset(&kp, 0, sizeof(kp));
- envelopedAlg = oid_id_rsadsi_des_ede3_cbc();
- sdAlg = oid_id_pkcs7_data();
-
ret = copy_EncryptionKey(reply_key, &kp.replyKey);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
- kp.nonce = client_params->nonce;
-
- ASN1_MALLOC_ENCODE(ReplyKeyPack_Win2k,
+ kp.nonce = cp->nonce;
+
+ ASN1_MALLOC_ENCODE(ReplyKeyPack_Win2k,
buf.data, buf.length,
&kp, &size,ret);
free_ReplyKeyPack_Win2k(&kp);
@@ -738,17 +976,15 @@ pk_mk_pa_reply_enckey(krb5_context context,
ReplyKeyPack kp;
memset(&kp, 0, sizeof(kp));
- sdAlg = oid_id_pkrkeydata();
-
ret = copy_EncryptionKey(reply_key, &kp.replyKey);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
ret = krb5_crypto_init(context, reply_key, 0, &ascrypto);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
@@ -756,21 +992,21 @@ pk_mk_pa_reply_enckey(krb5_context context,
req_buffer->data, req_buffer->length,
&kp.asChecksum);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
-
+
ret = krb5_crypto_destroy(context, ascrypto);
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
goto out;
}
ASN1_MALLOC_ENCODE(ReplyKeyPack, buf.data, buf.length, &kp, &size,ret);
free_ReplyKeyPack(&kp);
}
if (ret) {
- krb5_set_error_string(context, "ASN.1 encoding of ReplyKeyPack "
- "failed (%d)", ret);
+ krb5_set_error_message(context, ret, "ASN.1 encoding of ReplyKeyPack "
+ "failed (%d)", ret);
goto out;
}
if (buf.length != size)
@@ -779,42 +1015,43 @@ pk_mk_pa_reply_enckey(krb5_context context,
{
hx509_query *q;
hx509_cert cert;
-
- ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+
+ ret = hx509_query_alloc(context->hx509ctx, &q);
if (ret)
goto out;
-
+
hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
- hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
-
- ret = hx509_certs_find(kdc_identity->hx509ctx,
- kdc_identity->certs,
- q,
+ if (config->pkinit_kdc_friendly_name)
+ hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
+
+ ret = hx509_certs_find(context->hx509ctx,
+ kdc_identity->certs,
+ q,
&cert);
- hx509_query_free(kdc_identity->hx509ctx, q);
+ hx509_query_free(context->hx509ctx, q);
if (ret)
goto out;
-
- ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
+
+ ret = hx509_cms_create_signed_1(context->hx509ctx,
0,
sdAlg,
buf.data,
buf.length,
NULL,
cert,
- client_params->peer,
- client_params->client_anchors,
+ cp->peer,
+ cp->client_anchors,
kdc_identity->certpool,
&signed_data);
- hx509_cert_free(cert);
+ *kdc_cert = cert;
}
krb5_data_free(&buf);
- if (ret)
+ if (ret)
goto out;
- if (client_params->type == PKINIT_COMPAT_WIN2K) {
- ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(),
+ if (cp->type == PKINIT_WIN2K) {
+ ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_signedData,
&signed_data,
&buf);
if (ret)
@@ -823,20 +1060,25 @@ pk_mk_pa_reply_enckey(krb5_context context,
signed_data = buf;
}
- ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,
- 0,
- client_params->cert,
- signed_data.data, signed_data.length,
+ ret = hx509_cms_envelope_1(context->hx509ctx,
+ HX509_CMS_EV_NO_KU_CHECK,
+ cp->cert,
+ signed_data.data, signed_data.length,
envelopedAlg,
- oid_id_pkcs7_signedData(), &buf);
+ evAlg, &buf);
if (ret)
goto out;
-
+
ret = _krb5_pk_mk_ContentInfo(context,
&buf,
- oid_id_pkcs7_envelopedData(),
+ &asn1_oid_id_pkcs7_envelopedData,
content_info);
out:
+ if (ret && *kdc_cert) {
+ hx509_cert_free(*kdc_cert);
+ *kdc_cert = NULL;
+ }
+
krb5_data_free(&buf);
krb5_data_free(&signed_data);
return ret;
@@ -848,9 +1090,8 @@ out:
static krb5_error_code
pk_mk_pa_reply_dh(krb5_context context,
- DH *kdc_dh,
- pk_client_params *client_params,
- krb5_keyblock *reply_key,
+ krb5_kdc_configuration *config,
+ pk_client_params *cp,
ContentInfo *content_info,
hx509_cert *kdc_cert)
{
@@ -858,88 +1099,115 @@ pk_mk_pa_reply_dh(krb5_context context,
krb5_data signed_data, buf;
ContentInfo contentinfo;
krb5_error_code ret;
- size_t size;
- heim_integer i;
+ hx509_cert cert;
+ hx509_query *q;
+ size_t size = 0;
memset(&contentinfo, 0, sizeof(contentinfo));
memset(&dh_info, 0, sizeof(dh_info));
- krb5_data_zero(&buf);
krb5_data_zero(&signed_data);
+ krb5_data_zero(&buf);
*kdc_cert = NULL;
- ret = BN_to_integer(context, kdc_dh->pub_key, &i);
- if (ret)
- return ret;
+ if (cp->keyex == USE_DH) {
+ DH *kdc_dh = cp->u.dh.key;
+ heim_integer i;
+
+ ret = BN_to_integer(context, kdc_dh->pub_key, &i);
+ if (ret)
+ return ret;
+
+ ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);
+ der_free_heim_integer(&i);
+ if (ret) {
+ krb5_set_error_message(context, ret, "ASN.1 encoding of "
+ "DHPublicKey failed (%d)", ret);
+ return ret;
+ }
+ if (buf.length != size)
+ krb5_abortx(context, "Internal ASN.1 encoder error");
+
+ dh_info.subjectPublicKey.length = buf.length * 8;
+ dh_info.subjectPublicKey.data = buf.data;
+ krb5_data_zero(&buf);
+#ifdef HAVE_OPENSSL
+ } else if (cp->keyex == USE_ECDH) {
+ unsigned char *p;
+ int len;
+
+ len = i2o_ECPublicKey(cp->u.ecdh.key, NULL);
+ if (len <= 0)
+ abort();
+
+ p = malloc(len);
+ if (p == NULL)
+ abort();
+
+ dh_info.subjectPublicKey.length = len * 8;
+ dh_info.subjectPublicKey.data = p;
+
+ len = i2o_ECPublicKey(cp->u.ecdh.key, &p);
+ if (len <= 0)
+ abort();
+#endif
+ } else
+ krb5_abortx(context, "no keyex selected ?");
- ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);
- if (ret) {
- krb5_set_error_string(context, "ASN.1 encoding of "
- "DHPublicKey failed (%d)", ret);
- krb5_clear_error_string(context);
- return ret;
- }
- if (buf.length != size)
- krb5_abortx(context, "Internal ASN.1 encoder error");
- dh_info.subjectPublicKey.length = buf.length * 8;
- dh_info.subjectPublicKey.data = buf.data;
-
- dh_info.nonce = client_params->nonce;
+ dh_info.nonce = cp->nonce;
- ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size,
+ ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size,
ret);
if (ret) {
- krb5_set_error_string(context, "ASN.1 encoding of "
- "KdcDHKeyInfo failed (%d)", ret);
+ krb5_set_error_message(context, ret, "ASN.1 encoding of "
+ "KdcDHKeyInfo failed (%d)", ret);
goto out;
}
if (buf.length != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
- /*
+ /*
* Create the SignedData structure and sign the KdcDHKeyInfo
* filled in above
*/
- {
- hx509_query *q;
- hx509_cert cert;
-
- ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
- if (ret)
- goto out;
-
- hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
- hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
-
- ret = hx509_certs_find(kdc_identity->hx509ctx,
- kdc_identity->certs,
- q,
- &cert);
- hx509_query_free(kdc_identity->hx509ctx, q);
- if (ret)
- goto out;
-
- ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
- 0,
- oid_id_pkdhkeydata(),
- buf.data,
- buf.length,
- NULL,
- cert,
- client_params->peer,
- client_params->client_anchors,
- kdc_identity->certpool,
- &signed_data);
- *kdc_cert = cert;
- }
+ ret = hx509_query_alloc(context->hx509ctx, &q);
if (ret)
goto out;
+ hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+ if (config->pkinit_kdc_friendly_name)
+ hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
+
+ ret = hx509_certs_find(context->hx509ctx,
+ kdc_identity->certs,
+ q,
+ &cert);
+ hx509_query_free(context->hx509ctx, q);
+ if (ret)
+ goto out;
+
+ ret = hx509_cms_create_signed_1(context->hx509ctx,
+ 0,
+ &asn1_oid_id_pkdhkeydata,
+ buf.data,
+ buf.length,
+ NULL,
+ cert,
+ cp->peer,
+ cp->client_anchors,
+ kdc_identity->certpool,
+ &signed_data);
+ if (ret) {
+ kdc_log(context, config, 0, "Failed signing the DH* reply: %d", ret);
+ goto out;
+ }
+ *kdc_cert = cert;
+
ret = _krb5_pk_mk_ContentInfo(context,
&signed_data,
- oid_id_pkcs7_signedData(),
+ &asn1_oid_id_pkcs7_signedData,
content_info);
if (ret)
goto out;
@@ -964,23 +1232,25 @@ pk_mk_pa_reply_dh(krb5_context context,
krb5_error_code
_kdc_pk_mk_pa_reply(krb5_context context,
krb5_kdc_configuration *config,
- pk_client_params *client_params,
+ pk_client_params *cp,
const hdb_entry_ex *client,
+ krb5_enctype sessionetype,
const KDC_REQ *req,
const krb5_data *req_buffer,
krb5_keyblock **reply_key,
+ krb5_keyblock *sessionkey,
METHOD_DATA *md)
{
krb5_error_code ret;
- void *buf;
- size_t len, size;
+ void *buf = NULL;
+ size_t len = 0, size = 0;
krb5_enctype enctype;
int pa_type;
hx509_cert kdc_cert = NULL;
- int i;
+ size_t i;
if (!config->enable_pkinit) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return 0;
}
@@ -990,15 +1260,15 @@ _kdc_pk_mk_pa_reply(krb5_context context,
break;
if (req->req_body.etype.len <= i) {
ret = KRB5KRB_ERR_GENERIC;
- krb5_set_error_string(context,
- "No valid enctype available from client");
+ krb5_set_error_message(context, ret,
+ "No valid enctype available from client");
goto out;
- }
+ }
enctype = req->req_body.etype.val[i];
} else
enctype = ETYPE_DES3_CBC_SHA1;
- if (client_params->type == PKINIT_COMPAT_27) {
+ if (cp->type == PKINIT_27) {
PA_PK_AS_REP rep;
const char *type, *other = "";
@@ -1006,87 +1276,129 @@ _kdc_pk_mk_pa_reply(krb5_context context,
pa_type = KRB5_PADATA_PK_AS_REP;
- if (client_params->dh == NULL) {
+ if (cp->keyex == USE_RSA) {
ContentInfo info;
type = "enckey";
rep.element = choice_PA_PK_AS_REP_encKeyPack;
- ret = krb5_generate_random_keyblock(context, enctype,
- &client_params->reply_key);
+ ret = krb5_generate_random_keyblock(context, enctype,
+ &cp->reply_key);
if (ret) {
free_PA_PK_AS_REP(&rep);
goto out;
}
ret = pk_mk_pa_reply_enckey(context,
config,
- client_params,
+ cp,
req,
req_buffer,
- &client_params->reply_key,
- &info);
+ &cp->reply_key,
+ &info,
+ &kdc_cert);
if (ret) {
free_PA_PK_AS_REP(&rep);
goto out;
}
- ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data,
- rep.u.encKeyPack.length, &info, &size,
+ ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data,
+ rep.u.encKeyPack.length, &info, &size,
ret);
free_ContentInfo(&info);
if (ret) {
- krb5_set_error_string(context, "encoding of Key ContentInfo "
- "failed %d", ret);
+ krb5_set_error_message(context, ret, "encoding of Key ContentInfo "
+ "failed %d", ret);
free_PA_PK_AS_REP(&rep);
goto out;
}
if (rep.u.encKeyPack.length != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
+ ret = krb5_generate_random_keyblock(context, sessionetype,
+ sessionkey);
+ if (ret) {
+ free_PA_PK_AS_REP(&rep);
+ goto out;
+ }
+
} else {
ContentInfo info;
- type = "dh";
- if (client_params->dh_group_name)
- other = client_params->dh_group_name;
+ switch (cp->keyex) {
+ case USE_DH: type = "dh"; break;
+#ifdef HAVE_OPENSSL
+ case USE_ECDH: type = "ecdh"; break;
+#endif
+ default: krb5_abortx(context, "unknown keyex"); break;
+ }
+
+ if (cp->dh_group_name)
+ other = cp->dh_group_name;
rep.element = choice_PA_PK_AS_REP_dhInfo;
- ret = generate_dh_keyblock(context, client_params, enctype,
- &client_params->reply_key);
+ ret = generate_dh_keyblock(context, cp, enctype);
if (ret)
return ret;
- ret = pk_mk_pa_reply_dh(context, client_params->dh,
- client_params,
- &client_params->reply_key,
+ ret = pk_mk_pa_reply_dh(context, config,
+ cp,
&info,
&kdc_cert);
+ if (ret) {
+ free_PA_PK_AS_REP(&rep);
+ krb5_set_error_message(context, ret,
+ "create pa-reply-dh "
+ "failed %d", ret);
+ goto out;
+ }
ASN1_MALLOC_ENCODE(ContentInfo, rep.u.dhInfo.dhSignedData.data,
rep.u.dhInfo.dhSignedData.length, &info, &size,
ret);
free_ContentInfo(&info);
if (ret) {
- krb5_set_error_string(context, "encoding of Key ContentInfo "
- "failed %d", ret);
+ krb5_set_error_message(context, ret,
+ "encoding of Key ContentInfo "
+ "failed %d", ret);
free_PA_PK_AS_REP(&rep);
goto out;
}
if (rep.u.encKeyPack.length != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
+ /* XXX KRB-FX-CF2 */
+ ret = krb5_generate_random_keyblock(context, sessionetype,
+ sessionkey);
+ if (ret) {
+ free_PA_PK_AS_REP(&rep);
+ goto out;
+ }
+
+ /* XXX Add PA-PKINIT-KX */
+
}
- if (ret) {
- free_PA_PK_AS_REP(&rep);
- goto out;
+
+#define use_btmm_with_enckey 0
+ if (use_btmm_with_enckey && rep.element == choice_PA_PK_AS_REP_encKeyPack) {
+ PA_PK_AS_REP_BTMM btmm;
+ heim_any any;
+
+ any.data = rep.u.encKeyPack.data;
+ any.length = rep.u.encKeyPack.length;
+
+ btmm.dhSignedData = NULL;
+ btmm.encKeyPack = &any;
+
+ ASN1_MALLOC_ENCODE(PA_PK_AS_REP_BTMM, buf, len, &btmm, &size, ret);
+ } else {
+ ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret);
}
- ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret);
free_PA_PK_AS_REP(&rep);
if (ret) {
- krb5_set_error_string(context, "encode PA-PK-AS-REP failed %d",
- ret);
+ krb5_set_error_message(context, ret,
+ "encode PA-PK-AS-REP failed %d", ret);
goto out;
}
if (len != size)
@@ -1094,44 +1406,46 @@ _kdc_pk_mk_pa_reply(krb5_context context,
kdc_log(context, config, 0, "PK-INIT using %s %s", type, other);
- } else if (client_params->type == PKINIT_COMPAT_WIN2K) {
+ } else if (cp->type == PKINIT_WIN2K) {
PA_PK_AS_REP_Win2k rep;
ContentInfo info;
- if (client_params->dh) {
- krb5_set_error_string(context, "Windows PK-INIT doesn't support DH");
+ if (cp->keyex != USE_RSA) {
ret = KRB5KRB_ERR_GENERIC;
+ krb5_set_error_message(context, ret,
+ "Windows PK-INIT doesn't support DH");
goto out;
}
memset(&rep, 0, sizeof(rep));
pa_type = KRB5_PADATA_PK_AS_REP_19;
- rep.element = choice_PA_PK_AS_REP_encKeyPack;
+ rep.element = choice_PA_PK_AS_REP_Win2k_encKeyPack;
- ret = krb5_generate_random_keyblock(context, enctype,
- &client_params->reply_key);
+ ret = krb5_generate_random_keyblock(context, enctype,
+ &cp->reply_key);
if (ret) {
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
}
ret = pk_mk_pa_reply_enckey(context,
config,
- client_params,
+ cp,
req,
req_buffer,
- &client_params->reply_key,
- &info);
+ &cp->reply_key,
+ &info,
+ &kdc_cert);
if (ret) {
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
}
- ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data,
- rep.u.encKeyPack.length, &info, &size,
+ ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data,
+ rep.u.encKeyPack.length, &info, &size,
ret);
free_ContentInfo(&info);
if (ret) {
- krb5_set_error_string(context, "encoding of Key ContentInfo "
+ krb5_set_error_message(context, ret, "encoding of Key ContentInfo "
"failed %d", ret);
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
@@ -1142,20 +1456,28 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ASN1_MALLOC_ENCODE(PA_PK_AS_REP_Win2k, buf, len, &rep, &size, ret);
free_PA_PK_AS_REP_Win2k(&rep);
if (ret) {
- krb5_set_error_string(context,
+ krb5_set_error_message(context, ret,
"encode PA-PK-AS-REP-Win2k failed %d", ret);
goto out;
}
if (len != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
+ ret = krb5_generate_random_keyblock(context, sessionetype,
+ sessionkey);
+ if (ret) {
+ free(buf);
+ goto out;
+ }
+
} else
krb5_abortx(context, "PK-INIT internal error");
ret = krb5_padata_add(context, md, pa_type, buf, len);
if (ret) {
- krb5_set_error_string(context, "failed adding PA-PK-AS-REP %d", ret);
+ krb5_set_error_message(context, ret,
+ "Failed adding PA-PK-AS-REP %d", ret);
free(buf);
goto out;
}
@@ -1173,7 +1495,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
fd = open(config->pkinit_kdc_ocsp_file, O_RDONLY);
if (fd < 0) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"PK-INIT failed to open ocsp data file %d", errno);
goto out_ocsp;
}
@@ -1181,15 +1503,15 @@ _kdc_pk_mk_pa_reply(krb5_context context,
if (ret) {
ret = errno;
close(fd);
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"PK-INIT failed to stat ocsp data %d", ret);
goto out_ocsp;
}
-
+
ret = krb5_data_alloc(&ocsp.data, sb.st_size);
if (ret) {
close(fd);
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"PK-INIT failed to stat ocsp data %d", ret);
goto out_ocsp;
}
@@ -1197,19 +1519,19 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ret = read(fd, ocsp.data.data, sb.st_size);
close(fd);
if (ret != sb.st_size) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"PK-INIT failed to read ocsp data %d", errno);
goto out_ocsp;
}
- ret = hx509_ocsp_verify(kdc_identity->hx509ctx,
+ ret = hx509_ocsp_verify(context->hx509ctx,
kdc_time,
kdc_cert,
0,
ocsp.data.data, ocsp.data.length,
&ocsp.expire);
if (ret) {
- kdc_log(context, config, 0,
+ kdc_log(context, config, 0,
"PK-INIT failed to verify ocsp data %d", ret);
krb5_data_free(&ocsp.data);
ocsp.expire = 0;
@@ -1225,12 +1547,12 @@ _kdc_pk_mk_pa_reply(krb5_context context,
if (ocsp.expire != 0 && ocsp.expire > kdc_time) {
- ret = krb5_padata_add(context, md,
+ ret = krb5_padata_add(context, md,
KRB5_PADATA_PA_PK_OCSP_RESPONSE,
ocsp.data.data, ocsp.data.length);
if (ret) {
- krb5_set_error_string(context,
- "Failed adding OCSP response %d", ret);
+ krb5_set_error_message(context, ret,
+ "Failed adding OCSP response %d", ret);
goto out;
}
}
@@ -1241,25 +1563,26 @@ out:
hx509_cert_free(kdc_cert);
if (ret == 0)
- *reply_key = &client_params->reply_key;
+ *reply_key = &cp->reply_key;
return ret;
}
static int
-match_rfc_san(krb5_context context,
+match_rfc_san(krb5_context context,
krb5_kdc_configuration *config,
hx509_context hx509ctx,
- hx509_cert client_cert,
+ hx509_cert client_cert,
krb5_const_principal match)
{
hx509_octet_string_list list;
- int ret, i, found = 0;
+ int ret, found = 0;
+ size_t i;
memset(&list, 0 , sizeof(list));
ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
client_cert,
- oid_id_pkinit_san(),
+ &asn1_oid_id_pkinit_san,
&list);
if (ret)
goto out;
@@ -1269,13 +1592,14 @@ match_rfc_san(krb5_context context,
KRB5PrincipalName kn;
size_t size;
- ret = decode_KRB5PrincipalName(list.val[i].data,
+ ret = decode_KRB5PrincipalName(list.val[i].data,
list.val[i].length,
&kn, &size);
if (ret) {
+ const char *msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 0,
- "Decoding kerberos name in certificate failed: %s",
- krb5_get_err_text(context, ret));
+ "Decoding kerberos name in certificate failed: %s", msg);
+ krb5_free_error_message(context, msg);
break;
}
if (size != list.val[i].length) {
@@ -1293,7 +1617,7 @@ match_rfc_san(krb5_context context,
}
out:
- hx509_free_octet_string_list(&list);
+ hx509_free_octet_string_list(&list);
if (ret)
return ret;
@@ -1304,15 +1628,16 @@ out:
}
static int
-match_ms_upn_san(krb5_context context,
+match_ms_upn_san(krb5_context context,
krb5_kdc_configuration *config,
hx509_context hx509ctx,
- hx509_cert client_cert,
- krb5_const_principal match)
+ hx509_cert client_cert,
+ HDB *clientdb,
+ hdb_entry_ex *client)
{
hx509_octet_string_list list;
krb5_principal principal = NULL;
- int ret, found = 0;
+ int ret;
MS_UPN_SAN upn;
size_t size;
@@ -1320,7 +1645,7 @@ match_ms_upn_san(krb5_context context,
ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
client_cert,
- oid_id_pkinit_ms_san(),
+ &asn1_oid_id_pkinit_ms_san,
&list);
if (ret)
goto out;
@@ -1336,6 +1661,12 @@ match_ms_upn_san(krb5_context context,
kdc_log(context, config, 0, "Decode of MS-UPN-SAN failed");
goto out;
}
+ if (size != list.val[0].length) {
+ free_MS_UPN_SAN(&upn);
+ kdc_log(context, config, 0, "Trailing data in ");
+ ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+ goto out;
+ }
kdc_log(context, config, 0, "found MS UPN SAN: %s", upn);
@@ -1346,42 +1677,51 @@ match_ms_upn_san(krb5_context context,
goto out;
}
- /*
- * This is very wrong, but will do for now, should really and a
- * plugin to the windc layer to very this ACL.
- */
- strupr(principal->realm);
+ if (clientdb->hdb_check_pkinit_ms_upn_match) {
+ ret = clientdb->hdb_check_pkinit_ms_upn_match(context, clientdb, client, principal);
+ } else {
+
+ /*
+ * This is very wrong, but will do for a fallback
+ */
+ strupr(principal->realm);
- if (krb5_principal_compare(context, principal, match) == TRUE)
- found = 1;
+ if (krb5_principal_compare(context, principal, client->entry.principal) == FALSE)
+ ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+ }
out:
if (principal)
krb5_free_principal(context, principal);
- hx509_free_octet_string_list(&list);
- if (ret)
- return ret;
+ hx509_free_octet_string_list(&list);
- if (!found)
- return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
-
- return 0;
+ return ret;
}
krb5_error_code
_kdc_pk_check_client(krb5_context context,
krb5_kdc_configuration *config,
- const hdb_entry_ex *client,
- pk_client_params *client_params,
+ HDB *clientdb,
+ hdb_entry_ex *client,
+ pk_client_params *cp,
char **subject_name)
{
const HDB_Ext_PKINIT_acl *acl;
+ const HDB_Ext_PKINIT_cert *pc;
krb5_error_code ret;
hx509_name name;
- int i;
+ size_t i;
+
+ if (cp->cert == NULL) {
- ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
- client_params->cert,
+ *subject_name = strdup("anonymous client client");
+ if (*subject_name == NULL)
+ return ENOMEM;
+ return 0;
+ }
+
+ ret = hx509_cert_get_base_subject(context->hx509ctx,
+ cp->cert,
&name);
if (ret)
return ret;
@@ -1392,13 +1732,36 @@ _kdc_pk_check_client(krb5_context context,
return ret;
kdc_log(context, config, 0,
- "Trying to authorize PK-INIT subject DN %s",
+ "Trying to authorize PK-INIT subject DN %s",
*subject_name);
+ ret = hdb_entry_get_pkinit_cert(&client->entry, &pc);
+ if (ret == 0 && pc) {
+ hx509_cert cert;
+ size_t j;
+
+ for (j = 0; j < pc->len; j++) {
+ ret = hx509_cert_init_data(context->hx509ctx,
+ pc->val[j].cert.data,
+ pc->val[j].cert.length,
+ &cert);
+ if (ret)
+ continue;
+ ret = hx509_cert_cmp(cert, cp->cert);
+ hx509_cert_free(cert);
+ if (ret == 0) {
+ kdc_log(context, config, 5,
+ "Found matching PK-INIT cert in hdb");
+ return 0;
+ }
+ }
+ }
+
+
if (config->pkinit_princ_in_cert) {
ret = match_rfc_san(context, config,
- kdc_identity->hx509ctx,
- client_params->cert,
+ context->hx509ctx,
+ cp->cert,
client->entry.principal);
if (ret == 0) {
kdc_log(context, config, 5,
@@ -1406,9 +1769,10 @@ _kdc_pk_check_client(krb5_context context,
return 0;
}
ret = match_ms_upn_san(context, config,
- kdc_identity->hx509ctx,
- client_params->cert,
- client->entry.principal);
+ context->hx509ctx,
+ cp->cert,
+ clientdb,
+ client);
if (ret == 0) {
kdc_log(context, config, 5,
"Found matching MS UPN SAN in certificate");
@@ -1453,7 +1817,8 @@ _kdc_pk_check_client(krb5_context context,
return 0;
}
- krb5_set_error_string(context,
+ ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+ krb5_set_error_message(context, ret,
"PKINIT no matching principals for %s",
*subject_name);
@@ -1464,11 +1829,11 @@ _kdc_pk_check_client(krb5_context context,
free(*subject_name);
*subject_name = NULL;
- return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+ return ret;
}
static krb5_error_code
-add_principal_mapping(krb5_context context,
+add_principal_mapping(krb5_context context,
const char *principal_name,
const char * subject)
{
@@ -1501,16 +1866,16 @@ add_principal_mapping(krb5_context context,
krb5_error_code
_kdc_add_inital_verified_cas(krb5_context context,
krb5_kdc_configuration *config,
- pk_client_params *params,
+ pk_client_params *cp,
EncTicketPart *tkt)
{
AD_INITIAL_VERIFIED_CAS cas;
krb5_error_code ret;
krb5_data data;
- size_t size;
+ size_t size = 0;
memset(&cas, 0, sizeof(cas));
-
+
/* XXX add CAs to cas here */
ASN1_MALLOC_ENCODE(AD_INITIAL_VERIFIED_CAS, data.data, data.length,
@@ -1520,7 +1885,7 @@ _kdc_add_inital_verified_cas(krb5_context context,
if (data.length != size)
krb5_abortx(context, "internal asn.1 encoder error");
- ret = _kdc_tkt_add_if_relevant_ad(context, tkt,
+ ret = _kdc_tkt_add_if_relevant_ad(context, tkt,
KRB5_AUTHDATA_INITIAL_VERIFIED_CAS,
&data);
krb5_data_free(&data);
@@ -1545,7 +1910,7 @@ load_mappings(krb5_context context, const char *fn)
while (fgets(buf, sizeof(buf), f) != NULL) {
char *subject_name, *p;
-
+
buf[strcspn(buf, "\n")] = '\0';
lineno++;
@@ -1569,22 +1934,22 @@ load_mappings(krb5_context context, const char *fn)
lineno, buf);
continue;
}
- }
+ }
fclose(f);
}
-
+
/*
*
*/
krb5_error_code
-_kdc_pk_initialize(krb5_context context,
- krb5_kdc_configuration *config,
- const char *user_id,
- const char *anchors,
- char **pool,
- char **revoke_list)
+krb5_kdc_pk_initialize(krb5_context context,
+ krb5_kdc_configuration *config,
+ const char *user_id,
+ const char *anchors,
+ char **pool,
+ char **revoke_list)
{
const char *file;
char *fn = NULL;
@@ -1618,42 +1983,52 @@ _kdc_pk_initialize(krb5_context context,
{
hx509_query *q;
hx509_cert cert;
-
- ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+
+ ret = hx509_query_alloc(context->hx509ctx, &q);
if (ret) {
krb5_warnx(context, "PKINIT: out of memory");
return ENOMEM;
}
-
+
hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
- hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
-
- ret = hx509_certs_find(kdc_identity->hx509ctx,
+ if (config->pkinit_kdc_friendly_name)
+ hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name);
+
+ ret = hx509_certs_find(context->hx509ctx,
kdc_identity->certs,
q,
&cert);
- hx509_query_free(kdc_identity->hx509ctx, q);
+ hx509_query_free(context->hx509ctx, q);
if (ret == 0) {
- if (hx509_cert_check_eku(kdc_identity->hx509ctx, cert,
- oid_id_pkkdcekuoid(), 0))
- krb5_warnx(context, "WARNING Found KDC certificate "
- "is missing the PK-INIT KDC EKU, this is bad for "
- "interoperability.");
+ if (hx509_cert_check_eku(context->hx509ctx, cert,
+ &asn1_oid_id_pkkdcekuoid, 0)) {
+ hx509_name name;
+ char *str;
+ ret = hx509_cert_get_subject(cert, &name);
+ if (ret == 0) {
+ hx509_name_to_string(name, &str);
+ krb5_warnx(context, "WARNING Found KDC certificate (%s)"
+ "is missing the PK-INIT KDC EKU, this is bad for "
+ "interoperability.", str);
+ hx509_name_free(&name);
+ free(str);
+ }
+ }
hx509_cert_free(cert);
} else
krb5_warnx(context, "PKINIT: failed to find a signing "
"certifiate with a public key");
}
- ret = krb5_config_get_bool_default(context,
- NULL,
- FALSE,
- "kdc",
- "pkinit_allow_proxy_certificate",
- NULL);
- _krb5_pk_allow_proxy_certificate(kdc_identity, ret);
+ if (krb5_config_get_bool_default(context,
+ NULL,
+ FALSE,
+ "kdc",
+ "pkinit_allow_proxy_certificate",
+ NULL))
+ config->pkinit_allow_proxy_certs = 1;
- file = krb5_config_get_string(context,
+ file = krb5_config_get_string(context,
NULL,
"kdc",
"pkinit_mappings_file",
diff --git a/crypto/heimdal/kdc/process.c b/crypto/heimdal/kdc/process.c
index 1d0a01a..6f36915 100644
--- a/crypto/heimdal/kdc/process.c
+++ b/crypto/heimdal/kdc/process.c
@@ -1,41 +1,39 @@
/*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
*
- * All rights reserved.
+ * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: process.c 20959 2007-06-07 04:46:06Z lha $");
-
/*
*
*/
@@ -49,66 +47,167 @@ krb5_kdc_update_time(struct timeval *tv)
_kdc_now = *tv;
}
+static krb5_error_code
+kdc_as_req(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_data *req_buffer,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *addr,
+ int datagram_reply,
+ int *claim)
+{
+ krb5_error_code ret;
+ KDC_REQ req;
+ size_t len;
+
+ ret = decode_AS_REQ(req_buffer->data, req_buffer->length, &req, &len);
+ if (ret)
+ return ret;
+
+ *claim = 1;
+
+ ret = _kdc_as_rep(context, config, &req, req_buffer,
+ reply, from, addr, datagram_reply);
+ free_AS_REQ(&req);
+ return ret;
+}
+
+
+static krb5_error_code
+kdc_tgs_req(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_data *req_buffer,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *addr,
+ int datagram_reply,
+ int *claim)
+{
+ krb5_error_code ret;
+ KDC_REQ req;
+ size_t len;
+
+ ret = decode_TGS_REQ(req_buffer->data, req_buffer->length, &req, &len);
+ if (ret)
+ return ret;
+
+ *claim = 1;
+
+ ret = _kdc_tgs_rep(context, config, &req, reply,
+ from, addr, datagram_reply);
+ free_TGS_REQ(&req);
+ return ret;
+}
+
+#ifdef DIGEST
+
+static krb5_error_code
+kdc_digest(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_data *req_buffer,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *addr,
+ int datagram_reply,
+ int *claim)
+{
+ DigestREQ digestreq;
+ krb5_error_code ret;
+ size_t len;
+
+ ret = decode_DigestREQ(req_buffer->data, req_buffer->length,
+ &digestreq, &len);
+ if (ret)
+ return ret;
+
+ *claim = 1;
+
+ ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
+ free_DigestREQ(&digestreq);
+ return ret;
+}
+
+#endif
+
+#ifdef KX509
+
+static krb5_error_code
+kdc_kx509(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_data *req_buffer,
+ krb5_data *reply,
+ const char *from,
+ struct sockaddr *addr,
+ int datagram_reply,
+ int *claim)
+{
+ Kx509Request kx509req;
+ krb5_error_code ret;
+ size_t len;
+
+ ret = _kdc_try_kx509_request(req_buffer->data, req_buffer->length,
+ &kx509req, &len);
+ if (ret)
+ return ret;
+
+ *claim = 1;
+
+ ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
+ free_Kx509Request(&kx509req);
+ return ret;
+}
+
+#endif
+
+
+static struct krb5_kdc_service services[] = {
+ { KS_KRB5, kdc_as_req },
+ { KS_KRB5, kdc_tgs_req },
+#ifdef DIGEST
+ { 0, kdc_digest },
+#endif
+#ifdef KX509
+ { 0, kdc_kx509 },
+#endif
+ { 0, NULL }
+};
+
/*
* handle the request in `buf, len', from `addr' (or `from' as a string),
* sending a reply in `reply'.
*/
int
-krb5_kdc_process_request(krb5_context context,
+krb5_kdc_process_request(krb5_context context,
krb5_kdc_configuration *config,
- unsigned char *buf,
- size_t len,
+ unsigned char *buf,
+ size_t len,
krb5_data *reply,
krb5_boolean *prependlength,
const char *from,
struct sockaddr *addr,
int datagram_reply)
{
- KDC_REQ req;
- Ticket ticket;
- DigestREQ digestreq;
- Kx509Request kx509req;
krb5_error_code ret;
- size_t i;
-
- if(decode_AS_REQ(buf, len, &req, &i) == 0){
- krb5_data req_buffer;
+ unsigned int i;
+ krb5_data req_buffer;
+ int claim = 0;
- req_buffer.data = buf;
- req_buffer.length = len;
+ req_buffer.data = buf;
+ req_buffer.length = len;
- ret = _kdc_as_rep(context, config, &req, &req_buffer,
- reply, from, addr, datagram_reply);
- free_AS_REQ(&req);
- return ret;
- }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
- ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply);
- free_TGS_REQ(&req);
- return ret;
- }else if(decode_Ticket(buf, len, &ticket, &i) == 0){
- ret = _kdc_do_524(context, config, &ticket, reply, from, addr);
- free_Ticket(&ticket);
- return ret;
- }else if(decode_DigestREQ(buf, len, &digestreq, &i) == 0){
- ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
- free_DigestREQ(&digestreq);
- return ret;
- } else if (_kdc_try_kx509_request(buf, len, &kx509req, &i) == 0) {
- ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
- free_Kx509Request(&kx509req);
- return ret;
- } else if(_kdc_maybe_version4(buf, len)){
- *prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */
- _kdc_do_version4(context, config, buf, len, reply, from,
- (struct sockaddr_in*)addr);
- return 0;
- } else if (config->enable_kaserver) {
- ret = _kdc_do_kaserver(context, config, buf, len, reply, from,
- (struct sockaddr_in*)addr);
- return ret;
+ for (i = 0; services[i].process != NULL; i++) {
+ ret = (*services[i].process)(context, config, &req_buffer,
+ reply, from, addr, datagram_reply,
+ &claim);
+ if (claim) {
+ if (services[i].flags & KS_NO_LENGTH)
+ *prependlength = 0;
+ return ret;
+ }
}
-
+
return -1;
}
@@ -120,34 +219,33 @@ krb5_kdc_process_request(krb5_context context,
*/
int
-krb5_kdc_process_krb5_request(krb5_context context,
+krb5_kdc_process_krb5_request(krb5_context context,
krb5_kdc_configuration *config,
- unsigned char *buf,
- size_t len,
+ unsigned char *buf,
+ size_t len,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply)
{
- KDC_REQ req;
krb5_error_code ret;
- size_t i;
-
- if(decode_AS_REQ(buf, len, &req, &i) == 0){
- krb5_data req_buffer;
+ unsigned int i;
+ krb5_data req_buffer;
+ int claim = 0;
- req_buffer.data = buf;
- req_buffer.length = len;
+ req_buffer.data = buf;
+ req_buffer.length = len;
- ret = _kdc_as_rep(context, config, &req, &req_buffer,
- reply, from, addr, datagram_reply);
- free_AS_REQ(&req);
- return ret;
- }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
- ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply);
- free_TGS_REQ(&req);
- return ret;
+ for (i = 0; services[i].process != NULL; i++) {
+ if ((services[i].flags & KS_KRB5) == 0)
+ continue;
+ ret = (*services[i].process)(context, config, &req_buffer,
+ reply, from, addr, datagram_reply,
+ &claim);
+ if (claim)
+ return ret;
}
+
return -1;
}
@@ -156,7 +254,7 @@ krb5_kdc_process_krb5_request(krb5_context context,
*/
int
-krb5_kdc_save_request(krb5_context context,
+krb5_kdc_save_request(krb5_context context,
const char *fn,
const unsigned char *buf,
size_t len,
@@ -177,14 +275,15 @@ krb5_kdc_save_request(krb5_context context,
fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600);
if (fd < 0) {
- krb5_set_error_string(context, "Failed to open: %s", fn);
- return errno;
+ int saved_errno = errno;
+ krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn);
+ return saved_errno;
}
-
+
sp = krb5_storage_from_fd(fd);
close(fd);
if (sp == NULL) {
- krb5_set_error_string(context, "Storage failed to open fd");
+ krb5_set_error_message(context, ENOMEM, "Storage failed to open fd");
return ENOMEM;
}
diff --git a/crypto/heimdal/kdc/rx.h b/crypto/heimdal/kdc/rx.h
index 18806d7..f914e93 100644
--- a/crypto/heimdal/kdc/rx.h
+++ b/crypto/heimdal/kdc/rx.h
@@ -1,37 +1,37 @@
/*
- * Copyright (c) 1997 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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: rx.h 17447 2006-05-05 10:52:01Z lha $ */
+/* $Id$ */
#ifndef __RX_H__
#define __RX_H__
diff --git a/crypto/heimdal/kdc/set_dbinfo.c b/crypto/heimdal/kdc/set_dbinfo.c
index 651f4c4..d22e083 100644
--- a/crypto/heimdal/kdc/set_dbinfo.c
+++ b/crypto/heimdal/kdc/set_dbinfo.c
@@ -1,40 +1,68 @@
/*
- * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
*
- * All rights reserved.
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: default_config.c 21296 2007-06-25 14:49:11Z lha $");
+static krb5_error_code
+add_db(krb5_context context, struct krb5_kdc_configuration *c,
+ const char *conf, const char *master_key)
+{
+ krb5_error_code ret;
+ void *ptr;
+
+ ptr = realloc(c->db, (c->num_db + 1) * sizeof(*c->db));
+ if (ptr == NULL) {
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+ return ENOMEM;
+ }
+ c->db = ptr;
+
+ ret = hdb_create(context, &c->db[c->num_db], conf);
+ if(ret)
+ return ret;
+
+ c->num_db++;
+
+ if (master_key) {
+ ret = hdb_set_master_keyfile(context, c->db[c->num_db - 1], master_key);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
krb5_error_code
krb5_kdc_set_dbinfo(krb5_context context, struct krb5_kdc_configuration *c)
@@ -47,30 +75,15 @@ krb5_kdc_set_dbinfo(krb5_context context, struct krb5_kdc_configuration *c)
ret = hdb_get_dbinfo(context, &info);
if (ret)
return ret;
-
+
d = NULL;
while ((d = hdb_dbinfo_get_next(info, d)) != NULL) {
- void *ptr;
-
- ptr = realloc(c->db, (c->num_db + 1) * sizeof(*c->db));
- if (ptr == NULL) {
- ret = ENOMEM;
- krb5_set_error_string(context, "out of memory");
- goto out;
- }
- c->db = ptr;
-
- ret = hdb_create(context, &c->db[c->num_db],
- hdb_dbinfo_get_dbname(context, d));
- if(ret)
- goto out;
-
- ret = hdb_set_master_keyfile(context, c->db[c->num_db],
- hdb_dbinfo_get_mkey_file(context, d));
+
+ ret = add_db(context, c,
+ hdb_dbinfo_get_dbname(context, d),
+ hdb_dbinfo_get_mkey_file(context, d));
if (ret)
goto out;
-
- c->num_db++;
kdc_log(context, c, 0, "label: %s",
hdb_dbinfo_get_label(context, d));
@@ -91,7 +104,7 @@ out:
c->num_db = 0;
free(c->db);
c->db = NULL;
-
+
hdb_free_dbinfo(context, &info);
return ret;
diff --git a/crypto/heimdal/kdc/string2key.8 b/crypto/heimdal/kdc/string2key.8
index 8f2d562..1b38d33 100644
--- a/crypto/heimdal/kdc/string2key.8
+++ b/crypto/heimdal/kdc/string2key.8
@@ -1,35 +1,35 @@
-.\" Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan
-.\" (Royal Institute of Technology, Stockholm, Sweden).
-.\" All rights reserved.
+.\" Copyright (c) 2000 - 2002 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:
+.\" 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.
+.\" 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.
+.\" 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.
+.\" 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: string2key.8 11648 2003-02-16 21:10:32Z lha $
+.\" 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$
.\"
.Dd March 4, 2000
.Dt STRING2KEY 8
@@ -39,23 +39,23 @@
.Nd map a password into a key
.Sh SYNOPSIS
.Nm
-.Op Fl 5 | Fl -version5
-.Op Fl 4 | Fl -version4
-.Op Fl a | Fl -afs
+.Op Fl 5 | Fl Fl version5
+.Op Fl 4 | Fl Fl version4
+.Op Fl a | Fl Fl afs
.Oo Fl c Ar cell \*(Ba Xo
-.Fl -cell= Ns Ar cell
+.Fl Fl cell= Ns Ar cell
.Xc
.Oc
.Oo Fl w Ar password \*(Ba Xo
-.Fl -password= Ns Ar password
+.Fl Fl password= Ns Ar password
.Xc
.Oc
.Oo Fl p Ar principal \*(Ba Xo
-.Fl -principal= Ns Ar principal
+.Fl Fl principal= Ns Ar principal
.Xc
.Oc
.Oo Fl k Ar string \*(Ba Xo
-.Fl -keytype= Ns Ar string
+.Fl Fl keytype= Ns Ar string
.Xc
.Oc
.Ar password
@@ -65,46 +65,21 @@ performs the string-to-key function.
This is useful when you want to handle the raw key instead of the password.
Supported options:
.Bl -tag -width Ds
-.It Xo
-.Fl 5 ,
-.Fl -version5
-.Xc
+.It Fl 5 , Fl Fl version5
Output Kerberos v5 string-to-key
-.It Xo
-.Fl 4 ,
-.Fl -version4
-.Xc
+.It Fl 4 , Fl Fl version4
Output Kerberos v4 string-to-key
-.It Xo
-.Fl a ,
-.Fl -afs
-.Xc
+.It Fl a , Fl Fl afs
Output AFS string-to-key
-.It Xo
-.Fl c Ar cell ,
-.Fl -cell= Ns Ar cell
-.Xc
+.It Fl c Ar cell , Fl Fl cell= Ns Ar cell
AFS cell to use
-.It Xo
-.Fl w Ar password ,
-.Fl -password= Ns Ar password
-.Xc
+.It Fl w Ar password , Fl Fl password= Ns Ar password
Password to use
-.It Xo
-.Fl p Ar principal ,
-.Fl -principal= Ns Ar principal
-.Xc
+.It Fl p Ar principal , Fl Fl principal= Ns Ar principal
Kerberos v5 principal to use
-.It Xo
-.Fl k Ar string ,
-.Fl -keytype= Ns Ar string
-.Xc
+.It Fl k Ar string , Fl Fl keytype= Ns Ar string
Keytype
-.It Xo
-.Fl -version
-.Xc
+.It Fl Fl version
print version
-.It Xo
-.Fl -help
-.Xc
+.It Fl Fl help
.El
diff --git a/crypto/heimdal/kdc/string2key.c b/crypto/heimdal/kdc/string2key.c
index 4211bf7..6f24c27 100644
--- a/crypto/heimdal/kdc/string2key.c
+++ b/crypto/heimdal/kdc/string2key.c
@@ -1,41 +1,39 @@
/*
- * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997-2003 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "headers.h"
#include <getarg.h>
-RCSID("$Id: string2key.c 19213 2006-12-04 23:36:36Z lha $");
-
int version5;
int version4;
int afs;
@@ -47,15 +45,17 @@ int version;
int help;
struct getargs args[] = {
- { "version5", '5', arg_flag, &version5, "Output Kerberos v5 string-to-key" },
- { "version4", '4', arg_flag, &version4, "Output Kerberos v4 string-to-key" },
- { "afs", 'a', arg_flag, &afs, "Output AFS string-to-key" },
+ { "version5", '5', arg_flag, &version5, "Output Kerberos v5 string-to-key",
+ NULL },
+ { "version4", '4', arg_flag, &version4, "Output Kerberos v4 string-to-key",
+ NULL },
+ { "afs", 'a', arg_flag, &afs, "Output AFS string-to-key", NULL },
{ "cell", 'c', arg_string, &cell, "AFS cell to use", "cell" },
{ "password", 'w', arg_string, &password, "Password to use", "password" },
{ "principal",'p', arg_string, &principal, "Kerberos v5 principal to use", "principal" },
- { "keytype", 'k', arg_string, &keytype_str, "Keytype" },
- { "version", 0, arg_flag, &version, "print version" },
- { "help", 0, arg_flag, &help, NULL }
+ { "keytype", 'k', arg_string, rk_UNCONST(&keytype_str), "Keytype", NULL },
+ { "version", 0, arg_flag, &version, "print version", NULL },
+ { "help", 0, arg_flag, &help, NULL, NULL }
};
int num_args = sizeof(args) / sizeof(args[0]);
@@ -68,14 +68,14 @@ usage(int status)
}
static void
-tokey(krb5_context context,
- krb5_enctype enctype,
- const char *pw,
- krb5_salt salt,
+tokey(krb5_context context,
+ krb5_enctype enctype,
+ const char *pw,
+ krb5_salt salt,
const char *label)
{
krb5_error_code ret;
- int i;
+ size_t i;
krb5_keyblock key;
char *e;
@@ -109,7 +109,7 @@ main(int argc, char **argv)
if(help)
usage(0);
-
+
if(version){
print_version (NULL);
return 0;
@@ -125,26 +125,9 @@ main(int argc, char **argv)
version5 = 1;
ret = krb5_string_to_enctype(context, keytype_str, &etype);
- if(ret) {
- krb5_keytype keytype;
- int *etypes;
- unsigned num;
- char *str;
- ret = krb5_string_to_keytype(context, keytype_str, &keytype);
- if(ret)
- krb5_err(context, 1, ret, "%s", keytype_str);
- ret = krb5_keytype_to_enctypes(context, keytype, &num, &etypes);
- if(ret)
- krb5_err(context, 1, ret, "%s", keytype_str);
- if(num == 0)
- krb5_errx(context, 1, "there are no encryption types for that keytype");
- etype = etypes[0];
- krb5_enctype_to_string(context, etype, &str);
- keytype_str = str;
- if(num > 1 && version5)
- krb5_warnx(context, "ambiguous keytype, using %s", keytype_str);
- }
-
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_string_to_enctype");
+
if((etype != ETYPE_DES_CBC_CRC &&
etype != ETYPE_DES_CBC_MD4 &&
etype != ETYPE_DES_CBC_MD5) &&
@@ -152,7 +135,7 @@ main(int argc, char **argv)
if(!version5) {
etype = ETYPE_DES_CBC_CRC;
} else {
- krb5_errx(context, 1,
+ krb5_errx(context, 1,
"DES is the only valid keytype for AFS and Kerberos 4");
}
}
@@ -178,7 +161,7 @@ main(int argc, char **argv)
return 1;
password = buf;
}
-
+
if(version5){
krb5_parse_name(context, principal, &princ);
krb5_get_pw_salt(context, princ, &salt);
diff --git a/crypto/heimdal/kdc/v4_dump.c b/crypto/heimdal/kdc/v4_dump.c
deleted file mode 100644
index 93c56f8..0000000
--- a/crypto/heimdal/kdc/v4_dump.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2000 - 2001, 2003 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 "hprop.h"
-
-RCSID("$Id: v4_dump.c 17023 2006-04-09 17:41:47Z lha $");
-
-static time_t
-time_parse(const char *cp)
-{
- char wbuf[5];
- struct tm tp;
- int local;
-
- memset(&tp, 0, sizeof(tp)); /* clear out the struct */
-
- /* new format is YYYYMMDDHHMM UTC,
- old format is YYMMDDHHMM local time */
- if (strlen(cp) > 10) { /* new format */
- strlcpy(wbuf, cp, sizeof(wbuf));
- tp.tm_year = atoi(wbuf) - 1900;
- cp += 4;
- local = 0;
- } else {
- wbuf[0] = *cp++;
- wbuf[1] = *cp++;
- wbuf[2] = '\0';
- tp.tm_year = atoi(wbuf);
- if(tp.tm_year < 38)
- tp.tm_year += 100;
- local = 1;
- }
-
- wbuf[0] = *cp++;
- wbuf[1] = *cp++;
- wbuf[2] = 0;
- tp.tm_mon = atoi(wbuf) - 1;
-
- wbuf[0] = *cp++;
- wbuf[1] = *cp++;
- tp.tm_mday = atoi(wbuf);
-
- wbuf[0] = *cp++;
- wbuf[1] = *cp++;
- tp.tm_hour = atoi(wbuf);
-
- wbuf[0] = *cp++;
- wbuf[1] = *cp++;
- tp.tm_min = atoi(wbuf);
-
- return(tm2time(tp, local));
-}
-
-/* convert a version 4 dump file */
-int
-v4_prop_dump(void *arg, const char *file)
-{
- char buf [1024];
- FILE *f;
- int lineno = 0;
-
- f = fopen(file, "r");
- if(f == NULL)
- return errno;
-
- while(fgets(buf, sizeof(buf), f)) {
- int ret;
- unsigned long key[2]; /* yes, long */
- char exp_date[64], mod_date[64];
- struct v4_principal pr;
- int attributes;
-
- memset(&pr, 0, sizeof(pr));
- errno = 0;
- lineno++;
- ret = sscanf(buf, "%63s %63s %d %d %d %d %lx %lx %63s %63s %63s %63s",
- pr.name, pr.instance,
- &pr.max_life, &pr.mkvno, &pr.kvno,
- &attributes,
- &key[0], &key[1],
- exp_date, mod_date,
- pr.mod_name, pr.mod_instance);
- if(ret != 12){
- warnx("Line %d malformed (ignored)", lineno);
- continue;
- }
- if(attributes != 0) {
- warnx("Line %d (%s.%s) has non-zero attributes - skipping",
- lineno, pr.name, pr.instance);
- continue;
- }
- pr.key[0] = (key[0] >> 24) & 0xff;
- pr.key[1] = (key[0] >> 16) & 0xff;
- pr.key[2] = (key[0] >> 8) & 0xff;
- pr.key[3] = (key[0] >> 0) & 0xff;
- pr.key[4] = (key[1] >> 24) & 0xff;
- pr.key[5] = (key[1] >> 16) & 0xff;
- pr.key[6] = (key[1] >> 8) & 0xff;
- pr.key[7] = (key[1] >> 0) & 0xff;
- pr.exp_date = time_parse(exp_date);
- pr.mod_date = time_parse(mod_date);
- if (pr.instance[0] == '*')
- pr.instance[0] = '\0';
- if (pr.mod_name[0] == '*')
- pr.mod_name[0] = '\0';
- if (pr.mod_instance[0] == '*')
- pr.mod_instance[0] = '\0';
- v4_prop(arg, &pr);
- memset(&pr, 0, sizeof(pr));
- }
- fclose(f);
- return 0;
-}
diff --git a/crypto/heimdal/kdc/version-script.map b/crypto/heimdal/kdc/version-script.map
index 2612b8e..ae16f39 100644
--- a/crypto/heimdal/kdc/version-script.map
+++ b/crypto/heimdal/kdc/version-script.map
@@ -1,4 +1,4 @@
-# $Id: version-script.map 21110 2007-06-18 10:52:20Z lha $
+# $Id$
HEIMDAL_KDC_1.0 {
global:
@@ -6,13 +6,20 @@ HEIMDAL_KDC_1.0 {
kdc_log_msg;
kdc_log_msg_va;
kdc_openlog;
+ kdc_check_flags;
krb5_kdc_windc_init;
krb5_kdc_get_config;
+ krb5_kdc_pkinit_config;
krb5_kdc_set_dbinfo;
krb5_kdc_process_krb5_request;
krb5_kdc_process_request;
krb5_kdc_save_request;
krb5_kdc_update_time;
+ krb5_kdc_pk_initialize;
+
+ # needed for digest-service
+ _kdc_db_fetch;
+ _kdc_free_ent;
local:
*;
};
diff --git a/crypto/heimdal/kdc/windc.c b/crypto/heimdal/kdc/windc.c
index 395ab73..ba87abb7 100644
--- a/crypto/heimdal/kdc/windc.c
+++ b/crypto/heimdal/kdc/windc.c
@@ -1,40 +1,38 @@
/*
- * Copyright (c) 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2007 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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 "kdc_locl.h"
-RCSID("$Id: windc.c 20559 2007-04-24 16:00:07Z lha $");
-
static krb5plugin_windc_ftable *windcft;
static void *windcctx;
@@ -55,15 +53,15 @@ krb5_kdc_windc_init(krb5_context context)
for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) {
windcft = _krb5_plugin_get_symbol(e);
- if (windcft->minor_version < KRB5_WINDC_PLUGING_MINOR)
+ if (windcft->minor_version < KRB5_WINDC_PLUGIN_MINOR)
continue;
-
+
(*windcft->init)(context, &windcctx);
break;
}
+ _krb5_plugin_free(list);
if (e == NULL) {
- _krb5_plugin_free(list);
- krb5_set_error_string(context, "Did not find any WINDC plugin");
+ krb5_set_error_message(context, ENOENT, "Did not find any WINDC plugin");
windcft = NULL;
return ENOENT;
}
@@ -72,9 +70,9 @@ krb5_kdc_windc_init(krb5_context context)
}
-krb5_error_code
+krb5_error_code
_kdc_pac_generate(krb5_context context,
- hdb_entry_ex *client,
+ hdb_entry_ex *client,
krb5_pac *pac)
{
*pac = NULL;
@@ -83,27 +81,47 @@ _kdc_pac_generate(krb5_context context,
return (windcft->pac_generate)(windcctx, context, client, pac);
}
-krb5_error_code
-_kdc_pac_verify(krb5_context context,
+krb5_error_code
+_kdc_pac_verify(krb5_context context,
const krb5_principal client_principal,
+ const krb5_principal delegated_proxy_principal,
hdb_entry_ex *client,
hdb_entry_ex *server,
- krb5_pac *pac)
+ hdb_entry_ex *krbtgt,
+ krb5_pac *pac,
+ int *verified)
{
- if (windcft == NULL) {
- krb5_set_error_string(context, "Can't verify PAC, no function");
- return EINVAL;
- }
- return (windcft->pac_verify)(windcctx, context,
- client_principal, client, server, pac);
+ krb5_error_code ret;
+
+ if (windcft == NULL)
+ return 0;
+
+ ret = windcft->pac_verify(windcctx, context,
+ client_principal,
+ delegated_proxy_principal,
+ client, server, krbtgt, pac);
+ if (ret == 0)
+ *verified = 1;
+ return ret;
}
krb5_error_code
-_kdc_windc_client_access(krb5_context context,
- struct hdb_entry_ex *client,
- KDC_REQ *req)
+_kdc_check_access(krb5_context context,
+ krb5_kdc_configuration *config,
+ hdb_entry_ex *client_ex, const char *client_name,
+ hdb_entry_ex *server_ex, const char *server_name,
+ KDC_REQ *req,
+ krb5_data *e_data)
{
if (windcft == NULL)
- return 0;
- return (windcft->client_access)(windcctx, context, client, req);
+ return kdc_check_flags(context, config,
+ client_ex, client_name,
+ server_ex, server_name,
+ req->msg_type == krb_as_req);
+
+ return (windcft->client_access)(windcctx,
+ context, config,
+ client_ex, client_name,
+ server_ex, server_name,
+ req, e_data);
}
diff --git a/crypto/heimdal/kdc/windc_plugin.h b/crypto/heimdal/kdc/windc_plugin.h
index ec480cf..fa4ba43 100644
--- a/crypto/heimdal/kdc/windc_plugin.h
+++ b/crypto/heimdal/kdc/windc_plugin.h
@@ -1,37 +1,37 @@
/*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2006 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:
+ * 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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: windc_plugin.h 19798 2007-01-10 15:24:51Z lha $ */
+/* $Id$ */
#ifndef HEIMDAL_KRB5_PAC_PLUGIN_H
#define HEIMDAL_KRB5_PAC_PLUGIN_H 1
@@ -51,23 +51,30 @@
struct hdb_entry_ex;
-typedef krb5_error_code
+typedef krb5_error_code
(*krb5plugin_windc_pac_generate)(void *, krb5_context,
struct hdb_entry_ex *, krb5_pac *);
-typedef krb5_error_code
+typedef krb5_error_code
(*krb5plugin_windc_pac_verify)(void *, krb5_context,
- const krb5_principal,
- struct hdb_entry_ex *,
- struct hdb_entry_ex *,
+ const krb5_principal, /* new ticket client */
+ const krb5_principal, /* delegation proxy */
+ struct hdb_entry_ex *,/* client */
+ struct hdb_entry_ex *,/* server */
+ struct hdb_entry_ex *,/* krbtgt */
krb5_pac *);
-typedef krb5_error_code
+typedef krb5_error_code
(*krb5plugin_windc_client_access)(
- void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *);
+ void *, krb5_context,
+ krb5_kdc_configuration *config,
+ hdb_entry_ex *, const char *,
+ hdb_entry_ex *, const char *,
+ KDC_REQ *, krb5_data *);
-#define KRB5_WINDC_PLUGING_MINOR 2
+#define KRB5_WINDC_PLUGIN_MINOR 6
+#define KRB5_WINDC_PLUGING_MINOR KRB5_WINDC_PLUGIN_MINOR
typedef struct krb5plugin_windc_ftable {
int minor_version;
OpenPOWER on IntegriCloud