commit 9b6518a9cda31bcf32565219ba041e45a93d03d2 Author: CentOS Sources Date: Tue Nov 8 01:59:52 2022 -0500 import gssproxy-0.8.0-21.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7811b1a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/gssproxy-0.8.0.tar.gz diff --git a/.gssproxy.metadata b/.gssproxy.metadata new file mode 100644 index 0000000..4cb1476 --- /dev/null +++ b/.gssproxy.metadata @@ -0,0 +1 @@ +51f38bd9e0adf6018e4d3008bb06311c9cd12381 SOURCES/gssproxy-0.8.0.tar.gz diff --git a/SOURCES/Add-a-safety-timeout-to-epoll.patch b/SOURCES/Add-a-safety-timeout-to-epoll.patch new file mode 100644 index 0000000..d909965 --- /dev/null +++ b/SOURCES/Add-a-safety-timeout-to-epoll.patch @@ -0,0 +1,48 @@ +From b4b7e3fc0f2008967202f2453e9c33b378e7a000 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 6 Mar 2019 10:36:11 -0500 +Subject: [PATCH] Add a safety timeout to epoll + +Add a safety timeout just in case something goes wrong with the use of +timerfd. This way the process should't be stuck forever. + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: remove outdated comment] +Reviewed-by: Robbie Harwood +Merges: #241 +(cherry picked from commit d55be9fa2455fe52b6eb904ad427f22141ab3f26) +(cherry picked from commit a494f23b6d8d43fe1a824cd69c3dd93a18fc75a1) +--- + src/client/gpm_common.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c +index 36df5cc..808f350 100644 +--- a/src/client/gpm_common.c ++++ b/src/client/gpm_common.c +@@ -14,6 +14,7 @@ + #define FRAGMENT_BIT (1 << 31) + + #define RESPONSE_TIMEOUT 15 ++#define SAFETY_TIMEOUT RESPONSE_TIMEOUT * 10 * 1000 + #define MAX_TIMEOUT_RETRY 3 + + struct gpm_ctx { +@@ -291,7 +292,7 @@ static int gpm_epoll_wait(struct gpm_ctx *gpmctx, uint32_t event_flags) + } + + do { +- epoll_ret = epoll_wait(gpmctx->epollfd, events, 2, -1); ++ epoll_ret = epoll_wait(gpmctx->epollfd, events, 2, SAFETY_TIMEOUT); + } while (epoll_ret < 0 && errno == EINTR); + + if (epoll_ret < 0) { +@@ -299,8 +300,6 @@ static int gpm_epoll_wait(struct gpm_ctx *gpmctx, uint32_t event_flags) + ret = errno; + gpm_epoll_close(gpmctx); + } else if (epoll_ret == 0) { +- /* Shouldn't happen as timeout == -1; treat it like a timeout +- * occurred. */ + ret = ETIMEDOUT; + gpm_epoll_close(gpmctx); + } else if (epoll_ret == 1 && events[0].data.fd == gpmctx->timerfd) { diff --git a/SOURCES/Add-an-option-for-minimum-lifetime.patch b/SOURCES/Add-an-option-for-minimum-lifetime.patch new file mode 100644 index 0000000..c3c4e98 --- /dev/null +++ b/SOURCES/Add-an-option-for-minimum-lifetime.patch @@ -0,0 +1,140 @@ +From c6847f012b326a7e27dbe79d8df0faafdeb2dbef Mon Sep 17 00:00:00 2001 +From: Scott Mayhew +Date: Thu, 2 Sep 2021 12:44:27 -0400 +Subject: [PATCH] Add an option for minimum lifetime + +It's possible for gssproxy to return a cached credential with a very +small remaining lifetime. This can be problematic for NFS clients since +it requires a round trip to the NFS server to establish a GSS context. +Add a min_lifetime option that represents the lowest value that the +lifetime of the cached credential can be. Any lower than that, and +gp_check_cred() returns GSS_S_CREDENTIALS_EXPIRED, so that +gp_add_krb5_creds() is forced to try to obtain a new credential. + +Signed-off-by: Scott Mayhew +[antorres@redhat.com: adjusted lines number for man diff] +--- + examples/99-nfs-client.conf.in | 1 + + man/gssproxy.conf.5.xml | 15 +++++++++++++++ + src/gp_config.c | 12 ++++++++++++ + src/gp_creds.c | 12 ++++++++++-- + src/gp_proxy.h | 1 + + 5 files changed, 39 insertions(+), 2 deletions(-) + +diff --git a/examples/99-nfs-client.conf.in b/examples/99-nfs-client.conf.in +index c0985d9..9dd1891 100644 +--- a/examples/99-nfs-client.conf.in ++++ b/examples/99-nfs-client.conf.in +@@ -7,3 +7,4 @@ + allow_any_uid = yes + trusted = yes + euid = 0 ++ min_lifetime = 60 +diff --git a/man/gssproxy.conf.5.xml b/man/gssproxy.conf.5.xml +index de846b4..af6ca18 100644 +--- a/man/gssproxy.conf.5.xml ++++ b/man/gssproxy.conf.5.xml +@@ -348,6 +348,21 @@ + + + ++ ++ min_lifetime (integer) ++ ++ Minimum lifetime of a cached credential, in seconds. ++ If non-zero, when gssproxy is deciding whether to use ++ a cached credential, it will compare the lifetime of the ++ cached credential to this value. If the lifetime of the ++ cached credential is lower, gssproxy will treat the cached ++ credential as expired and will attempt to obtain a new ++ credential. ++ ++ Default: min_lifetime = 15 ++ ++ ++ + + program (string) + +diff --git a/src/gp_config.c b/src/gp_config.c +index 4cda579..a0afa73 100644 +--- a/src/gp_config.c ++++ b/src/gp_config.c +@@ -32,6 +32,7 @@ struct gp_flag_def flag_names[] = { + + #define DEFAULT_FILTERED_FLAGS GSS_C_DELEG_FLAG + #define DEFAULT_ENFORCED_FLAGS 0 ++#define DEFAULT_MIN_LIFETIME 15 + + static void free_str_array(const char ***a, int *count) + { +@@ -538,6 +539,17 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx) + goto done; + } + } ++ ++ cfg->svcs[n]->min_lifetime = DEFAULT_MIN_LIFETIME; ++ ret = gp_config_get_int(ctx, secname, "min_lifetime", &valnum); ++ if (ret == 0) { ++ if (valnum >= 0) { ++ cfg->svcs[n]->min_lifetime = valnum; ++ } else { ++ GPDEBUG("Invalid value '%d' for min_lifetime in [%s], ignoring.\n", ++ valnum, secname); ++ } ++ } + } + safefree(secname); + } +diff --git a/src/gp_creds.c b/src/gp_creds.c +index 92a6f13..843d1a3 100644 +--- a/src/gp_creds.c ++++ b/src/gp_creds.c +@@ -492,6 +492,7 @@ done: + } + + static uint32_t gp_check_cred(uint32_t *min, ++ struct gp_service *svc, + gss_cred_id_t in_cred, + gssx_name *desired_name, + gss_cred_usage_t cred_usage) +@@ -563,7 +564,14 @@ static uint32_t gp_check_cred(uint32_t *min, + if (lifetime == 0) { + ret_maj = GSS_S_CREDENTIALS_EXPIRED; + } else { +- ret_maj = GSS_S_COMPLETE; ++ if (svc->min_lifetime && lifetime < svc->min_lifetime) { ++ GPDEBUG("%s: lifetime (%u) less than min_lifetime (%u) " ++ "for service \"%s\" - returning\n", ++ __func__, lifetime, svc->min_lifetime, svc->name); ++ ret_maj = GSS_S_CREDENTIALS_EXPIRED; ++ } else { ++ ret_maj = GSS_S_COMPLETE; ++ } + } + + done: +@@ -622,7 +630,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min, + * function completely */ + + /* just check if it is a valid krb5 cred */ +- ret_maj = gp_check_cred(&ret_min, in_cred, desired_name, cred_usage); ++ ret_maj = gp_check_cred(&ret_min, gpcall->service, in_cred, desired_name, cred_usage); + if (ret_maj == GSS_S_COMPLETE) { + return GSS_S_COMPLETE; + } else if (ret_maj == GSS_S_CREDENTIALS_EXPIRED || +diff --git a/src/gp_proxy.h b/src/gp_proxy.h +index 3f58a43..f56d640 100644 +--- a/src/gp_proxy.h ++++ b/src/gp_proxy.h +@@ -45,6 +45,7 @@ struct gp_service { + gss_cred_usage_t cred_usage; + uint32_t filter_flags; + uint32_t enforce_flags; ++ uint32_t min_lifetime; + char *program; + + uint32_t mechs; +-- +2.31.1 + diff --git a/SOURCES/Always-choose-highest-requested-debug-level.patch b/SOURCES/Always-choose-highest-requested-debug-level.patch new file mode 100644 index 0000000..59acb8e --- /dev/null +++ b/SOURCES/Always-choose-highest-requested-debug-level.patch @@ -0,0 +1,107 @@ +From d284ec7dc9fe0a824b177873078aeb36a25b7878 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 11 Apr 2018 16:15:00 -0400 +Subject: [PATCH] Always choose highest requested debug level + +Allowing the CLI to lower the debug level specified in a config file +is dubious, and previously broken since we don't distinguish "default +value" from "explicitly requested value of 0" in popt. This resulted +in "Debug Enabled (level: 0)" even when the log level was not actually +0, which is confusing for users. + +Remove the gp_debug_args() function since it is no longer used. + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Merges: #229 +(cherry picked from commit 5a714768aec776dc875237dd729c85389932a688) +--- + src/gp_debug.c | 34 ++++++++-------------------------- + src/gp_debug.h | 3 +-- + src/gssproxy.c | 2 +- + 3 files changed, 10 insertions(+), 29 deletions(-) + +diff --git a/src/gp_debug.c b/src/gp_debug.c +index 4a141fc..a0f51f0 100644 +--- a/src/gp_debug.c ++++ b/src/gp_debug.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */ ++/* Copyright (C) 2011,2018 the GSS-PROXY contributors, see COPYING for license */ + + #include "config.h" + #include +@@ -7,35 +7,17 @@ + #include "gp_log.h" + + /* global debug switch */ +-int gp_debug; +- +-int gp_debug_args(int level) { +- static int args_level = 0; +- +- if (level != 0) { +- args_level = level; +- } +- return args_level; +-} ++int gp_debug = 0; + + void gp_debug_toggle(int level) + { +- static bool krb5_trace_set = false; ++ if (level <= gp_debug) ++ return; + +- /* Command line and environment options override config file */ +- gp_debug = gp_debug_args(0); +- if (gp_debug == 0) { +- gp_debug = level; +- } +- if (level >= 3) { +- if (!getenv("KRB5_TRACE")) { +- setenv("KRB5_TRACE", "/dev/stderr", 1); +- krb5_trace_set = true; +- } +- } else if (krb5_trace_set) { +- unsetenv("KRB5_TRACE"); +- krb5_trace_set = false; +- } ++ if (level >= 3 && !getenv("KRB5_TRACE")) ++ setenv("KRB5_TRACE", "/dev/stderr", 1); ++ ++ gp_debug = level; + GPDEBUG("Debug Enabled (level: %d)\n", level); + } + +diff --git a/src/gp_debug.h b/src/gp_debug.h +index 1c2f8a3..4932bfd 100644 +--- a/src/gp_debug.h ++++ b/src/gp_debug.h +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */ ++/* Copyright (C) 2011,2018 the GSS-PROXY contributors, see COPYING for license */ + + #ifndef _GP_DEBUG_H_ + #define _GP_DEBUG_H_ +@@ -10,7 +10,6 @@ + + extern int gp_debug; + +-int gp_debug_args(int level); + void gp_debug_toggle(int); + void gp_debug_printf(const char *format, ...); + void gp_debug_time_printf(const char *format, ...); +diff --git a/src/gssproxy.c b/src/gssproxy.c +index 6d36a5d..db6e89b 100644 +--- a/src/gssproxy.c ++++ b/src/gssproxy.c +@@ -208,7 +208,7 @@ int main(int argc, const char *argv[]) + + if (opt_debug || opt_debug_level > 0) { + if (opt_debug_level == 0) opt_debug_level = 1; +- gp_debug_args(opt_debug_level); ++ gp_debug_toggle(opt_debug_level); + } + + if (opt_daemon && opt_interactive) { diff --git a/SOURCES/Always-free-ciphertext-data-in-gp_encrypt_buffer.patch b/SOURCES/Always-free-ciphertext-data-in-gp_encrypt_buffer.patch new file mode 100644 index 0000000..979e277 --- /dev/null +++ b/SOURCES/Always-free-ciphertext-data-in-gp_encrypt_buffer.patch @@ -0,0 +1,32 @@ +From ccac7b766cd871aa0baeaebd697b386a47c28812 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 15:35:40 -0400 +Subject: [PATCH] Always free ciphertext data in gp_encrypt_buffer + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: rewrote commit message] +Reviewed-by: Robbie Harwood +(cherry picked from commit fe9e3c29caab90daf19028fb31ff28622d8708a9) +(cherry picked from commit d9a37354c9a040b151fbd737b84b7cacb315ec9d) +--- + src/gp_export.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/gp_export.c b/src/gp_export.c +index a5681c0..fb2f81b 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -308,10 +308,9 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + ret = gp_conv_octet_string(enc_handle.ciphertext.length, + enc_handle.ciphertext.data, + out); +- if (ret) { +- free(enc_handle.ciphertext.data); +- goto done; +- } ++ /* the conversion function copies the data, so free our copy ++ * unconditionally, or we leak */ ++ free(enc_handle.ciphertext.data); + + done: + free(padded); diff --git a/SOURCES/Always-initialize-out-cred-in-gp_import_gssx_cred.patch b/SOURCES/Always-initialize-out-cred-in-gp_import_gssx_cred.patch new file mode 100644 index 0000000..b1387f3 --- /dev/null +++ b/SOURCES/Always-initialize-out-cred-in-gp_import_gssx_cred.patch @@ -0,0 +1,34 @@ +From 8f787b66bc23b8317d95c6cf64fe6e0e6409f869 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 15 Apr 2019 19:54:17 -0400 +Subject: [PATCH] Always initialize out cred in gp_import_gssx_cred() + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Merges: #244 +(cherry picked from commit 5697dfd94345c945f93070c40b9d4480f3d3d7ea) +--- + src/gp_export.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/gp_export.c b/src/gp_export.c +index 5e8e160..403e339 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -449,6 +449,8 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall, + uint32_t ret_min = 0; + int ret; + ++ *out = GSS_C_NO_CREDENTIAL; ++ + handle = gp_service_get_creds_handle(gpcall->service); + if (!handle) { + ret_maj = GSS_S_FAILURE; +@@ -470,7 +472,6 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall, + if (ret) { + /* Allow for re-issuance of the keytab. */ + GPDEBUG("Stored ccache failed to decrypt; treating as empty\n"); +- *out = GSS_C_NO_CREDENTIAL; + goto done; + } + diff --git a/SOURCES/Always-use-the-encype-we-selected.patch b/SOURCES/Always-use-the-encype-we-selected.patch new file mode 100644 index 0000000..afbf251 --- /dev/null +++ b/SOURCES/Always-use-the-encype-we-selected.patch @@ -0,0 +1,43 @@ +From 64bf7f099fe52a214794486d16e3383ff25e8682 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Tue, 27 Feb 2018 11:59:25 -0500 +Subject: [PATCH] Always use the encype we selected + +The enctype is selected from the keytab or from the fallback code. +Either way make sure to use the enctype stored in the key block. + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +Merges: #226 +(cherry picked from commit d73c96d658059ce64ecd41ff2924071d86f2b54f) +--- + src/gp_export.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/gp_export.c b/src/gp_export.c +index c9f5fd4..5e8e160 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -168,11 +168,10 @@ uint32_t gp_init_creds_handle(uint32_t *min, const char *svc_name, + GP_CREDS_HANDLE_KEY_ENCTYPE, 0, + &handle->key); + if (ret == 0) { +- ret = krb5_c_make_random_key(handle->context, +- GP_CREDS_HANDLE_KEY_ENCTYPE, ++ ret = krb5_c_make_random_key(handle->context, handle->key->enctype, + handle->key); + GPDEBUG("Service: %s, Enckey: [ephemeral], Enctype: %d\n", +- svc_name, GP_CREDS_HANDLE_KEY_ENCTYPE); ++ svc_name, handle->key->enctype); + } + if (ret) { + ret_min = ret; +@@ -254,7 +253,7 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key, + + memset(&enc_handle, '\0', sizeof(krb5_enc_data)); + +- enc_handle.enctype = GP_CREDS_HANDLE_KEY_ENCTYPE; ++ enc_handle.enctype = key->enctype; + enc_handle.ciphertext.data = in->octet_string_val; + enc_handle.ciphertext.length = in->octet_string_len; + diff --git a/SOURCES/Avoid-leak-of-special-mechs-in-gss_mech_interposer.patch b/SOURCES/Avoid-leak-of-special-mechs-in-gss_mech_interposer.patch new file mode 100644 index 0000000..5baa122 --- /dev/null +++ b/SOURCES/Avoid-leak-of-special-mechs-in-gss_mech_interposer.patch @@ -0,0 +1,34 @@ +From 87a1335a9618788f5d82de08ed0587feebe92c74 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 31 Jul 2020 13:23:30 -0400 +Subject: [PATCH] Avoid leak of special mechs in gss_mech_interposer() + +Signed-off-by: Robbie Harwood +(cherry picked from commit dc405df92173cceac2cafc09a70b1724bb2b97c8) +(cherry picked from commit 4b9e5f00d36d9b5c1f80835a989fa8865c045ff3) +--- + src/mechglue/gss_plugin.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/mechglue/gss_plugin.c b/src/mechglue/gss_plugin.c +index d735537..8b799cf 100644 +--- a/src/mechglue/gss_plugin.c ++++ b/src/mechglue/gss_plugin.c +@@ -76,6 +76,7 @@ gss_OID_set gss_mech_interposer(gss_OID mech_type) + gss_OID_set interposed_mechs; + OM_uint32 maj, min; + char *envval; ++ gss_OID_set special_mechs; + + /* avoid looping in the gssproxy daemon by avoiding to interpose + * any mechanism */ +@@ -118,7 +119,8 @@ gss_OID_set gss_mech_interposer(gss_OID mech_type) + } + + /* while there also initiaize special_mechs */ +- (void)gpp_special_available_mechs(interposed_mechs); ++ special_mechs = gpp_special_available_mechs(interposed_mechs); ++ (void)gss_release_oid_set(&min, &special_mechs); + + done: + if (maj != 0) { diff --git a/SOURCES/Avoid-uninitialized-free-when-allocating-buffers.patch b/SOURCES/Avoid-uninitialized-free-when-allocating-buffers.patch new file mode 100644 index 0000000..aaf5478 --- /dev/null +++ b/SOURCES/Avoid-uninitialized-free-when-allocating-buffers.patch @@ -0,0 +1,39 @@ +From 160f7a7c66e7e3d249de853cd5a1ebe0becd9fe1 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 1 May 2019 11:27:13 -0400 +Subject: [PATCH] Avoid uninitialized free when allocating buffers + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Resolves: #248 +(cherry picked from commit eafa3c9272c95646400123f8e4d6fb50cf36d36c) +--- + src/gp_export.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/gp_export.c b/src/gp_export.c +index dbfddeb..a5681c0 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -300,6 +300,7 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + &data_in, + &enc_handle); + if (ret) { ++ free(enc_handle.ciphertext.data); + ret = EINVAL; + goto done; + } +@@ -308,12 +309,12 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + enc_handle.ciphertext.data, + out); + if (ret) { ++ free(enc_handle.ciphertext.data); + goto done; + } + + done: + free(padded); +- free(enc_handle.ciphertext.data); + return ret; + } + diff --git a/SOURCES/Avoid-unnecessary-allocation-in-gpm_inquire_mechs_fo.patch b/SOURCES/Avoid-unnecessary-allocation-in-gpm_inquire_mechs_fo.patch new file mode 100644 index 0000000..3f7d0f3 --- /dev/null +++ b/SOURCES/Avoid-unnecessary-allocation-in-gpm_inquire_mechs_fo.patch @@ -0,0 +1,57 @@ +From 167d9775dd88cc91f74393fa487f126d21c560c7 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 17:20:44 -0400 +Subject: [PATCH] Avoid unnecessary allocation in gpm_inquire_mechs_for_name() + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: clarified commit message] +Reviewed-by: Robbie Harwood +(cherry picked from commit c0561c078bc22b9523ac25f515ad85b735c26a92) +(cherry picked from commit ebd66fbf42887220a0ff38cfea03a7b20fa4da17) +--- + src/client/gpm_indicate_mechs.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/src/client/gpm_indicate_mechs.c b/src/client/gpm_indicate_mechs.c +index 4041dcd..73fadf0 100644 +--- a/src/client/gpm_indicate_mechs.c ++++ b/src/client/gpm_indicate_mechs.c +@@ -390,7 +390,7 @@ OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, + uint32_t ret_min; + uint32_t ret_maj; + uint32_t discard; +- gss_OID name_type = GSS_C_NO_OID; ++ gss_OID_desc name_type; + int present; + + if (!minor_status) { +@@ -407,19 +407,14 @@ OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, + return GSS_S_FAILURE; + } + +- ret_min = gp_conv_gssx_to_oid_alloc(&input_name->name_type, &name_type); +- if (ret_min) { +- ret_maj = GSS_S_FAILURE; +- goto done; +- } +- + ret_maj = gss_create_empty_oid_set(&ret_min, mech_types); + if (ret_maj) { + goto done; + } + ++ gp_conv_gssx_to_oid(&input_name->name_type, &name_type); + for (unsigned i = 0; i < global_mechs.info_len; i++) { +- ret_maj = gss_test_oid_set_member(&ret_min, name_type, ++ ret_maj = gss_test_oid_set_member(&ret_min, &name_type, + global_mechs.info[i].name_types, + &present); + if (ret_maj) { +@@ -437,7 +432,6 @@ OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, + } + + done: +- gss_release_oid(&discard, &name_type); + if (ret_maj) { + gss_release_oid_set(&discard, mech_types); + *minor_status = ret_min; diff --git a/SOURCES/Change-the-way-we-handle-encrypted-buffers.patch b/SOURCES/Change-the-way-we-handle-encrypted-buffers.patch new file mode 100644 index 0000000..bfce327 --- /dev/null +++ b/SOURCES/Change-the-way-we-handle-encrypted-buffers.patch @@ -0,0 +1,193 @@ +From 51bba6bf325716534c509e0528d2ccfd0050d28c Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 17 Apr 2019 18:00:59 -0400 +Subject: [PATCH] Change the way we handle encrypted buffers + +The previous change has backwards incompatible behavior that may also +lead to buffer overruns. + +Because we have no easy way to indicate a format change and to maintain +backwards compatibility for the ciphers that were working (those that +added padding were hopelessly borken anyway) introduce code to simply +add padding that we can recognize and remove when we read back the token. + +On ciphers that do not add padding this is basically a no op and the +tokens will be identical to the ones we previously emitted. + +On ciphers that add padding we pad the plaintext so that we hit a block +boundary and cause no extra padding to be added by krb5_c_encrypt +itself. On decryption we check if padding bytes are appended to the +buffer and remove them. + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +Merges: #246 +(cherry picked from commit 839be8aa7e54e93819e8291b570e4c7cfe7e98f1) +--- + src/gp_export.c | 110 +++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 86 insertions(+), 24 deletions(-) + +diff --git a/src/gp_export.c b/src/gp_export.c +index aa0a8ec..dbfddeb 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -193,9 +193,15 @@ done: + return ret_maj; + } + +-/* We need to include a length in our payloads because krb5_c_decrypt() will +- * pad the contents for some enctypes, and gss_import_cred() doesn't like +- * having extra bytes on tokens. */ ++#define ENC_MIN_PAD_LEN 8 ++ ++/* We need to pad our payloads because krb5_c_decrypt() may pad the ++ * contents for some enctypes, and gss_import_cred() doesn't like ++ * having extra bytes on tokens. ++ * Explicit padding and depadding is used in order to maintain backwards ++ * compatibility over upgrades (and downgrades), it would have been ++ * better if we simply had a better formatting of the returned blob ++ * so we could simply change a "blob version" number */ + static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + size_t len, void *buf, octet_string *out) + { +@@ -203,8 +209,9 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + krb5_data data_in; + krb5_enc_data enc_handle; + size_t cipherlen; +- char *packed = NULL; +- uint32_t netlen; ++ size_t padcheck; ++ uint8_t pad = 0; ++ char *padded = NULL; + + if (len > (uint32_t)(-1)) { + /* Needs to fit in 4 bytes of payload, so... */ +@@ -212,28 +219,72 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + goto done; + } + +- packed = malloc(len); +- if (!packed) { +- ret = errno; ++ ret = krb5_c_encrypt_length(context, ++ key->enctype, ++ len, &cipherlen); ++ if (ret) { + goto done; + } + +- netlen = htonl(len); +- memcpy(packed, (uint8_t *)&netlen, 4); +- memcpy(packed + 4, buf, len); +- +- data_in.length = len + 4; +- data_in.data = packed; +- +- memset(&enc_handle, '\0', sizeof(krb5_enc_data)); +- ++ /* try again with len + 1 to see if padding is required */ + ret = krb5_c_encrypt_length(context, + key->enctype, +- data_in.length, +- &cipherlen); ++ len + 1, &padcheck); + if (ret) { + goto done; + } ++ if (padcheck == cipherlen) { ++ int i; ++ /* padding required */ ++ pad = ENC_MIN_PAD_LEN; ++ /* always add enough padding that it makes it extremely unlikley ++ * legitimate plaintext will be incorrectly depadded in the ++ * decrypt function */ ++ ret = krb5_c_encrypt_length(context, ++ key->enctype, ++ len + pad, &cipherlen); ++ if (ret) { ++ goto done; ++ } ++ /* we support only block sizes up to 16 bytes as this is the largest ++ * supported block size in krb ciphers for now */ ++ for (i = 0; i < 15; i++) { ++ /* find the point at which padcheck increases, that's when we ++ * cross a blocksize boundary internally and we can calculate ++ * the padding that will be used */ ++ ret = krb5_c_encrypt_length(context, ++ key->enctype, ++ len + pad + i + 1, &padcheck); ++ if (ret) { ++ goto done; ++ } ++ if (padcheck > cipherlen) { ++ pad += i; ++ break; ++ } ++ } ++ if (i > 15) { ++ ret = EINVAL; ++ goto done; ++ } ++ } ++ ++ if (pad != 0) { ++ padded = malloc(len + pad); ++ if (!padded) { ++ ret = errno; ++ goto done; ++ } ++ ++ memcpy(padded, buf, len); ++ memset(padded + len, pad, pad); ++ ++ data_in.length = len + pad; ++ data_in.data = padded; ++ } else { ++ data_in.length = len; ++ data_in.data = buf; ++ } + + enc_handle.ciphertext.length = cipherlen; + enc_handle.ciphertext.data = malloc(enc_handle.ciphertext.length); +@@ -261,7 +312,7 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + } + + done: +- free(packed); ++ free(padded); + free(enc_handle.ciphertext.data); + return ret; + } +@@ -273,7 +324,8 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key, + int ret; + krb5_data data_out; + krb5_enc_data enc_handle; +- uint32_t netlen; ++ uint8_t pad; ++ int i, j; + + memset(&enc_handle, '\0', sizeof(krb5_enc_data)); + +@@ -295,9 +347,19 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key, + } + + /* And handle the padding. */ +- memcpy(&netlen, buf, 4); +- *len = ntohl(netlen); +- memmove(buf, buf + 4, *len); ++ i = data_out.length - 1; ++ pad = data_out.data[i]; ++ if (pad >= ENC_MIN_PAD_LEN && pad < i) { ++ j = pad; ++ while (j > 0) { ++ j--; ++ if (pad != data_out.data[i - j]) break; ++ } ++ if (j == 0) { ++ data_out.length -= pad; ++ } ++ } ++ *len = data_out.length; + + return 0; + } diff --git a/SOURCES/Clarify-debug-and-debug_level-in-man-pages.patch b/SOURCES/Clarify-debug-and-debug_level-in-man-pages.patch new file mode 100644 index 0000000..1a5f224 --- /dev/null +++ b/SOURCES/Clarify-debug-and-debug_level-in-man-pages.patch @@ -0,0 +1,74 @@ +From d71d354f1020a7deac57f26cc7c2cafb3fa675a3 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 11 Apr 2018 16:01:21 -0400 +Subject: [PATCH] Clarify debug and debug_level in man pages + +In particular, add debug_level to gssproxy(5) since it was previously +accepted but not documented. + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Merges: #229 +(cherry picked from commit e0e96e46be03102903533a9816b4deefe1adfaf8) +--- + man/gssproxy.8.xml | 24 +++++++++++++++++++++++- + man/gssproxy.conf.5.xml | 5 ++++- + 2 files changed, 27 insertions(+), 2 deletions(-) + +diff --git a/man/gssproxy.8.xml b/man/gssproxy.8.xml +index 1df4b0d..21f7e6a 100644 +--- a/man/gssproxy.8.xml ++++ b/man/gssproxy.8.xml +@@ -118,13 +118,35 @@ + + + ++ + + + , + + + +- Turn on debugging. ++ Turn on debugging. This option is identical to ++ --debug-level=1. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Turn on debugging at the specified level. 0 ++ corresponds to no logging, while 1 turns on basic ++ debug logging. Level 2 increases verbosity, including ++ more detailed credential verification. ++ ++ ++ At level 3 and above, KRB5_TRACE output is logged. If ++ KRB5_TRACE was already set in the execution ++ environment, trace output is sent to its value ++ instead. + + + +diff --git a/man/gssproxy.conf.5.xml b/man/gssproxy.conf.5.xml +index de846b4..21c9653 100644 +--- a/man/gssproxy.conf.5.xml ++++ b/man/gssproxy.conf.5.xml +@@ -192,7 +192,10 @@ + + debug (boolean) + +- Enable debugging to syslog. ++ ++ Enable debugging to syslog. Setting to true is ++ identical to setting debug_level to 1. ++ + Default: debug = false + + diff --git a/SOURCES/Close-epoll-fd-within-the-lock.patch b/SOURCES/Close-epoll-fd-within-the-lock.patch new file mode 100644 index 0000000..129b316 --- /dev/null +++ b/SOURCES/Close-epoll-fd-within-the-lock.patch @@ -0,0 +1,159 @@ +From 01ff7b67bfaad9b4f6cebc7c46ac9b1d99671d4f Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 6 Mar 2019 10:31:13 -0500 +Subject: [PATCH] Close epoll fd within the lock + +A race condition may happen where we close the epoll socket, after +another thread grabbed the lock and is using epoll itself. +On some kernels this may cause epoll to not fire any event leaving the +thread stuck forever. + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: cleanup commit message, adjusted function ordering] +Reviewed-by: Robbie Harwood +Merges: #241 +(cherry picked from commit 0ccfd32f8ef16caf65698c5319dfa251d43433af) + +Squashed with: + +Reorder functions + +Keep related functions closer together like before + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +Resolves: #242 +(cherry picked from commit 6accc0afead574e11447447c949f2abcb1a34826) +(cherry picked from commit c33de0c213d570f370fd954869c2ad99901b2cf3) +--- + src/client/gpm_common.c | 96 ++++++++++++++++++++++------------------- + 1 file changed, 51 insertions(+), 45 deletions(-) + +diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c +index c254280..36df5cc 100644 +--- a/src/client/gpm_common.c ++++ b/src/client/gpm_common.c +@@ -139,43 +139,6 @@ static void gpm_close_socket(struct gpm_ctx *gpmctx) + gpmctx->fd = -1; + } + +-static int gpm_grab_sock(struct gpm_ctx *gpmctx) +-{ +- int ret; +- pid_t p; +- uid_t u; +- gid_t g; +- +- ret = pthread_mutex_lock(&gpmctx->lock); +- if (ret) { +- return ret; +- } +- +- /* Detect fork / setresuid and friends */ +- p = getpid(); +- u = geteuid(); +- g = getegid(); +- +- if (gpmctx->fd != -1 && +- (p != gpmctx->pid || u != gpmctx->uid || g != gpmctx->gid)) { +- gpm_close_socket(gpmctx); +- } +- +- if (gpmctx->fd == -1) { +- ret = gpm_open_socket(gpmctx); +- } +- +- if (ret) { +- pthread_mutex_unlock(&gpmctx->lock); +- } +- return ret; +-} +- +-static int gpm_release_sock(struct gpm_ctx *gpmctx) +-{ +- return pthread_mutex_unlock(&gpmctx->lock); +-} +- + static void gpm_timer_close(struct gpm_ctx *gpmctx) + { + if (gpmctx->timerfd < 0) { +@@ -253,6 +216,57 @@ static int gpm_epoll_setup(struct gpm_ctx *gpmctx) + return ret; + } + ++static int gpm_release_sock(struct gpm_ctx *gpmctx) ++{ ++ gpm_epoll_close(gpmctx); ++ gpm_timer_close(gpmctx); ++ return pthread_mutex_unlock(&gpmctx->lock); ++} ++ ++static int gpm_grab_sock(struct gpm_ctx *gpmctx) ++{ ++ int ret; ++ pid_t p; ++ uid_t u; ++ gid_t g; ++ ++ ret = pthread_mutex_lock(&gpmctx->lock); ++ if (ret) { ++ return ret; ++ } ++ ++ /* Detect fork / setresuid and friends */ ++ p = getpid(); ++ u = geteuid(); ++ g = getegid(); ++ ++ if (gpmctx->fd != -1 && ++ (p != gpmctx->pid || u != gpmctx->uid || g != gpmctx->gid)) { ++ gpm_close_socket(gpmctx); ++ } ++ ++ if (gpmctx->fd == -1) { ++ ret = gpm_open_socket(gpmctx); ++ if (ret) { ++ goto done; ++ } ++ } ++ ++ /* setup timer */ ++ ret = gpm_timer_setup(gpmctx, RESPONSE_TIMEOUT); ++ if (ret) { ++ goto done; ++ } ++ /* create epoll fd as well */ ++ ret = gpm_epoll_setup(gpmctx); ++ ++done: ++ if (ret) { ++ gpm_release_sock(gpmctx); ++ } ++ return ret; ++} ++ + static int gpm_epoll_wait(struct gpm_ctx *gpmctx, uint32_t event_flags) + { + int ret; +@@ -530,11 +544,6 @@ static int gpm_send_recv_loop(struct gpm_ctx *gpmctx, char *send_buffer, + int ret; + int retry_count; + +- /* setup timer */ +- ret = gpm_timer_setup(gpmctx, RESPONSE_TIMEOUT); +- if (ret) +- return ret; +- + for (retry_count = 0; retry_count < MAX_TIMEOUT_RETRY; retry_count++) { + /* send to proxy */ + ret = gpm_send_buffer(gpmctx, send_buffer, send_length); +@@ -761,9 +770,6 @@ int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res) + } + + done: +- gpm_timer_close(gpmctx); +- gpm_epoll_close(gpmctx); +- + if (sockgrab) { + gpm_release_sock(gpmctx); + } diff --git a/SOURCES/Correctly-size-loop-counter-in-gpp_special_available.patch b/SOURCES/Correctly-size-loop-counter-in-gpp_special_available.patch new file mode 100644 index 0000000..13e2b39 --- /dev/null +++ b/SOURCES/Correctly-size-loop-counter-in-gpp_special_available.patch @@ -0,0 +1,34 @@ +From 06cee2eb9ba3096cf5f1e532dae56132fd69c948 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 9 Apr 2020 12:00:04 -0400 +Subject: [PATCH] Correctly size loop counter in gpp_special_available_mechs() + +Fixes compiler warning for clang in CI. + +Signed-off-by: Robbie Harwood +(cherry picked from commit f9c0abb935125683972c9289db38dfe840f41b37) +--- + src/mechglue/gss_plugin.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/mechglue/gss_plugin.c b/src/mechglue/gss_plugin.c +index bf70d87..b9813dc 100644 +--- a/src/mechglue/gss_plugin.c ++++ b/src/mechglue/gss_plugin.c +@@ -306,7 +306,6 @@ gss_OID_set gpp_special_available_mechs(const gss_OID_set mechs) + struct gpp_special_oid_list *item; + gss_OID n; + uint32_t maj, min; +- int i; + + item = gpp_get_special_oids(); + +@@ -314,7 +313,7 @@ gss_OID_set gpp_special_available_mechs(const gss_OID_set mechs) + if (maj) { + return GSS_C_NO_OID_SET; + } +- for (i = 0; i < mechs->count; i++) { ++ for (size_t i = 0; i < mechs->count; i++) { + while (item) { + if (gpp_is_special_oid(&mechs->elements[i])) { + maj = gss_add_oid_set_member(&min, diff --git a/SOURCES/Delay-gssproxy-start-until-after-network.target.patch b/SOURCES/Delay-gssproxy-start-until-after-network.target.patch new file mode 100644 index 0000000..98b7bc6 --- /dev/null +++ b/SOURCES/Delay-gssproxy-start-until-after-network.target.patch @@ -0,0 +1,31 @@ +From ce630033523e7a6492dcfde82edae9e89818f84e Mon Sep 17 00:00:00 2001 +From: Pat Riehecky +Date: Fri, 27 Dec 2019 13:33:42 -0600 +Subject: [PATCH] Delay gssproxy start until after network.target + +Systemd docs are unclear in this regard, but it appears that +network.target must be ready before domain sockets can be created. + +Signed-off-by: Pat Riehecky +[rharwood@redhat.com: rewrote commit message] +Reviewed-by: Robbie Harwood +Merges: #252 +(cherry picked from commit 153b2ed51c5059abee507ddd240b5abc288d722c) +(cherry picked from commit 004ac514cd238122b25e5bc5b493dc8d4964ad75) +--- + systemd/gssproxy.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/systemd/gssproxy.service.in b/systemd/gssproxy.service.in +index ac37df6..50aafd7 100644 +--- a/systemd/gssproxy.service.in ++++ b/systemd/gssproxy.service.in +@@ -1,7 +1,7 @@ + [Unit] + Description=GSSAPI Proxy Daemon + # GSSPROXY will not be started until syslog is +-After=syslog.target ++After=syslog.target network.target + Before=rpc-gssd.service + + [Service] diff --git a/SOURCES/Document-config-file-non-merging.patch b/SOURCES/Document-config-file-non-merging.patch new file mode 100644 index 0000000..5fa05a4 --- /dev/null +++ b/SOURCES/Document-config-file-non-merging.patch @@ -0,0 +1,30 @@ +From ceeb1ff9226d21ff166d6737bab34b91fa6660fa Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 10 Jun 2020 15:50:36 -0400 +Subject: [PATCH] Document config file non-merging + +Merges: #4 +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +(cherry picked from commit a05b876badd52ba99d95c981f5f8b0e50de28c63) +(cherry picked from commit 2592d32c5c6d39f30dc0bfdb78b5c292ed0af2ae) +--- + man/gssproxy.conf.5.xml | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/man/gssproxy.conf.5.xml b/man/gssproxy.conf.5.xml +index 53cae3d..c8dd504 100644 +--- a/man/gssproxy.conf.5.xml ++++ b/man/gssproxy.conf.5.xml +@@ -37,7 +37,10 @@ + of the form "##-foo.conf" (that is, start with two numbers + followed by a dash, and end in ".conf"). Files not conforming to + this will be ignored unless specifically requested through command +- line parameters. ++ line parameters. Within a single file, any duplicate values or ++ sections will be merged. Across multiple files, duplicates will ++ generate a warning, and the first value encountered will take ++ precedence (i.e., there is no merging). + + + diff --git a/SOURCES/Expand-use-of-global-static-mechs-to-conform-to-SPI.patch b/SOURCES/Expand-use-of-global-static-mechs-to-conform-to-SPI.patch new file mode 100644 index 0000000..dd3fcf0 --- /dev/null +++ b/SOURCES/Expand-use-of-global-static-mechs-to-conform-to-SPI.patch @@ -0,0 +1,218 @@ +From 2ca80c193ffa13c89b9b63fb9cb690a9789d5842 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 11:34:45 -0400 +Subject: [PATCH] Expand use of global static mechs to conform to SPI + +GSSAPI requires some specific APIs to return "static" OIDs that the user +does not have to free. The krb5 mechglue in fact requires mechanisms to +also honor this or the mech oid will be irretrievably leaked in some +cases. + +To accomodate this, expand use of global mechs structure we already +allocate for the gss_inidicate_mechs case so we can return "static" OIDs +from calls like ISC and ASC. + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: commit message fixups] +Reviewed-by: Robbie Harwood +(cherry picked from commit a3f13b30ef3c90ff7344c3913f6e26e55b82451f) +(cherry picked from commit b7ccb627f4663ca949e3483486478add8f61cb27) +--- + src/client/gpm_accept_sec_context.c | 22 ++++++------------- + src/client/gpm_common.c | 1 - + src/client/gpm_indicate_mechs.c | 34 +++++++++++++++++++++++++++++ + src/client/gpm_init_sec_context.c | 19 +++++----------- + src/client/gssapi_gpm.h | 3 +++ + src/mechglue/gss_plugin.c | 5 +++++ + 6 files changed, 55 insertions(+), 29 deletions(-) + +diff --git a/src/client/gpm_accept_sec_context.c b/src/client/gpm_accept_sec_context.c +index ef5e79c..ab20b03 100644 +--- a/src/client/gpm_accept_sec_context.c ++++ b/src/client/gpm_accept_sec_context.c +@@ -21,7 +21,6 @@ OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, + gssx_res_accept_sec_context *res = &ures.accept_sec_context; + gssx_ctx *ctx = NULL; + gssx_name *name = NULL; +- gss_OID_desc *mech = NULL; + gss_buffer_t outbuf = NULL; + uint32_t ret_maj; + int ret; +@@ -70,15 +69,6 @@ OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, + goto done; + } + +- if (mech_type) { +- if (res->status.mech.octet_string_len) { +- ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech); +- if (ret) { +- goto done; +- } +- } +- } +- + ctx = res->context_handle; + /* we are stealing the delegated creds on success, so we do not want + * it to be freed by xdr_free */ +@@ -101,8 +91,14 @@ OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, + } + + if (mech_type) { +- *mech_type = mech; ++ gss_OID_desc mech; ++ gp_conv_gssx_to_oid(&res->status.mech, &mech); ++ ret = gpm_mech_to_static(&mech, mech_type); ++ if (ret) { ++ goto done; ++ } + } ++ + if (src_name) { + *src_name = name; + } +@@ -145,10 +141,6 @@ done: + xdr_free((xdrproc_t)xdr_gssx_name, (char *)name); + free(name); + } +- if (mech) { +- free(mech->elements); +- free(mech); +- } + if (outbuf) { + free(outbuf->value); + free(outbuf); +diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c +index d932ba2..02325c4 100644 +--- a/src/client/gpm_common.c ++++ b/src/client/gpm_common.c +@@ -795,4 +795,3 @@ void gpm_free_xdrs(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res) + xdr_free(gpm_xdr_set[proc].arg_fn, (char *)arg); + xdr_free(gpm_xdr_set[proc].res_fn, (char *)res); + } +- +diff --git a/src/client/gpm_indicate_mechs.c b/src/client/gpm_indicate_mechs.c +index b019a96..86c7de3 100644 +--- a/src/client/gpm_indicate_mechs.c ++++ b/src/client/gpm_indicate_mechs.c +@@ -300,6 +300,40 @@ static int gpmint_init_global_mechs(void) + return 0; + } + ++/* GSSAPI requires some APIs to return "static" mechs that callers do not need ++ * to free. So match a radom mech and return from our global "static" array */ ++int gpm_mech_to_static(gss_OID mech_type, gss_OID *mech_static) ++{ ++ int ret; ++ ++ ret = gpmint_init_global_mechs(); ++ if (ret) { ++ return ret; ++ } ++ ++ *mech_static = GSS_C_NO_OID; ++ for (size_t i = 0; i < global_mechs.mech_set->count; i++) { ++ if (gpm_equal_oids(&global_mechs.mech_set->elements[i], mech_type)) { ++ *mech_static = &global_mechs.mech_set->elements[i]; ++ return 0; ++ } ++ } ++ /* TODO: potentially in future add the mech to the list if missing */ ++ return ENOENT; ++} ++ ++bool gpm_mech_is_static(gss_OID mech_type) ++{ ++ if (global_mechs.mech_set) { ++ for (size_t i = 0; i < global_mechs.mech_set->count; i++) { ++ if (&global_mechs.mech_set->elements[i] == mech_type) { ++ return true; ++ } ++ } ++ } ++ return false; ++} ++ + OM_uint32 gpm_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set) + { + uint32_t ret_min; +diff --git a/src/client/gpm_init_sec_context.c b/src/client/gpm_init_sec_context.c +index bea2010..b84ff94 100644 +--- a/src/client/gpm_init_sec_context.c ++++ b/src/client/gpm_init_sec_context.c +@@ -43,7 +43,6 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, + gssx_arg_init_sec_context *arg = &uarg.init_sec_context; + gssx_res_init_sec_context *res = &ures.init_sec_context; + gssx_ctx *ctx = NULL; +- gss_OID_desc *mech = NULL; + gss_buffer_t outbuf = NULL; + uint32_t ret_maj = GSS_S_COMPLETE; + uint32_t ret_min = 0; +@@ -100,11 +99,12 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, + + /* return values */ + if (actual_mech_type) { +- if (res->status.mech.octet_string_len) { +- ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech); +- if (ret) { +- goto done; +- } ++ gss_OID_desc mech; ++ gp_conv_gssx_to_oid(&res->status.mech, &mech); ++ ret = gpm_mech_to_static(&mech, actual_mech_type); ++ if (ret) { ++ gpm_save_internal_status(ret, gp_strerror(ret)); ++ goto done; + } + } + +@@ -151,9 +151,6 @@ done: + gpm_free_xdrs(GSSX_INIT_SEC_CONTEXT, &uarg, &ures); + + if (ret_maj == GSS_S_COMPLETE || ret_maj == GSS_S_CONTINUE_NEEDED) { +- if (actual_mech_type) { +- *actual_mech_type = mech; +- } + if (outbuf) { + *output_token = *outbuf; + free(outbuf); +@@ -170,10 +167,6 @@ done: + free(ctx); + ctx = NULL; + } +- if (mech) { +- free(mech->elements); +- free(mech); +- } + if (outbuf) { + free(outbuf->value); + free(outbuf); +diff --git a/src/client/gssapi_gpm.h b/src/client/gssapi_gpm.h +index 61124e0..b7ba04b 100644 +--- a/src/client/gssapi_gpm.h ++++ b/src/client/gssapi_gpm.h +@@ -27,6 +27,9 @@ void gpm_display_status_init_once(void); + void gpm_save_status(gssx_status *status); + void gpm_save_internal_status(uint32_t err, char *err_str); + ++int gpm_mech_to_static(gss_OID mech_type, gss_OID *mech_static); ++bool gpm_mech_is_static(gss_OID mech_type); ++ + OM_uint32 gpm_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, +diff --git a/src/mechglue/gss_plugin.c b/src/mechglue/gss_plugin.c +index 8b799cf..bf70d87 100644 +--- a/src/mechglue/gss_plugin.c ++++ b/src/mechglue/gss_plugin.c +@@ -377,6 +377,11 @@ OM_uint32 gssi_internal_release_oid(OM_uint32 *minor_status, gss_OID *oid) + item = gpp_next_special_oids(item); + } + ++ if (gpm_mech_is_static(*oid)) { ++ *oid = GSS_C_NO_OID; ++ return GSS_S_COMPLETE; ++ } ++ + /* none matched, it's not ours */ + return GSS_S_CONTINUE_NEEDED; + } diff --git a/SOURCES/Fix-handling-of-selinux-context-when-NULL.patch b/SOURCES/Fix-handling-of-selinux-context-when-NULL.patch new file mode 100644 index 0000000..5fff0cb --- /dev/null +++ b/SOURCES/Fix-handling-of-selinux-context-when-NULL.patch @@ -0,0 +1,41 @@ +From 255188b5e3cfc3be5aebd037389bcf7da686a622 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Tue, 7 Apr 2020 08:56:53 -0400 +Subject: [PATCH] Fix handling of selinux context when NULL + +Fixes: #256 +Signed-off-by: Simo Sorce +Merges: #257 +Reviewed-by: Robbie Harwood +--- + src/gp_socket.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/gp_socket.c b/src/gp_socket.c +index 7a19ee5..9070928 100644 +--- a/src/gp_socket.c ++++ b/src/gp_socket.c +@@ -122,7 +122,9 @@ void gp_conn_free(struct gp_conn *conn) + close(conn->us.sd); + } + free(conn->program); +- SELINUX_context_free(conn->selinux_ctx); ++ if (conn->selinux_ctx) { ++ SELINUX_context_free(conn->selinux_ctx); ++ } + free(conn); + } + +@@ -635,7 +637,8 @@ void accept_sock_conn(verto_ctx *vctx, verto_ev *ev) + conn->creds.ucred.uid, + conn->creds.ucred.gid); + } +- if (conn->creds.type & CRED_TYPE_SELINUX) { ++ if ((conn->creds.type & CRED_TYPE_SELINUX) && ++ (conn->selinux_ctx != NULL)) { + GPDEBUG(" (context = %s)", + SELINUX_context_str(conn->selinux_ctx)); + } +-- +2.35.3 + diff --git a/SOURCES/Fix-leak-of-mech-OID-in-gssi_inquire_context.patch b/SOURCES/Fix-leak-of-mech-OID-in-gssi_inquire_context.patch new file mode 100644 index 0000000..dbde259 --- /dev/null +++ b/SOURCES/Fix-leak-of-mech-OID-in-gssi_inquire_context.patch @@ -0,0 +1,27 @@ +From 7777d261923e0f0c3bd9cb2b7f0c2ac81b83f2c3 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 26 Aug 2020 13:36:50 -0400 +Subject: [PATCH] Fix leak of mech OID in gssi_inquire_context() + +The name it creates holds a copy of the OID, which we need to release. + +Signed-off-by: Robbie Harwood +(cherry picked from commit 482349fa6bd536471216a898713c83260c78c08d) +(cherry picked from commit ce271e38be223a9442efd406c9a8fa961930e35b) +--- + src/mechglue/gpp_import_and_canon_name.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/mechglue/gpp_import_and_canon_name.c b/src/mechglue/gpp_import_and_canon_name.c +index 745be20..7d6829f 100644 +--- a/src/mechglue/gpp_import_and_canon_name.c ++++ b/src/mechglue/gpp_import_and_canon_name.c +@@ -257,6 +257,8 @@ OM_uint32 gssi_release_name(OM_uint32 *minor_status, + return GSS_S_BAD_NAME; + } + ++ (void)gss_release_oid(&rmin, &name->mech_type); ++ + rmaj = gpm_release_name(&rmin, &name->remote); + + if (name->local) { diff --git a/SOURCES/Fix-leaks-in-our-test-suite-itself.patch b/SOURCES/Fix-leaks-in-our-test-suite-itself.patch new file mode 100644 index 0000000..70348af --- /dev/null +++ b/SOURCES/Fix-leaks-in-our-test-suite-itself.patch @@ -0,0 +1,157 @@ +From 5881a9dbc87f20cd149f53f444b95e8b579638c7 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 13:23:49 -0400 +Subject: [PATCH] Fix leaks in our test suite itself + +These are mostly laziness in freeing since the programs are short-lived. + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: rewrote commit message] +Reviewed-by: Robbie Harwood +(cherry picked from commit dc56c86f1dcb1ae4dbc35facf5f50fb21c9d5049) +(cherry picked from commit 617d9ee9ce967cf20462e3cc7a575fda0f945075) +--- + tests/interposetest.c | 22 +++++++++++++++------- + tests/t_impersonate.c | 11 ++++++++--- + tests/t_init.c | 2 ++ + tests/t_setcredopt.c | 8 ++++++-- + 4 files changed, 31 insertions(+), 12 deletions(-) + +diff --git a/tests/interposetest.c b/tests/interposetest.c +index a00904f..0cdd473 100644 +--- a/tests/interposetest.c ++++ b/tests/interposetest.c +@@ -71,6 +71,8 @@ static int gptest_inq_context(gss_ctx_id_t ctx) + DEBUG("Context validity: %d sec.\n", time_rec); + + done: ++ (void)gss_release_name(&min, &src_name); ++ (void)gss_release_name(&min, &targ_name); + (void)gss_release_buffer(&min, &sname); + (void)gss_release_buffer(&min, &tname); + (void)gss_release_buffer(&min, &mechstr); +@@ -274,7 +276,7 @@ void run_client(struct aproc *data) + gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min); + goto done; + } +- fprintf(stdout, "Client, RECV: [%s]\n", buffer); ++ fprintf(stdout, "Client, RECV: [%*s]\n", buflen, buffer); + + /* test gss_wrap_iov_length */ + +@@ -837,19 +839,22 @@ int main(int argc, const char *main_argv[]) + + if (opt_version) { + puts(VERSION""DISTRO_VERSION""PRERELEASE_VERSION); +- return 0; ++ ret = 0; ++ goto done; + } + + if (opt_target == NULL) { + fprintf(stderr, "Missing target!\n"); + poptPrintUsage(pc, stderr, 0); +- return 1; ++ ret = 1; ++ goto done; + } + + if (!opt_all) { +- return run_cli_srv_test(PROXY_LOCAL_ONLY, +- PROXY_LOCAL_ONLY, +- opt_target); ++ ret = run_cli_srv_test(PROXY_LOCAL_ONLY, ++ PROXY_LOCAL_ONLY, ++ opt_target); ++ goto done; + } + + for (i=0; i<4; i++) { +@@ -861,10 +866,13 @@ int main(int argc, const char *main_argv[]) + lookup_gssproxy_behavior(k), + ret ? "failed" : "succeeded"); + if (ret) { +- return ret; ++ goto done; + } + } + } + ++done: ++ poptFreeContext(pc); ++ free(opt_target); + return ret; + } +diff --git a/tests/t_impersonate.c b/tests/t_impersonate.c +index 8ca6e9c..e7b0bc2 100644 +--- a/tests/t_impersonate.c ++++ b/tests/t_impersonate.c +@@ -12,9 +12,9 @@ int main(int argc, const char *argv[]) + gss_ctx_id_t accept_ctx = GSS_C_NO_CONTEXT; + gss_buffer_desc in_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc out_token = GSS_C_EMPTY_BUFFER; +- gss_name_t user_name; +- gss_name_t proxy_name; +- gss_name_t target_name; ++ gss_name_t user_name = GSS_C_NO_NAME; ++ gss_name_t proxy_name = GSS_C_NO_NAME; ++ gss_name_t target_name = GSS_C_NO_NAME; + gss_OID_set_desc oid_set = { 1, discard_const(gss_mech_krb5) }; + uint32_t ret_maj; + uint32_t ret_min; +@@ -207,9 +207,14 @@ int main(int argc, const char *argv[]) + ret = 0; + + done: ++ gss_release_name(&ret_min, &user_name); ++ gss_release_name(&ret_min, &proxy_name); ++ gss_release_name(&ret_min, &target_name); + gss_release_buffer(&ret_min, &in_token); + gss_release_buffer(&ret_min, &out_token); + gss_release_cred(&ret_min, &impersonator_cred_handle); + gss_release_cred(&ret_min, &cred_handle); ++ gss_delete_sec_context(&ret_min, &accept_ctx, GSS_C_NO_BUFFER); ++ gss_delete_sec_context(&ret_min, &init_ctx, GSS_C_NO_BUFFER); + return ret; + } +diff --git a/tests/t_init.c b/tests/t_init.c +index 02407ce..76bd4c1 100644 +--- a/tests/t_init.c ++++ b/tests/t_init.c +@@ -82,6 +82,8 @@ int main(int argc, const char *argv[]) + goto done; + } + ++ gss_release_buffer(&ret_min, &out_token); ++ + ret = t_recv_buffer(STDIN_FD, buffer, &buflen); + if (ret != 0) { + DEBUG("Failed to read token from STDIN\n"); +diff --git a/tests/t_setcredopt.c b/tests/t_setcredopt.c +index 1399474..bc5e13f 100644 +--- a/tests/t_setcredopt.c ++++ b/tests/t_setcredopt.c +@@ -12,8 +12,8 @@ int main(int argc, const char *argv[]) + gss_ctx_id_t accept_ctx = GSS_C_NO_CONTEXT; + gss_buffer_desc in_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc out_token = GSS_C_EMPTY_BUFFER; +- gss_name_t user_name; +- gss_name_t target_name; ++ gss_name_t user_name = GSS_C_NO_NAME; ++ gss_name_t target_name = GSS_C_NO_NAME; + gss_OID_set_desc oid_set = { 1, discard_const(gss_mech_krb5) }; + uint32_t ret_maj; + uint32_t ret_min; +@@ -160,8 +160,12 @@ int main(int argc, const char *argv[]) + ret = 0; + + done: ++ gss_release_name(&ret_min, &user_name); ++ gss_release_name(&ret_min, &target_name); + gss_release_buffer(&ret_min, &in_token); + gss_release_buffer(&ret_min, &out_token); + gss_release_cred(&ret_min, &cred_handle); ++ gss_delete_sec_context(&ret_min, &init_ctx, GSS_C_NO_BUFFER); ++ gss_delete_sec_context(&ret_min, &accept_ctx, GSS_C_NO_BUFFER); + return ret; + } diff --git a/SOURCES/Handle-gss_import_cred-failure-when-importing-gssx-c.patch b/SOURCES/Handle-gss_import_cred-failure-when-importing-gssx-c.patch new file mode 100644 index 0000000..ddc7faa --- /dev/null +++ b/SOURCES/Handle-gss_import_cred-failure-when-importing-gssx-c.patch @@ -0,0 +1,31 @@ +From 0379411547792a58b3d36c9928354072b5f6cabf Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 15 Apr 2019 19:56:50 -0400 +Subject: [PATCH] Handle gss_import_cred() failure when importing gssx creds + +Otherwise, we might attempt to set options on a non-existent handle, +leading to a segfault. + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Merges: #244 +(cherry picked from commit 84cf88f6c6cfeb8e3fd2c26ed0fe9fe5bf3810d2) +--- + src/gp_export.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/gp_export.c b/src/gp_export.c +index 403e339..7ad8037 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -476,6 +476,10 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall, + } + + ret_maj = gss_import_cred(&ret_min, &token, out); ++ if (ret_maj) { ++ GPDEBUG("gss_import_cred failed when importing gssx cred\n"); ++ goto done; ++ } + + /* check if there is any client option we need to set on credentials */ + gp_set_cred_options(cred, *out); diff --git a/SOURCES/Include-length-when-using-krb5_c_decrypt.patch b/SOURCES/Include-length-when-using-krb5_c_decrypt.patch new file mode 100644 index 0000000..dcff9c3 --- /dev/null +++ b/SOURCES/Include-length-when-using-krb5_c_decrypt.patch @@ -0,0 +1,98 @@ +From 5dec1aeb0a6080ea661061b52248e60afc969426 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 16 Apr 2019 16:08:32 -0400 +Subject: [PATCH] Include length when using krb5_c_decrypt() + +For some enctypes, krb5_c_decrypt() will add padding bytes which are +included in the returned length. However, functions which use the +objects we're storing aren't always prepared for that: in particular, +gss_import_cred() will declare a token invalid if there's trailing +garbage. + +Work around this by including 4 bytes of length on encrypted objects. + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Merges: #244 +(cherry picked from commit 87957caf541114f6f15a495dd7d30556dc5801d9) +--- + src/gp_export.c | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +diff --git a/src/gp_export.c b/src/gp_export.c +index 7ad8037..aa0a8ec 100644 +--- a/src/gp_export.c ++++ b/src/gp_export.c +@@ -193,6 +193,9 @@ done: + return ret_maj; + } + ++/* We need to include a length in our payloads because krb5_c_decrypt() will ++ * pad the contents for some enctypes, and gss_import_cred() doesn't like ++ * having extra bytes on tokens. */ + static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + size_t len, void *buf, octet_string *out) + { +@@ -200,9 +203,27 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + krb5_data data_in; + krb5_enc_data enc_handle; + size_t cipherlen; ++ char *packed = NULL; ++ uint32_t netlen; + +- data_in.length = len; +- data_in.data = buf; ++ if (len > (uint32_t)(-1)) { ++ /* Needs to fit in 4 bytes of payload, so... */ ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ packed = malloc(len); ++ if (!packed) { ++ ret = errno; ++ goto done; ++ } ++ ++ netlen = htonl(len); ++ memcpy(packed, (uint8_t *)&netlen, 4); ++ memcpy(packed + 4, buf, len); ++ ++ data_in.length = len + 4; ++ data_in.data = packed; + + memset(&enc_handle, '\0', sizeof(krb5_enc_data)); + +@@ -240,16 +261,19 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key, + } + + done: ++ free(packed); + free(enc_handle.ciphertext.data); + return ret; + } + ++/* See comment above on gp_encrypt_buffer(). */ + static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key, +- octet_string *in, size_t *len, void *buf) ++ octet_string *in, size_t *len, char *buf) + { + int ret; + krb5_data data_out; + krb5_enc_data enc_handle; ++ uint32_t netlen; + + memset(&enc_handle, '\0', sizeof(krb5_enc_data)); + +@@ -270,7 +294,10 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key, + return ret; + } + +- *len = data_out.length; ++ /* And handle the padding. */ ++ memcpy(&netlen, buf, 4); ++ *len = ntohl(netlen); ++ memmove(buf, buf + 4, *len); + + return 0; + } diff --git a/SOURCES/Initialize-interposed-mech-list-without-allocation.patch b/SOURCES/Initialize-interposed-mech-list-without-allocation.patch new file mode 100644 index 0000000..3b8bb4f --- /dev/null +++ b/SOURCES/Initialize-interposed-mech-list-without-allocation.patch @@ -0,0 +1,93 @@ +From 70f30d61e7f5da178e47dcfc8feb083a17be74ff Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 12:32:06 -0400 +Subject: [PATCH] Initialize interposed mech list without allocation + +While we had already fixed the leak here in main, the code performed +unnecessary extra work, so just replacethe whole lot with a function +that does not do any extra allocation or copy. + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: commit message] +Reviewed-by: Robbie Harwood +(cherry picked from commit 447d5352c2a81e219ccf04348a87b2ff25b7de15) +(cherry picked from commit 4abda7e47551f39adfc074fc017f6006a4b91a19) +--- + src/mechglue/gss_plugin.c | 31 ++++++++++++++++++++++++++----- + 1 file changed, 26 insertions(+), 5 deletions(-) + +diff --git a/src/mechglue/gss_plugin.c b/src/mechglue/gss_plugin.c +index b9813dc..79e04d0 100644 +--- a/src/mechglue/gss_plugin.c ++++ b/src/mechglue/gss_plugin.c +@@ -65,6 +65,8 @@ enum gpp_behavior gpp_get_behavior(void) + return behavior; + } + ++static void gpp_init_special_available_mechs(const gss_OID_set mechs); ++ + /* 2.16.840.1.113730.3.8.15.1 */ + const gss_OID_desc gssproxy_mech_interposer = { + .length = 11, +@@ -76,7 +78,6 @@ gss_OID_set gss_mech_interposer(gss_OID mech_type) + gss_OID_set interposed_mechs; + OM_uint32 maj, min; + char *envval; +- gss_OID_set special_mechs; + + /* avoid looping in the gssproxy daemon by avoiding to interpose + * any mechanism */ +@@ -119,8 +120,7 @@ gss_OID_set gss_mech_interposer(gss_OID mech_type) + } + + /* while there also initiaize special_mechs */ +- special_mechs = gpp_special_available_mechs(interposed_mechs); +- (void)gss_release_oid_set(&min, &special_mechs); ++ gpp_init_special_available_mechs(interposed_mechs); + + done: + if (maj != 0) { +@@ -307,13 +307,13 @@ gss_OID_set gpp_special_available_mechs(const gss_OID_set mechs) + gss_OID n; + uint32_t maj, min; + +- item = gpp_get_special_oids(); +- + maj = gss_create_empty_oid_set(&min, &amechs); + if (maj) { + return GSS_C_NO_OID_SET; + } + for (size_t i = 0; i < mechs->count; i++) { ++ item = gpp_get_special_oids(); ++ + while (item) { + if (gpp_is_special_oid(&mechs->elements[i])) { + maj = gss_add_oid_set_member(&min, +@@ -354,6 +354,27 @@ done: + return amechs; + } + ++static void gpp_init_special_available_mechs(const gss_OID_set mechs) ++{ ++ struct gpp_special_oid_list *item; ++ ++ for (size_t i = 0; i < mechs->count; i++) { ++ item = gpp_get_special_oids(); ++ ++ while (item) { ++ if (gpp_is_special_oid(&mechs->elements[i]) || ++ gpp_special_equal(&item->special_oid, &mechs->elements[i])) { ++ break; ++ } ++ item = gpp_next_special_oids(item); ++ } ++ if (item == NULL) { ++ /* not found, add to static list */ ++ (void)gpp_new_special_mech(&mechs->elements[i]); ++ } ++ } ++} ++ + OM_uint32 gssi_internal_release_oid(OM_uint32 *minor_status, gss_OID *oid) + { + struct gpp_special_oid_list *item = NULL; diff --git a/SOURCES/Initialize-our-epoll_event-structures.patch b/SOURCES/Initialize-our-epoll_event-structures.patch new file mode 100644 index 0000000..44751d9 --- /dev/null +++ b/SOURCES/Initialize-our-epoll_event-structures.patch @@ -0,0 +1,38 @@ +From c824b8ef3b5ec630edb0f8be78b64b2431c4482f Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Thu, 30 Jul 2020 16:43:30 -0400 +Subject: [PATCH] Initialize our epoll_event structures + +Fixes a valgrind error for the other fields of epoll_event. + +Signed-off-by: Robbie Harwood +(cherry picked from commit 48bfadc538bca3b9ca478c711af75245163d0b67) +(cherry picked from commit 35579d9de1d3f295fb4548c73fc6a729d04128c6) +--- + src/client/gpm_common.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c +index 808f350..d932ba2 100644 +--- a/src/client/gpm_common.c ++++ b/src/client/gpm_common.c +@@ -195,6 +195,8 @@ static int gpm_epoll_setup(struct gpm_ctx *gpmctx) + struct epoll_event ev; + int ret; + ++ memset(&ev, 0, sizeof(ev)); ++ + if (gpmctx->epollfd >= 0) { + gpm_epoll_close(gpmctx); + } +@@ -276,6 +278,10 @@ static int gpm_epoll_wait(struct gpm_ctx *gpmctx, uint32_t event_flags) + struct epoll_event events[2]; + uint64_t timer_read; + ++ memset(&ev, 0, sizeof(ev)); ++ memset(&events[0], 0, sizeof(events[0])); ++ memset(&events[1], 0, sizeof(events[1])); ++ + if (gpmctx->epollfd < 0) { + ret = gpm_epoll_setup(gpmctx); + if (ret) diff --git a/SOURCES/Make-sure-to-free-also-the-remote-ctx-struct.patch b/SOURCES/Make-sure-to-free-also-the-remote-ctx-struct.patch new file mode 100644 index 0000000..95f93f1 --- /dev/null +++ b/SOURCES/Make-sure-to-free-also-the-remote-ctx-struct.patch @@ -0,0 +1,28 @@ +From a02741d82ff44b3c93747615f560dae1bbe7c57b Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 12:44:45 -0400 +Subject: [PATCH] Make sure to free also the remote ctx struct + +The xdr_free() call only frees the contents and not the containing +structure itself. + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +(cherry picked from commit e6811347c23b6c62d9f1869da089ab9900f97a84) +(cherry picked from commit 8d5457c290d513781b54be54ede9c81cc5d1fff8) +--- + src/client/gpm_release_handle.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/client/gpm_release_handle.c b/src/client/gpm_release_handle.c +index 8f49ee9..2f70781 100644 +--- a/src/client/gpm_release_handle.c ++++ b/src/client/gpm_release_handle.c +@@ -106,5 +106,7 @@ rel_done: + gpm_free_xdrs(GSSX_RELEASE_HANDLE, &uarg, &ures); + done: + xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)r); ++ free(r); ++ *context_handle = NULL; + return ret; + } diff --git a/SOURCES/Make-syslog-of-call-status-configurable.patch b/SOURCES/Make-syslog-of-call-status-configurable.patch new file mode 100644 index 0000000..52473c3 --- /dev/null +++ b/SOURCES/Make-syslog-of-call-status-configurable.patch @@ -0,0 +1,158 @@ +From 07b32184ee337ec06a405724b4b88cad22829c6d Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 30 Sep 2019 15:00:56 -0400 +Subject: [PATCH] Make syslog of call status configurable + +Add a parameter (syslog_status) to configuration and +CLI (--syslog-status). This logs the results of GSSAPI calls at +LOG_DEBUG. Typically these calls resemble: + + gssproxy[28914]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS + failure. Minor code may provide more information, No credentials + cache found + +Since these messages worry some admins, turn them off by default. + +Signed-off-by: Robbie Harwood +(cherry picked from commit 116618e1523038691fcb481107ba15ffd42942ac) +(cherry picked from commit cc61409b7b20974332549dd028d889b87dbff98d) +--- + man/gssproxy.8.xml | 8 ++++++++ + man/gssproxy.conf.5.xml | 10 ++++++++++ + src/gp_config.c | 6 ++++++ + src/gp_log.c | 9 +++++++-- + src/gp_log.h | 3 +++ + src/gssproxy.c | 6 ++++++ + 6 files changed, 40 insertions(+), 2 deletions(-) + +diff --git a/man/gssproxy.8.xml b/man/gssproxy.8.xml +index 21f7e6a..4019135 100644 +--- a/man/gssproxy.8.xml ++++ b/man/gssproxy.8.xml +@@ -151,6 +151,14 @@ + + + ++ ++ ++ ++ ++ ++ Enable additional logging to syslog. ++ ++ + + + +diff --git a/man/gssproxy.conf.5.xml b/man/gssproxy.conf.5.xml +index 21c9653..53cae3d 100644 +--- a/man/gssproxy.conf.5.xml ++++ b/man/gssproxy.conf.5.xml +@@ -365,6 +365,16 @@ + + + ++ ++ syslog_status (boolean) ++ ++ Enable per-call debugging output to the syslog. ++ This may be useful for investigating problems in ++ applications using gssproxy. ++ Default: syslog_status = false ++ ++ ++ + + trusted (boolean) + Defines whether this service is considered trusted. Use with caution, this enables impersonation. +diff --git a/src/gp_config.c b/src/gp_config.c +index 78474ed..88d5f29 100644 +--- a/src/gp_config.c ++++ b/src/gp_config.c +@@ -611,6 +611,12 @@ int load_config(struct gp_config *cfg) + goto done; + } + ++ ret = gp_config_get_string(ctx, "gssproxy", "syslog_status", &tmpstr); ++ if (ret == 0) ++ gp_syslog_status = gp_boolean_is_true(tmpstr); ++ else if (ret != ENOENT) ++ goto done; ++ + ret = gp_config_get_string(ctx, "gssproxy", "run_as_user", &tmpstr); + if (ret == 0) { + cfg->proxy_user = strdup(tmpstr); +diff --git a/src/gp_log.c b/src/gp_log.c +index b6eb161..e67e8d3 100644 +--- a/src/gp_log.c ++++ b/src/gp_log.c +@@ -5,6 +5,9 @@ + #include + #include + ++/* global logging switch */ ++bool gp_syslog_status = false; ++ + void gp_logging_init(void) + { + openlog("gssproxy", +@@ -55,7 +58,9 @@ void gp_log_status(gss_OID mech, uint32_t maj, uint32_t min) + { + char buf[MAX_LOG_LINE]; + +- gp_fmt_status(mech, maj, min, buf, MAX_LOG_LINE); ++ if (!gp_syslog_status) ++ return; + +- GPERROR("%s\n", buf); ++ gp_fmt_status(mech, maj, min, buf, MAX_LOG_LINE); ++ syslog(LOG_DEBUG, "%s\n", buf); + } +diff --git a/src/gp_log.h b/src/gp_log.h +index fc8cbdb..31ad648 100644 +--- a/src/gp_log.h ++++ b/src/gp_log.h +@@ -3,9 +3,12 @@ + #ifndef _GP_LOG_H_ + #define _GP_LOG_H_ + ++#include + #include + #include + ++extern bool gp_syslog_status; ++ + #define MAX_LOG_LINE 1024 + #define GPERROR(...) syslog(LOG_ERR, __VA_ARGS__); + #define GPAUDIT(...) syslog(LOG_INFO, __VA_ARGS__); +diff --git a/src/gssproxy.c b/src/gssproxy.c +index db6e89b..6b72a9b 100644 +--- a/src/gssproxy.c ++++ b/src/gssproxy.c +@@ -157,6 +157,7 @@ int main(int argc, const char *argv[]) + int opt_version = 0; + int opt_debug = 0; + int opt_debug_level = 0; ++ int opt_syslog_status = 0; + verto_ctx *vctx; + verto_ev *ev; + int wait_fd; +@@ -182,6 +183,8 @@ int main(int argc, const char *argv[]) + _("Enable debugging"), NULL}, \ + {"debug-level", '\0', POPT_ARG_INT, &opt_debug_level, 0, \ + _("Set debugging level"), NULL}, \ ++ {"syslog-status", '\0', POPT_ARG_NONE, &opt_syslog_status, 0, \ ++ _("Enable GSSAPI status logging to syslog"), NULL}, \ + {"version", '\0', POPT_ARG_NONE, &opt_version, 0, \ + _("Print version number and exit"), NULL }, \ + POPT_TABLEEND +@@ -211,6 +214,9 @@ int main(int argc, const char *argv[]) + gp_debug_toggle(opt_debug_level); + } + ++ if (opt_syslog_status) ++ gp_syslog_status = true; ++ + if (opt_daemon && opt_interactive) { + fprintf(stderr, "Option -i|--interactive is not allowed together with -D|--daemon\n"); + poptPrintUsage(pc, stderr, 0); diff --git a/SOURCES/Return-static-oids-for-naming-functions.patch b/SOURCES/Return-static-oids-for-naming-functions.patch new file mode 100644 index 0000000..3444050 --- /dev/null +++ b/SOURCES/Return-static-oids-for-naming-functions.patch @@ -0,0 +1,157 @@ +From 0987e0e137854285d4022f5a910e7923d4e663fd Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 17:01:39 -0400 +Subject: [PATCH] Return static oids for naming functions + +gss_display_name and gss_inquire_name reteurn "static" oids, that are +generally not freed by callers, so make sure to match and return actual +static OIDs exported by GSSAPI. + +Also remove gpm_equal_oids() and use the library provided gss_oid_equal +function instead. + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +(cherry picked from commit 6ea8391257e687dfb3981b634c06cf7a55008eb0) +(cherry picked from commit 41cb9683627d6c3b136a4b48e1b1842619132f16) +--- + src/client/gpm_import_and_canon_name.c | 28 ++++++++++++++++++++++++-- + src/client/gpm_indicate_mechs.c | 24 +++++----------------- + src/client/gssapi_gpm.h | 1 + + 3 files changed, 32 insertions(+), 21 deletions(-) + +diff --git a/src/client/gpm_import_and_canon_name.c b/src/client/gpm_import_and_canon_name.c +index 70149a3..88b8d7c 100644 +--- a/src/client/gpm_import_and_canon_name.c ++++ b/src/client/gpm_import_and_canon_name.c +@@ -2,6 +2,26 @@ + + #include "gssapi_gpm.h" + ++static int gpm_name_oid_to_static(gss_OID name_type, gss_OID *name_static) ++{ ++#define ret_static(b) \ ++ if (gss_oid_equal(name_type, b)) { \ ++ *name_static = b; \ ++ return 0; \ ++ } ++ ret_static(GSS_C_NT_USER_NAME); ++ ret_static(GSS_C_NT_MACHINE_UID_NAME); ++ ret_static(GSS_C_NT_STRING_UID_NAME); ++ ret_static(GSS_C_NT_HOSTBASED_SERVICE_X); ++ ret_static(GSS_C_NT_HOSTBASED_SERVICE); ++ ret_static(GSS_C_NT_ANONYMOUS); ++ ret_static(GSS_C_NT_EXPORT_NAME); ++ ret_static(GSS_C_NT_COMPOSITE_EXPORT); ++ ret_static(GSS_KRB5_NT_PRINCIPAL_NAME); ++ ret_static(gss_nt_krb5_name); ++ return ENOENT; ++} ++ + OM_uint32 gpm_display_name(OM_uint32 *minor_status, + gssx_name *in_name, + gss_buffer_t output_name_buffer, +@@ -57,7 +77,9 @@ OM_uint32 gpm_display_name(OM_uint32 *minor_status, + } + + if (output_name_type) { +- ret = gp_conv_gssx_to_oid_alloc(&in_name->name_type, output_name_type); ++ gss_OID_desc oid; ++ gp_conv_gssx_to_oid(&in_name->name_type, &oid); ++ ret = gpm_name_oid_to_static(&oid, output_name_type); + if (ret) { + gss_release_buffer(&discard, output_name_buffer); + ret_min = ret; +@@ -285,7 +307,9 @@ OM_uint32 gpm_inquire_name(OM_uint32 *minor_status, + } + + if (MN_mech != NULL) { +- ret = gp_conv_gssx_to_oid_alloc(&name->name_type, MN_mech); ++ gss_OID_desc oid; ++ gp_conv_gssx_to_oid(&name->name_type, &oid); ++ ret = gpm_name_oid_to_static(&oid, MN_mech); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; +diff --git a/src/client/gpm_indicate_mechs.c b/src/client/gpm_indicate_mechs.c +index 86c7de3..4041dcd 100644 +--- a/src/client/gpm_indicate_mechs.c ++++ b/src/client/gpm_indicate_mechs.c +@@ -95,20 +95,6 @@ static uint32_t gpm_copy_gss_buffer(uint32_t *minor_status, + return GSS_S_COMPLETE; + } + +-static bool gpm_equal_oids(gss_const_OID a, gss_const_OID b) +-{ +- int ret; +- +- if (a->length == b->length) { +- ret = memcmp(a->elements, b->elements, a->length); +- if (ret == 0) { +- return true; +- } +- } +- +- return false; +-} +- + static void gpmint_indicate_mechs(void) + { + union gp_rpc_arg uarg; +@@ -313,7 +299,7 @@ int gpm_mech_to_static(gss_OID mech_type, gss_OID *mech_static) + + *mech_static = GSS_C_NO_OID; + for (size_t i = 0; i < global_mechs.mech_set->count; i++) { +- if (gpm_equal_oids(&global_mechs.mech_set->elements[i], mech_type)) { ++ if (gss_oid_equal(&global_mechs.mech_set->elements[i], mech_type)) { + *mech_static = &global_mechs.mech_set->elements[i]; + return 0; + } +@@ -383,7 +369,7 @@ OM_uint32 gpm_inquire_names_for_mech(OM_uint32 *minor_status, + } + + for (unsigned i = 0; i < global_mechs.info_len; i++) { +- if (!gpm_equal_oids(global_mechs.info[i].mech, mech_type)) { ++ if (!gss_oid_equal(global_mechs.info[i].mech, mech_type)) { + continue; + } + ret_maj = gpm_copy_gss_OID_set(&ret_min, +@@ -481,7 +467,7 @@ OM_uint32 gpm_inquire_attrs_for_mech(OM_uint32 *minor_status, + } + + for (unsigned i = 0; i < global_mechs.info_len; i++) { +- if (!gpm_equal_oids(global_mechs.info[i].mech, mech)) { ++ if (!gss_oid_equal(global_mechs.info[i].mech, mech)) { + continue; + } + +@@ -540,7 +526,7 @@ OM_uint32 gpm_inquire_saslname_for_mech(OM_uint32 *minor_status, + } + + for (unsigned i = 0; i < global_mechs.info_len; i++) { +- if (!gpm_equal_oids(global_mechs.info[i].mech, desired_mech)) { ++ if (!gss_oid_equal(global_mechs.info[i].mech, desired_mech)) { + continue; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, +@@ -598,7 +584,7 @@ OM_uint32 gpm_display_mech_attr(OM_uint32 *minor_status, + } + + for (unsigned i = 0; i < global_mechs.desc_len; i++) { +- if (!gpm_equal_oids(global_mechs.desc[i].attr, mech_attr)) { ++ if (!gss_oid_equal(global_mechs.desc[i].attr, mech_attr)) { + continue; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, +diff --git a/src/client/gssapi_gpm.h b/src/client/gssapi_gpm.h +index b7ba04b..bdf12e1 100644 +--- a/src/client/gssapi_gpm.h ++++ b/src/client/gssapi_gpm.h +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include "rpcgen/gp_rpc.h" + #include "rpcgen/gss_proxy.h" + #include "src/gp_common.h" diff --git a/SOURCES/Update-NFS-service-name-in-systemd-unit.patch b/SOURCES/Update-NFS-service-name-in-systemd-unit.patch new file mode 100644 index 0000000..6ee71e5 --- /dev/null +++ b/SOURCES/Update-NFS-service-name-in-systemd-unit.patch @@ -0,0 +1,27 @@ +From 9860e73b5da0f0448594ecc700ccc7ba08177718 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 24 Apr 2019 12:07:47 -0400 +Subject: [PATCH] Update NFS service name in systemd unit + +Signed-off-by: Robbie Harwood +Reviewed-by: Simo Sorce +Merges: #247 +(cherry picked from commit 1a789a645175d5aea109a3c0831806b94337b20e) +(cherry picked from commit aa4f43049d1037d1c23becd78ad2f7dd601132f4) +--- + systemd/gssproxy.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/systemd/gssproxy.service.in b/systemd/gssproxy.service.in +index f50f526..ac37df6 100644 +--- a/systemd/gssproxy.service.in ++++ b/systemd/gssproxy.service.in +@@ -2,7 +2,7 @@ + Description=GSSAPI Proxy Daemon + # GSSPROXY will not be started until syslog is + After=syslog.target +-Before=nfs-secure.service nfs-secure-server.service ++Before=rpc-gssd.service + + [Service] + Environment=KRB5RCACHEDIR=/var/lib/gssproxy/rcache diff --git a/SOURCES/Use-pthread-keys-for-thread-local-storage.patch b/SOURCES/Use-pthread-keys-for-thread-local-storage.patch new file mode 100644 index 0000000..e49ad31 --- /dev/null +++ b/SOURCES/Use-pthread-keys-for-thread-local-storage.patch @@ -0,0 +1,150 @@ +From e0b142320342ef16260b6072f1c83d6fcf4142e6 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 20 Sep 2018 17:37:53 -0400 +Subject: [PATCH] Use pthread keys for thread local storage + +This interface is slower but also more portable, and more importantly +it provides a way to specify destructor that is called when a thread +is canceled so we stop leaking memory. + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +Merges: #233 +(cherry picked from commit 0faccc1441bc7a6b3e8bd806f22c8a961e5f586e) +(cherry picked from commit 89dc0ee157caa4617d32fd72287849296d7fe26d) +--- + src/client/gpm_common.c | 2 ++ + src/client/gpm_display_status.c | 57 ++++++++++++++++++++++----------- + src/client/gssapi_gpm.h | 1 + + 3 files changed, 42 insertions(+), 18 deletions(-) + +diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c +index dd29519..c254280 100644 +--- a/src/client/gpm_common.c ++++ b/src/client/gpm_common.c +@@ -55,6 +55,8 @@ static void gpm_init_once(void) + gpm_global_ctx.next_xid = rand_r(&seedp); + + pthread_mutexattr_destroy(&attr); ++ ++ gpm_display_status_init_once(); + } + + static int get_pipe_name(char *name) +diff --git a/src/client/gpm_display_status.c b/src/client/gpm_display_status.c +index bbb546f..e3aa4ea 100644 +--- a/src/client/gpm_display_status.c ++++ b/src/client/gpm_display_status.c +@@ -1,27 +1,47 @@ + /* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */ + + #include "gssapi_gpm.h" ++#include + +-__thread gssx_status *tls_last_status = NULL; ++static pthread_key_t gpm_last_status; + +-/* Thread local storage for return status. +- * FIXME: it's not the most portable construct, so may need fixing in future */ ++static void gpm_destroy_last_status(void *arg) ++{ ++ gssx_status *status = (gssx_status *)arg; ++ xdr_free((xdrproc_t)xdr_gssx_status, (char *)status); ++ free(status); ++} ++ ++void gpm_display_status_init_once(void) ++{ ++ (void)pthread_key_create(&gpm_last_status, gpm_destroy_last_status); ++} ++ ++/* Portable thread local storage for return status. */ + void gpm_save_status(gssx_status *status) + { ++ gssx_status *last_status; + int ret; + +- if (tls_last_status) { +- xdr_free((xdrproc_t)xdr_gssx_status, (char *)tls_last_status); +- free(tls_last_status); ++ last_status = (gssx_status *)pthread_getspecific(gpm_last_status); ++ if (last_status != NULL) { ++ /* store NULL first so we do not risk a double free if we are ++ * racing on a pthread_cancel */ ++ pthread_setspecific(gpm_last_status, NULL); ++ gpm_destroy_last_status(last_status); + } + +- ret = gp_copy_gssx_status_alloc(status, &tls_last_status); +- if (ret) { +- /* make sure tls_last_status is zeored on error */ +- tls_last_status = NULL; ++ ret = gp_copy_gssx_status_alloc(status, &last_status); ++ if (ret == 0) { ++ pthread_setspecific(gpm_last_status, last_status); + } + } + ++gssx_status *gpm_get_saved_status(void) ++{ ++ return (gssx_status *)pthread_getspecific(gpm_last_status); ++} ++ + /* This funciton is used to record internal mech errors that are + * generated by the proxy client code */ + void gpm_save_internal_status(uint32_t err, char *err_str) +@@ -47,15 +67,16 @@ OM_uint32 gpm_display_status(OM_uint32 *minor_status, + OM_uint32 *message_context, + gss_buffer_t status_string) + { ++ gssx_status *last_status = gpm_get_saved_status(); + utf8string tmp; + int ret; + + switch(status_type) { + case GSS_C_GSS_CODE: +- if (tls_last_status && +- tls_last_status->major_status == status_value && +- tls_last_status->major_status_string.utf8string_len) { +- ret = gp_copy_utf8string(&tls_last_status->major_status_string, ++ if (last_status && ++ last_status->major_status == status_value && ++ last_status->major_status_string.utf8string_len) { ++ ret = gp_copy_utf8string(&last_status->major_status_string, + &tmp); + if (ret) { + *minor_status = ret; +@@ -70,9 +91,9 @@ OM_uint32 gpm_display_status(OM_uint32 *minor_status, + return GSS_S_UNAVAILABLE; + } + case GSS_C_MECH_CODE: +- if (tls_last_status && +- tls_last_status->minor_status == status_value && +- tls_last_status->minor_status_string.utf8string_len) { ++ if (last_status && ++ last_status->minor_status == status_value && ++ last_status->minor_status_string.utf8string_len) { + + if (*message_context) { + /* we do not support multiple messages for now */ +@@ -80,7 +101,7 @@ OM_uint32 gpm_display_status(OM_uint32 *minor_status, + return GSS_S_FAILURE; + } + +- ret = gp_copy_utf8string(&tls_last_status->minor_status_string, ++ ret = gp_copy_utf8string(&last_status->minor_status_string, + &tmp); + if (ret) { + *minor_status = ret; +diff --git a/src/client/gssapi_gpm.h b/src/client/gssapi_gpm.h +index 22beecf..61124e0 100644 +--- a/src/client/gssapi_gpm.h ++++ b/src/client/gssapi_gpm.h +@@ -23,6 +23,7 @@ OM_uint32 gpm_release_name(OM_uint32 *minor_status, + OM_uint32 gpm_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer); + ++void gpm_display_status_init_once(void); + void gpm_save_status(gssx_status *status); + void gpm_save_internal_status(uint32_t err, char *err_str); + diff --git a/SOURCES/Use-static-OIDs-in-gss_inquire_context.patch b/SOURCES/Use-static-OIDs-in-gss_inquire_context.patch new file mode 100644 index 0000000..614d9e4 --- /dev/null +++ b/SOURCES/Use-static-OIDs-in-gss_inquire_context.patch @@ -0,0 +1,31 @@ +From 448501f1b3e0204353544ab245dd4ec77d46faae Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 17:21:03 -0400 +Subject: [PATCH] Use static OIDs in gss_inquire_context() + +As per other functions gssapi expect a static OID here. + +Signed-off-by: Simo Sorce +[rharwood@redhat.com: commit message fixup] +Reviewed-by: Robbie Harwood +(cherry picked from commit 502e448b3b126bf828ed871496dd7520d5075564) +(cherry picked from commit 9cc525b1f1184241483705dfc0a4162bc0c55632) +--- + src/client/gpm_inquire_context.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/client/gpm_inquire_context.c b/src/client/gpm_inquire_context.c +index 8c683fe..5800a8d 100644 +--- a/src/client/gpm_inquire_context.c ++++ b/src/client/gpm_inquire_context.c +@@ -51,7 +51,9 @@ OM_uint32 gpm_inquire_context(OM_uint32 *minor_status, + } + + if (mech_type) { +- ret = gp_conv_gssx_to_oid_alloc(&context_handle->mech, mech_type); ++ gss_OID_desc mech; ++ gp_conv_gssx_to_oid(&context_handle->mech, &mech); ++ ret = gpm_mech_to_static(&mech, mech_type); + if (ret) { + if (src_name) { + (void)gpm_release_name(&tmp_min, src_name); diff --git a/SOURCES/Use-the-correct-function-to-free-unused-creds.patch b/SOURCES/Use-the-correct-function-to-free-unused-creds.patch new file mode 100644 index 0000000..6e275c7 --- /dev/null +++ b/SOURCES/Use-the-correct-function-to-free-unused-creds.patch @@ -0,0 +1,40 @@ +From a23fd33ce8bdf4cdc4d2d00153d3bbf89f363475 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 27 Aug 2020 13:20:49 -0400 +Subject: [PATCH] Use the correct function to free unused creds + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +(cherry picked from commit a2ffd1230fd572d7fa9099af2365dfb7ac394d07) +(cherry picked from commit f77b75b7928a2c7813aebc8a1ec107d495627685) +--- + src/mechglue/gpp_creds.c | 2 +- + src/mechglue/gpp_init_sec_context.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/mechglue/gpp_creds.c b/src/mechglue/gpp_creds.c +index e87da82..338fadd 100644 +--- a/src/mechglue/gpp_creds.c ++++ b/src/mechglue/gpp_creds.c +@@ -895,7 +895,7 @@ done: + if (maj == GSS_S_COMPLETE) { + *cred_handle = (gss_cred_id_t)cred; + } else { +- free(cred); ++ (void)gpp_cred_handle_free(&min, cred); + } + (void)gss_release_buffer(&min, &wrap_token); + return maj; +diff --git a/src/mechglue/gpp_init_sec_context.c b/src/mechglue/gpp_init_sec_context.c +index 94d9b01..bb878df 100644 +--- a/src/mechglue/gpp_init_sec_context.c ++++ b/src/mechglue/gpp_init_sec_context.c +@@ -215,7 +215,7 @@ done: + *context_handle = (gss_ctx_id_t)ctx_handle; + + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { +- free(cred_handle); ++ (void)gpp_cred_handle_free(&min, cred_handle); + } + return maj; + } diff --git a/SPECS/gssproxy.spec b/SPECS/gssproxy.spec new file mode 100644 index 0000000..cd946da --- /dev/null +++ b/SPECS/gssproxy.spec @@ -0,0 +1,503 @@ +Name: gssproxy + +Version: 0.8.0 +Release: 21%{?dist} +Summary: GSSAPI Proxy + +Group: System Environment/Libraries +License: MIT +URL: https://pagure.io/gssproxy +Source0: https://releases.pagure.org/%{name}/%{name}-%{version}.tar.gz + +%global servicename gssproxy +%global pubconfpath %{_sysconfdir}/gssproxy +%global gpstatedir %{_localstatedir}/lib/gssproxy + +### Patches ### +Patch0: Always-use-the-encype-we-selected.patch +Patch1: Clarify-debug-and-debug_level-in-man-pages.patch +Patch2: Always-choose-highest-requested-debug-level.patch +Patch3: Use-pthread-keys-for-thread-local-storage.patch +Patch4: Close-epoll-fd-within-the-lock.patch +Patch5: Add-a-safety-timeout-to-epoll.patch +Patch7: Update-NFS-service-name-in-systemd-unit.patch +Patch8: Always-initialize-out-cred-in-gp_import_gssx_cred.patch +Patch9: Handle-gss_import_cred-failure-when-importing-gssx-c.patch +Patch10: Include-length-when-using-krb5_c_decrypt.patch +Patch11: Change-the-way-we-handle-encrypted-buffers.patch +Patch12: Avoid-uninitialized-free-when-allocating-buffers.patch +Patch13: Make-syslog-of-call-status-configurable.patch +Patch14: Delay-gssproxy-start-until-after-network.target.patch +Patch15: Document-config-file-non-merging.patch +Patch16: Initialize-our-epoll_event-structures.patch +Patch17: Avoid-leak-of-special-mechs-in-gss_mech_interposer.patch +Patch18: Fix-leak-of-mech-OID-in-gssi_inquire_context.patch +Patch19: Expand-use-of-global-static-mechs-to-conform-to-SPI.patch +Patch20: Correctly-size-loop-counter-in-gpp_special_available.patch +Patch21: Initialize-interposed-mech-list-without-allocation.patch +Patch22: Make-sure-to-free-also-the-remote-ctx-struct.patch +Patch23: Use-the-correct-function-to-free-unused-creds.patch +Patch24: Fix-leaks-in-our-test-suite-itself.patch +Patch25: Always-free-ciphertext-data-in-gp_encrypt_buffer.patch +Patch26: Return-static-oids-for-naming-functions.patch +Patch27: Avoid-unnecessary-allocation-in-gpm_inquire_mechs_fo.patch +Patch28: Use-static-OIDs-in-gss_inquire_context.patch +Patch29: Add-an-option-for-minimum-lifetime.patch +Patch30: Fix-handling-of-selinux-context-when-NULL.patch + +### Dependencies ### +Requires: krb5-libs >= 1.12.0 +Requires: keyutils-libs +Requires: libverto-module-base +Requires: libini_config >= 1.2.0 +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +# We use a Conflicts: here so as not to interfere with users who make +# their own policy. The version is the last time someone has filed a +# bug about gssproxy being broken with selinux. +Conflicts: selinux-policy < 3.13.1-283.5 + +### Build Dependencies ### +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: docbook-style-xsl +BuildRequires: doxygen +BuildRequires: findutils +BuildRequires: gettext-devel +BuildRequires: keyutils-libs-devel +BuildRequires: krb5-devel >= 1.12.0 +BuildRequires: libini_config-devel >= 1.2.0 +BuildRequires: libselinux-devel +BuildRequires: libtool +BuildRequires: libverto-devel +BuildRequires: libxml2 +BuildRequires: libxslt +BuildRequires: m4 +BuildRequires: pkgconfig +BuildRequires: popt-devel +BuildRequires: systemd-units + +BuildRequires: git + +%description +A proxy for GSSAPI credential handling + +%prep +%autosetup -S git + +%build +autoreconf -f -i +%configure \ + --with-pubconf-path=%{pubconfpath} \ + --with-initscript=systemd \ + --disable-static \ + --disable-rpath \ + --with-gpp-default-behavior=REMOTE_FIRST + +make %{?_smp_mflags} all +make test_proxymech + +%install +rm -rf %{buildroot} +make install DESTDIR=%{buildroot} +rm -f %{buildroot}%{_libdir}/gssproxy/proxymech.la +install -d -m755 %{buildroot}%{_sysconfdir}/gssproxy +install -m644 examples/gssproxy.conf %{buildroot}%{_sysconfdir}/gssproxy/gssproxy.conf +install -m644 examples/99-nfs-client.conf %{buildroot}%{_sysconfdir}/gssproxy/99-nfs-client.conf +mkdir -p %{buildroot}%{_sysconfdir}/gss/mech.d +install -m644 examples/mech %{buildroot}%{_sysconfdir}/gss/mech.d/gssproxy.conf +mkdir -p %{buildroot}%{gpstatedir}/rcache + + +%files +%license COPYING +%{_unitdir}/gssproxy.service +%{_sbindir}/gssproxy +%attr(755,root,root) %dir %{pubconfpath} +%attr(755,root,root) %dir %{gpstatedir} +%attr(700,root,root) %dir %{gpstatedir}/clients +%attr(700,root,root) %dir %{gpstatedir}/rcache +%attr(0600,root,root) %config(noreplace) /%{_sysconfdir}/gssproxy/gssproxy.conf +%attr(0600,root,root) %config(noreplace) /%{_sysconfdir}/gssproxy/99-nfs-client.conf +%attr(0644,root,root) %config(noreplace) /%{_sysconfdir}/gss/mech.d/gssproxy.conf +%dir %{_libdir}/gssproxy +%{_libdir}/gssproxy/proxymech.so +%{_mandir}/man5/gssproxy.conf.5* +%{_mandir}/man8/gssproxy.8* +%{_mandir}/man8/gssproxy-mech.8* + +%post +%systemd_post gssproxy.service + +%preun +%systemd_preun gssproxy.service + +%postun +%systemd_postun_with_restart gssproxy.service + +%changelog +* Mon Jul 04 2022 Julien Rische - 0.8.0-21 +- Fix handling of selinux context when NULL +- Resolves: rhbz#2061061 + +* Wed Nov 17 2021 Antonio Torres - 0.8.0-20 +- Add an option for minimum lifetime +- Resolves: #1721331 + +* Thu Oct 29 2020 Robbie Harwood - 0.8.0-19 +- More leak fixes +- Resolves: #1813200 + +* Wed Oct 14 2020 Robbie Harwood - 0.8.0-18 +- Fix leak of mech OID in gssi_inquire_context() +- Resolves: #1813200 + +* Tue Oct 13 2020 Robbie Harwood - 0.8.0-17 +- Document config file non-merging +- Resolves: #1838222 + +* Mon Apr 06 2020 Robbie Harwood - 0.8.0-16 +- Delay gssproxy start until after network.target +- Resolves: #1780876 + +* Thu Oct 31 2019 Robbie Harwood - 0.8.0-15 +- Make syslog of call status configurable +- Resolves: #1759665 + +* Mon May 13 2019 Robbie Harwood - 0.8.0-14 +- Fix explicit NULL deref around encrypted token processing +- Resolves: #1700539 + +* Fri May 03 2019 Robbie Harwood - 0.8.0-13 +- Update NFS service name in systemd unit +- Resolves: #1701820 + +* Wed May 01 2019 Robbie Harwood - 0.8.0-12 +- Avoid uninitialized free when allocating buffers +- Resolves: #1682281 + +* Fri Mar 22 2019 Robbie Harwood - 0.8.0-11 +- Fix race condition around epoll and socket release +- Resolves: #1690082 + +* Fri Mar 22 2019 Robbie Harwood - 0.8.0-10 +- Add a safety timeout to epoll +- Resolves: #1690082 + +* Wed Mar 20 2019 Robbie Harwood - 0.8.0-9 +- Bump to re-run gating +- Resolves: #1682281 + +* Tue Mar 19 2019 Robbie Harwood - 0.8.0-8 +- Bump to re-run gating +- Resolves: #1682281 + +* Mon Mar 18 2019 Robbie Harwood - 0.8.0-7 +- Use pthread keys for thread local storage +- Resolves: #1631564 + +* Wed Mar 13 2019 Robbie Harwood - 0.8.0-6 +- Add gating tests +- Resolves: #1682281 + +* Fri Jul 13 2018 Fedora Release Engineering - 0.8.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Apr 12 2018 Robbie Harwood - 0.8.0-4 +- Drop patch level by one (woo!) + +* Thu Apr 12 2018 Robbie Harwood - 0.8.0-3 +- Always choose highest requested debug level +- Update man pages about debugging + +* Tue Feb 27 2018 Robbie Harwood - 0.8.0-2 +- Always use the encype we selected + +* Fri Feb 09 2018 Robbie Harwood - 0.8.0-1 +- Release version 0.8.0 + +* Wed Feb 07 2018 Fedora Release Engineering - 0.7.0-30 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Dec 13 2017 Robbie Harwood - 0.7.0-29 +- Conditionally reload kernel interface on SIGHUP + +* Tue Dec 12 2017 Robbie Harwood - 0.7.0-28 +- Fixup previous + +* Tue Dec 12 2017 Robbie Harwood - 0.7.0-27 +- More code hygeine fixes from upstream +- Reorder patches to match el7 + +* Tue Dec 05 2017 Robbie Harwood - 0.7.0-26 +- Properly initialize ccaches before storing into them + +* Fri Dec 01 2017 Robbie Harwood - 0.7.0-25 +- Properly locate credentials in collection caches in mechglue + +* Tue Oct 31 2017 Robbie Harwood - 0.7.0-24 +- Only empty FILE ccaches when storing remote creds + +* Mon Oct 30 2017 Robbie Harwood - 0.7.0-23 +- Fix error message handling in gp_config_from_dir() + +* Fri Oct 27 2017 Robbie Harwood - 0.7.0-22 +- Fix concurrency issue in server socket handling + +* Mon Oct 02 2017 Robbie Harwood - 0.7.0-21 +- Off-by-one error fix in selinux-policy version + +* Mon Oct 02 2017 Robbie Harwood - 0.7.0-20 +- Change selinux-policy versioning to Conflicts + +* Fri Sep 29 2017 Robbie Harwood - 0.7.0-19 +- Add explicit selinux-policy dependency after some fixes + +* Fri Sep 29 2017 Robbie Harwood - 0.7.0-18 +- Fix silent death if config file has duplicate sections + +* Thu Sep 21 2017 Robbie Harwood - 0.7.0-17 +- Handle outdated encrypted ccaches + +* Fri Sep 15 2017 Robbie Harwood - 0.7.0-16 +- Backport updates to epoll logic + +* Tue Sep 12 2017 Robbie Harwood - 0.7.0-15 +- Backport two security fixes + +* Tue Aug 22 2017 Robbie Harwood - 0.7.0-14 +- Non-blocking IO + Extended request debug logging + +* Sun Aug 20 2017 Ville Skyttä - 0.7.0-13 +- Own the %%{_libdir}/gssproxy dir +- Mark COPYING as %%license + +* Mon Jul 31 2017 Robbie Harwood - 0.7.0-12 +- Add client ID to debug messages +- Move packaging to autosetup + +* Wed Jul 26 2017 Fedora Release Engineering - 0.7.0-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Jun 19 2017 Robbie Harwood - 0.7.0-10 + - Fix potential explicit NULL deref of program name + +* Thu May 25 2017 Robbie Harwood - 0.7.0-9 +- Make proc failure loud but nonfatal + +* Wed May 24 2017 Robbie Harwood - 0.7.0-8 +- Remove (buggy?) logic around NFS snippet. + +* Wed May 17 2017 Robbie Harwood - 0.7.0-7 +- Remove NFS server stanza if nfs-utils not present +- Also update gcc7 patch to match upstream + +* Tue May 16 2017 Robbie Harwood - 0.7.0-6 +- Fix segfault when no configuration files are found +- Various build fixes for gcc7 + +* Mon May 01 2017 Robbie Harwood - 0.7.0-5 +- Update systemd unit file (nfs removal, reload capability) + +* Mon Apr 03 2017 Robbie Harwood - 0.7.0-4 +- Backport fix for double unlock + +* Tue Mar 28 2017 Robbie Harwood - 0.7.0-3 +- Drop NFS server snippet (removes dependency on nfs kernel component) + +* Tue Mar 14 2017 Robbie Harwood - 0.7.0-2 +- Fix credential renewal and impersonator checking for m_a_g + +* Tue Mar 07 2017 Robbie Harwood - 0.7.0-1 +- New upstream release - 0.7.0 + +* Mon Mar 06 2017 Robbie Harwood - 0.6.2-4 +- Actually apply the patches I just added +- Also include a Coverity fix. + +* Tue Feb 28 2017 Robbie Harwood - 0.6.2-2 +- Include other non-null fix and various things from master + +* Thu Feb 23 2017 Robbie Harwood - 0.6.2-1 +- Fix incorrect use of non-null string in xdr +- Also move version number to better reflect what is inside + +* Fri Feb 10 2017 Fedora Release Engineering - 0.6.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Jan 23 2017 Robbie Harwood - 0.6.1-2 +- Fix allocation issue of cred store +- Resolves: #1415400 + +* Fri Jan 20 2017 Robbie Harwood - 0.6.1-1 +- New upstream release v0.6.1 +- Resolves: #1415090 + +* Wed Jan 18 2017 Robbie Harwood - 0.6.0-1 +- New upstream release v0.6.0 + +* Tue Sep 27 2016 Robbie Harwood - 0.5.1-3 +- Adjust libverto dependency to not use a specific backend +- Resolves: #1379812 + +* Tue Jun 14 2016 Robbie Harwood - 0.5.1-2 +- Own /var/lib/gssproxy/rcache + +* Mon Jun 13 2016 Robbie Harwood - 0.5.1-1 +- Update to upstream release v0.5.1 +- Resolves: #1345871 + +* Tue Jun 07 2016 Robbie Harwood - 0.5.0-5 +- Acquire new socket for fork/permission drops on clients + +* Mon May 09 2016 Robbie Harwood - 0.5.0-4 +- Do not package mod_auth_gssapi conf file + - This ensures gssproxy works even when the apache user does not exist + +* Thu May 05 2016 Robbie Harwood - 0.5.0-3 +- Ensure we actually package the config files + +* Thu May 05 2016 Simo Sorce - 0.5.0-2 +- Fix typo in requires + +* Wed May 04 2016 Robbie Harwood - 0.5.0-1 +- Release new upstream version +- Bump ini_config version for `ini_config_augment()` + +* Wed Feb 03 2016 Fedora Release Engineering - 0.4.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Dec 16 2015 Robbie Harwood - 0.4.1-4 +- Fix issues with 1.14 +- Fix bogus date in changelog (March 30 2015 was a Monday) + +* Wed Oct 21 2015 Robbie Harwood - 0.4.1-3 +- Clear message buffer to fix segfault on arm +- resolves: #1235902 + +* Wed Jun 17 2015 Fedora Release Engineering - 0.4.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon Mar 30 2015 Simo Sorce 0.4.1-1 +- New upstream release +- Fix issues with paths in config files + +* Tue Mar 24 2015 Simo Sorce 0.4.0-2 +- Workaround rawhide bug (bz1204646) with krb5-config by switching to + pkg-config (patch from upstream) + +* Tue Mar 24 2015 Simo Sorce 0.4.0-1 +- New upstream realease + Added optional support for running GSS-Proxy as an unprivileged user + Uses new /etc/gss/mech.d configuration directory for gss mechanisms + Kernel related fixes + General bug fixing, many minor errors or incorrect behaviours have been corrected +- drop all patches, they are all included upstream + +* Sat Aug 16 2014 Fedora Release Engineering - 0.3.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 0.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu May 29 2014 Simo Sorce 0.3.1-2 +- Rebuild as new ding-libs brings in soname bump + +* Thu Mar 13 2014 Guenther Deschner 0.3.1-1 +- Fix flags handling in gss_init_sec_context() +- resolves: https://fedorahosted.org/gss-proxy/ticket/112 +- Fix nfsd startup +- resolves: https://fedorahosted.org/gss-proxy/ticket/114 +- Fix potential mutex deadlock +- resolves: https://fedorahosted.org/gss-proxy/ticket/120 +- Fix segfault in gssi_inquire_context +- resolves: https://fedorahosted.org/gss-proxy/ticket/117 +- resolves: #1061133 + +* Tue Nov 26 2013 Guenther Deschner 0.3.1-0 +- New upstream release 0.3.1: + * Fix use of gssproxy for client initiation + * Add new enforcing and filtering options for context initialization + * Fix potential thread safety issues +- resolves: https://fedorahosted.org/gss-proxy/ticket/110 +- resolves: https://fedorahosted.org/gss-proxy/ticket/111 + +* Tue Nov 19 2013 Guenther Deschner 0.3.0-3 +- Fix flags handling in gss_init_sec_context() +- resolves: https://fedorahosted.org/gss-proxy/ticket/106 +- Fix OID handling in gss_inquire_cred_by_mech() +- resolves: https://fedorahosted.org/gss-proxy/ticket/107 +- Fix continuation processing for not yet fully established contexts. +- resolves: https://fedorahosted.org/gss-proxy/ticket/108 +- Add flags filtering and flags enforcing. +- resolves: https://fedorahosted.org/gss-proxy/ticket/109 + +* Wed Oct 23 2013 Guenther Deschner 0.3.0-0 +- New upstream release 0.3.0: + * Add support for impersonation (depends on s4u2self/s4u2proxy on the KDC) + * Add support for new rpc.gssd mode of operation that forks and changes uid + * Add 2 new options allow_any_uid and cred_usage + +* Fri Oct 18 2013 Guenther Deschner 0.2.3-8 +- Fix default proxymech documentation and fix LOCAL_FIRST implementation +- resolves: https://fedorahosted.org/gss-proxy/ticket/105 + +* Sat Aug 03 2013 Fedora Release Engineering - 0.2.3-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jul 24 2013 Guenther Deschner 0.2.3-6 +- Add better default gssproxy.conf file for nfs client and server usage + +* Thu Jun 06 2013 Guenther Deschner 0.2.3-5 +- New upstream release + +* Fri May 31 2013 Guenther Deschner 0.2.2-5 +- Require libverto-tevent to make sure libverto initialization succeeds + +* Wed May 29 2013 Guenther Deschner 0.2.2-4 +- Modify systemd unit files for nfs-secure services + +* Wed May 22 2013 Guenther Deschner 0.2.2-3 +- Fix cred_store handling w/o client keytab + +* Thu May 16 2013 Guenther Deschner 0.2.2-2 +- New upstream release + +* Tue May 07 2013 Guenther Deschner 0.2.1-2 +- New upstream release + +* Wed Apr 24 2013 Guenther Deschner 0.2.0-1 +- New upstream release + +* Mon Apr 01 2013 Simo Sorce - 0.1.0-0 +- New upstream release + +* Thu Feb 14 2013 Fedora Release Engineering - 0.0.3-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Nov 06 2012 Guenther Deschner 0.0.3-7 +- Update to 0.0.3 + +* Wed Aug 22 2012 Guenther Deschner 0.0.2-6 +- Use new systemd-rpm macros +- resolves: #850139 + +* Wed Jul 18 2012 Guenther Deschner 0.0.2-5 +- More spec file fixes + +* Mon Jul 16 2012 Guenther Deschner 0.0.2-4 +- Fix systemd service file + +* Fri Jul 13 2012 Guenther Deschner 0.0.2-3 +- Fix various packaging issues + +* Mon Jul 02 2012 Guenther Deschner 0.0.1-2 +- Add systemd packaging + +* Wed Mar 28 2012 Guenther Deschner 0.0.1-1 +- Various fixes + +* Mon Dec 12 2011 Simo Sorce - 0.0.2-0 +- Automated build of the gssproxy daemon