void Curl_http_ntlm_cleanup(struct connectdata *conn) { Curl_auth_ntlm_cleanup(&conn->ntlm); Curl_auth_ntlm_cleanup(&conn->proxyntlm); #if defined(NTLM_WB_ENABLED) Curl_ntlm_wb_cleanup(conn); #endif }
/* * Curl_auth_create_ntlm_type3_message() * Curl_auth_create_ntlm_type3_message() * * This is used to generate an already encoded NTLM type-3 message ready for * sending to the recipient. * * Parameters: * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. * passwdp [in] - The user's password. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, const char *userp, const char *passwdp, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { CURLcode result = CURLE_OK; SecBuffer type_2_buf; SecBuffer type_3_buf; SecBufferDesc type_2_desc; SecBufferDesc type_3_desc; SECURITY_STATUS status; unsigned long attrs; TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ (void) passwdp; (void) userp; /* Setup the type-2 "input" security buffer */ type_2_desc.ulVersion = SECBUFFER_VERSION; type_2_desc.cBuffers = 1; type_2_desc.pBuffers = &type_2_buf; type_2_buf.BufferType = SECBUFFER_TOKEN; type_2_buf.pvBuffer = ntlm->input_token; type_2_buf.cbBuffer = curlx_uztoul(ntlm->input_token_len); /* Setup the type-3 "output" security buffer */ type_3_desc.ulVersion = SECBUFFER_VERSION; type_3_desc.cBuffers = 1; type_3_desc.pBuffers = &type_3_buf; type_3_buf.BufferType = SECBUFFER_TOKEN; type_3_buf.pvBuffer = ntlm->output_token; type_3_buf.cbBuffer = curlx_uztoul(ntlm->token_max); /* Generate our type-3 message */ status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, ntlm->context, ntlm->spn, 0, 0, SECURITY_NETWORK_DREP, &type_2_desc, 0, ntlm->context, &type_3_desc, &attrs, &expiry); if(status != SEC_E_OK) { infof(data, "NTLM handshake failure (type-3 message): Status=%x\n", status); return CURLE_RECV_ERROR; } /* Base64 encode the response */ result = Curl_base64_encode(data, (char *) ntlm->output_token, type_3_buf.cbBuffer, outptr, outlen); Curl_auth_ntlm_cleanup(ntlm); return result; }
/* * Curl_sasl_cleanup() * * This is used to cleanup any libraries or curl modules used by the sasl * functions. * * Parameters: * * conn [in] - The connection data. * authused [in] - The authentication mechanism used. */ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) { #if defined(USE_KERBEROS5) /* Cleanup the gssapi structure */ if(authused == SASL_MECH_GSSAPI) { Curl_auth_gssapi_cleanup(&conn->krb5); } #endif #if defined(USE_NTLM) /* Cleanup the NTLM structure */ if(authused == SASL_MECH_NTLM) { Curl_auth_ntlm_cleanup(&conn->ntlm); } #endif #if !defined(USE_KERBEROS5) && !defined(USE_NTLM) /* Reserved for future use */ (void)conn; (void)authused; #endif }
/* * Curl_auth_create_ntlm_type1_message() * * This is used to generate an already encoded NTLM type-1 message ready for * sending to the recipient. * * Parameters: * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *userp, const char *passwdp, const char *service, const char *host, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { PSecPkgInfo SecurityPackage; SecBuffer type_1_buf; SecBufferDesc type_1_desc; SECURITY_STATUS status; unsigned long attrs; TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ /* Clean up any former leftovers and initialise to defaults */ Curl_auth_ntlm_cleanup(ntlm); /* Query the security package for NTLM */ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), &SecurityPackage); if(status != SEC_E_OK) return CURLE_NOT_BUILT_IN; ntlm->token_max = SecurityPackage->cbMaxToken; /* Release the package buffer as it is not required anymore */ s_pSecFn->FreeContextBuffer(SecurityPackage); /* Allocate our output buffer */ ntlm->output_token = malloc(ntlm->token_max); if(!ntlm->output_token) return CURLE_OUT_OF_MEMORY; if(userp && *userp) { CURLcode result; /* Populate our identity structure */ result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity); if(result) return result; /* Allow proper cleanup of the identity structure */ ntlm->p_identity = &ntlm->identity; } else /* Use the current Windows user */ ntlm->p_identity = NULL; /* Allocate our credentials handle */ ntlm->credentials = calloc(1, sizeof(CredHandle)); if(!ntlm->credentials) return CURLE_OUT_OF_MEMORY; /* Acquire our credentials handle */ status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_NTLM), SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity, NULL, NULL, ntlm->credentials, &expiry); if(status != SEC_E_OK) return CURLE_LOGIN_DENIED; /* Allocate our new context handle */ ntlm->context = calloc(1, sizeof(CtxtHandle)); if(!ntlm->context) return CURLE_OUT_OF_MEMORY; ntlm->spn = Curl_auth_build_spn(service, host, NULL); if(!ntlm->spn) return CURLE_OUT_OF_MEMORY; /* Setup the type-1 "output" security buffer */ type_1_desc.ulVersion = SECBUFFER_VERSION; type_1_desc.cBuffers = 1; type_1_desc.pBuffers = &type_1_buf; type_1_buf.BufferType = SECBUFFER_TOKEN; type_1_buf.pvBuffer = ntlm->output_token; type_1_buf.cbBuffer = curlx_uztoul(ntlm->token_max); /* Generate our type-1 message */ status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, ntlm->spn, 0, 0, SECURITY_NETWORK_DREP, NULL, 0, ntlm->context, &type_1_desc, &attrs, &expiry); if(status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) return CURLE_RECV_ERROR; /* Base64 encode the response */ return Curl_base64_encode(data, (char *) ntlm->output_token, type_1_buf.cbBuffer, outptr, outlen); }