import krb5-1.17-9.el8

This commit is contained in:
CentOS Sources 2019-11-05 15:19:57 -05:00 committed by Andrew Lukoshko
parent caf33d73fa
commit 8fbeb381dc
75 changed files with 1590 additions and 26721 deletions

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/krb5-1.16.1-pdfs.tar
SOURCES/krb5-1.16.1.tar.gz
SOURCES/krb5-1.17-pdfs.tar
SOURCES/krb5-1.17.tar.gz

View File

@ -1,2 +1,2 @@
494c62bea08e5d26e01d47c409ac745b65e509c8 SOURCES/krb5-1.16.1-pdfs.tar
8353f2d900a7d52499c7c2605d5e295f71dd5e67 SOURCES/krb5-1.16.1.tar.gz
494c62bea08e5d26e01d47c409ac745b65e509c8 SOURCES/krb5-1.17-pdfs.tar
0c404b081db9c996c581f636ce450ee28778f338 SOURCES/krb5-1.17.tar.gz

View File

@ -1,866 +0,0 @@
From dff5177801444307d19071fc4fac7de864fda92a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 13 Jun 2015 16:04:53 -0400
Subject: [PATCH] Add ASN.1 encoders and decoders for SPAKE types
Add a new internal header k5-spake.h. Add ASN.1 encoder and decoder
functions and an internal free function for SPAKE types. Add ASN.1
tests and asn1c test vectors the new types.
The additions to to make-vectors.c use C99 designated initializers in
order to initialize unions. This is okay since make-vectors.c is only
compiled as part of "make test-vectors" and not as part of the regular
build.
(cherry picked from commit 78a09d95dff6915da4079bc611f4bb95f6a95f70)
---
src/include/k5-spake.h | 107 +++++++++++++++++++++++++++
src/lib/krb5/asn.1/asn1_k_encode.c | 52 ++++++++++++-
src/lib/krb5/krb/kfree.c | 40 ++++++++++
src/lib/krb5/libkrb5.exports | 6 ++
src/tests/asn.1/Makefile.in | 2 +-
src/tests/asn.1/krb5_decode_test.c | 37 +++++++++
src/tests/asn.1/krb5_encode_test.c | 29 ++++++++
src/tests/asn.1/ktest.c | 97 ++++++++++++++++++++++++
src/tests/asn.1/ktest.h | 9 +++
src/tests/asn.1/ktest_equal.c | 49 ++++++++++++
src/tests/asn.1/ktest_equal.h | 6 ++
src/tests/asn.1/make-vectors.c | 56 ++++++++++++++
src/tests/asn.1/reference_encode.out | 6 ++
src/tests/asn.1/spake.asn1 | 44 +++++++++++
src/tests/asn.1/trval_reference.out | 50 +++++++++++++
15 files changed, 588 insertions(+), 2 deletions(-)
create mode 100644 src/include/k5-spake.h
create mode 100644 src/tests/asn.1/spake.asn1
diff --git a/src/include/k5-spake.h b/src/include/k5-spake.h
new file mode 100644
index 000000000..ddb5d810d
--- /dev/null
+++ b/src/include/k5-spake.h
@@ -0,0 +1,107 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-spake.h - SPAKE preauth mech declarations */
+/*
+ * Copyright (C) 2015 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+/*
+ * The SPAKE preauth mechanism allows long-term client keys to be used for
+ * preauthentication without exposing them to offline dictionary attacks. The
+ * negotiated key can also be used for second-factor authentication. This
+ * header file declares structures and encoder/decoder functions for the
+ * mechanism's padata messages.
+ */
+
+#ifndef K5_SPAKE_H
+#define K5_SPAKE_H
+
+#include "k5-int.h"
+
+/* SPAKESecondFactor is contained within a SPAKEChallenge, SPAKEResponse, or
+ * EncryptedData message and contains a second-factor challenge or response. */
+typedef struct krb5_spake_factor_st {
+ int32_t type;
+ krb5_data *data;
+} krb5_spake_factor;
+
+/* SPAKESupport is sent from the client to the KDC to indicate which group the
+ * client supports. */
+typedef struct krb5_spake_support_st {
+ int32_t ngroups;
+ int32_t *groups;
+} krb5_spake_support;
+
+/* SPAKEChallenge is sent from the KDC to the client to communicate its group
+ * selection, public value, and second-factor challenge options. */
+typedef struct krb5_spake_challenge_st {
+ int32_t group;
+ krb5_data pubkey;
+ krb5_spake_factor **factors;
+} krb5_spake_challenge;
+
+/* SPAKEResponse is sent from the client to the KDC to communicate its public
+ * value and encrypted second-factor response. */
+typedef struct krb5_spake_response_st {
+ krb5_data pubkey;
+ krb5_enc_data factor;
+} krb5_spake_response;
+
+enum krb5_spake_msgtype {
+ SPAKE_MSGTYPE_UNKNOWN = -1,
+ SPAKE_MSGTYPE_SUPPORT = 0,
+ SPAKE_MSGTYPE_CHALLENGE = 1,
+ SPAKE_MSGTYPE_RESPONSE = 2,
+ SPAKE_MSGTYPE_ENCDATA = 3
+};
+
+/* PA-SPAKE is a choice among the message types which can appear in a PA-SPAKE
+ * padata element. */
+typedef struct krb5_pa_spake_st {
+ enum krb5_spake_msgtype choice;
+ union krb5_spake_message_choices {
+ krb5_spake_support support;
+ krb5_spake_challenge challenge;
+ krb5_spake_response response;
+ krb5_enc_data encdata;
+ } u;
+} krb5_pa_spake;
+
+krb5_error_code encode_krb5_spake_factor(const krb5_spake_factor *val,
+ krb5_data **code_out);
+krb5_error_code decode_krb5_spake_factor(const krb5_data *code,
+ krb5_spake_factor **val_out);
+void k5_free_spake_factor(krb5_context context, krb5_spake_factor *val);
+
+krb5_error_code encode_krb5_pa_spake(const krb5_pa_spake *val,
+ krb5_data **code_out);
+krb5_error_code decode_krb5_pa_spake(const krb5_data *code,
+ krb5_pa_spake **val_out);
+void k5_free_pa_spake(krb5_context context, krb5_pa_spake *val);
+
+#endif /* K5_SPAKE_H */
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 3b23fe34a..29f6b903d 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -25,7 +25,7 @@
*/
#include "asn1_encode.h"
-#include <assert.h>
+#include "k5-spake.h"
DEFINT_IMMEDIATE(krb5_version, KVNO, KRB5KDC_ERR_BAD_PVNO);
@@ -1817,3 +1817,53 @@ static const struct atype_info *secure_cookie_fields[] = {
DEFSEQTYPE(secure_cookie, krb5_secure_cookie, secure_cookie_fields);
MAKE_ENCODER(encode_krb5_secure_cookie, secure_cookie);
MAKE_DECODER(decode_krb5_secure_cookie, secure_cookie);
+
+DEFFIELD(spake_factor_0, krb5_spake_factor, type, 0, int32);
+DEFFIELD(spake_factor_1, krb5_spake_factor, data, 1, opt_ostring_data_ptr);
+static const struct atype_info *spake_factor_fields[] = {
+ &k5_atype_spake_factor_0, &k5_atype_spake_factor_1
+};
+DEFSEQTYPE(spake_factor, krb5_spake_factor, spake_factor_fields);
+DEFPTRTYPE(spake_factor_ptr, spake_factor);
+DEFNULLTERMSEQOFTYPE(seqof_spake_factor, spake_factor_ptr);
+DEFPTRTYPE(ptr_seqof_spake_factor, seqof_spake_factor);
+MAKE_ENCODER(encode_krb5_spake_factor, spake_factor);
+MAKE_DECODER(decode_krb5_spake_factor, spake_factor);
+
+DEFCNFIELD(spake_support_0, krb5_spake_support, groups, ngroups, 0,
+ cseqof_int32);
+static const struct atype_info *spake_support_fields[] = {
+ &k5_atype_spake_support_0
+};
+DEFSEQTYPE(spake_support, krb5_spake_support, spake_support_fields);
+
+DEFFIELD(spake_challenge_0, krb5_spake_challenge, group, 0, int32);
+DEFFIELD(spake_challenge_1, krb5_spake_challenge, pubkey, 1, ostring_data);
+DEFFIELD(spake_challenge_2, krb5_spake_challenge, factors, 2,
+ ptr_seqof_spake_factor);
+static const struct atype_info *spake_challenge_fields[] = {
+ &k5_atype_spake_challenge_0, &k5_atype_spake_challenge_1,
+ &k5_atype_spake_challenge_2
+};
+DEFSEQTYPE(spake_challenge, krb5_spake_challenge, spake_challenge_fields);
+
+DEFFIELD(spake_response_0, krb5_spake_response, pubkey, 0, ostring_data);
+DEFFIELD(spake_response_1, krb5_spake_response, factor, 1, encrypted_data);
+static const struct atype_info *spake_response_fields[] = {
+ &k5_atype_spake_response_0, &k5_atype_spake_response_1,
+};
+DEFSEQTYPE(spake_response, krb5_spake_response, spake_response_fields);
+
+DEFCTAGGEDTYPE(pa_spake_0, 0, spake_support);
+DEFCTAGGEDTYPE(pa_spake_1, 1, spake_challenge);
+DEFCTAGGEDTYPE(pa_spake_2, 2, spake_response);
+DEFCTAGGEDTYPE(pa_spake_3, 3, encrypted_data);
+static const struct atype_info *pa_spake_alternatives[] = {
+ &k5_atype_pa_spake_0, &k5_atype_pa_spake_1, &k5_atype_pa_spake_2,
+ &k5_atype_pa_spake_3
+};
+DEFCHOICETYPE(pa_spake_choice, union krb5_spake_message_choices,
+ enum krb5_spake_msgtype, pa_spake_alternatives);
+DEFCOUNTEDTYPE_SIGNED(pa_spake, krb5_pa_spake, u, choice, pa_spake_choice);
+MAKE_ENCODER(encode_krb5_pa_spake, pa_spake);
+MAKE_DECODER(decode_krb5_pa_spake, pa_spake);
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index a631807d3..e1ea1494a 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -51,6 +51,7 @@
*/
#include "k5-int.h"
+#include "k5-spake.h"
#include <assert.h>
void KRB5_CALLCONV
@@ -890,3 +891,42 @@ k5_free_secure_cookie(krb5_context context, krb5_secure_cookie *val)
k5_zapfree_pa_data(val->data);
free(val);
}
+
+void
+k5_free_spake_factor(krb5_context context, krb5_spake_factor *val)
+{
+ if (val == NULL)
+ return;
+ krb5_free_data(context, val->data);
+ free(val);
+}
+
+void
+k5_free_pa_spake(krb5_context context, krb5_pa_spake *val)
+{
+ krb5_spake_factor **f;
+
+ if (val == NULL)
+ return;
+ switch (val->choice) {
+ case SPAKE_MSGTYPE_SUPPORT:
+ free(val->u.support.groups);
+ break;
+ case SPAKE_MSGTYPE_CHALLENGE:
+ krb5_free_data_contents(context, &val->u.challenge.pubkey);
+ for (f = val->u.challenge.factors; f != NULL && *f != NULL; f++)
+ k5_free_spake_factor(context, *f);
+ free(val->u.challenge.factors);
+ break;
+ case SPAKE_MSGTYPE_RESPONSE:
+ krb5_free_data_contents(context, &val->u.response.pubkey);
+ krb5_free_data_contents(context, &val->u.response.factor.ciphertext);
+ break;
+ case SPAKE_MSGTYPE_ENCDATA:
+ krb5_free_data_contents(context, &val->u.encdata.ciphertext);
+ break;
+ default:
+ break;
+ }
+ free(val);
+}
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index ed6cad6ad..622bc3673 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -36,6 +36,7 @@ decode_krb5_pa_otp_req
decode_krb5_pa_otp_enc_req
decode_krb5_pa_pac_req
decode_krb5_pa_s4u_x509_user
+decode_krb5_pa_spake
decode_krb5_padata_sequence
decode_krb5_priv
decode_krb5_safe
@@ -44,6 +45,7 @@ decode_krb5_sam_challenge_2_body
decode_krb5_sam_response_2
decode_krb5_secure_cookie
decode_krb5_setpw_req
+decode_krb5_spake_factor
decode_krb5_tgs_rep
decode_krb5_tgs_req
decode_krb5_ticket
@@ -85,6 +87,7 @@ encode_krb5_pa_otp_challenge
encode_krb5_pa_otp_req
encode_krb5_pa_otp_enc_req
encode_krb5_pa_s4u_x509_user
+encode_krb5_pa_spake
encode_krb5_padata_sequence
encode_krb5_pkinit_supp_pub_info
encode_krb5_priv
@@ -95,6 +98,7 @@ encode_krb5_sam_challenge_2_body
encode_krb5_sam_response_2
encode_krb5_secure_cookie
encode_krb5_sp80056a_other_info
+encode_krb5_spake_factor
encode_krb5_tgs_rep
encode_krb5_tgs_req
encode_krb5_ticket
@@ -128,7 +132,9 @@ k5_free_kkdcp_message
k5_free_pa_otp_challenge
k5_free_pa_otp_req
k5_free_secure_cookie
+k5_free_pa_spake
k5_free_serverlist
+k5_free_spake_factor
k5_hostrealm_free_context
k5_init_trace
k5_is_string_numeric
diff --git a/src/tests/asn.1/Makefile.in b/src/tests/asn.1/Makefile.in
index fec4e109e..ec9c67495 100644
--- a/src/tests/asn.1/Makefile.in
+++ b/src/tests/asn.1/Makefile.in
@@ -9,7 +9,7 @@ SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_decode_test.c \
ASN1SRCS= $(srcdir)/krb5.asn1 $(srcdir)/pkix.asn1 $(srcdir)/otp.asn1 \
$(srcdir)/pkinit.asn1 $(srcdir)/pkinit-agility.asn1 \
- $(srcdir)/cammac.asn1
+ $(srcdir)/cammac.asn1 $(srcdir)/spake.asn1
all: krb5_encode_test krb5_decode_test krb5_decode_leak t_trval
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
index f17f9b1f1..ee70fa4b9 100644
--- a/src/tests/asn.1/krb5_decode_test.c
+++ b/src/tests/asn.1/krb5_decode_test.c
@@ -25,6 +25,7 @@
*/
#include "k5-int.h"
+#include "k5-spake.h"
#include "ktest.h"
#include "com_err.h"
#include "utility.h"
@@ -1107,6 +1108,42 @@ int main(argc, argv)
ktest_empty_secure_cookie(&ref);
}
+ /****************************************************************/
+ /* decode_krb5_spake_factor */
+ {
+ setup(krb5_spake_factor,ktest_make_minimal_spake_factor);
+ decode_run("spake_factor","(optionals NULL)","30 05 A0 03 02 01 01",decode_krb5_spake_factor,ktest_equal_spake_factor,k5_free_spake_factor);
+ ktest_empty_spake_factor(&ref);
+ }
+ {
+ setup(krb5_spake_factor,ktest_make_maximal_spake_factor);
+ decode_run("spake_factor","","30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61",decode_krb5_spake_factor,ktest_equal_spake_factor,k5_free_spake_factor);
+ ktest_empty_spake_factor(&ref);
+ }
+
+ /****************************************************************/
+ /* decode_krb5_pa_spake */
+ {
+ setup(krb5_pa_spake,ktest_make_support_pa_spake);
+ decode_run("pa_spake","(support)","A0 0C 30 0A A0 08 30 06 02 01 01 02 01 02",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake);
+ ktest_empty_pa_spake(&ref);
+ }
+ {
+ setup(krb5_pa_spake,ktest_make_challenge_pa_spake);
+ decode_run("pa_spake","(challenge)","A1 2D 30 2B A0 03 02 01 01 A1 09 04 07 54 20 76 61 6C 75 65 A2 19 30 17 30 05 A0 03 02 01 01 30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake);
+ ktest_empty_pa_spake(&ref);
+ }
+ {
+ setup(krb5_pa_spake,ktest_make_response_pa_spake);
+ decode_run("pa_spake","(response)","A2 34 30 32 A0 09 04 07 53 20 76 61 6C 75 65 A1 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake);
+ ktest_empty_pa_spake(&ref);
+ }
+ {
+ setup(krb5_pa_spake,ktest_make_encdata_pa_spake);
+ decode_run("pa_spake","(encdata)","A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake);
+ ktest_empty_pa_spake(&ref);
+ }
+
#ifndef DISABLE_PKINIT
/****************************************************************/
diff --git a/src/tests/asn.1/krb5_encode_test.c b/src/tests/asn.1/krb5_encode_test.c
index f5710b68c..3efbfb4c0 100644
--- a/src/tests/asn.1/krb5_encode_test.c
+++ b/src/tests/asn.1/krb5_encode_test.c
@@ -759,6 +759,35 @@ main(argc, argv)
encode_run(cookie, "secure_cookie", "", encode_krb5_secure_cookie);
ktest_empty_secure_cookie(&cookie);
}
+ /****************************************************************/
+ /* encode_krb5_spake_factor */
+ {
+ krb5_spake_factor factor;
+ ktest_make_minimal_spake_factor(&factor);
+ encode_run(factor, "spake_factor", "(optionals NULL)",
+ encode_krb5_spake_factor);
+ ktest_empty_spake_factor(&factor);
+ ktest_make_maximal_spake_factor(&factor);
+ encode_run(factor, "spake_factor", "", encode_krb5_spake_factor);
+ ktest_empty_spake_factor(&factor);
+ }
+ /****************************************************************/
+ /* encode_krb5_pa_spake */
+ {
+ krb5_pa_spake pa_spake;
+ ktest_make_support_pa_spake(&pa_spake);
+ encode_run(pa_spake, "pa_spake", "(support)", encode_krb5_pa_spake);
+ ktest_empty_pa_spake(&pa_spake);
+ ktest_make_challenge_pa_spake(&pa_spake);
+ encode_run(pa_spake, "pa_spake", "(challenge)", encode_krb5_pa_spake);
+ ktest_empty_pa_spake(&pa_spake);
+ ktest_make_response_pa_spake(&pa_spake);
+ encode_run(pa_spake, "pa_spake", "(response)", encode_krb5_pa_spake);
+ ktest_empty_pa_spake(&pa_spake);
+ ktest_make_encdata_pa_spake(&pa_spake);
+ encode_run(pa_spake, "pa_spake", "(encdata)", encode_krb5_pa_spake);
+ ktest_empty_pa_spake(&pa_spake);
+ }
#ifndef DISABLE_PKINIT
/****************************************************************/
/* encode_krb5_pa_pk_as_req */
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
index cf63f3f66..5bfdc5be2 100644
--- a/src/tests/asn.1/ktest.c
+++ b/src/tests/asn.1/ktest.c
@@ -1018,6 +1018,66 @@ ktest_make_sample_secure_cookie(krb5_secure_cookie *p)
p->time = SAMPLE_TIME;
}
+void
+ktest_make_minimal_spake_factor(krb5_spake_factor *p)
+{
+ p->type = 1;
+ p->data = NULL;
+}
+
+void
+ktest_make_maximal_spake_factor(krb5_spake_factor *p)
+{
+ p->type = 2;
+ p->data = ealloc(sizeof(*p->data));
+ krb5_data_parse(p->data, "fdata");
+}
+
+void
+ktest_make_support_pa_spake(krb5_pa_spake *p)
+{
+ krb5_spake_support *s = &p->u.support;
+
+ s->ngroups = 2;
+ s->groups = ealloc(s->ngroups * sizeof(*s->groups));
+ s->groups[0] = 1;
+ s->groups[1] = 2;
+ p->choice = SPAKE_MSGTYPE_SUPPORT;
+}
+
+void
+ktest_make_challenge_pa_spake(krb5_pa_spake *p)
+{
+ krb5_spake_challenge *c = &p->u.challenge;
+
+ c->group = 1;
+ krb5_data_parse(&c->pubkey, "T value");
+ c->factors = ealloc(3 * sizeof(*c->factors));
+ c->factors[0] = ealloc(sizeof(*c->factors[0]));
+ ktest_make_minimal_spake_factor(c->factors[0]);
+ c->factors[1] = ealloc(sizeof(*c->factors[1]));
+ ktest_make_maximal_spake_factor(c->factors[1]);
+ c->factors[2] = NULL;
+ p->choice = SPAKE_MSGTYPE_CHALLENGE;
+}
+
+void
+ktest_make_response_pa_spake(krb5_pa_spake *p)
+{
+ krb5_spake_response *r = &p->u.response;
+
+ krb5_data_parse(&r->pubkey, "S value");
+ ktest_make_sample_enc_data(&r->factor);
+ p->choice = SPAKE_MSGTYPE_RESPONSE;
+}
+
+void
+ktest_make_encdata_pa_spake(krb5_pa_spake *p)
+{
+ ktest_make_sample_enc_data(&p->u.encdata);
+ p->choice = SPAKE_MSGTYPE_ENCDATA;
+}
+
/****************************************************************/
/* destructors */
@@ -1858,3 +1918,40 @@ ktest_empty_secure_cookie(krb5_secure_cookie *p)
{
ktest_empty_pa_data_array(p->data);
}
+
+void
+ktest_empty_spake_factor(krb5_spake_factor *p)
+{
+ krb5_free_data(NULL, p->data);
+ p->data = NULL;
+}
+
+void
+ktest_empty_pa_spake(krb5_pa_spake *p)
+{
+ krb5_spake_factor **f;
+
+ switch (p->choice) {
+ case SPAKE_MSGTYPE_SUPPORT:
+ free(p->u.support.groups);
+ break;
+ case SPAKE_MSGTYPE_CHALLENGE:
+ ktest_empty_data(&p->u.challenge.pubkey);
+ for (f = p->u.challenge.factors; *f != NULL; f++) {
+ ktest_empty_spake_factor(*f);
+ free(*f);
+ }
+ free(p->u.challenge.factors);
+ break;
+ case SPAKE_MSGTYPE_RESPONSE:
+ ktest_empty_data(&p->u.response.pubkey);
+ ktest_destroy_enc_data(&p->u.response.factor);
+ break;
+ case SPAKE_MSGTYPE_ENCDATA:
+ ktest_destroy_enc_data(&p->u.encdata);
+ break;
+ default:
+ break;
+ }
+ p->choice = SPAKE_MSGTYPE_UNKNOWN;
+}
diff --git a/src/tests/asn.1/ktest.h b/src/tests/asn.1/ktest.h
index 493303cc8..1413cfae1 100644
--- a/src/tests/asn.1/ktest.h
+++ b/src/tests/asn.1/ktest.h
@@ -28,6 +28,7 @@
#define __KTEST_H__
#include "k5-int.h"
+#include "k5-spake.h"
#include "kdb.h"
#define SAMPLE_USEC 123456
@@ -124,6 +125,12 @@ void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p);
void ktest_make_minimal_cammac(krb5_cammac *p);
void ktest_make_maximal_cammac(krb5_cammac *p);
void ktest_make_sample_secure_cookie(krb5_secure_cookie *p);
+void ktest_make_minimal_spake_factor(krb5_spake_factor *p);
+void ktest_make_maximal_spake_factor(krb5_spake_factor *p);
+void ktest_make_support_pa_spake(krb5_pa_spake *p);
+void ktest_make_challenge_pa_spake(krb5_pa_spake *p);
+void ktest_make_response_pa_spake(krb5_pa_spake *p);
+void ktest_make_encdata_pa_spake(krb5_pa_spake *p);
/*----------------------------------------------------------------------*/
@@ -209,6 +216,8 @@ void ktest_empty_ldap_seqof_key_data(krb5_context, ldap_seqof_key_data *p);
void ktest_empty_kkdcp_message(krb5_kkdcp_message *p);
void ktest_empty_cammac(krb5_cammac *p);
void ktest_empty_secure_cookie(krb5_secure_cookie *p);
+void ktest_empty_spake_factor(krb5_spake_factor *p);
+void ktest_empty_pa_spake(krb5_pa_spake *p);
extern krb5_context test_context;
extern char *sample_principal_name;
diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c
index e8bb88944..714cc4398 100644
--- a/src/tests/asn.1/ktest_equal.c
+++ b/src/tests/asn.1/ktest_equal.c
@@ -853,6 +853,13 @@ ktest_equal_sequence_of_otp_tokeninfo(krb5_otp_tokeninfo **ref,
array_compare(ktest_equal_otp_tokeninfo);
}
+int
+ktest_equal_sequence_of_spake_factor(krb5_spake_factor **ref,
+ krb5_spake_factor **var)
+{
+ array_compare(ktest_equal_spake_factor);
+}
+
#ifndef DISABLE_PKINIT
static int
@@ -1094,3 +1101,45 @@ ktest_equal_secure_cookie(krb5_secure_cookie *ref, krb5_secure_cookie *var)
p = p && ref->time == ref->time;
return p;
}
+
+int
+ktest_equal_spake_factor(krb5_spake_factor *ref, krb5_spake_factor *var)
+{
+ int p = TRUE;
+ if (ref == var) return TRUE;
+ else if (ref == NULL || var == NULL) return FALSE;
+ p = p && scalar_equal(type);
+ p = p && ptr_equal(data,ktest_equal_data);
+ return p;
+}
+
+int
+ktest_equal_pa_spake(krb5_pa_spake *ref, krb5_pa_spake *var)
+{
+ int p = TRUE;
+ if (ref == var) return TRUE;
+ else if (ref == NULL || var == NULL) return FALSE;
+ else if (ref->choice != var->choice) return FALSE;
+ switch (ref->choice) {
+ case SPAKE_MSGTYPE_SUPPORT:
+ p = p && scalar_equal(u.support.ngroups);
+ p = p && (memcmp(ref->u.support.groups,var->u.support.groups,
+ ref->u.support.ngroups * sizeof(int32_t)) == 0);
+ break;
+ case SPAKE_MSGTYPE_CHALLENGE:
+ p = p && struct_equal(u.challenge.pubkey,ktest_equal_data);
+ p = p && ptr_equal(u.challenge.factors,
+ ktest_equal_sequence_of_spake_factor);
+ break;
+ case SPAKE_MSGTYPE_RESPONSE:
+ p = p && struct_equal(u.response.pubkey,ktest_equal_data);
+ p = p && struct_equal(u.response.factor,ktest_equal_enc_data);
+ break;
+ case SPAKE_MSGTYPE_ENCDATA:
+ p = p && struct_equal(u.encdata,ktest_equal_enc_data);
+ break;
+ default:
+ break;
+ }
+ return p;
+}
diff --git a/src/tests/asn.1/ktest_equal.h b/src/tests/asn.1/ktest_equal.h
index c7b5d7467..cfa82ac6e 100644
--- a/src/tests/asn.1/ktest_equal.h
+++ b/src/tests/asn.1/ktest_equal.h
@@ -28,6 +28,7 @@
#define __KTEST_EQUAL_H__
#include "k5-int.h"
+#include "k5-spake.h"
#include "kdb.h"
/* int ktest_equal_structure(krb5_structure *ref, *var) */
@@ -97,6 +98,8 @@ ktest_equal_sequence_of_algorithm_identifier(krb5_algorithm_identifier **ref,
krb5_algorithm_identifier **var);
int ktest_equal_sequence_of_otp_tokeninfo(krb5_otp_tokeninfo **ref,
krb5_otp_tokeninfo **var);
+int ktest_equal_sequence_of_spake_factor(krb5_spake_factor **ref,
+ krb5_spake_factor **var);
len_array(ktest_equal_array_of_enctype,krb5_enctype);
len_array(ktest_equal_array_of_data,krb5_data);
@@ -152,4 +155,7 @@ int ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var);
int ktest_equal_secure_cookie(krb5_secure_cookie *ref,
krb5_secure_cookie *var);
+generic(ktest_equal_spake_factor, krb5_spake_factor);
+generic(ktest_equal_pa_spake, krb5_pa_spake);
+
#endif
diff --git a/src/tests/asn.1/make-vectors.c b/src/tests/asn.1/make-vectors.c
index 3cb8a45ba..2fc85466b 100644
--- a/src/tests/asn.1/make-vectors.c
+++ b/src/tests/asn.1/make-vectors.c
@@ -40,6 +40,8 @@
#include <PA-OTP-REQUEST.h>
#include <PA-OTP-ENC-REQUEST.h>
#include <AD-CAMMAC.h>
+#include <SPAKESecondFactor.h>
+#include <PA-SPAKE.h>
static unsigned char buf[8192];
static size_t buf_pos;
@@ -168,6 +170,36 @@ static struct other_verifiers overfs = { { verifiers, 2, 2 } };
static AD_CAMMAC_t cammac_2 = { { { (void *)adlist_2, 2, 2 } },
&vmac_1, &vmac_2, &overfs };
+/* SPAKESecondFactor */
+static SPAKESecondFactor_t factor_1 = { 1, NULL };
+static OCTET_STRING_t factor_data = { "fdata", 5 };
+static SPAKESecondFactor_t factor_2 = { 2, &factor_data };
+
+/* PA-SPAKE (support) */
+static Int32_t group_1 = 1, group_2 = 2, *groups[] = { &group_1, &group_2 };
+static PA_SPAKE_t pa_spake_1 = { PA_SPAKE_PR_support,
+ { .support = { { groups, 2, 2 } } } };
+
+/* PA-SPAKE (challenge) */
+static SPAKESecondFactor_t *factors[2] = { &factor_1, &factor_2 };
+static PA_SPAKE_t pa_spake_2 = { PA_SPAKE_PR_challenge,
+ { .challenge = { 1, { "T value", 7 },
+ { factors, 2, 2 } } } };
+
+/* PA-SPAKE (response) */
+UInt32_t enctype_5 = 5;
+static PA_SPAKE_t pa_spake_3 = { PA_SPAKE_PR_response,
+ { .response = { { "S value", 7 },
+ { 0, &enctype_5,
+ { "krbASN.1 test message",
+ 21 } } } } };
+
+/* PA-SPAKE (encdata) */
+static PA_SPAKE_t pa_spake_4 = { PA_SPAKE_PR_encdata,
+ { .encdata = { 0, &enctype_5,
+ { "krbASN.1 test message",
+ 21 } } } };
+
static int
consume(const void *data, size_t size, void *dummy)
{
@@ -272,6 +304,30 @@ main()
der_encode(&asn_DEF_AD_CAMMAC, &cammac_2, consume, NULL);
printbuf();
+ printf("\nMinimal SPAKESecondFactor:\n");
+ der_encode(&asn_DEF_SPAKESecondFactor, &factor_1, consume, NULL);
+ printbuf();
+
+ printf("\nMaximal SPAKESecondFactor:\n");
+ der_encode(&asn_DEF_SPAKESecondFactor, &factor_2, consume, NULL);
+ printbuf();
+
+ printf("\nPA-SPAKE (support):\n");
+ der_encode(&asn_DEF_PA_SPAKE, &pa_spake_1, consume, NULL);
+ printbuf();
+
+ printf("\nPA-SPAKE (challenge):\n");
+ der_encode(&asn_DEF_PA_SPAKE, &pa_spake_2, consume, NULL);
+ printbuf();
+
+ printf("\nPA-SPAKE (response):\n");
+ der_encode(&asn_DEF_PA_SPAKE, &pa_spake_3, consume, NULL);
+ printbuf();
+
+ printf("\nPA-SPAKE (encdata):\n");
+ der_encode(&asn_DEF_PA_SPAKE, &pa_spake_4, consume, NULL);
+ printbuf();
+
printf("\n");
return 0;
}
diff --git a/src/tests/asn.1/reference_encode.out b/src/tests/asn.1/reference_encode.out
index 824e0798b..a76deead2 100644
--- a/src/tests/asn.1/reference_encode.out
+++ b/src/tests/asn.1/reference_encode.out
@@ -72,3 +72,9 @@ encode_krb5_kkdcp_message: 30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82
encode_krb5_cammac(optionals NULL): 30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31
encode_krb5_cammac: 30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32
encode_krb5_secure_cookie: 30 2C 02 04 2D F8 02 25 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61
+encode_krb5_spake_factor(optionals NULL): 30 05 A0 03 02 01 01
+encode_krb5_spake_factor: 30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61
+encode_krb5_pa_spake(support): A0 0C 30 0A A0 08 30 06 02 01 01 02 01 02
+encode_krb5_pa_spake(challenge): A1 2D 30 2B A0 03 02 01 01 A1 09 04 07 54 20 76 61 6C 75 65 A2 19 30 17 30 05 A0 03 02 01 01 30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61
+encode_krb5_pa_spake(response): A2 34 30 32 A0 09 04 07 53 20 76 61 6C 75 65 A1 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65
+encode_krb5_pa_spake(encdata): A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65
diff --git a/src/tests/asn.1/spake.asn1 b/src/tests/asn.1/spake.asn1
new file mode 100644
index 000000000..50718d8ad
--- /dev/null
+++ b/src/tests/asn.1/spake.asn1
@@ -0,0 +1,44 @@
+KerberosV5SPAKE {
+ iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) kerberosV5(2) modules(4) spake(8)
+} DEFINITIONS EXPLICIT TAGS ::= BEGIN
+
+IMPORTS
+ EncryptedData, Int32
+ FROM KerberosV5Spec2 { iso(1) identified-organization(3)
+ dod(6) internet(1) security(5) kerberosV5(2) modules(4)
+ krb5spec2(2) };
+ -- as defined in RFC 4120.
+
+SPAKESupport ::= SEQUENCE {
+ groups [0] SEQUENCE (SIZE(1..MAX)) OF Int32,
+ ...
+}
+
+SPAKEChallenge ::= SEQUENCE {
+ group [0] Int32,
+ pubkey [1] OCTET STRING,
+ factors [2] SEQUENCE (SIZE(1..MAX)) OF SPAKESecondFactor,
+ ...
+}
+
+SPAKESecondFactor ::= SEQUENCE {
+ type [0] Int32,
+ data [1] OCTET STRING OPTIONAL
+}
+
+SPAKEResponse ::= SEQUENCE {
+ pubkey [0] OCTET STRING,
+ factor [1] EncryptedData, -- SPAKESecondFactor
+ ...
+}
+
+PA-SPAKE ::= CHOICE {
+ support [0] SPAKESupport,
+ challenge [1] SPAKEChallenge,
+ response [2] SPAKEResponse,
+ encdata [3] EncryptedData,
+ ...
+}
+
+END
diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out
index c27a0425b..e5c715924 100644
--- a/src/tests/asn.1/trval_reference.out
+++ b/src/tests/asn.1/trval_reference.out
@@ -1584,3 +1584,53 @@ encode_krb5_secure_cookie:
. . [Sequence/Sequence Of]
. . . [1] [Integer] 13
. . . [2] [Octet String] "pa-data"
+
+encode_krb5_spake_factor(optionals NULL):
+
+[Sequence/Sequence Of]
+. [0] [Integer] 1
+
+encode_krb5_spake_factor:
+
+[Sequence/Sequence Of]
+. [0] [Integer] 2
+. [1] [Octet String] "fdata"
+
+encode_krb5_pa_spake(support):
+
+[CONT 0]
+. [Sequence/Sequence Of]
+. . [0] [Sequence/Sequence Of]
+. . . [Integer] 1
+. . . [Integer] 2
+
+encode_krb5_pa_spake(challenge):
+
+[CONT 1]
+. [Sequence/Sequence Of]
+. . [0] [Integer] 1
+. . [1] [Octet String] "T value"
+. . [2] [Sequence/Sequence Of]
+. . . [Sequence/Sequence Of]
+. . . . [0] [Integer] 1
+. . . [Sequence/Sequence Of]
+. . . . [0] [Integer] 2
+. . . . [1] [Octet String] "fdata"
+
+encode_krb5_pa_spake(response):
+
+[CONT 2]
+. [Sequence/Sequence Of]
+. . [0] [Octet String] "S value"
+. . [1] [Sequence/Sequence Of]
+. . . [0] [Integer] 0
+. . . [1] [Integer] 5
+. . . [2] [Octet String] "krbASN.1 test message"
+
+encode_krb5_pa_spake(encdata):
+
+[CONT 3]
+. [Sequence/Sequence Of]
+. . [0] [Integer] 0
+. . [1] [Integer] 5
+. . [2] [Octet String] "krbASN.1 test message"

View File

@ -1,631 +0,0 @@
From c93112a19f73b9a984cabd320129ee8f70cb4823 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 12 Mar 2018 11:31:46 -0400
Subject: [PATCH] Add PKINIT KDC support for freshness token
Send a freshness token in the preauth hint list if PKINIT is
configured and the request padata indicates support. Verify the
freshness token if the client includes one in a PKINIT request, and
log whether one was received. If pkinit_require_freshness is set to
true in the realm config, reject non-anonymous requests which don't
contain a freshness token.
Add freshness token tests to t_pkinit.py with some related changes.
Remove client long-term keys after testing password preauth so we get
better error reporting when pkinit_require_freshness is set and a
token is not sent. Remove ./responder invocations for test cases
which don't ask PKINIT responder questions, or else the responder
would fail now that it isn't being asked for the password. Leave
anonymous PKINIT enabled after the anonymous tests so that we can use
it again when testing enforcement of pkinit_require_freshness. Add
expected trace messages for the basic test, including one for
receiving a freshness token. Add minimal expected trace messages for
the RSA test.
ticket: 8648
(cherry picked from commit 4a9050df0bc34bfb08ba24462d6e2514640f4b8e)
---
doc/admin/conf_files/kdc_conf.rst | 4 +
doc/admin/pkinit.rst | 25 +++++
doc/appdev/refs/macros/index.rst | 2 +
doc/formats/freshness_token.rst | 19 ++++
doc/formats/index.rst | 1 +
src/include/krb5/kdcpreauth_plugin.h | 17 ++++
src/include/krb5/krb5.hin | 3 +
src/kdc/do_as_req.c | 2 +
src/kdc/kdc_preauth.c | 130 +++++++++++++++++++++++-
src/kdc/kdc_util.h | 2 +
src/plugins/preauth/pkinit/pkinit.h | 2 +
src/plugins/preauth/pkinit/pkinit_srv.c | 51 +++++++++-
src/tests/t_pkinit.py | 50 ++++++---
13 files changed, 292 insertions(+), 16 deletions(-)
create mode 100644 doc/formats/freshness_token.rst
diff --git a/doc/admin/conf_files/kdc_conf.rst b/doc/admin/conf_files/kdc_conf.rst
index 3af1c3796..1ac1a37c2 100644
--- a/doc/admin/conf_files/kdc_conf.rst
+++ b/doc/admin/conf_files/kdc_conf.rst
@@ -798,6 +798,10 @@ For information about the syntax of some of these options, see
**pkinit_require_crl_checking** should be set to true if the
policy is such that up-to-date CRLs must be present for every CA.
+**pkinit_require_freshness**
+ Specifies whether to require clients to include a freshness token
+ in PKINIT requests. The default value is false. (New in release
+ 1.17.)
.. _Encryption_types:
diff --git a/doc/admin/pkinit.rst b/doc/admin/pkinit.rst
index c601c5c9e..bec4fc800 100644
--- a/doc/admin/pkinit.rst
+++ b/doc/admin/pkinit.rst
@@ -327,3 +327,28 @@ appropriate :ref:`kdc_realms` subsection of the KDC's
To obtain anonymous credentials on a client, run ``kinit -n``, or
``kinit -n @REALMNAME`` to specify a realm. The resulting tickets
will have the client name ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``.
+
+
+Freshness tokens
+----------------
+
+Freshness tokens can ensure that the client has recently had access to
+its certificate private key. If freshness tokens are not required by
+the KDC, a client program with temporary possession of the private key
+can compose requests for future timestamps and use them later.
+
+In release 1.17 and later, freshness tokens are supported by the
+client and are sent by the KDC when the client indicates support for
+them. Because not all clients support freshness tokens yet, they are
+not required by default. To check if freshness tokens are supported
+by a realm's clients, look in the KDC logs for the lines::
+
+ PKINIT: freshness token received from <client principal>
+ PKINIT: no freshness token received from <client principal>
+
+To require freshness tokens for all clients in a realm (except for
+clients authenticating anonymously), set the
+**pkinit_require_freshness** variable to ``true`` in the appropriate
+:ref:`kdc_realms` subsection of the KDC's :ref:`kdc.conf(5)` file. To
+test that this option is in effect, run ``kinit -X disable_freshness``
+and verify that authentication is unsuccessful.
diff --git a/doc/appdev/refs/macros/index.rst b/doc/appdev/refs/macros/index.rst
index e76747102..dba818b26 100644
--- a/doc/appdev/refs/macros/index.rst
+++ b/doc/appdev/refs/macros/index.rst
@@ -181,6 +181,7 @@ Public
KRB5_KEYUSAGE_KRB_ERROR_CKSUM.rst
KRB5_KEYUSAGE_KRB_PRIV_ENCPART.rst
KRB5_KEYUSAGE_KRB_SAFE_CKSUM.rst
+ KRB5_KEYUSAGE_PA_AS_FRESHNESS.rst
KRB5_KEYUSAGE_PA_FX_COOKIE.rst
KRB5_KEYUSAGE_PA_OTP_REQUEST.rst
KRB5_KEYUSAGE_PA_PKINIT_KX.rst
@@ -241,6 +242,7 @@ Public
KRB5_PADATA_AFS3_SALT.rst
KRB5_PADATA_AP_REQ.rst
KRB5_PADATA_AS_CHECKSUM.rst
+ KRB5_PADATA_AS_FRESHNESS.rst
KRB5_PADATA_ENCRYPTED_CHALLENGE.rst
KRB5_PADATA_ENC_SANDIA_SECURID.rst
KRB5_PADATA_ENC_TIMESTAMP.rst
diff --git a/doc/formats/freshness_token.rst b/doc/formats/freshness_token.rst
new file mode 100644
index 000000000..3127621a9
--- /dev/null
+++ b/doc/formats/freshness_token.rst
@@ -0,0 +1,19 @@
+PKINIT freshness tokens
+=======================
+
+:rfc:`8070` specifies a pa-data type PA_AS_FRESHNESS, which clients
+should reflect within signed PKINIT data to prove recent access to the
+client certificate private key. The contents of a freshness token are
+left to the KDC implementation. The MIT krb5 KDC uses the following
+format for freshness tokens (starting in release 1.17):
+
+* a four-byte big-endian POSIX timestamp
+* a four-byte big-endian key version number
+* an :rfc:`3961` checksum, with no ASN.1 wrapper
+
+The checksum is computed using the first key in the local krbtgt
+principal entry for the realm (e.g. ``krbtgt/KRBTEST.COM@KRBTEST.COM``
+if the request is to the ``KRBTEST.COM`` realm) of the indicated key
+version. The checksum type must be the mandatory checksum type for
+the encryption type of the krbtgt key. The key usage value for the
+checksum is 514.
diff --git a/doc/formats/index.rst b/doc/formats/index.rst
index 8b30626d4..4ad534424 100644
--- a/doc/formats/index.rst
+++ b/doc/formats/index.rst
@@ -7,3 +7,4 @@ Protocols and file formats
ccache_file_format
keytab_file_format
cookie
+ freshness_token
diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h
index f38820099..3a4754234 100644
--- a/src/include/krb5/kdcpreauth_plugin.h
+++ b/src/include/krb5/kdcpreauth_plugin.h
@@ -240,6 +240,23 @@ typedef struct krb5_kdcpreauth_callbacks_st {
/* End of version 4 kdcpreauth callbacks. */
+ /*
+ * Instruct the KDC to send a freshness token in the method data
+ * accompanying a PREAUTH_REQUIRED or PREAUTH_FAILED error, if the client
+ * indicated support for freshness tokens. This callback should only be
+ * invoked from the edata method.
+ */
+ void (*send_freshness_token)(krb5_context context,
+ krb5_kdcpreauth_rock rock);
+
+ /* Validate a freshness token sent by the client. Return 0 on success,
+ * KRB5KDC_ERR_PREAUTH_EXPIRED on error. */
+ krb5_error_code (*check_freshness_token)(krb5_context context,
+ krb5_kdcpreauth_rock rock,
+ const krb5_data *token);
+
+ /* End of version 5 kdcpreauth callbacks. */
+
} *krb5_kdcpreauth_callbacks;
/* Optional: preauth plugin initialization function. */
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 833e72335..a650ecece 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -1035,7 +1035,10 @@ krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype,
#define KRB5_KEYUSAGE_AS_REQ 56
#define KRB5_KEYUSAGE_CAMMAC 64
+/* Key usage values 512-1023 are reserved for uses internal to a Kerberos
+ * implementation. */
#define KRB5_KEYUSAGE_PA_FX_COOKIE 513 /**< Used for encrypted FAST cookies */
+#define KRB5_KEYUSAGE_PA_AS_FRESHNESS 514 /**< Used for freshness tokens */
/** @} */ /* end of KRB5_KEYUSAGE group */
/**
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 7c8da63e1..588c1375a 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -563,6 +563,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
state->rock.rstate = state->rstate;
state->rock.vctx = vctx;
state->rock.auth_indicators = &state->auth_indicators;
+ state->rock.send_freshness_token = FALSE;
if (!state->request->client) {
state->status = "NULL_CLIENT";
errcode = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
@@ -659,6 +660,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
state->status = "GET_LOCAL_TGT";
goto errout;
}
+ state->rock.local_tgt = state->local_tgt;
au_state->stage = VALIDATE_POL;
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 6f34dc289..80b130222 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -87,6 +87,9 @@
#include <assert.h>
#include <krb5/kdcpreauth_plugin.h>
+/* Let freshness tokens be valid for ten minutes. */
+#define FRESHNESS_LIFETIME 600
+
typedef struct preauth_system_st {
const char *name;
int type;
@@ -497,8 +500,68 @@ client_name(krb5_context context, krb5_kdcpreauth_rock rock)
return rock->client->princ;
}
+static void
+send_freshness_token(krb5_context context, krb5_kdcpreauth_rock rock)
+{
+ rock->send_freshness_token = TRUE;
+}
+
+static krb5_error_code
+check_freshness_token(krb5_context context, krb5_kdcpreauth_rock rock,
+ const krb5_data *token)
+{
+ krb5_timestamp token_ts, now;
+ krb5_key_data *kd;
+ krb5_keyblock kb;
+ krb5_kvno token_kvno;
+ krb5_checksum cksum;
+ krb5_data d;
+ uint8_t *token_cksum;
+ size_t token_cksum_len;
+ krb5_boolean valid = FALSE;
+ char ckbuf[4];
+
+ memset(&kb, 0, sizeof(kb));
+
+ if (krb5_timeofday(context, &now) != 0)
+ goto cleanup;
+
+ if (token->length <= 8)
+ goto cleanup;
+ token_ts = load_32_be(token->data);
+ token_kvno = load_32_be(token->data + 4);
+ token_cksum = (uint8_t *)token->data + 8;
+ token_cksum_len = token->length - 8;
+
+ /* Check if the token timestamp is too old. */
+ if (ts_after(now, ts_incr(token_ts, FRESHNESS_LIFETIME)))
+ goto cleanup;
+
+ /* Fetch and decrypt the local krbtgt key of the token's kvno. */
+ if (krb5_dbe_find_enctype(context, rock->local_tgt, -1, -1, token_kvno,
+ &kd) != 0)
+ goto cleanup;
+ if (krb5_dbe_decrypt_key_data(context, NULL, kd, &kb, NULL) != 0)
+ goto cleanup;
+
+ /* Verify the token checksum against the current KDC time. The checksum
+ * must use the mandatory checksum type of the krbtgt key's enctype. */
+ store_32_be(token_ts, ckbuf);
+ d = make_data(ckbuf, sizeof(ckbuf));
+ cksum.magic = KV5M_CHECKSUM;
+ cksum.checksum_type = 0;
+ cksum.length = token_cksum_len;
+ cksum.contents = token_cksum;
+ (void)krb5_c_verify_checksum(context, &kb, KRB5_KEYUSAGE_PA_AS_FRESHNESS,
+ &d, &cksum, &valid);
+
+cleanup:
+ krb5_free_keyblock_contents(context, &kb);
+ return valid ? 0 : KRB5KDC_ERR_PREAUTH_EXPIRED;
+}
+
static struct krb5_kdcpreauth_callbacks_st callbacks = {
- 4,
+ 5,
max_time_skew,
client_keys,
free_keys,
@@ -514,7 +577,9 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = {
get_cookie,
set_cookie,
match_client,
- client_name
+ client_name,
+ send_freshness_token,
+ check_freshness_token
};
static krb5_error_code
@@ -770,6 +835,62 @@ cleanup:
return ret;
}
+static krb5_error_code
+add_freshness_token(krb5_context context, krb5_kdcpreauth_rock rock,
+ krb5_pa_data ***pa_list)
+{
+ krb5_error_code ret;
+ krb5_timestamp now;
+ krb5_key_data *kd;
+ krb5_keyblock kb;
+ krb5_checksum cksum;
+ krb5_data d;
+ krb5_pa_data *pa;
+ char ckbuf[4];
+
+ memset(&cksum, 0, sizeof(cksum));
+ memset(&kb, 0, sizeof(kb));
+
+ if (!rock->send_freshness_token)
+ return 0;
+ if (krb5int_find_pa_data(context, rock->request->padata,
+ KRB5_PADATA_AS_FRESHNESS) == NULL)
+ return 0;
+
+ /* Fetch and decrypt the current local krbtgt key. */
+ ret = krb5_dbe_find_enctype(context, rock->local_tgt, -1, -1, 0, &kd);
+ if (ret)
+ goto cleanup;
+ ret = krb5_dbe_decrypt_key_data(context, NULL, kd, &kb, NULL);
+ if (ret)
+ goto cleanup;
+
+ /* Compute a checksum over the current KDC time. */
+ ret = krb5_timeofday(context, &now);
+ if (ret)
+ goto cleanup;
+ store_32_be(now, ckbuf);
+ d = make_data(ckbuf, sizeof(ckbuf));
+ ret = krb5_c_make_checksum(context, 0, &kb, KRB5_KEYUSAGE_PA_AS_FRESHNESS,
+ &d, &cksum);
+
+ /* Compose a freshness token from the time, krbtgt kvno, and checksum. */
+ ret = alloc_pa_data(KRB5_PADATA_AS_FRESHNESS, 8 + cksum.length, &pa);
+ if (ret)
+ goto cleanup;
+ store_32_be(now, pa->contents);
+ store_32_be(kd->key_data_kvno, pa->contents + 4);
+ memcpy(pa->contents + 8, cksum.contents, cksum.length);
+
+ /* add_pa_data_element() claims pa on success or failure. */
+ ret = add_pa_data_element(pa_list, pa);
+
+cleanup:
+ krb5_free_keyblock_contents(context, &kb);
+ krb5_free_checksum_contents(context, &cksum);
+ return ret;
+}
+
struct hint_state {
kdc_hint_respond_fn respond;
void *arg;
@@ -792,6 +913,11 @@ hint_list_finish(struct hint_state *state, krb5_error_code code)
void *oldarg = state->arg;
kdc_realm_t *kdc_active_realm = state->realm;
+ /* Add a freshness token if a preauth module requested it and the client
+ * request indicates support for it. */
+ if (!code)
+ code = add_freshness_token(kdc_context, state->rock, &state->pa_data);
+
if (!code) {
if (state->pa_data == NULL) {
krb5_klog_syslog(LOG_INFO,
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 198eab9c4..1885c9f80 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -426,11 +426,13 @@ struct krb5_kdcpreauth_rock_st {
krb5_kdc_req *request;
krb5_data *inner_body;
krb5_db_entry *client;
+ krb5_db_entry *local_tgt;
krb5_key_data *client_key;
krb5_keyblock *client_keyblock;
struct kdc_request_state *rstate;
verto_ctx *vctx;
krb5_data ***auth_indicators;
+ krb5_boolean send_freshness_token;
};
#define isflagset(flagfield, flag) (flagfield & (flag))
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index 8489a3e23..fe2ec0d31 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -77,6 +77,7 @@
#define KRB5_CONF_PKINIT_KDC_OCSP "pkinit_kdc_ocsp"
#define KRB5_CONF_PKINIT_POOL "pkinit_pool"
#define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING "pkinit_require_crl_checking"
+#define KRB5_CONF_PKINIT_REQUIRE_FRESHNESS "pkinit_require_freshness"
#define KRB5_CONF_PKINIT_REVOKE "pkinit_revoke"
/* Make pkiDebug(fmt,...) print, or not. */
@@ -148,6 +149,7 @@ typedef struct _pkinit_plg_opts {
int allow_upn; /* allow UPN-SAN instead of pkinit-SAN */
int dh_or_rsa; /* selects DH or RSA based pkinit */
int require_crl_checking; /* require CRL for a CA (default is false) */
+ int require_freshness; /* require freshness token (default is false) */
int disable_freshness; /* disable freshness token on client for testing */
int dh_min_bits; /* minimum DH modulus size allowed */
} pkinit_plg_opts;
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 8aa4d8b49..76ad5bf19 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -161,6 +161,10 @@ pkinit_server_get_edata(krb5_context context,
if (plgctx == NULL)
retval = EINVAL;
+ /* Send a freshness token if the client requested one. */
+ if (!retval)
+ cb->send_freshness_token(context, rock);
+
(*respond)(arg, retval, NULL);
}
@@ -403,6 +407,31 @@ cleanup:
return ret;
}
+/* Return an error if freshness tokens are required and one was not received.
+ * Log an appropriate message indicating whether a valid token was received. */
+static krb5_error_code
+check_log_freshness(krb5_context context, pkinit_kdc_context plgctx,
+ krb5_kdc_req *request, krb5_boolean valid_freshness_token)
+{
+ krb5_error_code ret;
+ char *name = NULL;
+
+ ret = krb5_unparse_name(context, request->client, &name);
+ if (ret)
+ return ret;
+ if (plgctx->opts->require_freshness && !valid_freshness_token) {
+ com_err("", 0, _("PKINIT: no freshness token, rejecting auth from %s"),
+ name);
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ } else if (valid_freshness_token) {
+ com_err("", 0, _("PKINIT: freshness token received from %s"), name);
+ } else {
+ com_err("", 0, _("PKINIT: no freshness token received from %s"), name);
+ }
+ krb5_free_unparsed_name(context, name);
+ return ret;
+}
+
static void
pkinit_server_verify_padata(krb5_context context,
krb5_data *req_pkt,
@@ -425,10 +454,11 @@ pkinit_server_verify_padata(krb5_context context,
pkinit_kdc_req_context reqctx = NULL;
krb5_checksum cksum = {0, 0, 0, NULL};
krb5_data *der_req = NULL;
- krb5_data k5data;
+ krb5_data k5data, *ftoken;
int is_signed = 1;
krb5_pa_data **e_data = NULL;
krb5_kdcpreauth_modreq modreq = NULL;
+ krb5_boolean valid_freshness_token = FALSE;
char **sp;
pkiDebug("pkinit_verify_padata: entered!\n");
@@ -599,6 +629,14 @@ pkinit_server_verify_padata(krb5_context context,
goto cleanup;
}
+ ftoken = auth_pack->pkAuthenticator.freshnessToken;
+ if (ftoken != NULL) {
+ retval = cb->check_freshness_token(context, rock, ftoken);
+ if (retval)
+ goto cleanup;
+ valid_freshness_token = TRUE;
+ }
+
/* check if kdcPkId present and match KDC's subjectIdentifier */
if (reqp->kdcPkId.data != NULL) {
int valid_kdcPkId = 0;
@@ -641,6 +679,13 @@ pkinit_server_verify_padata(krb5_context context,
break;
}
+ if (is_signed) {
+ retval = check_log_freshness(context, plgctx, request,
+ valid_freshness_token);
+ if (retval)
+ goto cleanup;
+ }
+
if (is_signed && plgctx->auth_indicators != NULL) {
/* Assert configured authentication indicators. */
for (sp = plgctx->auth_indicators; *sp != NULL; sp++) {
@@ -1330,6 +1375,10 @@ pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING,
0, &plgctx->opts->require_crl_checking);
+ pkinit_kdcdefault_boolean(context, plgctx->realmname,
+ KRB5_CONF_PKINIT_REQUIRE_FRESHNESS,
+ 0, &plgctx->opts->require_freshness);
+
pkinit_kdcdefault_string(context, plgctx->realmname,
KRB5_CONF_PKINIT_EKU_CHECKING,
&eku_string);
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 86fe661a0..5bc60cb1e 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -39,6 +39,8 @@ pkinit_kdc_conf = {'realms': {'$realm': {
'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}}
restrictive_kdc_conf = {'realms': {'$realm': {
'restrict_anonymous_to_tgt': 'true' }}}
+freshness_kdc_conf = {'realms': {'$realm': {
+ 'pkinit_require_freshness': 'true'}}}
testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
@@ -118,6 +120,10 @@ realm.kinit(realm.user_princ, password=password('user'))
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
+# Having tested password preauth, remove the keys for better error
+# reporting.
+realm.run([kadminl, 'purgekeys', '-all', realm.user_princ])
+
# Test anonymous PKINIT.
realm.kinit('@%s' % realm.realm, flags=['-n'], expected_code=1,
expected_msg='not found in Kerberos database')
@@ -153,23 +159,32 @@ realm.run([kvno, realm.host_princ], expected_code=1,
realm.kinit(realm.host_princ, flags=['-k'])
realm.run([kvno, '-U', 'user', realm.host_princ])
-# Go back to a normal KDC and disable anonymous PKINIT.
+# Go back to the normal KDC environment.
realm.stop_kdc()
realm.start_kdc()
-realm.run([kadminl, 'delprinc', 'WELLKNOWN/ANONYMOUS'])
# Run the basic test - PKINIT with FILE: identity, with no password on the key.
-realm.run(['./responder', '-x', 'pkinit=',
- '-X', 'X509_user_identity=%s' % file_identity, realm.user_princ])
realm.kinit(realm.user_princ,
- flags=['-X', 'X509_user_identity=%s' % file_identity])
+ flags=['-X', 'X509_user_identity=%s' % file_identity],
+ expected_trace=('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'PKINIT client received freshness token from KDC',
+ 'PKINIT loading CA certs and CRLs from FILE',
+ 'PKINIT client making DH request',
+ 'Produced preauth for next request: 133, 16',
+ 'PKINIT client verified DH reply',
+ 'PKINIT client found id-pkinit-san in KDC cert',
+ 'PKINIT client matched KDC principal krbtgt/'))
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
# Try again using RSA instead of DH.
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % file_identity,
- '-X', 'flag_RSA_PROTOCOL=yes'])
+ '-X', 'flag_RSA_PROTOCOL=yes'],
+ expected_trace=('PKINIT client making RSA request',
+ 'PKINIT client verified RSA reply'))
realm.klist(realm.user_princ)
# Test a DH parameter renegotiation by temporarily setting a 4096-bit
@@ -192,8 +207,23 @@ expected_trace = ('Sending unauthenticated request',
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % file_identity],
expected_trace=expected_trace)
+
+# Test enforcement of required freshness tokens. (We can leave
+# freshness tokens required after this test.)
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % file_identity,
+ '-X', 'disable_freshness=yes'])
+f_env = realm.special_env('freshness', True, kdc_conf=freshness_kdc_conf)
realm.stop_kdc()
-realm.start_kdc()
+realm.start_kdc(env=f_env)
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % file_identity])
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % file_identity,
+ '-X', 'disable_freshness=yes'],
+ expected_code=1, expected_msg='Preauthentication failed')
+# Anonymous should never require a freshness token.
+realm.kinit('@%s' % realm.realm, flags=['-n', '-X', 'disable_freshness=yes'])
# Run the basic test - PKINIT with FILE: identity, with a password on the key,
# supplied by the prompter.
@@ -229,8 +259,6 @@ shutil.copy(privkey_pem, os.path.join(path, 'user.key'))
shutil.copy(privkey_enc_pem, os.path.join(path_enc, 'user.key'))
shutil.copy(user_pem, os.path.join(path, 'user.crt'))
shutil.copy(user_pem, os.path.join(path_enc, 'user.crt'))
-realm.run(['./responder', '-x', 'pkinit=', '-X',
- 'X509_user_identity=%s' % dir_identity, realm.user_princ])
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % dir_identity])
realm.klist(realm.user_princ)
@@ -262,8 +290,6 @@ realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
# PKINIT with PKCS12: identity, with no password on the bundle.
-realm.run(['./responder', '-x', 'pkinit=',
- '-X', 'X509_user_identity=%s' % p12_identity, realm.user_princ])
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % p12_identity])
realm.klist(realm.user_princ)
@@ -357,8 +383,6 @@ conf = open(softpkcs11rc, 'w')
conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem))
conf.close()
# Expect to succeed without having to supply any more information.
-realm.run(['./responder', '-x', 'pkinit=',
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ])
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % p11_identity])
realm.klist(realm.user_princ)

View File

@ -1,336 +0,0 @@
From 5edc6de93196b4f07da6695a4b271a067000c84d Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 31 Jan 2017 17:02:34 -0500
Subject: [PATCH] Add PKINIT client support for freshness token
Send an empty PA_AS_FRESHNESS padata item in unauthenticated AS
requests to indicate support for RFC 8070. If the KDC includes a
PA_AS_FRESHNESS value in its method data, echo it back in the new
freshnessToken field of pkAuthenticator
ticket: 8648
(cherry picked from commit 085785362e01467cb25c79a90dcebfba9ea019d8)
---
doc/user/user_commands/kinit.rst | 3 +++
src/include/k5-int-pkinit.h | 1 +
src/include/krb5/krb5.hin | 1 +
src/lib/krb5/asn.1/asn1_k_encode.c | 5 ++++-
src/lib/krb5/krb/get_in_tkt.c | 12 ++++++++----
src/lib/krb5/krb/init_creds_ctx.h | 2 +-
src/plugins/preauth/pkinit/pkinit.h | 3 +++
src/plugins/preauth/pkinit/pkinit_clnt.c | 19 ++++++++++++++++++-
src/plugins/preauth/pkinit/pkinit_lib.c | 3 +++
src/plugins/preauth/pkinit/pkinit_trace.h | 2 ++
src/tests/asn.1/ktest.c | 4 ++++
src/tests/asn.1/pkinit_encode.out | 2 +-
src/tests/asn.1/pkinit_trval.out | 1 +
13 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/doc/user/user_commands/kinit.rst b/doc/user/user_commands/kinit.rst
index 3f9d5340f..1f696920f 100644
--- a/doc/user/user_commands/kinit.rst
+++ b/doc/user/user_commands/kinit.rst
@@ -197,6 +197,9 @@ OPTIONS
specify use of RSA, rather than the default Diffie-Hellman
protocol
+ **disable_freshness**\ [**=yes**]
+ disable sending freshness tokens (for testing purposes only)
+
ENVIRONMENT
-----------
diff --git a/src/include/k5-int-pkinit.h b/src/include/k5-int-pkinit.h
index 7b2f595cb..4622a629e 100644
--- a/src/include/k5-int-pkinit.h
+++ b/src/include/k5-int-pkinit.h
@@ -42,6 +42,7 @@ typedef struct _krb5_pk_authenticator {
krb5_timestamp ctime;
krb5_int32 nonce; /* (0..4294967295) */
krb5_checksum paChecksum;
+ krb5_data *freshnessToken;
} krb5_pk_authenticator;
/* PKAuthenticator draft9 */
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index e81bb0a6d..833e72335 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -1879,6 +1879,7 @@ krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype,
#define KRB5_PADATA_OTP_PIN_CHANGE 144 /**< RFC 6560 section 4.3 */
#define KRB5_PADATA_PKINIT_KX 147 /**< RFC 6112 */
#define KRB5_ENCPADATA_REQ_ENC_PA_REP 149 /**< RFC 6806 */
+#define KRB5_PADATA_AS_FRESHNESS 150 /**< RFC 8070 */
#define KRB5_SAM_USE_SAD_AS_KEY 0x80000000
#define KRB5_SAM_SEND_ENCRYPTED_SAD 0x40000000
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 889460989..3b23fe34a 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -1442,9 +1442,12 @@ DEFFIELD(pk_authenticator_1, krb5_pk_authenticator, ctime, 1, kerberos_time);
DEFFIELD(pk_authenticator_2, krb5_pk_authenticator, nonce, 2, int32);
DEFFIELD(pk_authenticator_3, krb5_pk_authenticator, paChecksum, 3,
ostring_checksum);
+DEFFIELD(pk_authenticator_4, krb5_pk_authenticator, freshnessToken, 4,
+ opt_ostring_data_ptr);
static const struct atype_info *pk_authenticator_fields[] = {
&k5_atype_pk_authenticator_0, &k5_atype_pk_authenticator_1,
- &k5_atype_pk_authenticator_2, &k5_atype_pk_authenticator_3
+ &k5_atype_pk_authenticator_2, &k5_atype_pk_authenticator_3,
+ &k5_atype_pk_authenticator_4
};
DEFSEQTYPE(pk_authenticator, krb5_pk_authenticator, pk_authenticator_fields);
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 47a00bf2c..1d96ff163 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -895,7 +895,7 @@ krb5_init_creds_init(krb5_context context,
ctx->request = k5alloc(sizeof(krb5_kdc_req), &code);
if (code != 0)
goto cleanup;
- ctx->enc_pa_rep_permitted = TRUE;
+ ctx->info_pa_permitted = TRUE;
code = krb5_copy_principal(context, client, &ctx->request->client);
if (code != 0)
goto cleanup;
@@ -1389,7 +1389,11 @@ init_creds_step_request(krb5_context context,
krb5_free_data(context, ctx->encoded_previous_request);
ctx->encoded_previous_request = NULL;
}
- if (ctx->enc_pa_rep_permitted) {
+ if (ctx->info_pa_permitted) {
+ code = add_padata(&ctx->request->padata, KRB5_PADATA_AS_FRESHNESS,
+ NULL, 0);
+ if (code)
+ goto cleanup;
code = add_padata(&ctx->request->padata, KRB5_ENCPADATA_REQ_ENC_PA_REP,
NULL, 0);
}
@@ -1530,7 +1534,7 @@ init_creds_step_reply(krb5_context context,
ctx->selected_preauth_type == KRB5_PADATA_NONE) {
/* The KDC didn't like our informational padata (probably a pre-1.7
* MIT krb5 KDC). Retry without it. */
- ctx->enc_pa_rep_permitted = FALSE;
+ ctx->info_pa_permitted = FALSE;
ctx->restarted = TRUE;
code = restart_init_creds_loop(context, ctx, FALSE);
} else if (reply_code == KDC_ERR_PREAUTH_EXPIRED) {
@@ -1574,7 +1578,7 @@ init_creds_step_reply(krb5_context context,
goto cleanup;
/* Reset per-realm negotiation state. */
ctx->restarted = FALSE;
- ctx->enc_pa_rep_permitted = TRUE;
+ ctx->info_pa_permitted = TRUE;
code = restart_init_creds_loop(context, ctx, FALSE);
} else {
if (retry && ctx->selected_preauth_type != KRB5_PADATA_NONE) {
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index fe769685b..b19410a13 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -58,7 +58,7 @@ struct _krb5_init_creds_context {
krb5_data s2kparams;
krb5_keyblock as_key;
krb5_enctype etype;
- krb5_boolean enc_pa_rep_permitted;
+ krb5_boolean info_pa_permitted;
krb5_boolean restarted;
struct krb5_responder_context_st rctx;
krb5_preauthtype selected_preauth_type;
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index f3de9ad7a..8489a3e23 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -148,6 +148,7 @@ typedef struct _pkinit_plg_opts {
int allow_upn; /* allow UPN-SAN instead of pkinit-SAN */
int dh_or_rsa; /* selects DH or RSA based pkinit */
int require_crl_checking; /* require CRL for a CA (default is false) */
+ int disable_freshness; /* disable freshness token on client for testing */
int dh_min_bits; /* minimum DH modulus size allowed */
} pkinit_plg_opts;
@@ -162,6 +163,7 @@ typedef struct _pkinit_req_opts {
int require_crl_checking;
int dh_size; /* initial request DH modulus size (default=1024) */
int require_hostname_match;
+ int disable_freshness;
} pkinit_req_opts;
/*
@@ -214,6 +216,7 @@ struct _pkinit_req_context {
int identity_initialized;
int identity_prompted;
krb5_error_code identity_prompt_retval;
+ krb5_data *freshness_token;
};
typedef struct _pkinit_req_context *pkinit_req_context;
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index f1bc6b21d..9483d69e5 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -231,6 +231,8 @@ pkinit_as_req_create(krb5_context context,
auth_pack.pkAuthenticator.cusec = cusec;
auth_pack.pkAuthenticator.nonce = nonce;
auth_pack.pkAuthenticator.paChecksum = *cksum;
+ if (!reqctx->opts->disable_freshness)
+ auth_pack.pkAuthenticator.freshnessToken = reqctx->freshness_token;
auth_pack.clientDHNonce.length = 0;
auth_pack.clientPublicValue = &info;
auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids;
@@ -1162,6 +1164,7 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
pkinit_context plgctx = (pkinit_context)moddata;
pkinit_req_context reqctx = (pkinit_req_context)modreq;
krb5_keyblock as_key;
+ krb5_data d;
pkiDebug("pkinit_client_process %p %p %p %p\n",
context, plgctx, reqctx, request);
@@ -1174,6 +1177,12 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
case KRB5_PADATA_PKINIT_KX:
reqctx->rfc6112_kdc = 1;
return 0;
+ case KRB5_PADATA_AS_FRESHNESS:
+ TRACE_PKINIT_CLIENT_FRESHNESS_TOKEN(context);
+ krb5_free_data(context, reqctx->freshness_token);
+ reqctx->freshness_token = NULL;
+ d = make_data(in_padata->contents, in_padata->length);
+ return krb5_copy_data(context, &d, &reqctx->freshness_token);
case KRB5_PADATA_PK_AS_REQ:
reqctx->rfc4556_kdc = 1;
pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
@@ -1359,7 +1368,7 @@ cleanup:
static int
pkinit_client_get_flags(krb5_context kcontext, krb5_preauthtype patype)
{
- if (patype == KRB5_PADATA_PKINIT_KX)
+ if (patype == KRB5_PADATA_PKINIT_KX || patype == KRB5_PADATA_AS_FRESHNESS)
return PA_INFO;
return PA_REAL;
}
@@ -1376,6 +1385,7 @@ static krb5_preauthtype supported_client_pa_types[] = {
KRB5_PADATA_PK_AS_REP_OLD,
KRB5_PADATA_PK_AS_REQ_OLD,
KRB5_PADATA_PKINIT_KX,
+ KRB5_PADATA_AS_FRESHNESS,
0
};
@@ -1400,6 +1410,7 @@ pkinit_client_req_init(krb5_context context,
reqctx->opts = NULL;
reqctx->idctx = NULL;
reqctx->idopts = NULL;
+ reqctx->freshness_token = NULL;
retval = pkinit_init_req_opts(&reqctx->opts);
if (retval)
@@ -1410,6 +1421,7 @@ pkinit_client_req_init(krb5_context context,
reqctx->opts->dh_or_rsa = plgctx->opts->dh_or_rsa;
reqctx->opts->allow_upn = plgctx->opts->allow_upn;
reqctx->opts->require_crl_checking = plgctx->opts->require_crl_checking;
+ reqctx->opts->disable_freshness = plgctx->opts->disable_freshness;
retval = pkinit_init_req_crypto(&reqctx->cryptoctx);
if (retval)
@@ -1468,6 +1480,8 @@ pkinit_client_req_fini(krb5_context context, krb5_clpreauth_moddata moddata,
if (reqctx->idopts != NULL)
pkinit_fini_identity_opts(reqctx->idopts);
+ krb5_free_data(context, reqctx->freshness_token);
+
free(reqctx);
return;
}
@@ -1580,6 +1594,9 @@ handle_gic_opt(krb5_context context,
pkiDebug("Setting flag to use RSA_PROTOCOL\n");
plgctx->opts->dh_or_rsa = RSA_PROTOCOL;
}
+ } else if (strcmp(attr, "disable_freshness") == 0) {
+ if (strcmp(value, "yes") == 0)
+ plgctx->opts->disable_freshness = 1;
}
return 0;
}
diff --git a/src/plugins/preauth/pkinit/pkinit_lib.c b/src/plugins/preauth/pkinit/pkinit_lib.c
index 2f88545da..d5858c424 100644
--- a/src/plugins/preauth/pkinit/pkinit_lib.c
+++ b/src/plugins/preauth/pkinit/pkinit_lib.c
@@ -82,6 +82,8 @@ pkinit_init_plg_opts(pkinit_plg_opts **plgopts)
opts->dh_or_rsa = DH_PROTOCOL;
opts->allow_upn = 0;
opts->require_crl_checking = 0;
+ opts->require_freshness = 0;
+ opts->disable_freshness = 0;
opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
@@ -145,6 +147,7 @@ free_krb5_auth_pack(krb5_auth_pack **in)
free((*in)->clientPublicValue);
}
free((*in)->pkAuthenticator.paChecksum.contents);
+ krb5_free_data(NULL, (*in)->pkAuthenticator.freshnessToken);
if ((*in)->supportedCMSTypes != NULL)
free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
if ((*in)->supportedKDFs) {
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index 2d95da94a..7f95206c0 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -41,6 +41,8 @@
TRACE(c, "PKINIT client found no acceptable EKU in KDC cert")
#define TRACE_PKINIT_CLIENT_EKU_SKIP(c) \
TRACE(c, "PKINIT client skipping EKU check due to configuration")
+#define TRACE_PKINIT_CLIENT_FRESHNESS_TOKEN(c) \
+ TRACE(c, "PKINIT client received freshness token from KDC")
#define TRACE_PKINIT_CLIENT_KDF_ALG(c, kdf, keyblock) \
TRACE(c, "PKINIT client used KDF {hexdata} to compute reply key " \
"{keyblock}", kdf, keyblock)
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
index 43084cbbd..cf63f3f66 100644
--- a/src/tests/asn.1/ktest.c
+++ b/src/tests/asn.1/ktest.c
@@ -725,6 +725,8 @@ ktest_make_sample_pk_authenticator(krb5_pk_authenticator *p)
ktest_make_sample_checksum(&p->paChecksum);
/* We don't encode the checksum type, only the contents. */
p->paChecksum.checksum_type = 0;
+ p->freshnessToken = ealloc(sizeof(krb5_data));
+ ktest_make_sample_data(p->freshnessToken);
}
static void
@@ -1651,6 +1653,8 @@ ktest_empty_pk_authenticator(krb5_pk_authenticator *p)
{
ktest_empty_checksum(&p->paChecksum);
p->paChecksum.contents = NULL;
+ krb5_free_data(NULL, p->freshnessToken);
+ p->freshnessToken = NULL;
}
static void
diff --git a/src/tests/asn.1/pkinit_encode.out b/src/tests/asn.1/pkinit_encode.out
index 463128de0..3b0f7190a 100644
--- a/src/tests/asn.1/pkinit_encode.out
+++ b/src/tests/asn.1/pkinit_encode.out
@@ -4,7 +4,7 @@ encode_krb5_pa_pk_as_rep(dhInfo): A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0
encode_krb5_pa_pk_as_rep(encKeyPack): 81 08 6B 72 62 35 64 61 74 61
encode_krb5_pa_pk_as_rep_draft9(dhSignedData): 80 08 6B 72 62 35 64 61 74 61
encode_krb5_pa_pk_as_rep_draft9(encKeyPack): 81 08 6B 72 62 35 64 61 74 61
-encode_krb5_auth_pack: 30 81 93 A0 29 30 27 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
+encode_krb5_auth_pack: 30 81 9F A0 35 30 33 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
encode_krb5_auth_pack_draft9: 30 75 A0 4F 30 4D A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 05 02 03 01 E2 40 A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 03 02 01 2A A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61
encode_krb5_kdc_dh_key_info: 30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A
encode_krb5_reply_key_pack: 30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34
diff --git a/src/tests/asn.1/pkinit_trval.out b/src/tests/asn.1/pkinit_trval.out
index 58d870631..f9edbe154 100644
--- a/src/tests/asn.1/pkinit_trval.out
+++ b/src/tests/asn.1/pkinit_trval.out
@@ -57,6 +57,7 @@ encode_krb5_auth_pack:
. . [1] [Generalized Time] "19940610060317Z"
. . [2] [Integer] 42
. . [3] [Octet String] "1234"
+. . [4] [Octet String] "krb5data"
. [1] [Sequence/Sequence Of]
. . [Sequence/Sequence Of]
. . . [Object Identifier] <9>

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
From c891e4bc54c8083a1af8d28aa9b12ab1177ebb9a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 27 Mar 2018 00:49:43 -0400
Subject: [PATCH] Add doc index entries for SPAKE constants
ticket: 8647
(cherry picked from commit c010c9031753f356bb380e8a1324cc34721f8221)
---
doc/appdev/refs/macros/index.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/doc/appdev/refs/macros/index.rst b/doc/appdev/refs/macros/index.rst
index dba818b26..47c6d4413 100644
--- a/doc/appdev/refs/macros/index.rst
+++ b/doc/appdev/refs/macros/index.rst
@@ -190,6 +190,7 @@ Public
KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM.rst
KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID.rst
KRB5_KEYUSAGE_PA_SAM_RESPONSE.rst
+ KRB5_KEYUSAGE_SPAKE.rst
KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY.rst
KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY.rst
KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY.rst
@@ -274,6 +275,7 @@ Public
KRB5_PADATA_SAM_RESPONSE.rst
KRB5_PADATA_SAM_RESPONSE_2.rst
KRB5_PADATA_SESAME.rst
+ KRB5_PADATA_SPAKE.rst
KRB5_PADATA_SVR_REFERRAL_INFO.rst
KRB5_PADATA_TGS_REQ.rst
KRB5_PADATA_USE_SPECIFIED_KVNO.rst

View File

@ -1,204 +0,0 @@
From f44ef4893050e673f495444c27a19525813f75a8 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 11 Jun 2018 13:53:27 -0400
Subject: [PATCH] Add flag to disable encrypted timestamp on client
ticket: 8655
(cherry picked from commit 4ad376134b8d456392edbac7a7d351e6c7a7f0e7)
---
doc/admin/conf_files/krb5_conf.rst | 10 ++++++++++
doc/admin/spake.rst | 8 ++++++++
src/include/k5-int.h | 1 +
src/include/k5-trace.h | 2 ++
src/lib/krb5/krb/get_in_tkt.c | 23 +++++++++++++++++++++++
src/lib/krb5/krb/init_creds_ctx.h | 1 +
src/lib/krb5/krb/preauth_encts.c | 14 +++++++++++++-
src/tests/t_referral.py | 13 +++++++++++++
8 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index ce545492d..eb5c29e5d 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -475,6 +475,16 @@ following tags may be specified in the realm's subsection:
(for example, when converting ``rcmd.hostname`` to
``host/hostname.domain``).
+**disable_encrypted_timestamp**
+ If this flag is true, the client will not perform encrypted
+ timestamp preauthentication if requested by the KDC. Setting this
+ flag can help to prevent dictionary attacks by active attackers,
+ if the realm's KDCs support SPAKE preauthentication or if initial
+ authentication always uses another mechanism or always uses FAST.
+ This flag persists across client referrals during initial
+ authentication. This flag does not prevent the KDC from offering
+ encrypted timestamp. New in release 1.17.
+
**http_anchors**
When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag
can be used to specify the location of the CA certificate which should be
diff --git a/doc/admin/spake.rst b/doc/admin/spake.rst
index b65c694aa..4f6eeaf53 100644
--- a/doc/admin/spake.rst
+++ b/doc/admin/spake.rst
@@ -30,6 +30,14 @@ principal entries, as you would for any preauthentication mechanism::
Clients which do not implement SPAKE preauthentication will fall back
to encrypted timestamp.
+An active attacker can force a fallback to encrypted timestamp by
+modifying the initial KDC response, defeating the protection against
+dictionary attacks. To prevent this fallback on clients which do
+implement SPAKE preauthentication, set the
+**disable_encrypted_timestamp** variable to ``true`` in the
+:ref:`realms` subsection for realms whose KDCs offer SPAKE
+preauthentication.
+
By default, SPAKE preauthentication requires an extra network round
trip to the KDC during initial authentication. If most of the clients
in a realm support SPAKE, this extra round trip can be eliminated
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 86b53c76b..e4a9a1412 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -204,6 +204,7 @@ typedef unsigned char u_char;
#define KRB5_CONF_DES_CRC_SESSION_SUPPORTED "des_crc_session_supported"
#define KRB5_CONF_DICT_FILE "dict_file"
#define KRB5_CONF_DISABLE "disable"
+#define KRB5_CONF_DISABLE_ENCRYPTED_TIMESTAMP "disable_encrypted_timestamp"
#define KRB5_CONF_DISABLE_LAST_SUCCESS "disable_last_success"
#define KRB5_CONF_DISABLE_LOCKOUT "disable_lockout"
#define KRB5_CONF_DNS_CANONICALIZE_HOSTNAME "dns_canonicalize_hostname"
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
index 5f7eb9517..0854974dc 100644
--- a/src/include/k5-trace.h
+++ b/src/include/k5-trace.h
@@ -299,6 +299,8 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_PREAUTH_ENC_TS(c, sec, usec, plain, enc) \
TRACE(c, "Encrypted timestamp (for {long}.{int}): plain {hexdata}, " \
"encrypted {hexdata}", (long) sec, (int) usec, plain, enc)
+#define TRACE_PREAUTH_ENC_TS_DISABLED(c) \
+ TRACE(c, "Ignoring encrypted timestamp because it is disabled")
#define TRACE_PREAUTH_ETYPE_INFO(c, etype, salt, s2kparams) \
TRACE(c, "Selected etype info: etype {etype}, salt \"{data}\", " \
"params \"{data}\"", etype, salt, s2kparams)
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index c026bbc6d..79dede2c6 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -801,6 +801,24 @@ read_allowed_preauth_type(krb5_context context, krb5_init_creds_context ctx)
free(tmp);
}
+/* Return true if encrypted timestamp is disabled for realm. */
+static krb5_boolean
+encts_disabled(profile_t profile, const krb5_data *realm)
+{
+ krb5_error_code ret;
+ char *realmstr;
+ int bval;
+
+ realmstr = k5memdup0(realm->data, realm->length, &ret);
+ if (realmstr == NULL)
+ return FALSE;
+ ret = profile_get_boolean(profile, KRB5_CONF_REALMS, realmstr,
+ KRB5_CONF_DISABLE_ENCRYPTED_TIMESTAMP, FALSE,
+ &bval);
+ free(realmstr);
+ return (ret == 0) ? bval : FALSE;
+}
+
/**
* Throw away any pre-authentication realm state and begin with a
* unauthenticated or optimistically authenticated request. If fast_upgrade is
@@ -842,6 +860,11 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
goto cleanup;
}
+ /* Never set encts_disabled back to false, so it can't be circumvented with
+ * client realm referrals. */
+ if (encts_disabled(context->profile, &ctx->request->client->realm))
+ ctx->encts_disabled = TRUE;
+
krb5_free_principal(context, ctx->request->server);
ctx->request->server = NULL;
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index 7ba61e17c..7a6219b1c 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -61,6 +61,7 @@ struct _krb5_init_creds_context {
krb5_boolean info_pa_permitted;
krb5_boolean restarted;
krb5_boolean fallback_disabled;
+ krb5_boolean encts_disabled;
struct krb5_responder_context_st rctx;
krb5_preauthtype selected_preauth_type;
krb5_preauthtype allowed_preauth_type;
diff --git a/src/lib/krb5/krb/preauth_encts.c b/src/lib/krb5/krb/preauth_encts.c
index 45bf9da92..345701984 100644
--- a/src/lib/krb5/krb/preauth_encts.c
+++ b/src/lib/krb5/krb/preauth_encts.c
@@ -28,6 +28,7 @@
#include <k5-int.h>
#include <krb5/clpreauth_plugin.h>
#include "int-proto.h"
+#include "init_creds_ctx.h"
static krb5_error_code
encts_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata,
@@ -38,7 +39,10 @@ encts_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata,
krb5_data *encoded_previous_request,
krb5_pa_data *pa_data)
{
- cb->need_as_key(context, rock);
+ krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
+
+ if (!ctx->encts_disabled)
+ cb->need_as_key(context, rock);
return 0;
}
@@ -51,6 +55,7 @@ encts_process(krb5_context context, krb5_clpreauth_moddata moddata,
krb5_prompter_fct prompter, void *prompter_data,
krb5_pa_data ***out_padata)
{
+ krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
krb5_error_code ret;
krb5_pa_enc_ts pa_enc;
krb5_data *ts = NULL, *enc_ts = NULL;
@@ -60,6 +65,13 @@ encts_process(krb5_context context, krb5_clpreauth_moddata moddata,
enc_data.ciphertext = empty_data();
+ if (ctx->encts_disabled) {
+ TRACE_PREAUTH_ENC_TS_DISABLED(context);
+ k5_setmsg(context, KRB5_PREAUTH_FAILED,
+ _("Encrypted timestamp is disabled"));
+ return KRB5_PREAUTH_FAILED;
+ }
+
ret = cb->get_as_key(context, rock, &as_key);
if (ret)
goto cleanup;
diff --git a/src/tests/t_referral.py b/src/tests/t_referral.py
index 98fdf2925..e12fdc2e9 100755
--- a/src/tests/t_referral.py
+++ b/src/tests/t_referral.py
@@ -126,4 +126,17 @@ r1.klist('user@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM')
r1.kinit('abc@XYZ', 'pw', ['-E'])
r1.klist('abc\@XYZ@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM')
+# Test that disable_encrypted_timestamp persists across client
+# referrals. (This test relies on SPAKE not being enabled by default
+# on the KDC.)
+r2.run([kadminl, 'modprinc', '+preauth', 'user'])
+msgs = ('Encrypted timestamp (for ')
+r1.kinit('user', password('user'), ['-C'], expected_trace=msgs)
+dconf = {'realms': {'$realm': {'disable_encrypted_timestamp': 'true'}}}
+denv = r1.special_env('disable_encts', False, krb5_conf=dconf)
+msgs = ('Ignoring encrypted timestamp because it is disabled',
+ '/Encrypted timestamp is disabled')
+r1.kinit('user', None, ['-C'], env=denv, expected_code=1, expected_trace=msgs,
+ expected_msg='Encrypted timestamp is disabled')
+
success('KDC host referral tests')

View File

@ -0,0 +1,183 @@
From 656fb920da2d6be3c55976320e3e13a69af30c8a Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 15 Jan 2019 16:16:57 -0500
Subject: [PATCH] Add function and enctype flag for deprecations
krb5int_c_deprecated_enctype() checks for the ETYPE_DEPRECATED flag on
enctypes. All ENCTYPE_WEAK enctypes are currently deprecated; not all
deprecated enctypes are considered weak. Deprecations follow RFC 6649
and RFC 8429.
(cherry picked from commit 484a6e7712f9b66e782b2520f07b0883889e116f)
---
src/include/k5-int.h | 1 +
src/lib/crypto/krb/crypto_int.h | 9 ++++++++-
src/lib/crypto/krb/enctype_util.c | 7 +++++++
src/lib/crypto/krb/etypes.c | 19 ++++++++++---------
src/lib/crypto/libk5crypto.exports | 1 +
src/lib/krb5_32.def | 3 +++
6 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 8f9329c59..255cee822 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2077,6 +2077,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **);
krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype);
krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype);
+krb5_boolean KRB5_CALLCONV krb5int_c_deprecated_enctype(krb5_enctype);
krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out);
krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *,
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index e5099291e..6c1c77cac 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -114,7 +114,14 @@ struct krb5_keytypes {
unsigned int ssf;
};
-#define ETYPE_WEAK 1
+/*
+ * "Weak" means the enctype is believed to be vulnerable to practical attacks,
+ * and will be disabled unless allow_weak_crypto is set to true. "Deprecated"
+ * means the enctype has been deprecated by the IETF, and affects display and
+ * logging.
+ */
+#define ETYPE_WEAK (1 << 0)
+#define ETYPE_DEPRECATED (1 << 1)
extern const struct krb5_keytypes krb5int_enctypes_list[];
extern const int krb5int_enctypes_length;
diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c
index b1b40e7ec..e394f4e19 100644
--- a/src/lib/crypto/krb/enctype_util.c
+++ b/src/lib/crypto/krb/enctype_util.c
@@ -51,6 +51,13 @@ krb5int_c_weak_enctype(krb5_enctype etype)
return (ktp != NULL && (ktp->flags & ETYPE_WEAK) != 0);
}
+krb5_boolean KRB5_CALLCONV
+krb5int_c_deprecated_enctype(krb5_enctype etype)
+{
+ const struct krb5_keytypes *ktp = find_enctype(etype);
+ return ktp != NULL && (ktp->flags & ETYPE_DEPRECATED) != 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2,
krb5_boolean *similar)
diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c
index 53d4a5c79..8f44c37e7 100644
--- a/src/lib/crypto/krb/etypes.c
+++ b/src/lib/crypto/krb/etypes.c
@@ -33,6 +33,7 @@
that the keytypes are all near each other. I'd rather not make
that assumption. */
+/* Deprecations come from RFC 6649 and RFC 8249. */
const struct krb5_keytypes krb5int_enctypes_list[] = {
{ ENCTYPE_DES_CBC_CRC,
"des-cbc-crc", { 0 }, "DES cbc mode with CRC-32",
@@ -42,7 +43,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES_CBC_MD4,
"des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4",
&krb5int_enc_des, &krb5int_hash_md4,
@@ -51,7 +52,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD4_DES,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES_CBC_MD5,
"des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5",
&krb5int_enc_des, &krb5int_hash_md5,
@@ -60,7 +61,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES_CBC_RAW,
"des-cbc-raw", { 0 }, "DES cbc mode raw",
&krb5int_enc_des, NULL,
@@ -69,7 +70,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
0,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
{ ENCTYPE_DES3_CBC_RAW,
"des3-cbc-raw", { 0 }, "Triple DES cbc mode raw",
&krb5int_enc_des3, NULL,
@@ -78,7 +79,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
NULL, /*PRF*/
0,
- ETYPE_WEAK, 112 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 112 },
{ ENCTYPE_DES3_CBC_SHA1,
"des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" },
@@ -89,7 +90,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_DES3,
- 0 /*flags*/, 112 },
+ ETYPE_DEPRECATED, 112 },
{ ENCTYPE_DES_HMAC_SHA1,
"des-hmac-sha1", { 0 }, "DES with HMAC/sha1",
@@ -99,7 +100,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des,
NULL, /*PRF*/
0,
- ETYPE_WEAK, 56 },
+ ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
/* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we
* consider its strength degraded and assign it an SSF value of 64. */
@@ -113,7 +114,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- 0 /*flags*/, 64 },
+ ETYPE_DEPRECATED, 64 },
{ ENCTYPE_ARCFOUR_HMAC_EXP,
"arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
"Exportable ArcFour with HMAC/md5",
@@ -124,7 +125,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- ETYPE_WEAK, 40
+ ETYPE_WEAK | ETYPE_DEPRECATED, 40
},
{ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 82eb5f30c..90afdf5f7 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -109,3 +109,4 @@ k5_allow_weak_pbkdf2iter
krb5_c_prfplus
krb5_c_derive_prfplus
k5_enctype_to_ssf
+krb5int_c_deprecated_enctype
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index c35022931..e6a487593 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -487,3 +487,6 @@ EXPORTS
encode_krb5_pa_spake @444 ; PRIVATE
decode_krb5_pa_spake @445 ; PRIVATE
k5_free_pa_spake @446 ; PRIVATE
+
+; new in 1.18
+ krb5int_c_deprecated_enctype @450 ; PRIVATE

View File

@ -1,119 +0,0 @@
From 74e1079df0cc6e8932e487455177a69f782b863a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 4 Jan 2018 14:35:12 -0500
Subject: [PATCH] Add k5_buf_add_vfmt to k5buf interface
(cherry picked from commit f05766469efc2a055085c0bcf9d40c4cdf47fe36)
---
src/include/k5-buf.h | 8 ++++++
src/util/support/k5buf.c | 26 +++++++++++--------
src/util/support/libkrb5support-fixed.exports | 1 +
3 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/src/include/k5-buf.h b/src/include/k5-buf.h
index f3207bd09..1223916a6 100644
--- a/src/include/k5-buf.h
+++ b/src/include/k5-buf.h
@@ -76,6 +76,14 @@ void k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
#endif
;
+/* Add sprintf-style formatted data to BUF, with a va_list. The value of ap is
+ * undefined after the call. */
+void k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+ __attribute__((__format__(__printf__, 2, 0)))
+#endif
+ ;
+
/* Extend the length of buf by len and return a pointer to the reserved space,
* to be filled in by the caller. Return NULL on error. */
void *k5_buf_get_space(struct k5buf *buf, size_t len);
diff --git a/src/util/support/k5buf.c b/src/util/support/k5buf.c
index f619f6a48..35978f238 100644
--- a/src/util/support/k5buf.c
+++ b/src/util/support/k5buf.c
@@ -141,9 +141,9 @@ k5_buf_add_len(struct k5buf *buf, const void *data, size_t len)
}
void
-k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
{
- va_list ap;
+ va_list apcopy;
int r;
size_t remaining;
char *tmp;
@@ -154,9 +154,7 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
if (buf->buftype == K5BUF_FIXED) {
/* Format the data directly into the fixed buffer. */
- va_start(ap, fmt);
r = vsnprintf(endptr(buf), remaining, fmt, ap);
- va_end(ap);
if (SNPRINTF_OVERFLOW(r, remaining))
set_error(buf);
else
@@ -166,9 +164,9 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
/* Optimistically format the data directly into the dynamic buffer. */
assert(buf->buftype == K5BUF_DYNAMIC);
- va_start(ap, fmt);
- r = vsnprintf(endptr(buf), remaining, fmt, ap);
- va_end(ap);
+ va_copy(apcopy, ap);
+ r = vsnprintf(endptr(buf), remaining, fmt, apcopy);
+ va_end(apcopy);
if (!SNPRINTF_OVERFLOW(r, remaining)) {
buf->len += (unsigned int) r;
return;
@@ -179,9 +177,7 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
if (!ensure_space(buf, r))
return;
remaining = buf->space - buf->len;
- va_start(ap, fmt);
r = vsnprintf(endptr(buf), remaining, fmt, ap);
- va_end(ap);
if (SNPRINTF_OVERFLOW(r, remaining)) /* Shouldn't ever happen. */
k5_buf_free(buf);
else
@@ -191,9 +187,7 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
/* It's a pre-C99 snprintf implementation, or something else went wrong.
* Fall back to asprintf. */
- va_start(ap, fmt);
r = vasprintf(&tmp, fmt, ap);
- va_end(ap);
if (r < 0) {
k5_buf_free(buf);
return;
@@ -206,6 +200,16 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
free(tmp);
}
+void
+k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ k5_buf_add_vfmt(buf, fmt, ap);
+ va_end(ap);
+}
+
void *
k5_buf_get_space(struct k5buf *buf, size_t len)
{
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index 30c946e7e..cb9bf0826 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -6,6 +6,7 @@ k5_buf_init_dynamic
k5_buf_add
k5_buf_add_len
k5_buf_add_fmt
+k5_buf_add_vfmt
k5_buf_get_space
k5_buf_truncate
k5_buf_status

View File

@ -1,222 +0,0 @@
From 9010a0dbf59771cb0a9c1e6fd5a18a92a1200ca7 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 5 Jun 2018 14:01:05 -0400
Subject: [PATCH] Add k5_dir_filenames() to libkrb5support
Add a support function to get a list of filenames from a directory in
sorted order.
(cherry picked from commit 27534121eb39089ff4335d8b465027e9ba783682)
---
src/include/k5-platform.h | 7 +
src/util/support/Makefile.in | 3 +
src/util/support/dir_filenames.c | 135 ++++++++++++++++++
src/util/support/libkrb5support-fixed.exports | 2 +
4 files changed, 147 insertions(+)
create mode 100644 src/util/support/dir_filenames.c
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
index 07ef6a4ca..763408a09 100644
--- a/src/include/k5-platform.h
+++ b/src/include/k5-platform.h
@@ -44,6 +44,8 @@
* + constant time memory comparison
* + path manipulation
* + _, N_, dgettext, bindtextdomain (for localization)
+ * + getopt_long
+ * + fetching filenames from a directory
*/
#ifndef K5_PLATFORM_H
@@ -1148,4 +1150,9 @@ extern int k5_getopt_long(int nargc, char **nargv, char *options,
#define getopt_long k5_getopt_long
#endif /* HAVE_GETOPT_LONG */
+/* Set *fnames_out to a null-terminated list of filenames within dirname,
+ * sorted according to strcmp(). Return 0 on success, or ENOENT/ENOMEM. */
+int k5_dir_filenames(const char *dirname, char ***fnames_out);
+void k5_free_filenames(char **fnames);
+
#endif /* K5_PLATFORM_H */
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index caaf15822..4715e0391 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -85,6 +85,7 @@ STLIBOBJS= \
hex.o \
bcmp.o \
strerror_r.o \
+ dir_filenames.o \
$(GETTIMEOFDAY_ST_OBJ) \
$(IPC_ST_OBJ) \
$(STRLCPY_ST_OBJ) \
@@ -111,6 +112,7 @@ LIBOBJS= \
$(OUTPRE)hex.$(OBJEXT) \
$(OUTPRE)bcmp.$(OBJEXT) \
$(OUTPRE)strerror_r.$(OBJEXT) \
+ $(OUTPRE)dir_filenames.$(OBJEXT) \
$(GETTIMEOFDAY_OBJ) \
$(IPC_OBJ) \
$(STRLCPY_OBJ) \
@@ -147,6 +149,7 @@ SRCS=\
$(srcdir)/hex.c \
$(srcdir)/bcmp.c \
$(srcdir)/strerror_r.c \
+ $(srcdir)/dir_filenames.c \
$(srcdir)/t_utf8.c \
$(srcdir)/t_utf16.c \
$(srcdir)/getopt.c \
diff --git a/src/util/support/dir_filenames.c b/src/util/support/dir_filenames.c
new file mode 100644
index 000000000..9312b0238
--- /dev/null
+++ b/src/util/support/dir_filenames.c
@@ -0,0 +1,135 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* util/support/dir_filenames.c - fetch filenames in a directory */
+/*
+ * Copyright (C) 2018 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 "k5-platform.h"
+
+void
+k5_free_filenames(char **fnames)
+{
+ char **fn;
+
+ for (fn = fnames; fn != NULL && *fn != NULL; fn++)
+ free(*fn);
+ free(fnames);
+}
+
+/* Resize the filename list and add a name. */
+static int
+add_filename(char ***fnames, int *n_fnames, const char *name)
+{
+ char **newlist;
+
+ newlist = realloc(*fnames, (*n_fnames + 2) * sizeof(*newlist));
+ if (newlist == NULL)
+ return ENOMEM;
+ *fnames = newlist;
+ newlist[*n_fnames] = strdup(name);
+ if (newlist[*n_fnames] == NULL)
+ return ENOMEM;
+ (*n_fnames)++;
+ newlist[*n_fnames] = NULL;
+ return 0;
+}
+
+static int
+compare_with_strcmp(const void *a, const void *b)
+{
+ return strcmp(*(char **)a, *(char **)b);
+}
+
+#ifdef _WIN32
+
+int
+k5_dir_filenames(const char *dirname, char ***fnames_out)
+{
+ char *wildcard;
+ WIN32_FIND_DATA ffd;
+ HANDLE handle;
+ char **fnames = NULL;
+ int n_fnames = 0;
+
+ *fnames_out = NULL;
+
+ if (asprintf(&wildcard, "%s\\*", dirname) < 0)
+ return ENOMEM;
+ handle = FindFirstFile(wildcard, &ffd);
+ free(wildcard);
+ if (handle == INVALID_HANDLE_VALUE)
+ return ENOENT;
+
+ do {
+ if (add_filename(&fnames, &n_fnames, &ffd.cFileName) != 0) {
+ k5_free_filenames(fnames);
+ FindClose(handle);
+ return ENOMEM;
+ }
+ } while (FindNextFile(handle, &ffd) != 0);
+
+ FindClose(handle);
+ qsort(fnames, n_fnames, sizeof(*fnames), compare_with_strcmp);
+ *fnames_out = fnames;
+ return 0;
+}
+
+#else /* _WIN32 */
+
+#include <dirent.h>
+
+int
+k5_dir_filenames(const char *dirname, char ***fnames_out)
+{
+ DIR *dir;
+ struct dirent *ent;
+ char **fnames = NULL;
+ int n_fnames = 0;
+
+ *fnames_out = NULL;
+
+ dir = opendir(dirname);
+ if (dir == NULL)
+ return ENOENT;
+
+ while ((ent = readdir(dir)) != NULL) {
+ if (add_filename(&fnames, &n_fnames, ent->d_name) != 0) {
+ k5_free_filenames(fnames);
+ closedir(dir);
+ return ENOMEM;
+ }
+ }
+
+ closedir(dir);
+ qsort(fnames, n_fnames, sizeof(*fnames), compare_with_strcmp);
+ *fnames_out = fnames;
+ return 0;
+}
+
+#endif /* not _WIN32 */
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index a5e2ade04..16ed5a6c1 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -58,6 +58,8 @@ k5_path_split
k5_strerror_r
k5_utf8_to_utf16le
k5_utf16le_to_utf8
+k5_dir_filenames
+k5_free_filenames
krb5int_key_register
krb5int_key_delete
krb5int_getspecific

View File

@ -1,60 +0,0 @@
From 68b61c6d6402c0ad57509705137c92ae814ace27 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 18 Apr 2018 19:21:40 -0400
Subject: [PATCH] Add k5test mark() function
Make it easier to locate a failing command in long Python test scripts
by allowing the script to output marks, and displaying the most recent
mark with command failures.
(cherry picked from commit 4e813204ac3dace93297f47d64dfc0aaecc370f8)
---
src/util/k5test.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/util/k5test.py b/src/util/k5test.py
index 4d30baf40..bc32877a7 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -141,6 +141,11 @@ Scripts may use the following functions and variables:
added newline) in testlog, and write it to stdout if running
verbosely.
+* mark(message): Place a divider message in the test output, to make
+ it easier to determine what part of the test script a command
+ invocation belongs to. The last mark message will also be displayed
+ if a command invocation fails. Do not include a newline in message.
+
* which(progname): Return the location of progname in the executable
path, or None if it is not found.
@@ -376,6 +381,8 @@ def fail(msg):
"""Print a message and exit with failure."""
global _current_pass
print "*** Failure:", msg
+ if _last_mark:
+ print "*** Last mark: %s" % _last_mark
if _last_cmd:
print "*** Last command (#%d): %s" % (_cmd_index - 1, _last_cmd)
if _last_cmd_output:
@@ -392,6 +399,12 @@ def success(msg):
_success = True
+def mark(msg):
+ global _last_mark
+ output('\n====== %s ======\n' % msg)
+ _last_mark = msg
+
+
def skipped(whatmsg, whymsg):
output('*** Skipping: %s: %s\n' % (whatmsg, whymsg), force_verbose=True)
f = open(os.path.join(buildtop, 'skiptests'), 'a')
@@ -1275,6 +1288,7 @@ atexit.register(_onexit)
signal.signal(signal.SIGINT, _onsigint)
_outfile = open('testlog', 'w')
_cmd_index = 1
+_last_mark = None
_last_cmd = None
_last_cmd_output = None
buildtop = _find_buildtop()

View File

@ -1,484 +0,0 @@
From 507b1aff60fdadc91ca7c56d39711049aeeb1e58 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 19 Feb 2018 00:51:44 -0500
Subject: [PATCH] Add libkrb5support hex functions and tests
(cherry picked from commit 720dea558da0062d3cea4385327161e62cf09a5e)
[rharwood@redhat.com Remove .gitignore]
---
src/include/k5-hex.h | 53 ++++++
src/util/support/Makefile.in | 15 +-
src/util/support/deps | 6 +
src/util/support/hex.c | 116 ++++++++++++
src/util/support/libkrb5support-fixed.exports | 2 +
src/util/support/t_hex.c | 169 ++++++++++++++++++
6 files changed, 358 insertions(+), 3 deletions(-)
create mode 100644 src/include/k5-hex.h
create mode 100644 src/util/support/hex.c
create mode 100644 src/util/support/t_hex.c
diff --git a/src/include/k5-hex.h b/src/include/k5-hex.h
new file mode 100644
index 000000000..75bd2cb19
--- /dev/null
+++ b/src/include/k5-hex.h
@@ -0,0 +1,53 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-hex.h - libkrb5support hex encoding/decoding declarations */
+/*
+ * Copyright (C) 2018 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+#ifndef K5_HEX_H
+#define K5_HEX_H
+
+#include "k5-platform.h"
+
+/*
+ * Encode len bytes in hex, placing the result in allocated storage in
+ * *hex_out. Use uppercase hex digits if uppercase is non-zero. Return 0 on
+ * success, ENOMEM on error.
+ */
+int k5_hex_encode(const void *bytes, size_t len, int uppercase,
+ char **hex_out);
+
+/*
+ * Decode hex bytes, placing the result in allocated storage in *bytes_out and
+ * *len_out. Null-terminate the result (primarily for decoding passwords in
+ * libkdb_ldap). Return 0 on success, ENOMEM or EINVAL on error.
+ */
+int k5_hex_decode(const char *hex, uint8_t **bytes_out, size_t *len_out);
+
+#endif /* K5_HEX_H */
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index 58ac2e333..caaf15822 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -82,6 +82,7 @@ STLIBOBJS= \
path.o \
base64.o \
json.o \
+ hex.o \
bcmp.o \
strerror_r.o \
$(GETTIMEOFDAY_ST_OBJ) \
@@ -107,6 +108,7 @@ LIBOBJS= \
$(OUTPRE)path.$(OBJEXT) \
$(OUTPRE)base64.$(OBJEXT) \
$(OUTPRE)json.$(OBJEXT) \
+ $(OUTPRE)hex.$(OBJEXT) \
$(OUTPRE)bcmp.$(OBJEXT) \
$(OUTPRE)strerror_r.$(OBJEXT) \
$(GETTIMEOFDAY_OBJ) \
@@ -137,10 +139,12 @@ SRCS=\
$(srcdir)/t_unal.c \
$(srcdir)/t_path.c \
$(srcdir)/t_json.c \
+ $(srcdir)/t_hex.c \
$(srcdir)/zap.c \
$(srcdir)/path.c \
$(srcdir)/base64.c \
$(srcdir)/json.c \
+ $(srcdir)/hex.c \
$(srcdir)/bcmp.c \
$(srcdir)/strerror_r.c \
$(srcdir)/t_utf8.c \
@@ -216,6 +220,9 @@ T_JSON_OBJS= t_json.o json.o base64.o k5buf.o $(PRINTF_ST_OBJ)
t_json: $(T_JSON_OBJS)
$(CC_LINK) -o $@ $(T_JSON_OBJS)
+t_hex: t_hex.o hex.o
+ $(CC_LINK) -o $@ t_hex.o hex.o
+
t_unal: t_unal.o
$(CC_LINK) -o t_unal t_unal.o
@@ -227,7 +234,8 @@ T_UTF16_OBJS= t_utf16.o utf8_conv.o utf8.o k5buf.o $(PRINTF_ST_OBJ)
t_utf16: $(T_UTF16_OBJS)
$(CC_LINK) -o $@ $(T_UTF16_OBJS)
-TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_json t_unal t_utf8 t_utf16
+TEST_PROGS= t_k5buf t_path t_path_win t_base64 t_json t_hex t_unal t_utf8 \
+ t_utf16
check-unix: $(TEST_PROGS)
./t_k5buf
@@ -235,6 +243,7 @@ check-unix: $(TEST_PROGS)
./t_path_win
./t_base64
./t_json
+ ./t_hex
./t_unal
./t_utf8
./t_utf16
@@ -242,8 +251,8 @@ check-unix: $(TEST_PROGS)
clean:
$(RM) t_k5buf.o t_k5buf t_unal.o t_unal path_win.o path_win
$(RM) t_path_win.o t_path_win t_path.o t_path t_base64.o t_base64
- $(RM) t_json.o t_json libkrb5support.exports t_utf8.o t_utf8
- $(RM) t_utf16.o t_utf16
+ $(RM) t_json.o t_json t_hex.o t_hex libkrb5support.exports
+ $(RM) t_utf8.o t_utf8 t_utf16.o t_utf16
@lib_frag@
@libobj_frag@
diff --git a/src/util/support/deps b/src/util/support/deps
index 34d8a884b..80e9a1c58 100644
--- a/src/util/support/deps
+++ b/src/util/support/deps
@@ -63,6 +63,9 @@ t_path.so t_path.po $(OUTPRE)t_path.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
t_path.c
t_json.so t_json.po $(OUTPRE)t_json.$(OBJEXT): $(top_srcdir)/include/k5-json.h \
t_json.c
+t_hex.so t_hex.po $(OUTPRE)t_hex.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h t_hex.c
zap.so zap.po $(OUTPRE)zap.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
zap.c
@@ -76,6 +79,9 @@ json.so json.po $(OUTPRE)json.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-base64.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-json.h $(top_srcdir)/include/k5-platform.h \
$(top_srcdir)/include/k5-thread.h json.c
+hex.so hex.po $(OUTPRE)hex.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h hex.c
bcmp.so bcmp.po $(OUTPRE)bcmp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
bcmp.c
diff --git a/src/util/support/hex.c b/src/util/support/hex.c
new file mode 100644
index 000000000..4407ff9ff
--- /dev/null
+++ b/src/util/support/hex.c
@@ -0,0 +1,116 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* util/support/hex.c - hex encoding/decoding implementation */
+/*
+ * Copyright (C) 2018 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 <k5-platform.h>
+#include <k5-hex.h>
+#include <ctype.h>
+
+static inline char
+hex_digit(uint8_t bval, int uppercase)
+{
+ assert(bval >= 0 && bval <= 0xF);
+ if (bval < 10)
+ return '0' + bval;
+ else if (uppercase)
+ return 'A' + (bval - 10);
+ else
+ return 'a' + (bval - 10);
+}
+
+int
+k5_hex_encode(const void *bytes, size_t len, int uppercase, char **hex_out)
+{
+ size_t i;
+ const uint8_t *p = bytes;
+ char *hex;
+
+ *hex_out = NULL;
+
+ hex = malloc(len * 2 + 1);
+ if (hex == NULL)
+ return ENOMEM;
+
+ for (i = 0; i < len; i++) {
+ hex[i * 2] = hex_digit(p[i] >> 4, uppercase);
+ hex[i * 2 + 1] = hex_digit(p[i] & 0xF, uppercase);
+ }
+ hex[len * 2] = '\0';
+
+ *hex_out = hex;
+ return 0;
+}
+
+/* Decode a hex digit. Return 0-15 on success, -1 on invalid input. */
+static inline int
+decode_hexchar(unsigned char c)
+{
+ if (isdigit(c))
+ return c - '0';
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ return -1;
+}
+
+int
+k5_hex_decode(const char *hex, uint8_t **bytes_out, size_t *len_out)
+{
+ size_t hexlen, i;
+ int h1, h2;
+ uint8_t *bytes;
+
+ *bytes_out = NULL;
+ *len_out = 0;
+
+ hexlen = strlen(hex);
+ if (hexlen % 2 != 0)
+ return EINVAL;
+ bytes = malloc(hexlen / 2 + 1);
+ if (bytes == NULL)
+ return ENOMEM;
+
+ for (i = 0; i < hexlen / 2; i++) {
+ h1 = decode_hexchar(hex[i * 2]);
+ h2 = decode_hexchar(hex[i * 2 + 1]);
+ if (h1 == -1 || h2 == -1) {
+ free(bytes);
+ return EINVAL;
+ }
+ bytes[i] = h1 * 16 + h2;
+ }
+ bytes[i] = 0;
+
+ *bytes_out = bytes;
+ *len_out = hexlen / 2;
+ return 0;
+}
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index fd74a1897..30c946e7e 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -16,6 +16,8 @@ k5_get_error
k5_free_error
k5_clear_error
k5_set_error_info_callout_fn
+k5_hex_decode
+k5_hex_encode
k5_json_array_add
k5_json_array_create
k5_json_array_fmt
diff --git a/src/util/support/t_hex.c b/src/util/support/t_hex.c
new file mode 100644
index 000000000..a586a1bc8
--- /dev/null
+++ b/src/util/support/t_hex.c
@@ -0,0 +1,169 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* util/support/t_hex.c - Test hex encoding and decoding */
+/*
+ * Copyright (C) 2018 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 <k5-platform.h>
+#include <k5-hex.h>
+
+struct {
+ const char *hex;
+ const char *binary;
+ size_t binary_len;
+ int uppercase;
+} tests[] = {
+ /* Invalid hex strings */
+ { "1" },
+ { "123" },
+ { "0/" },
+ { "/0" },
+ { "0:" },
+ { ":0" },
+ { "0@" },
+ { "@0" },
+ { "0G" },
+ { "G0" },
+ { "0`" },
+ { "`0" },
+ { "0g" },
+ { "g0" },
+ { " 00 " },
+ { "0\x01" },
+
+ { "", "", 0 },
+ { "00", "\x00", 1 },
+ { "01", "\x01", 1 },
+ { "10", "\x10", 1 },
+ { "01ff", "\x01\xFF", 2 },
+ { "A0B0C0", "\xA0\xB0\xC0", 3, 1 },
+ { "1a2b3c4d5e6f", "\x1A\x2B\x3C\x4D\x5E\x6F", 6 },
+ { "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 32 },
+
+ /* All byte values, lowercase */
+ { "0001020304050607", "\x00\x01\x02\x03\x04\x05\x06\x07", 8 },
+ { "08090a0b0c0d0e0f", "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 8 },
+ { "1011121314151617", "\x10\x11\x12\x13\x14\x15\x16\x17", 8 },
+ { "18191a1b1c1d1e1f", "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 8 },
+ { "2021222324252627", "\x20\x21\x22\x23\x24\x25\x26\x27", 8 },
+ { "28292a2b2c2d2e2f", "\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F", 8 },
+ { "3031323334353637", "\x30\x31\x32\x33\x34\x35\x36\x37", 8 },
+ { "38393a3b3c3d3e3f", "\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F", 8 },
+ { "4041424344454647", "\x40\x41\x42\x43\x44\x45\x46\x47", 8 },
+ { "48494a4b4c4d4e4f", "\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F", 8 },
+ { "5051525354555657", "\x50\x51\x52\x53\x54\x55\x56\x57", 8 },
+ { "58595a5b5c5d5e5f", "\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F", 8 },
+ { "6061626364656667", "\x60\x61\x62\x63\x64\x65\x66\x67", 8 },
+ { "68696a6b6c6d6e6f", "\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F", 8 },
+ { "7071727374757677", "\x70\x71\x72\x73\x74\x75\x76\x77", 8 },
+ { "78797a7b7c7d7e7f", "\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F", 8 },
+ { "8081828384858687", "\x80\x81\x82\x83\x84\x85\x86\x87", 8 },
+ { "88898a8b8c8d8e8f", "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F", 8 },
+ { "9091929394959697", "\x90\x91\x92\x93\x94\x95\x96\x97", 8 },
+ { "98999a9b9c9d9e9f", "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F", 8 },
+ { "a0a1a2a3a4a5a6a7", "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", 8 },
+ { "a8a9aaabacadaeaf", "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", 8 },
+ { "b0b1b2b3b4b5b6b7", "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", 8 },
+ { "b8b9babbbcbdbebf", "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF", 8 },
+ { "c0c1c2c3c4c5c6c7", "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7", 8 },
+ { "c8c9cacbcccdcecf", "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 8 },
+ { "d0d1d2d3d4d5d6d7", "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7", 8 },
+ { "d8d9dadbdcdddedf", "\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF", 8 },
+ { "e0e1e2e3e4e5e6e7", "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7", 8 },
+ { "e8e9eaebecedeeef", "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF", 8 },
+ { "f0f1f2f3f4f5f6f7", "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7", 8 },
+ { "f8f9fafbfcfdfeff", "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", 8 },
+
+ /* All byte values, uppercase */
+ { "0001020304050607", "\x00\x01\x02\x03\x04\x05\x06\x07", 8, 1 },
+ { "08090A0B0C0D0E0F", "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 8, 1 },
+ { "1011121314151617", "\x10\x11\x12\x13\x14\x15\x16\x17", 8, 1 },
+ { "18191A1B1C1D1E1F", "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 8, 1 },
+ { "2021222324252627", "\x20\x21\x22\x23\x24\x25\x26\x27", 8, 1 },
+ { "28292A2B2C2D2E2F", "\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F", 8, 1 },
+ { "3031323334353637", "\x30\x31\x32\x33\x34\x35\x36\x37", 8, 1 },
+ { "38393A3B3C3D3E3F", "\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F", 8, 1 },
+ { "4041424344454647", "\x40\x41\x42\x43\x44\x45\x46\x47", 8, 1 },
+ { "48494A4B4C4D4E4F", "\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F", 8, 1 },
+ { "5051525354555657", "\x50\x51\x52\x53\x54\x55\x56\x57", 8, 1 },
+ { "58595A5B5C5D5E5F", "\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F", 8, 1 },
+ { "6061626364656667", "\x60\x61\x62\x63\x64\x65\x66\x67", 8, 1 },
+ { "68696A6B6C6D6E6F", "\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F", 8, 1 },
+ { "7071727374757677", "\x70\x71\x72\x73\x74\x75\x76\x77", 8, 1 },
+ { "78797A7B7C7D7E7F", "\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F", 8, 1 },
+ { "8081828384858687", "\x80\x81\x82\x83\x84\x85\x86\x87", 8, 1 },
+ { "88898A8B8C8D8E8F", "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F", 8, 1 },
+ { "9091929394959697", "\x90\x91\x92\x93\x94\x95\x96\x97", 8, 1 },
+ { "98999A9B9C9D9E9F", "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F", 8, 1 },
+ { "A0A1A2A3A4A5A6A7", "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", 8, 1 },
+ { "A8A9AAABACADAEAF", "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", 8, 1 },
+ { "B0B1B2B3B4B5B6B7", "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", 8, 1 },
+ { "B8B9BABBBCBDBEBF", "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF", 8, 1 },
+ { "C0C1C2C3C4C5C6C7", "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7", 8, 1 },
+ { "C8C9CACBCCCDCECF", "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 8, 1 },
+ { "D0D1D2D3D4D5D6D7", "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7", 8, 1 },
+ { "D8D9DADBDCDDDEDF", "\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF", 8, 1 },
+ { "E0E1E2E3E4E5E6E7", "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7", 8, 1 },
+ { "E8E9EAEBECEDEEEF", "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF", 8, 1 },
+ { "F0F1F2F3F4F5F6F7", "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7", 8, 1 },
+ { "F8F9FAFBFCFDFEFF", "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", 8, 1 },
+};
+
+int main()
+{
+ size_t i;
+ char *hex;
+ int ret;
+ uint8_t *bytes;
+ size_t len;
+
+ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
+ if (tests[i].binary == NULL) {
+ ret = k5_hex_decode(tests[i].hex, &bytes, &len);
+ assert(ret == EINVAL && bytes == NULL && len == 0);
+ continue;
+ }
+
+ ret = k5_hex_decode(tests[i].hex, &bytes, &len);
+ assert(ret == 0);
+ assert(len == tests[i].binary_len);
+ assert(memcmp(bytes, tests[i].binary, len) == 0);
+ assert(bytes[len] == 0);
+ free(bytes);
+
+ ret = k5_hex_encode((uint8_t *)tests[i].binary, tests[i].binary_len,
+ tests[i].uppercase, &hex);
+ assert(ret == 0);
+ assert(strcmp(tests[i].hex, hex) == 0);
+ free(hex);
+ }
+ return 0;
+}

View File

@ -0,0 +1,295 @@
From dd863eb4311310c23ee12961fa8e91703f29a6f5 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 22 Nov 2018 00:27:35 -0500
Subject: [PATCH] Add tests for KCM ccache type
Using a trivial Python implementation of a KCM server, run the
t_ccache.py tests against the KCM ccache type.
(cherry picked from commit f0bcb86131e385b2603ccf0f3c7d65aa3891b220)
(cherry picked from commit 5ecbe8d3ab4f53c0923a0442273bf18a9ff04fd5)
---
src/tests/kcmserver.py | 246 +++++++++++++++++++++++++++++++++++++++++
src/tests/t_ccache.py | 9 +-
2 files changed, 254 insertions(+), 1 deletion(-)
create mode 100644 src/tests/kcmserver.py
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
new file mode 100644
index 000000000..57432e5a7
--- /dev/null
+++ b/src/tests/kcmserver.py
@@ -0,0 +1,246 @@
+# This is a simple KCM test server, used to exercise the KCM ccache
+# client code. It will generally throw an uncaught exception if the
+# client sends anything unexpected, so is unsuitable for production.
+# (It also imposes no namespace or access constraints, and blocks
+# while reading requests and writing responses.)
+
+# This code knows nothing about how to marshal and unmarshal principal
+# names and credentials as is required in the KCM protocol; instead,
+# it just remembers the marshalled forms and replays them to the
+# client when asked. This works because marshalled creds and
+# principal names are always the last part of marshalled request
+# arguments, and because we don't need to implement remove_cred (which
+# would need to know how to match a cred tag against previously stored
+# credentials).
+
+# The following code is useful for debugging if anything appears to be
+# going wrong in the server, since daemon output is generally not
+# visible in Python test scripts.
+#
+# import sys, traceback
+# def ehook(etype, value, tb):
+# with open('/tmp/exception', 'w') as f:
+# traceback.print_exception(etype, value, tb, file=f)
+# sys.excepthook = ehook
+
+import select
+import socket
+import struct
+import sys
+
+caches = {}
+cache_uuidmap = {}
+defname = b'default'
+next_unique = 1
+next_uuid = 1
+
+class KCMOpcodes(object):
+ GEN_NEW = 3
+ INITIALIZE = 4
+ DESTROY = 5
+ STORE = 6
+ GET_PRINCIPAL = 8
+ GET_CRED_UUID_LIST = 9
+ GET_CRED_BY_UUID = 10
+ REMOVE_CRED = 11
+ GET_CACHE_UUID_LIST = 18
+ GET_CACHE_BY_UUID = 19
+ GET_DEFAULT_CACHE = 20
+ SET_DEFAULT_CACHE = 21
+ GET_KDC_OFFSET = 22
+ SET_KDC_OFFSET = 23
+
+
+class KRB5Errors(object):
+ KRB5_CC_END = -1765328242
+ KRB5_CC_NOSUPP = -1765328137
+ KRB5_FCC_NOFILE = -1765328189
+
+
+def make_uuid():
+ global next_uuid
+ uuid = bytes(12) + struct.pack('>L', next_uuid)
+ next_uuid = next_uuid + 1
+ return uuid
+
+
+class Cache(object):
+ def __init__(self, name):
+ self.name = name
+ self.princ = None
+ self.uuid = make_uuid()
+ self.cred_uuids = []
+ self.creds = {}
+ self.time_offset = 0
+
+
+def get_cache(name):
+ if name in caches:
+ return caches[name]
+ cache = Cache(name)
+ caches[name] = cache
+ cache_uuidmap[cache.uuid] = cache
+ return cache
+
+
+def unmarshal_name(argbytes):
+ offset = argbytes.find(b'\0')
+ return argbytes[0:offset], argbytes[offset+1:]
+
+
+def op_gen_new(argbytes):
+ # Does not actually check for uniqueness.
+ global next_unique
+ name = b'unique' + str(next_unique).encode('ascii')
+ next_unique += 1
+ return 0, name + b'\0'
+
+
+def op_initialize(argbytes):
+ name, princ = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ cache.princ = princ
+ cache.cred_uuids = []
+ cache.creds = {}
+ cache.time_offset = 0
+ return 0, b''
+
+
+def op_destroy(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ del cache_uuidmap[cache.uuid]
+ del caches[name]
+ return 0, b''
+
+
+def op_store(argbytes):
+ name, cred = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ uuid = make_uuid()
+ cache.creds[uuid] = cred
+ cache.cred_uuids.append(uuid)
+ return 0, b''
+
+
+def op_get_principal(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ if cache.princ is None:
+ return KRB5Errors.KRB5_FCC_NOFILE, b''
+ return 0, cache.princ + b'\0'
+
+
+def op_get_cred_uuid_list(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ return 0, b''.join(cache.cred_uuids)
+
+
+def op_get_cred_by_uuid(argbytes):
+ name, uuid = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ if uuid not in cache.creds:
+ return KRB5Errors.KRB5_CC_END, b''
+ return 0, cache.creds[uuid]
+
+
+def op_remove_cred(argbytes):
+ return KRB5Errors.KRB5_CC_NOSUPP, b''
+
+
+def op_get_cache_uuid_list(argbytes):
+ return 0, b''.join(cache_uuidmap.keys())
+
+
+def op_get_cache_by_uuid(argbytes):
+ uuid = argbytes
+ if uuid not in cache_uuidmap:
+ return KRB5Errors.KRB5_CC_END, b''
+ return 0, cache_uuidmap[uuid].name + b'\0'
+
+
+def op_get_default_cache(argbytes):
+ return 0, defname + b'\0'
+
+
+def op_set_default_cache(argbytes):
+ global defname
+ defname, rest = unmarshal_name(argbytes)
+ return 0, b''
+
+
+def op_get_kdc_offset(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ return 0, struct.pack('>l', cache.time_offset)
+
+
+def op_set_kdc_offset(argbytes):
+ name, obytes = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ cache.time_offset, = struct.unpack('>l', obytes)
+ return 0, b''
+
+
+ophandlers = {
+ KCMOpcodes.GEN_NEW : op_gen_new,
+ KCMOpcodes.INITIALIZE : op_initialize,
+ KCMOpcodes.DESTROY : op_destroy,
+ KCMOpcodes.STORE : op_store,
+ KCMOpcodes.GET_PRINCIPAL : op_get_principal,
+ KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list,
+ KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid,
+ KCMOpcodes.REMOVE_CRED : op_remove_cred,
+ KCMOpcodes.GET_CACHE_UUID_LIST : op_get_cache_uuid_list,
+ KCMOpcodes.GET_CACHE_BY_UUID : op_get_cache_by_uuid,
+ KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache,
+ KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache,
+ KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset,
+ KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset
+}
+
+# Read and respond to a request from the socket s.
+def service_request(s):
+ lenbytes = b''
+ while len(lenbytes) < 4:
+ lenbytes += s.recv(4 - len(lenbytes))
+ if lenbytes == b'':
+ return False
+
+ reqlen, = struct.unpack('>L', lenbytes)
+ req = b''
+ while len(req) < reqlen:
+ req += s.recv(reqlen - len(req))
+
+ majver, minver, op = struct.unpack('>BBH', req[:4])
+ argbytes = req[4:]
+ code, payload = ophandlers[op](argbytes)
+
+ # The KCM response is the code (4 bytes) and the response payload.
+ # The Heimdal IPC response is the length of the KCM response (4
+ # bytes), a status code which is essentially always 0 (4 bytes),
+ # and the KCM response.
+ kcm_response = struct.pack('>l', code) + payload
+ hipc_response = struct.pack('>LL', len(kcm_response), 0) + kcm_response
+ s.sendall(hipc_response)
+ return True
+
+
+server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+server.bind(sys.argv[1])
+server.listen(5)
+select_input = [server,]
+sys.stderr.write('starting...\n')
+sys.stderr.flush()
+
+while True:
+ iready, oready, xready = select.select(select_input, [], [])
+ for s in iready:
+ if s == server:
+ client, addr = server.accept()
+ select_input.append(client)
+ else:
+ if not service_request(s):
+ select_input.remove(s)
+ s.close()
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
index fcf1a611e..66804afa5 100755
--- a/src/tests/t_ccache.py
+++ b/src/tests/t_ccache.py
@@ -22,7 +22,10 @@
from k5test import *
-realm = K5Realm(create_host=False)
+kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm')
+conf = {'libdefaults': {'kcm_socket': kcm_socket_path,
+ 'kcm_mach_service': '-'}}
+realm = K5Realm(create_host=False, krb5_conf=conf)
keyctl = which('keyctl')
out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1)
@@ -122,6 +125,10 @@ def collection_test(realm, ccname):
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
+kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
+realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
+ 'starting...')
+collection_test(realm, 'KCM:')
if test_keyring:
def cleanup_keyring(anchor, name):
out = realm.run(['keyctl', 'list', anchor])

View File

@ -1,106 +0,0 @@
From f8b14b92cc4c82578f8fc56dd1fddebe88120769 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 3 Feb 2018 20:53:42 -0500
Subject: [PATCH] Add vector support to k5_sha256()
Add a length argument so that multiple krb5_data values can be passed
to k5_sha256(), for efficient computation of SHA-256 hashes over
concatenations of data values.
(cherry picked from commit 4f3373e8c55b3e9bdfb5b065e07214c5816c85fa)
---
src/include/k5-int.h | 4 ++--
src/lib/crypto/builtin/sha2/sha256.c | 6 ++++--
src/lib/crypto/crypto_tests/t_sha2.c | 2 +-
src/lib/crypto/openssl/sha256.c | 6 ++++--
src/lib/krb5/rcache/rc_conv.c | 2 +-
5 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 9378ae047..1c1d9783b 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -635,9 +635,9 @@ krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
#define K5_SHA256_HASHLEN (256 / 8)
-/* Write the SHA-256 hash of in to out. */
+/* Write the SHA-256 hash of in (containing n elements) to out. */
krb5_error_code
-k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN]);
+k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]);
/*
* Attempt to zero memory in a way that compilers won't optimize out.
diff --git a/src/lib/crypto/builtin/sha2/sha256.c b/src/lib/crypto/builtin/sha2/sha256.c
index 2b5cbe480..9a940b3f8 100644
--- a/src/lib/crypto/builtin/sha2/sha256.c
+++ b/src/lib/crypto/builtin/sha2/sha256.c
@@ -257,12 +257,14 @@ k5_sha256_final(void *res, SHA256_CTX *m)
}
krb5_error_code
-k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN])
+k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN])
{
SHA256_CTX ctx;
+ size_t i;
k5_sha256_init(&ctx);
- k5_sha256_update(&ctx, in->data, in->length);
+ for (i = 0; i < n; i++)
+ k5_sha256_update(&ctx, in[i].data, in[i].length);
k5_sha256_final(out, &ctx);
return 0;
}
diff --git a/src/lib/crypto/crypto_tests/t_sha2.c b/src/lib/crypto/crypto_tests/t_sha2.c
index 12f32869b..e6fa58498 100644
--- a/src/lib/crypto/crypto_tests/t_sha2.c
+++ b/src/lib/crypto/crypto_tests/t_sha2.c
@@ -125,7 +125,7 @@ hash_test(const struct krb5_hash_provider *hash, struct test *tests)
if (hash == &krb5int_hash_sha256) {
/* Try again using k5_sha256(). */
- if (k5_sha256(&iov.data, (uint8_t *)hval.data) != 0)
+ if (k5_sha256(&iov.data, 1, (uint8_t *)hval.data) != 0)
abort();
if (memcmp(hval.data, t->hash, hval.length) != 0)
abort();
diff --git a/src/lib/crypto/openssl/sha256.c b/src/lib/crypto/openssl/sha256.c
index fa095d472..0edd8b7ba 100644
--- a/src/lib/crypto/openssl/sha256.c
+++ b/src/lib/crypto/openssl/sha256.c
@@ -34,16 +34,18 @@
#include <openssl/evp.h>
krb5_error_code
-k5_sha256(const krb5_data *in, uint8_t out[K5_SHA256_HASHLEN])
+k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN])
{
EVP_MD_CTX *ctx;
+ size_t i;
int ok;
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
return ENOMEM;
ok = EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
- ok = ok && EVP_DigestUpdate(ctx, in->data, in->length);
+ for (i = 0; i < n; i++)
+ ok = ok && EVP_DigestUpdate(ctx, in[i].data, in[i].length);
ok = ok && EVP_DigestFinal_ex(ctx, out, NULL);
EVP_MD_CTX_free(ctx);
return ok ? 0 : ENOMEM;
diff --git a/src/lib/krb5/rcache/rc_conv.c b/src/lib/krb5/rcache/rc_conv.c
index 0e021f5d8..f2fe528ac 100644
--- a/src/lib/krb5/rcache/rc_conv.c
+++ b/src/lib/krb5/rcache/rc_conv.c
@@ -58,7 +58,7 @@ krb5_rc_hash_message(krb5_context context, const krb5_data *message,
*out = NULL;
/* Calculate the binary checksum. */
- retval = k5_sha256(message, cksum);
+ retval = k5_sha256(message, 1, cksum);
if (retval)
return retval;

View File

@ -0,0 +1,95 @@
From 54348bbfaec50bb72d1625c015f8e5c4cfa59e0d Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 30 Dec 2018 16:40:28 -0500
Subject: [PATCH] Address some optimized-out memset() calls
Ilja Van Sprundel reported a list of memset() calls which gcc
optimizes out. In krb_auth_su.c, use zap() to clear the password, and
remove two memset() calls when there is no password to clear. In
iakerb.c, remove an unnecessary memset() before setting the only two
fields of the IAKERB header structure. In svr_principal.c, use
krb5_free_key_keyblock_contents() instead of hand-freeing key data.
In asn1_k_encode.c, remove an unnecessary memset() of the kdc_req_hack
shell before returning.
(cherry picked from commit 1057b0befec1f1c0e9d4da5521a58496e2dc0997)
(cherry picked from commit 1dfff7202448a950c9133cdfe43d650092d930fd)
---
src/clients/ksu/krb_auth_su.c | 4 +---
src/lib/gssapi/krb5/iakerb.c | 1 -
src/lib/kadm5/srv/svr_principal.c | 10 ++--------
src/lib/krb5/asn.1/asn1_k_encode.c | 1 -
4 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c
index 7af48195c..e39685fff 100644
--- a/src/clients/ksu/krb_auth_su.c
+++ b/src/clients/ksu/krb_auth_su.c
@@ -183,21 +183,19 @@ krb5_boolean ksu_get_tgt_via_passwd(context, client, options, zero_password,
if (code ) {
com_err(prog_name, code, _("while reading password for '%s'\n"),
client_name);
- memset(password, 0, sizeof(password));
return (FALSE);
}
if ( pwsize == 0) {
fprintf(stderr, _("No password given\n"));
*zero_password = TRUE;
- memset(password, 0, sizeof(password));
return (FALSE);
}
code = krb5_get_init_creds_password(context, &creds, client, password,
krb5_prompter_posix, NULL, 0, NULL,
options);
- memset(password, 0, sizeof(password));
+ zap(password, sizeof(password));
if (code) {
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
index bb1072fe4..47c161ec9 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -262,7 +262,6 @@ iakerb_make_token(iakerb_ctx_id_t ctx,
/*
* Assemble the IAKERB-HEADER from the realm and cookie
*/
- memset(&iah, 0, sizeof(iah));
iah.target_realm = *realm;
iah.cookie = cookie;
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 21c53ece1..9ab2c5a74 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -2093,14 +2093,8 @@ static int decrypt_key_data(krb5_context context,
ret = krb5_dbe_decrypt_key_data(context, NULL, &key_data[i], &keys[i],
NULL);
if (ret) {
- for (; i >= 0; i--) {
- if (keys[i].contents) {
- memset (keys[i].contents, 0, keys[i].length);
- free( keys[i].contents );
- }
- }
-
- memset(keys, 0, n_key_data*sizeof(krb5_keyblock));
+ for (; i >= 0; i--)
+ krb5_free_keyblock_contents(context, &keys[i]);
free(keys);
return ret;
}
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 65c84be2f..81a34bac9 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -528,7 +528,6 @@ decode_kdc_req_body(const taginfo *t, const uint8_t *asn1, size_t len,
if (ret) {
free_kdc_req_body(b);
free(h.server_realm.data);
- memset(&h, 0, sizeof(h));
return ret;
}
b->server->realm = h.server_realm;

View File

@ -1,229 +0,0 @@
From 2b9e79d58b28196dba5f7d3ff2f32ca577444ddc Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 31 Mar 2018 10:43:49 -0400
Subject: [PATCH] Be more careful asking for AS key in SPAKE client
Asking for the AS key too early can result in password prompts in
situations where SPAKE won't proceed, such as when the KDC offers only
second factor types not supported by the client.
In spake_prep_questions(), decode the received message and make sure
it's a challenge with a supported group and second factor type
(SF-NONE at the moment). Save the decoded message and use it in
spake_process(). Do not retrieve the AS key at the beginning of
spake_process(); instead do so in process_challenge() after checking
the challenge group and factor types.
Move contains_sf_none() earlier in the file so that it can be used by
spake_prep_questions() without a prototype.
ticket: 8659
(cherry picked from commit f240f1b0d324312be8aa59ead7cfbe0c329ed064)
---
src/plugins/preauth/spake/spake_client.c | 111 ++++++++++++++---------
1 file changed, 66 insertions(+), 45 deletions(-)
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
index d72bd64aa..47a6ba26c 100644
--- a/src/plugins/preauth/spake/spake_client.c
+++ b/src/plugins/preauth/spake/spake_client.c
@@ -39,12 +39,26 @@
#include <krb5/clpreauth_plugin.h>
typedef struct reqstate_st {
+ krb5_pa_spake *msg; /* set in prep_questions, used in process */
krb5_keyblock *initial_key;
krb5_data *support;
krb5_data thash;
krb5_data spakeresult;
} reqstate;
+/* Return true if SF-NONE is present in factors. */
+static krb5_boolean
+contains_sf_none(krb5_spake_factor **factors)
+{
+ int i;
+
+ for (i = 0; factors != NULL && factors[i] != NULL; i++) {
+ if (factors[i]->type == SPAKE_SF_NONE)
+ return TRUE;
+ }
+ return FALSE;
+}
+
static krb5_error_code
spake_init(krb5_context context, krb5_clpreauth_moddata *moddata_out)
{
@@ -77,6 +91,7 @@ spake_request_fini(krb5_context context, krb5_clpreauth_moddata moddata,
{
reqstate *st = (reqstate *)modreq;
+ k5_free_pa_spake(context, st->msg);
krb5_free_keyblock(context, st->initial_key);
krb5_free_data(context, st->support);
krb5_free_data_contents(context, &st->thash);
@@ -92,16 +107,42 @@ spake_prep_questions(krb5_context context, krb5_clpreauth_moddata moddata,
krb5_data *enc_req, krb5_data *enc_prev_req,
krb5_pa_data *pa_data)
{
+ krb5_error_code ret;
+ groupstate *gstate = (groupstate *)moddata;
reqstate *st = (reqstate *)modreq;
+ krb5_data in_data;
+ krb5_spake_challenge *ch;
if (st == NULL)
return ENOMEM;
- if (st->initial_key == NULL && pa_data->length > 0)
+
+ /* We don't need to ask any questions to send a support message. */
+ if (pa_data->length == 0)
+ return 0;
+
+ /* Decode the incoming message, replacing any previous one in the request
+ * state. If we can't decode it, we have no questions to ask. */
+ k5_free_pa_spake(context, st->msg);
+ st->msg = NULL;
+ in_data = make_data(pa_data->contents, pa_data->length);
+ ret = decode_krb5_pa_spake(&in_data, &st->msg);
+ if (ret)
+ return (ret == ENOMEM) ? ENOMEM : 0;
+
+ if (st->msg->choice == SPAKE_MSGTYPE_CHALLENGE) {
+ ch = &st->msg->u.challenge;
+ if (!group_is_permitted(gstate, ch->group))
+ return 0;
+ /* When second factor support is implemented, we should ask questions
+ * based on the factors in the challenge. */
+ if (!contains_sf_none(ch->factors))
+ return 0;
+ /* We will need the AS key to respond to the challenge. */
cb->need_as_key(context, rock);
-
- /* When second-factor is implemented, we should ask questions based on the
- * factors in the challenge. */
-
+ } else if (st->msg->choice == SPAKE_MSGTYPE_ENCDATA) {
+ /* When second factor support is implemented, we should decrypt the
+ * encdata message and ask questions based on the factor data. */
+ }
return 0;
}
@@ -136,19 +177,6 @@ send_support(krb5_context context, groupstate *gstate, reqstate *st,
return convert_to_padata(support, pa_out);
}
-/* Return true if SF-NONE is present in factors. */
-static krb5_boolean
-contains_sf_none(krb5_spake_factor **factors)
-{
- int i;
-
- for (i = 0; factors != NULL && factors[i] != NULL; i++) {
- if (factors[i]->type == SPAKE_SF_NONE)
- return TRUE;
- }
- return FALSE;
-}
-
static krb5_error_code
process_challenge(krb5_context context, groupstate *gstate, reqstate *st,
krb5_spake_challenge *ch, const krb5_data *der_msg,
@@ -157,7 +185,7 @@ process_challenge(krb5_context context, groupstate *gstate, reqstate *st,
const krb5_data *der_req, krb5_pa_data ***pa_out)
{
krb5_error_code ret;
- krb5_keyblock *k0 = NULL, *k1 = NULL;
+ krb5_keyblock *k0 = NULL, *k1 = NULL, *as_key;
krb5_spake_factor factor;
krb5_pa_spake msg;
krb5_data *der_factor = NULL, *response;
@@ -167,8 +195,8 @@ process_challenge(krb5_context context, groupstate *gstate, reqstate *st,
enc_factor.ciphertext = empty_data();
- /* Not expected if we already computed the SPAKE result. */
- if (st->spakeresult.length != 0)
+ /* Not expected if we processed a challenge and didn't reject it. */
+ if (st->initial_key != NULL)
return KRB5KDC_ERR_PREAUTH_FAILED;
if (!group_is_permitted(gstate, ch->group)) {
@@ -193,6 +221,12 @@ process_challenge(krb5_context context, groupstate *gstate, reqstate *st,
if (!contains_sf_none(ch->factors))
return KRB5KDC_ERR_PREAUTH_FAILED;
+ ret = cb->get_as_key(context, rock, &as_key);
+ if (ret)
+ goto cleanup;
+ ret = krb5_copy_keyblock(context, as_key, &st->initial_key);
+ if (ret)
+ goto cleanup;
ret = derive_wbytes(context, ch->group, st->initial_key, &wbytes);
if (ret)
goto cleanup;
@@ -267,7 +301,7 @@ process_encdata(krb5_context context, reqstate *st, krb5_enc_data *enc,
krb5_pa_data ***pa_out)
{
/* Not expected if we haven't sent a response yet. */
- if (st->spakeresult.length == 0)
+ if (st->initial_key == NULL || st->spakeresult.length == 0)
return KRB5KDC_ERR_PREAUTH_FAILED;
/*
@@ -292,9 +326,7 @@ spake_process(krb5_context context, krb5_clpreauth_moddata moddata,
krb5_error_code ret;
groupstate *gstate = (groupstate *)moddata;
reqstate *st = (reqstate *)modreq;
- krb5_pa_spake *msg;
krb5_data in_data;
- krb5_keyblock *as_key;
if (st == NULL)
return ENOMEM;
@@ -306,34 +338,23 @@ spake_process(krb5_context context, krb5_clpreauth_moddata moddata,
return send_support(context, gstate, st, pa_out);
}
- /* We need the initial reply key to process any non-trivial message. */
- if (st->initial_key == NULL) {
- ret = cb->get_as_key(context, rock, &as_key);
- if (ret)
- return ret;
- ret = krb5_copy_keyblock(context, as_key, &st->initial_key);
- if (ret)
- return ret;
- }
-
- in_data = make_data(pa_in->contents, pa_in->length);
- ret = decode_krb5_pa_spake(&in_data, &msg);
- if (ret)
- return ret;
-
- if (msg->choice == SPAKE_MSGTYPE_CHALLENGE) {
- ret = process_challenge(context, gstate, st, &msg->u.challenge,
+ if (st->msg == NULL) {
+ /* The message failed to decode in spake_prep_questions(). */
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
+ } else if (st->msg->choice == SPAKE_MSGTYPE_CHALLENGE) {
+ in_data = make_data(pa_in->contents, pa_in->length);
+ ret = process_challenge(context, gstate, st, &st->msg->u.challenge,
&in_data, cb, rock, prompter, prompter_data,
der_req, pa_out);
- } else if (msg->choice == SPAKE_MSGTYPE_ENCDATA) {
- ret = process_encdata(context, st, &msg->u.encdata, cb, rock, prompter,
- prompter_data, der_prev_req, der_req, pa_out);
+ } else if (st->msg->choice == SPAKE_MSGTYPE_ENCDATA) {
+ ret = process_encdata(context, st, &st->msg->u.encdata, cb, rock,
+ prompter, prompter_data, der_prev_req, der_req,
+ pa_out);
} else {
/* Unexpected message type */
ret = KRB5KDC_ERR_PREAUTH_FAILED;
}
- k5_free_pa_spake(context, msg);
return ret;
}

View File

@ -1,7 +1,7 @@
From ce06474e3b12430480374f923c25bae9581fb146 Mon Sep 17 00:00:00 2001
From 0c361343839b2ff6f89f1ee9c1e01d4f05ab6ffe Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] Become FIPS-aware
Subject: [PATCH] Become FIPS-aware (with 3DES)
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
@ -10,15 +10,18 @@ ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any crypto we care about - AES is fine, for
instance.
locks), but not for any crypto we care about - which is to say that
AES is fine.
(cherry picked from commit 9f5fbf191d74cae9b28d318fff4c80d3d3e49c86)
---
src/lib/crypto/openssl/enc_provider/camellia.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/des.c | 9 +++++++++
src/lib/crypto/openssl/enc_provider/des3.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 ++++++++++++-
src/lib/crypto/openssl/hash_provider/hash_evp.c | 4 ++++
src/lib/crypto/openssl/hmac.c | 6 +++++-
5 files changed, 36 insertions(+), 2 deletions(-)
6 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 2da691329..f79679a0b 100644
@ -78,6 +81,30 @@ index a662db512..7d17d287e 100644
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
index 1c439c2cd..8be555a8d 100644
--- a/src/lib/crypto/openssl/enc_provider/des3.c
+++ b/src/lib/crypto/openssl/enc_provider/des3.c
@@ -84,6 +84,9 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 7f3c086ed..a3f2a7442 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c

View File

@ -1,536 +0,0 @@
From 2bc365f12282cdd83a191478b97f4ea0d9aa60dd Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 19 Feb 2018 21:10:09 -0500
Subject: [PATCH] Convert Python tests to Python 3
Look for python3 in configure.in and verify that we got it. Convert
test code to conform to Python 3.
ticket: 8710 (new)
(cherry picked from commit e23d24beacb73581bbf4351250f3955e6fd44361)
[rharwood@redhat.com: Context skew due to not having LMDB in tests]
---
src/Makefile.in | 1 +
src/configure.in | 6 ++--
src/kadmin/dbutil/t_tdumputil.py | 4 +--
src/tests/jsonwalker.py | 16 +++++------
src/tests/t_cve-2012-1014.py | 2 +-
src/tests/t_cve-2012-1015.py | 2 +-
src/tests/t_hostrealm.py | 4 ++-
src/tests/t_kdb.py | 11 ++++---
src/tests/t_keytab.py | 34 +++++++++++-----------
src/tests/t_mkey.py | 6 ++--
src/tests/t_otp.py | 7 +++--
src/tests/t_tabdump.py | 4 +--
src/util/Makefile.in | 1 +
src/util/k5test.py | 49 +++++++++++++++++---------------
src/util/princflags.py | 25 ++++++++--------
15 files changed, 88 insertions(+), 84 deletions(-)
diff --git a/src/Makefile.in b/src/Makefile.in
index 77beff8bc..79b8d5f98 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -533,6 +533,7 @@ runenv.py: pyrunenv.vals
clean-unix::
$(RM) runenv.py runenv.pyc pyrunenv.vals
+ $(RM) -r __pycache__
COV_BUILD= cov-build
COV_ANALYZE= cov-analyze
diff --git a/src/configure.in b/src/configure.in
index 3f45784b5..00cb297b8 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1098,15 +1098,13 @@ fi
AC_SUBST(HAVE_RUNTEST)
# For Python tests.
-AC_CHECK_PROG(PYTHON,python2,python2)
+AC_CHECK_PROG(PYTHON,python3,python3)
if text x"$PYTHON" = x; then
AC_CHECK_PROG(PYTHON,python,python)
fi
HAVE_PYTHON=no
if test x"$PYTHON" != x; then
- # k5test.py requires python 2.4 (for the subprocess module).
- # Some code needs python 2.5 (for syntax like conditional expressions).
- wantver="(sys.hexversion >= 0x2050000 and sys.hexversion < 0x3000000)"
+ wantver="(sys.hexversion >= 0x3000000)"
if "$PYTHON" -c "import sys; sys.exit(not $wantver and 1 or 0)"; then
HAVE_PYTHON=yes
fi
diff --git a/src/kadmin/dbutil/t_tdumputil.py b/src/kadmin/dbutil/t_tdumputil.py
index 52e356533..47b2aa7a3 100755
--- a/src/kadmin/dbutil/t_tdumputil.py
+++ b/src/kadmin/dbutil/t_tdumputil.py
@@ -6,8 +6,8 @@ realm = K5Realm(create_kdb=False)
def compare(s, expected, msg):
if s == expected:
return
- print 'expected:', repr(expected)
- print 'got:', repr(s)
+ print('expected:', repr(expected))
+ print('got:', repr(s))
fail(msg)
out = realm.run(['./t_tdumputil', '2', 'field1', 'field2',
diff --git a/src/tests/jsonwalker.py b/src/tests/jsonwalker.py
index 942ca2db7..7a0675e08 100644
--- a/src/tests/jsonwalker.py
+++ b/src/tests/jsonwalker.py
@@ -2,8 +2,8 @@ import sys
try:
import cjson
except ImportError:
- print "Warning: skipping audit log verification because the cjson module" \
- " is unavailable"
+ print("Warning: skipping audit log verification because the cjson module" \
+ " is unavailable")
sys.exit(0)
from collections import defaultdict
from optparse import OptionParser
@@ -22,10 +22,10 @@ class Parser(object):
result = self.parse(logs)
if len(result) != len(self.defaults):
diff = set(self.defaults.keys()).difference(result.keys())
- print 'Test failed.'
- print 'The following attributes were not set:'
+ print('Test failed.')
+ print('The following attributes were not set:')
for it in diff:
- print it
+ print(it)
sys.exit(1)
def flatten(self, defaults):
@@ -42,7 +42,7 @@ class Parser(object):
result = dict()
for path,value in self._walk(defaults):
if path in result:
- print 'Warning: attribute path %s already exists' % path
+ print('Warning: attribute path %s already exists' % path)
result[path] = value
return result
@@ -60,7 +60,7 @@ class Parser(object):
if v is not None:
dv = self.DEFAULTS[type(v)]
else:
- print 'Warning: attribute %s is set to None' % a
+ print('Warning: attribute %s is set to None' % a)
continue
# by now we have default value
if v != dv:
@@ -96,7 +96,7 @@ if __name__ == '__main__':
content.append(cjson.decode(l.rstrip()))
f.close()
else:
- print 'Input file in jason format is required'
+ print('Input file in jason format is required')
exit()
defaults = None
diff --git a/src/tests/t_cve-2012-1014.py b/src/tests/t_cve-2012-1014.py
index dcff95f6e..8447e0ee7 100755
--- a/src/tests/t_cve-2012-1014.py
+++ b/src/tests/t_cve-2012-1014.py
@@ -20,7 +20,7 @@ x2 = base64.b16decode('A44F304DA007030500FEDCBA90A10E30' +
'01')
for x in range(11, 128):
- s.sendto(''.join([x1, chr(x), x2]), a)
+ s.sendto(x1 + bytes([x]) + x2, a)
# Make sure kinit still works.
diff --git a/src/tests/t_cve-2012-1015.py b/src/tests/t_cve-2012-1015.py
index 28b1e619b..ae5678cac 100755
--- a/src/tests/t_cve-2012-1015.py
+++ b/src/tests/t_cve-2012-1015.py
@@ -27,7 +27,7 @@ x1 = base64.b16decode('6A81A030819DA103020105A20302010A' +
x2 = base64.b16decode('A8083006020106020112')
for x in range(0, 128):
- s.sendto(''.join([x1, chr(x), x2]), a)
+ s.sendto(x1 + bytes([x]) + x2, a)
# Make sure kinit still works.
diff --git a/src/tests/t_hostrealm.py b/src/tests/t_hostrealm.py
index 256ba2a38..beea6f3bc 100755
--- a/src/tests/t_hostrealm.py
+++ b/src/tests/t_hostrealm.py
@@ -119,7 +119,9 @@ testd(realm, 'KRBTEST.COM', 'default_realm profile', env=notest2)
# see the first. Remove the profile default_realm setting to expose
# this behavior.
remove_default = {'libdefaults': {'default_realm': None}}
-nodefault_conf = dict(disable_conf.items() + remove_default.items())
+# Python 3.5+: nodefault_conf = {**disable_conf, **remove_default}
+nodefault_conf = dict(list(disable_conf.items()) +
+ list(remove_default.items()))
nodefault = realm.special_env('nodefault', False, krb5_conf=nodefault_conf)
testd(realm, 'one', 'default_realm test1', env=nodefault)
diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py
index 983cd93c8..42237f7a1 100755
--- a/src/tests/t_kdb.py
+++ b/src/tests/t_kdb.py
@@ -1,6 +1,5 @@
from k5test import *
import time
-from itertools import imap
# Run kdbtest against the BDB module.
realm = K5Realm(create_kdb=False)
@@ -51,7 +50,7 @@ else:
def slap_add(ldif):
proc = subprocess.Popen([slapadd, '-b', 'cn=config', '-F', slapd_conf],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT, universal_newlines=True)
(out, dummy) = proc.communicate(ldif)
output(out)
return proc.wait()
@@ -98,7 +97,7 @@ if slap_add('include: file://%s\n' % schema) != 0:
ldap_homes = ['/etc/ldap', '/etc/openldap', '/usr/local/etc/openldap',
'/usr/local/etc/ldap']
local_schema_path = '/schema/core.ldif'
-core_schema = next((i for i in imap(lambda x:x+local_schema_path, ldap_homes)
+core_schema = next((i for i in map(lambda x:x+local_schema_path, ldap_homes)
if os.path.isfile(i)), None)
if core_schema:
if slap_add('include: file://%s\n' % core_schema) != 0:
@@ -114,7 +113,7 @@ atexit.register(kill_slapd)
out = open(slapd_out, 'w')
subprocess.call([slapd, '-h', ldap_uri, '-F', slapd_conf], stdout=out,
- stderr=out)
+ stderr=out, universal_newlines=True)
out.close()
pidf = open(slapd_pidfile, 'r')
slapd_pid = int(pidf.read())
@@ -158,7 +157,7 @@ def ldap_search(args):
proc = subprocess.Popen([ldapsearch, '-H', ldap_uri, '-b', top_dn,
'-D', admin_dn, '-w', admin_pw, args],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT, universal_newlines=True)
(out, dummy) = proc.communicate()
return out
@@ -166,7 +165,7 @@ def ldap_modify(ldif, args=[]):
proc = subprocess.Popen([ldapmodify, '-H', ldap_uri, '-D', admin_dn,
'-x', '-w', admin_pw] + args,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT, universal_newlines=True)
(out, dummy) = proc.communicate(ldif)
output(out)
diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py
index 228c36334..8a17ae2eb 100755
--- a/src/tests/t_keytab.py
+++ b/src/tests/t_keytab.py
@@ -90,36 +90,36 @@ test_key_rotate(realm, princ, 2)
# Test that klist -k can read a keytab entry without a 32-bit kvno and
# reports the 8-bit key version.
-record = '\x00\x01' # principal component count
-record += '\x00\x0bKRBTEST.COM' # realm
-record += '\x00\x04user' # principal component
-record += '\x00\x00\x00\x01' # name type (NT-PRINCIPAL)
-record += '\x54\xf7\x4d\x35' # timestamp
-record += '\x02' # key version
-record += '\x00\x12' # enctype
-record += '\x00\x20' # key length
-record += '\x00' * 32 # key bytes
-f = open(realm.keytab, 'w')
-f.write('\x05\x02\x00\x00\x00' + chr(len(record)))
+record = b'\x00\x01' # principal component count
+record += b'\x00\x0bKRBTEST.COM' # realm
+record += b'\x00\x04user' # principal component
+record += b'\x00\x00\x00\x01' # name type (NT-PRINCIPAL)
+record += b'\x54\xf7\x4d\x35' # timestamp
+record += b'\x02' # key version
+record += b'\x00\x12' # enctype
+record += b'\x00\x20' # key length
+record += b'\x00' * 32 # key bytes
+f = open(realm.keytab, 'wb')
+f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record)]))
f.write(record)
f.close()
msg = ' 2 %s' % realm.user_princ
out = realm.run([klist, '-k'], expected_msg=msg)
# Make sure zero-fill isn't treated as a 32-bit kvno.
-f = open(realm.keytab, 'w')
-f.write('\x05\x02\x00\x00\x00' + chr(len(record) + 4))
+f = open(realm.keytab, 'wb')
+f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record) + 4]))
f.write(record)
-f.write('\x00\x00\x00\x00')
+f.write(b'\x00\x00\x00\x00')
f.close()
msg = ' 2 %s' % realm.user_princ
out = realm.run([klist, '-k'], expected_msg=msg)
# Make sure a hand-crafted 32-bit kvno is recognized.
-f = open(realm.keytab, 'w')
-f.write('\x05\x02\x00\x00\x00' + chr(len(record) + 4))
+f = open(realm.keytab, 'wb')
+f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record) + 4]))
f.write(record)
-f.write('\x00\x00\x00\x03')
+f.write(b'\x00\x00\x00\x03')
f.close()
msg = ' 3 %s' % realm.user_princ
out = realm.run([klist, '-k'], expected_msg=msg)
diff --git a/src/tests/t_mkey.py b/src/tests/t_mkey.py
index 48a533059..cbc830235 100755
--- a/src/tests/t_mkey.py
+++ b/src/tests/t_mkey.py
@@ -296,10 +296,10 @@ realm.stop()
# 2. list_mkeys displays the same list as for a post-1.7 KDB.
dumpfile = os.path.join(srctop, 'tests', 'dumpfiles', 'dump.16')
os.remove(stash_file)
-f = open(stash_file, 'w')
+f = open(stash_file, 'wb')
f.write(struct.pack('=HL24s', 16, 24,
- '\xF8\x3E\xFB\xBA\x6D\x80\xD9\x54\xE5\x5D\xF2\xE0'
- '\x94\xAD\x6D\x86\xB5\x16\x37\xEC\x7C\x8A\xBC\x86'))
+ b'\xF8\x3E\xFB\xBA\x6D\x80\xD9\x54\xE5\x5D\xF2\xE0'
+ b'\x94\xAD\x6D\x86\xB5\x16\x37\xEC\x7C\x8A\xBC\x86'))
f.close()
realm.run([kdb5_util, 'load', dumpfile])
nprincs = len(realm.run([kadminl, 'listprincs']).splitlines())
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
index 0fd35d576..617a8ecf5 100755
--- a/src/tests/t_otp.py
+++ b/src/tests/t_otp.py
@@ -29,8 +29,8 @@
#
from k5test import *
-from Queue import Empty
-import StringIO
+from queue import Empty
+from io import StringIO
import struct
try:
@@ -120,7 +120,8 @@ class UnixRadiusDaemon(RadiusDaemon):
sock.listen(1)
return (sock, addr)
- def recvRequest(self, (sock, addr)):
+ def recvRequest(self, sock_and_addr):
+ sock, addr = sock_and_addr
conn = sock.accept()[0]
sock.close()
os.remove(addr)
diff --git a/src/tests/t_tabdump.py b/src/tests/t_tabdump.py
index 2a86136dd..49531bf49 100755
--- a/src/tests/t_tabdump.py
+++ b/src/tests/t_tabdump.py
@@ -1,10 +1,10 @@
from k5test import *
import csv
-import StringIO
+from io import StringIO
def tab_csv(s):
- io = StringIO.StringIO(s)
+ io = StringIO(s)
return list(csv.DictReader(io, dialect=csv.excel_tab))
diff --git a/src/util/Makefile.in b/src/util/Makefile.in
index 2611581c1..19a6bd312 100644
--- a/src/util/Makefile.in
+++ b/src/util/Makefile.in
@@ -26,3 +26,4 @@ install:
clean-unix::
$(RM) *.pyc
+ $(RM) -r __pycache__
diff --git a/src/util/k5test.py b/src/util/k5test.py
index bc32877a7..81fac3063 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -380,16 +380,16 @@ import imp
def fail(msg):
"""Print a message and exit with failure."""
global _current_pass
- print "*** Failure:", msg
+ print("*** Failure:", msg)
if _last_mark:
- print "*** Last mark: %s" % _last_mark
+ print("*** Last mark: %s" % _last_mark)
if _last_cmd:
- print "*** Last command (#%d): %s" % (_cmd_index - 1, _last_cmd)
+ print("*** Last command (#%d): %s" % (_cmd_index - 1, _last_cmd))
if _last_cmd_output:
- print "*** Output of last command:"
+ print("*** Output of last command:")
sys.stdout.write(_last_cmd_output)
if _current_pass:
- print "*** Failed in test pass:", _current_pass
+ print("*** Failed in test pass:", _current_pass)
sys.exit(1)
@@ -465,15 +465,16 @@ def _onexit():
if not verbose:
testlogfile = os.path.join(os.getcwd(), 'testlog')
utildir = os.path.join(srctop, 'util')
- print 'For details, see: %s' % testlogfile
- print 'Or re-run this test script with the -v flag:'
- print ' cd %s' % os.getcwd()
- print ' PYTHONPATH=%s %s %s -v' % \
- (utildir, sys.executable, sys.argv[0])
- print
- print 'Use --debug=NUM to run a command under a debugger. Use'
- print '--stop-after=NUM to stop after a daemon is started in order to'
- print 'attach to it with a debugger. Use --help to see other options.'
+ print('For details, see: %s' % testlogfile)
+ print('Or re-run this test script with the -v flag:')
+ print(' cd %s' % os.getcwd())
+ print(' PYTHONPATH=%s %s %s -v' %
+ (utildir, sys.executable, sys.argv[0]))
+ print()
+ print('Use --debug=NUM to run a command under a debugger. Use')
+ print('--stop-after=NUM to stop after a daemon is started in order to')
+ print('attach to it with a debugger. Use --help to see other')
+ print('options.')
def _onsigint(signum, frame):
@@ -523,8 +524,8 @@ def _get_hostname():
hostname = socket.gethostname()
try:
ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
- except socket.gaierror, (error, errstr):
- fail('Local hostname "%s" does not resolve: %s.' % (hostname, errstr))
+ except socket.gaierror as e:
+ fail('Local hostname "%s" does not resolve: %s.' % (hostname, e[1]))
(family, socktype, proto, canonname, sockaddr) = ai[0]
try:
name = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
@@ -594,7 +595,7 @@ def _match_cmdnum(cmdnum, ind):
def _build_env():
global buildtop, runenv
env = os.environ.copy()
- for (k, v) in runenv.env.iteritems():
+ for (k, v) in runenv.env.items():
if v.find('./') == 0:
env[k] = os.path.join(buildtop, v)
else:
@@ -704,7 +705,8 @@ def _run_cmd(args, env, input=None, expected_code=0, expected_msg=None,
# Run the command and log the result, folding stderr into stdout.
proc = subprocess.Popen(args, stdin=infile, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, env=env)
+ stderr=subprocess.STDOUT, env=env,
+ universal_newlines=True)
(outdata, dummy_errdata) = proc.communicate(input)
_last_cmd_output = outdata
code = proc.returncode
@@ -734,10 +736,10 @@ def _debug_cmd(args, env, input):
(_cmd_index, _shell_equiv(args)), True)
if input:
print
- print '*** Enter the following input when appropriate:'
- print
- print input
- print
+ print('*** Enter the following input when appropriate:')
+ print()
+ print(input)
+ print()
code = subprocess.call(args, env=env)
output('*** [%d] Completed in debugger with return code %d\n' %
(_cmd_index, code))
@@ -765,7 +767,8 @@ def _start_daemon(args, env, sentinel):
# Start the daemon and look for the sentinel in stdout or stderr.
proc = subprocess.Popen(args, stdin=null_input, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, env=env)
+ stderr=subprocess.STDOUT, env=env,
+ universal_newlines=True)
_last_cmd_output = ''
while True:
line = proc.stdout.readline()
diff --git a/src/util/princflags.py b/src/util/princflags.py
index f568dd2f1..f645e86e4 100644
--- a/src/util/princflags.py
+++ b/src/util/princflags.py
@@ -1,5 +1,4 @@
import re
-import string
# Module for translating KDB principal flags between string and
# integer forms.
@@ -81,7 +80,7 @@ _prefixlen = len(_prefix)
_flagnames = {}
# Translation table to map hyphens to underscores
-_squash = string.maketrans('-', '_')
+_squash = str.maketrans('-', '_')
# Combined input-to-flag lookup table, to be filled in by
# _setup_tables()
@@ -176,7 +175,7 @@ def flagnum2str(n):
# Return a list of flag names from a flag word.
def flags2namelist(flags):
a = []
- for n in xrange(32):
+ for n in range(32):
if flags & (1 << n):
a.append(flagnum2str(n))
return a
@@ -225,21 +224,21 @@ def speclist2mask(s):
# Print C table of input flag specifiers for lib/kadm5/str_conv.c.
def _print_ftbl():
- print 'static const struct flag_table_row ftbl[] = {'
- a = sorted(pflags.items(), key=lambda (k, v): (v.flag, -v.invert, k))
+ print('static const struct flag_table_row ftbl[] = {')
+ a = sorted(pflags.items(), key=lambda k, v: (v.flag, -v.invert, k))
for k, v in a:
s1 = ' {"%s",' % k
s2 = '%-31s KRB5_KDB_%s,' % (s1, v.flagname())
- print '%-63s %d},' % (s2, 1 if v.invert else 0)
+ print('%-63s %d},' % (s2, 1 if v.invert else 0))
- print '};'
- print '#define NFTBL (sizeof(ftbl) / sizeof(ftbl[0]))'
+ print('};')
+ print('#define NFTBL (sizeof(ftbl) / sizeof(ftbl[0]))')
# Print C table of output flag names for lib/kadm5/str_conv.c.
def _print_outflags():
- print 'static const char *outflags[] = {'
- for i in xrange(32):
+ print('static const char *outflags[] = {')
+ for i in range(32):
flag = 1 << i
if flag > max(_flagnames.keys()):
break
@@ -247,10 +246,10 @@ def _print_outflags():
s = ' "%s",' % _flagnames[flag]
except KeyError:
s = ' NULL,'
- print '%-32s/* 0x%08x */' % (s, flag)
+ print('%-32s/* 0x%08x */' % (s, flag))
- print '};'
- print '#define NOUTFLAGS (sizeof(outflags) / sizeof(outflags[0]))'
+ print('};')
+ print('#define NOUTFLAGS (sizeof(outflags) / sizeof(outflags[0]))')
# Print out C tables to insert into lib/kadm5/str_conv.c.

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
From 3bfe632c7011c335362d78356232507d9ee26f73 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 14 Mar 2018 14:31:22 -0400
Subject: [PATCH] Exit with status 0 from kadmind
Typically, 0 denotes successful exit. In particular, init systems
will complain if another different value is returned. This presents a
problem for automated installation jobs which want to restart kadmind.
`service kadmin stop` typically sends SIGTERM, which is caught by
verto and passed to our handler. Besides cleanup, we then call
verto_break(), which causes the verto_run() event loop to return. The
weird return code has been present since the addition of the kadmin
code, which used a similar event model for signals.
(cherry picked from commit f970ad412aca36f8a7d3addb1cd4026ed22e5592)
---
src/kadmin/server/ovsec_kadmd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index aac4d4ffd..0a28b2384 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -559,5 +559,5 @@ main(int argc, char *argv[])
krb5_klog_close(context);
krb5_free_context(context);
- exit(2);
+ exit(0);
}

View File

@ -1,816 +0,0 @@
From 1d0c0db7755076834519fd02c271a78bbf26bb19 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 3 Jul 2018 01:20:50 -0400
Subject: [PATCH] Explicitly look for python2 in configure.in
The executable "python" has traditionally been Python 2, but is
becoming more ambiguous as operating systems transition towards Python
3. Look for "python2" in the path in preference to "python", and
check that what we found isn't Python 3.
Remove the "#!/usr/bin/python" headers at the start of Python test
scripts since we run them explicitly under python, not as executables.
Execute paste-kdcproxy.py via sys.executable in t_proxy.py so that it
doesn't need a #!/usr/bin/python header.
ticket: 8709 (new)
(cherry picked from commit 2bd410ecdb366083fe9b4e5f6ac4b741b624230b)
---
src/appl/gss-sample/t_gss_sample.py | 2 --
src/appl/user_user/t_user2user.py | 1 -
src/configure.in | 9 ++++++---
src/kadmin/dbutil/t_tdumputil.py | 2 --
src/kdc/t_bigreply.py | 1 -
src/kdc/t_emptytgt.py | 1 -
src/kdc/t_workers.py | 1 -
src/lib/kdb/t_stringattr.py | 1 -
src/lib/krad/t_daemon.py | 2 --
src/lib/krb5/ccache/t_cccol.py | 1 -
src/lib/krb5/krb/t_expire_warn.py | 2 --
src/lib/krb5/krb/t_in_ccache_patypes.py | 2 --
src/lib/krb5/krb/t_vfy_increds.py | 2 --
src/lib/krb5/os/t_discover_uri.py | 1 -
src/tests/gssapi/t_authind.py | 1 -
src/tests/gssapi/t_ccselect.py | 2 --
src/tests/gssapi/t_client_keytab.py | 1 -
src/tests/gssapi/t_enctypes.py | 1 -
src/tests/gssapi/t_export_cred.py | 1 -
src/tests/gssapi/t_gssapi.py | 1 -
src/tests/gssapi/t_s4u.py | 1 -
src/tests/jsonwalker.py | 2 --
src/tests/t_audit.py | 1 -
src/tests/t_authdata.py | 1 -
src/tests/t_bogus_kdc_req.py | 2 --
src/tests/t_ccache.py | 2 --
src/tests/t_certauth.py | 1 -
src/tests/t_changepw.py | 1 -
src/tests/t_crossrealm.py | 2 --
src/tests/t_cve-2012-1014.py | 2 --
src/tests/t_cve-2012-1015.py | 2 --
src/tests/t_cve-2013-1416.py | 2 --
src/tests/t_cve-2013-1417.py | 2 --
src/tests/t_dump.py | 1 -
src/tests/t_errmsg.py | 1 -
src/tests/t_etype_info.py | 1 -
src/tests/t_general.py | 1 -
src/tests/t_hooks.py | 1 -
src/tests/t_hostrealm.py | 1 -
src/tests/t_iprop.py | 2 --
src/tests/t_kadm5_auth.py | 1 -
src/tests/t_kadm5_hook.py | 1 -
src/tests/t_kadmin_acl.py | 1 -
src/tests/t_kadmin_parsing.py | 1 -
src/tests/t_kdb.py | 1 -
src/tests/t_kdb_locking.py | 2 --
src/tests/t_kdc_log.py | 2 --
src/tests/t_kdcpolicy.py | 1 -
src/tests/t_keydata.py | 1 -
src/tests/t_keyrollover.py | 1 -
src/tests/t_keytab.py | 1 -
src/tests/t_kprop.py | 1 -
src/tests/t_localauth.py | 1 -
src/tests/t_mkey.py | 1 -
src/tests/t_otp.py | 2 --
src/tests/t_pkinit.py | 1 -
src/tests/t_policy.py | 1 -
src/tests/t_preauth.py | 1 -
src/tests/t_princflags.py | 1 -
src/tests/t_proxy.py | 4 ++--
src/tests/t_pwqual.py | 1 -
src/tests/t_rdreq.py | 1 -
src/tests/t_referral.py | 1 -
src/tests/t_renew.py | 1 -
src/tests/t_renprinc.py | 2 --
src/tests/t_salt.py | 1 -
src/tests/t_sesskeynego.py | 1 -
src/tests/t_skew.py | 1 -
src/tests/t_sn2princ.py | 1 -
src/tests/t_spake.py | 1 -
src/tests/t_stringattr.py | 2 --
src/tests/t_tabdump.py | 1 -
src/tests/t_unlockiter.py | 1 -
src/tests/t_y2038.py | 1 -
src/util/paste-kdcproxy.py | 1 -
75 files changed, 8 insertions(+), 99 deletions(-)
diff --git a/src/appl/gss-sample/t_gss_sample.py b/src/appl/gss-sample/t_gss_sample.py
index 0299e4590..2f537823a 100755
--- a/src/appl/gss-sample/t_gss_sample.py
+++ b/src/appl/gss-sample/t_gss_sample.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2010 by the Massachusetts Institute of Technology.
# All rights reserved.
#
diff --git a/src/appl/user_user/t_user2user.py b/src/appl/user_user/t_user2user.py
index 2a7d03f8d..2c054f181 100755
--- a/src/appl/user_user/t_user2user.py
+++ b/src/appl/user_user/t_user2user.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# If uuserver is not compiled under -DDEBUG, then set to 0
diff --git a/src/configure.in b/src/configure.in
index 08c63beca..3f45784b5 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1098,13 +1098,16 @@ fi
AC_SUBST(HAVE_RUNTEST)
# For Python tests.
-AC_CHECK_PROG(PYTHON,python,python)
+AC_CHECK_PROG(PYTHON,python2,python2)
+if text x"$PYTHON" = x; then
+ AC_CHECK_PROG(PYTHON,python,python)
+fi
HAVE_PYTHON=no
if test x"$PYTHON" != x; then
# k5test.py requires python 2.4 (for the subprocess module).
# Some code needs python 2.5 (for syntax like conditional expressions).
- vercheck="import sys;sys.exit((sys.hexversion < 0x2050000) and 1 or 0)"
- if python -c "$vercheck"; then
+ wantver="(sys.hexversion >= 0x2050000 and sys.hexversion < 0x3000000)"
+ if "$PYTHON" -c "import sys; sys.exit(not $wantver and 1 or 0)"; then
HAVE_PYTHON=yes
fi
fi
diff --git a/src/kadmin/dbutil/t_tdumputil.py b/src/kadmin/dbutil/t_tdumputil.py
index 5d7ac38d2..52e356533 100755
--- a/src/kadmin/dbutil/t_tdumputil.py
+++ b/src/kadmin/dbutil/t_tdumputil.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from k5test import *
from subprocess import *
diff --git a/src/kdc/t_bigreply.py b/src/kdc/t_bigreply.py
index 6bc9a8fe0..b6300154f 100644
--- a/src/kdc/t_bigreply.py
+++ b/src/kdc/t_bigreply.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Set the maximum UDP reply size very low, so that all replies go
diff --git a/src/kdc/t_emptytgt.py b/src/kdc/t_emptytgt.py
index 2d0432e33..c601c010c 100755
--- a/src/kdc/t_emptytgt.py
+++ b/src/kdc/t_emptytgt.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(create_host=False)
diff --git a/src/kdc/t_workers.py b/src/kdc/t_workers.py
index 6dd4f6805..8de3f34d9 100755
--- a/src/kdc/t_workers.py
+++ b/src/kdc/t_workers.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(start_kdc=False, create_host=False)
diff --git a/src/lib/kdb/t_stringattr.py b/src/lib/kdb/t_stringattr.py
index 085e179e4..93e2b0c01 100755
--- a/src/lib/kdb/t_stringattr.py
+++ b/src/lib/kdb/t_stringattr.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(create_kdb=False)
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
index dcda0050b..7d7a5d0c8 100755
--- a/src/lib/krad/t_daemon.py
+++ b/src/lib/krad/t_daemon.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-#
# Copyright 2013 Red Hat, Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
diff --git a/src/lib/krb5/ccache/t_cccol.py b/src/lib/krb5/ccache/t_cccol.py
index f7f178564..1467512e2 100755
--- a/src/lib/krb5/ccache/t_cccol.py
+++ b/src/lib/krb5/ccache/t_cccol.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(create_kdb=False)
diff --git a/src/lib/krb5/krb/t_expire_warn.py b/src/lib/krb5/krb/t_expire_warn.py
index aed39e399..781f2728a 100755
--- a/src/lib/krb5/krb/t_expire_warn.py
+++ b/src/lib/krb5/krb/t_expire_warn.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2010 by the Massachusetts Institute of Technology.
# All rights reserved.
#
diff --git a/src/lib/krb5/krb/t_in_ccache_patypes.py b/src/lib/krb5/krb/t_in_ccache_patypes.py
index c04234064..b2812688c 100755
--- a/src/lib/krb5/krb/t_in_ccache_patypes.py
+++ b/src/lib/krb5/krb/t_in_ccache_patypes.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2010,2012 by the Massachusetts Institute of Technology.
# All rights reserved.
#
diff --git a/src/lib/krb5/krb/t_vfy_increds.py b/src/lib/krb5/krb/t_vfy_increds.py
index c820cc690..b899308a8 100755
--- a/src/lib/krb5/krb/t_vfy_increds.py
+++ b/src/lib/krb5/krb/t_vfy_increds.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2011 by the Massachusetts Institute of Technology.
# All rights reserved.
#
diff --git a/src/lib/krb5/os/t_discover_uri.py b/src/lib/krb5/os/t_discover_uri.py
index 278f98371..87bac1792 100644
--- a/src/lib/krb5/os/t_discover_uri.py
+++ b/src/lib/krb5/os/t_discover_uri.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
entries = ('URI _kerberos.TEST krb5srv::kkdcp:https://kdc1 1 1\n',
diff --git a/src/tests/gssapi/t_authind.py b/src/tests/gssapi/t_authind.py
index 84793beb6..af1741a23 100644
--- a/src/tests/gssapi/t_authind.py
+++ b/src/tests/gssapi/t_authind.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Test authentication indicators. Load the test preauth module so we
diff --git a/src/tests/gssapi/t_ccselect.py b/src/tests/gssapi/t_ccselect.py
index 3503f9269..cd62da231 100755
--- a/src/tests/gssapi/t_ccselect.py
+++ b/src/tests/gssapi/t_ccselect.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2011 by the Massachusetts Institute of Technology.
# All rights reserved.
diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py
index 2da87f45b..e474a27c7 100755
--- a/src/tests/gssapi/t_client_keytab.py
+++ b/src/tests/gssapi/t_client_keytab.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Set up a basic realm and a client keytab containing two user principals.
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index f513db2b5..ee43ff028 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Define some convenience abbreviations for enctypes we will see in
diff --git a/src/tests/gssapi/t_export_cred.py b/src/tests/gssapi/t_export_cred.py
index b98962788..89167bcc5 100755
--- a/src/tests/gssapi/t_export_cred.py
+++ b/src/tests/gssapi/t_export_cred.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Test gss_export_cred and gss_import_cred for initiator creds,
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
index 6da5fceff..a7dda20fb 100755
--- a/src/tests/gssapi/t_gssapi.py
+++ b/src/tests/gssapi/t_gssapi.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Test krb5 negotiation under SPNEGO for all enctype configurations. Also
diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py
index e4cd68469..fc9d9e8a4 100755
--- a/src/tests/gssapi/t_s4u.py
+++ b/src/tests/gssapi/t_s4u.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(create_host=False, get_creds=False)
diff --git a/src/tests/jsonwalker.py b/src/tests/jsonwalker.py
index 265c69c70..942ca2db7 100644
--- a/src/tests/jsonwalker.py
+++ b/src/tests/jsonwalker.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import sys
try:
import cjson
diff --git a/src/tests/t_audit.py b/src/tests/t_audit.py
index 00e96bfea..0f880edb2 100755
--- a/src/tests/t_audit.py
+++ b/src/tests/t_audit.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
conf = {'plugins': {'audit': {
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
index 8a577b4b1..5cff80348 100644
--- a/src/tests/t_authdata.py
+++ b/src/tests/t_authdata.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Load the sample KDC authdata module.
diff --git a/src/tests/t_bogus_kdc_req.py b/src/tests/t_bogus_kdc_req.py
index b6208ca68..a101c0e10 100755
--- a/src/tests/t_bogus_kdc_req.py
+++ b/src/tests/t_bogus_kdc_req.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import base64
import socket
from k5test import *
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
index 61d549b7b..a913eb025 100755
--- a/src/tests/t_ccache.py
+++ b/src/tests/t_ccache.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2011 by the Massachusetts Institute of Technology.
# All rights reserved.
diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py
index e64a57b0d..9c7094525 100644
--- a/src/tests/t_certauth.py
+++ b/src/tests/t_certauth.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Skip this test if pkinit wasn't built.
diff --git a/src/tests/t_changepw.py b/src/tests/t_changepw.py
index 37fe4fce1..211cda6c3 100755
--- a/src/tests/t_changepw.py
+++ b/src/tests/t_changepw.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# This file is intended to cover any password-changing mechanism. For
diff --git a/src/tests/t_crossrealm.py b/src/tests/t_crossrealm.py
index 4d595dca6..09028bfa7 100755
--- a/src/tests/t_crossrealm.py
+++ b/src/tests/t_crossrealm.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2011 by the Massachusetts Institute of Technology.
# All rights reserved.
#
diff --git a/src/tests/t_cve-2012-1014.py b/src/tests/t_cve-2012-1014.py
index e02162d6c..dcff95f6e 100755
--- a/src/tests/t_cve-2012-1014.py
+++ b/src/tests/t_cve-2012-1014.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import base64
import socket
from k5test import *
diff --git a/src/tests/t_cve-2012-1015.py b/src/tests/t_cve-2012-1015.py
index e00c4dc90..28b1e619b 100755
--- a/src/tests/t_cve-2012-1015.py
+++ b/src/tests/t_cve-2012-1015.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import base64
import socket
from k5test import *
diff --git a/src/tests/t_cve-2013-1416.py b/src/tests/t_cve-2013-1416.py
index 94fb6d5ef..8c4391a86 100755
--- a/src/tests/t_cve-2013-1416.py
+++ b/src/tests/t_cve-2013-1416.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from k5test import *
realm = K5Realm()
diff --git a/src/tests/t_cve-2013-1417.py b/src/tests/t_cve-2013-1417.py
index c26930a30..ce47d21ca 100755
--- a/src/tests/t_cve-2013-1417.py
+++ b/src/tests/t_cve-2013-1417.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from k5test import *
realm = K5Realm(realm='TEST')
diff --git a/src/tests/t_dump.py b/src/tests/t_dump.py
index 8a9462bd8..2cfeada6c 100755
--- a/src/tests/t_dump.py
+++ b/src/tests/t_dump.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
from filecmp import cmp
diff --git a/src/tests/t_errmsg.py b/src/tests/t_errmsg.py
index c9ae6637f..4aacf4e0a 100755
--- a/src/tests/t_errmsg.py
+++ b/src/tests/t_errmsg.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(create_kdb=False)
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
index b2eb0f7af..b12fb53c8 100644
--- a/src/tests/t_etype_info.py
+++ b/src/tests/t_etype_info.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac des-cbc-crc:afs3'
diff --git a/src/tests/t_general.py b/src/tests/t_general.py
index 91ad0cb8a..96ba8a4b0 100755
--- a/src/tests/t_general.py
+++ b/src/tests/t_general.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
for realm in multipass_realms(create_host=False):
diff --git a/src/tests/t_hooks.py b/src/tests/t_hooks.py
index 58dff3ae7..4fd3822e8 100755
--- a/src/tests/t_hooks.py
+++ b/src/tests/t_hooks.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Test that KDC send and recv hooks work correctly.
diff --git a/src/tests/t_hostrealm.py b/src/tests/t_hostrealm.py
index 224c067ef..256ba2a38 100755
--- a/src/tests/t_hostrealm.py
+++ b/src/tests/t_hostrealm.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
plugin = os.path.join(buildtop, "plugins", "hostrealm", "test",
diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py
index 8e23cd5de..9cbeb3e68 100755
--- a/src/tests/t_iprop.py
+++ b/src/tests/t_iprop.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import os
import re
diff --git a/src/tests/t_kadm5_auth.py b/src/tests/t_kadm5_auth.py
index ba4ab8ef1..6e0f42b08 100644
--- a/src/tests/t_kadm5_auth.py
+++ b/src/tests/t_kadm5_auth.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Create a realm with the welcomer and bouncer kadm5_auth test modules
diff --git a/src/tests/t_kadm5_hook.py b/src/tests/t_kadm5_hook.py
index c1c8c9419..32fab781d 100755
--- a/src/tests/t_kadm5_hook.py
+++ b/src/tests/t_kadm5_hook.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
plugin = os.path.join(buildtop, "plugins", "kadm5_hook", "test",
diff --git a/src/tests/t_kadmin_acl.py b/src/tests/t_kadmin_acl.py
index 42bdf423c..01a3eda29 100755
--- a/src/tests/t_kadmin_acl.py
+++ b/src/tests/t_kadmin_acl.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import os
diff --git a/src/tests/t_kadmin_parsing.py b/src/tests/t_kadmin_parsing.py
index 8de387c64..bebb01488 100644
--- a/src/tests/t_kadmin_parsing.py
+++ b/src/tests/t_kadmin_parsing.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# This file contains tests for kadmin command parsing. Principal
diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py
index 6e563b103..983cd93c8 100755
--- a/src/tests/t_kdb.py
+++ b/src/tests/t_kdb.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import time
from itertools import imap
diff --git a/src/tests/t_kdb_locking.py b/src/tests/t_kdb_locking.py
index aac0a220f..b5afd6d23 100755
--- a/src/tests/t_kdb_locking.py
+++ b/src/tests/t_kdb_locking.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# This is a regression test for
# https://bugzilla.redhat.com/show_bug.cgi?id=586032 .
#
diff --git a/src/tests/t_kdc_log.py b/src/tests/t_kdc_log.py
index 8ddb7691b..1b14828de 100755
--- a/src/tests/t_kdc_log.py
+++ b/src/tests/t_kdc_log.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from k5test import *
# Make a TGS request with an expired ticket.
diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py
index 5b198bb43..a44adfdb5 100644
--- a/src/tests/t_kdcpolicy.py
+++ b/src/tests/t_kdcpolicy.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
from datetime import datetime
import re
diff --git a/src/tests/t_keydata.py b/src/tests/t_keydata.py
index 5c04a8523..b37233b21 100755
--- a/src/tests/t_keydata.py
+++ b/src/tests/t_keydata.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
realm = K5Realm(create_user=False, create_host=False)
diff --git a/src/tests/t_keyrollover.py b/src/tests/t_keyrollover.py
index bfd38914b..7c8d828f0 100755
--- a/src/tests/t_keyrollover.py
+++ b/src/tests/t_keyrollover.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
rollover_krb5_conf = {'libdefaults': {'allow_weak_crypto': 'true'}}
diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py
index a48740ba5..228c36334 100755
--- a/src/tests/t_keytab.py
+++ b/src/tests/t_keytab.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
for realm in multipass_realms(create_user=False):
diff --git a/src/tests/t_kprop.py b/src/tests/t_kprop.py
index 39169675d..f352ec8d7 100755
--- a/src/tests/t_kprop.py
+++ b/src/tests/t_kprop.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
conf_slave = {'dbmodules': {'db': {'database_name': '$testdir/db.slave'}}}
diff --git a/src/tests/t_localauth.py b/src/tests/t_localauth.py
index aa625d038..ebc9cdfde 100755
--- a/src/tests/t_localauth.py
+++ b/src/tests/t_localauth.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Unfortunately, we can't reliably test the k5login module. We can control
diff --git a/src/tests/t_mkey.py b/src/tests/t_mkey.py
index 615cd91ca..48a533059 100755
--- a/src/tests/t_mkey.py
+++ b/src/tests/t_mkey.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import random
import re
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
index 9b18ff94b..0fd35d576 100755
--- a/src/tests/t_otp.py
+++ b/src/tests/t_otp.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-#
# Author: Nathaniel McCallum <npmccallum@redhat.com>
#
# Copyright (c) 2013 Red Hat, Inc.
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 0e964c689..850db4fdd 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Skip this test if pkinit wasn't built.
diff --git a/src/tests/t_policy.py b/src/tests/t_policy.py
index 26c4e466e..eb3865d7c 100755
--- a/src/tests/t_policy.py
+++ b/src/tests/t_policy.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import re
diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py
index 32e35b08b..f597c3d08 100644
--- a/src/tests/t_preauth.py
+++ b/src/tests/t_preauth.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Test that the kdcpreauth client_keyblock() callback matches the key
diff --git a/src/tests/t_princflags.py b/src/tests/t_princflags.py
index 6378ef94f..aa3660217 100755
--- a/src/tests/t_princflags.py
+++ b/src/tests/t_princflags.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
from princflags import *
import re
diff --git a/src/tests/t_proxy.py b/src/tests/t_proxy.py
index 4e86fce8f..ff1929bef 100755
--- a/src/tests/t_proxy.py
+++ b/src/tests/t_proxy.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Skip this test if we're missing proxy functionality or parts of the proxy.
@@ -62,7 +61,8 @@ def start_proxy(realm, keycertpem):
conf.write('kpasswd = kpasswd://localhost:%d\n' % (realm.portbase + 2))
conf.close()
realm.env['KDCPROXY_CONFIG'] = proxy_conf_path
- cmd = [proxy_exec_path, str(realm.server_port()), keycertpem]
+ cmd = [sys.executable, proxy_exec_path, str(realm.server_port()),
+ keycertpem]
return realm.start_server(cmd, sentinel='proxy server ready')
# Fail: untrusted issuer and hostname doesn't match.
diff --git a/src/tests/t_pwqual.py b/src/tests/t_pwqual.py
index 011110bd1..171805697 100755
--- a/src/tests/t_pwqual.py
+++ b/src/tests/t_pwqual.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
plugin = os.path.join(buildtop, "plugins", "pwqual", "test", "pwqual_test.so")
diff --git a/src/tests/t_rdreq.py b/src/tests/t_rdreq.py
index f67c34866..00cd5cbb4 100755
--- a/src/tests/t_rdreq.py
+++ b/src/tests/t_rdreq.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
conf = {'realms': {'$realm': {'supported_enctypes': 'aes256-cts aes128-cts'}}}
diff --git a/src/tests/t_referral.py b/src/tests/t_referral.py
index e12fdc2e9..2f29d5712 100755
--- a/src/tests/t_referral.py
+++ b/src/tests/t_referral.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Create a pair of realms, where KRBTEST1.COM can authenticate to
diff --git a/src/tests/t_renew.py b/src/tests/t_renew.py
index 034190c80..67b4182fd 100755
--- a/src/tests/t_renew.py
+++ b/src/tests/t_renew.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
from datetime import datetime
import re
diff --git a/src/tests/t_renprinc.py b/src/tests/t_renprinc.py
index cc780839a..46cbed441 100755
--- a/src/tests/t_renprinc.py
+++ b/src/tests/t_renprinc.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2011 by the Massachusetts Institute of Technology.
# All rights reserved.
diff --git a/src/tests/t_salt.py b/src/tests/t_salt.py
index ddb1905ed..278911a22 100755
--- a/src/tests/t_salt.py
+++ b/src/tests/t_salt.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import re
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 732c306ea..448092387 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import re
diff --git a/src/tests/t_skew.py b/src/tests/t_skew.py
index f2ae06695..36d5a95c5 100755
--- a/src/tests/t_skew.py
+++ b/src/tests/t_skew.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Create a realm with the KDC one hour in the past.
diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py
index 19a0d2fa7..e2c85e665 100755
--- a/src/tests/t_sn2princ.py
+++ b/src/tests/t_sn2princ.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
offline = (len(args) > 0 and args[0] != "no")
diff --git a/src/tests/t_spake.py b/src/tests/t_spake.py
index 5b47e62d3..65af46d18 100644
--- a/src/tests/t_spake.py
+++ b/src/tests/t_spake.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# The name and number of each supported SPAKE group.
diff --git a/src/tests/t_stringattr.py b/src/tests/t_stringattr.py
index 5672a0f20..c2dc348e9 100755
--- a/src/tests/t_stringattr.py
+++ b/src/tests/t_stringattr.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# Copyright (C) 2011 by the Massachusetts Institute of Technology.
# All rights reserved.
diff --git a/src/tests/t_tabdump.py b/src/tests/t_tabdump.py
index 066e48418..2a86136dd 100755
--- a/src/tests/t_tabdump.py
+++ b/src/tests/t_tabdump.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
import csv
diff --git a/src/tests/t_unlockiter.py b/src/tests/t_unlockiter.py
index 2a438e99a..603cf721d 100755
--- a/src/tests/t_unlockiter.py
+++ b/src/tests/t_unlockiter.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# Default KDB iteration is locked. Expect write lock failure unless
diff --git a/src/tests/t_y2038.py b/src/tests/t_y2038.py
index 02e946df4..42a4ff7ed 100644
--- a/src/tests/t_y2038.py
+++ b/src/tests/t_y2038.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
from k5test import *
# These tests will become much less important after the y2038 boundary
diff --git a/src/util/paste-kdcproxy.py b/src/util/paste-kdcproxy.py
index 1e56b8954..30467fd74 100755
--- a/src/util/paste-kdcproxy.py
+++ b/src/util/paste-kdcproxy.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
import kdcproxy
from paste import httpserver
import os

View File

@ -0,0 +1,43 @@
From 5b4467a2c47e6de814e69ec3eb4c3e7a4632119c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 1 Apr 2019 13:13:09 -0400
Subject: [PATCH] FIPS-aware SPAKE group negotiation
(cherry picked from commit 59269fca96168aa89dc32834d188a54eea8953ac)
---
src/plugins/preauth/spake/groups.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/plugins/preauth/spake/groups.c b/src/plugins/preauth/spake/groups.c
index a195cc195..8a913cb5a 100644
--- a/src/plugins/preauth/spake/groups.c
+++ b/src/plugins/preauth/spake/groups.c
@@ -56,6 +56,8 @@
#include "trace.h"
#include "groups.h"
+#include <openssl/crypto.h>
+
#define DEFAULT_GROUPS_CLIENT "edwards25519"
#define DEFAULT_GROUPS_KDC ""
@@ -102,6 +104,9 @@ find_gdef(int32_t group)
{
size_t i;
+ if (group == builtin_edwards25519.reg->id && FIPS_mode())
+ return NULL;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (groupdefs[i]->reg->id == group)
return groupdefs[i];
@@ -116,6 +121,9 @@ find_gnum(const char *name)
{
size_t i;
+ if (strcasecmp(name, builtin_edwards25519.reg->name) == 0 && FIPS_mode())
+ return 0;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (strcasecmp(name, groupdefs[i]->reg->name) == 0)
return groupdefs[i]->reg->id;

View File

@ -1,41 +0,0 @@
From 390c515e13dffc8c00b44623cba47e27c2f20cf7 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 27 Mar 2018 10:36:05 -0400
Subject: [PATCH] Fix SPAKE memory leak
In the NIST group implementations, ossl_fini() needs to free the
groupdata container as well as its fields. Also in
spake_kdc.c:parse_data(), initialize the magic field of the resulting
data object to avoid a harmless uninitialized memory copy.
ticket: 8647
(cherry picked from commit 70b88b8018658e052d6eabf06f8fdad17fbe993c)
---
src/plugins/preauth/spake/openssl.c | 1 +
src/plugins/preauth/spake/spake_kdc.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/plugins/preauth/spake/openssl.c b/src/plugins/preauth/spake/openssl.c
index b821a9158..f2e4b53ec 100644
--- a/src/plugins/preauth/spake/openssl.c
+++ b/src/plugins/preauth/spake/openssl.c
@@ -69,6 +69,7 @@ ossl_fini(groupdata *gd)
EC_POINT_free(gd->N);
BN_CTX_free(gd->ctx);
BN_free(gd->order);
+ free(gd);
}
static krb5_error_code
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
index c1723ebaf..59e88409e 100644
--- a/src/plugins/preauth/spake/spake_kdc.c
+++ b/src/plugins/preauth/spake/spake_kdc.c
@@ -75,6 +75,7 @@ parse_data(struct k5input *in, krb5_data *out)
{
out->length = k5_input_get_uint32_be(in);
out->data = (char *)k5_input_get_bytes(in, out->length);
+ out->magic = KV5M_DATA;
}
/* Parse a received cookie into its components. The pointers stored in the

View File

@ -0,0 +1,22 @@
From 3a64eb3477e0e60d447c99f86b7bf4fd1259cb58 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 17 Sep 2019 18:29:15 -0400
Subject: [PATCH] Fix argument order on strlcpy() in enctype_name()
---
src/kdc/kdc_util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 96c88edc1..6d1861a3b 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1081,7 +1081,7 @@ enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
else
return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
- if (strlcpy(name, buf, buflen) >= buflen)
+ if (strlcpy(buf, name, buflen) >= buflen)
return ENOMEM;
return 0;
}

View File

@ -1,92 +0,0 @@
From 8b898badbe8051270c6da96f5c15f3bc8b6d974e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 26 Jan 2018 11:47:50 -0500
Subject: [PATCH] Fix hex conversion of PKINIT certid strings
When parsing a PKCS11 token specification, correctly convert from hex
to binary instead of using OpenSSL bignum functions (which would strip
leading zeros).
[ghudson@mit.edu: made hex_string_to_bin() a bit less verbose; wrote
commit message]
ticket: 8636
(cherry picked from commit 63e8b8142fd7b3931a7bf2d6448978ca536bafc0)
---
.../preauth/pkinit/pkinit_crypto_openssl.c | 55 +++++++++++++++----
1 file changed, 44 insertions(+), 11 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 2064eb7bd..eb2953fe1 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -4616,6 +4616,43 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts)
return ret;
}
+static int
+hex_string_to_bin(const char *str, int *bin_len_out, CK_BYTE **bin_out)
+{
+ size_t str_len, i;
+ CK_BYTE *bin;
+ char *endptr, tmp[3] = { '\0', '\0', '\0' };
+ long val;
+
+ *bin_len_out = 0;
+ *bin_out = NULL;
+
+ str_len = strlen(str);
+ if (str_len % 2 != 0)
+ return EINVAL;
+ bin = malloc(str_len / 2);
+ if (bin == NULL)
+ return ENOMEM;
+
+ errno = 0;
+ for (i = 0; i < str_len / 2; i++) {
+ tmp[0] = str[i * 2];
+ tmp[1] = str[i * 2 + 1];
+
+ val = strtol(tmp, &endptr, 16);
+ if (val < 0 || val > 255 || errno != 0 || endptr != &tmp[2]) {
+ free(bin);
+ return EINVAL;
+ }
+
+ bin[i] = (CK_BYTE)val;
+ }
+
+ *bin_len_out = str_len / 2;
+ *bin_out = bin;
+ return 0;
+}
+
static krb5_error_code
pkinit_get_certs_pkcs11(krb5_context context,
pkinit_plg_crypto_context plg_cryptoctx,
@@ -4658,18 +4695,14 @@ pkinit_get_certs_pkcs11(krb5_context context,
}
/* Convert the ascii cert_id string into a binary blob */
if (idopts->cert_id_string != NULL) {
- BIGNUM *bn = NULL;
- BN_hex2bn(&bn, idopts->cert_id_string);
- if (bn == NULL)
- return ENOMEM;
- id_cryptoctx->cert_id_len = BN_num_bytes(bn);
- id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len);
- if (id_cryptoctx->cert_id == NULL) {
- BN_free(bn);
- return ENOMEM;
+ r = hex_string_to_bin(idopts->cert_id_string,
+ &id_cryptoctx->cert_id_len,
+ &id_cryptoctx->cert_id);
+ if (r != 0) {
+ pkiDebug("Failed to convert certid string [%s]\n",
+ idopts->cert_id_string);
+ return r;
}
- BN_bn2bin(bn, id_cryptoctx->cert_id);
- BN_free(bn);
}
id_cryptoctx->slotid = idopts->slotid;
id_cryptoctx->pkcs11_method = 1;

View File

@ -1,35 +0,0 @@
From 43cf653d21d931b792b36c7e6e4cfab3a6236bef Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 25 Jul 2018 11:50:02 -0400
Subject: [PATCH] Fix k5test prompts for Python 3
With Python 3, sys.stdout.write() of a partial line followed by
sys.stdin.readline() does not display the partial line. Add explicit
flushes to make prompts visible in k5test.py.
ticket: 8710
(cherry picked from commit 297535b72177dcced036b78107e9d0e37781c7a3)
---
src/util/k5test.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/util/k5test.py b/src/util/k5test.py
index 81fac3063..e4f99b211 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -457,6 +457,7 @@ def _onexit():
if _debug or _stop_before or _stop_after or _shell_before or _shell_after:
# Wait before killing daemons in case one is being debugged.
sys.stdout.write('*** Press return to kill daemons and exit script: ')
+ sys.stdout.flush()
sys.stdin.readline()
for proc in _daemons:
os.kill(proc.pid, signal.SIGTERM)
@@ -658,6 +659,7 @@ def _valgrind(args):
def _stop_or_shell(stop, shell, env, ind):
if (_match_cmdnum(stop, ind)):
sys.stdout.write('*** [%d] Waiting for return: ' % ind)
+ sys.stdout.flush()
sys.stdin.readline()
if (_match_cmdnum(shell, ind)):
output('*** [%d] Spawning shell\n' % ind, True)

View File

@ -0,0 +1,34 @@
From a904a5b85e8425823016b821153b37396edc2306 Mon Sep 17 00:00:00 2001
From: Corene Casper <C.Casper@Dell.com>
Date: Sat, 16 Feb 2019 00:49:26 -0500
Subject: [PATCH] Fix memory leak in 'none' replay cache type
Commit 0f06098e2ab419d02e89a1ca6bc9f2828f6bdb1e fixed part of a memory
leak in the 'none' replay cache type by freeing the outer container,
but we also need to free the mutex.
[ghudson@mit.edu: wrote commit message]
ticket: 8783
tags: pullup
target_version: 1.17-next
target_version: 1.16-next
(cherry picked from commit af2a3115cb8feb5174151b4b40223ae45aa9db17)
(cherry picked from commit ff79351c4755d6df7c3245274708454311c25731)
---
src/lib/krb5/rcache/rc_none.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lib/krb5/rcache/rc_none.c b/src/lib/krb5/rcache/rc_none.c
index e30aed09f..0b2274df7 100644
--- a/src/lib/krb5/rcache/rc_none.c
+++ b/src/lib/krb5/rcache/rc_none.c
@@ -50,6 +50,7 @@ krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc)
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_close(krb5_context ctx, krb5_rcache rc)
{
+ k5_mutex_destroy(&rc->lock);
free (rc);
return 0;
}

View File

@ -1,48 +0,0 @@
From 59a28991e15496e6f9cf867c32dc18e7e1062f59 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 15 Mar 2018 20:27:30 -0400
Subject: [PATCH] Fix read overflow in KDC sort_pa_data()
sort_pa_data() could read past the end of pa_order if all preauth
systems in the table have the PA_REPLACES_KEY flag, causing a
dereference of preauth_systems[-1]. This situation became possible
after commit fea1a488924faa3938ef723feaa1ff12d22a91ff with the
elimination of static_preauth_systems; before that there were always
table entries which did not have PA_REPLACES_KEY set.
Fix this bug by removing the loop to count n_key_replacers, and
instead get the count from the prior loop by stopping once we move all
of the key-replacing modules to the front.
(cherry picked from commit b38e318cea18fd65647189eed64aef83bf1cb772)
---
src/kdc/kdc_preauth.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 80b130222..62ff9a8a7 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -663,17 +663,18 @@ sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order)
break;
}
}
+ /* If we didn't find one, we have moved all of the key-replacing
+ * modules, and i is the count of those modules. */
+ if (j == n_repliers)
+ break;
}
+ n_key_replacers = i;
if (request->padata != NULL) {
/* Now reorder the subset of modules which replace the key,
* bubbling those which handle pa_data types provided by the
* client ahead of the others.
*/
- for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
- continue;
- }
- n_key_replacers = i;
for (i = 0; i < n_key_replacers; i++) {
if (pa_list_includes(request->padata,
preauth_systems[pa_order[i]].type))

View File

@ -1,43 +0,0 @@
From e405f42b532e377e7e3d654313a07f8c11f48f9a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 3 Jan 2018 12:06:08 -0500
Subject: [PATCH] Fix securid_sam2 preauth for non-default salt
When looking up the client long-term key, look for any salt type, not
just the default salt type.
ticket: 8629
(cherry picked from commit a2339099ad13c84de0843fd04d0ba612fc194a1e)
---
src/plugins/preauth/securid_sam2/grail.c | 3 +--
src/plugins/preauth/securid_sam2/securid2.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/plugins/preauth/securid_sam2/grail.c b/src/plugins/preauth/securid_sam2/grail.c
index 18d48f924..48b61b0d1 100644
--- a/src/plugins/preauth/securid_sam2/grail.c
+++ b/src/plugins/preauth/securid_sam2/grail.c
@@ -213,8 +213,7 @@ verify_grail_data(krb5_context context, krb5_db_entry *client,
return KRB5KDC_ERR_PREAUTH_FAILED;
ret = krb5_dbe_find_enctype(context, client,
- sr2->sam_enc_nonce_or_sad.enctype,
- KRB5_KDB_SALTTYPE_NORMAL,
+ sr2->sam_enc_nonce_or_sad.enctype, -1,
sr2->sam_enc_nonce_or_sad.kvno,
&client_key_data);
if (ret)
diff --git a/src/plugins/preauth/securid_sam2/securid2.c b/src/plugins/preauth/securid_sam2/securid2.c
index ca99ce3ef..363e17a10 100644
--- a/src/plugins/preauth/securid_sam2/securid2.c
+++ b/src/plugins/preauth/securid_sam2/securid2.c
@@ -313,8 +313,7 @@ verify_securid_data_2(krb5_context context, krb5_db_entry *client,
}
retval = krb5_dbe_find_enctype(context, client,
- sr2->sam_enc_nonce_or_sad.enctype,
- KRB5_KDB_SALTTYPE_NORMAL,
+ sr2->sam_enc_nonce_or_sad.enctype, -1,
sr2->sam_enc_nonce_or_sad.kvno,
&client_key_data);
if (retval) {

View File

@ -1,133 +0,0 @@
From 617d153bb32d0bd7db33ccec21043d1113651f3a Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 18 Apr 2018 14:13:28 -0400
Subject: [PATCH] Fix segfault in finish_dispatch()
dispatch() doesn't necessarily initialize state->active_realm which
led to an explicit NULL dereference in finish_dispatch().
Additionally, fix make_too_big_error() so that it won't subsequently
dereference state->active_realm.
tags: pullup
target_version: 1.16-next
target_version: 1.15-next
---
src/kdc/dispatch.c | 79 ++++++++++++++++++++++++----------------------
1 file changed, 42 insertions(+), 37 deletions(-)
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c
index 3ed5176a8..fb3686c98 100644
--- a/src/kdc/dispatch.c
+++ b/src/kdc/dispatch.c
@@ -35,9 +35,6 @@
static krb5_int32 last_usec = 0, last_os_random = 0;
-static krb5_error_code make_too_big_error(kdc_realm_t *kdc_active_realm,
- krb5_data **out);
-
struct dispatch_state {
loop_respond_fn respond;
void *arg;
@@ -47,6 +44,41 @@ struct dispatch_state {
krb5_context kdc_err_context;
};
+
+static krb5_error_code
+make_too_big_error(krb5_context context, krb5_principal tgsprinc,
+ krb5_data **out)
+{
+ krb5_error errpkt;
+ krb5_error_code retval;
+ krb5_data *scratch;
+
+ *out = NULL;
+ memset(&errpkt, 0, sizeof(errpkt));
+
+ retval = krb5_us_timeofday(context, &errpkt.stime, &errpkt.susec);
+ if (retval)
+ return retval;
+ errpkt.error = KRB_ERR_RESPONSE_TOO_BIG;
+ errpkt.server = tgsprinc;
+ errpkt.client = NULL;
+ errpkt.text.length = 0;
+ errpkt.text.data = 0;
+ errpkt.e_data.length = 0;
+ errpkt.e_data.data = 0;
+ scratch = malloc(sizeof(*scratch));
+ if (scratch == NULL)
+ return ENOMEM;
+ retval = krb5_mk_error(context, &errpkt, scratch);
+ if (retval) {
+ free(scratch);
+ return retval;
+ }
+
+ *out = scratch;
+ return 0;
+}
+
static void
finish_dispatch(struct dispatch_state *state, krb5_error_code code,
krb5_data *response)
@@ -54,12 +86,17 @@ finish_dispatch(struct dispatch_state *state, krb5_error_code code,
loop_respond_fn oldrespond = state->respond;
void *oldarg = state->arg;
kdc_realm_t *kdc_active_realm = state->active_realm;
+ krb5_principal tgsprinc = NULL;
+
+ if (kdc_active_realm != NULL)
+ tgsprinc = kdc_active_realm->realm_tgsprinc;
if (state->is_tcp == 0 && response &&
response->length > (unsigned int)max_dgram_reply_size) {
- krb5_free_data(kdc_context, response);
+ krb5_free_data(state->kdc_err_context, response);
response = NULL;
- code = make_too_big_error(kdc_active_realm, &response);
+ code = make_too_big_error(state->kdc_err_context, tgsprinc,
+ &response);
if (code)
krb5_klog_syslog(LOG_ERR, "error constructing "
"KRB_ERR_RESPONSE_TOO_BIG error: %s",
@@ -208,38 +245,6 @@ done:
finish_dispatch_cache(state, retval, response);
}
-static krb5_error_code
-make_too_big_error(kdc_realm_t *kdc_active_realm, krb5_data **out)
-{
- krb5_error errpkt;
- krb5_error_code retval;
- krb5_data *scratch;
-
- *out = NULL;
- memset(&errpkt, 0, sizeof(errpkt));
-
- retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
- if (retval)
- return retval;
- errpkt.error = KRB_ERR_RESPONSE_TOO_BIG;
- errpkt.server = tgs_server;
- errpkt.client = NULL;
- errpkt.text.length = 0;
- errpkt.text.data = 0;
- errpkt.e_data.length = 0;
- errpkt.e_data.data = 0;
- scratch = malloc(sizeof(*scratch));
- if (scratch == NULL)
- return ENOMEM;
- retval = krb5_mk_error(kdc_context, &errpkt, scratch);
- if (retval) {
- free(scratch);
- return retval;
- }
-
- *out = scratch;
- return 0;
-}
krb5_context get_context(void *handle)
{

View File

@ -1,81 +0,0 @@
From eb60404564852a262d4082c3e38086742afb1bd9 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 16 Jul 2018 16:44:01 -0400
Subject: [PATCH] Fix some broken tests for Python 3
Remove python2 dependencies in .travis.yml and add python3-paste.
Convert t_daemon.py and jsonwalker.py to python3. csjon has no
python3 version, so replace it with python's built-in JSON module.
python3-pyrad isn't available for Trusty, so krad and OTP tests are
currently not exercised by Travis.
[ghudson@mit.edu: squashed commits; edited commit message]
ticket: 8710
(cherry picked from commit d1fb3551c0dff5c3e6555b31fcbf04ff04d577fe)
[rharwood@redhat.com: .travis.yml]
---
src/lib/krad/t_daemon.py | 2 +-
src/tests/jsonwalker.py | 16 +++++-----------
2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
index 7d7a5d0c8..7668cd7f8 100755
--- a/src/lib/krad/t_daemon.py
+++ b/src/lib/krad/t_daemon.py
@@ -23,7 +23,7 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import StringIO
+from io import StringIO
import os
import sys
import signal
diff --git a/src/tests/jsonwalker.py b/src/tests/jsonwalker.py
index 7a0675e08..1880363d2 100644
--- a/src/tests/jsonwalker.py
+++ b/src/tests/jsonwalker.py
@@ -1,10 +1,5 @@
import sys
-try:
- import cjson
-except ImportError:
- print("Warning: skipping audit log verification because the cjson module" \
- " is unavailable")
- sys.exit(0)
+import json
from collections import defaultdict
from optparse import OptionParser
@@ -72,7 +67,7 @@ class Parser(object):
"""
Generator that works through dictionary.
"""
- for a,v in adict.iteritems():
+ for a,v in adict.items():
if isinstance(v,dict):
for (attrpath,u) in self._walk(v):
yield (a+'.'+attrpath,u)
@@ -93,17 +88,16 @@ if __name__ == '__main__':
with open(options.filename, 'r') as f:
content = list()
for l in f:
- content.append(cjson.decode(l.rstrip()))
+ content.append(json.loads(l.rstrip()))
f.close()
else:
- print('Input file in jason format is required')
+ print('Input file in JSON format is required')
exit()
defaults = None
if options.defaults is not None:
with open(options.defaults, 'r') as f:
- defaults = cjson.decode(f.read())
- f.close()
+ defaults = json.load(f)
# run test
p = Parser(defaults)

View File

@ -1,149 +0,0 @@
From 3d651a6e234bed4c4d4865a56c5fa47dab89a5a6 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 26 Mar 2018 11:12:39 -0400
Subject: [PATCH] Implement k5_buf_init_dynamic_zap
Add a variant of dynamic k5buf objects which zeroes memory when
reallocating or freeing the buffer.
(cherry picked from commit 8ee8246c14702dc03b02e31b9fb5b7c2bb674bfb)
---
src/include/k5-buf.h | 6 ++-
src/util/support/k5buf.c | 41 +++++++++++++++----
src/util/support/libkrb5support-fixed.exports | 1 +
3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/src/include/k5-buf.h b/src/include/k5-buf.h
index 1223916a6..48e2a7d53 100644
--- a/src/include/k5-buf.h
+++ b/src/include/k5-buf.h
@@ -45,7 +45,7 @@
*/
/* Buffer type values */
-enum k5buftype { K5BUF_ERROR, K5BUF_FIXED, K5BUF_DYNAMIC };
+enum k5buftype { K5BUF_ERROR, K5BUF_FIXED, K5BUF_DYNAMIC, K5BUF_DYNAMIC_ZAP };
struct k5buf {
enum k5buftype buftype;
@@ -63,6 +63,10 @@ void k5_buf_init_fixed(struct k5buf *buf, char *data, size_t space);
/* Initialize a k5buf using an internally allocated dynamic buffer. */
void k5_buf_init_dynamic(struct k5buf *buf);
+/* Initialize a k5buf using an internally allocated dynamic buffer, zeroing
+ * memory when reallocating or freeing. */
+void k5_buf_init_dynamic_zap(struct k5buf *buf);
+
/* Add a C string to BUF. */
void k5_buf_add(struct k5buf *buf, const char *data);
diff --git a/src/util/support/k5buf.c b/src/util/support/k5buf.c
index 35978f238..b2b5e5b67 100644
--- a/src/util/support/k5buf.c
+++ b/src/util/support/k5buf.c
@@ -37,7 +37,7 @@
/*
* Structure invariants:
*
- * buftype is K5BUF_FIXED, K5BUF_DYNAMIC, or K5BUF_ERROR
+ * buftype is K5BUF_FIXED, K5BUF_DYNAMIC, K5BUF_DYNAMIC_ZAP, or K5BUF_ERROR
* if buftype is K5BUF_ERROR, the other fields are NULL or 0
* if buftype is not K5BUF_ERROR:
* space > 0
@@ -77,22 +77,35 @@ ensure_space(struct k5buf *buf, size_t len)
return 1;
if (buf->buftype == K5BUF_FIXED) /* Can't resize a fixed buffer. */
goto error_exit;
- assert(buf->buftype == K5BUF_DYNAMIC);
+ assert(buf->buftype == K5BUF_DYNAMIC || buf->buftype == K5BUF_DYNAMIC_ZAP);
new_space = buf->space * 2;
while (new_space - buf->len - 1 < len) {
if (new_space > SIZE_MAX / 2)
goto error_exit;
new_space *= 2;
}
- new_data = realloc(buf->data, new_space);
- if (new_data == NULL)
- goto error_exit;
+ if (buf->buftype == K5BUF_DYNAMIC_ZAP) {
+ /* realloc() could leave behind a partial copy of sensitive data. */
+ new_data = malloc(new_space);
+ if (new_data == NULL)
+ goto error_exit;
+ memcpy(new_data, buf->data, buf->len);
+ new_data[buf->len] = '\0';
+ zap(buf->data, buf->len);
+ free(buf->data);
+ } else {
+ new_data = realloc(buf->data, new_space);
+ if (new_data == NULL)
+ goto error_exit;
+ }
buf->data = new_data;
buf->space = new_space;
return 1;
error_exit:
- if (buf->buftype == K5BUF_DYNAMIC)
+ if (buf->buftype == K5BUF_DYNAMIC_ZAP)
+ zap(buf->data, buf->len);
+ if (buf->buftype == K5BUF_DYNAMIC_ZAP || buf->buftype == K5BUF_DYNAMIC)
free(buf->data);
set_error(buf);
return 0;
@@ -123,6 +136,14 @@ k5_buf_init_dynamic(struct k5buf *buf)
*endptr(buf) = '\0';
}
+void
+k5_buf_init_dynamic_zap(struct k5buf *buf)
+{
+ k5_buf_init_dynamic(buf);
+ if (buf->buftype == K5BUF_DYNAMIC)
+ buf->buftype = K5BUF_DYNAMIC_ZAP;
+}
+
void
k5_buf_add(struct k5buf *buf, const char *data)
{
@@ -163,7 +184,7 @@ k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
}
/* Optimistically format the data directly into the dynamic buffer. */
- assert(buf->buftype == K5BUF_DYNAMIC);
+ assert(buf->buftype == K5BUF_DYNAMIC || buf->buftype == K5BUF_DYNAMIC_ZAP);
va_copy(apcopy, ap);
r = vsnprintf(endptr(buf), remaining, fmt, apcopy);
va_end(apcopy);
@@ -197,6 +218,8 @@ k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
memcpy(endptr(buf), tmp, r + 1);
buf->len += r;
}
+ if (buf->buftype == K5BUF_DYNAMIC_ZAP)
+ zap(tmp, strlen(tmp));
free(tmp);
}
@@ -241,7 +264,9 @@ k5_buf_free(struct k5buf *buf)
{
if (buf->buftype == K5BUF_ERROR)
return;
- assert(buf->buftype == K5BUF_DYNAMIC);
+ assert(buf->buftype == K5BUF_DYNAMIC || buf->buftype == K5BUF_DYNAMIC_ZAP);
+ if (buf->buftype == K5BUF_DYNAMIC_ZAP)
+ zap(buf->data, buf->len);
free(buf->data);
set_error(buf);
}
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index cb9bf0826..a5e2ade04 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -3,6 +3,7 @@ k5_base64_encode
k5_bcmp
k5_buf_init_fixed
k5_buf_init_dynamic
+k5_buf_init_dynamic_zap
k5_buf_add
k5_buf_add_len
k5_buf_add_fmt

View File

@ -1,4 +1,4 @@
From e04d483890496a1747f3cdb20a4df5285147f59b Mon Sep 17 00:00:00 2001
From 088fd5a56e030739a31a43aee7335bc661a92b1c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 31 Jul 2018 13:47:26 -0400
Subject: [PATCH] In FIPS mode, add plaintext fallback for RC4 usages and taint

View File

@ -0,0 +1,28 @@
From e07ddc519254a35e54af020643685b9da9e0e973 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 15 Jan 2019 13:41:16 -0500
Subject: [PATCH] In kpropd, debug-log proper ticket enctype names
This change replaces the last call of krb5_enctype_to_string() in our
sources with krb5_enctype_to_name(), ensuring that we log consistently
to users using readily discoverable strings.
(cherry picked from commit 30e12a2ecdf7e2a034a91626a03b5c9909e4c68d)
---
src/kprop/kpropd.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
index 4cc035dc6..0c7bffa24 100644
--- a/src/kprop/kpropd.c
+++ b/src/kprop/kpropd.c
@@ -1279,7 +1279,8 @@ kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp,
exit(1);
}
- retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf));
+ retval = krb5_enctype_to_name(*etype, FALSE, etypebuf,
+ sizeof(etypebuf));
if (retval) {
com_err(progname, retval, _("while unparsing ticket etype"));
exit(1);

View File

@ -0,0 +1,54 @@
From 83c2f0bac35c2ad0872dc9b2a9ca1bdde948f216 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 14 Jan 2019 17:14:42 -0500
Subject: [PATCH] In rd_req_dec, always log non-permitted enctypes
The buffer specified in negotiate_etype() is too small for use with
the AES enctypes when used with krb5_enctype_to_string(), so switch to
using krb5_enctype_to_name().
(cherry picked from commit bf75ebf583a51bf00005a96d17924818d19377be)
---
src/lib/krb5/krb/rd_req_dec.c | 5 ++---
src/tests/gssapi/t_enctypes.py | 5 +++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index 4cd429a11..e75192fee 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -864,9 +864,8 @@ negotiate_etype(krb5_context context,
if (permitted == FALSE) {
char enctype_name[30];
- if (krb5_enctype_to_string(desired_etypes[i],
- enctype_name,
- sizeof(enctype_name)) == 0)
+ if (krb5_enctype_to_name(desired_etypes[i], FALSE, enctype_name,
+ sizeof(enctype_name)) == 0)
k5_setmsg(context, KRB5_NOPERM_ETYPE,
_("Encryption type %s not permitted"), enctype_name);
return KRB5_NOPERM_ETYPE;
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index ee43ff028..5d9f80e04 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -85,7 +85,8 @@ test('both aes128', 'aes128-cts', 'aes128-cts',
# If only the acceptor constrains the permitted session enctypes to
# aes128, subkey negotiation fails because the acceptor considers the
# aes256 session key to be non-permitted.
-test_err('acc aes128', None, 'aes128-cts', 'Encryption type not permitted')
+test_err('acc aes128', None, 'aes128-cts',
+ 'Encryption type aes256-cts-hmac-sha1-96 not permitted')
# If the initiator constrains the permitted session enctypes to des3,
# no acceptor subkey will be generated because we can't upgrade to a
@@ -128,7 +129,7 @@ test('upgrade init des3+rc4', 'des3 rc4', None,
# is only for the sake of the kernel, since we could upgrade to an
# aes128 subkey, but it's the current semantics.)
test_err('upgrade acc aes128', None, 'aes128-cts',
- 'Encryption type ArcFour with HMAC/md5 not permitted')
+ 'Encryption type arcfour-hmac not permitted')
# If the acceptor permits rc4 but prefers aes128, it will negotiate an
# upgrade to aes128.

View File

@ -1,38 +0,0 @@
From bbc68d1657306a61a7646dd7b9690f67705e24be Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 3 Jan 2018 11:59:14 -0500
Subject: [PATCH] Include etype-info in for hardware preauth hints
If a principal has the requires_hwauth bit set, include PA-ETYPE-INFO
or PA-ETYPE-INFO2 padata in the PREAUTH_REQUIRED error, as preauth
mechs involving hardware tokens may also use the principal's Kerberos
password.
ticket: 8629
(cherry picked from commit ba92da05accc524b8037453b63ced1a6c65fd2a1)
---
src/kdc/kdc_preauth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 81d0b8cff..739c5e776 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -144,7 +144,7 @@ static preauth_system static_preauth_systems[] = {
{
"etype-info",
KRB5_PADATA_ETYPE_INFO,
- 0,
+ PA_HARDWARE,
NULL,
NULL,
NULL,
@@ -155,7 +155,7 @@ static preauth_system static_preauth_systems[] = {
{
"etype-info2",
KRB5_PADATA_ETYPE_INFO2,
- 0,
+ PA_HARDWARE,
NULL,
NULL,
NULL,

View File

@ -1,514 +0,0 @@
From b623881ec039bffc758f53906f7e4f9b884f1cf4 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 15 Mar 2018 14:37:28 -0400
Subject: [PATCH] Include preauth name in trace output if possible
Add a {patype} trace format specifier for a single pa-type value. Add
a krb5_preauthtype to string conversion function to trace machinery
and use it when formatting {patype} or {patypes}.
[ghudson@mit.edu: wrote conversion function; edited commit message]
ticket: 8653 (new)
(cherry picked from commit 9c68fe39b018666eabe033b639c1f35d03ba51c7)
---
src/include/k5-trace.h | 17 +--
src/lib/krb5/os/t_trace.ref | 2 +-
src/lib/krb5/os/trace.c | 61 +++++++++-
src/tests/t_pkinit.py | 43 +++----
src/tests/t_preauth.py | 216 ++++++++++++++++++------------------
5 files changed, 200 insertions(+), 139 deletions(-)
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
index 390a8b7d6..5f7eb9517 100644
--- a/src/include/k5-trace.h
+++ b/src/include/k5-trace.h
@@ -75,6 +75,7 @@
* {cksum} const krb5_checksum *, display cksumtype and hex checksum
* {princ} krb5_principal, unparse and display
* {ptype} krb5_int32, krb5_principal type, display name
+ * {patype} krb5_preauthtype, a single padata type number
* {patypes} krb5_pa_data **, display list of padata type numbers
* {etype} krb5_enctype, display shortest name of enctype
* {etypes} krb5_enctype *, display list of enctypes
@@ -232,14 +233,14 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \
TRACE(c, "Decrypt with preauth AS key failed: {kerr}", code)
#define TRACE_INIT_CREDS_PREAUTH_MORE(c, patype) \
- TRACE(c, "Continuing preauth mech {int}", (int)patype)
+ TRACE(c, "Continuing preauth mech {patype}", patype)
#define TRACE_INIT_CREDS_PREAUTH_NONE(c) \
TRACE(c, "Sending unauthenticated request")
#define TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(c) \
TRACE(c, "Attempting optimistic preauth")
#define TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(c, patype, code) \
- TRACE(c, "Recovering from KDC error {int} using preauth mech {int}", \
- (int)patype, (int)code)
+ TRACE(c, "Recovering from KDC error {int} using preauth mech {patype}", \
+ patype, (int)code)
#define TRACE_INIT_CREDS_RESTART_FAST(c) \
TRACE(c, "Restarting to upgrade to FAST")
#define TRACE_INIT_CREDS_RESTART_PREAUTH_FAILED(c) \
@@ -290,7 +291,7 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_PREAUTH_CONFLICT(c, name1, name2, patype) \
TRACE(c, "Preauth module {str} conflicts with module {str} for pa " \
- "type {int}", name1, name2, (int) patype)
+ "type {patype}", name1, name2, patype)
#define TRACE_PREAUTH_COOKIE(c, len, data) \
TRACE(c, "Received cookie: {lenstr}", (size_t) len, data)
#define TRACE_PREAUTH_ENC_TS_KEY_GAK(c, keyblock) \
@@ -302,8 +303,8 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "Selected etype info: etype {etype}, salt \"{data}\", " \
"params \"{data}\"", etype, salt, s2kparams)
#define TRACE_PREAUTH_INFO_FAIL(c, patype, code) \
- TRACE(c, "Preauth builtin info function failure, type={int}: {kerr}", \
- (int) patype, code)
+ TRACE(c, "Preauth builtin info function failure, type={patype}: {kerr}", \
+ patype, code)
#define TRACE_PREAUTH_INPUT(c, padata) \
TRACE(c, "Processing preauth types: {patypes}", padata)
#define TRACE_PREAUTH_OUTPUT(c, padata) \
@@ -314,8 +315,8 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_PREAUTH_SAM_KEY_GAK(c, keyblock) \
TRACE(c, "AS key obtained for SAM: {keyblock}", keyblock)
#define TRACE_PREAUTH_SALT(c, salt, patype) \
- TRACE(c, "Received salt \"{data}\" via padata type {int}", salt, \
- (int) patype)
+ TRACE(c, "Received salt \"{data}\" via padata type {patype}", salt, \
+ patype)
#define TRACE_PREAUTH_SKIP(c, name, patype) \
TRACE(c, "Skipping previously used preauth module {str} ({int})", \
name, (int) patype)
diff --git a/src/lib/krb5/os/t_trace.ref b/src/lib/krb5/os/t_trace.ref
index ca5818a1e..bd5d9b6b6 100644
--- a/src/lib/krb5/os/t_trace.ref
+++ b/src/lib/krb5/os/t_trace.ref
@@ -38,7 +38,7 @@ int, krb5_principal type: Windows 2000 UPN and SID
int, krb5_principal type: NT 4 style name
int, krb5_principal type: NT 4 style name and SID
int, krb5_principal type: ?
-krb5_pa_data **, display list of padata type numbers: 3, 0
+krb5_pa_data **, display list of padata type numbers: PA-PW-SALT (3), 0
krb5_pa_data **, display list of padata type numbers: (empty)
krb5_enctype, display shortest name of enctype: des-cbc-crc
krb5_enctype *, display list of enctypes: 5, rc4-hmac-exp, 511
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index 779f184cb..10b4f0c14 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -123,6 +123,50 @@ principal_type_string(krb5_int32 type)
}
}
+static char *
+padata_type_string(krb5_preauthtype type)
+{
+ switch (type) {
+ case KRB5_PADATA_TGS_REQ: return "PA-TGS-REQ";
+ case KRB5_PADATA_ENC_TIMESTAMP: return "PA-ENC-TIMESTAMP";
+ case KRB5_PADATA_PW_SALT: return "PA-PW-SALT";
+ case KRB5_PADATA_ENC_UNIX_TIME: return "PA-ENC-UNIX-TIME";
+ case KRB5_PADATA_ENC_SANDIA_SECURID: return "PA-SANDIA-SECUREID";
+ case KRB5_PADATA_SESAME: return "PA-SESAME";
+ case KRB5_PADATA_OSF_DCE: return "PA-OSF-DCE";
+ case KRB5_CYBERSAFE_SECUREID: return "PA-CYBERSAFE-SECUREID";
+ case KRB5_PADATA_AFS3_SALT: return "PA-AFS3-SALT";
+ case KRB5_PADATA_ETYPE_INFO: return "PA-ETYPE-INFO";
+ case KRB5_PADATA_SAM_CHALLENGE: return "PA-SAM-CHALLENGE";
+ case KRB5_PADATA_SAM_RESPONSE: return "PA-SAM-RESPONSE";
+ case KRB5_PADATA_PK_AS_REQ_OLD: return "PA-PK-AS-REQ_OLD";
+ case KRB5_PADATA_PK_AS_REP_OLD: return "PA-PK-AS-REP_OLD";
+ case KRB5_PADATA_PK_AS_REQ: return "PA-PK-AS-REQ";
+ case KRB5_PADATA_PK_AS_REP: return "PA-PK-AS-REP";
+ case KRB5_PADATA_ETYPE_INFO2: return "PA-ETYPE-INFO2";
+ case KRB5_PADATA_SVR_REFERRAL_INFO: return "PA-SVR-REFERRAL-INFO";
+ case KRB5_PADATA_SAM_REDIRECT: return "PA-SAM-REDIRECT";
+ case KRB5_PADATA_GET_FROM_TYPED_DATA: return "PA-GET-FROM-TYPED-DATA";
+ case KRB5_PADATA_SAM_CHALLENGE_2: return "PA-SAM-CHALLENGE2";
+ case KRB5_PADATA_SAM_RESPONSE_2: return "PA-SAM-RESPONSE2";
+ case KRB5_PADATA_PAC_REQUEST: return "PA-PAC-REQUEST";
+ case KRB5_PADATA_FOR_USER: return "PA-FOR_USER";
+ case KRB5_PADATA_S4U_X509_USER: return "PA-FOR-X509-USER";
+ case KRB5_PADATA_AS_CHECKSUM: return "PA-AS-CHECKSUM";
+ case KRB5_PADATA_FX_COOKIE: return "PA-FX-COOKIE";
+ case KRB5_PADATA_FX_FAST: return "PA-FX-FAST";
+ case KRB5_PADATA_FX_ERROR: return "PA-FX-ERROR";
+ case KRB5_PADATA_ENCRYPTED_CHALLENGE: return "PA-ENCRYPTED-CHALLENGE";
+ case KRB5_PADATA_OTP_CHALLENGE: return "PA-OTP-CHALLENGE";
+ case KRB5_PADATA_OTP_REQUEST: return "PA-OTP-REQUEST";
+ case KRB5_PADATA_OTP_PIN_CHANGE: return "PA-OTP-PIN-CHANGE";
+ case KRB5_PADATA_PKINIT_KX: return "PA-PKINIT-KX";
+ case KRB5_ENCPADATA_REQ_ENC_PA_REP: return "PA-REQ-ENC-PA-REP";
+ case KRB5_PADATA_AS_FRESHNESS: return "PA_AS_FRESHNESS";
+ default: return NULL;
+ }
+}
+
static char *
trace_format(krb5_context context, const char *fmt, va_list ap)
{
@@ -140,6 +184,8 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
krb5_key key;
const krb5_checksum *cksum;
krb5_pa_data **padata;
+ krb5_preauthtype pa_type;
+ const char *name;
krb5_ccache ccache;
krb5_keytab keytab;
krb5_creds *creds;
@@ -271,10 +317,23 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
if (padata == NULL || *padata == NULL)
k5_buf_add(&buf, "(empty)");
for (; padata != NULL && *padata != NULL; padata++) {
- k5_buf_add_fmt(&buf, "%d", (int)(*padata)->pa_type);
+ pa_type = (*padata)->pa_type;
+ name = padata_type_string(pa_type);
+ if (name != NULL)
+ k5_buf_add_fmt(&buf, "%s (%d)", name, (int)pa_type);
+ else
+ k5_buf_add_fmt(&buf, "%d", (int)pa_type);
+
if (*(padata + 1) != NULL)
k5_buf_add(&buf, ", ");
}
+ } else if (strcmp(tmpbuf, "patype") == 0) {
+ pa_type = va_arg(ap, krb5_preauthtype);
+ name = padata_type_string(pa_type);
+ if (name != NULL)
+ k5_buf_add_fmt(&buf, "%s (%d)", name, (int)pa_type);
+ else
+ k5_buf_add_fmt(&buf, "%d", (int)pa_type);
} else if (strcmp(tmpbuf, "etype") == 0) {
etype = va_arg(ap, krb5_enctype);
if (krb5_enctype_to_name(etype, TRUE, tmpbuf, sizeof(tmpbuf)) == 0)
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 5bc60cb1e..0e964c689 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -164,18 +164,19 @@ realm.stop_kdc()
realm.start_kdc()
# Run the basic test - PKINIT with FILE: identity, with no password on the key.
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'PKINIT client received freshness token from KDC',
+ 'PKINIT loading CA certs and CRLs from FILE',
+ 'PKINIT client making DH request',
+ ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)',
+ 'PKINIT client verified DH reply',
+ 'PKINIT client found id-pkinit-san in KDC cert',
+ 'PKINIT client matched KDC principal krbtgt/')
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % file_identity],
- expected_trace=('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'PKINIT client received freshness token from KDC',
- 'PKINIT loading CA certs and CRLs from FILE',
- 'PKINIT client making DH request',
- 'Produced preauth for next request: 133, 16',
- 'PKINIT client verified DH reply',
- 'PKINIT client found id-pkinit-san in KDC cert',
- 'PKINIT client matched KDC principal krbtgt/'))
+ expected_trace=msgs)
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
@@ -194,19 +195,19 @@ minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}}
minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf)
realm.stop_kdc()
realm.start_kdc(env=minbits_env)
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Preauth module pkinit (16) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, 16',
- '/Key parameters not accepted',
- 'Preauth tryagain input types (16): 109, 133',
- 'trying again with KDC-provided parameters',
- 'Preauth module pkinit (16) tryagain returned: 0/Success',
- 'Followup preauth for next request: 16, 133')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Preauth module pkinit (16) (real) returned: 0/Success',
+ ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)',
+ '/Key parameters not accepted',
+ 'Preauth tryagain input types (16): 109, PA-FX-COOKIE (133)',
+ 'trying again with KDC-provided parameters',
+ 'Preauth module pkinit (16) tryagain returned: 0/Success',
+ ' preauth for next request: PA-PK-AS-REQ (16), PA-FX-COOKIE (133)')
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % file_identity],
- expected_trace=expected_trace)
+ expected_trace=msgs)
# Test enforcement of required freshness tokens. (We can leave
# freshness tokens required after this test.)
diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py
index fec0bf619..efb3ea20d 100644
--- a/src/tests/t_preauth.py
+++ b/src/tests/t_preauth.py
@@ -18,15 +18,15 @@ realm.kinit('nokeyuser', password('user'), expected_code=1,
# PA-FX-COOKIE; 2 is encrypted timestamp.
# Test normal preauth flow.
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- 'Decrypted AS reply')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ 'Decrypted AS reply')
realm.run(['./icred', realm.user_princ, password('user')],
- expected_msg='testval', expected_trace=expected_trace)
+ expected_msg='testval', expected_trace=msgs)
# Test successful optimistic preauth.
expected_trace = ('Attempting optimistic preauth',
@@ -39,136 +39,136 @@ realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')],
# Test optimistic preauth failing on client, followed by successful
# preauth using the same module.
-expected_trace = ('Attempting optimistic preauth',
- 'Processing preauth types: -123',
- '/induced optimistic fail',
- 'Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- 'Decrypted AS reply')
+msgs = ('Attempting optimistic preauth',
+ 'Processing preauth types: -123',
+ '/induced optimistic fail',
+ 'Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ 'Decrypted AS reply')
realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ,
password('user')], expected_msg='testval',
- expected_trace=expected_trace)
+ expected_trace=msgs)
# Test optimistic preauth failing on KDC, followed by successful preauth
# using the same module.
realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes'])
-expected_trace = ('Attempting optimistic preauth',
- 'Processing preauth types: -123',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: -123',
- '/Preauthentication failed',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- 'Decrypted AS reply')
+msgs = ('Attempting optimistic preauth',
+ 'Processing preauth types: -123',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: -123',
+ '/Preauthentication failed',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ 'Decrypted AS reply')
realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')],
- expected_msg='testval', expected_trace=expected_trace)
+ expected_msg='testval', expected_trace=msgs)
realm.run([kadminl, 'delstr', realm.user_princ, 'failopt'])
# Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies.
realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip'])
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- '/More preauthentication data is required',
- 'Continuing preauth mech -123',
- 'Processing preauth types: -123, 133',
- 'Produced preauth for next request: 133, -123',
- 'Decrypted AS reply')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/More preauthentication data is required',
+ 'Continuing preauth mech -123',
+ 'Processing preauth types: -123, PA-FX-COOKIE (133)',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ 'Decrypted AS reply')
realm.run(['./icred', realm.user_princ, password('user')],
- expected_msg='2rt: secondtrip', expected_trace=expected_trace)
+ expected_msg='2rt: secondtrip', expected_trace=msgs)
# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
# falling back to encrypted timestamp.
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- '/More preauthentication data is required',
- 'Continuing preauth mech -123',
- 'Processing preauth types: -123, 133',
- '/induced 2rt fail',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Encrypted timestamp (for ',
- 'module encrypted_timestamp (2) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, 2',
- 'Decrypted AS reply')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/More preauthentication data is required',
+ 'Continuing preauth mech -123',
+ 'Processing preauth types: -123, PA-FX-COOKIE (133)',
+ '/induced 2rt fail',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Encrypted timestamp (for ',
+ 'module encrypted_timestamp (2) (real) returned: 0/Success',
+ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
+ 'Decrypted AS reply')
realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')],
- expected_msg='2rt: secondtrip', expected_trace=expected_trace)
+ expected_msg='2rt: secondtrip', expected_trace=msgs)
# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
# falling back to encrypted timestamp.
realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes'])
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- '/More preauthentication data is required',
- 'Continuing preauth mech -123',
- 'Processing preauth types: -123, 133',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- '/Preauthentication failed',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Encrypted timestamp (for ',
- 'module encrypted_timestamp (2) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, 2',
- 'Decrypted AS reply')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/More preauthentication data is required',
+ 'Continuing preauth mech -123',
+ 'Processing preauth types: -123, PA-FX-COOKIE (133)',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/Preauthentication failed',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Encrypted timestamp (for ',
+ 'module encrypted_timestamp (2) (real) returned: 0/Success',
+ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
+ 'Decrypted AS reply')
realm.run(['./icred', realm.user_princ, password('user')],
- expected_msg='2rt: secondtrip', expected_trace=expected_trace)
+ expected_msg='2rt: secondtrip', expected_trace=msgs)
realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt'])
# Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC.
realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain'])
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- '/KDC has no support for encryption type',
- 'Recovering from KDC error 14 using preauth mech -123',
- 'Preauth tryagain input types (-123): -123, 133',
- 'Preauth module test (-123) tryagain returned: 0/Success',
- 'Followup preauth for next request: -123, 133',
- 'Decrypted AS reply')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/KDC has no support for encryption type',
+ 'Recovering from KDC error 14 using preauth mech -123',
+ 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)',
+ 'Preauth module test (-123) tryagain returned: 0/Success',
+ 'Followup preauth for next request: -123, PA-FX-COOKIE (133)',
+ 'Decrypted AS reply')
realm.run(['./icred', realm.user_princ, password('user')],
- expected_msg='tryagain: testagain', expected_trace=expected_trace)
+ expected_msg='tryagain: testagain', expected_trace=msgs)
# Test a client-side tryagain failure, falling back to encrypted
# timestamp.
-expected_trace = ('Sending unauthenticated request',
- '/Additional pre-authentication required',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, -123',
- '/KDC has no support for encryption type',
- 'Recovering from KDC error 14 using preauth mech -123',
- 'Preauth tryagain input types (-123): -123, 133',
- '/induced tryagain fail',
- 'Preauthenticating using KDC method data',
- 'Processing preauth types:',
- 'Encrypted timestamp (for ',
- 'module encrypted_timestamp (2) (real) returned: 0/Success',
- 'Produced preauth for next request: 133, 2',
- 'Decrypted AS reply')
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/KDC has no support for encryption type',
+ 'Recovering from KDC error 14 using preauth mech -123',
+ 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)',
+ '/induced tryagain fail',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Encrypted timestamp (for ',
+ 'module encrypted_timestamp (2) (real) returned: 0/Success',
+ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
+ 'Decrypted AS reply')
realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ,
- password('user')], expected_trace=expected_trace)
+ password('user')], expected_trace=msgs)
# Test that multiple stepwise initial creds operations can be
# performed with the same krb5_context, with proper tracking of

View File

@ -1,35 +0,0 @@
From 9dd3a84f324979c29e8ab4b472e98dfa73e6b290 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 7 May 2018 16:42:59 -0400
Subject: [PATCH] Log when non-root ksu authorization fails
If non-root user attempts to ksu but is denied by policy, log to
syslog at LOG_WARNING in keeping with other failure messages.
ticket: 8270
(cherry picked from commit 6cfa5c113e981f14f70ccafa20abfa5c46b665ba)
---
src/clients/ksu/main.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index c6321c01b..35ff8978f 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -417,6 +417,16 @@ main (argc, argv)
if (hp){
if (gb_err) fprintf(stderr, "%s", gb_err);
fprintf(stderr, _("account %s: authorization failed\n"), target_user);
+
+ if (cmd != NULL) {
+ syslog(LOG_WARNING,
+ "Account %s: authorization for %s for execution of %s failed",
+ target_user, source_user, cmd);
+ } else {
+ syslog(LOG_WARNING, "Account %s: authorization of %s failed",
+ target_user, source_user);
+ }
+
exit(1);
}

View File

@ -1,36 +0,0 @@
From 16c745b7e9e239535a8c71dc7022b477a5165e01 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 13 Jun 2018 15:07:48 -0400
Subject: [PATCH] Make docs build python3-compatible
python3 removed execfile(), which we use for loading version data and
paths information in docs. Call exec() directly instead.
ticket: 8692 (new)
(cherry picked from commit a7c6d98480f1e33454173f88381921472d72f80a)
---
doc/conf.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/conf.py b/doc/conf.py
index 25ba214a8..0555808e6 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -50,7 +50,7 @@ copyright = u'1985-2018, MIT'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
-execfile("version.py")
+exec(open("version.py").read())
# The short X.Y version.
r_list = [r_major, r_minor]
if r_patch:
@@ -238,7 +238,7 @@ if 'mansubs' in tags:
ckeytab = '``@CKTNAME@``'
elif 'pathsubs' in tags:
# Read configured paths from a file produced by the build system.
- execfile('paths.py')
+ exec(open("paths.py").read())
else:
bindir = ':ref:`BINDIR <paths>`'
sbindir = ':ref:`SBINDIR <paths>`'

View File

@ -0,0 +1,293 @@
From c3dd133cf06d55e3fe516a2aa8b4b37e203878da Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 8 Jan 2019 17:42:35 -0500
Subject: [PATCH] Make etype names in KDC logs human-readable
Introduce enctype_name() as a wrapper over krb5_enctype_to_name for
converting between registered constants and names. Adjust signatures
and rewrite ktypes2str() and rep_etypes2str() to operate on dynamic
buffers.
ticket: 8772 (new)
(cherry picked from commit a649279727490687d54becad91fde8cf7429d951)
---
src/kdc/kdc_log.c | 42 +++++++--------
src/kdc/kdc_util.c | 125 +++++++++++++++++++++++----------------------
src/kdc/kdc_util.h | 6 +--
3 files changed, 87 insertions(+), 86 deletions(-)
diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c
index 4eec50373..b160ba21a 100644
--- a/src/kdc/kdc_log.c
+++ b/src/kdc/kdc_log.c
@@ -65,7 +65,7 @@ log_as_req(krb5_context context,
{
const char *fromstring = 0;
char fromstringbuf[70];
- char ktypestr[128];
+ char *ktypestr = NULL;
const char *cname2 = cname ? cname : "<unknown client>";
const char *sname2 = sname ? sname : "<unknown server>";
@@ -74,26 +74,29 @@ log_as_req(krb5_context context,
fromstringbuf, sizeof(fromstringbuf));
if (!fromstring)
fromstring = "<unknown>";
- ktypes2str(ktypestr, sizeof(ktypestr),
- request->nktypes, request->ktype);
+
+ ktypestr = ktypes2str(request->ktype, request->nktypes);
if (status == NULL) {
/* success */
- char rep_etypestr[128];
- rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
+ char *rep_etypestr = rep_etypes2str(reply);
krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, "
"%s for %s"),
- ktypestr, fromstring, (unsigned int)authtime,
- rep_etypestr, cname2, sname2);
+ ktypestr ? ktypestr : "", fromstring,
+ (unsigned int)authtime,
+ rep_etypestr ? rep_etypestr : "", cname2, sname2);
+ free(rep_etypestr);
} else {
/* fail */
krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: %s: %s for %s%s%s"),
- ktypestr, fromstring, status,
- cname2, sname2, emsg ? ", " : "", emsg ? emsg : "");
+ ktypestr ? ktypestr : "", fromstring, status, cname2,
+ sname2, emsg ? ", " : "", emsg ? emsg : "");
}
krb5_db_audit_as_req(context, request,
local_addr->address, remote_addr->address,
client, server, authtime, errcode);
+
+ free(ktypestr);
}
/*
@@ -122,10 +125,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
unsigned int c_flags,
const char *status, krb5_error_code errcode, const char *emsg)
{
- char ktypestr[128];
+ char *ktypestr = NULL, *rep_etypestr = NULL;
const char *fromstring = 0;
char fromstringbuf[70];
- char rep_etypestr[128];
char *cname = NULL, *sname = NULL, *altcname = NULL;
char *logcname = NULL, *logsname = NULL, *logaltcname = NULL;
@@ -134,11 +136,6 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
fromstringbuf, sizeof(fromstringbuf));
if (!fromstring)
fromstring = "<unknown>";
- ktypes2str(ktypestr, sizeof(ktypestr), request->nktypes, request->ktype);
- if (!errcode)
- rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
- else
- rep_etypestr[0] = 0;
unparse_and_limit(ctx, cprinc, &cname);
logcname = (cname != NULL) ? cname : "<unknown client>";
@@ -151,10 +148,14 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
name (useful), and doesn't log ktypestr (probably not
important). */
if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) {
+ ktypestr = ktypes2str(request->ktype, request->nktypes);
+ rep_etypestr = rep_etypes2str(reply);
krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s "
"%s for %s%s%s"),
- ktypestr, fromstring, status, (unsigned int)authtime,
- rep_etypestr, !errcode ? "," : "", logcname, logsname,
+ ktypestr ? ktypestr : "", fromstring, status,
+ (unsigned int)authtime,
+ rep_etypestr ? rep_etypestr : "",
+ !errcode ? "," : "", logcname, logsname,
errcode ? ", " : "", errcode ? emsg : "");
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
krb5_klog_syslog(LOG_INFO,
@@ -171,9 +172,8 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
fromstring, status, (unsigned int)authtime,
logcname, logsname, logaltcname);
- /* OpenSolaris: audit_krb5kdc_tgs_req(...) or
- audit_krb5kdc_tgs_req_2ndtktmm(...) */
-
+ free(rep_etypestr);
+ free(ktypestr);
krb5_free_unparsed_name(ctx, cname);
krb5_free_unparsed_name(ctx, sname);
krb5_free_unparsed_name(ctx, altcname);
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 0155c28c6..f5c581c82 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1043,84 +1043,87 @@ void limit_string(char *name)
return;
}
-/*
- * L10_2 = log10(2**x), rounded up; log10(2) ~= 0.301.
- */
-#define L10_2(x) ((int)(((x * 301) + 999) / 1000))
+/* Wrapper of krb5_enctype_to_name() to include the PKINIT types. */
+static krb5_error_code
+enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
+{
+ char *name;
+
+ if (buflen == 0)
+ return EINVAL;
+ *buf = '\0'; /* ensure these are always valid C-strings */
+
+ /* rfc4556 recommends that clients wishing to indicate support for these
+ * pkinit algorithms include them in the etype field of the AS-REQ. */
+ if (ktype == ENCTYPE_DSA_SHA1_CMS)
+ name = "id-dsa-with-sha1-CmsOID";
+ else if (ktype == ENCTYPE_MD5_RSA_CMS)
+ name = "md5WithRSAEncryption-CmsOID";
+ else if (ktype == ENCTYPE_SHA1_RSA_CMS)
+ name = "sha-1WithRSAEncryption-CmsOID";
+ else if (ktype == ENCTYPE_RC2_CBC_ENV)
+ name = "rc2-cbc-EnvOID";
+ else if (ktype == ENCTYPE_RSA_ENV)
+ name = "rsaEncryption-EnvOID";
+ else if (ktype == ENCTYPE_RSA_ES_OAEP_ENV)
+ name = "id-RSAES-OAEP-EnvOID";
+ else if (ktype == ENCTYPE_DES3_CBC_ENV)
+ name = "des-ede3-cbc-EnvOID";
+ else
+ return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
-/*
- * Max length of sprintf("%ld") for an int of type T; includes leading
- * minus sign and terminating NUL.
- */
-#define D_LEN(t) (L10_2(sizeof(t) * CHAR_BIT) + 2)
+ if (strlcpy(name, buf, buflen) >= buflen)
+ return ENOMEM;
+ return 0;
+}
-void
-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype)
+char *
+ktypes2str(krb5_enctype *ktype, int nktypes)
{
+ struct k5buf buf;
int i;
- char stmp[D_LEN(krb5_enctype) + 1];
- char *p;
+ char name[64];
- if (nktypes < 0
- || len < (sizeof(" etypes {...}") + D_LEN(int))) {
- *s = '\0';
- return;
- }
+ if (nktypes < 0)
+ return NULL;
- snprintf(s, len, "%d etypes {", nktypes);
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add_fmt(&buf, "%d etypes {", nktypes);
for (i = 0; i < nktypes; i++) {
- snprintf(stmp, sizeof(stmp), "%s%ld", i ? " " : "", (long)ktype[i]);
- if (strlen(s) + strlen(stmp) + sizeof("}") > len)
- break;
- strlcat(s, stmp, len);
+ enctype_name(ktype[i], name, sizeof(name));
+ k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]);
}
- if (i < nktypes) {
- /*
- * We broke out of the loop. Try to truncate the list.
- */
- p = s + strlen(s);
- while (p - s + sizeof("...}") > len) {
- while (p > s && *p != ' ' && *p != '{')
- *p-- = '\0';
- if (p > s && *p == ' ') {
- *p-- = '\0';
- continue;
- }
- }
- strlcat(s, "...", len);
- }
- strlcat(s, "}", len);
- return;
+ k5_buf_add(&buf, "}");
+ return buf.data;
}
-void
-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep)
+char *
+rep_etypes2str(krb5_kdc_rep *rep)
{
- char stmp[sizeof("ses=") + D_LEN(krb5_enctype)];
-
- if (len < (3 * D_LEN(krb5_enctype)
- + sizeof("etypes {rep= tkt= ses=}"))) {
- *s = '\0';
- return;
- }
+ struct k5buf buf;
+ char name[64];
+ krb5_enctype etype;
- snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype);
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add(&buf, "etypes {rep=");
+ enctype_name(rep->enc_part.enctype, name, sizeof(name));
+ k5_buf_add_fmt(&buf, "%s(%ld)", name, (long)rep->enc_part.enctype);
if (rep->ticket != NULL) {
- snprintf(stmp, sizeof(stmp),
- " tkt=%ld", (long)rep->ticket->enc_part.enctype);
- strlcat(s, stmp, len);
+ etype = rep->ticket->enc_part.enctype;
+ enctype_name(etype, name, sizeof(name));
+ k5_buf_add_fmt(&buf, ", tkt=%s(%ld)", name, (long)etype);
}
- if (rep->ticket != NULL
- && rep->ticket->enc_part2 != NULL
- && rep->ticket->enc_part2->session != NULL) {
- snprintf(stmp, sizeof(stmp), " ses=%ld",
- (long)rep->ticket->enc_part2->session->enctype);
- strlcat(s, stmp, len);
+ if (rep->ticket != NULL && rep->ticket->enc_part2 != NULL &&
+ rep->ticket->enc_part2->session != NULL) {
+ etype = rep->ticket->enc_part2->session->enctype;
+ enctype_name(etype, name, sizeof(name));
+ k5_buf_add_fmt(&buf, ", ses=%s(%ld)", name, (long)etype);
}
- strlcat(s, "}", len);
- return;
+
+ k5_buf_add(&buf, "}");
+ return buf.data;
}
static krb5_error_code
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 6ec645fc3..25077cbf5 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -110,11 +110,9 @@ select_session_keytype (kdc_realm_t *kdc_active_realm,
void limit_string (char *name);
-void
-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype);
+char *ktypes2str(krb5_enctype *ktype, int nktypes);
-void
-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep);
+char *rep_etypes2str(krb5_kdc_rep *rep);
/* authind.c */
krb5_boolean

View File

@ -1,67 +0,0 @@
From 5587c1de938324faa1871e08ccfc835415acb443 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 17 Jul 2018 11:29:19 -0400
Subject: [PATCH] Make krb5kdc -p affect TCP ports
Now that the KDC listens for TCP connections by default (ticket 6731),
the "-p" option should affect both UDP and TCP default listening
ports.
ticket: 8715 (new)
(cherry picked from commit eb514587acc5c357bf0f554199bf0489b5515f8b)
---
doc/admin/admin_commands/krb5kdc.rst | 12 ++++++------
src/kdc/main.c | 12 ++++--------
2 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/doc/admin/admin_commands/krb5kdc.rst b/doc/admin/admin_commands/krb5kdc.rst
index 7ec4ee4d3..bda2c015c 100644
--- a/doc/admin/admin_commands/krb5kdc.rst
+++ b/doc/admin/admin_commands/krb5kdc.rst
@@ -57,12 +57,12 @@ The **-P** *pid_file* option tells the KDC to write its PID into
the KDC is still running and to allow init scripts to stop the correct
process.
-The **-p** *portnum* option specifies the default UDP port numbers
-which the KDC should listen on for Kerberos version 5 requests, as a
-comma-separated list. This value overrides the UDP port numbers
-specified in the :ref:`kdcdefaults` section of :ref:`kdc.conf(5)`, but
-may be overridden by realm-specific values. If no value is given from
-any source, the default port is 88.
+The **-p** *portnum* option specifies the default UDP and TCP port
+numbers which the KDC should listen on for Kerberos version 5
+requests, as a comma-separated list. This value overrides the port
+numbers specified in the :ref:`kdcdefaults` section of
+:ref:`kdc.conf(5)`, but may be overridden by realm-specific values.
+If no value is given from any source, the default port is 88.
The **-w** *numworkers* option tells the KDC to fork *numworkers*
processes to listen to the KDC ports and process requests in parallel.
diff --git a/src/kdc/main.c b/src/kdc/main.c
index ccac3a759..89dac23ae 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -793,19 +793,15 @@ initialize_realms(krb5_context kcontext, int argc, char **argv,
pid_file = optarg;
break;
case 'p':
- if (def_udp_listen)
- free(def_udp_listen);
+ free(def_udp_listen);
+ free(def_tcp_listen);
def_udp_listen = strdup(optarg);
- if (!def_udp_listen) {
+ def_tcp_listen = strdup(optarg);
+ if (def_udp_listen == NULL || def_tcp_listen == NULL) {
fprintf(stderr, _(" KDC cannot initialize. Not enough "
"memory\n"));
exit(1);
}
-#if 0 /* not yet */
- if (default_tcp_ports)
- free(default_tcp_ports);
- default_tcp_ports = strdup(optarg);
-#endif
break;
case 'T':
time_offset = atoi(optarg);

View File

@ -0,0 +1,250 @@
From 4f56267a204764ed3d00e69cd16a0e877f055455 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 10 Jan 2019 16:34:54 -0500
Subject: [PATCH] Mark deprecated enctypes when used
Preface ETYPE_DEPRECATED enctypes with "DEPRECATED:" in klist output,
KDC logs, and kadmin interactions. Also complain in krb5kdc when the
stash file has a deprecated enctype or a deprecated enctype is
requested with -k.
ticket: 8773 (new)
(cherry picked from commit 8d8e68283b599e680f9fe45eff8af397e827bd6c)
---
src/clients/klist/klist.c | 14 ++++++++++----
src/kadmin/cli/kadmin.c | 6 +++++-
src/kdc/kdc_util.c | 9 +++++++++
src/kdc/main.c | 19 +++++++++++++++++++
src/tests/gssapi/t_enctypes.py | 15 +++++++++------
src/tests/t_keyrollover.py | 8 +++++---
src/tests/t_sesskeynego.py | 4 ++--
7 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index 70adb54e8..8c307151a 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -571,11 +571,17 @@ static char *
etype_string(krb5_enctype enctype)
{
static char buf[100];
- krb5_error_code ret;
+ char *bp = buf;
+ size_t deplen, buflen = sizeof(buf);
- ret = krb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf));
- if (ret)
- snprintf(buf, sizeof(buf), "etype %d", enctype);
+ if (krb5int_c_deprecated_enctype(enctype)) {
+ deplen = strlcpy(bp, "DEPRECATED:", buflen);
+ buflen -= deplen;
+ bp += deplen;
+ }
+
+ if (krb5_enctype_to_name(enctype, FALSE, bp, buflen))
+ snprintf(bp, buflen, "etype %d", enctype);
return buf;
}
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index ed581ee79..cc74921bf 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -1451,12 +1451,16 @@ kadmin_getprinc(int argc, char *argv[])
for (i = 0; i < dprinc.n_key_data; i++) {
krb5_key_data *key_data = &dprinc.key_data[i];
char enctype[BUFSIZ], salttype[BUFSIZ];
+ char *deprecated = "";
if (krb5_enctype_to_name(key_data->key_data_type[0], FALSE,
enctype, sizeof(enctype)))
snprintf(enctype, sizeof(enctype), _("<Encryption type 0x%x>"),
key_data->key_data_type[0]);
- printf("Key: vno %d, %s", key_data->key_data_kvno, enctype);
+ if (krb5int_c_deprecated_enctype(key_data->key_data_type[0]))
+ deprecated = "DEPRECATED:";
+ printf("Key: vno %d, %s%s", key_data->key_data_kvno, deprecated,
+ enctype);
if (key_data->key_data_ver > 1 &&
key_data->key_data_type[1] != KRB5_KDB_SALTTYPE_NORMAL) {
if (krb5_salttype_to_string(key_data->key_data_type[1],
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index f5c581c82..96c88edc1 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1048,11 +1048,20 @@ static krb5_error_code
enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
{
char *name;
+ size_t len;
if (buflen == 0)
return EINVAL;
*buf = '\0'; /* ensure these are always valid C-strings */
+ if (krb5int_c_deprecated_enctype(ktype)) {
+ len = strlcpy(buf, "DEPRECATED:", buflen);
+ if (len >= buflen)
+ return ENOMEM;
+ buflen -= len;
+ buf += len;
+ }
+
/* rfc4556 recommends that clients wishing to indicate support for these
* pkinit algorithms include them in the etype field of the AS-REQ. */
if (ktype == ENCTYPE_DSA_SHA1_CMS)
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 663fd6303..60092a0df 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -210,12 +210,23 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
char *svalue = NULL;
const char *hierarchy[4];
krb5_kvno mkvno = IGNORE_VNO;
+ char ename[32];
memset(rdp, 0, sizeof(kdc_realm_t));
if (!realm) {
kret = EINVAL;
goto whoops;
}
+
+ if (def_enctype != ENCTYPE_UNKNOWN &&
+ krb5int_c_deprecated_enctype(def_enctype)) {
+ if (krb5_enctype_to_name(def_enctype, FALSE, ename, sizeof(ename)))
+ ename[0] = '\0';
+ fprintf(stderr,
+ _("Requested master password enctype %s in %s is DEPRECATED!"),
+ ename, realm);
+ }
+
hierarchy[0] = KRB5_CONF_REALMS;
hierarchy[1] = realm;
hierarchy[3] = NULL;
@@ -370,6 +381,14 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
goto whoops;
}
+ if (krb5int_c_deprecated_enctype(rdp->realm_mkey.enctype)) {
+ if (krb5_enctype_to_name(rdp->realm_mkey.enctype, FALSE, ename,
+ sizeof(ename)))
+ ename[0] = '\0';
+ fprintf(stderr, _("Stash file %s uses DEPRECATED enctype %s!"),
+ rdp->realm_stash, ename);
+ }
+
if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
&rdp->realm_mkey))) {
kdc_err(rdp->realm_context, kret,
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index 5d9f80e04..ca3d32d21 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -9,8 +9,11 @@ from k5test import *
aes256 = 'aes256-cts-hmac-sha1-96'
aes128 = 'aes128-cts-hmac-sha1-96'
des3 = 'des3-cbc-sha1'
+d_des3 = 'DEPRECATED:des3-cbc-sha1'
des3raw = 'des3-cbc-raw'
+d_des3raw = 'DEPRECATED:des3-cbc-raw'
rc4 = 'arcfour-hmac'
+d_rc4 = 'DEPRECATED:arcfour-hmac'
# These tests make assumptions about the default enctype lists, so set
# them explicitly rather than relying on the library defaults.
@@ -92,7 +95,7 @@ test_err('acc aes128', None, 'aes128-cts',
# no acceptor subkey will be generated because we can't upgrade to a
# CFX enctype.
test('init des3', 'des3', None,
- tktenc=aes256, tktsession=des3,
+ tktenc=aes256, tktsession=d_des3,
proto='rfc1964', isubkey=des3raw, asubkey=None)
# Force the ticket session key to be rc4, so we can test some subkey
@@ -103,7 +106,7 @@ realm.run([kadminl, 'setstr', realm.host_princ, 'session_enctypes', 'rc4'])
# [aes256 aes128 des3] and the acceptor should upgrade to an aes256
# subkey.
test('upgrade noargs', None, None,
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='cfx', isubkey=rc4, asubkey=aes256)
# If the initiator won't permit rc4 as a session key, it won't be able
@@ -113,14 +116,14 @@ test_err('upgrade init aes', 'aes', None, 'no support for encryption type')
# If the initiator permits rc4 but prefers aes128, it will send an
# upgrade list of [aes128] and the acceptor will upgrade to aes128.
test('upgrade init aes128+rc4', 'aes128-cts rc4', None,
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='cfx', isubkey=rc4, asubkey=aes128)
# If the initiator permits rc4 but prefers des3, it will send an
# upgrade list of [des3], but the acceptor won't generate a subkey
# because des3 isn't a CFX enctype.
test('upgrade init des3+rc4', 'des3 rc4', None,
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='rfc1964', isubkey=rc4, asubkey=None)
# If the acceptor permits only aes128, subkey negotiation will fail
@@ -134,14 +137,14 @@ test_err('upgrade acc aes128', None, 'aes128-cts',
# If the acceptor permits rc4 but prefers aes128, it will negotiate an
# upgrade to aes128.
test('upgrade acc aes128 rc4', None, 'aes128-cts rc4',
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='cfx', isubkey=rc4, asubkey=aes128)
# In this test, the initiator and acceptor each prefer an AES enctype
# to rc4, but they can't agree on which one, so no subkey is
# generated.
test('upgrade mismatch', 'aes128-cts rc4', 'aes256-cts rc4',
- tktenc=aes256, tktsession=rc4,
+ tktenc=aes256, tktsession=d_rc4,
proto='rfc1964', isubkey=rc4, asubkey=None)
success('gss_krb5_set_allowable_enctypes tests')
diff --git a/src/tests/t_keyrollover.py b/src/tests/t_keyrollover.py
index 7c8d828f0..4af6804f2 100755
--- a/src/tests/t_keyrollover.py
+++ b/src/tests/t_keyrollover.py
@@ -22,8 +22,9 @@ realm.run([kvno, princ1])
realm.run([kadminl, 'purgekeys', realm.krbtgt_princ])
# Make sure an old TGT fails after purging old TGS key.
realm.run([kvno, princ2], expected_code=1)
-msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): des-cbc-crc, des-cbc-crc' % \
- (realm.realm, realm.realm)
+ddes = "DEPRECATED:des-cbc-crc"
+msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): %s, %s' % \
+ (realm.realm, realm.realm, ddes, ddes)
realm.run([klist, '-e'], expected_msg=msg)
# Check that new key actually works.
@@ -48,7 +49,8 @@ realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts',
realm.krbtgt_princ])
realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ])
out = realm.run([kadminl, 'getprinc', realm.krbtgt_princ])
-if 'vno 1, aes256' not in out or 'vno 1, des3' not in out:
+if 'vno 1, aes256-cts' not in out or \
+ 'vno 1, DEPRECATED:des3-cbc-sha1' not in out:
fail('keyrollover: setup for TGS enctype test failed')
# Now present the DES3 ticket to the KDC and make sure it's rejected.
realm.run([kvno, realm.host_princ], expected_code=1)
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 448092387..da02f224a 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -62,11 +62,11 @@ test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
# 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
'rc4-hmac,aes128-cts,aes256-cts'])
-test_kvno(realm, 'arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
# 3c: Test des-cbc-crc default assumption.
realm.run([kadminl, 'delstr', 'server', 'session_enctypes'])
-test_kvno(realm, 'des-cbc-crc', 'aes256-cts-hmac-sha1-96')
+test_kvno(realm, 'DEPRECATED:des-cbc-crc', 'aes256-cts-hmac-sha1-96')
realm.stop()
# Last go: test that we can disable the des-cbc-crc assumption

View File

@ -1,151 +0,0 @@
From ee941a490268bb045ec7e153bdf229adcd6d2f73 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 26 Mar 2018 10:54:29 -0400
Subject: [PATCH] Move zap() definition to k5-platform.h
Make it possible to use zap() in parts of the code which should not
include k5-int.h by moving its definition to k5-platform.h.
(cherry picked from commit df6bef6f9ea6a5f6f3956a2988cd658c78aae817)
---
src/include/k5-int.h | 45 -------------------------------------
src/include/k5-platform.h | 47 ++++++++++++++++++++++++++++++++++++++-
src/util/support/zap.c | 4 ++--
3 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 1c1d9783b..69b81a7f7 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -639,51 +639,6 @@ krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
krb5_error_code
k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]);
-/*
- * Attempt to zero memory in a way that compilers won't optimize out.
- *
- * This mechanism should work even for heap storage about to be freed,
- * or automatic storage right before we return from a function.
- *
- * Then, even if we leak uninitialized memory someplace, or UNIX
- * "core" files get created with world-read access, some of the most
- * sensitive data in the process memory will already be safely wiped.
- *
- * We're not going so far -- yet -- as to try to protect key data that
- * may have been written into swap space....
- */
-#ifdef _WIN32
-# define zap(ptr, len) SecureZeroMemory(ptr, len)
-#elif defined(__STDC_LIB_EXT1__)
-/*
- * Use memset_s() which cannot be optimized out. Avoid memset_s(NULL, 0, 0, 0)
- * which would cause a runtime constraint violation.
- */
-static inline void zap(void *ptr, size_t len)
-{
- if (len > 0)
- memset_s(ptr, len, 0, len);
-}
-#elif defined(__GNUC__) || defined(__clang__)
-/*
- * Use an asm statement which declares a memory clobber to force the memset to
- * be carried out. Avoid memset(NULL, 0, 0) which has undefined behavior.
- */
-static inline void zap(void *ptr, size_t len)
-{
- if (len > 0)
- memset(ptr, 0, len);
- __asm__ __volatile__("" : : "r" (ptr) : "memory");
-}
-#else
-/*
- * Use a function from libkrb5support to defeat inlining unless link-time
- * optimization is used. The function uses a volatile pointer, which prevents
- * current compilers from optimizing out the memset.
- */
-# define zap(ptr, len) krb5int_zap(ptr, len)
-#endif
-
/* Convenience function: zap and free ptr if it is non-NULL. */
static inline void
zapfree(void *ptr, size_t len)
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
index 548c0486d..07ef6a4ca 100644
--- a/src/include/k5-platform.h
+++ b/src/include/k5-platform.h
@@ -40,7 +40,7 @@
* + [v]asprintf
* + strerror_r
* + mkstemp
- * + zap (support function; macro is in k5-int.h)
+ * + zap (support function and macro)
* + constant time memory comparison
* + path manipulation
* + _, N_, dgettext, bindtextdomain (for localization)
@@ -1022,6 +1022,51 @@ extern int krb5int_gettimeofday(struct timeval *tp, void *ignore);
#define gettimeofday krb5int_gettimeofday
#endif
+/*
+ * Attempt to zero memory in a way that compilers won't optimize out.
+ *
+ * This mechanism should work even for heap storage about to be freed,
+ * or automatic storage right before we return from a function.
+ *
+ * Then, even if we leak uninitialized memory someplace, or UNIX
+ * "core" files get created with world-read access, some of the most
+ * sensitive data in the process memory will already be safely wiped.
+ *
+ * We're not going so far -- yet -- as to try to protect key data that
+ * may have been written into swap space....
+ */
+#ifdef _WIN32
+# define zap(ptr, len) SecureZeroMemory(ptr, len)
+#elif defined(__STDC_LIB_EXT1__)
+/*
+ * Use memset_s() which cannot be optimized out. Avoid memset_s(NULL, 0, 0, 0)
+ * which would cause a runtime constraint violation.
+ */
+static inline void zap(void *ptr, size_t len)
+{
+ if (len > 0)
+ memset_s(ptr, len, 0, len);
+}
+#elif defined(__GNUC__) || defined(__clang__)
+/*
+ * Use an asm statement which declares a memory clobber to force the memset to
+ * be carried out. Avoid memset(NULL, 0, 0) which has undefined behavior.
+ */
+static inline void zap(void *ptr, size_t len)
+{
+ if (len > 0)
+ memset(ptr, 0, len);
+ __asm__ __volatile__("" : : "r" (ptr) : "memory");
+}
+#else
+/*
+ * Use a function from libkrb5support to defeat inlining unless link-time
+ * optimization is used. The function uses a volatile pointer, which prevents
+ * current compilers from optimizing out the memset.
+ */
+# define zap(ptr, len) krb5int_zap(ptr, len)
+#endif
+
extern void krb5int_zap(void *ptr, size_t len);
/*
diff --git a/src/util/support/zap.c b/src/util/support/zap.c
index ed31630db..2f6cdd70e 100644
--- a/src/util/support/zap.c
+++ b/src/util/support/zap.c
@@ -25,8 +25,8 @@
*/
/*
- * krb5int_zap() is used by zap() (a static inline function defined in
- * k5-int.h) on non-Windows, non-gcc compilers, in order to prevent the
+ * krb5int_zap() is used by zap() (a macro or static inline function defined in
+ * k5-platform.h) on non-Windows, non-gcc compilers, in order to prevent the
* compiler from inlining and optimizing out the memset() call.
*/

View File

@ -1,114 +0,0 @@
From 5d868264bca1771aa16abbc8cc0aefb0e1750a73 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 6 Jun 2018 17:58:41 -0400
Subject: [PATCH] Process profile includedir in sorted order
In the profile library, use k5_dir_filenames() so that files within an
included directory are read in a predictable order (alphanumeric
within the C locale).
ticket: 8686
(cherry picked from commit f574eda48740ad192f51e9a382a205e2ea0e60ad)
---
doc/admin/conf_files/krb5_conf.rst | 4 ++-
src/util/profile/prof_parse.c | 56 +++++-------------------------
2 files changed, 12 insertions(+), 48 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 2574e5c26..ce545492d 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -60,7 +60,9 @@ alphanumeric characters, dashes, or underscores. Starting in release
1.15, files with names ending in ".conf" are also included, unless the
name begins with ".". Included profile files are syntactically
independent of their parents, so each included file must begin with a
-section header.
+section header. Starting in release 1.17, files are read in
+alphanumeric order; in previous releases, they may be read in any
+order.
The krb5.conf file can specify that configuration should be obtained
from a loadable module, rather than the file itself, using the
diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c
index 1baceea9e..531e4a099 100644
--- a/src/util/profile/prof_parse.c
+++ b/src/util/profile/prof_parse.c
@@ -246,59 +246,22 @@ static int valid_name(const char *filename)
* Include files within dirname. Only files with names ending in ".conf", or
* consisting entirely of alphanumeric characters, dashes, and underscores are
* included. This restriction avoids including editor backup files, .rpmsave
- * files, and the like.
+ * files, and the like. Files are processed in alphanumeric order.
*/
static errcode_t parse_include_dir(const char *dirname,
struct profile_node *root_section)
{
-#ifdef _WIN32
- char *wildcard = NULL, *pathname;
- WIN32_FIND_DATA ffd;
- HANDLE handle;
errcode_t retval = 0;
+ char **fnames, *pathname;
+ int i;
- if (asprintf(&wildcard, "%s\\*", dirname) < 0)
- return ENOMEM;
-
- handle = FindFirstFile(wildcard, &ffd);
- if (handle == INVALID_HANDLE_VALUE) {
- retval = PROF_FAIL_INCLUDE_DIR;
- goto cleanup;
- }
-
- do {
- if (!valid_name(ffd.cFileName))
- continue;
- if (asprintf(&pathname, "%s\\%s", dirname, ffd.cFileName) < 0) {
- retval = ENOMEM;
- break;
- }
- retval = parse_include_file(pathname, root_section);
- free(pathname);
- if (retval)
- break;
- } while (FindNextFile(handle, &ffd) != 0);
-
- FindClose(handle);
-
-cleanup:
- free(wildcard);
- return retval;
-
-#else /* not _WIN32 */
-
- DIR *dir;
- char *pathname;
- errcode_t retval = 0;
- struct dirent *ent;
-
- dir = opendir(dirname);
- if (dir == NULL)
+ if (k5_dir_filenames(dirname, &fnames) != 0)
return PROF_FAIL_INCLUDE_DIR;
- while ((ent = readdir(dir)) != NULL) {
- if (!valid_name(ent->d_name))
+
+ for (i = 0; fnames != NULL && fnames[i] != NULL; i++) {
+ if (!valid_name(fnames[i]))
continue;
- if (asprintf(&pathname, "%s/%s", dirname, ent->d_name) < 0) {
+ if (asprintf(&pathname, "%s/%s", dirname, fnames[i]) < 0) {
retval = ENOMEM;
break;
}
@@ -307,9 +270,8 @@ cleanup:
if (retval)
break;
}
- closedir(dir);
+ k5_free_filenames(fnames);
return retval;
-#endif /* not _WIN32 */
}
static errcode_t parse_line(char *line, struct parse_state *state,

View File

@ -0,0 +1,34 @@
From 11ebf658c737baddcd5ce91e018213f28c279737 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 14 Feb 2019 11:50:35 -0500
Subject: [PATCH] Properly size #ifdef in k5_cccol_lock()
The cleanup code only could get executed in the USE_CCAPI_V3 case, so
move it inside that block. Reported by Coverity.
(cherry picked from commit 444a15f9cf82b9a6c1bca3f20307f82fee91c228)
(cherry picked from commit e2a0e04fb3be9297a8c532dd35a7c1045cae88f4)
---
src/lib/krb5/ccache/ccbase.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
index 8198f2b9b..2702bef69 100644
--- a/src/lib/krb5/ccache/ccbase.c
+++ b/src/lib/krb5/ccache/ccbase.c
@@ -511,7 +511,6 @@ krb5_cccol_lock(krb5_context context)
#endif
#ifdef USE_CCAPI_V3
ret = krb5_stdccv3_context_lock(context);
-#endif
if (ret) {
k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
k5_cc_mutex_unlock(context, &krb5int_cc_file_mutex);
@@ -519,6 +518,7 @@ krb5_cccol_lock(krb5_context context)
k5_cc_mutex_unlock(context, &cccol_lock);
return ret;
}
+#endif
k5_mutex_unlock(&cc_typelist_lock);
return ret;
}

View File

@ -1,393 +0,0 @@
From 7c59b7ee063489a4259c34b725728fee7e411c46 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 21 Dec 2017 11:28:52 -0500
Subject: [PATCH] Refactor KDC krb5_pa_data utility functions
Move alloc_padata from fast_util.c to kdc_util.c and make it
non-static so it can be used by other files. Rename it to
alloc_pa_data for consistency with add_pa_data_element. Make it
correctly handle zero length using a null contents pointer.
Make add_pa_data_element claim both the container and contents memory
from the caller, now that callers can use alloc_pa_data to simplify
allocation and copying. Remove the copy parameter and the unused
context parameter, and put the list parameter first. Adjust all
callers accordingly, making small simplifications to memory handling
where applicable.
(cherry picked from commit 4af478c18b02e1d2444a328bb79e6976ef3d312b)
---
src/kdc/fast_util.c | 28 +------
src/kdc/kdc_preauth.c | 14 ++--
src/kdc/kdc_util.c | 187 +++++++++++++++++++++---------------------
src/kdc/kdc_util.h | 8 +-
4 files changed, 109 insertions(+), 128 deletions(-)
diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c
index e05107ef3..6a3fc11b9 100644
--- a/src/kdc/fast_util.c
+++ b/src/kdc/fast_util.c
@@ -451,36 +451,12 @@ kdc_fast_hide_client(struct kdc_request_state *state)
return (state->fast_options & KRB5_FAST_OPTION_HIDE_CLIENT_NAMES) != 0;
}
-/* Allocate a pa-data entry with an uninitialized buffer of size len. */
-static krb5_error_code
-alloc_padata(krb5_preauthtype pa_type, size_t len, krb5_pa_data **out)
-{
- krb5_pa_data *pa;
- uint8_t *buf;
-
- *out = NULL;
- buf = malloc(len);
- if (buf == NULL)
- return ENOMEM;
- pa = malloc(sizeof(*pa));
- if (pa == NULL) {
- free(buf);
- return ENOMEM;
- }
- pa->magic = KV5M_PA_DATA;
- pa->pa_type = pa_type;
- pa->length = len;
- pa->contents = buf;
- *out = pa;
- return 0;
-}
-
/* Create a pa-data entry with the specified type and contents. */
static krb5_error_code
make_padata(krb5_preauthtype pa_type, const void *contents, size_t len,
krb5_pa_data **out)
{
- if (alloc_padata(pa_type, len, out) != 0)
+ if (alloc_pa_data(pa_type, len, out) != 0)
return ENOMEM;
memcpy((*out)->contents, contents, len);
return 0;
@@ -720,7 +696,7 @@ kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state,
goto cleanup;
/* Construct the cookie pa-data entry. */
- ret = alloc_padata(KRB5_PADATA_FX_COOKIE, 8 + enc.ciphertext.length, &pa);
+ ret = alloc_pa_data(KRB5_PADATA_FX_COOKIE, 8 + enc.ciphertext.length, &pa);
memcpy(pa->contents, "MIT1", 4);
store_32_be(kvno, pa->contents + 4);
memcpy(pa->contents + 8, enc.ciphertext.data, enc.ciphertext.length);
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 739c5e776..edc30bd83 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -1617,18 +1617,20 @@ return_referral_enc_padata( krb5_context context,
{
krb5_error_code code;
krb5_tl_data tl_data;
- krb5_pa_data pa_data;
+ krb5_pa_data *pa;
tl_data.tl_data_type = KRB5_TL_SVR_REFERRAL_DATA;
code = krb5_dbe_lookup_tl_data(context, server, &tl_data);
if (code || tl_data.tl_data_length == 0)
return 0;
- pa_data.magic = KV5M_PA_DATA;
- pa_data.pa_type = KRB5_PADATA_SVR_REFERRAL_INFO;
- pa_data.length = tl_data.tl_data_length;
- pa_data.contents = tl_data.tl_data_contents;
- return add_pa_data_element(context, &pa_data, &reply->enc_padata, TRUE);
+ code = alloc_pa_data(KRB5_PADATA_SVR_REFERRAL_INFO, tl_data.tl_data_length,
+ &pa);
+ if (code)
+ return code;
+ memcpy(pa->contents, tl_data.tl_data_contents, tl_data.tl_data_length);
+ /* add_pa_data_element() claims pa on success or failure. */
+ return add_pa_data_element(&reply->enc_padata, pa);
}
krb5_error_code
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 754570c01..13111215d 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1353,9 +1353,9 @@ kdc_make_s4u2self_rep(krb5_context context,
krb5_enc_kdc_rep_part *reply_encpart)
{
krb5_error_code code;
- krb5_data *data = NULL;
+ krb5_data *der_user_id = NULL, *der_s4u_x509_user = NULL;
krb5_pa_s4u_x509_user rep_s4u_user;
- krb5_pa_data padata;
+ krb5_pa_data *pa;
krb5_enctype enctype;
krb5_keyusage usage;
@@ -1366,7 +1366,7 @@ kdc_make_s4u2self_rep(krb5_context context,
rep_s4u_user.user_id.options =
req_s4u_user->user_id.options & KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE;
- code = encode_krb5_s4u_userid(&rep_s4u_user.user_id, &data);
+ code = encode_krb5_s4u_userid(&rep_s4u_user.user_id, &der_user_id);
if (code != 0)
goto cleanup;
@@ -1377,29 +1377,25 @@ kdc_make_s4u2self_rep(krb5_context context,
code = krb5_c_make_checksum(context, req_s4u_user->cksum.checksum_type,
tgs_subkey != NULL ? tgs_subkey : tgs_session,
- usage, data,
- &rep_s4u_user.cksum);
+ usage, der_user_id, &rep_s4u_user.cksum);
if (code != 0)
goto cleanup;
- krb5_free_data(context, data);
- data = NULL;
-
- code = encode_krb5_pa_s4u_x509_user(&rep_s4u_user, &data);
+ code = encode_krb5_pa_s4u_x509_user(&rep_s4u_user, &der_s4u_x509_user);
if (code != 0)
goto cleanup;
- padata.magic = KV5M_PA_DATA;
- padata.pa_type = KRB5_PADATA_S4U_X509_USER;
- padata.length = data->length;
- padata.contents = (krb5_octet *)data->data;
-
- code = add_pa_data_element(context, &padata, &reply->padata, FALSE);
+ /* Add a padata element, stealing memory from der_s4u_x509_user. */
+ code = alloc_pa_data(KRB5_PADATA_S4U_X509_USER, 0, &pa);
+ if (code != 0)
+ goto cleanup;
+ pa->length = der_s4u_x509_user->length;
+ pa->contents = (uint8_t *)der_s4u_x509_user->data;
+ der_s4u_x509_user->data = NULL;
+ /* add_pa_data_element() claims pa on success or failure. */
+ code = add_pa_data_element(&reply->padata, pa);
if (code != 0)
goto cleanup;
-
- free(data);
- data = NULL;
if (tgs_subkey != NULL)
enctype = tgs_subkey->enctype;
@@ -1413,33 +1409,27 @@ kdc_make_s4u2self_rep(krb5_context context,
*/
if ((req_s4u_user->user_id.options & KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE) &&
enctype_requires_etype_info_2(enctype) == FALSE) {
- padata.length = req_s4u_user->cksum.length +
- rep_s4u_user.cksum.length;
- padata.contents = malloc(padata.length);
- if (padata.contents == NULL) {
- code = ENOMEM;
+ code = alloc_pa_data(KRB5_PADATA_S4U_X509_USER,
+ req_s4u_user->cksum.length +
+ rep_s4u_user.cksum.length, &pa);
+ if (code != 0)
goto cleanup;
- }
+ memcpy(pa->contents,
+ req_s4u_user->cksum.contents, req_s4u_user->cksum.length);
+ memcpy(&pa->contents[req_s4u_user->cksum.length],
+ rep_s4u_user.cksum.contents, rep_s4u_user.cksum.length);
- memcpy(padata.contents,
- req_s4u_user->cksum.contents,
- req_s4u_user->cksum.length);
- memcpy(&padata.contents[req_s4u_user->cksum.length],
- rep_s4u_user.cksum.contents,
- rep_s4u_user.cksum.length);
-
- code = add_pa_data_element(context,&padata,
- &reply_encpart->enc_padata, FALSE);
- if (code != 0) {
- free(padata.contents);
+ /* add_pa_data_element() claims pa on success or failure. */
+ code = add_pa_data_element(&reply_encpart->enc_padata, pa);
+ if (code != 0)
goto cleanup;
- }
}
cleanup:
if (rep_s4u_user.cksum.contents != NULL)
krb5_free_checksum_contents(context, &rep_s4u_user.cksum);
- krb5_free_data(context, data);
+ krb5_free_data(context, der_user_id);
+ krb5_free_data(context, der_s4u_x509_user);
return code;
}
@@ -1707,46 +1697,50 @@ enctype_requires_etype_info_2(krb5_enctype enctype)
}
}
-/* XXX where are the generic helper routines for this? */
+/* Allocate a pa-data entry with an uninitialized buffer of size len. */
krb5_error_code
-add_pa_data_element(krb5_context context,
- krb5_pa_data *padata,
- krb5_pa_data ***inout_padata,
- krb5_boolean copy)
+alloc_pa_data(krb5_preauthtype pa_type, size_t len, krb5_pa_data **out)
{
- int i;
- krb5_pa_data **p;
+ krb5_pa_data *pa;
+ uint8_t *buf = NULL;
- if (*inout_padata != NULL) {
- for (i = 0; (*inout_padata)[i] != NULL; i++)
- ;
- } else
- i = 0;
-
- p = realloc(*inout_padata, (i + 2) * sizeof(krb5_pa_data *));
- if (p == NULL)
- return ENOMEM;
-
- *inout_padata = p;
-
- p[i] = (krb5_pa_data *)malloc(sizeof(krb5_pa_data));
- if (p[i] == NULL)
- return ENOMEM;
- *(p[i]) = *padata;
-
- p[i + 1] = NULL;
-
- if (copy) {
- p[i]->contents = (krb5_octet *)malloc(padata->length);
- if (p[i]->contents == NULL) {
- free(p[i]);
- p[i] = NULL;
+ *out = NULL;
+ if (len > 0) {
+ buf = malloc(len);
+ if (buf == NULL)
return ENOMEM;
- }
-
- memcpy(p[i]->contents, padata->contents, padata->length);
}
+ pa = malloc(sizeof(*pa));
+ if (pa == NULL) {
+ free(buf);
+ return ENOMEM;
+ }
+ pa->magic = KV5M_PA_DATA;
+ pa->pa_type = pa_type;
+ pa->length = len;
+ pa->contents = buf;
+ *out = pa;
+ return 0;
+}
+/* Add pa to list, claiming its memory. Free pa on failure. */
+krb5_error_code
+add_pa_data_element(krb5_pa_data ***list, krb5_pa_data *pa)
+{
+ size_t count;
+ krb5_pa_data **newlist;
+
+ for (count = 0; *list != NULL && (*list)[count] != NULL; count++);
+
+ newlist = realloc(*list, (count + 2) * sizeof(*newlist));
+ if (newlist == NULL) {
+ free(pa->contents);
+ free(pa);
+ return ENOMEM;
+ }
+ newlist[count] = pa;
+ newlist[count + 1] = NULL;
+ *list = newlist;
return 0;
}
@@ -1850,38 +1844,47 @@ kdc_handle_protected_negotiation(krb5_context context,
{
krb5_error_code retval = 0;
krb5_checksum checksum;
- krb5_data *out = NULL;
- krb5_pa_data pa, *pa_in;
+ krb5_data *der_cksum = NULL;
+ krb5_pa_data *pa, *pa_in;
+
+ memset(&checksum, 0, sizeof(checksum));
+
pa_in = krb5int_find_pa_data(context, request->padata,
KRB5_ENCPADATA_REQ_ENC_PA_REP);
if (pa_in == NULL)
return 0;
- pa.magic = KV5M_PA_DATA;
- pa.pa_type = KRB5_ENCPADATA_REQ_ENC_PA_REP;
- memset(&checksum, 0, sizeof(checksum));
- retval = krb5_c_make_checksum(context,0, reply_key,
- KRB5_KEYUSAGE_AS_REQ, req_pkt, &checksum);
+
+ /* Compute and encode a checksum over the AS-REQ. */
+ retval = krb5_c_make_checksum(context, 0, reply_key, KRB5_KEYUSAGE_AS_REQ,
+ req_pkt, &checksum);
if (retval != 0)
goto cleanup;
- retval = encode_krb5_checksum(&checksum, &out);
+ retval = encode_krb5_checksum(&checksum, &der_cksum);
if (retval != 0)
goto cleanup;
- pa.contents = (krb5_octet *) out->data;
- pa.length = out->length;
- retval = add_pa_data_element(context, &pa, out_enc_padata, FALSE);
+
+ /* Add a pa-data element to the list, stealing memory from der_cksum. */
+ retval = alloc_pa_data(KRB5_ENCPADATA_REQ_ENC_PA_REP, 0, &pa);
if (retval)
goto cleanup;
- out->data = NULL;
- pa.magic = KV5M_PA_DATA;
- pa.pa_type = KRB5_PADATA_FX_FAST;
- pa.length = 0;
- pa.contents = NULL;
- retval = add_pa_data_element(context, &pa, out_enc_padata, FALSE);
+ pa->length = der_cksum->length;
+ pa->contents = (uint8_t *)der_cksum->data;
+ der_cksum->data = NULL;
+ /* add_pa_data_element() claims pa on success or failure. */
+ retval = add_pa_data_element(out_enc_padata, pa);
+ if (retval)
+ goto cleanup;
+
+ /* Add a zero-length PA-FX-FAST element to the list. */
+ retval = alloc_pa_data(KRB5_PADATA_FX_FAST, 0, &pa);
+ if (retval)
+ goto cleanup;
+ /* add_pa_data_element() claims pa on success or failure. */
+ retval = add_pa_data_element(out_enc_padata, pa);
+
cleanup:
- if (checksum.contents)
- krb5_free_checksum_contents(context, &checksum);
- if (out != NULL)
- krb5_free_data(context, out);
+ krb5_free_checksum_contents(context, &checksum);
+ krb5_free_data(context, der_cksum);
return retval;
}
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index c57d48f73..198eab9c4 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -202,10 +202,10 @@ void
free_padata_context(krb5_context context, void *padata_context);
krb5_error_code
-add_pa_data_element (krb5_context context,
- krb5_pa_data *padata,
- krb5_pa_data ***out_padata,
- krb5_boolean copy);
+alloc_pa_data(krb5_preauthtype pa_type, size_t len, krb5_pa_data **out);
+
+krb5_error_code
+add_pa_data_element(krb5_pa_data ***list, krb5_pa_data *pa);
/* kdc_preauth_ec.c */
krb5_error_code

View File

@ -1,59 +0,0 @@
From 2a96564f6fd53f2e1e8424d865c02349bfe5b818 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Sat, 15 Dec 2018 11:56:36 +0200
Subject: [PATCH] Remove incorrect KDC assertion
The assertion in return_enc_padata() is reachable because
kdc_make_s4u2self_rep() may have previously added encrypted padata.
It is no longer necessary because the code uses add_pa_data_element()
instead of allocating a new list.
CVE-2018-20217:
In MIT krb5 1.8 or later, an authenticated user who can obtain a TGT
using an older encryption type (DES, DES3, or RC4) can cause an
assertion failure in the KDC by sending an S4U2Self request.
[ghudson@mit.edu: rewrote commit message with CVE description]
(cherry picked from commit 94e5eda5bb94d1d44733a49c3d9b6d1e42c74def)
ticket: 8767
version_fixed: 1.16.3
(cherry picked from commit 56870f9456da78d77a667dfc03a6d90f948dc3a5)
---
src/kdc/kdc_preauth.c | 1 -
src/tests/gssapi/t_s4u.py | 7 +++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 811c16368..6f0cf68d9 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -1666,7 +1666,6 @@ return_enc_padata(krb5_context context, krb5_data *req_pkt,
krb5_error_code code = 0;
/* This should be initialized and only used for Win2K compat and other
* specific standardized uses such as FAST negotiation. */
- assert(reply_encpart->enc_padata == NULL);
if (is_referral) {
code = return_referral_enc_padata(context, reply_encpart, server);
if (code)
diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py
index fc9d9e8a4..f65000453 100755
--- a/src/tests/gssapi/t_s4u.py
+++ b/src/tests/gssapi/t_s4u.py
@@ -139,6 +139,13 @@ if 'auth1: user@' not in out or 'auth2: user@' not in out:
realm.stop()
+for realm in multipass_realms(create_host=False, get_creds=False):
+ service1 = 'service/1@%s' % realm.realm
+ realm.addprinc(service1)
+ realm.extract_keytab(service1, realm.keytab)
+ realm.kinit(service1, None, ['-k'])
+ realm.run(['./t_s4u', 'p:user', '-'])
+
# Exercise cross-realm S4U2Self. The query in the foreign realm will
# fail, but we can check that the right server principal was used.
r1, r2 = cross_realms(2, create_user=False)

View File

@ -1,45 +0,0 @@
From 83da5675551dba13fee837adc26ce885a061dbc1 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 3 May 2018 14:40:45 -0400
Subject: [PATCH] Remove "-nodes" option from make-certs scripts
The openssl command does not recognize options after positional
arguments, so in "openssl genrsa $KEYSIZE -nodes", the "-nodes" was
ignored as a excess positional argument prior to OpenSSL 1.1.0h, and
now causes an error. "-nodes" is an option to the openssl req and
pkcs12 subcommands, but genrsa creates unencrypted keys by default.
[ghudson@mit.edu: edited commit message]
(cherry picked from commit 928a36aae326d496c9a73f2cd41b4da45eef577c)
---
src/tests/dejagnu/pkinit-certs/make-certs.sh | 2 +-
src/tests/dejagnu/proxy-certs/make-certs.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh
index 63f0c6f75..387311aed 100755
--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh
+++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh
@@ -114,7 +114,7 @@ extendedKeyUsage = $CLIENT_EKU_LIST
EOF
# Generate a private key.
-openssl genrsa $KEYSIZE -nodes > privkey.pem
+openssl genrsa $KEYSIZE > privkey.pem
openssl rsa -in privkey.pem -out privkey-enc.pem -des3 -passout pass:encrypted
# Generate a "CA" certificate.
diff --git a/src/tests/dejagnu/proxy-certs/make-certs.sh b/src/tests/dejagnu/proxy-certs/make-certs.sh
index 1191bf05e..24ef91bde 100755
--- a/src/tests/dejagnu/proxy-certs/make-certs.sh
+++ b/src/tests/dejagnu/proxy-certs/make-certs.sh
@@ -79,7 +79,7 @@ extendedKeyUsage = $PROXY_EKU_LIST
EOF
# Generate a private key.
-openssl genrsa $KEYSIZE -nodes > privkey.pem
+openssl genrsa $KEYSIZE > privkey.pem
# Generate a "CA" certificate.
SUBJECT=signer openssl req -config openssl.cnf -new -x509 -extensions exts_ca \

View File

@ -1,37 +0,0 @@
From 65130d13c59c13b7e5e07cfe69421ce1a08c0b7f Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 17 Jul 2018 11:33:03 -0400
Subject: [PATCH] Remove outdated note in krb5kdc man page
Commit af5b77c887bfff24603715f8296c00d5eb839b0c (ticket 8348) removed
the interface-scanning workaround for platforms without pktinfo
support, so there is no longer an interaction between the krb5kdc -w
option and this workaround.
ticket: 8716 (new)
tags: pullup
target_version: 1.16-next
(cherry picked from commit 728b66ab867e31c4c338c6a6309d629d39a4ec3f)
---
doc/admin/admin_commands/krb5kdc.rst | 7 -------
1 file changed, 7 deletions(-)
diff --git a/doc/admin/admin_commands/krb5kdc.rst b/doc/admin/admin_commands/krb5kdc.rst
index bda2c015c..b605b563d 100644
--- a/doc/admin/admin_commands/krb5kdc.rst
+++ b/doc/admin/admin_commands/krb5kdc.rst
@@ -72,13 +72,6 @@ will relay SIGHUP signals to the worker subprocesses, and will
terminate the worker subprocess if the it is itself terminated or if
any other worker process exits.
-.. note::
-
- On operating systems which do not have *pktinfo* support,
- using worker processes will prevent the KDC from listening
- for UDP packets on network interfaces created after the KDC
- starts.
-
The **-x** *db_args* option specifies database-specific arguments.
See :ref:`Database Options <dboptions>` in :ref:`kadmin(1)` for
supported arguments.

View File

@ -1,27 +0,0 @@
From 3b3e31316ae247e18ea22293dffbc8f604338fa7 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 17 Mar 2018 22:47:34 -0400
Subject: [PATCH] Report extended errors in kinit -k -t KDB:
In kinit, if we recreate the context using kinit_kdb_init(), also
reset the global errctx so that we use the new context to retrieve
extended error messages.
ticket: 8652 (new)
(cherry picked from commit d4d902d317a2acc46ee71094a33a9203b6135275)
---
src/clients/kinit/kinit.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
index a518284ea..3fdae2878 100644
--- a/src/clients/kinit/kinit.c
+++ b/src/clients/kinit/kinit.c
@@ -718,6 +718,7 @@ k5_kinit(struct k_opts *opts, struct k5_data *k5)
#ifndef _WIN32
if (strncmp(opts->keytab_name, "KDB:", 4) == 0) {
ret = kinit_kdb_init(&k5->ctx, k5->me->realm.data);
+ errctx = k5->ctx;
if (ret) {
com_err(progname, ret,
_("while setting up KDB keytab for realm %s"),

View File

@ -1,491 +0,0 @@
From 70f41a8dafaadfb43aba4918564c22460f812dca Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 5 Apr 2018 16:23:34 -0400
Subject: [PATCH] Restrict pre-authentication fallback cases
Add a new callback disable_fallback() and call it from each clpreauth
module when it generates a client message using credentials to
authenticate. (For SPAKE, this is the message responding to a
challenge; for all other current mechanisms, it is the first and only
client message.) If disable_fallback() is called, do not try another
mechanism after a KDC error.
Remove k5_reset_preauth_types_tried() and its call sites, so that
preauth mechanisms which are tried optimistically will no longer be
retried after a failure.
ticket: 8654
(cherry picked from commit 7a24a088c16d326127dd2b29084d4ca085c70d10)
---
src/include/krb5/clpreauth_plugin.h | 14 ++++
src/lib/krb5/krb/get_in_tkt.c | 21 +++---
src/lib/krb5/krb/init_creds_ctx.h | 1 +
src/lib/krb5/krb/int-proto.h | 3 -
src/lib/krb5/krb/preauth2.c | 23 +++----
src/lib/krb5/krb/preauth_ec.c | 1 +
src/lib/krb5/krb/preauth_encts.c | 2 +
src/lib/krb5/krb/preauth_otp.c | 4 ++
src/lib/krb5/krb/preauth_sam2.c | 1 +
src/plugins/preauth/pkinit/pkinit_clnt.c | 1 +
src/plugins/preauth/spake/spake_client.c | 4 ++
src/plugins/preauth/test/cltest.c | 11 +++
src/tests/t_preauth.py | 88 +++++++++++++++++++++---
src/tests/t_spake.py | 9 +--
14 files changed, 134 insertions(+), 49 deletions(-)
diff --git a/src/include/krb5/clpreauth_plugin.h b/src/include/krb5/clpreauth_plugin.h
index 0106734ad..5317669b7 100644
--- a/src/include/krb5/clpreauth_plugin.h
+++ b/src/include/krb5/clpreauth_plugin.h
@@ -160,7 +160,21 @@ typedef struct krb5_clpreauth_callbacks_st {
krb5_error_code (*set_cc_config)(krb5_context context,
krb5_clpreauth_rock rock,
const char *key, const char *data);
+
/* End of version 2 clpreauth callbacks (added in 1.11). */
+
+ /*
+ * Prevent further fallbacks to other preauth mechanisms if the KDC replies
+ * with an error. (The module itself can still respond to errors with its
+ * tryagain method, or continue after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
+ * errors with its process method.) A module should invoke this callback
+ * from the process method when it generates an authenticated request using
+ * credentials; often this will be the first or only client message
+ * generated by the mechanism.
+ */
+ void (*disable_fallback)(krb5_context context, krb5_clpreauth_rock rock);
+
+ /* End of version 3 clpreauth callbacks (added in 1.17). */
} *krb5_clpreauth_callbacks;
/*
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 1d96ff163..c026bbc6d 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1331,9 +1331,7 @@ init_creds_step_request(krb5_context context,
krb5_free_pa_data(context, ctx->optimistic_padata);
ctx->optimistic_padata = NULL;
if (code) {
- /* Make an unauthenticated request, and possibly try again using
- * the same mechanisms as we tried optimistically. */
- k5_reset_preauth_types_tried(ctx);
+ /* Make an unauthenticated request. */
krb5_clear_error_message(context);
code = 0;
}
@@ -1361,6 +1359,9 @@ init_creds_step_request(krb5_context context,
/* Don't continue after a keyboard interrupt. */
if (code == KRB5_LIBOS_PWDINTR)
goto cleanup;
+ /* Don't continue if fallback is disabled. */
+ if (code && ctx->fallback_disabled)
+ goto cleanup;
if (code) {
/* See if we can try a different preauth mech before giving up. */
k5_save_ctx_error(context, code, &save);
@@ -1549,16 +1550,10 @@ init_creds_step_reply(krb5_context context,
} else if (reply_code == KDC_ERR_PREAUTH_FAILED && retry) {
note_req_timestamp(context, ctx, ctx->err_reply->stime,
ctx->err_reply->susec);
- if (ctx->method_padata == NULL) {
- /* Optimistic preauth failed on the KDC. Allow all mechanisms
- * to be tried again using method data. */
- k5_reset_preauth_types_tried(ctx);
- } else {
- /* Don't try again with the mechanism that failed. */
- code = k5_preauth_note_failed(ctx, ctx->selected_preauth_type);
- if (code)
- goto cleanup;
- }
+ /* Don't try again with the mechanism that failed. */
+ code = k5_preauth_note_failed(ctx, ctx->selected_preauth_type);
+ if (code)
+ goto cleanup;
ctx->selected_preauth_type = KRB5_PADATA_NONE;
/* Accept or update method data if the KDC sent it. */
if (ctx->err_padata != NULL)
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index b19410a13..7ba61e17c 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -60,6 +60,7 @@ struct _krb5_init_creds_context {
krb5_enctype etype;
krb5_boolean info_pa_permitted;
krb5_boolean restarted;
+ krb5_boolean fallback_disabled;
struct krb5_responder_context_st rctx;
krb5_preauthtype selected_preauth_type;
krb5_preauthtype allowed_preauth_type;
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
index cda9010e3..d20133885 100644
--- a/src/lib/krb5/krb/int-proto.h
+++ b/src/lib/krb5/krb/int-proto.h
@@ -197,9 +197,6 @@ k5_init_preauth_context(krb5_context context);
void
k5_free_preauth_context(krb5_context context);
-void
-k5_reset_preauth_types_tried(krb5_init_creds_context ctx);
-
krb5_error_code
k5_preauth_note_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type);
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 451e0b7a8..1f17ec2b0 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -203,18 +203,6 @@ cleanup:
free_handles(context, list);
}
-/* Reset the memory of which preauth types we have already tried. */
-void
-k5_reset_preauth_types_tried(krb5_init_creds_context ctx)
-{
- krb5_preauth_req_context reqctx = ctx->preauth_reqctx;
-
- if (reqctx == NULL)
- return;
- free(reqctx->failed);
- reqctx->failed = NULL;
-}
-
/* Add pa_type to the list of types which has previously failed. */
krb5_error_code
k5_preauth_note_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type)
@@ -553,8 +541,14 @@ set_cc_config(krb5_context context, krb5_clpreauth_rock rock,
return ret;
}
+static void
+disable_fallback(krb5_context context, krb5_clpreauth_rock rock)
+{
+ ((krb5_init_creds_context)rock)->fallback_disabled = TRUE;
+}
+
static struct krb5_clpreauth_callbacks_st callbacks = {
- 2,
+ 3,
get_etype,
fast_armor,
get_as_key,
@@ -564,7 +558,8 @@ static struct krb5_clpreauth_callbacks_st callbacks = {
responder_get_answer,
need_as_key,
get_cc_config,
- set_cc_config
+ set_cc_config,
+ disable_fallback
};
/* Tweak the request body, for now adding any enctypes which the module claims
diff --git a/src/lib/krb5/krb/preauth_ec.c b/src/lib/krb5/krb/preauth_ec.c
index c1aa9090f..75aab770e 100644
--- a/src/lib/krb5/krb/preauth_ec.c
+++ b/src/lib/krb5/krb/preauth_ec.c
@@ -138,6 +138,7 @@ ec_process(krb5_context context, krb5_clpreauth_moddata moddata,
encoded_ts->data = NULL;
*out_padata = pa;
pa = NULL;
+ cb->disable_fallback(context, rock);
}
free(pa);
krb5_free_data(context, encoded_ts);
diff --git a/src/lib/krb5/krb/preauth_encts.c b/src/lib/krb5/krb/preauth_encts.c
index cec384227..45bf9da92 100644
--- a/src/lib/krb5/krb/preauth_encts.c
+++ b/src/lib/krb5/krb/preauth_encts.c
@@ -109,6 +109,8 @@ encts_process(krb5_context context, krb5_clpreauth_moddata moddata,
*out_padata = pa;
pa = NULL;
+ cb->disable_fallback(context, rock);
+
cleanup:
krb5_free_data(context, ts);
krb5_free_data(context, enc_ts);
diff --git a/src/lib/krb5/krb/preauth_otp.c b/src/lib/krb5/krb/preauth_otp.c
index 48fcbb5d5..13e584657 100644
--- a/src/lib/krb5/krb/preauth_otp.c
+++ b/src/lib/krb5/krb/preauth_otp.c
@@ -1123,6 +1123,10 @@ otp_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
/* Encode the request into the pa_data output. */
retval = set_pa_data(req, pa_data_out);
+ if (retval != 0)
+ goto error;
+ cb->disable_fallback(context, rock);
+
error:
krb5_free_data_contents(context, &value);
krb5_free_data_contents(context, &pin);
diff --git a/src/lib/krb5/krb/preauth_sam2.c b/src/lib/krb5/krb/preauth_sam2.c
index c8a330655..4c70021a9 100644
--- a/src/lib/krb5/krb/preauth_sam2.c
+++ b/src/lib/krb5/krb/preauth_sam2.c
@@ -410,6 +410,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
sam_padata[1] = NULL;
*out_padata = sam_padata;
+ cb->disable_fallback(context, rock);
return(0);
}
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index 9483d69e5..77e9e5308 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -179,6 +179,7 @@ pa_pkinit_gen_req(krb5_context context,
*out_padata = return_pa_data;
return_pa_data = NULL;
+ cb->disable_fallback(context, rock);
cleanup:
krb5_free_data(context, der_req);
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
index 47a6ba26c..00734a13b 100644
--- a/src/plugins/preauth/spake/spake_client.c
+++ b/src/plugins/preauth/spake/spake_client.c
@@ -278,6 +278,10 @@ process_challenge(krb5_context context, groupstate *gstate, reqstate *st,
goto cleanup;
TRACE_SPAKE_SEND_RESPONSE(context);
ret = convert_to_padata(response, pa_out);
+ if (ret)
+ goto cleanup;
+
+ cb->disable_fallback(context, rock);
cleanup:
krb5_free_keyblock(context, k0);
diff --git a/src/plugins/preauth/test/cltest.c b/src/plugins/preauth/test/cltest.c
index f5f7c5aba..51b848481 100644
--- a/src/plugins/preauth/test/cltest.c
+++ b/src/plugins/preauth/test/cltest.c
@@ -53,6 +53,9 @@
* - If the "fail_optimistic", "fail_2rt", or "fail_tryagain" gic options are
* set, it fails with a recognizable error string at the requested point in
* processing.
+ *
+ * - If the "disable_fallback" gic option is set, fallback is disabled when a
+ * client message is generated.
*/
#include "k5-int.h"
@@ -66,6 +69,7 @@ struct client_state {
krb5_boolean fail_optimistic;
krb5_boolean fail_2rt;
krb5_boolean fail_tryagain;
+ krb5_boolean disable_fallback;
};
struct client_request_state {
@@ -81,6 +85,7 @@ test_init(krb5_context context, krb5_clpreauth_moddata *moddata_out)
assert(st != NULL);
st->indicators = NULL;
st->fail_optimistic = st->fail_2rt = st->fail_tryagain = FALSE;
+ st->disable_fallback = FALSE;
*moddata_out = (krb5_clpreauth_moddata)st;
return 0;
}
@@ -138,6 +143,8 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata,
return KRB5_PREAUTH_FAILED;
}
*out_pa_data = make_pa_list("optimistic", 10);
+ if (st->disable_fallback)
+ cb->disable_fallback(context, rock);
return 0;
} else if (reqst->second_round_trip) {
printf("2rt: %.*s\n", pa_data->length, pa_data->contents);
@@ -166,6 +173,8 @@ test_process(krb5_context context, krb5_clpreauth_moddata moddata,
indstr = (st->indicators != NULL) ? st->indicators : "";
*out_pa_data = make_pa_list(indstr, strlen(indstr));
+ if (st->disable_fallback)
+ cb->disable_fallback(context, rock);
return 0;
}
@@ -212,6 +221,8 @@ test_gic_opt(krb5_context kcontext, krb5_clpreauth_moddata moddata,
st->fail_2rt = TRUE;
} else if (strcmp(attr, "fail_tryagain") == 0) {
st->fail_tryagain = TRUE;
+ } else if (strcmp(attr, "disable_fallback") == 0) {
+ st->disable_fallback = TRUE;
}
return 0;
}
diff --git a/src/tests/t_preauth.py b/src/tests/t_preauth.py
index efb3ea20d..32e35b08b 100644
--- a/src/tests/t_preauth.py
+++ b/src/tests/t_preauth.py
@@ -37,8 +37,8 @@ expected_trace = ('Attempting optimistic preauth',
realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')],
expected_trace=expected_trace)
-# Test optimistic preauth failing on client, followed by successful
-# preauth using the same module.
+# Test optimistic preauth failing on client, falling back to encrypted
+# timestamp.
msgs = ('Attempting optimistic preauth',
'Processing preauth types: -123',
'/induced optimistic fail',
@@ -46,15 +46,15 @@ msgs = ('Attempting optimistic preauth',
'/Additional pre-authentication required',
'Preauthenticating using KDC method data',
'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ 'Encrypted timestamp (for ',
+ 'module encrypted_timestamp (2) (real) returned: 0/Success',
+ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
'Decrypted AS reply')
realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ,
- password('user')], expected_msg='testval',
- expected_trace=msgs)
+ password('user')], expected_trace=msgs)
-# Test optimistic preauth failing on KDC, followed by successful preauth
-# using the same module.
+# Test optimistic preauth failing on KDC, falling back to encrypted
+# timestamp.
realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes'])
msgs = ('Attempting optimistic preauth',
'Processing preauth types: -123',
@@ -63,11 +63,24 @@ msgs = ('Attempting optimistic preauth',
'/Preauthentication failed',
'Preauthenticating using KDC method data',
'Processing preauth types:',
- 'Preauth module test (-123) (real) returned: 0/Success',
- 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ 'Encrypted timestamp (for ',
+ 'module encrypted_timestamp (2) (real) returned: 0/Success',
+ 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
'Decrypted AS reply')
realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')],
- expected_msg='testval', expected_trace=msgs)
+ expected_trace=msgs)
+# Leave failopt set for the next test.
+
+# Test optimistic preauth failing on KDC, stopping because the test
+# module disabled fallback.
+msgs = ('Attempting optimistic preauth',
+ 'Processing preauth types: -123',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: -123',
+ '/Preauthentication failed')
+realm.run(['./icred', '-X', 'disable_fallback', '-o', '-123', realm.user_princ,
+ password('user')], expected_code=1,
+ expected_msg='Preauthentication failed', expected_trace=msgs)
realm.run([kadminl, 'delstr', realm.user_princ, 'failopt'])
# Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies.
@@ -107,6 +120,23 @@ msgs = ('Sending unauthenticated request',
realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')],
expected_msg='2rt: secondtrip', expected_trace=msgs)
+# Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
+# stopping because the test module disabled fallback.
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/More preauthentication data is required',
+ 'Continuing preauth mech -123',
+ 'Processing preauth types: -123, PA-FX-COOKIE (133)',
+ '/induced 2rt fail')
+realm.run(['./icred', '-X', 'fail_2rt', '-X', 'disable_fallback',
+ realm.user_princ, password('user')], expected_code=1,
+ expected_msg='Pre-authentication failed: induced 2rt fail',
+ expected_trace=msgs)
+
# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
# falling back to encrypted timestamp.
realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes'])
@@ -130,6 +160,25 @@ msgs = ('Sending unauthenticated request',
'Decrypted AS reply')
realm.run(['./icred', realm.user_princ, password('user')],
expected_msg='2rt: secondtrip', expected_trace=msgs)
+# Leave fail2rt set for the next test.
+
+# Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,
+# stopping because the test module disabled fallback.
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/More preauthentication data is required',
+ 'Continuing preauth mech -123',
+ 'Processing preauth types: -123, PA-FX-COOKIE (133)',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/Preauthentication failed')
+realm.run(['./icred', '-X', 'disable_fallback',
+ realm.user_princ, password('user')], expected_code=1,
+ expected_msg='Preauthentication failed', expected_trace=msgs)
realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt'])
# Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC.
@@ -170,6 +219,23 @@ msgs = ('Sending unauthenticated request',
realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ,
password('user')], expected_trace=msgs)
+# Test a client-side tryagain failure, stopping because the test
+# module disabled fallback.
+msgs = ('Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ 'Preauthenticating using KDC method data',
+ 'Processing preauth types:',
+ 'Preauth module test (-123) (real) returned: 0/Success',
+ 'Produced preauth for next request: PA-FX-COOKIE (133), -123',
+ '/KDC has no support for encryption type',
+ 'Recovering from KDC error 14 using preauth mech -123',
+ 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)',
+ '/induced tryagain fail')
+realm.run(['./icred', '-X', 'fail_tryagain', '-X', 'disable_fallback',
+ realm.user_princ, password('user')], expected_code=1,
+ expected_msg='KDC has no support for encryption type',
+ expected_trace=msgs)
+
# Test that multiple stepwise initial creds operations can be
# performed with the same krb5_context, with proper tracking of
# clpreauth module request handles.
diff --git a/src/tests/t_spake.py b/src/tests/t_spake.py
index a81a238b4..5b47e62d3 100644
--- a/src/tests/t_spake.py
+++ b/src/tests/t_spake.py
@@ -31,9 +31,7 @@ for gnum, gname in groups:
'Decrypted AS reply')
realm.kinit('user', 'pw', expected_trace=msgs)
- # Test an unsuccessful authentication. (The client will try
- # again with encrypted timestamp, which isn't really desired,
- # but check for that as long as it is expected.)
+ # Test an unsuccessful authentication.
msgs = ('/Additional pre-authentication required',
'Selected etype info:',
'Sending SPAKE support message',
@@ -42,9 +40,6 @@ for gnum, gname in groups:
'Continuing preauth mech PA-SPAKE (151)',
'SPAKE challenge received with group ' + str(gnum),
'Sending SPAKE response',
- '/Preauthentication failed',
- 'Encrypted timestamp ',
- 'for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
'/Preauthentication failed')
realm.kinit('user', 'wrongpw', expected_code=1, expected_trace=msgs)
@@ -114,8 +109,6 @@ msgs = ('Attempting optimistic preauth',
'for next request: PA-SPAKE (151)',
'/Preauthentication failed',
'Selected etype info:',
- 'SPAKE challenge with group 1 rejected',
- 'spake (151) (real) returned: -1765328360/Preauthentication failed',
'Encrypted timestamp ',
'for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)',
'AS key determined by preauth:',

View File

@ -1,738 +0,0 @@
From 65f078dfc68f5680e87e686a59970291b64ebd95 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 11 Feb 2018 15:23:35 -0500
Subject: [PATCH] Simplify kdc_preauth.c systems table
Get rid of static_preauth_systems, and replace it with explicit calls
to helper functions in get_preauth_hint_list() and return_padata().
Stop preallocating pa-data lists, instead reallocating on each
addition using add_pa_data_element(). Also simplify
maybe_add_etype_info2() using add_pa_data_element().
The KRB5_PADATA_PAC_REQUEST table entry did nothing, and was probably
originally added back when the KDC would error out on unrecognized
padata types. The KRB5_PADATA_SERVER_REFERRAL entry has been disabled
since it was first added.
(cherry picked from commit fea1a488924faa3938ef723feaa1ff12d22a91ff)
---
src/kdc/kdc_preauth.c | 526 +++++++++++++++---------------------------
1 file changed, 184 insertions(+), 342 deletions(-)
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index edc30bd83..6f34dc289 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -101,108 +101,14 @@ typedef struct preauth_system_st {
krb5_kdcpreauth_loop_fn loop;
} preauth_system;
+static preauth_system *preauth_systems;
+static size_t n_preauth_systems;
+
static krb5_error_code
make_etype_info(krb5_context context, krb5_preauthtype pa_type,
krb5_principal client, krb5_key_data *client_key,
krb5_enctype enctype, krb5_pa_data **pa_out);
-static void
-get_etype_info(krb5_context context, krb5_kdc_req *request,
- krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
- krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type,
- krb5_kdcpreauth_edata_respond_fn respond, void *arg);
-
-static krb5_error_code
-return_etype_info(krb5_context, krb5_pa_data *padata,
- krb5_data *req_pkt, krb5_kdc_req *request,
- krb5_kdc_rep *reply, krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb,
- krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata,
- krb5_kdcpreauth_modreq modreq);
-
-static krb5_error_code
-return_pw_salt(krb5_context, krb5_pa_data *padata,
- krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
- krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
- krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
- krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq);
-
-
-
-static preauth_system static_preauth_systems[] = {
- {
- "FAST",
- KRB5_PADATA_FX_FAST,
- PA_HARDWARE,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- 0
- },
- {
- "etype-info",
- KRB5_PADATA_ETYPE_INFO,
- PA_HARDWARE,
- NULL,
- NULL,
- NULL,
- get_etype_info,
- 0,
- return_etype_info
- },
- {
- "etype-info2",
- KRB5_PADATA_ETYPE_INFO2,
- PA_HARDWARE,
- NULL,
- NULL,
- NULL,
- get_etype_info,
- 0,
- return_etype_info
- },
- {
- "pw-salt",
- KRB5_PADATA_PW_SALT,
- PA_PSEUDO, /* Don't include this in the error list */
- NULL,
- NULL,
- NULL,
- 0,
- 0,
- return_pw_salt
- },
- {
- "pac-request",
- KRB5_PADATA_PAC_REQUEST,
- PA_PSEUDO,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
- },
-#if 0
- {
- "server-referral",
- KRB5_PADATA_SERVER_REFERRAL,
- PA_PSEUDO,
- 0,
- 0,
- return_server_referral
- },
-#endif
-};
-
-#define NUM_STATIC_PREAUTH_SYSTEMS (sizeof(static_preauth_systems) / \
- sizeof(*static_preauth_systems))
-
-static preauth_system *preauth_systems;
-static size_t n_preauth_systems;
-
/* Get all available kdcpreauth vtables and a count of preauth types they
* support. Return an empty list on failure. */
static void
@@ -284,7 +190,6 @@ load_preauth_plugins(struct server_handle *handle, krb5_context context,
get_plugin_vtables(context, &vtables, &n_tables, &n_systems);
/* Allocate the list of static and plugin preauth systems. */
- n_systems += NUM_STATIC_PREAUTH_SYSTEMS;
preauth_systems = calloc(n_systems + 1, sizeof(preauth_system));
if (preauth_systems == NULL)
goto cleanup;
@@ -292,13 +197,8 @@ load_preauth_plugins(struct server_handle *handle, krb5_context context,
if (get_realm_names(handle, &realm_names))
goto cleanup;
- /* Add the static system to the list first. No static systems require
- * initialization, so just make a direct copy. */
- memcpy(preauth_systems, static_preauth_systems,
- sizeof(static_preauth_systems));
-
/* Add the dynamically-loaded mechanisms to the list. */
- n_systems = NUM_STATIC_PREAUTH_SYSTEMS;
+ n_systems = 0;
for (i = 0; i < n_tables; i++) {
/* Try to initialize this module. */
vt = &vtables[i];
@@ -622,7 +522,9 @@ find_pa_system(int type, preauth_system **preauth)
{
preauth_system *ap;
- ap = preauth_systems ? preauth_systems : static_preauth_systems;
+ if (preauth_systems == NULL)
+ return KRB5_PREAUTH_BAD_TYPE;
+ ap = preauth_systems;
while ((ap->type != -1) && (ap->type != type))
ap++;
if (ap->type == -1)
@@ -776,6 +678,98 @@ const char *missing_required_preauth(krb5_db_entry *client,
return 0;
}
+/* Return true if request's enctypes indicate support for etype-info2. */
+static krb5_boolean
+requires_info2(const krb5_kdc_req *request)
+{
+ int i;
+
+ for (i = 0; i < request->nktypes; i++) {
+ if (enctype_requires_etype_info_2(request->ktype[i]))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Add PA-ETYPE-INFO2 and possibly PA-ETYPE-INFO entries to pa_list as
+ * appropriate for the request and client principal. */
+static krb5_error_code
+add_etype_info(krb5_context context, krb5_kdcpreauth_rock rock,
+ krb5_pa_data ***pa_list)
+{
+ krb5_error_code ret;
+ krb5_pa_data *pa;
+
+ if (rock->client_key == NULL)
+ return 0;
+
+ if (!requires_info2(rock->request)) {
+ /* Include PA-ETYPE-INFO only for old clients. */
+ ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO,
+ rock->client->princ, rock->client_key,
+ rock->client_keyblock->enctype, &pa);
+ if (ret)
+ return ret;
+ /* add_pa_data_element() claims pa on success or failure. */
+ ret = add_pa_data_element(pa_list, pa);
+ if (ret)
+ return ret;
+ }
+
+ /* Always include PA-ETYPE-INFO2. */
+ ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO2,
+ rock->client->princ, rock->client_key,
+ rock->client_keyblock->enctype, &pa);
+ if (ret)
+ return ret;
+ /* add_pa_data_element() claims pa on success or failure. */
+ return add_pa_data_element(pa_list, pa);
+}
+
+/* Add PW-SALT or AFS3-SALT entries to pa_list as appropriate for the request
+ * and client principal. */
+static krb5_error_code
+add_pw_salt(krb5_context context, krb5_kdcpreauth_rock rock,
+ krb5_pa_data ***pa_list)
+{
+ krb5_error_code ret;
+ krb5_pa_data *pa;
+ krb5_data *salt = NULL;
+ krb5_int16 salttype;
+
+ /* Only include this pa-data for old clients. */
+ if (rock->client_key == NULL || requires_info2(rock->request))
+ return 0;
+
+ ret = krb5_dbe_compute_salt(context, rock->client_key,
+ rock->request->client, &salttype, &salt);
+ if (ret)
+ return 0;
+
+ if (salttype == KRB5_KDB_SALTTYPE_AFS3) {
+ ret = alloc_pa_data(KRB5_PADATA_AFS3_SALT, salt->length + 1, &pa);
+ if (ret)
+ goto cleanup;
+ memcpy(pa->contents, salt->data, salt->length);
+ pa->contents[salt->length] = '\0';
+ } else {
+ /* Steal memory from salt to make the pa-data entry. */
+ ret = alloc_pa_data(KRB5_PADATA_PW_SALT, 0, &pa);
+ if (ret)
+ goto cleanup;
+ pa->length = salt->length;
+ pa->contents = (uint8_t *)salt->data;
+ salt->data = NULL;
+ }
+
+ /* add_pa_data_element() claims pa on success or failure. */
+ ret = add_pa_data_element(pa_list, pa);
+
+cleanup:
+ krb5_free_data(context, salt);
+ return ret;
+}
+
struct hint_state {
kdc_hint_respond_fn respond;
void *arg;
@@ -787,7 +781,7 @@ struct hint_state {
int hw_only;
preauth_system *ap;
- krb5_pa_data **pa_data, **pa_cur;
+ krb5_pa_data **pa_data;
krb5_preauthtype pa_type;
};
@@ -799,7 +793,7 @@ hint_list_finish(struct hint_state *state, krb5_error_code code)
kdc_realm_t *kdc_active_realm = state->realm;
if (!code) {
- if (state->pa_data[0] == 0) {
+ if (state->pa_data == NULL) {
krb5_klog_syslog(LOG_INFO,
_("%spreauth required but hint list is empty"),
state->hw_only ? "hw" : "");
@@ -820,20 +814,27 @@ hint_list_next(struct hint_state *arg);
static void
finish_get_edata(void *arg, krb5_error_code code, krb5_pa_data *pa)
{
+ krb5_error_code ret;
struct hint_state *state = arg;
if (code == 0) {
if (pa == NULL) {
- /* Include an empty value of the current type. */
- pa = calloc(1, sizeof(*pa));
- pa->magic = KV5M_PA_DATA;
- pa->pa_type = state->pa_type;
+ ret = alloc_pa_data(state->pa_type, 0, &pa);
+ if (ret)
+ goto error;
}
- *state->pa_cur++ = pa;
+ /* add_pa_data_element() claims pa on success or failure. */
+ ret = add_pa_data_element(&state->pa_data, pa);
+ if (ret)
+ goto error;
}
state->ap++;
hint_list_next(state);
+ return;
+
+error:
+ hint_list_finish(state, ret);
}
static void
@@ -870,16 +871,16 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
krb5_pa_data ***e_data_out, kdc_hint_respond_fn respond,
void *arg)
{
+ kdc_realm_t *kdc_active_realm = rock->rstate->realm_data;
struct hint_state *state;
+ krb5_pa_data *pa;
*e_data_out = NULL;
/* Allocate our state. */
state = calloc(1, sizeof(*state));
- if (state == NULL) {
- (*respond)(arg);
- return;
- }
+ if (state == NULL)
+ goto error;
state->hw_only = isflagset(rock->client->attributes,
KRB5_KDB_REQUIRES_HW_AUTH);
state->respond = respond;
@@ -888,17 +889,27 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
state->rock = rock;
state->realm = rock->rstate->realm_data;
state->e_data_out = e_data_out;
-
- state->pa_data = calloc(n_preauth_systems + 1, sizeof(krb5_pa_data *));
- if (!state->pa_data) {
- free(state);
- (*respond)(arg);
- return;
- }
-
- state->pa_cur = state->pa_data;
+ state->pa_data = NULL;
state->ap = preauth_systems;
+
+ /* Add an empty PA-FX-FAST element to advertise FAST support. */
+ if (alloc_pa_data(KRB5_PADATA_FX_FAST, 0, &pa) != 0)
+ goto error;
+ /* add_pa_data_element() claims pa on success or failure. */
+ if (add_pa_data_element(&state->pa_data, pa) != 0)
+ goto error;
+
+ if (add_etype_info(kdc_context, rock, &state->pa_data) != 0)
+ goto error;
+
hint_list_next(state);
+ return;
+
+error:
+ if (state != NULL)
+ krb5_free_pa_data(kdc_context, state->pa_data);
+ free(state);
+ (*respond)(arg);
}
/*
@@ -1029,10 +1040,10 @@ filter_preauth_error(krb5_error_code code)
static krb5_error_code
maybe_add_etype_info2(struct padata_state *state, krb5_error_code code)
{
+ krb5_error_code ret;
krb5_context context = state->context;
krb5_kdcpreauth_rock rock = state->rock;
- krb5_pa_data **list = state->pa_e_data;
- size_t count;
+ krb5_pa_data *pa;
/* Only add key information when requesting another preauth round trip. */
if (code != KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED)
@@ -1048,18 +1059,14 @@ maybe_add_etype_info2(struct padata_state *state, krb5_error_code code)
KRB5_PADATA_FX_COOKIE) != NULL)
return 0;
- /* Reallocate state->pa_e_data to make room for the etype-info2 element. */
- for (count = 0; list != NULL && list[count] != NULL; count++);
- list = realloc(list, (count + 2) * sizeof(*list));
- if (list == NULL)
- return ENOMEM;
- list[count] = list[count + 1] = NULL;
- state->pa_e_data = list;
+ ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO2,
+ rock->client->princ, rock->client_key,
+ rock->client_keyblock->enctype, &pa);
+ if (ret)
+ return ret;
- /* Generate an etype-info2 element in the new slot. */
- return make_etype_info(context, KRB5_PADATA_ETYPE_INFO2,
- rock->client->princ, rock->client_key,
- rock->client_keyblock->enctype, &list[count]);
+ /* add_pa_data_element() claims pa on success or failure. */
+ return add_pa_data_element(&state->pa_e_data, pa);
}
/* Release state and respond to the AS-REQ processing code with the result of
@@ -1279,17 +1286,20 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
{
krb5_error_code retval;
krb5_pa_data ** padata;
- krb5_pa_data ** send_pa_list;
- krb5_pa_data ** send_pa;
+ krb5_pa_data ** send_pa_list = NULL;
+ krb5_pa_data * send_pa;
krb5_pa_data * pa = 0;
krb5_pa_data null_item;
preauth_system * ap;
- int * pa_order;
+ int * pa_order = NULL;
int * pa_type;
int size = 0;
krb5_kdcpreauth_modreq *modreq_ptr;
krb5_boolean key_modified;
krb5_keyblock original_key;
+
+ memset(&original_key, 0, sizeof(original_key));
+
if ((!*padata_context) &&
(make_padata_context(context, padata_context) != 0)) {
return KRB5KRB_ERR_GENERIC;
@@ -1300,26 +1310,18 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
size++;
}
- if ((send_pa_list = malloc((size+1) * sizeof(krb5_pa_data *))) == NULL)
- return ENOMEM;
- if ((pa_order = malloc((size+1) * sizeof(int))) == NULL) {
- free(send_pa_list);
- return ENOMEM;
- }
+ pa_order = k5calloc(size + 1, sizeof(int), &retval);
+ if (pa_order == NULL)
+ goto cleanup;
sort_pa_order(context, request, pa_order);
retval = krb5_copy_keyblock_contents(context, encrypting_key,
&original_key);
- if (retval) {
- free(send_pa_list);
- free(pa_order);
- return retval;
- }
+ if (retval)
+ goto cleanup;
key_modified = FALSE;
null_item.contents = NULL;
null_item.length = 0;
- send_pa = send_pa_list;
- *send_pa = 0;
for (pa_type = pa_order; *pa_type != -1; pa_type++) {
ap = &preauth_systems[*pa_type];
@@ -1349,20 +1351,30 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
}
}
}
+ send_pa = NULL;
retval = ap->return_padata(context, pa, req_pkt, request, reply,
- encrypting_key, send_pa, &callbacks, rock,
+ encrypting_key, &send_pa, &callbacks, rock,
ap->moddata, *modreq_ptr);
if (retval)
goto cleanup;
- if (*send_pa)
- send_pa++;
- *send_pa = 0;
+ if (send_pa != NULL) {
+ /* add_pa_data_element() claims send_pa on success or failure. */
+ retval = add_pa_data_element(&send_pa_list, send_pa);
+ if (retval)
+ goto cleanup;
+ }
}
- retval = 0;
+ /* Add etype-info and pw-salt pa-data as needed. */
+ retval = add_etype_info(context, rock, &send_pa_list);
+ if (retval)
+ goto cleanup;
+ retval = add_pw_salt(context, rock, &send_pa_list);
+ if (retval)
+ goto cleanup;
- if (send_pa_list[0]) {
+ if (send_pa_list != NULL) {
reply->padata = send_pa_list;
send_pa_list = 0;
}
@@ -1370,8 +1382,7 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
cleanup:
krb5_free_keyblock_contents(context, &original_key);
free(pa_order);
- if (send_pa_list)
- krb5_free_pa_data(context, send_pa_list);
+ krb5_free_pa_data(context, send_pa_list);
return (retval);
}
@@ -1438,9 +1449,8 @@ make_etype_info(krb5_context context, krb5_preauthtype pa_type,
krb5_enctype enctype, krb5_pa_data **pa_out)
{
krb5_error_code retval;
- krb5_pa_data *pa = NULL;
krb5_etype_info_entry **entry = NULL;
- krb5_data *scratch = NULL;
+ krb5_data *der_etype_info = NULL;
int etype_info2 = (pa_type == KRB5_PADATA_ETYPE_INFO2);
*pa_out = NULL;
@@ -1454,125 +1464,23 @@ make_etype_info(krb5_context context, krb5_preauthtype pa_type,
goto cleanup;
if (etype_info2)
- retval = encode_krb5_etype_info2(entry, &scratch);
+ retval = encode_krb5_etype_info2(entry, &der_etype_info);
else
- retval = encode_krb5_etype_info(entry, &scratch);
+ retval = encode_krb5_etype_info(entry, &der_etype_info);
if (retval)
goto cleanup;
- pa = k5alloc(sizeof(*pa), &retval);
- if (pa == NULL)
+
+ /* Steal the data from der_etype_info to create a pa-data element. */
+ retval = alloc_pa_data(pa_type, 0, pa_out);
+ if (retval)
goto cleanup;
- pa->magic = KV5M_PA_DATA;
- pa->pa_type = pa_type;
- pa->contents = (unsigned char *)scratch->data;
- pa->length = scratch->length;
- scratch->data = NULL;
- *pa_out = pa;
+ (*pa_out)->contents = (uint8_t *)der_etype_info->data;
+ (*pa_out)->length = der_etype_info->length;
+ der_etype_info->data = NULL;
cleanup:
krb5_free_etype_info(context, entry);
- krb5_free_data(context, scratch);
- return retval;
-}
-
-/* Return true if request's enctypes indicate support for etype-info2. */
-static krb5_boolean
-requires_info2(const krb5_kdc_req *request)
-{
- int i;
-
- for (i = 0; i < request->nktypes; i++) {
- if (enctype_requires_etype_info_2(request->ktype[i]))
- return TRUE;
- }
- return FALSE;
-}
-
-/* Generate hint list padata for PA-ETYPE-INFO or PA-ETYPE-INFO2. */
-static void
-get_etype_info(krb5_context context, krb5_kdc_req *request,
- krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
- krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type,
- krb5_kdcpreauth_edata_respond_fn respond, void *arg)
-{
- krb5_error_code ret;
- krb5_pa_data *pa = NULL;
-
- if (rock->client_key == NULL) {
- ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
- } else if (pa_type == KRB5_PADATA_ETYPE_INFO && requires_info2(request)) {
- ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
- } else {
- ret = make_etype_info(context, pa_type, rock->client->princ,
- rock->client_key, rock->client_keyblock->enctype,
- &pa);
- }
- (*respond)(arg, ret, pa);
-}
-
-/* Generate AS-REP padata for PA-ETYPE-INFO or PA-ETYPE-INFO2. */
-static krb5_error_code
-return_etype_info(krb5_context context, krb5_pa_data *padata,
- krb5_data *req_pkt, krb5_kdc_req *request,
- krb5_kdc_rep *reply, krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa, krb5_kdcpreauth_callbacks cb,
- krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata,
- krb5_kdcpreauth_modreq modreq)
-{
- *send_pa = NULL;
- if (rock->client_key == NULL)
- return 0;
- if (padata->pa_type == KRB5_PADATA_ETYPE_INFO && requires_info2(request))
- return 0;
- return make_etype_info(context, padata->pa_type, rock->client->princ,
- rock->client_key, encrypting_key->enctype, send_pa);
-}
-
-static krb5_error_code
-return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
- krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
- krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
- krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
- krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq)
-{
- krb5_error_code retval;
- krb5_pa_data * padata;
- krb5_data * salt = NULL;
- krb5_int16 salttype;
- krb5_key_data * client_key = rock->client_key;
-
- if (client_key == NULL || requires_info2(request))
- return 0;
-
- retval = krb5_dbe_compute_salt(context, client_key, request->client,
- &salttype, &salt);
- if (retval)
- return 0;
-
- padata = k5alloc(sizeof(*padata), &retval);
- if (padata == NULL)
- goto cleanup;
- padata->magic = KV5M_PA_DATA;
-
- if (salttype == KRB5_KDB_SALTTYPE_AFS3) {
- padata->contents = k5memdup0(salt->data, salt->length, &retval);
- if (padata->contents == NULL)
- goto cleanup;
- padata->pa_type = KRB5_PADATA_AFS3_SALT;
- padata->length = salt->length + 1;
- } else {
- padata->pa_type = KRB5_PADATA_PW_SALT;
- padata->length = salt->length;
- padata->contents = (krb5_octet *)salt->data;
- salt->data = NULL;
- }
-
- *send_pa = padata;
- padata = NULL;
-
-cleanup:
- free(padata);
- krb5_free_data(context, salt);
+ krb5_free_data(context, der_etype_info);
return retval;
}
@@ -1656,69 +1564,3 @@ return_enc_padata(krb5_context context, krb5_data *req_pkt,
cleanup:
return code;
}
-
-
-#if 0
-static krb5_error_code return_server_referral(krb5_context context,
- krb5_pa_data * padata,
- krb5_db_entry *client,
- krb5_db_entry *server,
- krb5_kdc_req *request,
- krb5_kdc_rep *reply,
- krb5_key_data *client_key,
- krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa)
-{
- krb5_error_code code;
- krb5_tl_data tl_data;
- krb5_pa_data *pa_data;
- krb5_enc_data enc_data;
- krb5_data plain;
- krb5_data *enc_pa_data;
-
- *send_pa = NULL;
-
- tl_data.tl_data_type = KRB5_TL_SERVER_REFERRAL;
-
- code = krb5_dbe_lookup_tl_data(context, server, &tl_data);
- if (code || tl_data.tl_data_length == 0)
- return 0; /* no server referrals to return */
-
- plain.length = tl_data.tl_data_length;
- plain.data = tl_data.tl_data_contents;
-
- /* Encrypt ServerReferralData */
- code = krb5_encrypt_helper(context, encrypting_key,
- KRB5_KEYUSAGE_PA_SERVER_REFERRAL_DATA,
- &plain, &enc_data);
- if (code)
- return code;
-
- /* Encode ServerReferralData into PA-SERVER-REFERRAL-DATA */
- code = encode_krb5_enc_data(&enc_data, &enc_pa_data);
- if (code) {
- krb5_free_data_contents(context, &enc_data.ciphertext);
- return code;
- }
-
- krb5_free_data_contents(context, &enc_data.ciphertext);
-
- /* Return PA-SERVER-REFERRAL-DATA */
- pa_data = (krb5_pa_data *)malloc(sizeof(*pa_data));
- if (pa_data == NULL) {
- krb5_free_data(context, enc_pa_data);
- return ENOMEM;
- }
-
- pa_data->magic = KV5M_PA_DATA;
- pa_data->pa_type = KRB5_PADATA_SVR_REFERRAL_INFO;
- pa_data->length = enc_pa_data->length;
- pa_data->contents = enc_pa_data->data;
-
- free(enc_pa_data); /* don't free contents */
-
- *send_pa = pa_data;
-
- return 0;
-}
-#endif

View File

@ -1,53 +0,0 @@
From a9bc03fe03ef4b00bcdad13c99bb4c376a8b9964 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 10 Jul 2018 16:17:15 -0400
Subject: [PATCH] Use SHA-256 instead of MD5 for audit ticket IDs
ticket: 8711 (new)
(cherry picked from commit c1e1bfa26bd2f045e88e6013c500fca9428c98f3)
---
src/kdc/kdc_audit.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/src/kdc/kdc_audit.c b/src/kdc/kdc_audit.c
index c9a7f9f9d..f40913dc8 100644
--- a/src/kdc/kdc_audit.c
+++ b/src/kdc/kdc_audit.c
@@ -146,7 +146,7 @@ kau_make_tkt_id(krb5_context context,
{
krb5_error_code ret = 0;
char *hash = NULL, *ptr;
- krb5_checksum cksum;
+ uint8_t hashbytes[K5_SHA256_HASHLEN];
unsigned int i;
*out = NULL;
@@ -154,19 +154,18 @@ kau_make_tkt_id(krb5_context context,
if (ticket == NULL)
return EINVAL;
- ret = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, NULL, 0,
- &ticket->enc_part.ciphertext, &cksum);
+ ret = k5_sha256(&ticket->enc_part.ciphertext, 1, hashbytes);
if (ret)
return ret;
- hash = k5alloc(cksum.length * 2 + 1, &ret);
- if (hash != NULL) {
- for (i = 0, ptr = hash; i < cksum.length; i++, ptr += 2)
- snprintf(ptr, 3, "%02X", cksum.contents[i]);
- *ptr = '\0';
- *out = hash;
- }
- krb5_free_checksum_contents(context, &cksum);
+ hash = k5alloc(sizeof(hashbytes) * 2 + 1, &ret);
+ if (hash == NULL)
+ return ret;
+
+ for (i = 0, ptr = hash; i < sizeof(hashbytes); i++, ptr += 2)
+ snprintf(ptr, 3, "%02X", hashbytes[i]);
+ *ptr = '\0';
+ *out = hash;
return 0;
}

View File

@ -1,62 +0,0 @@
From c5df16a88027d7f9b6eb53b1c3fa949d6538616b Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 26 Mar 2018 11:24:49 -0400
Subject: [PATCH] Use k5_buf_init_dynamic_zap where appropriate
(cherry picked from commit 9172599008f3a6790d4a9a67acff58049742dcb6)
---
src/lib/krb5/ccache/cc_file.c | 4 ++--
src/lib/krb5/ccache/cc_keyring.c | 2 +-
src/util/support/utf8_conv.c | 4 +++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c
index 6789c09e1..9263a0054 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -758,7 +758,7 @@ fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
memset(creds, 0, sizeof(*creds));
k5_cc_mutex_lock(context, &data->lock);
- k5_buf_init_dynamic(&buf);
+ k5_buf_init_dynamic_zap(&buf);
ret = krb5_lock_file(context, fileno(fcursor->fp), KRB5_LOCKMODE_SHARED);
if (ret)
@@ -982,7 +982,7 @@ fcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
goto cleanup;
/* Marshal the cred and write it to the file with a single append write. */
- k5_buf_init_dynamic(&buf);
+ k5_buf_init_dynamic_zap(&buf);
k5_marshal_cred(&buf, version, creds);
ret = k5_buf_status(&buf);
if (ret)
diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c
index fba710b1b..8419f6ebf 100644
--- a/src/lib/krb5/ccache/cc_keyring.c
+++ b/src/lib/krb5/ccache/cc_keyring.c
@@ -1295,7 +1295,7 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
goto errout;
/* Serialize credential using the file ccache version 4 format. */
- k5_buf_init_dynamic(&buf);
+ k5_buf_init_dynamic_zap(&buf);
k5_marshal_cred(&buf, 4, creds);
ret = k5_buf_status(&buf);
if (ret)
diff --git a/src/util/support/utf8_conv.c b/src/util/support/utf8_conv.c
index 5cfc2c512..08cef4168 100644
--- a/src/util/support/utf8_conv.c
+++ b/src/util/support/utf8_conv.c
@@ -99,7 +99,9 @@ k5_utf8_to_utf16le(const char *utf8, uint8_t **utf16_out, size_t *nbytes_out)
*utf16_out = NULL;
*nbytes_out = 0;
- k5_buf_init_dynamic(&buf);
+ /* UTF-16 conversion is used for RC4 string-to-key, so treat this data as
+ * sensitive. */
+ k5_buf_init_dynamic_zap(&buf);
/* Examine next UTF-8 character. */
while (*utf8 != '\0') {

View File

@ -1,869 +0,0 @@
From 19109505ad04efdfd70df3ee922e22bcf5a294f3 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 19 Feb 2018 00:52:35 -0500
Subject: [PATCH] Use libkrb5support hex functions where appropriate
(cherry picked from commit b0c700608be7455041a8afc0e4502e8783ee7f30)
---
src/kadmin/dbutil/deps | 16 ++---
src/kadmin/dbutil/tabdump.c | 19 +++---
src/kadmin/ktutil/deps | 13 ++--
src/kadmin/ktutil/ktutil_funcs.c | 30 ++++-----
src/lib/crypto/crypto_tests/deps | 39 ++++++-----
src/lib/crypto/crypto_tests/t_cksum.c | 35 +++-------
src/lib/crypto/crypto_tests/t_crc.c | 28 ++------
src/lib/crypto/crypto_tests/t_hmac.c | 34 +++++-----
src/plugins/kdb/ldap/ldap_util/deps | 18 ++---
.../kdb/ldap/ldap_util/kdb5_ldap_services.c | 32 +++------
.../kdb/ldap/ldap_util/kdb5_ldap_services.h | 2 -
src/plugins/kdb/ldap/libkdb_ldap/deps | 19 +++---
.../kdb/ldap/libkdb_ldap/ldap_service_stash.c | 65 +++----------------
.../kdb/ldap/libkdb_ldap/ldap_service_stash.h | 3 -
.../kdb/ldap/libkdb_ldap/libkdb_ldap.exports | 1 -
src/slave/deps | 15 +++--
src/slave/kproplog.c | 11 ++--
src/tests/gssapi/deps | 14 ++--
src/tests/gssapi/t_prf.c | 13 ++--
19 files changed, 152 insertions(+), 255 deletions(-)
diff --git a/src/kadmin/dbutil/deps b/src/kadmin/dbutil/deps
index 4dcc33628..8b0965aac 100644
--- a/src/kadmin/dbutil/deps
+++ b/src/kadmin/dbutil/deps
@@ -185,14 +185,14 @@ $(OUTPRE)tabdump.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \
$(top_srcdir)/include/iprop_hdr.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/kdb.h $(top_srcdir)/include/kdb_log.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h kdb5_util.h tabdump.c \
- tdumputil.h
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
+ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ kdb5_util.h tabdump.c tdumputil.h
$(OUTPRE)tdumputil.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
diff --git a/src/kadmin/dbutil/tabdump.c b/src/kadmin/dbutil/tabdump.c
index fb36b060a..2f313dbb0 100644
--- a/src/kadmin/dbutil/tabdump.c
+++ b/src/kadmin/dbutil/tabdump.c
@@ -32,6 +32,7 @@
#include <k5-int.h>
#include "k5-platform.h" /* for asprintf */
+#include "k5-hex.h"
#include <limits.h>
#include <stdio.h>
@@ -230,9 +231,7 @@ static int
write_data(struct rec_args *args, krb5_data *data)
{
int ret;
- char *p;
- size_t i;
- struct k5buf buf;
+ char *hex;
struct rechandle *h = args->rh;
struct tdopts *opts = args->opts;
@@ -241,17 +240,15 @@ write_data(struct rec_args *args, krb5_data *data)
return -1;
return 0;
}
- k5_buf_init_dynamic(&buf);
- p = data->data;
- for (i = 0; i < data->length; i++)
- k5_buf_add_fmt(&buf, "%02x", (unsigned char)p[i]);
- if (buf.data == NULL) {
- errno = ENOMEM;
+ ret = k5_hex_encode(data->data, data->length, FALSE, &hex);
+ if (ret) {
+ errno = ret;
return -1;
}
- ret = writefield(h, "%s", (char *)buf.data);
- k5_buf_free(&buf);
+
+ ret = writefield(h, "%s", hex);
+ free(hex);
return ret;
}
diff --git a/src/kadmin/ktutil/deps b/src/kadmin/ktutil/deps
index 4df399924..5863e63c7 100644
--- a/src/kadmin/ktutil/deps
+++ b/src/kadmin/ktutil/deps
@@ -18,9 +18,10 @@ $(OUTPRE)ktutil_funcs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h ktutil.h ktutil_funcs.c
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ ktutil.h ktutil_funcs.c
diff --git a/src/kadmin/ktutil/ktutil_funcs.c b/src/kadmin/ktutil/ktutil_funcs.c
index 7a3aa0dca..5843e24b7 100644
--- a/src/kadmin/ktutil/ktutil_funcs.c
+++ b/src/kadmin/ktutil/ktutil_funcs.c
@@ -29,6 +29,7 @@
*/
#include "k5-int.h"
+#include "k5-hex.h"
#include "ktutil.h"
#include <string.h>
#include <ctype.h>
@@ -106,9 +107,8 @@ krb5_error_code ktutil_add(context, list, princ_str, kvno,
krb5_keyblock key;
char buf[BUFSIZ];
char promptstr[1024];
-
- char *cp;
- int i, tmp;
+ uint8_t *keybytes;
+ size_t keylen;
unsigned int pwsize = BUFSIZ;
retval = krb5_parse_name(context, princ_str, &princ);
@@ -199,24 +199,18 @@ krb5_error_code ktutil_add(context, list, princ_str, kvno,
goto cleanup;
}
- lp->entry->key.enctype = enctype;
- lp->entry->key.contents = (krb5_octet *) malloc((strlen(buf) + 1) / 2);
- if (!lp->entry->key.contents) {
- retval = ENOMEM;
+ retval = k5_hex_decode(buf, &keybytes, &keylen);
+ if (retval) {
+ if (retval == EINVAL) {
+ fprintf(stderr, _("addent: Illegal character in key.\n"));
+ retval = 0;
+ }
goto cleanup;
}
- i = 0;
- for (cp = buf; *cp; cp += 2) {
- if (!isxdigit((int) cp[0]) || !isxdigit((int) cp[1])) {
- fprintf(stderr, _("addent: Illegal character in key.\n"));
- retval = 0;
- goto cleanup;
- }
- sscanf(cp, "%02x", &tmp);
- lp->entry->key.contents[i++] = (krb5_octet) tmp;
- }
- lp->entry->key.length = i;
+ lp->entry->key.enctype = enctype;
+ lp->entry->key.contents = keybytes;
+ lp->entry->key.length = keylen;
}
lp->entry->principal = princ;
lp->entry->vno = kvno;
diff --git a/src/lib/crypto/crypto_tests/deps b/src/lib/crypto/crypto_tests/deps
index bc5422a06..5d94a593d 100644
--- a/src/lib/crypto/crypto_tests/deps
+++ b/src/lib/crypto/crypto_tests/deps
@@ -73,12 +73,13 @@ $(OUTPRE)t_hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(srcdir)/../builtin/crypto_mod.h $(srcdir)/../builtin/sha2/sha2.h \
$(srcdir)/../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h t_hmac.c
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ t_hmac.c
$(OUTPRE)t_pkcs5.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
@@ -143,12 +144,13 @@ $(OUTPRE)t_cksum.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h t_cksum.c
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ t_cksum.c
$(OUTPRE)t_cksums.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
@@ -165,12 +167,13 @@ $(OUTPRE)t_crc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(srcdir)/../builtin/crypto_mod.h $(srcdir)/../builtin/sha2/sha2.h \
$(srcdir)/../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h t_crc.c
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ t_crc.c
$(OUTPRE)t_mddriver.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h \
diff --git a/src/lib/crypto/crypto_tests/t_cksum.c b/src/lib/crypto/crypto_tests/t_cksum.c
index 2200fe76e..0edaeb850 100644
--- a/src/lib/crypto/crypto_tests/t_cksum.c
+++ b/src/lib/crypto/crypto_tests/t_cksum.c
@@ -27,6 +27,7 @@
/* Test checksum and checksum compatability for rsa-md[4,5]-des. */
#include "k5-int.h"
+#include "k5-hex.h"
#define MD5_K5BETA_COMPAT
#define MD4_K5BETA_COMPAT
@@ -50,29 +51,6 @@ print_checksum(char *text, int number, char *message, krb5_checksum *checksum)
printf("\n");
}
-static void
-parse_hexstring(const char *s, krb5_checksum *cksum)
-{
- size_t i, len;
- unsigned int byte;
- unsigned char *cp;
-
- len = strlen(s);
- cp = malloc(len / 2);
- cksum->contents = cp;
- if (cp == NULL) {
- cksum->length = 0;
- return;
- }
- cksum->length = len / 2;
- for (i = 0; i + 1 < len; i += 2) {
- sscanf(&s[i], "%2x", &byte);
- *cp++ = byte;
- }
- cksum->checksum_type = CKTYPE;
- cksum->magic = KV5M_CHECKSUM;
-}
-
/*
* Test the checksum verification of Old Style (tm) and correct RSA-MD[4,5]-DES
* checksums.
@@ -86,6 +64,7 @@ main(argc, argv)
char **argv;
{
int msgindex;
+ size_t len;
krb5_boolean valid;
krb5_keyblock keyblock;
krb5_key key;
@@ -150,12 +129,14 @@ main(argc, argv)
free(checksum.contents);
/* Verify a known-good checksum for this plaintext. */
- parse_hexstring(argv[msgindex+1], &knowncksum);
- if (knowncksum.contents == NULL) {
- printf("parse_hexstring failed\n");
- kret = 1;
+ kret = k5_hex_decode(argv[msgindex + 1], &knowncksum.contents, &len);
+ if (kret) {
+ printf("k5_hex_decode failed\n");
break;
}
+ knowncksum.length = len;
+ knowncksum.checksum_type = CKTYPE;
+ knowncksum.magic = KV5M_CHECKSUM;
kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &knowncksum,
&valid);
if (kret != 0) {
diff --git a/src/lib/crypto/crypto_tests/t_crc.c b/src/lib/crypto/crypto_tests/t_crc.c
index 190773252..1a35cfba5 100644
--- a/src/lib/crypto/crypto_tests/t_crc.c
+++ b/src/lib/crypto/crypto_tests/t_crc.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <k5-hex.h>
#include "crypto_int.h"
#define HEX 1
@@ -139,31 +140,12 @@ timetest(unsigned int nblk, unsigned int blksiz)
}
#endif
-static void gethexstr(char *data, size_t *outlen, unsigned char *outbuf,
- size_t buflen)
-{
- size_t inlen;
- char *cp, buf[3];
- long n;
-
- inlen = strlen(data);
- *outlen = 0;
- for (cp = data; (size_t) (cp - data) < inlen; cp += 2) {
- strncpy(buf, cp, 2);
- buf[2] = '\0';
- n = strtol(buf, NULL, 16);
- outbuf[(*outlen)++] = n;
- if (*outlen > buflen)
- break;
- }
-}
-
static void
verify(void)
{
unsigned int i;
struct crc_trial trial;
- unsigned char buf[4];
+ uint8_t *bytes;
size_t len;
unsigned long cksum;
char *typestr;
@@ -179,9 +161,11 @@ verify(void)
break;
case HEX:
typestr = "HEX";
- gethexstr(trial.data, &len, buf, 4);
+ if (k5_hex_decode(trial.data, &bytes, &len) != 0)
+ abort();
cksum = 0;
- mit_crc32(buf, len, &cksum);
+ mit_crc32(bytes, len, &cksum);
+ free(bytes);
break;
default:
typestr = "BOGUS";
diff --git a/src/lib/crypto/crypto_tests/t_hmac.c b/src/lib/crypto/crypto_tests/t_hmac.c
index 8961380ea..93d54828f 100644
--- a/src/lib/crypto/crypto_tests/t_hmac.c
+++ b/src/lib/crypto/crypto_tests/t_hmac.c
@@ -34,6 +34,7 @@
#include <string.h>
#include <ctype.h>
+#include <k5-hex.h>
#include "crypto_int.h"
#define ASIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
@@ -136,12 +137,10 @@ static void test_hmac()
{
krb5_keyblock key;
krb5_data in, out;
- char outbuf[20];
- char stroutbuf[80];
+ char outbuf[20], *hexdigest;
krb5_error_code err;
- unsigned int i, j;
+ unsigned int i;
int lose = 0;
- struct k5buf buf;
/* RFC 2202 test vector. */
static const struct hmac_test md5tests[] = {
@@ -151,13 +150,13 @@ static void test_hmac()
0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
},
8, "Hi There",
- "0x9294727a3638bb1c13f48ef8158bfc9d"
+ "9294727a3638bb1c13f48ef8158bfc9d"
},
{
4, "Jefe",
28, "what do ya want for nothing?",
- "0x750c783e6ab0b503eaa86e310a5db738"
+ "750c783e6ab0b503eaa86e310a5db738"
},
{
@@ -172,7 +171,7 @@ static void test_hmac()
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
},
- "0x56be34521d144c88dbb8c733f0e8b3f6"
+ "56be34521d144c88dbb8c733f0e8b3f6"
},
{
@@ -188,7 +187,7 @@ static void test_hmac()
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
},
- "0x697eaf0aca3a3aea3a75164746ffaa79"
+ "697eaf0aca3a3aea3a75164746ffaa79"
},
{
@@ -197,7 +196,7 @@ static void test_hmac()
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c
},
20, "Test With Truncation",
- "0x56461ef2342edc00f9bab995690efd4c"
+ "56461ef2342edc00f9bab995690efd4c"
},
{
@@ -212,7 +211,7 @@ static void test_hmac()
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
},
54, "Test Using Larger Than Block-Size Key - Hash Key First",
- "0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"
+ "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"
},
{
@@ -228,7 +227,7 @@ static void test_hmac()
},
73,
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
- "0x6f630fad67cda0ee1fb1f562db3aa53e"
+ "6f630fad67cda0ee1fb1f562db3aa53e"
},
};
@@ -246,19 +245,16 @@ static void test_hmac()
exit(1);
}
- k5_buf_init_fixed(&buf, stroutbuf, sizeof(stroutbuf));
- k5_buf_add(&buf, "0x");
- for (j = 0; j < out.length; j++)
- k5_buf_add_fmt(&buf, "%02x", 0xff & outbuf[j]);
- if (k5_buf_status(&buf) != 0)
+ if (k5_hex_encode(out.data, out.length, FALSE, &hexdigest) != 0)
abort();
- if (strcmp(stroutbuf, md5tests[i].hexdigest)) {
+ if (strcmp(hexdigest, md5tests[i].hexdigest)) {
printf("*** CHECK FAILED!\n"
- "\tReturned: %s.\n"
- "\tExpected: %s.\n", stroutbuf, md5tests[i].hexdigest);
+ "\tReturned: 0x%s.\n"
+ "\tExpected: 0x%s.\n", hexdigest, md5tests[i].hexdigest);
lose++;
} else
printf("Matches expected result.\n");
+ free(hexdigest);
}
/* Do again with SHA-1 tests.... */
diff --git a/src/plugins/kdb/ldap/ldap_util/deps b/src/plugins/kdb/ldap/ldap_util/deps
index 75d4dd0cf..be0194c00 100644
--- a/src/plugins/kdb/ldap/ldap_util/deps
+++ b/src/plugins/kdb/ldap/ldap_util/deps
@@ -89,15 +89,15 @@ $(OUTPRE)kdb5_ldap_services.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(srcdir)/../libkdb_ldap/ldap_krbcontainer.h $(srcdir)/../libkdb_ldap/ldap_misc.h \
$(srcdir)/../libkdb_ldap/ldap_realm.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- $(top_srcdir)/lib/kdb/kdb5.h kdb5_ldap_list.h kdb5_ldap_policy.h \
- kdb5_ldap_realm.h kdb5_ldap_services.c kdb5_ldap_services.h \
- kdb5_ldap_util.h
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h $(top_srcdir)/lib/kdb/kdb5.h \
+ kdb5_ldap_list.h kdb5_ldap_policy.h kdb5_ldap_realm.h \
+ kdb5_ldap_services.c kdb5_ldap_services.h kdb5_ldap_util.h
$(OUTPRE)getdate.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
getdate.c
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
index 3d6994c67..ce038fc3d 100644
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
@@ -37,6 +37,7 @@
*/
#include <k5-int.h>
+#include <k5-hex.h>
#include "kdb5_ldap_util.h"
#include "kdb5_ldap_list.h"
@@ -96,11 +97,10 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
char *service_object = NULL;
char *file_name = NULL, *tmp_file = NULL;
char passwd[MAX_SERVICE_PASSWD_LEN];
- char *str = NULL;
+ char *str = NULL, *hexpasswd = NULL;
char line[MAX_LEN];
FILE *pfile = NULL;
krb5_boolean print_usage = FALSE;
- krb5_data hexpasswd = {0, 0, NULL};
mode_t old_mode = 0;
/*
@@ -183,21 +183,12 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
}
/* Convert the password to hexadecimal */
- {
- krb5_data pwd;
-
- pwd.length = passwd_len;
- pwd.data = passwd;
-
- ret = tohex(pwd, &hexpasswd);
- if (ret != 0) {
- com_err(me, ret,
- _("Failed to convert the password to hexadecimal"));
- memset(passwd, 0, passwd_len);
- goto cleanup;
- }
+ ret = k5_hex_encode(passwd, passwd_len, FALSE, &hexpasswd);
+ zap(passwd, passwd_len);
+ if (ret != 0) {
+ com_err(me, ret, _("Failed to convert the password to hexadecimal"));
+ goto cleanup;
}
- memset(passwd, 0, passwd_len);
/* TODO: file lock for the service password file */
@@ -225,7 +216,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
if (str == NULL) {
if (feof(pfile)) {
/* If the service object dn is not present in the service password file */
- if (fprintf(pfile, "%s#{HEX}%s\n", service_object, hexpasswd.data) < 0) {
+ if (fprintf(pfile, "%s#{HEX}%s\n", service_object, hexpasswd) < 0) {
com_err(me, errno,
_("Failed to write service object password to file"));
fclose(pfile);
@@ -277,7 +268,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
while (fgets(line, MAX_LEN, pfile) != NULL) {
if (((str = strstr(line, service_object)) != NULL) &&
(line[strlen(service_object)] == '#')) {
- if (fprintf(newfile, "%s#{HEX}%s\n", service_object, hexpasswd.data) < 0) {
+ if (fprintf(newfile, "%s#{HEX}%s\n", service_object, hexpasswd) < 0) {
com_err(me, errno, _("Failed to write service object "
"password to file"));
fclose(newfile);
@@ -322,10 +313,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
cleanup:
- if (hexpasswd.length != 0) {
- memset(hexpasswd.data, 0, hexpasswd.length);
- free(hexpasswd.data);
- }
+ zapfreestr(hexpasswd);
if (service_object)
free(service_object);
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.h b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.h
index cf652c578..08af62e17 100644
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.h
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.h
@@ -32,6 +32,4 @@
#define MAX_LEN 1024
#define MAX_SERVICE_PASSWD_LEN 256
-extern int tohex(krb5_data, krb5_data *);
-
extern void kdb5_ldap_stash_service_password(int argc, char **argv);
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/deps b/src/plugins/kdb/ldap/libkdb_ldap/deps
index 1ff28553f..afca604dc 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/deps
+++ b/src/plugins/kdb/ldap/libkdb_ldap/deps
@@ -220,15 +220,16 @@ ldap_service_stash.so ldap_service_stash.po $(OUTPRE)ldap_service_stash.$(OBJEXT
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
$(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
$(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h $(top_srcdir)/lib/kdb/kdb5.h \
- kdb_ldap.h ldap_handle.h ldap_krbcontainer.h ldap_main.h \
- ldap_misc.h ldap_realm.h ldap_service_stash.c ldap_service_stash.h
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hex.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ $(top_srcdir)/lib/kdb/kdb5.h kdb_ldap.h ldap_handle.h \
+ ldap_krbcontainer.h ldap_main.h ldap_misc.h ldap_realm.h \
+ ldap_service_stash.c ldap_service_stash.h
kdb_xdr.so kdb_xdr.po $(OUTPRE)kdb_xdr.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c
index 87a2118ff..cb30f4a7f 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.c
@@ -31,16 +31,16 @@
#include "ldap_main.h"
#include "kdb_ldap.h"
#include "ldap_service_stash.h"
+#include <k5-hex.h>
#include <ctype.h>
/* Decode a password of the form {HEX}<hexstring>. */
static krb5_error_code
dec_password(krb5_context context, const char *str, char **password_out)
{
+ krb5_error_code ret;
+ uint8_t *bytes;
size_t len;
- const unsigned char *p;
- unsigned char *password, *q;
- unsigned int k;
*password_out = NULL;
@@ -48,30 +48,15 @@ dec_password(krb5_context context, const char *str, char **password_out)
k5_setmsg(context, EINVAL, _("Not a hexadecimal password"));
return EINVAL;
}
- str += 5;
- len = strlen(str);
- if (len % 2 != 0) {
- k5_setmsg(context, EINVAL, _("Password corrupt"));
- return EINVAL;
+ ret = k5_hex_decode(str + 5, &bytes, &len);
+ if (ret) {
+ if (ret == EINVAL)
+ k5_setmsg(context, ret, _("Password corrupt"));
+ return ret;
}
- q = password = malloc(len / 2 + 1);
- if (password == NULL)
- return ENOMEM;
-
- for (p = (unsigned char *)str; *p != '\0'; p += 2) {
- if (!isxdigit(*p) || !isxdigit(p[1])) {
- free(password);
- k5_setmsg(context, EINVAL, _("Password corrupt"));
- return EINVAL;
- }
- sscanf((char *)p, "%2x", &k);
- *q++ = k;
- }
- *q = '\0';
-
- *password_out = (char *)password;
+ *password_out = (char *)bytes;
return 0;
}
@@ -128,35 +113,3 @@ krb5_ldap_readpassword(krb5_context context, const char *filename,
/* Extract the plain password information. */
return dec_password(context, val, password_out);
}
-
-/* Encodes a sequence of bytes in hexadecimal */
-
-int
-tohex(krb5_data in, krb5_data *ret)
-{
- unsigned int i=0;
- int err = 0;
-
- ret->length = 0;
- ret->data = NULL;
-
- ret->data = malloc((unsigned int)in.length * 2 + 1 /*Null termination */);
- if (ret->data == NULL) {
- err = ENOMEM;
- goto cleanup;
- }
- ret->length = in.length * 2;
- ret->data[ret->length] = 0;
-
- for (i = 0; i < in.length; i++)
- snprintf(ret->data + 2 * i, 3, "%02x", in.data[i] & 0xff);
-
-cleanup:
-
- if (ret->length == 0) {
- free(ret->data);
- ret->data = NULL;
- }
-
- return err;
-}
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h
index dbf62443a..03cf9a1f7 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_stash.h
@@ -37,7 +37,4 @@ krb5_error_code
krb5_ldap_readpassword(krb5_context context, const char *filename,
const char *name, char **password_out);
-int
-tohex(krb5_data, krb5_data *);
-
#endif
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports b/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports
index 2342f1db8..5376d3453 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports
+++ b/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports
@@ -1,4 +1,3 @@
-tohex
krb5_ldap_open
krb5_ldap_close
krb5_ldap_db_init
diff --git a/src/slave/deps b/src/slave/deps
index c3677a5e1..c0f558ecd 100644
--- a/src/slave/deps
+++ b/src/slave/deps
@@ -64,10 +64,11 @@ $(OUTPRE)kproplog.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \
$(top_srcdir)/include/iprop_hdr.h $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/kdb.h $(top_srcdir)/include/kdb_log.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h kproplog.c
+ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \
+ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ kproplog.c
diff --git a/src/slave/kproplog.c b/src/slave/kproplog.c
index 4f19eeb8c..d4aed7ba6 100644
--- a/src/slave/kproplog.c
+++ b/src/slave/kproplog.c
@@ -9,6 +9,7 @@
*/
#include "k5-int.h"
+#include "k5-hex.h"
#include <locale.h>
#include <sys/types.h>
#include <sys/mman.h>
@@ -106,15 +107,15 @@ print_deltat(uint32_t *deltat)
static void
print_hex(const char *tag, utf8str_t *str)
{
- unsigned int i;
unsigned int len;
+ char *hex;
len = str->utf8str_t_len;
- printf("\t\t\t%s(%d): 0x", tag, len);
- for (i = 0; i < len; i++)
- printf("%02x", (krb5_octet)str->utf8str_t_val[i]);
- printf("\n");
+ if (k5_hex_encode(str->utf8str_t_val, len, FALSE, &hex) != 0)
+ abort();
+ printf("\t\t\t%s(%d): 0x%s\n", tag, len, hex);
+ free(hex);
}
/* Display string primitive. */
diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps
index b784deb63..0b50d9ed3 100644
--- a/src/tests/gssapi/deps
+++ b/src/tests/gssapi/deps
@@ -149,13 +149,13 @@ $(OUTPRE)t_prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \
$(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \
$(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- common.h t_prf.c
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hex.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h common.h t_prf.c
$(OUTPRE)t_s4u.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
$(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
diff --git a/src/tests/gssapi/t_prf.c b/src/tests/gssapi/t_prf.c
index 2c8c85188..6a698ce0f 100644
--- a/src/tests/gssapi/t_prf.c
+++ b/src/tests/gssapi/t_prf.c
@@ -24,6 +24,7 @@
*/
#include "k5-int.h"
+#include "k5-hex.h"
#include "common.h"
#include "mglueP.h"
#include "gssapiP_krb5.h"
@@ -109,12 +110,14 @@ static struct {
static size_t
fromhex(const char *hexstr, unsigned char *out)
{
- const char *p;
- size_t count;
+ uint8_t *bytes;
+ size_t len;
- for (p = hexstr, count = 0; *p != '\0'; p += 2, count++)
- sscanf(p, "%2hhx", &out[count]);
- return count;
+ if (k5_hex_decode(hexstr, &bytes, &len) != 0)
+ abort();
+ memcpy(out, bytes, len);
+ free(bytes);
+ return len;
}
int

View File

@ -0,0 +1,41 @@
From 196ee40d489e4e6a72232a3cdbb7af19a72362b3 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 4 Jan 2019 17:00:15 -0500
Subject: [PATCH] Use openssl's PRNG in FIPS mode
(cherry picked from commit 31277d79675a76612015ea00d420b41b9a232d5a)
---
src/lib/crypto/krb/prng.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index cb9ca9b98..f0e9984ca 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -26,6 +26,8 @@
#include "crypto_int.h"
+#include <openssl/rand.h>
+
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
@@ -99,9 +101,16 @@ krb5_boolean
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
{
const char *device;
-#if defined(__linux__) && defined(SYS_getrandom)
int r;
+ /* A wild FIPS mode appeared! */
+ if (FIPS_mode()) {
+ /* The return codes on this API are not good */
+ r = RAND_bytes(buf, len);
+ return r == 1;
+ }
+
+#if defined(__linux__) && defined(SYS_getrandom)
while (len > 0) {
/*
* Pull from the /dev/urandom pool, but require it to have been seeded.

View File

@ -1,30 +0,0 @@
From 55a8161c3f5238df522447499a38bf2e9497b074 Mon Sep 17 00:00:00 2001
From: Dylan Gray <35609490+Dylan-MSFT@users.noreply.github.com>
Date: Fri, 13 Jul 2018 15:09:01 -0700
Subject: [PATCH] Zap copy of secret in RC4 string-to-key
Commit b8814745049b5f401e3ae39a81dc1e14598ae48c (ticket 8576) added a
zero-terminated copy of the input string in
krb5int_arcfour_string_to_key(). This copy should be zeroed when
freed as the input string typically contains a password.
[ghudson@mit.edu: rewrote commit message]
ticket: 8713 (new)
---
src/lib/crypto/krb/s2k_rc4.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/s2k_rc4.c b/src/lib/crypto/krb/s2k_rc4.c
index 081a91217..f7e699d60 100644
--- a/src/lib/crypto/krb/s2k_rc4.c
+++ b/src/lib/crypto/krb/s2k_rc4.c
@@ -25,7 +25,7 @@ krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp,
if (utf8 == NULL)
return err;
err = k5_utf8_to_utf16le(utf8, &copystr, &copystrlen);
- free(utf8);
+ zapfree(utf8, string->length);
if (err)
return err;

View File

@ -1,29 +0,0 @@
From 5d970e16e768a134e65ee7cf367b8f34a80e0980 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 27 Mar 2018 15:42:28 -0400
Subject: [PATCH] Zap data when freeing krb5_spake_factor
krb5_spake_factor structures will sometimes hold sensitive data when
second-factor SPAKE is implemented, so should be zapped when freed.
ticket: 8647
(cherry picked from commit 9cc94a3f1ce06a4430f684300a747ec079102403)
---
src/lib/krb5/krb/kfree.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index e1ea1494a..71e7fcad0 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -897,7 +897,9 @@ k5_free_spake_factor(krb5_context context, krb5_spake_factor *val)
{
if (val == NULL)
return;
- krb5_free_data(context, val->data);
+ if (val->data != NULL)
+ zapfree(val->data->data, val->data->length);
+ free(val->data);
free(val);
}

View File

@ -1,4 +1,4 @@
From fc2953ce9ce06ff896b1687e1c0cc9b8a4357d09 Mon Sep 17 00:00:00 2001
From 174fddfa0c7d0d5c0f12d1531bc791865b630596 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:52:01 -0400
Subject: [PATCH] krb5-1.11-kpasswdtest.patch

View File

@ -1,4 +1,4 @@
From b0adf9a65d5c22a77cf957ceb1c298baff01555d Mon Sep 17 00:00:00 2001
From f19ee759c49fac6477ef77eb4a0be41118add1f5 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:57 -0400
Subject: [PATCH] krb5-1.11-run_user_0.patch

View File

@ -1,4 +1,4 @@
From abb19d2d2eac5f9f6e4a1bf26f59f3a62143dab9 Mon Sep 17 00:00:00 2001
From 3bac1a71756c634fe6b8cb3858ee9df87b1a660d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:00 -0400
Subject: [PATCH] krb5-1.12-api.patch

View File

@ -1,4 +1,4 @@
From 7f076496c7441cd108929aa05dbe009f34054bf5 Mon Sep 17 00:00:00 2001
From ef8aa0a18c2bd2f960942380202a5fa992e2c7b3 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:32:09 -0400
Subject: [PATCH] krb5-1.12-ksu-path.patch

View File

@ -1,4 +1,4 @@
From 01acbf3cbd60bd460e6ec6702589451d19c89933 Mon Sep 17 00:00:00 2001
From 2ca8d242b1cac8abdb35bf0068e5d78300e07c3c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:33:53 -0400
Subject: [PATCH] krb5-1.12-ktany.patch

View File

@ -1,4 +1,4 @@
From 4cbb4325a86d1d71fa45d254221ec460c41b434d Mon Sep 17 00:00:00 2001
From 02a10f4b9a8decc8d10f3e045282a0ae7ed1c00d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:29:58 -0400
Subject: [PATCH] krb5-1.12.1-pam.patch
@ -28,10 +28,10 @@ changes we're proposing for how it handles cache collections.
create mode 100644 src/clients/ksu/pam.h
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index d6d1279c3..5c9c13e5f 100644
index 3752d9bd5..340546d80 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1696,3 +1696,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
@@ -1697,3 +1697,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
]))
])dnl
dnl
@ -141,7 +141,7 @@ index b2fcbf240..5755bb58a 100644
clean:
$(RM) ksu
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index 7ff676ca7..c6321c01b 100644
index d9596d948..ec06788bc 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -26,6 +26,7 @@
@ -171,7 +171,7 @@ index 7ff676ca7..c6321c01b 100644
/***********/
#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
@@ -515,6 +521,23 @@ main (argc, argv)
@@ -528,6 +534,23 @@ main (argc, argv)
prog_name,target_user,client_name,
source_user,ontty());
@ -195,7 +195,7 @@ index 7ff676ca7..c6321c01b 100644
/* Run authorization as target.*/
if (krb5_seteuid(target_uid)) {
com_err(prog_name, errno, _("while switching to target for "
@@ -575,6 +598,24 @@ main (argc, argv)
@@ -588,6 +611,24 @@ main (argc, argv)
exit(1);
}
@ -220,7 +220,7 @@ index 7ff676ca7..c6321c01b 100644
}
if( some_rest_copy){
@@ -632,6 +673,30 @@ main (argc, argv)
@@ -645,6 +686,30 @@ main (argc, argv)
exit(1);
}
@ -251,7 +251,7 @@ index 7ff676ca7..c6321c01b 100644
/* set permissions */
if (setgid(target_pwd->pw_gid) < 0) {
perror("ksu: setgid");
@@ -729,7 +794,7 @@ main (argc, argv)
@@ -742,7 +807,7 @@ main (argc, argv)
fprintf(stderr, "program to be execed %s\n",params[0]);
}
@ -260,7 +260,7 @@ index 7ff676ca7..c6321c01b 100644
execv(params[0], params);
com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
sweep_up(ksu_context, cc_target);
@@ -759,16 +824,35 @@ main (argc, argv)
@@ -772,16 +837,35 @@ main (argc, argv)
if (ret_pid == -1) {
com_err(prog_name, errno, _("while calling waitpid"));
}
@ -756,10 +756,10 @@ index 000000000..0ab76569c
+void appl_pam_cleanup(void);
+#endif
diff --git a/src/configure.in b/src/configure.in
index 10f45eb12..7288a71ec 100644
index 61ef738dc..e9a12ac16 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1306,6 +1306,8 @@ AC_SUBST([VERTO_VERSION])
@@ -1352,6 +1352,8 @@ AC_SUBST([VERTO_VERSION])
AC_PATH_PROG(GROFF, groff)

View File

@ -1,4 +1,4 @@
From bd9a3cc0c53f6dc47a124eb6e8f698c7f1d3cd36 Mon Sep 17 00:00:00 2001
From 1dc051d5964aba0b8cd3d01f063ffc28253456de Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:44 -0400
Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch
@ -12,10 +12,10 @@ original version filed as RT#5891.
3 files changed, 29 insertions(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 5eeaa2d8a..1fd243094 100644
index db18226ed..518b1a547 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1677,6 +1677,15 @@ if test "$with_ldap" = yes; then
@@ -1678,6 +1678,15 @@ if test "$with_ldap" = yes; then
AC_MSG_NOTICE(enabling OpenLDAP database backend module support)
OPENLDAP_PLUGIN=yes
fi

View File

@ -1,4 +1,4 @@
From 162ba7fbce23d82719956de1b126e48fe676e9d1 Mon Sep 17 00:00:00 2001
From 90bf9e3c4a80e7e46e6e00b9d541c6144968cad4 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:45:26 -0400
Subject: [PATCH] krb5-1.15-beta1-buildconf.patch
@ -33,7 +33,7 @@ index c17cb5eb5..1891dea99 100755
lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
library=krb5
diff --git a/src/config/pre.in b/src/config/pre.in
index d4714d29a..03f5c8890 100644
index 917357df9..a8540ae2a 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIVAwUAWushEwy6CFdfg3LfAQJ+eBAAijTUBfXzCuxCwbDhCFYb1fIbHMkKkTuq
knFKv0VbALW1qUAj5v35A6GjDam6a33bMvGX8MzbGK/a9IDkpvaaXP/c37V4OfiQ
MhA6uQl0vxBMoCZqAFEVcWd6+M/0rY0WBZKpXRiZxxuSNPnSXn1l9fQAcrYKGb7I
YpaAWnzw+cc1k4Xi+GaaSghEYA4dX7TXh1fViJyHaNSESYZjH3J6wEdPm6LtZk6q
GwJw/ieMQi8djde0AhCbzMHWiaeW3jNPOJmpd3mpY04BAAkzGCyRiYGscxb6ge4u
ag2fojv7rbnJxDzy9RO0ZP0+fVPDMwInZ5GHPftbraSDFkTH2JBAYFudPsLDAoRK
FdjLeHpvuU5ifXWrLyshVYYfeXSe0fHz9Xhfhq2/OmfBD6vQl5k86z8IqxNm4ujy
ziypmTzHFnP/sBKlMgSMdDEKoKZHxevVQM5eJQd1XGexmwogkSPX8mwoEc0q4dtZ
h5w/fCu4ERA0BihvnQMZCZgwe32pO27ccPc6PqNHffUSLOq74J4gBHeoAoZ+SYPu
33oG7wxh+8WONzEGujl1lmxHFstij/njg8nULQ6bo6hSZnlMD0gU59mG9seC2jjr
E4aM4TXd1ixxPzM/cqxfI9SalytwYW0gn7Vuyj3P8xIZ5GQZiTsD7XWJqzb3xHmA
2JSQt4TK3Cc=
=9z9K
-----END PGP SIGNATURE-----

View File

@ -1,7 +1,7 @@
From c79d3881fefb6108306eb56cff62de03897d4bbc Mon Sep 17 00:00:00 2001
From 46946e305e4536a56866ff21ac1f6e8ed7c3b814 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:30:53 -0400
Subject: [PATCH] krb5-1.15.1-selinux-label.patch
Subject: [PATCH] krb5-1.17-beta1-selinux-label.patch
SELinux bases access to files on the domain of the requesting process,
the operation being performed, and the context applied to the file.
@ -45,6 +45,7 @@ which we used earlier, is some improvement.
src/include/krb5/krb5.hin | 6 +
src/kadmin/dbutil/dump.c | 11 +-
src/kdc/main.c | 2 +-
src/kprop/kpropd.c | 9 +
src/lib/kadm5/logger.c | 4 +-
src/lib/kdb/kdb_log.c | 2 +-
src/lib/krb5/ccache/cc_dir.c | 26 +-
@ -57,7 +58,6 @@ which we used earlier, is some improvement.
src/plugins/kdb/db2/libdb2/hash/hash.c | 3 +-
src/plugins/kdb/db2/libdb2/recno/rec_open.c | 4 +-
.../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +-
src/slave/kpropd.c | 9 +
src/util/profile/prof_file.c | 3 +-
src/util/support/Makefile.in | 3 +-
src/util/support/selinux.c | 406 ++++++++++++++++++
@ -66,7 +66,7 @@ which we used earlier, is some improvement.
create mode 100644 src/util/support/selinux.c
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 5c9c13e5f..6257dba40 100644
index 340546d80..a7afec09e 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag)
@ -77,7 +77,7 @@ index 5c9c13e5f..6257dba40 100644
KRB5_LIB_PARAMS
KRB5_AC_INITFINI
KRB5_AC_ENABLE_THREADS
@@ -1763,3 +1764,51 @@ AC_SUBST(PAM_LIBS)
@@ -1764,3 +1765,51 @@ AC_SUBST(PAM_LIBS)
AC_SUBST(PAM_MAN)
AC_SUBST(NON_PAM_MAN)
])dnl
@ -151,7 +151,7 @@ index f6184da3f..c17cb5eb5 100755
echo $lib_flags
diff --git a/src/config/pre.in b/src/config/pre.in
index 3f267eb1f..d4714d29a 100644
index ce87e21ca..917357df9 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
@ -162,7 +162,7 @@ index 3f267eb1f..d4714d29a 100644
INSTALL=@INSTALL@
INSTALL_STRIP=
@@ -399,7 +400,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
@@ -402,7 +403,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
# HESIOD_LIBS is -lhesiod...
HESIOD_LIBS = @HESIOD_LIBS@
@ -172,10 +172,10 @@ index 3f267eb1f..d4714d29a 100644
GSS_LIBS = $(GSS_KRB5_LIB)
# needs fixing if ever used on macOS!
diff --git a/src/configure.in b/src/configure.in
index 7288a71ec..2b6d5baa7 100644
index e9a12ac16..93aec682e 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1308,6 +1308,8 @@ AC_PATH_PROG(GROFF, groff)
@@ -1354,6 +1354,8 @@ AC_PATH_PROG(GROFF, groff)
KRB5_WITH_PAM
@ -185,7 +185,7 @@ index 7288a71ec..2b6d5baa7 100644
if test "${localedir+set}" != set; then
localedir='$(datadir)/locale'
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index e1b1cb040..9378ae047 100644
index 652242207..8f9329c59 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
@ -235,7 +235,7 @@ index 000000000..dfaaa847c
+#endif
+#endif
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index c86e78274..e81bb0a6d 100644
index c40a6cca8..3ff86d7ff 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -87,6 +87,12 @@
@ -252,7 +252,7 @@ index c86e78274..e81bb0a6d 100644
#include <stdlib.h>
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index aca136f0b..22e926ae4 100644
index c9574c6e1..8301a33d0 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname)
@ -277,20 +277,20 @@ index aca136f0b..22e926ae4 100644
if (fd == -1)
goto error;
@@ -194,7 +203,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd)
return 0;
@@ -197,7 +206,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd_out)
goto cleanup;
}
- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (*fd == -1) {
- fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd == -1) {
com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
exit_status++;
goto cleanup;
diff --git a/src/kdc/main.c b/src/kdc/main.c
index f2226da25..ccac3a759 100644
index 408c723f5..663fd6303 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -873,7 +873,7 @@ write_pid_file(const char *path)
@@ -858,7 +858,7 @@ write_pid_file(const char *path)
FILE *file;
unsigned long pid;
@ -299,11 +299,41 @@ index f2226da25..ccac3a759 100644
if (file == NULL)
return errno;
pid = (unsigned long) getpid();
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
index 68323dd0f..4cc035dc6 100644
--- a/src/kprop/kpropd.c
+++ b/src/kprop/kpropd.c
@@ -488,6 +488,9 @@ doit(int fd)
krb5_enctype etype;
int database_fd;
char host[INET6_ADDRSTRLEN + 1];
+#ifdef USE_SELINUX
+ void *selabel;
+#endif
signal_wrapper(SIGALRM, alarm_handler);
alarm(params.iprop_resync_timeout);
@@ -543,9 +546,15 @@ doit(int fd)
free(name);
exit(1);
}
+#ifdef USE_SELINUX
+ selabel = krb5int_push_fscreatecon_for(file);
+#endif
omask = umask(077);
lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600);
(void)umask(omask);
+#ifdef USE_SELINUX
+ krb5int_pop_fscreatecon(selabel);
+#endif
retval = krb5_lock_file(kpropd_context, lock_fd,
KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
if (retval) {
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
index ce79fabf7..c53a5743f 100644
index c6885edf2..9aec3c05e 100644
--- a/src/lib/kadm5/logger.c
+++ b/src/lib/kadm5/logger.c
@@ -414,7 +414,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
@@ -309,7 +309,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
*/
append = (cp[4] == ':') ? O_APPEND : 0;
if (append || cp[4] == '=') {
@ -312,7 +342,7 @@ index ce79fabf7..c53a5743f 100644
S_IRUSR | S_IWUSR | S_IRGRP);
if (fd != -1)
f = fdopen(fd, append ? "a" : "w");
@@ -918,7 +918,7 @@ krb5_klog_reopen(krb5_context kcontext)
@@ -776,7 +776,7 @@ krb5_klog_reopen(krb5_context kcontext)
* In case the old logfile did not get moved out of the
* way, open for append to prevent squashing the old logs.
*/
@ -322,18 +352,18 @@ index ce79fabf7..c53a5743f 100644
set_cloexec_file(f);
log_control.log_entries[lindex].lfu_filep = f;
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index 766d3002a..6466417b7 100644
index 2659a2501..e9b95fce5 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -476,7 +476,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
int ulogfd = -1;
@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
return ENOMEM;
if (stat(logname, &st) == -1) {
- ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
+ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
if (ulogfd == -1)
return errno;
- log_ctx->ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
+ log_ctx->ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
if (log_ctx->ulogfd == -1) {
retval = errno;
goto cleanup;
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
index bba64e516..73f0fe62d 100644
--- a/src/lib/krb5/ccache/cc_dir.c
@ -385,7 +415,7 @@ index bba64e516..73f0fe62d 100644
_("Credential cache directory %s does not exist"),
dirname);
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
index 091f2c43f..ecc97ee2f 100644
index 89cb68680..21c80d419 100644
--- a/src/lib/krb5/keytab/kt_file.c
+++ b/src/lib/krb5/keytab/kt_file.c
@@ -1024,14 +1024,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
@ -406,10 +436,10 @@ index 091f2c43f..ecc97ee2f 100644
goto report_errno;
writevno = 1;
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index e97ce5fe5..779f184cb 100644
index 4fff8f38c..40a9e7b10 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -398,7 +398,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
@@ -458,7 +458,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
fd = malloc(sizeof(*fd));
if (fd == NULL)
return ENOMEM;
@ -464,7 +494,7 @@ index 7db30a33b..2b9d01921 100644
* maybe someone took away write permission so we could only
* get shared locks?
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
index d23587a59..e2825650b 100644
index 5106a5c99..e481e8121 100644
--- a/src/plugins/kdb/db2/kdb_db2.c
+++ b/src/plugins/kdb/db2/kdb_db2.c
@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
@ -543,10 +573,10 @@ index d8b26e701..b0daa7c02 100644
if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
index 022156a5e..3d6994c67 100644
index 1ed72afe9..ce038fc3d 100644
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
@@ -203,7 +203,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
@@ -194,7 +194,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
/* set password in the file */
old_mode = umask(0177);
@ -555,7 +585,7 @@ index 022156a5e..3d6994c67 100644
if (pfile == NULL) {
com_err(me, errno, _("Failed to open file %s: %s"), file_name,
strerror (errno));
@@ -244,6 +244,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
@@ -235,6 +235,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
* Delete the existing entry and add the new entry
*/
FILE *newfile;
@ -565,7 +595,7 @@ index 022156a5e..3d6994c67 100644
mode_t omask;
@@ -255,7 +258,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
@@ -246,7 +249,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
}
omask = umask(077);
@ -579,38 +609,8 @@ index 022156a5e..3d6994c67 100644
umask (omask);
if (newfile == NULL) {
com_err(me, errno, _("Error creating file %s"), tmp_file);
diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c
index d621f108f..99676cc97 100644
--- a/src/slave/kpropd.c
+++ b/src/slave/kpropd.c
@@ -488,6 +488,9 @@ doit(int fd)
krb5_enctype etype;
int database_fd;
char host[INET6_ADDRSTRLEN + 1];
+#ifdef USE_SELINUX
+ void *selabel;
+#endif
signal_wrapper(SIGALRM, alarm_handler);
alarm(params.iprop_resync_timeout);
@@ -543,9 +546,15 @@ doit(int fd)
free(name);
exit(1);
}
+#ifdef USE_SELINUX
+ selabel = krb5int_push_fscreatecon_for(file);
+#endif
omask = umask(077);
lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600);
(void)umask(omask);
+#ifdef USE_SELINUX
+ krb5int_pop_fscreatecon(selabel);
+#endif
retval = krb5_lock_file(kpropd_context, lock_fd,
KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
if (retval) {
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
index 907c119bb..0f5462aea 100644
index 24e41fb80..0dcb6b543 100644
--- a/src/util/profile/prof_file.c
+++ b/src/util/profile/prof_file.c
@@ -33,6 +33,7 @@
@ -621,7 +621,7 @@ index 907c119bb..0f5462aea 100644
struct global_shared_profile_data {
/* This is the head of the global list of shared trees */
@@ -423,7 +424,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
@@ -391,7 +392,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
errno = 0;
@ -631,7 +631,7 @@ index 907c119bb..0f5462aea 100644
retval = errno;
if (retval == 0)
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index 0bf0b7a87..58ac2e333 100644
index db7b030b8..321672bcb 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -69,6 +69,7 @@ IPC_SYMS= \
@ -642,7 +642,7 @@ index 0bf0b7a87..58ac2e333 100644
init-addrinfo.o \
plugins.o \
errors.o \
@@ -149,7 +150,7 @@ SRCS=\
@@ -160,7 +161,7 @@ SRCS=\
SHLIB_EXPDEPS =
# Add -lm if dumping thread stats, for sqrt.

View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJcNMxOAAoJEAy6CFdfg3LfjAwP/2/oQe+4Bs/XwZTwNfakTbBl
YHSY8MNAHIKsLh6Bn+SJBQQXSE0fEsm0hYH+JWz85+mzlZk7TbNZUI+zeikhLxi6
+d8MMQBpk2mQN0dkIeWjTdfkcThGCDSL7l0fh3MuEfN5C7QPAPD1JL1ZeqXPH5AV
PSQRC9s2wiOTwwuHM2i27rZ7gdhL/xfJ3ZPUFJH4klRgszwp9j10I/nh4/XyS/wB
82umjfusFPa9VNSPzm1jm94oRmALkR3CHGvmku2XD3YOv/f5yO8C1cHWNNLxg+5h
EqVv05ddb6iLku4fRhkEjfN3VgCtEvXuMkuAXppkDJJ7wWxMBWgCIr1DS/x7LfbL
CI0ZTejn8HCUBNmRWsKkUuebgHJ7ccch8p/Fp0cV4eT1FL35N2oV51u7+/zK6R8y
1dygUF2VWFOqwm8cyczdFue7dFQVDGCw7R2eK5lXY3NpZVmJblQ/gNLMcbOxGBis
H2dOzSn+CnxlD/2LqOZnhQ1WnGBhOMxoINwX/MQsIvkwAFaM1EsdhPIP/6mSVA/g
p04+YQ2u2ag7Pq3zHsMIonC18w4ZqDPcvXvOXqCHtlQBDAMtb927XvjoTNj5W8Ei
jywxqdWuuqalmrKGPEsKVOJZN6xg7UTgaKzcvQTvW7D3gLbrTT2iM++VKB3vh9V9
SkULnR3c7fKMzFeLb/Q2
=4hZX
-----END PGP SIGNATURE-----

View File

@ -1,4 +1,4 @@
From 2338e73d8dced4f85d6b4f5a0f7df21033ac78c1 Mon Sep 17 00:00:00 2001
From 19f0dc268c127fb51c4bb8c106104eee67119cca Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:46:21 -0400
Subject: [PATCH] krb5-1.3.1-dns.patch
@ -9,7 +9,7 @@ We want to be able to use --with-netlib and --enable-dns at the same time.
1 file changed, 1 insertion(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 6257dba40..5eeaa2d8a 100644
index a7afec09e..db18226ed 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -726,6 +726,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),

View File

@ -1,4 +1,4 @@
From 20bc1c9b1d37138d1a8538f9cef22108c8fabf4f Mon Sep 17 00:00:00 2001
From 56954a72afe83cce5168bc139139d7f74c3685d6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:25 -0400
Subject: [PATCH] krb5-1.9-debuginfo.patch

View File

@ -13,7 +13,7 @@ includedir /etc/krb5.conf.d/
renew_lifetime = 7d
forwardable = true
rdns = false
pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
spake_preauth_groups = edwards25519
# default_realm = EXAMPLE.COM

View File

@ -1,111 +0,0 @@
#define _GNU_SOURCE
#include <sys/socket.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
static int
port_is_okay(unsigned short port)
{
char *p, *q;
long l;
p = getenv("NOPORT");
while ((p != NULL) && (*p != '\0')) {
l = strtol(p, &q, 10);
if ((q == NULL) || (q == p)) {
break;
}
if ((*q == '\0') || (*q == ',')) {
if (port == l) {
errno = ECONNREFUSED;
return -1;
}
}
p = q;
p += strspn(p, ",");
}
return 0;
}
int
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
unsigned short port;
static int (*next_connect)(int, const struct sockaddr *, socklen_t);
if (next_connect == NULL) {
next_connect = dlsym(RTLD_NEXT, "connect");
if (next_connect == NULL) {
errno = ENOSYS;
return -1;
}
}
if (getenv("NOPORT") == NULL) {
return next_connect(sockfd, addr, addrlen);
}
switch (addr->sa_family) {
case AF_INET:
port = ntohs(((struct sockaddr_in *)addr)->sin_port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
case AF_INET6:
port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
default:
break;
}
return next_connect(sockfd, addr, addrlen);
}
ssize_t
sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
unsigned short port;
static int (*next_sendto)(int, const void *, size_t, int,
const struct sockaddr *, socklen_t);
if (next_sendto == NULL) {
next_sendto = dlsym(RTLD_NEXT, "sendto");
if (next_sendto == NULL) {
errno = ENOSYS;
return -1;
}
}
if (getenv("NOPORT") == NULL) {
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}
if (dest_addr != NULL) {
switch (dest_addr->sa_family) {
case AF_INET:
port = ((struct sockaddr_in *)dest_addr)->sin_port;
port = ntohs(port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
case AF_INET6:
port = ((struct sockaddr_in6 *)dest_addr)->sin6_port;
port = ntohs(port);
if (port_is_okay(port) != 0) {
return -1;
}
break;
default:
break;
}
}
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}

View File

@ -16,9 +16,9 @@
Summary: The Kerberos network authentication system
Name: krb5
Version: 1.16.1
Version: 1.17
# for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces)
Release: 22%{?dist}
Release: 9%{?dist}
# lookaside-cached sources; two downloads and a build artifact
Source0: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz
@ -46,11 +46,8 @@ Source33: krb5kdc.logrotate
Source34: kadmind.logrotate
Source39: krb5-krb5kdc.conf
# Carry this locally until it's available in a packaged form.
Source100: noport.c
Patch26: krb5-1.12.1-pam.patch
Patch27: krb5-1.15.1-selinux-label.patch
Patch27: krb5-1.17-beta1-selinux-label.patch
Patch28: krb5-1.12-ksu-path.patch
Patch29: krb5-1.12-ktany.patch
Patch30: krb5-1.15-beta1-buildconf.patch
@ -60,60 +57,38 @@ Patch33: krb5-1.13-dirsrv-accountlock.patch
Patch34: krb5-1.9-debuginfo.patch
Patch35: krb5-1.11-run_user_0.patch
Patch36: krb5-1.11-kpasswdtest.patch
Patch40: Fix-hex-conversion-of-PKINIT-certid-strings.patch
Patch41: Exit-with-status-0-from-kadmind.patch
Patch42: Include-etype-info-in-for-hardware-preauth-hints.patch
Patch43: Fix-securid_sam2-preauth-for-non-default-salt.patch
Patch44: Refactor-KDC-krb5_pa_data-utility-functions.patch
Patch45: Simplify-kdc_preauth.c-systems-table.patch
Patch46: Add-PKINIT-client-support-for-freshness-token.patch
Patch47: Add-PKINIT-KDC-support-for-freshness-token.patch
Patch49: Fix-read-overflow-in-KDC-sort_pa_data.patch
Patch50: Include-preauth-name-in-trace-output-if-possible.patch
Patch51: Report-extended-errors-in-kinit-k-t-KDB.patch
Patch52: Add-libkrb5support-hex-functions-and-tests.patch
Patch53: Use-libkrb5support-hex-functions-where-appropriate.patch
Patch54: Add-ASN.1-encoders-and-decoders-for-SPAKE-types.patch
Patch55: Add-k5_buf_add_vfmt-to-k5buf-interface.patch
Patch56: Add-vector-support-to-k5_sha256.patch
Patch57: Move-zap-definition-to-k5-platform.h.patch
Patch58: Implement-k5_buf_init_dynamic_zap.patch
Patch59: Use-k5_buf_init_dynamic_zap-where-appropriate.patch
Patch60: Add-SPAKE-preauth-support.patch
Patch61: Add-doc-index-entries-for-SPAKE-constants.patch
Patch62: Fix-SPAKE-memory-leak.patch
Patch64: Zap-data-when-freeing-krb5_spake_factor.patch
Patch65: Be-more-careful-asking-for-AS-key-in-SPAKE-client.patch
Patch68: Restrict-pre-authentication-fallback-cases.patch
Patch69: Remove-nodes-option-from-make-certs-scripts.patch
Patch70: Fix-segfault-in-finish_dispatch.patch
Patch71: Log-when-non-root-ksu-authorization-fails.patch
Patch72: Add-k5_dir_filenames-to-libkrb5support.patch
Patch73: Process-profile-includedir-in-sorted-order.patch
Patch74: Make-docs-build-python3-compatible.patch
Patch75: Add-flag-to-disable-encrypted-timestamp-on-client.patch
Patch76: Explicitly-look-for-python2-in-configure.in.patch
Patch77: Use-SHA-256-instead-of-MD5-for-audit-ticket-IDs.patch
Patch78: Add-k5test-mark-function.patch
Patch79: Convert-Python-tests-to-Python-3.patch
Patch80: Zap-copy-of-secret-in-RC4-string-to-key.patch
Patch81: Fix-some-broken-tests-for-Python-3.patch
Patch82: Eliminate-preprocessor-disabled-dead-code.patch
Patch83: Make-krb5kdc-p-affect-TCP-ports.patch
Patch84: Remove-outdated-note-in-krb5kdc-man-page.patch
Patch85: Fix-k5test-prompts-for-Python-3.patch
Patch86: Become-FIPS-aware.patch
Patch87: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch
Patch88: Remove-incorrect-KDC-assertion.patch
Patch88: Add-tests-for-KCM-ccache-type.patch
Patch89: Properly-size-ifdef-in-k5_cccol_lock.patch
Patch90: Fix-memory-leak-in-none-replay-cache-type.patch
Patch91: Address-some-optimized-out-memset-calls.patch
Patch92: Use-openssl-s-PRNG-in-FIPS-mode.patch
Patch93: Become-FIPS-aware-with-3DES.patch
Patch94: FIPS-aware-SPAKE-group-negotiation.patch
Patch95: In-rd_req_dec-always-log-non-permitted-enctypes.patch
Patch96: In-kpropd-debug-log-proper-ticket-enctype-names.patch
Patch97: Make-etype-names-in-KDC-logs-human-readable.patch
Patch98: Mark-deprecated-enctypes-when-used.patch
Patch99: Add-function-and-enctype-flag-for-deprecations.patch
Patch100: Fix-argument-order-on-strlcpy-in-enctype_name.patch
License: MIT
URL: http://web.mit.edu/kerberos/www/
Group: System Environment/Libraries
BuildRequires: autoconf, bison, cmake, flex, gawk, gettext, pkgconfig, sed
BuildRequires: gcc
BuildRequires: libcom_err-devel, libedit-devel, libss-devel
BuildRequires: gzip, ncurses-devel
BuildRequires: python3-sphinx, texlive-pdftex, latexmk
BuildRequires: libverto-devel
BuildRequires: openldap-devel
BuildRequires: openssl-devel >= 0.9.8
BuildRequires: python3
BuildRequires: keyutils, keyutils-libs-devel >= 1.5.8
BuildRequires: libselinux-devel
BuildRequires: pam-devel
BuildRequires: tcl-devel
# For autosetup
BuildRequires: git
@ -144,27 +119,12 @@ BuildRequires: tex(wrapfig.sty)
# Typical fonts, and the commands which we need to have present.
BuildRequires: texlive, texlive-latex, texlive-texmf-fonts
BuildRequires: /usr/bin/pdflatex /usr/bin/makeindex
BuildRequires: keyutils, keyutils-libs-devel >= 1.5.8
BuildRequires: libselinux-devel
BuildRequires: pam-devel
BuildRequires: systemd-units
# For the test framework.
BuildRequires: perl-interpreter, dejagnu, tcl-devel, python3
BuildRequires: net-tools, rpcbind
BuildRequires: hostname
BuildRequires: iproute
BuildRequires: libverto-devel
BuildRequires: openldap-devel
BuildRequires: openssl-devel >= 0.9.8
%ifarch %{ix86} x86_64
BuildRequires: yasm
%endif
BuildRequires: nss_wrapper
BuildRequires: socket_wrapper
%description
Kerberos V5 is a trusted-third-party network authentication system,
which can improve your network's security by eliminating the insecure
@ -178,7 +138,9 @@ Requires: libkadm5%{?_isa} = %{version}-%{release}
Requires: libcom_err-devel
Requires: keyutils-libs-devel, libselinux-devel
Requires: libverto-devel
Provides: krb5-kdb-version = %{kdbversion}
Provides: krb5-kdb-devel-version = %{kdbversion}
# IPA wants ^ to be a separate symbol because they don't trust package
# managers to match -server and -devel in version. Just go with it.
%description devel
Kerberos is a network authentication system. The krb5-devel package
@ -222,6 +184,7 @@ Obsoletes: %{name}-server-%{version}-%{release}.ppc
Obsoletes: %{name}-server-%{version}-%{release}.s390
%endif
Requires: libkadm5%{?_isa} = %{version}-%{release}
Provides: krb5-kdb-version = %{kdbversion}
%description server
Kerberos is a network authentication system. The krb5-server package
@ -397,45 +360,6 @@ done
# new krb5-%{version}-pdf
tar -cf "krb5-%{version}%{prerelease}-pdfs.tar.new" build-pdf/*.pdf
# We need to cut off any access to locally-running nameservers, too.
%{__cc} -fPIC -shared -o noport.so -Wall -Wextra $RPM_SOURCE_DIR/noport.c
%check
%ifarch i686
# i686 isn't an installable arch - it's only for multilib. So don't
# bother testing the client or server code. (Library code is already
# not testable in brew/koji/copr.)
exit 0
%endif
mkdir nss_wrapper
# Set things up to use the test wrappers.
export NSS_WRAPPER_HOSTNAME=test.example.com
export NSS_WRAPPER_HOSTS="$PWD/nss_wrapper/fakehosts"
echo "127.0.0.1 $NSS_WRAPPER_HOSTNAME localhost" > $NSS_WRAPPER_HOSTS
export NOPORT='53,111'
export SOCKET_WRAPPER_DIR="$PWD/sockets" ; mkdir -p $SOCKET_WRAPPER_DIR
export LD_PRELOAD="$PWD/noport.so:libnss_wrapper.so:libsocket_wrapper.so"
# ugh. COPR doesn't expose the keyring, so try to cope.
%if 0%{?copr_username:1}
%global keyctl :
%else
%global keyctl keyctl
%endif
# Run the test suite. We can't actually run the whole thing in the build
# system, but we can at least run more than we used to. The build system may
# give us a revoked session keyring, so run affected tests with a new one.
make -C src runenv.py
: make -C src check TMPDIR=%{_tmppath}
%{keyctl} session - make -C src/lib check TMPDIR=%{_tmppath} OFFLINE=yes
make -C src/kdc check TMPDIR=%{_tmppath}
%{keyctl} session - make -C src/appl check TMPDIR=%{_tmppath}
make -C src/clients check TMPDIR=%{_tmppath}
%{keyctl} session - make -C src/util check TMPDIR=%{_tmppath}
%install
[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- "$RPM_BUILD_ROOT"
@ -700,6 +624,7 @@ exit 0
/%{_mandir}/man5/k5identity.5*
/%{_mandir}/man5/k5login.5*
/%{_mandir}/man5/krb5.conf.5*
/%{_mandir}/man7/kerberos.7*
%{_libdir}/libgssapi_krb5.so.*
%{_libdir}/libgssrpc.so.*
%{_libdir}/libk5crypto.so.*
@ -758,6 +683,42 @@ exit 0
%{_libdir}/libkadm5srv_mit.so.*
%changelog
* Tue Sep 17 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-9
- Fix argument order on strlcpy() in enctype_name()
- Resolves: #1754369
* Wed Aug 07 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-8
- Clean up etype display on KDC
- Resolves: #1664157
* Tue Jun 04 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-7
- Fix pkinit_anchors path
- Resolves: #1661339
* Wed May 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-6
- Re-provide krb5-kdb-version in -devel as well (IPA wants it)
- Resolves: #1645594
* Thu Apr 18 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-5
- Move kdbversion info into -server for IPA (so we can rebase)
- Resolves: #1645594
* Mon Apr 01 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-4
- FIPS: disable 3DES and ed25519
- Resolves: #1616326
* Tue Mar 19 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-3
- Use openssl's PRNG in FIPS mode
- Resolves: #1663571
* Tue Mar 19 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-2
- Address some optimized-out memset() calls
- Resolves: #1663503
* Mon Mar 18 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-1
- New upstream version (1.17)
- Resolves: #1645594
* Thu Feb 07 2019 Robbie Harwood <rharwood@redhat.com> - 1.16.1-22
- Remove incorrect KDC assertion
- Resolves: #1673016