Compare commits
No commits in common. 'c9' and 'i10c-beta' have entirely different histories.
@ -1 +1 @@
|
||||
SOURCES/krb5-1.21.1.tar.gz
|
||||
SOURCES/krb5-1.21.3.tar.gz
|
||||
|
@ -1 +1 @@
|
||||
505440658a00e009c430439dba60e13a98067cd3 SOURCES/krb5-1.21.1.tar.gz
|
||||
3e383bbe88cbed56bdad4ba655c40abf0e961cf7 SOURCES/krb5-1.21.3.tar.gz
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 137e424f7ae7c054e1dcb41c929a961bb021ed8b Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schneider <asn@samba.org>
|
||||
Date: Fri, 4 Aug 2023 09:54:06 +0200
|
||||
Subject: [PATCH] Fix double-free in KDC TGS processing
|
||||
|
||||
When issuing a ticket for a TGS renew or validate request, copy only
|
||||
the server field from the outer part of the header ticket to the new
|
||||
ticket. Copying the whole structure causes the enc_part pointer to be
|
||||
aliased to the header ticket until krb5_encrypt_tkt_part() is called,
|
||||
resulting in a double-free if handle_authdata() fails.
|
||||
|
||||
[ghudson@mit.edu: changed the fix to avoid aliasing enc_part rather
|
||||
than check for aliasing before freeing; rewrote commit message]
|
||||
|
||||
CVE-2023-39975:
|
||||
|
||||
In MIT krb5 release 1.21, an authenticated attacker can cause a KDC to
|
||||
free the same pointer twice if it can induce a failure in
|
||||
authorization data handling.
|
||||
|
||||
ticket: 9101 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 88a1701b423c13991a8064feeb26952d3641d840)
|
||||
---
|
||||
src/kdc/do_tgs_req.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
||||
index 6e4c8fa9f3..0acc45850f 100644
|
||||
--- a/src/kdc/do_tgs_req.c
|
||||
+++ b/src/kdc/do_tgs_req.c
|
||||
@@ -1010,8 +1010,9 @@ tgs_issue_ticket(kdc_realm_t *realm, struct tgs_req_info *t,
|
||||
}
|
||||
|
||||
if (t->req->kdc_options & (KDC_OPT_VALIDATE | KDC_OPT_RENEW)) {
|
||||
- /* Copy the whole header ticket except for authorization data. */
|
||||
- ticket_reply = *t->header_tkt;
|
||||
+ /* Copy the header ticket server and all enc-part fields except for
|
||||
+ * authorization data. */
|
||||
+ ticket_reply.server = t->header_tkt->server;
|
||||
enc_tkt_reply = *t->header_tkt->enc_part2;
|
||||
enc_tkt_reply.authorization_data = NULL;
|
||||
} else {
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,64 @@
|
||||
From abb95e961f4e6a5482220a64fba843a3adc171df Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 19 Jul 2023 13:43:17 +0200
|
||||
Subject: [PATCH] Replace ssl.wrap_socket() for tests
|
||||
|
||||
The ssl.wrap_socket() function was deprecated in Python 3.7 and is
|
||||
removed in Python 3.12. The ssl.SSLContext.wrap_socket() method
|
||||
replaces it.
|
||||
|
||||
Bump the required Python version for tests to 3.4 for
|
||||
ssl.create_default_context().
|
||||
|
||||
[ghudson@mit.edu: changed minimum Python version]
|
||||
|
||||
(cherry picked from commit 0ceab6c363e65fb21d3312a663f2b9b569ecc415)
|
||||
---
|
||||
src/configure.ac | 9 ++++-----
|
||||
src/util/wsgiref-kdcproxy.py | 4 +++-
|
||||
2 files changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 2561e917a2..487f393146 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1157,10 +1157,9 @@ AC_SUBST(PKINIT)
|
||||
# for lib/apputils
|
||||
AC_REPLACE_FUNCS(daemon)
|
||||
|
||||
-# For Python tests. Python version 3.2.4 is required as prior
|
||||
-# versions do not accept string input to subprocess.Popen.communicate
|
||||
-# when universal_newlines is set.
|
||||
-PYTHON_MINVERSION=3.2.4
|
||||
+# For Python tests. Python version 3.4 is required for
|
||||
+# ssl.create_default_context().
|
||||
+PYTHON_MINVERSION=3.4
|
||||
AC_SUBST(PYTHON_MINVERSION)
|
||||
AC_CHECK_PROG(PYTHON,python3,python3)
|
||||
if test x"$PYTHON" = x; then
|
||||
@@ -1168,7 +1167,7 @@ if test x"$PYTHON" = x; then
|
||||
fi
|
||||
HAVE_PYTHON=no
|
||||
if test x"$PYTHON" != x; then
|
||||
- wantver="(sys.hexversion >= 0x30204F0)"
|
||||
+ wantver="(sys.hexversion >= 0x30400F0)"
|
||||
if "$PYTHON" -c "import sys; sys.exit(not $wantver and 1 or 0)"; then
|
||||
HAVE_PYTHON=yes
|
||||
fi
|
||||
diff --git a/src/util/wsgiref-kdcproxy.py b/src/util/wsgiref-kdcproxy.py
|
||||
index 58759696b6..d1d10d733c 100755
|
||||
--- a/src/util/wsgiref-kdcproxy.py
|
||||
+++ b/src/util/wsgiref-kdcproxy.py
|
||||
@@ -14,6 +14,8 @@ else:
|
||||
pem = '*'
|
||||
|
||||
server = make_server('localhost', port, kdcproxy.Application())
|
||||
-server.socket = ssl.wrap_socket(server.socket, certfile=pem, server_side=True)
|
||||
+sslctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
||||
+sslctx.load_cert_chain(certfile=pem)
|
||||
+server.socket = sslctx.wrap_socket(server.socket, server_side=True)
|
||||
os.write(sys.stdout.fileno(), b'proxy server ready\n')
|
||||
server.serve_forever()
|
||||
--
|
||||
2.45.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,381 +0,0 @@
|
||||
From 0cb2e6c09fee3863c16664bf180e773f662cd313 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Steffen=20Kie=C3=9F?=
|
||||
<steffen.kiess@cis.iti.uni-stuttgart.de>
|
||||
Date: Tue, 13 Feb 2024 18:39:27 +0100
|
||||
Subject: [PATCH] Avoid strict-prototype compiler errors
|
||||
|
||||
Commit 4b9d7f7c107f01a61600fddcd8cde3812d0366a2 added the
|
||||
-Werror=strict-prototypes parameter to the build process, but left
|
||||
behind 28 function definitions using "()" instead of "(void)". Most
|
||||
of these definitions could not cause compiler errors for various
|
||||
reasons (such as an accompanying prototype), but a few could cause
|
||||
errors in gcc depending on the build configuration.
|
||||
|
||||
For consistency and safety, add "(void)" to all 28 definitions.
|
||||
|
||||
[ghudson@mit.edu: rewrote commit message]
|
||||
|
||||
(cherry picked from commit 3ae9244cd021a75eba909d872a92c25db490714d)
|
||||
---
|
||||
src/clients/kcpytkt/kcpytkt.c | 2 +-
|
||||
src/clients/kdeltkt/kdeltkt.c | 2 +-
|
||||
src/clients/kinit/kinit.c | 4 ++--
|
||||
src/clients/kinit/kinit_kdb.c | 2 +-
|
||||
src/clients/klist/klist.c | 4 ++--
|
||||
src/kadmin/cli/kadmin.c | 2 +-
|
||||
src/kadmin/dbutil/kdb5_util.c | 4 ++--
|
||||
src/kdc/main.c | 2 +-
|
||||
src/kprop/kpropd.c | 4 ++--
|
||||
src/lib/crypto/builtin/enc_provider/aes.c | 2 +-
|
||||
src/lib/crypto/openssl/hmac.c | 2 +-
|
||||
src/lib/krb5/ccache/t_memory.c | 4 ++--
|
||||
src/lib/krb5/ccache/t_stdio.c | 4 ++--
|
||||
src/plugins/kdb/db2/libdb2/btree/bt_debug.c | 2 +-
|
||||
src/plugins/kdb/db2/libdb2/btree/bt_open.c | 4 ++--
|
||||
src/plugins/kdb/db2/libdb2/hash/dbm.c | 2 +-
|
||||
src/plugins/kdb/db2/libdb2/test/btree.tests/main.c | 2 +-
|
||||
src/plugins/kdb/db2/libdb2/test/dbtest.c | 2 +-
|
||||
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 2 +-
|
||||
src/plugins/tls/k5tls/openssl.c | 2 +-
|
||||
src/tests/asn.1/make-vectors.c | 2 +-
|
||||
21 files changed, 28 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/src/clients/kcpytkt/kcpytkt.c b/src/clients/kcpytkt/kcpytkt.c
|
||||
index 0b8802261e..f1d50e5de0 100644
|
||||
--- a/src/clients/kcpytkt/kcpytkt.c
|
||||
+++ b/src/clients/kcpytkt/kcpytkt.c
|
||||
@@ -10,7 +10,7 @@ static char *prog;
|
||||
static int quiet = 0;
|
||||
|
||||
static void
|
||||
-xusage()
|
||||
+xusage(void)
|
||||
{
|
||||
fprintf(stderr, "xusage: %s [-c from_ccache] [-e etype] [-f flags] "
|
||||
"dest_ccache service1 service2 ...\n", prog);
|
||||
diff --git a/src/clients/kdeltkt/kdeltkt.c b/src/clients/kdeltkt/kdeltkt.c
|
||||
index cd0bf637db..66a32a8bd3 100644
|
||||
--- a/src/clients/kdeltkt/kdeltkt.c
|
||||
+++ b/src/clients/kdeltkt/kdeltkt.c
|
||||
@@ -10,7 +10,7 @@ static char *prog;
|
||||
static int quiet = 0;
|
||||
|
||||
static void
|
||||
-xusage()
|
||||
+xusage(void)
|
||||
{
|
||||
fprintf(stderr, "xusage: %s [-c ccache] [-e etype] [-f flags] service1 "
|
||||
"service2 ...\n", prog);
|
||||
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
|
||||
index 7a33ffae59..b27b723f2d 100644
|
||||
--- a/src/clients/kinit/kinit.c
|
||||
+++ b/src/clients/kinit/kinit.c
|
||||
@@ -55,7 +55,7 @@ get_name_from_os(void)
|
||||
#else /* HAVE_PWD_H */
|
||||
#ifdef _WIN32
|
||||
static char *
|
||||
-get_name_from_os()
|
||||
+get_name_from_os(void)
|
||||
{
|
||||
static char name[1024];
|
||||
DWORD name_size = sizeof(name);
|
||||
@@ -69,7 +69,7 @@ get_name_from_os()
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
static char *
|
||||
-get_name_from_os()
|
||||
+get_name_from_os(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/src/clients/kinit/kinit_kdb.c b/src/clients/kinit/kinit_kdb.c
|
||||
index fbd174bf0c..4e7cd50169 100644
|
||||
--- a/src/clients/kinit/kinit_kdb.c
|
||||
+++ b/src/clients/kinit/kinit_kdb.c
|
||||
@@ -69,7 +69,7 @@ kinit_kdb_init(krb5_context *pcontext, char *realm)
|
||||
}
|
||||
|
||||
void
|
||||
-kinit_kdb_fini()
|
||||
+kinit_kdb_fini(void)
|
||||
{
|
||||
kadm5_destroy(server_handle);
|
||||
}
|
||||
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
|
||||
index c797b1698f..27cf0ee11b 100644
|
||||
--- a/src/clients/klist/klist.c
|
||||
+++ b/src/clients/klist/klist.c
|
||||
@@ -359,7 +359,7 @@ do_keytab(const char *name)
|
||||
}
|
||||
|
||||
static void
|
||||
-list_all_ccaches()
|
||||
+list_all_ccaches(void)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ccache cache;
|
||||
@@ -451,7 +451,7 @@ show_all_ccaches(void)
|
||||
}
|
||||
|
||||
static void
|
||||
-do_ccache()
|
||||
+do_ccache(void)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ccache cache;
|
||||
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
|
||||
index 23b64b0f58..c1256f7708 100644
|
||||
--- a/src/kadmin/cli/kadmin.c
|
||||
+++ b/src/kadmin/cli/kadmin.c
|
||||
@@ -607,7 +607,7 @@ kadmin_startup(int argc, char *argv[], char **request_out, char ***args_out)
|
||||
}
|
||||
|
||||
int
|
||||
-quit()
|
||||
+quit(void)
|
||||
{
|
||||
kadm5_ret_t retval;
|
||||
|
||||
diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c
|
||||
index 55d529fa4c..b9b61e3f91 100644
|
||||
--- a/src/kadmin/dbutil/kdb5_util.c
|
||||
+++ b/src/kadmin/dbutil/kdb5_util.c
|
||||
@@ -367,7 +367,7 @@ main(int argc, char *argv[])
|
||||
* program is run).
|
||||
*/
|
||||
static int
|
||||
-open_db_and_mkey()
|
||||
+open_db_and_mkey(void)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
krb5_data scratch, pwd, seed;
|
||||
@@ -489,7 +489,7 @@ open_db_and_mkey()
|
||||
#endif
|
||||
|
||||
int
|
||||
-quit()
|
||||
+quit(void)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
static krb5_boolean finished = 0;
|
||||
diff --git a/src/kdc/main.c b/src/kdc/main.c
|
||||
index b43fe9a082..2dfad5673f 100644
|
||||
--- a/src/kdc/main.c
|
||||
+++ b/src/kdc/main.c
|
||||
@@ -854,7 +854,7 @@ write_pid_file(const char *path)
|
||||
}
|
||||
|
||||
static void
|
||||
-finish_realms()
|
||||
+finish_realms(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
|
||||
index f883ae2df8..fbb8e37ae9 100644
|
||||
--- a/src/kprop/kpropd.c
|
||||
+++ b/src/kprop/kpropd.c
|
||||
@@ -376,7 +376,7 @@ get_wildcard_addr(struct addrinfo **res)
|
||||
}
|
||||
|
||||
static void
|
||||
-do_standalone()
|
||||
+do_standalone(void)
|
||||
{
|
||||
struct sockaddr_in frominet;
|
||||
struct addrinfo *res;
|
||||
@@ -639,7 +639,7 @@ full_resync(CLIENT *clnt)
|
||||
* Returns non-zero on failure due to errors.
|
||||
*/
|
||||
krb5_error_code
|
||||
-do_iprop()
|
||||
+do_iprop(void)
|
||||
{
|
||||
kadm5_ret_t retval;
|
||||
krb5_principal iprop_svc_principal = NULL;
|
||||
diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c
|
||||
index 7fa9449797..39e2a84005 100644
|
||||
--- a/src/lib/crypto/builtin/enc_provider/aes.c
|
||||
+++ b/src/lib/crypto/builtin/enc_provider/aes.c
|
||||
@@ -69,7 +69,7 @@ void k5_iEnc256_CBC(struct aes_data *data);
|
||||
void k5_iDec256_CBC(struct aes_data *data);
|
||||
|
||||
static krb5_boolean
|
||||
-aesni_supported_by_cpu()
|
||||
+aesni_supported_by_cpu(void)
|
||||
{
|
||||
unsigned int a, b, c, d;
|
||||
|
||||
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
|
||||
index 25a419d73a..32dec3022e 100644
|
||||
--- a/src/lib/crypto/openssl/hmac.c
|
||||
+++ b/src/lib/crypto/openssl/hmac.c
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
#define HMAC_CTX_new compat_hmac_ctx_new
|
||||
static HMAC_CTX *
|
||||
-compat_hmac_ctx_new()
|
||||
+compat_hmac_ctx_new(void)
|
||||
{
|
||||
HMAC_CTX *ctx;
|
||||
|
||||
diff --git a/src/lib/krb5/ccache/t_memory.c b/src/lib/krb5/ccache/t_memory.c
|
||||
index 6d103a00d1..0f94e823cb 100644
|
||||
--- a/src/lib/krb5/ccache/t_memory.c
|
||||
+++ b/src/lib/krb5/ccache/t_memory.c
|
||||
@@ -85,7 +85,7 @@ krb5_creds test_creds = {
|
||||
};
|
||||
|
||||
void
|
||||
-init_test_cred()
|
||||
+init_test_cred(void)
|
||||
{
|
||||
test_creds.client = (krb5_principal) malloc(sizeof(krb5_data *)*3);
|
||||
test_creds.client[0] = &client1;
|
||||
@@ -104,7 +104,7 @@ init_test_cred()
|
||||
};
|
||||
|
||||
void
|
||||
-mcc_test()
|
||||
+mcc_test(void)
|
||||
{
|
||||
krb5_ccache id;
|
||||
krb5_creds creds;
|
||||
diff --git a/src/lib/krb5/ccache/t_stdio.c b/src/lib/krb5/ccache/t_stdio.c
|
||||
index 15185e301c..06a9c2dea1 100644
|
||||
--- a/src/lib/krb5/ccache/t_stdio.c
|
||||
+++ b/src/lib/krb5/ccache/t_stdio.c
|
||||
@@ -98,7 +98,7 @@ krb5_creds test_creds = {
|
||||
};
|
||||
|
||||
void
|
||||
-init_test_cred()
|
||||
+init_test_cred(void)
|
||||
{
|
||||
test_creds.client = (krb5_principal) malloc(sizeof(krb5_data *)*3);
|
||||
test_creds.client[0] = &client1;
|
||||
@@ -118,7 +118,7 @@ init_test_cred()
|
||||
|
||||
int flags = 0;
|
||||
void
|
||||
-scc_test()
|
||||
+scc_test(void)
|
||||
{
|
||||
krb5_ccache id;
|
||||
krb5_creds creds;
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_debug.c b/src/plugins/kdb/db2/libdb2/btree/bt_debug.c
|
||||
index bc71076a35..5a955e09be 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/btree/bt_debug.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/btree/bt_debug.c
|
||||
@@ -56,7 +56,7 @@ static FILE *tracefp;
|
||||
* initialize debugging.
|
||||
*/
|
||||
static void
|
||||
-__bt_dinit()
|
||||
+__bt_dinit(void)
|
||||
{
|
||||
static int first = 1;
|
||||
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
index a2910422eb..ef7515c3d4 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
@@ -391,7 +391,7 @@ nroot(BTREE *t)
|
||||
}
|
||||
|
||||
static int
|
||||
-tmp()
|
||||
+tmp(void)
|
||||
{
|
||||
#ifdef SIG_BLOCK
|
||||
sigset_t set, oset;
|
||||
@@ -438,7 +438,7 @@ tmp()
|
||||
}
|
||||
|
||||
static int
|
||||
-byteorder()
|
||||
+byteorder(void)
|
||||
{
|
||||
u_int32_t x;
|
||||
u_char *p;
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/hash/dbm.c b/src/plugins/kdb/db2/libdb2/hash/dbm.c
|
||||
index 2dca256dc3..e643634433 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/hash/dbm.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/hash/dbm.c
|
||||
@@ -143,7 +143,7 @@ kdb2_store(datum key, datum dat)
|
||||
}
|
||||
|
||||
static void
|
||||
-no_open_db()
|
||||
+no_open_db(void)
|
||||
{
|
||||
(void)fprintf(stderr, "dbm: no open database.\n");
|
||||
}
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/test/btree.tests/main.c b/src/plugins/kdb/db2/libdb2/test/btree.tests/main.c
|
||||
index 088f903231..eec843d4db 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/test/btree.tests/main.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/test/btree.tests/main.c
|
||||
@@ -908,7 +908,7 @@ keydata(key, data)
|
||||
}
|
||||
|
||||
void
|
||||
-usage()
|
||||
+usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-bdluw] [-c cache] [-i file] [-p page] [file]\n",
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/test/dbtest.c b/src/plugins/kdb/db2/libdb2/test/dbtest.c
|
||||
index 04bf34b90d..a2866b4412 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/test/dbtest.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/test/dbtest.c
|
||||
@@ -792,7 +792,7 @@ xmalloc(char *text, size_t len)
|
||||
}
|
||||
|
||||
void
|
||||
-usage()
|
||||
+usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 6d96499d77..af3fa9ee8b 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -3090,7 +3090,7 @@ cleanup:
|
||||
}
|
||||
|
||||
int
|
||||
-pkinit_openssl_init()
|
||||
+pkinit_openssl_init(void)
|
||||
{
|
||||
/* Initialize OpenSSL. */
|
||||
ERR_load_crypto_strings();
|
||||
diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
|
||||
index 99fda7ffcd..aab67c01cb 100644
|
||||
--- a/src/plugins/tls/k5tls/openssl.c
|
||||
+++ b/src/plugins/tls/k5tls/openssl.c
|
||||
@@ -49,7 +49,7 @@ static int ex_handle_id = -1;
|
||||
MAKE_INIT_FUNCTION(init_openssl);
|
||||
|
||||
int
|
||||
-init_openssl()
|
||||
+init_openssl(void)
|
||||
{
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
diff --git a/src/tests/asn.1/make-vectors.c b/src/tests/asn.1/make-vectors.c
|
||||
index 2fc85466bb..6f2b7dd021 100644
|
||||
--- a/src/tests/asn.1/make-vectors.c
|
||||
+++ b/src/tests/asn.1/make-vectors.c
|
||||
@@ -224,7 +224,7 @@ printbuf(void)
|
||||
}
|
||||
|
||||
int
|
||||
-main()
|
||||
+main(void)
|
||||
{
|
||||
/* Initialize values which can't use static initializers. */
|
||||
asn_long2INTEGER(&otp_format, 2); /* Alphanumeric */
|
||||
--
|
||||
2.44.0
|
||||
|
@ -1,42 +0,0 @@
|
||||
From f54763bc90df9c76c69ee9a837cf856bcf93e633 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 5 Mar 2024 17:38:49 -0500
|
||||
Subject: [PATCH] Fix leak in KDC NDR encoding
|
||||
|
||||
If the KDC tries to encode a principal containing encode invalid UTF-8
|
||||
sequences for inclusion in a PAC delegation info buffer, it will leak
|
||||
a small amount of memory in enc_wchar_pointer() before failing. Fix
|
||||
the leak.
|
||||
|
||||
ticket: 9115 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 7d0d85bf99caf60c0afd4dcf91b0c4c683b983fe)
|
||||
---
|
||||
src/kdc/ndr.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/ndr.c b/src/kdc/ndr.c
|
||||
index 48395abe52..d438408ee2 100644
|
||||
--- a/src/kdc/ndr.c
|
||||
+++ b/src/kdc/ndr.c
|
||||
@@ -96,14 +96,13 @@ enc_wchar_pointer(const char *utf8, struct encoded_wchars *encoded_out)
|
||||
size_t utf16len, num_wchars;
|
||||
uint8_t *utf16;
|
||||
|
||||
- k5_buf_init_dynamic(&b);
|
||||
-
|
||||
ret = k5_utf8_to_utf16le(utf8, &utf16, &utf16len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
num_wchars = utf16len / 2;
|
||||
|
||||
+ k5_buf_init_dynamic(&b);
|
||||
k5_buf_add_uint32_le(&b, num_wchars + 1);
|
||||
k5_buf_add_uint32_le(&b, 0);
|
||||
k5_buf_add_uint32_le(&b, num_wchars);
|
||||
--
|
||||
2.44.0
|
||||
|
@ -0,0 +1,71 @@
|
||||
From fa9dfdc9d85e88b6880edde5de45333b97a53a11 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Mon, 8 Jan 2024 16:52:27 +0100
|
||||
Subject: [PATCH] Remove klist's defname global variable
|
||||
|
||||
Addition of a "cleanup" section in kinit's show_ccache() function as
|
||||
part of commit 6c5471176f5266564fbc8a7e02f03b4b042202f8 introduced a
|
||||
double-free bug, because defname is a global variable. After the
|
||||
first call, successive calls may take place with a dangling pointer in
|
||||
defname, which will be freed if krb5_cc_get_principal() fails.
|
||||
|
||||
Convert "defname" to a local variable initialized at the beginning of
|
||||
show_ccache().
|
||||
|
||||
[ghudson@mit.edu: edited commit message]
|
||||
|
||||
(cherry picked from commit 5b00197227231943bd2305328c8260dd0b0dbcf0)
|
||||
---
|
||||
src/clients/klist/klist.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
|
||||
index b5ae96a843..b5808e5c93 100644
|
||||
--- a/src/clients/klist/klist.c
|
||||
+++ b/src/clients/klist/klist.c
|
||||
@@ -53,7 +53,6 @@ int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
|
||||
int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0;
|
||||
int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
|
||||
int show_config = 0;
|
||||
-char *defname;
|
||||
char *progname;
|
||||
krb5_timestamp now;
|
||||
unsigned int timestamp_width;
|
||||
@@ -62,7 +61,7 @@ krb5_context context;
|
||||
|
||||
static krb5_boolean is_local_tgt(krb5_principal princ, krb5_data *realm);
|
||||
static char *etype_string(krb5_enctype );
|
||||
-static void show_credential(krb5_creds *);
|
||||
+static void show_credential(krb5_creds *, const char *);
|
||||
|
||||
static void list_all_ccaches(void);
|
||||
static int list_ccache(krb5_ccache);
|
||||
@@ -473,6 +472,7 @@ show_ccache(krb5_ccache cache)
|
||||
krb5_creds creds;
|
||||
krb5_principal princ = NULL;
|
||||
krb5_error_code ret;
|
||||
+ char *defname = NULL;
|
||||
int status = 1;
|
||||
|
||||
ret = krb5_cc_get_principal(context, cache, &princ);
|
||||
@@ -503,7 +503,7 @@ show_ccache(krb5_ccache cache)
|
||||
}
|
||||
while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) {
|
||||
if (show_config || !krb5_is_config_principal(context, creds.server))
|
||||
- show_credential(&creds);
|
||||
+ show_credential(&creds, defname);
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
}
|
||||
if (ret == KRB5_CC_END) {
|
||||
@@ -676,7 +676,7 @@ print_config_data(int col, krb5_data *data)
|
||||
}
|
||||
|
||||
static void
|
||||
-show_credential(krb5_creds *cred)
|
||||
+show_credential(krb5_creds *cred, const char *defname)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ticket *tkt = NULL;
|
||||
--
|
||||
2.45.1
|
||||
|
@ -1,535 +0,0 @@
|
||||
From 28009fda028c489ae38902b2c513c4208889f043 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 14 Jun 2024 10:56:12 -0400
|
||||
Subject: [PATCH] Fix vulnerabilities in GSS message token handling
|
||||
|
||||
In gss_krb5int_unseal_token_v3() and gss_krb5int_unseal_v3_iov(),
|
||||
verify the Extra Count field of CFX wrap tokens against the encrypted
|
||||
header. Reported by Jacob Champion.
|
||||
|
||||
In gss_krb5int_unseal_token_v3(), check for a decrypted plaintext
|
||||
length too short to contain the encrypted header and extra count
|
||||
bytes. Reported by Jacob Champion.
|
||||
|
||||
In kg_unseal_iov_token(), separately track the header IOV length and
|
||||
complete token length when parsing the token's ASN.1 wrapper. This
|
||||
fix contains modified versions of functions from k5-der.h and
|
||||
util_token.c; this duplication will be cleaned up in a future commit.
|
||||
|
||||
CVE-2024-37370:
|
||||
|
||||
In MIT krb5 release 1.3 and later, an attacker can modify the
|
||||
plaintext Extra Count field of a confidential GSS krb5 wrap token,
|
||||
causing the unwrapped token to appear truncated to the application.
|
||||
|
||||
CVE-2024-37371:
|
||||
|
||||
In MIT krb5 release 1.3 and later, an attacker can cause invalid
|
||||
memory reads by sending message tokens with invalid length fields.
|
||||
|
||||
ticket: 9128 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit b0a2f8a5365f2eec3e27d78907de9f9d2c80505a)
|
||||
---
|
||||
src/lib/gssapi/krb5/k5sealv3.c | 5 +
|
||||
src/lib/gssapi/krb5/k5sealv3iov.c | 3 +-
|
||||
src/lib/gssapi/krb5/k5unsealiov.c | 80 +++++++++-
|
||||
src/tests/gssapi/t_invalid.c | 233 +++++++++++++++++++++++++-----
|
||||
4 files changed, 275 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
|
||||
index e881eee835..d3210c1107 100644
|
||||
--- a/src/lib/gssapi/krb5/k5sealv3.c
|
||||
+++ b/src/lib/gssapi/krb5/k5sealv3.c
|
||||
@@ -400,10 +400,15 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
|
||||
/* Don't use bodysize here! Use the fact that
|
||||
cipher.ciphertext.length has been adjusted to the
|
||||
correct length. */
|
||||
+ if (plain.length < 16 + ec) {
|
||||
+ free(plain.data);
|
||||
+ goto defective;
|
||||
+ }
|
||||
althdr = (unsigned char *)plain.data + plain.length - 16;
|
||||
if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
|
||||
|| althdr[2] != ptr[2]
|
||||
|| althdr[3] != ptr[3]
|
||||
+ || load_16_be(althdr+4) != ec
|
||||
|| memcmp(althdr+8, ptr+8, 8)) {
|
||||
free(plain.data);
|
||||
goto defective;
|
||||
diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c
|
||||
index 333ee124dd..f8e90c35b4 100644
|
||||
--- a/src/lib/gssapi/krb5/k5sealv3iov.c
|
||||
+++ b/src/lib/gssapi/krb5/k5sealv3iov.c
|
||||
@@ -402,9 +402,10 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
|
||||
if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
|
||||
|| althdr[2] != ptr[2]
|
||||
|| althdr[3] != ptr[3]
|
||||
+ || load_16_be(althdr + 4) != ec
|
||||
|| memcmp(althdr + 8, ptr + 8, 8) != 0) {
|
||||
*minor_status = 0;
|
||||
- return GSS_S_BAD_SIG;
|
||||
+ return GSS_S_DEFECTIVE_TOKEN;
|
||||
}
|
||||
} else {
|
||||
/* Verify checksum: note EC is checksum size here, not padding */
|
||||
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
|
||||
index 3ce2a90ce9..6a6585d9af 100644
|
||||
--- a/src/lib/gssapi/krb5/k5unsealiov.c
|
||||
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "k5-int.h"
|
||||
+#include "k5-der.h"
|
||||
#include "gssapiP_krb5.h"
|
||||
|
||||
static OM_uint32
|
||||
@@ -247,6 +248,73 @@ cleanup:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/* Similar to k5_der_get_value(), but output an unchecked content length
|
||||
+ * instead of a k5input containing the contents. */
|
||||
+static inline bool
|
||||
+get_der_tag(struct k5input *in, uint8_t idbyte, size_t *len_out)
|
||||
+{
|
||||
+ uint8_t lenbyte, i;
|
||||
+ size_t len;
|
||||
+
|
||||
+ /* Do nothing if in is empty or the next byte doesn't match idbyte. */
|
||||
+ if (in->status || in->len == 0 || *in->ptr != idbyte)
|
||||
+ return false;
|
||||
+
|
||||
+ /* Advance past the identifier byte and decode the length. */
|
||||
+ (void)k5_input_get_byte(in);
|
||||
+ lenbyte = k5_input_get_byte(in);
|
||||
+ if (lenbyte < 128) {
|
||||
+ len = lenbyte;
|
||||
+ } else {
|
||||
+ len = 0;
|
||||
+ for (i = 0; i < (lenbyte & 0x7F); i++) {
|
||||
+ if (len > (SIZE_MAX >> 8)) {
|
||||
+ k5_input_set_status(in, EOVERFLOW);
|
||||
+ return false;
|
||||
+ }
|
||||
+ len = (len << 8) | k5_input_get_byte(in);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (in->status)
|
||||
+ return false;
|
||||
+
|
||||
+ *len_out = len;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Similar to g_verify_token_header() without toktype or flags, but do not read
|
||||
+ * more than *header_len bytes of ASN.1 wrapper, and on output set *header_len
|
||||
+ * to the remaining number of header bytes. Verify the outer DER tag's length
|
||||
+ * against token_len, which may be larger (but not smaller) than *header_len.
|
||||
+ */
|
||||
+static gss_int32
|
||||
+verify_detached_wrapper(const gss_OID_desc *mech, size_t *header_len,
|
||||
+ uint8_t **header_in, size_t token_len)
|
||||
+{
|
||||
+ struct k5input in, mech_der;
|
||||
+ gss_OID_desc toid;
|
||||
+ size_t len;
|
||||
+
|
||||
+ k5_input_init(&in, *header_in, *header_len);
|
||||
+
|
||||
+ if (get_der_tag(&in, 0x60, &len)) {
|
||||
+ if (len != token_len - (in.ptr - *header_in))
|
||||
+ return G_BAD_TOK_HEADER;
|
||||
+ if (!k5_der_get_value(&in, 0x06, &mech_der))
|
||||
+ return G_BAD_TOK_HEADER;
|
||||
+ toid.elements = (uint8_t *)mech_der.ptr;
|
||||
+ toid.length = mech_der.len;
|
||||
+ if (!g_OID_equal(&toid, mech))
|
||||
+ return G_WRONG_MECH;
|
||||
+ }
|
||||
+
|
||||
+ *header_in = (uint8_t *)in.ptr;
|
||||
+ *header_len = in.len;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Caller must provide TOKEN | DATA | PADDING | TRAILER, except
|
||||
* for DCE in which case it can just provide TOKEN | DATA (must
|
||||
@@ -267,8 +335,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
|
||||
gss_iov_buffer_t header;
|
||||
gss_iov_buffer_t padding;
|
||||
gss_iov_buffer_t trailer;
|
||||
- size_t input_length;
|
||||
- unsigned int bodysize;
|
||||
+ size_t input_length, hlen;
|
||||
int toktype2;
|
||||
|
||||
header = kg_locate_header_iov(iov, iov_count, toktype);
|
||||
@@ -298,15 +365,14 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
|
||||
input_length += trailer->buffer.length;
|
||||
}
|
||||
|
||||
- code = g_verify_token_header(ctx->mech_used,
|
||||
- &bodysize, &ptr, -1,
|
||||
- input_length, 0);
|
||||
+ hlen = header->buffer.length;
|
||||
+ code = verify_detached_wrapper(ctx->mech_used, &hlen, &ptr, input_length);
|
||||
if (code != 0) {
|
||||
*minor_status = code;
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
}
|
||||
|
||||
- if (bodysize < 2) {
|
||||
+ if (hlen < 2) {
|
||||
*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
}
|
||||
@@ -314,7 +380,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
|
||||
toktype2 = load_16_be(ptr);
|
||||
|
||||
ptr += 2;
|
||||
- bodysize -= 2;
|
||||
+ hlen -= 2;
|
||||
|
||||
switch (toktype2) {
|
||||
case KG2_TOK_MIC_MSG:
|
||||
diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c
|
||||
index e08c0039f8..a052b8ab6e 100644
|
||||
--- a/src/tests/gssapi/t_invalid.c
|
||||
+++ b/src/tests/gssapi/t_invalid.c
|
||||
@@ -36,31 +36,41 @@
|
||||
*
|
||||
* 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
|
||||
* null pointer dereference. (The token must use SEAL_ALG_NONE or it will
|
||||
- * be rejected.)
|
||||
+ * be rejected.) This vulnerability also applies to IOV unwrap.
|
||||
*
|
||||
- * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
|
||||
+ * 2. A CFX wrap token with a different value of EC between the plaintext and
|
||||
+ * encrypted copies will be erroneously accepted, which allows a message
|
||||
+ * truncation attack. This vulnerability also applies to IOV unwrap.
|
||||
+ *
|
||||
+ * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an
|
||||
+ * access before the beginning of the input buffer, possibly leading to a
|
||||
+ * crash.
|
||||
+ *
|
||||
+ * 4. A CFX wrap token with a plaintext EC value greater than the plaintext
|
||||
+ * length - 16 causes an integer underflow when computing the result length,
|
||||
+ * likely causing a crash.
|
||||
+ *
|
||||
+ * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1
|
||||
+ * wrapper longer than the header buffer is present.
|
||||
+ *
|
||||
+ * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
|
||||
* header causes an input buffer overrun, usually leading to either a segv
|
||||
* or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
|
||||
- * sequence number values.
|
||||
+ * sequence number values. This vulnerability also applies to IOV unwrap.
|
||||
*
|
||||
- * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
|
||||
+ * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
|
||||
* header causes an integer underflow when computing the ciphertext length,
|
||||
* leading to an allocation error on 32-bit platforms or a segv on 64-bit
|
||||
* platforms. A pre-CFX MIC token of this size causes an input buffer
|
||||
* overrun when comparing the checksum, perhaps leading to a segv.
|
||||
*
|
||||
- * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
|
||||
+ * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
|
||||
* ciphertext (where padlen is the last byte of the decrypted ciphertext)
|
||||
* causes an integer underflow when computing the original message length,
|
||||
* leading to an allocation error.
|
||||
*
|
||||
- * 5. In the mechglue, truncated encapsulation in the initial context token can
|
||||
+ * 9. In the mechglue, truncated encapsulation in the initial context token can
|
||||
* cause input buffer overruns in gss_accept_sec_context().
|
||||
- *
|
||||
- * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with
|
||||
- * fewer than 16 bytes after the ASN.1 header will be rejected.
|
||||
- * Vulnerabilities #2 and #5 can only be robustly detected using a
|
||||
- * memory-checking environment such as valgrind.
|
||||
*/
|
||||
|
||||
#include "k5-int.h"
|
||||
@@ -97,17 +107,25 @@ struct test {
|
||||
}
|
||||
};
|
||||
|
||||
-/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */
|
||||
+static void *
|
||||
+ealloc(size_t len)
|
||||
+{
|
||||
+ void *ptr = calloc(len, 1);
|
||||
+
|
||||
+ if (ptr == NULL)
|
||||
+ abort();
|
||||
+ return ptr;
|
||||
+}
|
||||
+
|
||||
+/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key.
|
||||
+ * The context takes ownership of subkey. */
|
||||
static gss_ctx_id_t
|
||||
-make_fake_cfx_context(void)
|
||||
+make_fake_cfx_context(krb5_key subkey)
|
||||
{
|
||||
gss_union_ctx_id_t uctx;
|
||||
krb5_gss_ctx_id_t kgctx;
|
||||
- krb5_keyblock kb;
|
||||
|
||||
- kgctx = calloc(1, sizeof(*kgctx));
|
||||
- if (kgctx == NULL)
|
||||
- abort();
|
||||
+ kgctx = ealloc(sizeof(*kgctx));
|
||||
kgctx->established = 1;
|
||||
kgctx->proto = 1;
|
||||
if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
|
||||
@@ -116,15 +134,10 @@ make_fake_cfx_context(void)
|
||||
kgctx->sealalg = -1;
|
||||
kgctx->signalg = -1;
|
||||
|
||||
- kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
|
||||
- kb.length = 16;
|
||||
- kb.contents = (unsigned char *)"1234567887654321";
|
||||
- if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
|
||||
- abort();
|
||||
+ kgctx->subkey = subkey;
|
||||
+ kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
|
||||
|
||||
- uctx = calloc(1, sizeof(*uctx));
|
||||
- if (uctx == NULL)
|
||||
- abort();
|
||||
+ uctx = ealloc(sizeof(*uctx));
|
||||
uctx->mech_type = &mech_krb5;
|
||||
uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
|
||||
return (gss_ctx_id_t)uctx;
|
||||
@@ -138,9 +151,7 @@ make_fake_context(const struct test *test)
|
||||
krb5_gss_ctx_id_t kgctx;
|
||||
krb5_keyblock kb;
|
||||
|
||||
- kgctx = calloc(1, sizeof(*kgctx));
|
||||
- if (kgctx == NULL)
|
||||
- abort();
|
||||
+ kgctx = ealloc(sizeof(*kgctx));
|
||||
kgctx->established = 1;
|
||||
if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
|
||||
abort();
|
||||
@@ -162,9 +173,7 @@ make_fake_context(const struct test *test)
|
||||
if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
|
||||
abort();
|
||||
|
||||
- uctx = calloc(1, sizeof(*uctx));
|
||||
- if (uctx == NULL)
|
||||
- abort();
|
||||
+ uctx = ealloc(sizeof(*uctx));
|
||||
uctx->mech_type = &mech_krb5;
|
||||
uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
|
||||
return (gss_ctx_id_t)uctx;
|
||||
@@ -194,9 +203,7 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out)
|
||||
|
||||
assert(mech_krb5.length == 9);
|
||||
assert(len + 11 < 128);
|
||||
- wrapped = malloc(len + 13);
|
||||
- if (wrapped == NULL)
|
||||
- abort();
|
||||
+ wrapped = ealloc(len + 13);
|
||||
wrapped[0] = 0x60;
|
||||
wrapped[1] = len + 11;
|
||||
wrapped[2] = 0x06;
|
||||
@@ -207,6 +214,18 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out)
|
||||
out->value = wrapped;
|
||||
}
|
||||
|
||||
+/* Create a 16-byte header for a CFX confidential wrap token to be processed by
|
||||
+ * the fake CFX context. */
|
||||
+static void
|
||||
+write_cfx_header(uint16_t ec, uint8_t *out)
|
||||
+{
|
||||
+ memset(out, 0, 16);
|
||||
+ store_16_be(KG2_TOK_WRAP_MSG, out);
|
||||
+ out[2] = FLAG_WRAP_CONFIDENTIAL;
|
||||
+ out[3] = 0xFF;
|
||||
+ store_16_be(ec, out + 4);
|
||||
+}
|
||||
+
|
||||
/* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
|
||||
* regular and IOV unwrap. */
|
||||
static void
|
||||
@@ -238,6 +257,134 @@ test_bogus_1964_token(gss_ctx_id_t ctx)
|
||||
free(in.value);
|
||||
}
|
||||
|
||||
+static void
|
||||
+test_cfx_altered_ec(gss_ctx_id_t ctx, krb5_key subkey)
|
||||
+{
|
||||
+ OM_uint32 major, minor;
|
||||
+ uint8_t tokbuf[128], plainbuf[24];
|
||||
+ krb5_data plain;
|
||||
+ krb5_enc_data cipher;
|
||||
+ gss_buffer_desc in, out;
|
||||
+ gss_iov_buffer_desc iov[2];
|
||||
+
|
||||
+ /* Construct a header with a plaintext EC value of 3. */
|
||||
+ write_cfx_header(3, tokbuf);
|
||||
+
|
||||
+ /* Encrypt a plaintext and a copy of the header with the EC value 0. */
|
||||
+ memcpy(plainbuf, "truncate", 8);
|
||||
+ memcpy(plainbuf + 8, tokbuf, 16);
|
||||
+ store_16_be(0, plainbuf + 12);
|
||||
+ plain = make_data(plainbuf, 24);
|
||||
+ cipher.ciphertext.data = (char *)tokbuf + 16;
|
||||
+ cipher.ciphertext.length = sizeof(tokbuf) - 16;
|
||||
+ cipher.enctype = subkey->keyblock.enctype;
|
||||
+ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
|
||||
+ &plain, &cipher) != 0)
|
||||
+ abort();
|
||||
+
|
||||
+ /* Verify that the token is rejected by gss_unwrap(). */
|
||||
+ in.value = tokbuf;
|
||||
+ in.length = 16 + cipher.ciphertext.length;
|
||||
+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
|
||||
+ if (major != GSS_S_DEFECTIVE_TOKEN)
|
||||
+ abort();
|
||||
+ (void)gss_release_buffer(&minor, &out);
|
||||
+
|
||||
+ /* Verify that the token is rejected by gss_unwrap_iov(). */
|
||||
+ iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
|
||||
+ iov[0].buffer = in;
|
||||
+ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
|
||||
+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
|
||||
+ if (major != GSS_S_DEFECTIVE_TOKEN)
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_cfx_short_plaintext(gss_ctx_id_t ctx, krb5_key subkey)
|
||||
+{
|
||||
+ OM_uint32 major, minor;
|
||||
+ uint8_t tokbuf[128], zerobyte = 0;
|
||||
+ krb5_data plain;
|
||||
+ krb5_enc_data cipher;
|
||||
+ gss_buffer_desc in, out;
|
||||
+
|
||||
+ write_cfx_header(0, tokbuf);
|
||||
+
|
||||
+ /* Encrypt a single byte, with no copy of the header. */
|
||||
+ plain = make_data(&zerobyte, 1);
|
||||
+ cipher.ciphertext.data = (char *)tokbuf + 16;
|
||||
+ cipher.ciphertext.length = sizeof(tokbuf) - 16;
|
||||
+ cipher.enctype = subkey->keyblock.enctype;
|
||||
+ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
|
||||
+ &plain, &cipher) != 0)
|
||||
+ abort();
|
||||
+
|
||||
+ /* Verify that the token is rejected by gss_unwrap(). */
|
||||
+ in.value = tokbuf;
|
||||
+ in.length = 16 + cipher.ciphertext.length;
|
||||
+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
|
||||
+ if (major != GSS_S_DEFECTIVE_TOKEN)
|
||||
+ abort();
|
||||
+ (void)gss_release_buffer(&minor, &out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_cfx_large_ec(gss_ctx_id_t ctx, krb5_key subkey)
|
||||
+{
|
||||
+ OM_uint32 major, minor;
|
||||
+ uint8_t tokbuf[128] = { 0 }, plainbuf[20];
|
||||
+ krb5_data plain;
|
||||
+ krb5_enc_data cipher;
|
||||
+ gss_buffer_desc in, out;
|
||||
+
|
||||
+ /* Construct a header with an EC value of 5. */
|
||||
+ write_cfx_header(5, tokbuf);
|
||||
+
|
||||
+ /* Encrypt a 4-byte plaintext plus the header. */
|
||||
+ memcpy(plainbuf, "abcd", 4);
|
||||
+ memcpy(plainbuf + 4, tokbuf, 16);
|
||||
+ plain = make_data(plainbuf, 20);
|
||||
+ cipher.ciphertext.data = (char *)tokbuf + 16;
|
||||
+ cipher.ciphertext.length = sizeof(tokbuf) - 16;
|
||||
+ cipher.enctype = subkey->keyblock.enctype;
|
||||
+ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
|
||||
+ &plain, &cipher) != 0)
|
||||
+ abort();
|
||||
+
|
||||
+ /* Verify that the token is rejected by gss_unwrap(). */
|
||||
+ in.value = tokbuf;
|
||||
+ in.length = 16 + cipher.ciphertext.length;
|
||||
+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
|
||||
+ if (major != GSS_S_DEFECTIVE_TOKEN)
|
||||
+ abort();
|
||||
+ (void)gss_release_buffer(&minor, &out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_iov_large_asn1_wrapper(gss_ctx_id_t ctx)
|
||||
+{
|
||||
+ OM_uint32 minor, major;
|
||||
+ uint8_t databuf[10] = { 0 };
|
||||
+ gss_iov_buffer_desc iov[2];
|
||||
+
|
||||
+ /*
|
||||
+ * In this IOV array, the header contains a DER tag with a dangling eight
|
||||
+ * bytes of length field. The data IOV indicates a total token length
|
||||
+ * sufficient to contain the length bytes.
|
||||
+ */
|
||||
+ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
|
||||
+ iov[0].buffer.value = ealloc(2);
|
||||
+ iov[0].buffer.length = 2;
|
||||
+ memcpy(iov[0].buffer.value, "\x60\x88", 2);
|
||||
+ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
|
||||
+ iov[1].buffer.value = databuf;
|
||||
+ iov[1].buffer.length = 10;
|
||||
+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
|
||||
+ if (major != GSS_S_DEFECTIVE_TOKEN)
|
||||
+ abort();
|
||||
+ free(iov[0].buffer.value);
|
||||
+}
|
||||
+
|
||||
/* Process wrap and MIC tokens with incomplete headers. */
|
||||
static void
|
||||
test_short_header(gss_ctx_id_t ctx)
|
||||
@@ -387,9 +534,7 @@ try_accept(void *value, size_t len)
|
||||
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
||||
|
||||
/* Copy the provided value to make input overruns more obvious. */
|
||||
- in.value = malloc(len);
|
||||
- if (in.value == NULL)
|
||||
- abort();
|
||||
+ in.value = ealloc(len);
|
||||
memcpy(in.value, value, len);
|
||||
in.length = len;
|
||||
(void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in,
|
||||
@@ -424,11 +569,23 @@ test_short_encapsulation(void)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
+ krb5_keyblock kb;
|
||||
+ krb5_key cfx_subkey;
|
||||
gss_ctx_id_t ctx;
|
||||
size_t i;
|
||||
|
||||
- ctx = make_fake_cfx_context();
|
||||
+ kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
|
||||
+ kb.length = 16;
|
||||
+ kb.contents = (unsigned char *)"1234567887654321";
|
||||
+ if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0)
|
||||
+ abort();
|
||||
+
|
||||
+ ctx = make_fake_cfx_context(cfx_subkey);
|
||||
test_bogus_1964_token(ctx);
|
||||
+ test_cfx_altered_ec(ctx, cfx_subkey);
|
||||
+ test_cfx_short_plaintext(ctx, cfx_subkey);
|
||||
+ test_cfx_large_ec(ctx, cfx_subkey);
|
||||
+ test_iov_large_asn1_wrapper(ctx);
|
||||
free_fake_context(ctx);
|
||||
|
||||
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
|
||||
--
|
||||
2.45.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,175 +0,0 @@
|
||||
From 5464ad5b64f7ce7c3d78082352189af7c8feb95f Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 6 Sep 2024 17:18:11 +0200
|
||||
Subject: [PATCH] Fix various issues detected by static analysis
|
||||
|
||||
(cherry picked from commit 53d352949941ee236461658d01f03c37abafc6f6)
|
||||
---
|
||||
src/clients/klist/klist.c | 13 +++++++------
|
||||
src/kadmin/dbutil/dump.c | 5 +++++
|
||||
src/kdc/ndr.c | 2 +-
|
||||
src/lib/kdb/decrypt_key.c | 2 +-
|
||||
src/lib/rpc/svc_auth_gss.c | 5 ++++-
|
||||
src/lib/rpc/svc_udp.c | 13 +++++++------
|
||||
src/util/support/threads.c | 2 --
|
||||
7 files changed, 25 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
|
||||
index 27cf0ee11b..9db66f6072 100644
|
||||
--- a/src/clients/klist/klist.c
|
||||
+++ b/src/clients/klist/klist.c
|
||||
@@ -666,7 +666,7 @@ show_credential(krb5_creds *cred)
|
||||
krb5_error_code ret;
|
||||
krb5_ticket *tkt = NULL;
|
||||
char *name = NULL, *sname = NULL, *tktsname, *flags;
|
||||
- int extra_field = 0, ccol = 0, i;
|
||||
+ int extra_field = 0, ccol = 0, i, r;
|
||||
krb5_boolean is_config = krb5_is_config_principal(context, cred->server);
|
||||
|
||||
ret = krb5_unparse_name(context, cred->client, &name);
|
||||
@@ -696,11 +696,12 @@ show_credential(krb5_creds *cred)
|
||||
fputs("config: ", stdout);
|
||||
ccol = 8;
|
||||
for (i = 1; i < cred->server->length; i++) {
|
||||
- ccol += printf("%s%.*s%s",
|
||||
- i > 1 ? "(" : "",
|
||||
- (int)cred->server->data[i].length,
|
||||
- cred->server->data[i].data,
|
||||
- i > 1 ? ")" : "");
|
||||
+ r = printf("%s%.*s%s", i > 1 ? "(" : "",
|
||||
+ (int)cred->server->data[i].length,
|
||||
+ cred->server->data[i].data,
|
||||
+ i > 1 ? ")" : "");
|
||||
+ if (r >= 0)
|
||||
+ ccol += r;
|
||||
}
|
||||
fputs(" = ", stdout);
|
||||
ccol += 3;
|
||||
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
|
||||
index 4d6cc0bdf9..feb053d834 100644
|
||||
--- a/src/kadmin/dbutil/dump.c
|
||||
+++ b/src/kadmin/dbutil/dump.c
|
||||
@@ -704,6 +704,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
|
||||
|
||||
dbentry->len = u1;
|
||||
dbentry->n_key_data = u4;
|
||||
+
|
||||
+ if (u5 > UINT16_MAX) {
|
||||
+ load_err(fname, *linenop, _("invalid principal extra data size"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
dbentry->e_length = u5;
|
||||
|
||||
if (kp != NULL) {
|
||||
diff --git a/src/kdc/ndr.c b/src/kdc/ndr.c
|
||||
index d438408ee2..38be9fe42a 100644
|
||||
--- a/src/kdc/ndr.c
|
||||
+++ b/src/kdc/ndr.c
|
||||
@@ -242,7 +242,7 @@ ndr_enc_delegation_info(struct pac_s4u_delegation_info *in, krb5_data *out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
size_t i;
|
||||
- struct k5buf b;
|
||||
+ struct k5buf b = EMPTY_K5BUF;
|
||||
struct encoded_wchars pt_encoded = { 0 }, *tss_encoded = NULL;
|
||||
uint32_t pointer = 0;
|
||||
|
||||
diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c
|
||||
index 82bbed6312..c971793c9d 100644
|
||||
--- a/src/lib/kdb/decrypt_key.c
|
||||
+++ b/src/lib/kdb/decrypt_key.c
|
||||
@@ -60,7 +60,7 @@ krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
|
||||
krb5_keyblock *dbkey_out,
|
||||
krb5_keysalt *keysalt_out)
|
||||
{
|
||||
- krb5_error_code ret;
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
int16_t keylen;
|
||||
krb5_enc_data cipher;
|
||||
krb5_data plain = empty_data();
|
||||
diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
|
||||
index 98d601c8ab..461e5de542 100644
|
||||
--- a/src/lib/rpc/svc_auth_gss.c
|
||||
+++ b/src/lib/rpc/svc_auth_gss.c
|
||||
@@ -297,7 +297,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
struct opaque_auth *oa;
|
||||
gss_buffer_desc rpcbuf, checksum;
|
||||
OM_uint32 maj_stat, min_stat, qop_state;
|
||||
- u_char rpchdr[128];
|
||||
+ u_char rpchdr[32 + MAX_AUTH_BYTES];
|
||||
int32_t *buf;
|
||||
|
||||
log_debug("in svcauth_gss_validate()");
|
||||
@@ -315,6 +315,8 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
return (FALSE);
|
||||
|
||||
buf = (int32_t *)(void *)rpchdr;
|
||||
+
|
||||
+ /* Write the 32 first bytes of the header. */
|
||||
IXDR_PUT_LONG(buf, msg->rm_xid);
|
||||
IXDR_PUT_ENUM(buf, msg->rm_direction);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
|
||||
@@ -323,6 +325,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
+
|
||||
if (oa->oa_length) {
|
||||
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
|
||||
buf += RNDUP(oa->oa_length) / sizeof(int32_t);
|
||||
diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c
|
||||
index 8ecbdf2b33..3aff277eb7 100644
|
||||
--- a/src/lib/rpc/svc_udp.c
|
||||
+++ b/src/lib/rpc/svc_udp.c
|
||||
@@ -248,8 +248,9 @@ static bool_t svcudp_reply(
|
||||
{
|
||||
struct svcudp_data *su = su_data(xprt);
|
||||
XDR *xdrs = &su->su_xdrs;
|
||||
- int slen;
|
||||
+ u_int slen;
|
||||
bool_t stat = FALSE;
|
||||
+ ssize_t r;
|
||||
|
||||
xdrproc_t xdr_results = NULL;
|
||||
caddr_t xdr_location = 0;
|
||||
@@ -272,12 +273,12 @@ static bool_t svcudp_reply(
|
||||
if (xdr_replymsg(xdrs, msg) &&
|
||||
(!has_args ||
|
||||
(SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
|
||||
- slen = (int)XDR_GETPOS(xdrs);
|
||||
- if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
|
||||
- (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
|
||||
- == slen) {
|
||||
+ slen = XDR_GETPOS(xdrs);
|
||||
+ r = sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
|
||||
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen);
|
||||
+ if (r >= 0 && (u_int)r == slen) {
|
||||
stat = TRUE;
|
||||
- if (su->su_cache && slen >= 0) {
|
||||
+ if (su->su_cache) {
|
||||
cache_set(xprt, (uint32_t) slen);
|
||||
}
|
||||
}
|
||||
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
|
||||
index be7e4c2e3f..4ded805b79 100644
|
||||
--- a/src/util/support/threads.c
|
||||
+++ b/src/util/support/threads.c
|
||||
@@ -118,7 +118,6 @@ struct tsd_block {
|
||||
# pragma weak pthread_mutex_destroy
|
||||
# pragma weak pthread_mutex_init
|
||||
# pragma weak pthread_self
|
||||
-# pragma weak pthread_equal
|
||||
# pragma weak pthread_getspecific
|
||||
# pragma weak pthread_setspecific
|
||||
# pragma weak pthread_key_create
|
||||
@@ -151,7 +150,6 @@ int krb5int_pthread_loaded (void)
|
||||
|| &pthread_mutex_destroy == 0
|
||||
|| &pthread_mutex_init == 0
|
||||
|| &pthread_self == 0
|
||||
- || &pthread_equal == 0
|
||||
/* Any program that's really multithreaded will have to be
|
||||
able to create threads. */
|
||||
|| &pthread_create == 0
|
||||
--
|
||||
2.46.0
|
||||
|
@ -1,629 +0,0 @@
|
||||
From 023dcf87d34e29649dd76d33ce7d896c2b6f61d2 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 22 Aug 2024 17:15:50 +0200
|
||||
Subject: [PATCH] Generate and verify message MACs in libkrad
|
||||
|
||||
Implement some of the measures specified in
|
||||
draft-ietf-radext-deprecating-radius-03 for mitigating the BlastRADIUS
|
||||
attack (CVE-2024-3596):
|
||||
|
||||
* Include a Message-Authenticator MAC as the first attribute when
|
||||
generating a packet of type Access-Request, Access-Reject,
|
||||
Access-Accept, or Access-Challenge (sections 5.2.1 and 5.2.4), if
|
||||
the secret is non-empty. (An empty secret indicates the use of Unix
|
||||
domain socket transport.)
|
||||
|
||||
* Validate the Message-Authenticator MAC in received packets, if
|
||||
present.
|
||||
|
||||
FreeRADIUS enforces Message-Authenticator as of versions 3.2.5 and
|
||||
3.0.27. libkrad must generate Message-Authenticator attributes in
|
||||
order to remain compatible with these implementations.
|
||||
|
||||
[ghudson@mit.edu: adjusted style and naming; simplified some
|
||||
functions; edited commit message]
|
||||
|
||||
ticket: 9142 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 871125fea8ce0370a972bf65f7d1de63f619b06c)
|
||||
---
|
||||
src/include/k5-int.h | 5 +
|
||||
src/lib/crypto/krb/checksum_hmac_md5.c | 28 ++++
|
||||
src/lib/crypto/libk5crypto.exports | 1 +
|
||||
src/lib/krad/attr.c | 17 ++
|
||||
src/lib/krad/attrset.c | 59 +++++--
|
||||
src/lib/krad/internal.h | 7 +-
|
||||
src/lib/krad/packet.c | 206 +++++++++++++++++++++++--
|
||||
src/lib/krad/t_attrset.c | 2 +-
|
||||
src/lib/krad/t_daemon.py | 3 +-
|
||||
src/lib/krad/t_packet.c | 11 ++
|
||||
src/tests/t_otp.py | 3 +
|
||||
11 files changed, 311 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index 69d6a6f569..b7789a2dd8 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -2403,4 +2403,9 @@ krb5_boolean
|
||||
k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
||||
krb5_const_principal princ);
|
||||
|
||||
+/* Generate an HMAC-MD5 keyed checksum as specified by RFC 2104. */
|
||||
+krb5_error_code
|
||||
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output);
|
||||
+
|
||||
#endif /* _KRB5_INT_H */
|
||||
diff --git a/src/lib/crypto/krb/checksum_hmac_md5.c b/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
index ec024f3966..a809388549 100644
|
||||
--- a/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
+++ b/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
@@ -92,3 +92,31 @@ cleanup:
|
||||
free(hash_iov);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+krb5_error_code
|
||||
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
|
||||
+ krb5_keyblock keyblock = { 0 };
|
||||
+ krb5_data hashed_key;
|
||||
+ uint8_t hkeybuf[16];
|
||||
+ krb5_crypto_iov iov;
|
||||
+
|
||||
+ /* Hash the key if it is longer than the block size. */
|
||||
+ if (key->length > hash->blocksize) {
|
||||
+ hashed_key = make_data(hkeybuf, sizeof(hkeybuf));
|
||||
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov.data = *key;
|
||||
+ ret = hash->hash(&iov, 1, &hashed_key);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ key = &hashed_key;
|
||||
+ }
|
||||
+
|
||||
+ keyblock.magic = KV5M_KEYBLOCK;
|
||||
+ keyblock.length = key->length;
|
||||
+ keyblock.contents = (uint8_t *)key->data;
|
||||
+ return krb5int_hmac_keyblock(hash, &keyblock, data, num_data, output);
|
||||
+}
|
||||
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
|
||||
index d8ffa63304..00e0ce1812 100644
|
||||
--- a/src/lib/crypto/libk5crypto.exports
|
||||
+++ b/src/lib/crypto/libk5crypto.exports
|
||||
@@ -102,3 +102,4 @@ krb5_c_prfplus
|
||||
krb5_c_derive_prfplus
|
||||
k5_enctype_to_ssf
|
||||
krb5int_c_deprecated_enctype
|
||||
+k5_hmac_md5
|
||||
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
|
||||
index 42d354a3b5..65ed1d35e7 100644
|
||||
--- a/src/lib/krad/attr.c
|
||||
+++ b/src/lib/krad/attr.c
|
||||
@@ -125,6 +125,23 @@ static const attribute_record attributes[UCHAR_MAX] = {
|
||||
{"NAS-Port-Type", 4, 4, NULL, NULL},
|
||||
{"Port-Limit", 4, 4, NULL, NULL},
|
||||
{"Login-LAT-Port", 1, MAX_ATTRSIZE, NULL, NULL},
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Password-Retry */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Prompt */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Connect-Info */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Configuration-Token */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* EAP-Message */
|
||||
+ {"Message-Authenticator", MD5_DIGEST_SIZE, MD5_DIGEST_SIZE, NULL, NULL},
|
||||
};
|
||||
|
||||
/* Encode User-Password attribute. */
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||
index 6ec031e320..e5457ebfd7 100644
|
||||
--- a/src/lib/krad/attrset.c
|
||||
+++ b/src/lib/krad/attrset.c
|
||||
@@ -164,15 +164,44 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Place an encoded attributes into outbuf at position *i. Increment *i by the
|
||||
+ * length of the encoding. */
|
||||
+static krb5_error_code
|
||||
+append_attr(krb5_context ctx, const char *secret,
|
||||
+ const uint8_t *auth, krad_attr type, const krb5_data *data,
|
||||
+ uint8_t outbuf[MAX_ATTRSETSIZE], size_t *i, krb5_boolean *is_fips)
|
||||
+{
|
||||
+ uint8_t buffer[MAX_ATTRSIZE];
|
||||
+ size_t attrlen;
|
||||
+ krb5_error_code retval;
|
||||
+
|
||||
+ retval = kr_attr_encode(ctx, secret, auth, type, data, buffer, &attrlen,
|
||||
+ is_fips);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ if (attrlen > MAX_ATTRSETSIZE - *i - 2)
|
||||
+ return EMSGSIZE;
|
||||
+
|
||||
+ outbuf[(*i)++] = type;
|
||||
+ outbuf[(*i)++] = attrlen + 2;
|
||||
+ memcpy(outbuf + *i, buffer, attrlen);
|
||||
+ *i += attrlen;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
krb5_error_code
|
||||
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
- const unsigned char *auth,
|
||||
+ const uint8_t *auth, krb5_boolean add_msgauth,
|
||||
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||
krb5_boolean *is_fips)
|
||||
{
|
||||
- unsigned char buffer[MAX_ATTRSIZE];
|
||||
krb5_error_code retval;
|
||||
- size_t i = 0, attrlen;
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const uint8_t zeroes[MD5_DIGEST_SIZE] = { 0 };
|
||||
+ krb5_data zerodata;
|
||||
+ size_t i = 0;
|
||||
attr *a;
|
||||
|
||||
if (set == NULL) {
|
||||
@@ -180,19 +209,21 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||
- retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
|
||||
- buffer, &attrlen, is_fips);
|
||||
- if (retval != 0)
|
||||
+ if (add_msgauth) {
|
||||
+ /* Encode Message-Authenticator as the first attribute, per
|
||||
+ * draft-ietf-radext-deprecating-radius-03 section 5.2. */
|
||||
+ zerodata = make_data((uint8_t *)zeroes, MD5_DIGEST_SIZE);
|
||||
+ retval = append_attr(set->ctx, secret, auth, msgauth_type, &zerodata,
|
||||
+ outbuf, &i, is_fips);
|
||||
+ if (retval)
|
||||
return retval;
|
||||
+ }
|
||||
|
||||
- if (i + attrlen + 2 > MAX_ATTRSETSIZE)
|
||||
- return EMSGSIZE;
|
||||
-
|
||||
- outbuf[i++] = a->type;
|
||||
- outbuf[i++] = attrlen + 2;
|
||||
- memcpy(&outbuf[i], buffer, attrlen);
|
||||
- i += attrlen;
|
||||
+ K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||
+ retval = append_attr(set->ctx, secret, auth, a->type, &a->attr,
|
||||
+ outbuf, &i, is_fips);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
*outlen = i;
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index a17b6f39b1..ca66f3ec68 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -49,6 +49,8 @@
|
||||
#define UCHAR_MAX 255
|
||||
#endif
|
||||
|
||||
+#define MD5_DIGEST_SIZE 16
|
||||
+
|
||||
/* RFC 2865 */
|
||||
#define MAX_ATTRSIZE (UCHAR_MAX - 2)
|
||||
#define MAX_ATTRSETSIZE (KRAD_PACKET_SIZE_MAX - 20)
|
||||
@@ -79,10 +81,11 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||
krad_attr type, const krb5_data *in,
|
||||
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||
|
||||
-/* Encode the attributes into the buffer. */
|
||||
+/* Encode set into outbuf. If add_msgauth is true, include a zeroed
|
||||
+ * Message-Authenticator as the first attribute. */
|
||||
krb5_error_code
|
||||
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
- const unsigned char *auth,
|
||||
+ const uint8_t *auth, krb5_boolean add_msgauth,
|
||||
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||
krb5_boolean *is_fips);
|
||||
|
||||
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||
index c5446b890c..3c1a4d507e 100644
|
||||
--- a/src/lib/krad/packet.c
|
||||
+++ b/src/lib/krad/packet.c
|
||||
@@ -36,6 +36,7 @@
|
||||
typedef unsigned char uchar;
|
||||
|
||||
/* RFC 2865 */
|
||||
+#define MSGAUTH_SIZE (2 + MD5_DIGEST_SIZE)
|
||||
#define OFFSET_CODE 0
|
||||
#define OFFSET_ID 1
|
||||
#define OFFSET_LENGTH 2
|
||||
@@ -222,6 +223,106 @@ packet_set_attrset(krb5_context ctx, const char *secret, krad_packet *pkt)
|
||||
return kr_attrset_decode(ctx, &tmp, secret, pkt_auth(pkt), &pkt->attrset);
|
||||
}
|
||||
|
||||
+/* Determine if a packet requires a Message-Authenticator attribute. */
|
||||
+static inline krb5_boolean
|
||||
+requires_msgauth(const char *secret, krad_code code)
|
||||
+{
|
||||
+ /* If no secret is provided, assume that the transport is a UNIX socket.
|
||||
+ * Message-Authenticator is required only on UDP and TCP connections. */
|
||||
+ if (*secret == '\0')
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /*
|
||||
+ * Per draft-ietf-radext-deprecating-radius-03 sections 5.2.1 and 5.2.4,
|
||||
+ * Message-Authenticator is required in Access-Request packets and all
|
||||
+ * potential responses when UDP or TCP transport is used.
|
||||
+ */
|
||||
+ return code == krad_code_name2num("Access-Request") ||
|
||||
+ code == krad_code_name2num("Access-Reject") ||
|
||||
+ code == krad_code_name2num("Access-Accept") ||
|
||||
+ code == krad_code_name2num("Access-Challenge");
|
||||
+}
|
||||
+
|
||||
+/* Check if the packet has a Message-Authenticator attribute. */
|
||||
+static inline krb5_boolean
|
||||
+has_pkt_msgauth(const krad_packet *pkt)
|
||||
+{
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+
|
||||
+ return krad_attrset_get(pkt->attrset, msgauth_type, 0) != NULL;
|
||||
+}
|
||||
+
|
||||
+/* Return the beginning of the Message-Authenticator attribute in pkt, or NULL
|
||||
+ * if no such attribute is present. */
|
||||
+static const uint8_t *
|
||||
+lookup_msgauth_addr(const krad_packet *pkt)
|
||||
+{
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ size_t i;
|
||||
+ uint8_t *p;
|
||||
+
|
||||
+ i = OFFSET_ATTR;
|
||||
+ while (i + 2 < pkt->pkt.length) {
|
||||
+ p = (uint8_t *)offset(&pkt->pkt, i);
|
||||
+ if (msgauth_type == *p)
|
||||
+ return p;
|
||||
+ i += p[1];
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Calculate the message authenticator MAC for pkt as specified in RFC 2869
|
||||
+ * section 5.14, placing the result in mac_out. Use the provided authenticator
|
||||
+ * auth, which may be from pkt or from a corresponding request.
|
||||
+ */
|
||||
+static krb5_error_code
|
||||
+calculate_mac(const char *secret, const krad_packet *pkt,
|
||||
+ const uint8_t auth[AUTH_FIELD_SIZE],
|
||||
+ uint8_t mac_out[MD5_DIGEST_SIZE])
|
||||
+{
|
||||
+ uint8_t zeroed_msgauth[MSGAUTH_SIZE];
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const uint8_t *msgauth_attr, *msgauth_end, *pkt_end;
|
||||
+ krb5_crypto_iov input[5];
|
||||
+ krb5_data ksecr, mac;
|
||||
+
|
||||
+ msgauth_attr = lookup_msgauth_addr(pkt);
|
||||
+ if (msgauth_attr == NULL)
|
||||
+ return EINVAL;
|
||||
+ msgauth_end = msgauth_attr + MSGAUTH_SIZE;
|
||||
+ pkt_end = (const uint8_t *)pkt->pkt.data + pkt->pkt.length;
|
||||
+
|
||||
+ /* Read code, id, and length from the packet. */
|
||||
+ input[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[0].data = make_data(pkt->pkt.data, OFFSET_AUTH);
|
||||
+
|
||||
+ /* Read the provided authenticator. */
|
||||
+ input[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[1].data = make_data((uint8_t *)auth, AUTH_FIELD_SIZE);
|
||||
+
|
||||
+ /* Read any attributes before Message-Authenticator. */
|
||||
+ input[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[2].data = make_data(pkt_attr(pkt), msgauth_attr - pkt_attr(pkt));
|
||||
+
|
||||
+ /* Read Message-Authenticator with the data bytes all set to zero, per RFC
|
||||
+ * 2869 section 5.14. */
|
||||
+ zeroed_msgauth[0] = msgauth_type;
|
||||
+ zeroed_msgauth[1] = MSGAUTH_SIZE;
|
||||
+ memset(zeroed_msgauth + 2, 0, MD5_DIGEST_SIZE);
|
||||
+ input[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[3].data = make_data(zeroed_msgauth, MSGAUTH_SIZE);
|
||||
+
|
||||
+ /* Read any attributes after Message-Authenticator. */
|
||||
+ input[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[4].data = make_data((uint8_t *)msgauth_end, pkt_end - msgauth_end);
|
||||
+
|
||||
+ mac = make_data(mac_out, MD5_DIGEST_SIZE);
|
||||
+ ksecr = string2data((char *)secret);
|
||||
+ return k5_hmac_md5(&ksecr, input, 5, &mac);
|
||||
+}
|
||||
+
|
||||
ssize_t
|
||||
krad_packet_bytes_needed(const krb5_data *buffer)
|
||||
{
|
||||
@@ -255,6 +356,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
krad_packet *pkt;
|
||||
uchar id;
|
||||
size_t attrset_len;
|
||||
+ krb5_boolean msgauth_required;
|
||||
|
||||
pkt = packet_new();
|
||||
if (pkt == NULL) {
|
||||
@@ -274,9 +376,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
+ /* Determine if Message-Authenticator is required. */
|
||||
+ msgauth_required = (*secret != '\0' &&
|
||||
+ code == krad_code_name2num("Access-Request"));
|
||||
+
|
||||
/* Encode the attributes. */
|
||||
- retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
|
||||
- &attrset_len, &pkt->is_fips);
|
||||
+ retval = kr_attrset_encode(set, secret, pkt_auth(pkt), msgauth_required,
|
||||
+ pkt_attr(pkt), &attrset_len, &pkt->is_fips);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
@@ -285,6 +391,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
pkt_code_set(pkt, code);
|
||||
pkt_len_set(pkt, pkt->pkt.length);
|
||||
|
||||
+ if (msgauth_required) {
|
||||
+ /* Calculate and set the Message-Authenticator MAC. */
|
||||
+ retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
|
||||
+ if (retval != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Copy the attrset for future use. */
|
||||
retval = packet_set_attrset(ctx, secret, pkt);
|
||||
if (retval != 0)
|
||||
@@ -307,14 +420,19 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
krb5_error_code retval;
|
||||
krad_packet *pkt;
|
||||
size_t attrset_len;
|
||||
+ krb5_boolean msgauth_required;
|
||||
|
||||
pkt = packet_new();
|
||||
if (pkt == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
+ /* Determine if Message-Authenticator is required. */
|
||||
+ msgauth_required = requires_msgauth(secret, code);
|
||||
+
|
||||
/* Encode the attributes. */
|
||||
- retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
|
||||
- &attrset_len, &pkt->is_fips);
|
||||
+ retval = kr_attrset_encode(set, secret, pkt_auth(request),
|
||||
+ msgauth_required, pkt_attr(pkt), &attrset_len,
|
||||
+ &pkt->is_fips);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
@@ -330,6 +448,18 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
+ if (msgauth_required) {
|
||||
+ /*
|
||||
+ * Calculate and replace the Message-Authenticator MAC. Per RFC 2869
|
||||
+ * section 5.14, use the authenticator from the request, not from the
|
||||
+ * response.
|
||||
+ */
|
||||
+ retval = calculate_mac(secret, pkt, pkt_auth(request),
|
||||
+ pkt_attr(pkt) + 2);
|
||||
+ if (retval != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Copy the attrset for future use. */
|
||||
retval = packet_set_attrset(ctx, secret, pkt);
|
||||
if (retval != 0)
|
||||
@@ -343,6 +473,34 @@ error:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/* Verify the Message-Authenticator value in pkt, using the provided
|
||||
+ * authenticator (which may be from pkt or from a corresponding request). */
|
||||
+static krb5_error_code
|
||||
+verify_msgauth(const char *secret, const krad_packet *pkt,
|
||||
+ const uint8_t auth[AUTH_FIELD_SIZE])
|
||||
+{
|
||||
+ uint8_t mac[MD5_DIGEST_SIZE];
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const krb5_data *msgauth;
|
||||
+ krb5_error_code retval;
|
||||
+
|
||||
+ msgauth = krad_packet_get_attr(pkt, msgauth_type, 0);
|
||||
+ if (msgauth == NULL)
|
||||
+ return ENODATA;
|
||||
+
|
||||
+ retval = calculate_mac(secret, pkt, auth, mac);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ if (msgauth->length != MD5_DIGEST_SIZE)
|
||||
+ return EMSGSIZE;
|
||||
+
|
||||
+ if (k5_bcmp(mac, msgauth->data, MD5_DIGEST_SIZE) != 0)
|
||||
+ return EBADMSG;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Decode a packet. */
|
||||
static krb5_error_code
|
||||
decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer,
|
||||
@@ -394,21 +552,35 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
|
||||
krad_packet **reqpkt)
|
||||
{
|
||||
const krad_packet *tmp = NULL;
|
||||
+ krad_packet *req;
|
||||
krb5_error_code retval;
|
||||
|
||||
- retval = decode_packet(ctx, secret, buffer, reqpkt);
|
||||
- if (cb != NULL && retval == 0) {
|
||||
+ retval = decode_packet(ctx, secret, buffer, &req);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ /* Verify Message-Authenticator if present. */
|
||||
+ if (has_pkt_msgauth(req)) {
|
||||
+ retval = verify_msgauth(secret, req, pkt_auth(req));
|
||||
+ if (retval) {
|
||||
+ krad_packet_free(req);
|
||||
+ return retval;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (cb != NULL) {
|
||||
for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) {
|
||||
if (pkt_id_get(*reqpkt) == pkt_id_get(tmp))
|
||||
break;
|
||||
}
|
||||
- }
|
||||
|
||||
- if (cb != NULL && (retval != 0 || tmp != NULL))
|
||||
- (*cb)(data, TRUE);
|
||||
+ if (tmp != NULL)
|
||||
+ (*cb)(data, TRUE);
|
||||
+ }
|
||||
|
||||
+ *reqpkt = req;
|
||||
*duppkt = tmp;
|
||||
- return retval;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -435,9 +607,17 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
|
||||
break;
|
||||
}
|
||||
|
||||
- /* If the authenticator matches, then the response is valid. */
|
||||
- if (memcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) == 0)
|
||||
- break;
|
||||
+ /* Verify the response authenticator. */
|
||||
+ if (k5_bcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Verify Message-Authenticator if present. */
|
||||
+ if (has_pkt_msgauth(*rsppkt)) {
|
||||
+ if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
|
||||
index 4cdb8b7d8e..f9c66509bd 100644
|
||||
--- a/src/lib/krad/t_attrset.c
|
||||
+++ b/src/lib/krad/t_attrset.c
|
||||
@@ -63,7 +63,7 @@ main(void)
|
||||
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
|
||||
|
||||
/* Encode attrset. */
|
||||
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
|
||||
+ noerror(kr_attrset_encode(set, "foo", auth, FALSE, buffer, &encode_len,
|
||||
&is_fips));
|
||||
krad_attrset_free(set);
|
||||
|
||||
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
|
||||
index 4a3de079c7..647d4894eb 100755
|
||||
--- a/src/lib/krad/t_daemon.py
|
||||
+++ b/src/lib/krad/t_daemon.py
|
||||
@@ -40,6 +40,7 @@ DICTIONARY = """
|
||||
ATTRIBUTE\tUser-Name\t1\tstring
|
||||
ATTRIBUTE\tUser-Password\t2\toctets
|
||||
ATTRIBUTE\tNAS-Identifier\t32\tstring
|
||||
+ATTRIBUTE\tMessage-Authenticator\t80\toctets
|
||||
"""
|
||||
|
||||
class TestServer(server.Server):
|
||||
@@ -52,7 +53,7 @@ class TestServer(server.Server):
|
||||
if key == "User-Password":
|
||||
passwd = [pkt.PwDecrypt(x) for x in pkt[key]]
|
||||
|
||||
- reply = self.CreateReplyPacket(pkt)
|
||||
+ reply = self.CreateReplyPacket(pkt, message_authenticator=True)
|
||||
if passwd == ['accept']:
|
||||
reply.code = packet.AccessAccept
|
||||
else:
|
||||
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
|
||||
index c22489144f..104b6507a2 100644
|
||||
--- a/src/lib/krad/t_packet.c
|
||||
+++ b/src/lib/krad/t_packet.c
|
||||
@@ -172,6 +172,9 @@ main(int argc, const char **argv)
|
||||
krb5_data username, password;
|
||||
krb5_boolean auth = FALSE;
|
||||
krb5_context ctx;
|
||||
+ const krad_packet *dupreq;
|
||||
+ const krb5_data *encpkt;
|
||||
+ krad_packet *decreq;
|
||||
|
||||
username = string2data("testUser");
|
||||
|
||||
@@ -184,9 +187,17 @@ main(int argc, const char **argv)
|
||||
|
||||
password = string2data("accept");
|
||||
noerror(make_packet(ctx, &username, &password, &packets[ACCEPT_PACKET]));
|
||||
+ encpkt = krad_packet_encode(packets[ACCEPT_PACKET]);
|
||||
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
|
||||
+ &dupreq, &decreq));
|
||||
+ krad_packet_free(decreq);
|
||||
|
||||
password = string2data("reject");
|
||||
noerror(make_packet(ctx, &username, &password, &packets[REJECT_PACKET]));
|
||||
+ encpkt = krad_packet_encode(packets[REJECT_PACKET]);
|
||||
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
|
||||
+ &dupreq, &decreq));
|
||||
+ krad_packet_free(decreq);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
|
||||
index c3b820a411..dd5cdc5c26 100755
|
||||
--- a/src/tests/t_otp.py
|
||||
+++ b/src/tests/t_otp.py
|
||||
@@ -49,6 +49,7 @@ ATTRIBUTE User-Name 1 string
|
||||
ATTRIBUTE User-Password 2 octets
|
||||
ATTRIBUTE Service-Type 6 integer
|
||||
ATTRIBUTE NAS-Identifier 32 string
|
||||
+ATTRIBUTE Message-Authenticator 80 octets
|
||||
'''
|
||||
|
||||
class RadiusDaemon(Process):
|
||||
@@ -97,6 +98,8 @@ class RadiusDaemon(Process):
|
||||
reply.code = packet.AccessReject
|
||||
replyq['reply'] = False
|
||||
|
||||
+ reply.add_message_authenticator()
|
||||
+
|
||||
outq.put(replyq)
|
||||
if addr is None:
|
||||
sock.send(reply.ReplyPacket())
|
||||
--
|
||||
2.46.0
|
||||
|
@ -1,16 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEExEk8tzn0qJ+YUsvCDLoIV1+Dct8FAmSsc/kACgkQDLoIV1+D
|
||||
ct+wPxAArlkJs5WpFIm2JDJXGF82BNw/FEhg+OkWcPHeLMWJF8qO0AxVp8Yq4g1g
|
||||
qFpTABwY8V2tfr84XQJ6rw7Qq93NjRjFHr1z1tDmCceLisXof6Tu7/RKjHwNmJt8
|
||||
M3srmsXPlmx/7cXuaYIljJfftun3D/iuEaydWluGb1DZicaU/OsofGhKE8/YEZrN
|
||||
H0XdIC45raG4O9t6CGjQRcAIv5Z4afCtXH4aaEmLg6E2+aTUyx+czu7nBASCaTyv
|
||||
s4df8fhbVpdBi6iA6BQJC296Rc1gyDnuxnjyCH8Rj2gTuiI4Oa2dxRPGT3mjksz3
|
||||
OheYcXK9XGCtUbG22zrxqUuHDA3jF6KKmsVSXnbygB6XSS/c0bqmeDRTQGPksWH6
|
||||
RJbmlKG9PQ0BavlXRa7Nupaa7f0jblFiduScYujRsyWxi/8YkckedugYyuww59gV
|
||||
piUwGGRDWldy+JIAYtvzirsfe6Oum0/SKY5wYXyKv0flM95pbfBEw+TzRxmlCQ5J
|
||||
+i8L9Frr4gTmT576GHB6WzBlOEPf6mRc8jg0DyyUOoDHXyj4MCyJGEJxvcyVV1WX
|
||||
tJlu0uH1f8pMZx4IQ279PsNFimO/NsdSTefqiVGXA7FWK1EPLc+l9ZBcrLi9KEmJ
|
||||
7TfVq9cAg6+m2tql+gjAQrfXHUU1mNdPLFMnShYlqHjTle4cQKE=
|
||||
=AIvQ
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,16 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEExEk8tzn0qJ+YUsvCDLoIV1+Dct8FAmZ8eHkACgkQDLoIV1+D
|
||||
ct//gw//bmvy6zXbKL6epNaExVgRdqzfQWm6WqeyGNxg59BQyJwsRsArsQRbSTZl
|
||||
uUExbV4HDTI/SemnYT8MfNOUtGZBCcAMYUr79Zmwi9S2pc30ZHIGcOf5E7HvIj6y
|
||||
ZZUvddoxWvxpruCuJHb9dP4ZUPE0iU2rJnLsXR/H4E574WlrWBjXu3gimLen7+yg
|
||||
aCLxIvw6lk4f/X8l+aqbK+haWHwMnca+kWSPbmL2iblHVqmoJVEmWhy7/9WjiT5S
|
||||
5HhDJIObO2qn1pbE1ZTQqfGOfFgOUVxTl2myMxX1RXEDVFzdLDdnoUJRt4o4GG27
|
||||
Y0WfLtmN6NisVF91dkl2+F7js+xVI3m9uZnpeccKO2Uq6BQRrfOMWUAHVKMUJZjh
|
||||
h0GMeTzOhw7qGKitAiuhauyDMMTgMx78bC0DpLYtq24fp7BSvD0jNZnfjUXVCk8D
|
||||
al9cfxC5m843aKiJ01Of13PziZsTQFz/TUsOrcpx4h7+qY7nldrovkQBiyVbbtn4
|
||||
MncYq8d84G/0vsbJ/6ftJ6Y+OL20jyzfC5xgmKtK/y1D987aum2BSudISUCylOOt
|
||||
j5/KiTRe0rWUjBNtoCjrtw4xlSbygmjuiE/xtcow0CHXDtMjlo8PrDi8W+xccBv2
|
||||
zQ2B+e9ywkF4uC/M91s/bVSMkOtxv2JCoUUHOMF4ku5vzKSOhyk=
|
||||
=TH0A
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
export RPM_PACKAGE_NAME={{ name }}
|
||||
export RPM_PACKAGE_VERSION={{ version }}
|
||||
export RPM_PACKAGE_RELEASE={{ release }}
|
||||
export RPM_ARCH={{ arch }}
|
||||
export RPM_BUILD_NCPUS="$(getconf _NPROCESSORS_ONLN)"
|
||||
|
||||
testdir="$(mktemp -d)"
|
||||
trap "rm -rf ${testdir}" EXIT
|
||||
|
||||
build_flags="$(eval "echo $(rpm --eval '%{_smp_mflags}')")"
|
||||
|
||||
mkdir "${testdir}/{{ name }}-tests"
|
||||
cp -rp /usr/share/{{ name }}-tests/{{ arch }} "${testdir}/{{ name }}-tests/"
|
||||
make -C "${testdir}/{{ name }}-tests/{{ arch }}/" $build_flags
|
||||
keyctl session - make -C "${testdir}/{{ name }}-tests/{{ arch }}/" check
|
Loading…
Reference in new issue