#include "curl_setup.h"
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
#include "urldata.h"
#include "sendf.h"
#include "http_negotiate.h"
#include "vauth/vauth.h"
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
const char *header)
{
CURLcode result;
struct Curl_easy *data = conn->data;
size_t len;
const char *userp;
const char *passwdp;
const char *service;
const char *host;
struct negotiatedata *neg_ctx;
if(proxy) {
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
host = conn->http_proxy.host.name;
neg_ctx = &data->state.proxyneg;
}
else {
userp = conn->user;
passwdp = conn->passwd;
service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] : "HTTP";
host = conn->host.name;
neg_ctx = &data->state.negotiate;
}
if(!userp)
userp = "";
if(!passwdp)
passwdp = "";
header += strlen("Negotiate");
while(*header && ISSPACE(*header))
header++;
len = strlen(header);
if(!len) {
if(neg_ctx->context) {
return CURLE_LOGIN_DENIED;
}
}
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
host, header, neg_ctx);
if(result)
Curl_auth_spnego_cleanup(neg_ctx);
return result;
}
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
{
struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg :
&conn->data->state.negotiate;
char *base64 = NULL;
size_t len = 0;
char *userp;
CURLcode result;
result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len);
if(result)
return result;
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
base64);
if(proxy) {
Curl_safefree(conn->allocptr.proxyuserpwd);
conn->allocptr.proxyuserpwd = userp;
}
else {
Curl_safefree(conn->allocptr.userpwd);
conn->allocptr.userpwd = userp;
}
free(base64);
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
}
void Curl_cleanup_negotiate(struct Curl_easy *data)
{
Curl_auth_spnego_cleanup(&data->state.negotiate);
Curl_auth_spnego_cleanup(&data->state.proxyneg);
}
#endif