mirror of
https://github.com/curl/curl.git
synced 2026-08-24 18:33:34 +03:00
gssapi: make channel binding conditional on GSS_C_CHANNEL_BOUND_FLAG
Fixes #19109 - GSSAPI authentication fails on macOS with Apple's Heimdal
implementation which lacks GSS_C_CHANNEL_BOUND_FLAG support for TLS
channel binding.
Commit 0a5ea09a91 introduced TLS channel binding for SPNEGO/GSSAPI
authentication unconditionally, but Apple's Heimdal fork (used on macOS)
does not support this feature, causing "unsupported mechanism" errors
when authenticating to corporate HTTP services with Kerberos.
Solution:
- Add CURL_GSSAPI_HAS_CHANNEL_BINDING detection in curl_gssapi.h based
on GSS_C_CHANNEL_BOUND_FLAG presence (MIT Kerberos >= 1.19)
- Make negotiatedata.channel_binding_data field conditional in vauth.h
- Guard channel binding collection/cleanup in http_negotiate.c
- Guard channel binding usage in spnego_gssapi.c
This follows the same pattern as GSS_C_DELEG_POLICY_FLAG detection and
ensures graceful degradation when channel binding is unavailable while
maintaining full support for implementations that have it.
Changes:
- lib/curl_gssapi.h: Add feature detection macro
- lib/vauth/vauth.h: Make struct field conditional
- lib/http_negotiate.c: Conditional init/cleanup (2 locations)
- lib/vauth/spnego_gssapi.c: Conditional channel binding usage
Tested on macOS with Apple Heimdal (no channel binding) and Linux with
MIT Kerberos (with channel binding). Both configurations authenticate
successfully without errors.
Closes #19164
This commit is contained in:
parent
cccc65f051
commit
8616e5aada
4 changed files with 14 additions and 3 deletions
|
|
@ -28,6 +28,11 @@
|
|||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#ifdef GSS_C_CHANNEL_BOUND_FLAG /* MIT Kerberos 1.19+, missing from GNU GSS */
|
||||
#define CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
#endif
|
||||
|
||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
neg_ctx->sslContext = conn->sslContext;
|
||||
#endif
|
||||
/* Check if the connection is using SSL and get the channel binding data */
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
#ifdef USE_SSL
|
||||
curlx_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE + 1);
|
||||
if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
|
||||
|
|
@ -138,13 +138,13 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
#else
|
||||
curlx_dyn_init(&neg_ctx->channel_binding_data, 1);
|
||||
#endif /* USE_SSL */
|
||||
#endif /* HAVE_GSSAPI */
|
||||
#endif /* CURL_GSSAPI_HAS_CHANNEL_BINDING */
|
||||
|
||||
/* Initialize the security context and decode our challenge */
|
||||
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
|
||||
host, header, neg_ctx);
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
curlx_dyn_free(&neg_ctx->channel_binding_data);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,9 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_channel_bindings_t chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
|
||||
#ifdef CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
struct gss_channel_bindings_struct chan;
|
||||
#endif
|
||||
|
||||
(void)user;
|
||||
(void)password;
|
||||
|
|
@ -157,12 +159,14 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
/* Set channel binding data if available */
|
||||
#ifdef CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
if(curlx_dyn_len(&nego->channel_binding_data)) {
|
||||
memset(&chan, 0, sizeof(struct gss_channel_bindings_struct));
|
||||
chan.application_data.length = curlx_dyn_len(&nego->channel_binding_data);
|
||||
chan.application_data.value = curlx_dyn_ptr(&nego->channel_binding_data);
|
||||
chan_bindings = &chan;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Generate our challenge-response message */
|
||||
major_status = Curl_gss_init_sec_context(data,
|
||||
|
|
|
|||
|
|
@ -306,7 +306,9 @@ struct negotiatedata {
|
|||
gss_ctx_id_t context;
|
||||
gss_name_t spn;
|
||||
gss_buffer_desc output_token;
|
||||
#ifdef CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
struct dynbuf channel_binding_data;
|
||||
#endif
|
||||
#else
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue