Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/curl/lib/http_negotiate.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /*************************************************************************** | |
| 2 * _ _ ____ _ | |
| 3 * Project ___| | | | _ \| | | |
| 4 * / __| | | | |_) | | | |
| 5 * | (__| |_| | _ <| |___ | |
| 6 * \___|\___/|_| \_\_____| | |
| 7 * | |
| 8 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. | |
| 9 * | |
| 10 * This software is licensed as described in the file COPYING, which | |
| 11 * you should have received as part of this distribution. The terms | |
| 12 * are also available at https://curl.haxx.se/docs/copyright.html. | |
| 13 * | |
| 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 ***************************************************************************/ | |
| 22 | |
| 23 #include "curl_setup.h" | |
| 24 | |
| 25 #if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) | |
| 26 | |
| 27 #include "urldata.h" | |
| 28 #include "sendf.h" | |
| 29 #include "http_negotiate.h" | |
| 30 #include "vauth/vauth.h" | |
| 31 | |
| 32 /* The last 3 #include files should be in this order */ | |
| 33 #include "curl_printf.h" | |
| 34 #include "curl_memory.h" | |
| 35 #include "memdebug.h" | |
| 36 | |
| 37 CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, | |
| 38 const char *header) | |
| 39 { | |
| 40 CURLcode result; | |
| 41 struct Curl_easy *data = conn->data; | |
| 42 size_t len; | |
| 43 | |
| 44 /* 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 curlnegotiate state; | |
| 53 | |
| 54 if(proxy) { | |
| 55 userp = conn->http_proxy.user; | |
| 56 passwdp = conn->http_proxy.passwd; | |
| 57 service = data->set.str[STRING_PROXY_SERVICE_NAME] ? | |
| 58 data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; | |
| 59 host = conn->http_proxy.host.name; | |
| 60 neg_ctx = &conn->proxyneg; | |
| 61 state = conn->proxy_negotiate_state; | |
| 62 } | |
| 63 else { | |
| 64 userp = conn->user; | |
| 65 passwdp = conn->passwd; | |
| 66 service = data->set.str[STRING_SERVICE_NAME] ? | |
| 67 data->set.str[STRING_SERVICE_NAME] : "HTTP"; | |
| 68 host = conn->host.name; | |
| 69 neg_ctx = &conn->negotiate; | |
| 70 state = conn->http_negotiate_state; | |
| 71 } | |
| 72 | |
| 73 /* Not set means empty */ | |
| 74 if(!userp) | |
| 75 userp = ""; | |
| 76 | |
| 77 if(!passwdp) | |
| 78 passwdp = ""; | |
| 79 | |
| 80 /* Obtain the input token, if any */ | |
| 81 header += strlen("Negotiate"); | |
| 82 while(*header && ISSPACE(*header)) | |
| 83 header++; | |
| 84 | |
| 85 len = strlen(header); | |
| 86 neg_ctx->havenegdata = len != 0; | |
| 87 if(!len) { | |
| 88 if(state == GSS_AUTHSUCC) { | |
| 89 infof(conn->data, "Negotiate auth restarted\n"); | |
| 90 Curl_http_auth_cleanup_negotiate(conn); | |
| 91 } | |
| 92 else if(state != GSS_AUTHNONE) { | |
| 93 /* The server rejected our authentication and hasn't supplied any more | |
| 94 negotiation mechanisms */ | |
| 95 Curl_http_auth_cleanup_negotiate(conn); | |
| 96 return CURLE_LOGIN_DENIED; | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 /* Supports SSL channel binding for Windows ISS extended protection */ | |
| 101 #if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) | |
| 102 neg_ctx->sslContext = conn->sslContext; | |
| 103 #endif | |
| 104 | |
| 105 /* Initialize the security context and decode our challenge */ | |
| 106 result = Curl_auth_decode_spnego_message(data, userp, passwdp, service, | |
| 107 host, header, neg_ctx); | |
| 108 | |
| 109 if(result) | |
| 110 Curl_http_auth_cleanup_negotiate(conn); | |
| 111 | |
| 112 return result; | |
| 113 } | |
| 114 | |
| 115 CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) | |
| 116 { | |
| 117 struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg : | |
| 118 &conn->negotiate; | |
| 119 struct auth *authp = proxy ? &conn->data->state.authproxy : | |
| 120 &conn->data->state.authhost; | |
| 121 curlnegotiate *state = proxy ? &conn->proxy_negotiate_state : | |
| 122 &conn->http_negotiate_state; | |
| 123 char *base64 = NULL; | |
| 124 size_t len = 0; | |
| 125 char *userp; | |
| 126 CURLcode result; | |
| 127 | |
| 128 authp->done = FALSE; | |
| 129 | |
| 130 if(*state == GSS_AUTHRECV) { | |
| 131 if(neg_ctx->havenegdata) { | |
| 132 neg_ctx->havemultiplerequests = TRUE; | |
| 133 } | |
| 134 } | |
| 135 else if(*state == GSS_AUTHSUCC) { | |
| 136 if(!neg_ctx->havenoauthpersist) { | |
| 137 neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 if(neg_ctx->noauthpersist || | |
| 142 (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { | |
| 143 | |
| 144 if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { | |
| 145 infof(conn->data, "Curl_output_negotiate, " | |
| 146 "no persistent authentication: cleanup existing context"); | |
| 147 Curl_http_auth_cleanup_negotiate(conn); | |
| 148 } | |
| 149 if(!neg_ctx->context) { | |
| 150 result = Curl_input_negotiate(conn, proxy, "Negotiate"); | |
| 151 if(result == CURLE_AUTH_ERROR) { | |
| 152 /* negotiate auth failed, let's continue unauthenticated to stay | |
| 153 * compatible with the behavior before curl-7_64_0-158-g6c6035532 */ | |
| 154 authp->done = TRUE; | |
| 155 return CURLE_OK; | |
| 156 } | |
| 157 else if(result) | |
| 158 return result; | |
| 159 } | |
| 160 | |
| 161 result = Curl_auth_create_spnego_message(conn->data, | |
| 162 neg_ctx, &base64, &len); | |
| 163 if(result) | |
| 164 return result; | |
| 165 | |
| 166 userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", | |
| 167 base64); | |
| 168 | |
| 169 if(proxy) { | |
| 170 Curl_safefree(conn->allocptr.proxyuserpwd); | |
| 171 conn->allocptr.proxyuserpwd = userp; | |
| 172 } | |
| 173 else { | |
| 174 Curl_safefree(conn->allocptr.userpwd); | |
| 175 conn->allocptr.userpwd = userp; | |
| 176 } | |
| 177 | |
| 178 free(base64); | |
| 179 | |
| 180 if(userp == NULL) { | |
| 181 return CURLE_OUT_OF_MEMORY; | |
| 182 } | |
| 183 | |
| 184 *state = GSS_AUTHSENT; | |
| 185 #ifdef HAVE_GSSAPI | |
| 186 if(neg_ctx->status == GSS_S_COMPLETE || | |
| 187 neg_ctx->status == GSS_S_CONTINUE_NEEDED) { | |
| 188 *state = GSS_AUTHDONE; | |
| 189 } | |
| 190 #else | |
| 191 #ifdef USE_WINDOWS_SSPI | |
| 192 if(neg_ctx->status == SEC_E_OK || | |
| 193 neg_ctx->status == SEC_I_CONTINUE_NEEDED) { | |
| 194 *state = GSS_AUTHDONE; | |
| 195 } | |
| 196 #endif | |
| 197 #endif | |
| 198 } | |
| 199 | |
| 200 if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) { | |
| 201 /* connection is already authenticated, | |
| 202 * don't send a header in future requests */ | |
| 203 authp->done = TRUE; | |
| 204 } | |
| 205 | |
| 206 neg_ctx->havenegdata = FALSE; | |
| 207 | |
| 208 return CURLE_OK; | |
| 209 } | |
| 210 | |
| 211 void Curl_http_auth_cleanup_negotiate(struct connectdata *conn) | |
| 212 { | |
| 213 conn->http_negotiate_state = GSS_AUTHNONE; | |
| 214 conn->proxy_negotiate_state = GSS_AUTHNONE; | |
| 215 | |
| 216 Curl_auth_cleanup_spnego(&conn->negotiate); | |
| 217 Curl_auth_cleanup_spnego(&conn->proxyneg); | |
| 218 } | |
| 219 | |
| 220 #endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ |
