diff options
author | Nikita Slyusarev <nslus@yandex-team.com> | 2022-02-10 16:46:53 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:53 +0300 |
commit | 469afdc4e2587bf62ecdd096b75a0baa444c4012 (patch) | |
tree | 49e222ea1c5804306084bb3ae065bb702625360f /contrib/libs/curl/lib/curl_ntlm_wb.c | |
parent | cd77cecfc03a3eaf87816af28a33067c4f0cdb59 (diff) | |
download | ydb-469afdc4e2587bf62ecdd096b75a0baa444c4012.tar.gz |
Restoring authorship annotation for Nikita Slyusarev <nslus@yandex-team.com>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/curl/lib/curl_ntlm_wb.c')
-rw-r--r-- | contrib/libs/curl/lib/curl_ntlm_wb.c | 554 |
1 files changed, 277 insertions, 277 deletions
diff --git a/contrib/libs/curl/lib/curl_ntlm_wb.c b/contrib/libs/curl/lib/curl_ntlm_wb.c index b340f4c865..c11757f557 100644 --- a/contrib/libs/curl/lib/curl_ntlm_wb.c +++ b/contrib/libs/curl/lib/curl_ntlm_wb.c @@ -1,142 +1,142 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ defined(NTLM_WB_ENABLED) - -/* - * NTLM details: - * + +/* + * NTLM details: + * * https://davenport.sourceforge.io/ntlm.html * https://www.innovation.ch/java/ntlm.html - */ - -#define DEBUG_ME 0 - -#ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif + */ + +#define DEBUG_ME 0 + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif #ifdef HAVE_PWD_H #include <pwd.h> #endif - -#include "urldata.h" -#include "sendf.h" -#include "select.h" + +#include "urldata.h" +#include "sendf.h" +#include "select.h" #include "vauth/ntlm.h" #include "curl_ntlm_core.h" -#include "curl_ntlm_wb.h" -#include "url.h" -#include "strerror.h" +#include "curl_ntlm_wb.h" +#include "url.h" +#include "strerror.h" #include "strdup.h" #include "strcase.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#if DEBUG_ME -# define DEBUG_OUT(x) x -#else -# define DEBUG_OUT(x) Curl_nop_stmt -#endif - -/* Portable 'sclose_nolog' used only in child process instead of 'sclose' - to avoid fooling the socket leak detector */ -#if defined(HAVE_CLOSESOCKET) -# define sclose_nolog(x) closesocket((x)) -#elif defined(HAVE_CLOSESOCKET_CAMEL) -# define sclose_nolog(x) CloseSocket((x)) -#else -# define sclose_nolog(x) close((x)) -#endif - +#include "curl_memory.h" +#include "memdebug.h" + +#if DEBUG_ME +# define DEBUG_OUT(x) x +#else +# define DEBUG_OUT(x) Curl_nop_stmt +#endif + +/* Portable 'sclose_nolog' used only in child process instead of 'sclose' + to avoid fooling the socket leak detector */ +#if defined(HAVE_CLOSESOCKET) +# define sclose_nolog(x) closesocket((x)) +#elif defined(HAVE_CLOSESOCKET_CAMEL) +# define sclose_nolog(x) CloseSocket((x)) +#else +# define sclose_nolog(x) close((x)) +#endif + static void ntlm_wb_cleanup(struct ntlmdata *ntlm) -{ +{ if(ntlm->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) { sclose(ntlm->ntlm_auth_hlpr_socket); ntlm->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; - } - + } + if(ntlm->ntlm_auth_hlpr_pid) { - int i; - for(i = 0; i < 4; i++) { + int i; + for(i = 0; i < 4; i++) { pid_t ret = waitpid(ntlm->ntlm_auth_hlpr_pid, NULL, WNOHANG); if(ret == ntlm->ntlm_auth_hlpr_pid || errno == ECHILD) - break; - switch(i) { - case 0: + break; + switch(i) { + case 0: kill(ntlm->ntlm_auth_hlpr_pid, SIGTERM); - break; - case 1: - /* Give the process another moment to shut down cleanly before - bringing down the axe */ - Curl_wait_ms(1); - break; - case 2: + break; + case 1: + /* Give the process another moment to shut down cleanly before + bringing down the axe */ + Curl_wait_ms(1); + break; + case 2: kill(ntlm->ntlm_auth_hlpr_pid, SIGKILL); - break; - case 3: - break; - } - } + break; + case 3: + break; + } + } ntlm->ntlm_auth_hlpr_pid = 0; - } - + } + Curl_safefree(ntlm->challenge); Curl_safefree(ntlm->response); -} - +} + static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, const char *userp) -{ - curl_socket_t sockfds[2]; - pid_t child_pid; - const char *username; - char *slash, *domain = NULL; - const char *ntlm_auth = NULL; - char *ntlm_auth_alloc = NULL; +{ + curl_socket_t sockfds[2]; + pid_t child_pid; + const char *username; + char *slash, *domain = NULL; + const char *ntlm_auth = NULL; + char *ntlm_auth_alloc = NULL; #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) struct passwd pw, *pw_res; char pwbuf[1024]; #endif char buffer[STRERROR_LEN]; - + #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) data; #endif - /* Return if communication with ntlm_auth already set up */ + /* Return if communication with ntlm_auth already set up */ if(ntlm->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD || ntlm->ntlm_auth_hlpr_pid) - return CURLE_OK; - - username = userp; + return CURLE_OK; + + username = userp; /* The real ntlm_auth really doesn't like being invoked with an empty username. It won't make inferences for itself, and expects the client to do so (mostly because it's really designed for @@ -161,135 +161,135 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, if(!username || !username[0]) username = userp; } - slash = strpbrk(username, "\\/"); - if(slash) { + slash = strpbrk(username, "\\/"); + if(slash) { domain = strdup(username); if(!domain) - return CURLE_OUT_OF_MEMORY; - slash = domain + (slash - username); - *slash = '\0'; - username = username + (slash - domain) + 1; - } - - /* For testing purposes, when DEBUGBUILD is defined and environment - variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform - NTLM challenge/response which only accepts commands and output - strings pre-written in test case definitions */ -#ifdef DEBUGBUILD - ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE"); - if(ntlm_auth_alloc) - ntlm_auth = ntlm_auth_alloc; - else -#endif - ntlm_auth = NTLM_WB_FILE; - - if(access(ntlm_auth, X_OK) != 0) { + return CURLE_OUT_OF_MEMORY; + slash = domain + (slash - username); + *slash = '\0'; + username = username + (slash - domain) + 1; + } + + /* For testing purposes, when DEBUGBUILD is defined and environment + variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform + NTLM challenge/response which only accepts commands and output + strings pre-written in test case definitions */ +#ifdef DEBUGBUILD + ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE"); + if(ntlm_auth_alloc) + ntlm_auth = ntlm_auth_alloc; + else +#endif + ntlm_auth = NTLM_WB_FILE; + + if(access(ntlm_auth, X_OK) != 0) { failf(data, "Could not access ntlm_auth: %s errno %d: %s", ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer))); - goto done; - } - + goto done; + } + if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { failf(data, "Could not open socket pair. errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); - goto done; - } - - child_pid = fork(); - if(child_pid == -1) { - sclose(sockfds[0]); - sclose(sockfds[1]); + goto done; + } + + child_pid = fork(); + if(child_pid == -1) { + sclose(sockfds[0]); + sclose(sockfds[1]); failf(data, "Could not fork. errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); - goto done; - } - else if(!child_pid) { - /* - * child process - */ - - /* Don't use sclose in the child since it fools the socket leak detector */ - sclose_nolog(sockfds[0]); - if(dup2(sockfds[1], STDIN_FILENO) == -1) { + goto done; + } + else if(!child_pid) { + /* + * child process + */ + + /* Don't use sclose in the child since it fools the socket leak detector */ + sclose_nolog(sockfds[0]); + if(dup2(sockfds[1], STDIN_FILENO) == -1) { failf(data, "Could not redirect child stdin. errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); - exit(1); - } - - if(dup2(sockfds[1], STDOUT_FILENO) == -1) { + exit(1); + } + + if(dup2(sockfds[1], STDOUT_FILENO) == -1) { failf(data, "Could not redirect child stdout. errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); - exit(1); - } - - if(domain) - execl(ntlm_auth, ntlm_auth, - "--helper-protocol", "ntlmssp-client-1", - "--use-cached-creds", - "--username", username, - "--domain", domain, - NULL); - else - execl(ntlm_auth, ntlm_auth, - "--helper-protocol", "ntlmssp-client-1", - "--use-cached-creds", - "--username", username, - NULL); - - sclose_nolog(sockfds[1]); + exit(1); + } + + if(domain) + execl(ntlm_auth, ntlm_auth, + "--helper-protocol", "ntlmssp-client-1", + "--use-cached-creds", + "--username", username, + "--domain", domain, + NULL); + else + execl(ntlm_auth, ntlm_auth, + "--helper-protocol", "ntlmssp-client-1", + "--use-cached-creds", + "--username", username, + NULL); + + sclose_nolog(sockfds[1]); failf(data, "Could not execl(). errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); - exit(1); - } - - sclose(sockfds[1]); + exit(1); + } + + sclose(sockfds[1]); ntlm->ntlm_auth_hlpr_socket = sockfds[0]; ntlm->ntlm_auth_hlpr_pid = child_pid; free(domain); free(ntlm_auth_alloc); - return CURLE_OK; - -done: + return CURLE_OK; + +done: free(domain); free(ntlm_auth_alloc); - return CURLE_REMOTE_ACCESS_DENIED; -} - + return CURLE_REMOTE_ACCESS_DENIED; +} + /* if larger than this, something is seriously wrong */ #define MAX_NTLM_WB_RESPONSE 100000 static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm, - const char *input, curlntlm state) -{ + const char *input, curlntlm state) +{ size_t len_in = strlen(input), len_out = 0; struct dynbuf b; char *ptr = NULL; unsigned char *buf = (unsigned char *)data->state.buffer; Curl_dyn_init(&b, MAX_NTLM_WB_RESPONSE); - - while(len_in > 0) { + + while(len_in > 0) { ssize_t written = swrite(ntlm->ntlm_auth_hlpr_socket, input, len_in); - if(written == -1) { - /* Interrupted by a signal, retry it */ - if(errno == EINTR) - continue; - /* write failed if other errors happen */ - goto done; - } - input += written; - len_in -= written; - } - /* Read one line */ + if(written == -1) { + /* Interrupted by a signal, retry it */ + if(errno == EINTR) + continue; + /* write failed if other errors happen */ + goto done; + } + input += written; + len_in -= written; + } + /* Read one line */ while(1) { ssize_t size = sread(ntlm->ntlm_auth_hlpr_socket, buf, data->set.buffer_size); - if(size == -1) { - if(errno == EINTR) - continue; - goto done; - } - else if(size == 0) - goto done; + if(size == -1) { + if(errno == EINTR) + continue; + goto done; + } + else if(size == 0) + goto done; if(Curl_dyn_addn(&b, buf, size)) goto done; @@ -301,34 +301,34 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm, break; /* done! */ } /* loop */ - } + } - /* Samba/winbind installed but not configured */ - if(state == NTLMSTATE_TYPE1 && + /* Samba/winbind installed but not configured */ + if(state == NTLMSTATE_TYPE1 && len_out == 3 && ptr[0] == 'P' && ptr[1] == 'W') goto done; - /* invalid response */ + /* invalid response */ if(len_out < 4) - goto done; - if(state == NTLMSTATE_TYPE1 && + goto done; + if(state == NTLMSTATE_TYPE1 && (ptr[0]!='Y' || ptr[1]!='R' || ptr[2]!=' ')) - goto done; - if(state == NTLMSTATE_TYPE2 && + goto done; + if(state == NTLMSTATE_TYPE2 && (ptr[0]!='K' || ptr[1]!='K' || ptr[2]!=' ') && (ptr[0]!='A' || ptr[1]!='F' || ptr[2]!=' ')) - goto done; - + goto done; + ntlm->response = strdup(ptr + 3); Curl_dyn_free(&b); if(!ntlm->response) return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -done: + return CURLE_OK; +done: Curl_dyn_free(&b); - return CURLE_REMOTE_ACCESS_DENIED; -} - + return CURLE_REMOTE_ACCESS_DENIED; +} + CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy, const char *header) @@ -372,119 +372,119 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn, return CURLE_OK; } -/* - * This is for creating ntlm header output by delegating challenge/response - * to Samba's winbind daemon helper ntlm_auth. - */ +/* + * This is for creating ntlm header output by delegating challenge/response + * to Samba's winbind daemon helper ntlm_auth. + */ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) -{ - /* 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; +{ + /* 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; struct ntlmdata *ntlm; curlntlm *state; - struct auth *authp; + struct auth *authp; struct Curl_easy *data = conn->data; - - CURLcode res = CURLE_OK; - - DEBUGASSERT(conn); - DEBUGASSERT(conn->data); - - if(proxy) { + + CURLcode res = CURLE_OK; + + DEBUGASSERT(conn); + DEBUGASSERT(conn->data); + + if(proxy) { #ifndef CURL_DISABLE_PROXY allocuserpwd = &data->state.aptr.proxyuserpwd; userp = conn->http_proxy.user; ntlm = &conn->proxyntlm; state = &conn->proxy_ntlm_state; - authp = &conn->data->state.authproxy; + authp = &conn->data->state.authproxy; #else return CURLE_NOT_BUILT_IN; #endif - } - else { + } + else { allocuserpwd = &data->state.aptr.userpwd; - userp = conn->user; + userp = conn->user; ntlm = &conn->ntlm; state = &conn->http_ntlm_state; - authp = &conn->data->state.authhost; - } - authp->done = FALSE; - - /* not set means empty */ - if(!userp) + authp = &conn->data->state.authhost; + } + authp->done = FALSE; + + /* not set means empty */ + if(!userp) userp = ""; - + switch(*state) { - case NTLMSTATE_TYPE1: - default: - /* Use Samba's 'winbind' daemon to support NTLM authentication, + case NTLMSTATE_TYPE1: + default: + /* Use Samba's 'winbind' daemon to support NTLM authentication, * by delegating the NTLM challenge/response protocol to a helper - * in ntlm_auth. - * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html + * in ntlm_auth. + * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html * https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html * https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html - * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this - * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute - * filename of ntlm_auth helper. - * If NTLM authentication using winbind fails, go back to original - * request handling process. - */ - /* Create communication with ntlm_auth */ + * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this + * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute + * filename of ntlm_auth helper. + * If NTLM authentication using winbind fails, go back to original + * request handling process. + */ + /* Create communication with ntlm_auth */ res = ntlm_wb_init(conn->data, ntlm, userp); - if(res) - return res; + if(res) + return res; res = ntlm_wb_response(conn->data, ntlm, "YR\n", *state); - if(res) - return res; - + if(res) + return res; + free(*allocuserpwd); *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", + proxy ? "Proxy-" : "", ntlm->response); - DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); + DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); Curl_safefree(ntlm->response); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; - break; + break; case NTLMSTATE_TYPE2: { char *input = aprintf("TT %s\n", ntlm->challenge); - if(!input) - return CURLE_OUT_OF_MEMORY; + if(!input) + return CURLE_OUT_OF_MEMORY; res = ntlm_wb_response(conn->data, ntlm, input, *state); - free(input); - if(res) - return res; - + free(input); + if(res) + return res; + free(*allocuserpwd); *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", + proxy ? "Proxy-" : "", ntlm->response); - DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); + DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); *state = NTLMSTATE_TYPE3; /* we sent a type-3 */ - authp->done = TRUE; + authp->done = TRUE; Curl_http_auth_cleanup_ntlm_wb(conn); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; - break; + break; } - case NTLMSTATE_TYPE3: - /* connection is already authenticated, - * don't send a header in future requests */ + case NTLMSTATE_TYPE3: + /* connection is already authenticated, + * don't send a header in future requests */ *state = NTLMSTATE_LAST; /* FALLTHROUGH */ case NTLMSTATE_LAST: Curl_safefree(*allocuserpwd); - authp->done = TRUE; - break; - } - - return CURLE_OK; -} - + authp->done = TRUE; + break; + } + + return CURLE_OK; +} + void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn) { ntlm_wb_cleanup(&conn->ntlm); |