mirror of
https://github.com/curl/curl.git
synced 2026-05-06 11:37:28 +03:00
Merge 0267a63dc0 into 188c2f166a
This commit is contained in:
commit
8917c9566b
21 changed files with 373 additions and 26 deletions
|
|
@ -434,6 +434,8 @@ option(CURL_DISABLE_KERBEROS_AUTH "Disable Kerberos authentication" OFF)
|
|||
mark_as_advanced(CURL_DISABLE_KERBEROS_AUTH)
|
||||
option(CURL_DISABLE_NEGOTIATE_AUTH "Disable negotiate authentication" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_NEGOTIATE_AUTH)
|
||||
option(CURL_DISABLE_NEGOTIATE_NTLM "Block NTLM within SPNEGO negotiation" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_NEGOTIATE_NTLM)
|
||||
option(CURL_DISABLE_AWS "Disable aws-sigv4" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_AWS)
|
||||
option(CURL_DISABLE_DICT "Disable DICT" OFF)
|
||||
|
|
@ -1339,6 +1341,11 @@ if(CURL_USE_GSSAPI)
|
|||
elseif(GSS_VERSION) # MIT
|
||||
set(CURL_KRB5_VERSION "\"${GSS_VERSION}\"")
|
||||
endif()
|
||||
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::gss)
|
||||
check_function_exists("gss_set_neg_mechs" HAVE_GSS_SET_NEG_MECHS)
|
||||
cmake_pop_check_state()
|
||||
else()
|
||||
message(WARNING "GSSAPI has been requested, but no supporting libraries found. Skipping.")
|
||||
endif()
|
||||
|
|
|
|||
21
configure.ac
21
configure.ac
|
|
@ -2016,6 +2016,7 @@ if test "$want_gss" = "yes"; then
|
|||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([--with-gssapi was specified, but a GSS-API library was not found.])
|
||||
])
|
||||
AC_CHECK_FUNCS([gss_set_neg_mechs])
|
||||
fi
|
||||
|
||||
build_libstubgss=no
|
||||
|
|
@ -4459,6 +4460,26 @@ AS_HELP_STRING([--disable-negotiate-auth],[Disable negotiate authentication]),
|
|||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
dnl ************************************************************
|
||||
dnl disable NTLM within SPNEGO negotiation
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to allow NTLM within SPNEGO])
|
||||
AC_ARG_ENABLE(negotiate-ntlm,
|
||||
AS_HELP_STRING([--enable-negotiate-ntlm],[Allow NTLM within SPNEGO (default)])
|
||||
AS_HELP_STRING([--disable-negotiate-ntlm],[Block NTLM within SPNEGO]),
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_NEGOTIATE_NTLM, 1, [to block NTLM within SPNEGO])
|
||||
CURL_DISABLE_NEGOTIATE_NTLM=1
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(yes)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
dnl ************************************************************
|
||||
dnl disable aws
|
||||
dnl
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ Disable support for the Kerberos authentication methods.
|
|||
|
||||
Disable support for the negotiate authentication methods.
|
||||
|
||||
## `CURL_DISABLE_NEGOTIATE_NTLM`
|
||||
|
||||
Block NTLM authentication within SPNEGO negotiation.
|
||||
|
||||
## `CURL_DISABLE_AWS`
|
||||
|
||||
Disable **aws-sigv4** support.
|
||||
|
|
|
|||
|
|
@ -312,6 +312,12 @@ libcurl ignore cookies with a domain that is on the list.
|
|||
libcurl was built with support for SPNEGO authentication (Simple and Protected
|
||||
GSS-API Negotiation Mechanism, defined in RFC 2478.)
|
||||
|
||||
## `SPNEGO-no-NTLM`
|
||||
|
||||
*features* mask bit: none
|
||||
|
||||
NTLM authentication is blocked within SPNEGO negotiation.
|
||||
|
||||
## `SSL`
|
||||
|
||||
*features* mask bit: CURL_VERSION_SSL
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
/* disables negotiate authentication */
|
||||
#cmakedefine CURL_DISABLE_NEGOTIATE_AUTH 1
|
||||
|
||||
/* blocks NTLM within SPNEGO negotiation */
|
||||
#cmakedefine CURL_DISABLE_NEGOTIATE_NTLM 1
|
||||
|
||||
/* disables aws-sigv4 */
|
||||
#cmakedefine CURL_DISABLE_AWS 1
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ enum min_err_code {
|
|||
|
||||
/* libcurl is also passing this struct to these functions, which are not yet
|
||||
* stubbed:
|
||||
* gss_inquire_context()
|
||||
* gss_unwrap()
|
||||
* gss_wrap()
|
||||
*/
|
||||
|
|
@ -308,6 +307,48 @@ static OM_uint32 stub_gss_delete_sec_context(
|
|||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
/* NTLMSSP OID: 1.3.6.1.4.1.311.2.2.10 */
|
||||
static gss_OID_desc stub_ntlmssp_oid = {
|
||||
10, CURL_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a")
|
||||
};
|
||||
|
||||
static OM_uint32
|
||||
stub_gss_inquire_context(OM_uint32 *min,
|
||||
struct stub_gss_ctx_id_t_desc *context,
|
||||
gss_name_t *src_name,
|
||||
gss_name_t *targ_name,
|
||||
OM_uint32 *lifetime_rec,
|
||||
gss_OID *mech_type,
|
||||
OM_uint32 *ctx_flags,
|
||||
int *locally_initiated,
|
||||
int *open_context)
|
||||
{
|
||||
(void)src_name;
|
||||
(void)targ_name;
|
||||
(void)lifetime_rec;
|
||||
(void)ctx_flags;
|
||||
(void)locally_initiated;
|
||||
(void)open_context;
|
||||
|
||||
if(!min)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
if(!context) {
|
||||
*min = STUB_GSS_INVALID_CTX;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
*min = 0;
|
||||
if(mech_type) {
|
||||
if(context->have_ntlm && !context->have_krb5)
|
||||
*mech_type = &stub_ntlmssp_oid;
|
||||
else
|
||||
*mech_type = (gss_OID)&Curl_krb5_mech_oid;
|
||||
}
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
|
|
@ -319,7 +360,8 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
|||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
const bool mutual_auth,
|
||||
OM_uint32 *ret_flags)
|
||||
OM_uint32 *ret_flags,
|
||||
gss_cred_id_t cred_handle)
|
||||
{
|
||||
OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
|
||||
|
||||
|
|
@ -341,7 +383,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
|||
#ifdef CURL_GSS_STUB
|
||||
if(getenv("CURL_STUB_GSS_CREDS"))
|
||||
return stub_gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
cred_handle,
|
||||
(struct stub_gss_ctx_id_t_desc **)context,
|
||||
target_name,
|
||||
mech_type,
|
||||
|
|
@ -356,7 +398,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
|||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
return gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
cred_handle,
|
||||
context,
|
||||
target_name,
|
||||
mech_type,
|
||||
|
|
@ -384,6 +426,23 @@ OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
|||
return gss_delete_sec_context(min, context, output_token);
|
||||
}
|
||||
|
||||
OM_uint32 Curl_gss_inquire_context(OM_uint32 *minor_status,
|
||||
gss_ctx_id_t context,
|
||||
gss_OID *mech_type)
|
||||
{
|
||||
#ifdef CURL_GSS_STUB
|
||||
if(getenv("CURL_STUB_GSS_CREDS"))
|
||||
return stub_gss_inquire_context(minor_status,
|
||||
(struct stub_gss_ctx_id_t_desc *)context,
|
||||
NULL, NULL, NULL, mech_type,
|
||||
NULL, NULL, NULL);
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
return gss_inquire_context(minor_status, context,
|
||||
NULL, NULL, NULL, mech_type,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef CURLVERBOSE
|
||||
#define GSS_LOG_BUFFER_LEN 1024
|
||||
static size_t display_gss_error(OM_uint32 status, int type,
|
||||
|
|
|
|||
|
|
@ -41,12 +41,17 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
|||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
const bool mutual_auth,
|
||||
OM_uint32 *ret_flags);
|
||||
OM_uint32 *ret_flags,
|
||||
gss_cred_id_t cred_handle);
|
||||
|
||||
OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
||||
gss_ctx_id_t *context,
|
||||
gss_buffer_t output_token);
|
||||
|
||||
OM_uint32 Curl_gss_inquire_context(OM_uint32 *minor_status,
|
||||
gss_ctx_id_t context,
|
||||
gss_OID *mech_type);
|
||||
|
||||
#ifdef CURLVERBOSE
|
||||
/* Helper to log a GSS-API error status */
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ void Curl_sspi_global_cleanup(void)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *identity)
|
||||
{
|
||||
xcharp_u useranddomain;
|
||||
xcharp_u user, dup_user;
|
||||
|
|
@ -105,6 +105,8 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
|||
|
||||
/* Initialize the identity */
|
||||
memset(identity, 0, sizeof(*identity));
|
||||
identity->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
|
||||
identity->Length = sizeof(*identity);
|
||||
|
||||
useranddomain.tchar_ptr = curlx_convert_UTF8_to_tchar(userp);
|
||||
if(!useranddomain.tchar_ptr)
|
||||
|
|
@ -195,7 +197,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
|||
*
|
||||
* identity [in/out] - The identity structure.
|
||||
*/
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY_EX *identity)
|
||||
{
|
||||
if(identity) {
|
||||
curlx_safefree(identity->User);
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ void Curl_sspi_global_cleanup(void);
|
|||
|
||||
/* This is used to populate the domain in an SSPI identity structure */
|
||||
CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *identity);
|
||||
|
||||
/* This is used to generate an SSPI identity structure */
|
||||
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *identity);
|
||||
|
||||
/* This is used to free an SSPI identity structure */
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY_EX *identity);
|
||||
|
||||
/* Forward-declaration of global variables defined in curl_sspi.c */
|
||||
extern PSecurityFunctionTable Curl_pSecFn;
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ static ULONG ldap_win_bind_auth(LDAP *server, const char *user,
|
|||
const char *passwd, unsigned long authflags)
|
||||
{
|
||||
ULONG method = 0;
|
||||
SEC_WINNT_AUTH_IDENTITY cred;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX cred;
|
||||
ULONG rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
|
||||
|
||||
memset(&cred, 0, sizeof(cred));
|
||||
|
|
|
|||
|
|
@ -180,7 +180,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf,
|
|||
gss_token,
|
||||
&gss_send_token,
|
||||
TRUE,
|
||||
&gss_ret_flags);
|
||||
&gss_ret_flags,
|
||||
GSS_C_NO_CREDENTIAL);
|
||||
|
||||
if(gss_token != GSS_C_NO_BUFFER) {
|
||||
curlx_safefree(gss_recv_token.value);
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
|||
CredHandle credentials;
|
||||
CtxtHandle context;
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *p_identity;
|
||||
SecBuffer chlg_buf;
|
||||
SecBuffer resp_buf;
|
||||
SecBufferDesc chlg_desc;
|
||||
|
|
@ -240,7 +240,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *identity)
|
||||
{
|
||||
xcharp_u domain, dup_domain;
|
||||
|
||||
|
|
@ -466,8 +466,8 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
|||
|
||||
if(!digest->http_context) {
|
||||
CredHandle credentials;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *p_identity;
|
||||
SecBuffer resp_buf;
|
||||
SecBufferDesc resp_desc;
|
||||
unsigned long attrs;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
|||
&input_token,
|
||||
&output_token,
|
||||
mutual_auth,
|
||||
NULL);
|
||||
NULL,
|
||||
GSS_C_NO_CREDENTIAL);
|
||||
|
||||
if(GSS_ERROR(major_status)) {
|
||||
if(output_token.value)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Curl_auth_is_spnego_supported()
|
||||
*
|
||||
|
|
@ -158,6 +159,54 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSS_SET_NEG_MECHS
|
||||
#ifdef CURL_DISABLE_NEGOTIATE_NTLM
|
||||
/* Acquire explicit credentials and restrict SPNEGO sub-mechanisms to
|
||||
* exclude NTLM. We enumerate all available mechanisms and filter out
|
||||
* the NTLMSSP OID, matching SSPI's "!ntlm". */
|
||||
if(nego->cred == GSS_C_NO_CREDENTIAL) {
|
||||
/* OID 1.3.6.1.4.1.311.2.2.10 (NTLMSSP) */
|
||||
static const gss_OID_desc ntlmssp_oid = {
|
||||
10, CURL_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a")
|
||||
};
|
||||
gss_OID_set available_mechs = GSS_C_NO_OID_SET;
|
||||
gss_OID_set filtered_mechs = GSS_C_NO_OID_SET;
|
||||
|
||||
/* Acquire default credentials for SPNEGO */
|
||||
major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME,
|
||||
GSS_C_INDEFINITE, GSS_C_NO_OID_SET,
|
||||
GSS_C_INITIATE, &nego->cred, NULL, NULL);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_log_error(data, "gss_acquire_cred() failed: ",
|
||||
major_status, minor_status);
|
||||
Curl_safefree(input_token.value);
|
||||
return CURLE_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* Get all available mechanisms */
|
||||
major_status = gss_indicate_mechs(&minor_status, &available_mechs);
|
||||
if(!GSS_ERROR(major_status)) {
|
||||
/* Build a set excluding NTLMSSP */
|
||||
major_status = gss_create_empty_oid_set(&minor_status, &filtered_mechs);
|
||||
if(!GSS_ERROR(major_status)) {
|
||||
size_t i;
|
||||
for(i = 0; i < available_mechs->count; i++) {
|
||||
gss_OID oid = &available_mechs->elements[i];
|
||||
if(oid->length != ntlmssp_oid.length ||
|
||||
memcmp(oid->elements, ntlmssp_oid.elements, oid->length)) {
|
||||
gss_add_oid_set_member(&minor_status, oid, &filtered_mechs);
|
||||
}
|
||||
}
|
||||
/* Restrict SPNEGO to only use non-NTLM mechanisms */
|
||||
gss_set_neg_mechs(&minor_status, nego->cred, filtered_mechs);
|
||||
gss_release_oid_set(&minor_status, &filtered_mechs);
|
||||
}
|
||||
gss_release_oid_set(&minor_status, &available_mechs);
|
||||
}
|
||||
}
|
||||
#endif /* CURL_DISABLE_NEGOTIATE_NTLM */
|
||||
#endif /* HAVE_GSS_SET_NEG_MECHS */
|
||||
|
||||
/* Generate our challenge-response message */
|
||||
major_status = Curl_gss_init_sec_context(data,
|
||||
&minor_status,
|
||||
|
|
@ -168,7 +217,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
&input_token,
|
||||
&output_token,
|
||||
TRUE,
|
||||
NULL);
|
||||
NULL,
|
||||
nego->cred);
|
||||
|
||||
/* Free the decoded challenge as it is not required anymore */
|
||||
curlx_safefree(input_token.value);
|
||||
|
|
@ -191,6 +241,31 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
return CURLE_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* Check if NTLM was selected and is disallowed */
|
||||
#ifdef CURL_DISABLE_NEGOTIATE_NTLM
|
||||
if(nego->context != GSS_C_NO_CONTEXT) {
|
||||
/* OID 1.3.6.1.4.1.311.2.2.10 (NTLMSSP) */
|
||||
static const gss_OID_desc ntlmssp_oid = {
|
||||
10, CURL_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a")
|
||||
};
|
||||
OM_uint32 inquire_major, inquire_minor;
|
||||
gss_OID mech_type = GSS_C_NO_OID;
|
||||
|
||||
inquire_major = Curl_gss_inquire_context(&inquire_minor,
|
||||
nego->context,
|
||||
&mech_type);
|
||||
if(!GSS_ERROR(inquire_major) && mech_type &&
|
||||
mech_type->length == ntlmssp_oid.length &&
|
||||
!memcmp(mech_type->elements, ntlmssp_oid.elements,
|
||||
ntlmssp_oid.length)) {
|
||||
infof(data, "SPNEGO chose NTLM, but NTLM is not allowed");
|
||||
gss_release_buffer(&unused_status, &output_token);
|
||||
Curl_auth_cleanup_spnego(nego);
|
||||
return CURLE_AUTH_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* CURL_DISABLE_NEGOTIATE_NTLM */
|
||||
|
||||
/* Free previous token */
|
||||
if(nego->output_token.length && nego->output_token.value)
|
||||
gss_release_buffer(&unused_status, &nego->output_token);
|
||||
|
|
@ -280,6 +355,12 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego)
|
|||
nego->spn = GSS_C_NO_NAME;
|
||||
}
|
||||
|
||||
/* Free our credentials */
|
||||
if(nego->cred != GSS_C_NO_CREDENTIAL) {
|
||||
gss_release_cred(&minor_status, &nego->cred);
|
||||
nego->cred = GSS_C_NO_CREDENTIAL;
|
||||
}
|
||||
|
||||
/* Reset any variables */
|
||||
nego->status = 0;
|
||||
nego->noauthpersist = FALSE;
|
||||
|
|
|
|||
|
|
@ -146,6 +146,29 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
/* Use the current Windows user */
|
||||
nego->p_identity = NULL;
|
||||
|
||||
#ifdef CURL_DISABLE_NEGOTIATE_NTLM
|
||||
/* Exclude NTLM from SPNEGO negotiation via the PackageList field */
|
||||
if(!nego->p_identity) {
|
||||
memset(&nego->identity, 0, sizeof(nego->identity));
|
||||
nego->identity.Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
|
||||
nego->identity.Length = sizeof(nego->identity);
|
||||
nego->identity.Flags =
|
||||
#ifdef UNICODE
|
||||
SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
#else
|
||||
SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
#endif
|
||||
nego->p_identity = &nego->identity;
|
||||
}
|
||||
|
||||
/* Use the special name "!ntlm" to prevent NTLM from being used:
|
||||
* https://learn.microsoft.com/en-us/windows/win32/api/sspi/ns-sspi-sec_winnt_auth_identity_exa
|
||||
*/
|
||||
nego->identity.PackageList =
|
||||
(unsigned TCHAR *)CURL_UNCONST(TEXT("!ntlm"));
|
||||
nego->identity.PackageListLength = 5;
|
||||
#endif /* CURL_DISABLE_NEGOTIATE_NTLM */
|
||||
|
||||
/* Allocate our credentials handle */
|
||||
nego->credentials = curlx_calloc(1, sizeof(CredHandle));
|
||||
if(!nego->credentials)
|
||||
|
|
|
|||
|
|
@ -170,8 +170,8 @@ struct ntlmdata {
|
|||
#endif
|
||||
CredHandle *credentials;
|
||||
CtxtHandle *context;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *p_identity;
|
||||
size_t token_max;
|
||||
BYTE *output_token;
|
||||
BYTE *input_token;
|
||||
|
|
@ -241,8 +241,8 @@ struct kerberos5data {
|
|||
CredHandle *credentials;
|
||||
CtxtHandle *context;
|
||||
TCHAR *spn;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *p_identity;
|
||||
size_t token_max;
|
||||
BYTE *output_token;
|
||||
#else
|
||||
|
|
@ -297,6 +297,7 @@ struct negotiatedata {
|
|||
OM_uint32 status;
|
||||
gss_ctx_id_t context;
|
||||
gss_name_t spn;
|
||||
gss_cred_id_t cred;
|
||||
gss_buffer_desc output_token;
|
||||
#ifdef GSS_C_CHANNEL_BOUND_FLAG
|
||||
struct dynbuf channel_binding_data;
|
||||
|
|
@ -309,8 +310,8 @@ struct negotiatedata {
|
|||
SECURITY_STATUS status;
|
||||
CredHandle *credentials;
|
||||
CtxtHandle *context;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX identity;
|
||||
SEC_WINNT_AUTH_IDENTITY_EX *p_identity;
|
||||
TCHAR *spn;
|
||||
size_t token_max;
|
||||
BYTE *output_token;
|
||||
|
|
|
|||
|
|
@ -503,6 +503,9 @@ static const struct feat features_table[] = {
|
|||
#endif /* USE_SSL */
|
||||
#ifdef USE_SPNEGO
|
||||
FEATURE("SPNEGO", NULL, CURL_VERSION_SPNEGO),
|
||||
#ifdef CURL_DISABLE_NEGOTIATE_NTLM
|
||||
FEATURE("SPNEGO-no-NTLM", NULL, 0),
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
FEATURE("SSL", NULL, CURL_VERSION_SSL),
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
|
|||
test2064 test2065 test2066 test2067 test2068 test2069 test2070 test2071 \
|
||||
test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 \
|
||||
test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 \
|
||||
test2088 test2089 test2090 test2091 \
|
||||
test2088 test2089 test2090 test2091 test2092 test2093 \
|
||||
test2100 test2101 test2102 test2103 test2104 \
|
||||
\
|
||||
test2200 test2201 test2202 test2203 test2204 test2205 \
|
||||
|
|
|
|||
59
tests/data/test2092
Normal file
59
tests/data/test2092
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
HTTP Negotiate auth (stub ntlm)
|
||||
SPNEGO NTLM disallowed
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<data nocheck="yes" crlf="headers">
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Content-Length: 23
|
||||
|
||||
This IS the real page!
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
SPNEGO skips auth when NTLM blocked by CURL_DISABLE_NEGOTIATE_NTLM
|
||||
</name>
|
||||
<features>
|
||||
GSS-API
|
||||
Debug
|
||||
negotiate-ntlm-disabled
|
||||
</features>
|
||||
<setenv>
|
||||
CURL_STUB_GSS_CREDS="NTLM_Alice"
|
||||
</setenv>
|
||||
<command>
|
||||
--negotiate http://%HOSTIP:%HTTPPORT/%TESTNUMBER
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<errorcode>
|
||||
0
|
||||
</errorcode>
|
||||
# When NTLM is the only available mechanism and is blocked,
|
||||
# negotiate auth silently fails and the request is sent without
|
||||
# any Authorization header.
|
||||
<protocol crlf="headers">
|
||||
GET /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
69
tests/data/test2093
Normal file
69
tests/data/test2093
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
HTTP Negotiate auth (stub krb5)
|
||||
SPNEGO NTLM disallowed
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<data1>
|
||||
HTTP/1.1 200 Things are fine in server land
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
WWW-Authenticate: Negotiate RA==
|
||||
Content-Length: 15
|
||||
|
||||
Nice auth sir!
|
||||
</data1>
|
||||
<datacheck>
|
||||
HTTP/1.1 200 Things are fine in server land
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
WWW-Authenticate: Negotiate RA==
|
||||
Content-Length: 15
|
||||
|
||||
Nice auth sir!
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
SPNEGO with Kerberos still works when built with CURL_DISABLE_NEGOTIATE_NTLM
|
||||
</name>
|
||||
<features>
|
||||
GSS-API
|
||||
Debug
|
||||
negotiate-ntlm-disabled
|
||||
</features>
|
||||
<setenv>
|
||||
CURL_STUB_GSS_CREDS="KRB5_Alice"
|
||||
</setenv>
|
||||
<command>
|
||||
--negotiate http://%HOSTIP:%HTTPPORT/%TESTNUMBER
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<errorcode>
|
||||
0
|
||||
</errorcode>
|
||||
<protocol crlf="headers">
|
||||
GET /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Authorization: Negotiate %b64["KRB5_Alice":HTTP@127.0.0.1:1:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA]b64%
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
|
@ -694,6 +694,8 @@ sub checksystemfeatures {
|
|||
$feature{"Kerberos"} = $feat =~ /Kerberos/i;
|
||||
# SPNEGO enabled
|
||||
$feature{"SPNEGO"} = $feat =~ /SPNEGO/i;
|
||||
# SPNEGO NTLM disabled (compile-time)
|
||||
$feature{"negotiate-ntlm-disabled"} = $feat =~ /SPNEGO-no-NTLM/i;
|
||||
# TLS-SRP enabled
|
||||
$feature{"TLS-SRP"} = $feat =~ /TLS-SRP/i;
|
||||
# PSL enabled
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue