Annotation of embedaddon/curl/lib/http_ntlm.c, revision 1.1
1.1 ! misho 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_NTLM)
! 26:
! 27: /*
! 28: * NTLM details:
! 29: *
! 30: * https://davenport.sourceforge.io/ntlm.html
! 31: * https://www.innovation.ch/java/ntlm.html
! 32: */
! 33:
! 34: #define DEBUG_ME 0
! 35:
! 36: #include "urldata.h"
! 37: #include "sendf.h"
! 38: #include "strcase.h"
! 39: #include "http_ntlm.h"
! 40: #include "curl_ntlm_core.h"
! 41: #include "curl_ntlm_wb.h"
! 42: #include "vauth/vauth.h"
! 43: #include "url.h"
! 44:
! 45: /* SSL backend-specific #if branches in this file must be kept in the order
! 46: documented in curl_ntlm_core. */
! 47: #if defined(USE_WINDOWS_SSPI)
! 48: #include "curl_sspi.h"
! 49: #endif
! 50:
! 51: /* The last 3 #include files should be in this order */
! 52: #include "curl_printf.h"
! 53: #include "curl_memory.h"
! 54: #include "memdebug.h"
! 55:
! 56: #if DEBUG_ME
! 57: # define DEBUG_OUT(x) x
! 58: #else
! 59: # define DEBUG_OUT(x) Curl_nop_stmt
! 60: #endif
! 61:
! 62: CURLcode Curl_input_ntlm(struct connectdata *conn,
! 63: bool proxy, /* if proxy or not */
! 64: const char *header) /* rest of the www-authenticate:
! 65: header */
! 66: {
! 67: /* point to the correct struct with this */
! 68: struct ntlmdata *ntlm;
! 69: curlntlm *state;
! 70: CURLcode result = CURLE_OK;
! 71:
! 72: ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
! 73: state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
! 74:
! 75: if(checkprefix("NTLM", header)) {
! 76: header += strlen("NTLM");
! 77:
! 78: while(*header && ISSPACE(*header))
! 79: header++;
! 80:
! 81: if(*header) {
! 82: result = Curl_auth_decode_ntlm_type2_message(conn->data, header, ntlm);
! 83: if(result)
! 84: return result;
! 85:
! 86: *state = NTLMSTATE_TYPE2; /* We got a type-2 message */
! 87: }
! 88: else {
! 89: if(*state == NTLMSTATE_LAST) {
! 90: infof(conn->data, "NTLM auth restarted\n");
! 91: Curl_http_auth_cleanup_ntlm(conn);
! 92: }
! 93: else if(*state == NTLMSTATE_TYPE3) {
! 94: infof(conn->data, "NTLM handshake rejected\n");
! 95: Curl_http_auth_cleanup_ntlm(conn);
! 96: *state = NTLMSTATE_NONE;
! 97: return CURLE_REMOTE_ACCESS_DENIED;
! 98: }
! 99: else if(*state >= NTLMSTATE_TYPE1) {
! 100: infof(conn->data, "NTLM handshake failure (internal error)\n");
! 101: return CURLE_REMOTE_ACCESS_DENIED;
! 102: }
! 103:
! 104: *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
! 105: }
! 106: }
! 107:
! 108: return result;
! 109: }
! 110:
! 111: /*
! 112: * This is for creating ntlm header output
! 113: */
! 114: CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
! 115: {
! 116: char *base64 = NULL;
! 117: size_t len = 0;
! 118: CURLcode result;
! 119:
! 120: /* point to the address of the pointer that holds the string to send to the
! 121: server, which is for a plain host or for a HTTP proxy */
! 122: char **allocuserpwd;
! 123:
! 124: /* point to the username, password, service and host */
! 125: const char *userp;
! 126: const char *passwdp;
! 127: const char *service = NULL;
! 128: const char *hostname = NULL;
! 129:
! 130: /* point to the correct struct with this */
! 131: struct ntlmdata *ntlm;
! 132: curlntlm *state;
! 133: struct auth *authp;
! 134:
! 135: DEBUGASSERT(conn);
! 136: DEBUGASSERT(conn->data);
! 137:
! 138: if(proxy) {
! 139: allocuserpwd = &conn->allocptr.proxyuserpwd;
! 140: userp = conn->http_proxy.user;
! 141: passwdp = conn->http_proxy.passwd;
! 142: service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ?
! 143: conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
! 144: hostname = conn->http_proxy.host.name;
! 145: ntlm = &conn->proxyntlm;
! 146: state = &conn->proxy_ntlm_state;
! 147: authp = &conn->data->state.authproxy;
! 148: }
! 149: else {
! 150: allocuserpwd = &conn->allocptr.userpwd;
! 151: userp = conn->user;
! 152: passwdp = conn->passwd;
! 153: service = conn->data->set.str[STRING_SERVICE_NAME] ?
! 154: conn->data->set.str[STRING_SERVICE_NAME] : "HTTP";
! 155: hostname = conn->host.name;
! 156: ntlm = &conn->ntlm;
! 157: state = &conn->http_ntlm_state;
! 158: authp = &conn->data->state.authhost;
! 159: }
! 160: authp->done = FALSE;
! 161:
! 162: /* not set means empty */
! 163: if(!userp)
! 164: userp = "";
! 165:
! 166: if(!passwdp)
! 167: passwdp = "";
! 168:
! 169: #ifdef USE_WINDOWS_SSPI
! 170: if(s_hSecDll == NULL) {
! 171: /* not thread safe and leaks - use curl_global_init() to avoid */
! 172: CURLcode err = Curl_sspi_global_init();
! 173: if(s_hSecDll == NULL)
! 174: return err;
! 175: }
! 176: #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
! 177: ntlm->sslContext = conn->sslContext;
! 178: #endif
! 179: #endif
! 180:
! 181: switch(*state) {
! 182: case NTLMSTATE_TYPE1:
! 183: default: /* for the weird cases we (re)start here */
! 184: /* Create a type-1 message */
! 185: result = Curl_auth_create_ntlm_type1_message(conn->data, userp, passwdp,
! 186: service, hostname,
! 187: ntlm, &base64,
! 188: &len);
! 189: if(result)
! 190: return result;
! 191:
! 192: if(base64) {
! 193: free(*allocuserpwd);
! 194: *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
! 195: proxy ? "Proxy-" : "",
! 196: base64);
! 197: free(base64);
! 198: if(!*allocuserpwd)
! 199: return CURLE_OUT_OF_MEMORY;
! 200:
! 201: DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
! 202: }
! 203: break;
! 204:
! 205: case NTLMSTATE_TYPE2:
! 206: /* We already received the type-2 message, create a type-3 message */
! 207: result = Curl_auth_create_ntlm_type3_message(conn->data, userp, passwdp,
! 208: ntlm, &base64, &len);
! 209: if(result)
! 210: return result;
! 211:
! 212: if(base64) {
! 213: free(*allocuserpwd);
! 214: *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
! 215: proxy ? "Proxy-" : "",
! 216: base64);
! 217: free(base64);
! 218: if(!*allocuserpwd)
! 219: return CURLE_OUT_OF_MEMORY;
! 220:
! 221: DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
! 222:
! 223: *state = NTLMSTATE_TYPE3; /* we send a type-3 */
! 224: authp->done = TRUE;
! 225: }
! 226: break;
! 227:
! 228: case NTLMSTATE_TYPE3:
! 229: /* connection is already authenticated,
! 230: * don't send a header in future requests */
! 231: *state = NTLMSTATE_LAST;
! 232: /* FALLTHROUGH */
! 233: case NTLMSTATE_LAST:
! 234: Curl_safefree(*allocuserpwd);
! 235: authp->done = TRUE;
! 236: break;
! 237: }
! 238:
! 239: return CURLE_OK;
! 240: }
! 241:
! 242: void Curl_http_auth_cleanup_ntlm(struct connectdata *conn)
! 243: {
! 244: Curl_auth_cleanup_ntlm(&conn->ntlm);
! 245: Curl_auth_cleanup_ntlm(&conn->proxyntlm);
! 246:
! 247: #if defined(NTLM_WB_ENABLED)
! 248: Curl_http_auth_cleanup_ntlm_wb(conn);
! 249: #endif
! 250: }
! 251:
! 252: #endif /* !CURL_DISABLE_HTTP && USE_NTLM */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>