blob: ddcd65b3b9cb6881c2af1764b688b5b27cb7d827 [file] [log] [blame]
Kristian Monsen5ab50182010-05-14 18:53:44 +01001/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
Alex Deymod15eaac2016-06-28 14:49:26 -07008 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
Kristian Monsen5ab50182010-05-14 18:53:44 +01009 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
Alex Deymod15eaac2016-06-28 14:49:26 -070012 * are also available at https://curl.haxx.se/docs/copyright.html.
Kristian Monsen5ab50182010-05-14 18:53:44 +010013 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
Kristian Monsen5ab50182010-05-14 18:53:44 +010022
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070023#include "curl_setup.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010024
Alex Deymod15eaac2016-06-28 14:49:26 -070025#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
Kristian Monsen5ab50182010-05-14 18:53:44 +010026
27#include "urldata.h"
28#include "sendf.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010029#include "http_negotiate.h"
Alex Deymod15eaac2016-06-28 14:49:26 -070030#include "vauth/vauth.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070031
Alex Deymod15eaac2016-06-28 14:49:26 -070032/* The last 3 #include files should be in this order */
33#include "curl_printf.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010034#include "curl_memory.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010035#include "memdebug.h"
36
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070037CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
38 const char *header)
Kristian Monsen5ab50182010-05-14 18:53:44 +010039{
Elliott Hughescee03382017-06-23 12:17:18 -070040 CURLcode result;
Alex Deymoe3149cc2016-10-05 11:18:42 -070041 struct Curl_easy *data = conn->data;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070042 size_t len;
Kristian Monsen5ab50182010-05-14 18:53:44 +010043
Alex Deymod15eaac2016-06-28 14:49:26 -070044 /* Point to the username, password, service and host */
45 const char *userp;
46 const char *passwdp;
47 const char *service;
48 const char *host;
49
50 /* Point to the correct struct with this */
51 struct negotiatedata *neg_ctx;
52
53 if(proxy) {
Elliott Hughescee03382017-06-23 12:17:18 -070054 userp = conn->http_proxy.user;
55 passwdp = conn->http_proxy.passwd;
Alex Deymod15eaac2016-06-28 14:49:26 -070056 service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
57 data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
Elliott Hughescee03382017-06-23 12:17:18 -070058 host = conn->http_proxy.host.name;
Alex Deymod15eaac2016-06-28 14:49:26 -070059 neg_ctx = &data->state.proxyneg;
60 }
61 else {
62 userp = conn->user;
63 passwdp = conn->passwd;
64 service = data->set.str[STRING_SERVICE_NAME] ?
65 data->set.str[STRING_SERVICE_NAME] : "HTTP";
66 host = conn->host.name;
67 neg_ctx = &data->state.negotiate;
Kristian Monsen5ab50182010-05-14 18:53:44 +010068 }
69
Alex Deymod15eaac2016-06-28 14:49:26 -070070 /* Not set means empty */
71 if(!userp)
72 userp = "";
Kristian Monsen5ab50182010-05-14 18:53:44 +010073
Alex Deymod15eaac2016-06-28 14:49:26 -070074 if(!passwdp)
75 passwdp = "";
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070076
Alex Deymod15eaac2016-06-28 14:49:26 -070077 /* Obtain the input token, if any */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070078 header += strlen("Negotiate");
Kristian Monsen5ab50182010-05-14 18:53:44 +010079 while(*header && ISSPACE(*header))
80 header++;
81
82 len = strlen(header);
Alex Deymod15eaac2016-06-28 14:49:26 -070083 if(!len) {
84 /* Is this the first call in a new negotiation? */
85 if(neg_ctx->context) {
86 /* The server rejected our authentication and hasn't suppled any more
87 negotiation mechanisms */
88 return CURLE_LOGIN_DENIED;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070089 }
Kristian Monsen5ab50182010-05-14 18:53:44 +010090 }
91
Elliott Hughes1ef06ba2018-05-30 15:43:58 -070092 /* Initialize the security context and decode our challenge */
Elliott Hughescee03382017-06-23 12:17:18 -070093 result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
94 host, header, neg_ctx);
95
96 if(result)
97 Curl_auth_spnego_cleanup(neg_ctx);
98
99 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100100}
101
Kristian Monsen5ab50182010-05-14 18:53:44 +0100102CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
103{
Alex Deymod15eaac2016-06-28 14:49:26 -0700104 struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg :
Kristian Monsen5ab50182010-05-14 18:53:44 +0100105 &conn->data->state.negotiate;
Alex Deymod15eaac2016-06-28 14:49:26 -0700106 char *base64 = NULL;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700107 size_t len = 0;
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700108 char *userp;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700109 CURLcode result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100110
Alex Deymod15eaac2016-06-28 14:49:26 -0700111 result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len);
112 if(result)
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700113 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100114
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700115 userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
Alex Deymod15eaac2016-06-28 14:49:26 -0700116 base64);
117
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700118 if(proxy) {
119 Curl_safefree(conn->allocptr.proxyuserpwd);
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700120 conn->allocptr.proxyuserpwd = userp;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700121 }
122 else {
123 Curl_safefree(conn->allocptr.userpwd);
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700124 conn->allocptr.userpwd = userp;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700125 }
126
Alex Deymod15eaac2016-06-28 14:49:26 -0700127 free(base64);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700128
Lucas Eckels9bd90e62012-08-06 15:07:02 -0700129 return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100130}
131
Alex Deymoe3149cc2016-10-05 11:18:42 -0700132void Curl_cleanup_negotiate(struct Curl_easy *data)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100133{
Alex Deymod15eaac2016-06-28 14:49:26 -0700134 Curl_auth_spnego_cleanup(&data->state.negotiate);
135 Curl_auth_spnego_cleanup(&data->state.proxyneg);
Kristian Monsen5ab50182010-05-14 18:53:44 +0100136}
137
Alex Deymod15eaac2016-06-28 14:49:26 -0700138#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */