27 #if defined(USE_WINDOWS_SSPI) && defined(USE_SPNEGO) 52 bool Curl_auth_is_spnego_supported(
void)
54 PSecPkgInfo SecurityPackage;
55 SECURITY_STATUS status;
58 status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
59 TEXT(SP_NAME_NEGOTIATE),
62 return (status == SEC_E_OK ?
TRUE :
FALSE);
89 struct negotiatedata *nego)
93 unsigned char *chlg = NULL;
94 PSecPkgInfo SecurityPackage;
97 SecBufferDesc chlg_desc;
98 SecBufferDesc resp_desc;
102 #if defined(CURL_DISABLE_VERBOSE_STRINGS) 106 if(nego->context && nego->status == SEC_E_OK) {
110 Curl_auth_spnego_cleanup(nego);
121 if(!nego->output_token) {
123 nego->status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
124 TEXT(SP_NAME_NEGOTIATE),
126 if(nego->status != SEC_E_OK)
129 nego->token_max = SecurityPackage->cbMaxToken;
132 s_pSecFn->FreeContextBuffer(SecurityPackage);
135 nego->output_token =
malloc(nego->token_max);
136 if(!nego->output_token)
140 if(!nego->credentials) {
144 result = Curl_create_sspi_identity(user, password, &nego->identity);
149 nego->p_identity = &nego->identity;
153 nego->p_identity = NULL;
156 nego->credentials =
malloc(
sizeof(CredHandle));
157 if(!nego->credentials)
160 memset(nego->credentials, 0,
sizeof(CredHandle));
164 s_pSecFn->AcquireCredentialsHandle(NULL,
165 (TCHAR *)TEXT(SP_NAME_NEGOTIATE),
166 SECPKG_CRED_OUTBOUND, NULL,
167 nego->p_identity, NULL, NULL,
168 nego->credentials, &expiry);
169 if(nego->status != SEC_E_OK)
173 nego->context =
malloc(
sizeof(CtxtHandle));
177 memset(nego->context, 0,
sizeof(CtxtHandle));
180 if(chlg64 && *chlg64) {
190 infof(data,
"SPNEGO handshake failure (empty challenge message)\n");
196 chlg_desc.ulVersion = SECBUFFER_VERSION;
197 chlg_desc.cBuffers = 1;
198 chlg_desc.pBuffers = &chlg_buf;
199 chlg_buf.BufferType = SECBUFFER_TOKEN;
200 chlg_buf.pvBuffer = chlg;
205 resp_desc.ulVersion = SECBUFFER_VERSION;
206 resp_desc.cBuffers = 1;
207 resp_desc.pBuffers = &resp_buf;
208 resp_buf.BufferType = SECBUFFER_TOKEN;
209 resp_buf.pvBuffer = nego->output_token;
213 nego->status = s_pSecFn->InitializeSecurityContext(nego->credentials,
214 chlg ? nego->context :
217 ISC_REQ_CONFIDENTIALITY,
218 0, SECURITY_NATIVE_DREP,
219 chlg ? &chlg_desc : NULL,
228 failf(data,
"InitializeSecurityContext failed: %s",
229 Curl_sspi_strerror(data->
easy_conn, nego->status));
233 if(nego->status == SEC_I_COMPLETE_NEEDED ||
234 nego->status == SEC_I_COMPLETE_AND_CONTINUE) {
235 nego->status = s_pSecFn->CompleteAuthToken(nego->context, &resp_desc);
241 nego->output_token_length = resp_buf.cbBuffer;
263 struct negotiatedata *nego,
264 char **outptr,
size_t *outlen)
270 (
const char *) nego->output_token,
271 nego->output_token_length,
277 if(!*outptr || !*outlen) {
295 void Curl_auth_spnego_cleanup(
struct negotiatedata *nego)
299 s_pSecFn->DeleteSecurityContext(nego->context);
301 nego->context = NULL;
305 if(nego->credentials) {
306 s_pSecFn->FreeCredentialsHandle(nego->credentials);
307 free(nego->credentials);
308 nego->credentials = NULL;
312 Curl_sspi_free_identity(nego->p_identity);
313 nego->p_identity = NULL;
CURLcode Curl_base64_decode(const char *src, unsigned char **outptr, size_t *outlen)
CURLcode Curl_base64_encode(struct Curl_easy *data, const char *inputbuff, size_t insize, char **outptr, size_t *outlen)
UNITTEST_START int result
struct connectdata * easy_conn
unsigned long curlx_uztoul(size_t uznum)
#define GSS_ERROR(status)
#define Curl_safefree(ptr)
char * Curl_auth_build_spn(const char *service, const char *host, const char *realm)