/* * Curl_sasl_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] - Pointer to session handle. * userp [in] - The user name in the format User or Domain\User. * passdwp [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_sasl_create_ntlm_type3_message(struct SessionHandle *data, const char *userp, const char *passwdp, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { return Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, outptr, outlen); }
/* * Curl_sasl_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] - Pointer to session handle. * header [in] - Pointer to the base64 encoded type-2 message buffer. * userp [in] - The user name in the format User or Domain\User. * passdwp [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_sasl_create_ntlm_type3_message(struct SessionHandle *data, const char *header, const char *userp, const char *passwdp, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { CURLcode result = Curl_ntlm_decode_type2_message(data, header, ntlm); if(!result) result = Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, outptr, outlen); return result; }
/* for the NTLM type-2 response (sent in reponse to our type-1 message). */ static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; char *type3msg = NULL; size_t len = 0; (void)instate; /* no use for this yet */ if(smtpcode != 334) { failf(data, "Access denied: %d", smtpcode); result = CURLE_LOGIN_DENIED; } else { result = Curl_ntlm_decode_type2_message(data, data->state.buffer + 4, &conn->ntlm); if(!result) { result = Curl_ntlm_create_type3_message(conn->data, conn->user, conn->passwd, &conn->ntlm, &type3msg, &len); if(!result) { if(type3msg) { result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type3msg); if(!result) state(conn, SMTP_AUTH); } Curl_safefree(type3msg); } } } return result; }
/* * This is for creating ntlm header output */ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) { char *base64 = NULL; size_t len = 0; CURLcode error; /* point to the address of the pointer that holds the string to send to the server, which is for a plain host or for a HTTP proxy */ char **allocuserpwd; /* point to the name and password for this */ const char *userp; const char *passwdp; /* point to the correct struct with this */ struct ntlmdata *ntlm; struct auth *authp; DEBUGASSERT(conn); DEBUGASSERT(conn->data); #ifdef USE_NSS if(CURLE_OK != Curl_nss_force_init(conn->data)) return CURLE_OUT_OF_MEMORY; #endif if(proxy) { allocuserpwd = &conn->allocptr.proxyuserpwd; userp = conn->proxyuser; passwdp = conn->proxypasswd; ntlm = &conn->proxyntlm; authp = &conn->data->state.authproxy; } else { allocuserpwd = &conn->allocptr.userpwd; userp = conn->user; passwdp = conn->passwd; ntlm = &conn->ntlm; authp = &conn->data->state.authhost; } authp->done = FALSE; /* not set means empty */ if(!userp) userp = ""; if(!passwdp) passwdp = ""; #ifdef USE_WINDOWS_SSPI if(s_hSecDll == NULL) { /* not thread safe and leaks - use curl_global_init() to avoid */ CURLcode err = Curl_sspi_global_init(); if(s_hSecDll == NULL) return err; } #endif switch(ntlm->state) { case NTLMSTATE_TYPE1: default: /* for the weird cases we (re)start here */ /* Create a type-1 message */ error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64, &len); if(error) return error; if(base64) { Curl_safefree(*allocuserpwd); *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", proxy ? "Proxy-" : "", base64); free(base64); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); } break; case NTLMSTATE_TYPE2: /* We already received the type-2 message, create a type-3 message */ error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp, ntlm, &base64, &len); if(error) return error; if(base64) { Curl_safefree(*allocuserpwd); *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", proxy ? "Proxy-" : "", base64); free(base64); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */ authp->done = TRUE; } break; case NTLMSTATE_TYPE3: /* connection is already authenticated, * don't send a header in future requests */ Curl_safefree(*allocuserpwd); authp->done = TRUE; break; } return CURLE_OK; }