25 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ 26 defined(NTLM_WB_ENABLED) 37 #ifdef HAVE_SYS_WAIT_H 62 # define DEBUG_OUT(x) x 64 # define DEBUG_OUT(x) Curl_nop_stmt 69 #if defined(HAVE_CLOSESOCKET) 70 # define sclose_nolog(x) closesocket((x)) 71 #elif defined(HAVE_CLOSESOCKET_CAMEL) 72 # define sclose_nolog(x) CloseSocket((x)) 74 # define sclose_nolog(x) close((x)) 80 sclose(conn->ntlm_auth_hlpr_socket);
84 if(conn->ntlm_auth_hlpr_pid) {
86 for(i = 0; i < 4; i++) {
87 pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
88 if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
92 kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
100 kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
106 conn->ntlm_auth_hlpr_pid = 0;
109 free(conn->challenge_header);
110 conn->challenge_header = NULL;
111 free(conn->response_header);
112 conn->response_header = NULL;
119 const char *username;
120 char *slash, *domain = NULL;
121 const char *ntlm_auth = NULL;
122 char *ntlm_auth_alloc = NULL;
123 #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) 124 struct passwd pw, *pw_res;
130 conn->ntlm_auth_hlpr_pid)
142 if(!username || !username[0]) {
143 username =
getenv(
"NTLMUSER");
144 if(!username || !username[0])
145 username =
getenv(
"LOGNAME");
146 if(!username || !username[0])
147 username =
getenv(
"USER");
148 #if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) 149 if((!username || !username[0]) &&
150 !getpwuid_r(geteuid(), &pw, pwbuf,
sizeof(pwbuf), &pw_res) &&
152 username = pw.pw_name;
155 if(!username || !username[0])
158 slash = strpbrk(username,
"\\/");
160 domain =
strdup(username);
163 slash = domain + (slash - username);
165 username = username + (slash - domain) + 1;
173 ntlm_auth_alloc =
curl_getenv(
"CURL_NTLM_WB_FILE");
175 ntlm_auth = ntlm_auth_alloc;
178 ntlm_auth = NTLM_WB_FILE;
180 if(access(ntlm_auth, X_OK) != 0) {
181 failf(conn->
data,
"Could not access ntlm_auth: %s errno %d: %s",
186 if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
187 failf(conn->
data,
"Could not open socket pair. errno %d: %s",
193 if(child_pid == -1) {
196 failf(conn->
data,
"Could not fork. errno %d: %s",
200 else if(!child_pid) {
206 sclose_nolog(sockfds[0]);
208 failf(conn->
data,
"Could not redirect child stdin. errno %d: %s",
214 failf(conn->
data,
"Could not redirect child stdout. errno %d: %s",
220 execl(ntlm_auth, ntlm_auth,
221 "--helper-protocol",
"ntlmssp-client-1",
222 "--use-cached-creds",
223 "--username", username,
227 execl(ntlm_auth, ntlm_auth,
228 "--helper-protocol",
"ntlmssp-client-1",
229 "--use-cached-creds",
230 "--username", username,
233 sclose_nolog(sockfds[1]);
234 failf(conn->
data,
"Could not execl(). errno %d: %s",
240 conn->ntlm_auth_hlpr_socket = sockfds[0];
241 conn->ntlm_auth_hlpr_pid = child_pid;
243 free(ntlm_auth_alloc);
248 free(ntlm_auth_alloc);
256 size_t len_in = strlen(input), len_out = 0;
262 ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
278 size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
288 if(buf[len_out - 1] ==
'\n') {
289 buf[len_out - 1] =
'\0';
302 buf[0] ==
'P' && buf[1] ==
'W')
308 (buf[0]!=
'Y' || buf[1]!=
'R' || buf[2]!=
' '))
311 (buf[0]!=
'K' || buf[1]!=
'K' || buf[2]!=
' ') &&
312 (buf[0]!=
'A' || buf[1]!=
'F' || buf[2]!=
' '))
315 conn->response_header =
aprintf(
"NTLM %.*s", len_out - 4, buf + 3);
336 struct ntlmdata *ntlm;
348 ntlm = &conn->proxyntlm;
363 switch(ntlm->state) {
379 res = ntlm_wb_init(conn, userp);
382 res = ntlm_wb_response(conn,
"YR\n", ntlm->state);
387 *allocuserpwd =
aprintf(
"%sAuthorization: %s\r\n",
388 proxy ?
"Proxy-" :
"",
389 conn->response_header);
390 DEBUG_OUT(
fprintf(stderr,
"**** Header %s\n ", *allocuserpwd));
391 free(conn->response_header);
392 conn->response_header = NULL;
395 input =
aprintf(
"TT %s\n", conn->challenge_header);
398 res = ntlm_wb_response(conn, input, ntlm->state);
405 *allocuserpwd =
aprintf(
"%sAuthorization: %s\r\n",
406 proxy ?
"Proxy-" :
"",
407 conn->response_header);
408 DEBUG_OUT(
fprintf(stderr,
"**** %s\n ", *allocuserpwd));
411 Curl_ntlm_wb_cleanup(conn);
417 *allocuserpwd = NULL;
CURL_EXTERN char * curl_getenv(const char *variable)
struct proxy_info http_proxy
int Curl_wait_ms(int timeout_ms)
const char * Curl_strerror(struct connectdata *conn, int err)
void * Curl_saferealloc(void *ptr, size_t size)
struct connectdata::dynamically_allocated_data allocptr