aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile.inc4
-rw-r--r--lib/Makefile.vc61
-rw-r--r--lib/curl_ntlm.c4
-rw-r--r--lib/curl_ntlm.h5
-rw-r--r--lib/curl_ntlm_wb.c385
-rw-r--r--lib/curl_ntlm_wb.h35
-rw-r--r--lib/http.c1
-rw-r--r--lib/http_ntlm.c326
-rw-r--r--lib/http_ntlm.h16
-rw-r--r--lib/setup.h1
-rw-r--r--packages/Symbian/group/libcurl.mmp2
11 files changed, 442 insertions, 338 deletions
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 147921d57..a724f605b 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -22,7 +22,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c polarssl.c \
curl_rtmp.c openldap.c curl_gethostname.c gopher.c axtls.c \
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
- asyn-ares.c asyn-thread.c curl_gssapi.c curl_ntlm.c
+ asyn-ares.c asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
@@ -38,4 +38,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h \
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h curl_ntlm.h \
- curl_gssapi.h
+ curl_gssapi.h curl_ntlm_wb.h
diff --git a/lib/Makefile.vc6 b/lib/Makefile.vc6
index 4c84d2b33..cbf4b8a03 100644
--- a/lib/Makefile.vc6
+++ b/lib/Makefile.vc6
@@ -507,6 +507,7 @@ X_OBJS= \
$(DIROBJ)\curl_gethostname.obj \
$(DIROBJ)\curl_memrchr.obj \
$(DIROBJ)\curl_ntlm.obj \
+ $(DIROBJ)\curl_ntlm_wb.obj \
$(DIROBJ)\curl_rand.obj \
$(DIROBJ)\curl_rtmp.obj \
$(DIROBJ)\curl_sspi.obj \
diff --git a/lib/curl_ntlm.c b/lib/curl_ntlm.c
index ea8936eb3..d4f2cc20b 100644
--- a/lib/curl_ntlm.c
+++ b/lib/curl_ntlm.c
@@ -28,7 +28,6 @@
http://www.innovation.ch/java/ntlm.html
*/
-#ifndef CURL_DISABLE_HTTP
#ifdef USE_NTLM
#define DEBUG_ME 0
@@ -47,6 +46,8 @@
#include <netdb.h>
#endif
+#define BUILDING_CURL_NTLM_C
+
#include "urldata.h"
#include "non-ascii.h" /* for Curl_convert_... prototypes */
#include "sendf.h"
@@ -1298,4 +1299,3 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
}
#endif /* USE_NTLM */
-#endif /* !CURL_DISABLE_HTTP */
diff --git a/lib/curl_ntlm.h b/lib/curl_ntlm.h
index ef3dfc1e4..fb6cad764 100644
--- a/lib/curl_ntlm.h
+++ b/lib/curl_ntlm.h
@@ -50,6 +50,9 @@ void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
/* NTLM buffer fixed size, large enough for long user + host + domain */
#define NTLM_BUFSIZE 1024
+/* Stuff only required for curl_ntlm.c */
+#ifdef BUILDING_CURL_NTLM_C
+
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
@@ -154,6 +157,8 @@ void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
#define NTLMFLAG_NEGOTIATE_56 (1<<31)
/* Indicates that 56-bit encryption is supported. */
+#endif /* BUILDING_CURL_NTLM_C */
+
#endif /* USE_NTLM */
#endif /* HEADER_CURL_NTLM_H */
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
new file mode 100644
index 000000000..fc7e09a57
--- /dev/null
+++ b/lib/curl_ntlm_wb.c
@@ -0,0 +1,385 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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
+ * are also available at http://curl.haxx.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 "setup.h"
+
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+
+#define DEBUG_ME 0
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+#include <netdb.h>
+#endif
+
+#include "urldata.h"
+#include "non-ascii.h" /* for Curl_convert_... prototypes */
+#include "sendf.h"
+#include "select.h"
+#include "rawstr.h"
+#include "curl_base64.h"
+#include "curl_ntlm_wb.h"
+#include "url.h"
+#include "strerror.h"
+#include "curl_gethostname.h"
+#include "curl_memory.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x)
+#endif
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn)
+{
+ if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
+ sclose(conn->ntlm_auth_hlpr_socket);
+ conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ }
+
+ if(conn->ntlm_auth_hlpr_pid) {
+ int i;
+ for(i = 0; i < 4; i++) {
+ pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
+ if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
+ break;
+ switch(i) {
+ case 0:
+ kill(conn->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:
+ kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
+ break;
+ case 3:
+ break;
+ }
+ }
+ conn->ntlm_auth_hlpr_pid = 0;
+ }
+
+ Curl_safefree(conn->challenge_header);
+ conn->challenge_header = NULL;
+ Curl_safefree(conn->response_header);
+ conn->response_header = NULL;
+}
+
+static CURLcode ntlm_wb_init(struct connectdata *conn, 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;
+ int error;
+
+ /* Return if communication with ntlm_auth already set up */
+ if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
+ conn->ntlm_auth_hlpr_pid)
+ return CURLE_OK;
+
+ username = userp;
+ slash = strpbrk(username, "\\/");
+ if(slash) {
+ if((domain = strdup(username)) == NULL)
+ 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) {
+ error = ERRNO;
+ failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
+ ntlm_auth, error, Curl_strerror(conn, error));
+ goto done;
+ }
+
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
+ error = ERRNO;
+ failf(conn->data, "Could not open socket pair. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ goto done;
+ }
+
+ child_pid = fork();
+ if(child_pid == -1) {
+ error = ERRNO;
+ sclose(sockfds[0]);
+ sclose(sockfds[1]);
+ failf(conn->data, "Could not fork. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ goto done;
+ }
+ else if(!child_pid) {
+ /*
+ * child process
+ */
+
+ sclose(sockfds[0]);
+
+ if(dup2(sockfds[1], STDIN_FILENO) == -1) {
+ error = ERRNO;
+ failf(conn->data, "Could not redirect child stdin. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ exit(1);
+ }
+
+ if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
+ error = ERRNO;
+ failf(conn->data, "Could not redirect child stdout. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ 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);
+
+ error = ERRNO;
+ sclose(sockfds[1]);
+ failf(conn->data, "Could not execl(). errno %d: %s",
+ error, Curl_strerror(conn, error));
+ exit(1);
+ }
+
+ sclose(sockfds[1]);
+ conn->ntlm_auth_hlpr_socket = sockfds[0];
+ conn->ntlm_auth_hlpr_pid = child_pid;
+ Curl_safefree(domain);
+ Curl_safefree(ntlm_auth_alloc);
+ return CURLE_OK;
+
+done:
+ Curl_safefree(domain);
+ Curl_safefree(ntlm_auth_alloc);
+ return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+static CURLcode ntlm_wb_response(struct connectdata *conn,
+ const char *input, curlntlm state)
+{
+ ssize_t size;
+ char buf[200]; /* enough, type 1, 3 message length is less then 200 */
+ char *tmpbuf = buf;
+ size_t len_in = strlen(input), len_out = sizeof(buf);
+
+ while(len_in > 0) {
+ ssize_t written = swrite(conn->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 */
+ while(len_out > 0) {
+ size = sread(conn->ntlm_auth_hlpr_socket, tmpbuf, len_out);
+ if(size == -1) {
+ if(errno == EINTR)
+ continue;
+ goto done;
+ }
+ else if(size == 0)
+ goto done;
+ else if(tmpbuf[size - 1] == '\n') {
+ tmpbuf[size - 1] = '\0';
+ goto wrfinish;
+ }
+ tmpbuf += size;
+ len_out -= size;
+ }
+ goto done;
+wrfinish:
+ /* Samba/winbind installed but not configured */
+ if(state == NTLMSTATE_TYPE1 &&
+ size == 3 &&
+ buf[0] == 'P' && buf[1] == 'W')
+ return CURLE_REMOTE_ACCESS_DENIED;
+ /* invalid response */
+ if(size < 4)
+ goto done;
+ if(state == NTLMSTATE_TYPE1 &&
+ (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
+ goto done;
+ if(state == NTLMSTATE_TYPE2 &&
+ (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
+ (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
+ goto done;
+
+ conn->response_header = aprintf("NTLM %.*s", size - 4, buf + 3);
+ return CURLE_OK;
+done:
+ return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+/*
+ * 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 correct struct with this */
+ struct ntlmdata *ntlm;
+ struct auth *authp;
+
+ CURLcode res = CURLE_OK;
+ char *input;
+
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->data);
+
+ if(proxy) {
+ allocuserpwd = &conn->allocptr.proxyuserpwd;
+ userp = conn->proxyuser;
+ ntlm = &conn->proxyntlm;
+ authp = &conn->data->state.authproxy;
+ }
+ else {
+ allocuserpwd = &conn->allocptr.userpwd;
+ userp = conn->user;
+ ntlm = &conn->ntlm;
+ authp = &conn->data->state.authhost;
+ }
+ authp->done = FALSE;
+
+ /* not set means empty */
+ if(!userp)
+ userp="";
+
+ switch(ntlm->state) {
+ case NTLMSTATE_TYPE1:
+ default:
+ /* Use Samba's 'winbind' daemon to support NTLM authentication,
+ * by delegating the NTLM challenge/response protocal to a helper
+ * in ntlm_auth.
+ * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
+ * http://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
+ * http://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 */
+ res = ntlm_wb_init(conn, userp);
+ if(res)
+ return res;
+ res = ntlm_wb_response(conn, "YR\n", ntlm->state);
+ if(res)
+ return res;
+
+ Curl_safefree(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+ proxy ? "Proxy-" : "",
+ conn->response_header);
+ DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+ Curl_safefree(conn->response_header);
+ conn->response_header = NULL;
+ break;
+ case NTLMSTATE_TYPE2:
+ input = aprintf("TT %s", conn->challenge_header);
+ if(!input)
+ return CURLE_OUT_OF_MEMORY;
+ res = ntlm_wb_response(conn, input, ntlm->state);
+ free(input);
+ input = NULL;
+ if(res)
+ return res;
+
+ Curl_safefree(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+ proxy ? "Proxy-" : "",
+ conn->response_header);
+ DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+ ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
+ authp->done = TRUE;
+ Curl_ntlm_wb_cleanup(conn);
+ break;
+ case NTLMSTATE_TYPE3:
+ /* connection is already authenticated,
+ * don't send a header in future requests */
+ if(*allocuserpwd) {
+ free(*allocuserpwd);
+ *allocuserpwd=NULL;
+ }
+ authp->done = TRUE;
+ break;
+ }
+
+ return CURLE_OK;
+}
+
+#endif /* USE_NTLM && NTLM_WB_ENABLED */
diff --git a/lib/curl_ntlm_wb.h b/lib/curl_ntlm_wb.h
new file mode 100644
index 000000000..b7448a736
--- /dev/null
+++ b/lib/curl_ntlm_wb.h
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_NTLM_WB_H
+#define HEADER_CURL_NTLM_WB_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, 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
+ * are also available at http://curl.haxx.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.
+ *
+ ***************************************************************************/
+
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+
+/* 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);
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn);
+
+#endif
+
+#endif /* HEADER_CURL_NTLM_WB_H */
diff --git a/lib/http.c b/lib/http.c
index c1a94712e..36062d7c2 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -63,6 +63,7 @@
#include "sslgen.h"
#include "http_digest.h"
#include "http_ntlm.h"
+#include "curl_ntlm_wb.h"
#include "http_negotiate.h"
#include "url.h"
#include "share.h"
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index 8d9a8a1b5..f7defe0a8 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -28,7 +28,6 @@
http://www.innovation.ch/java/ntlm.html
*/
-#ifndef CURL_DISABLE_HTTP
#ifdef USE_NTLM
#define DEBUG_ME 0
@@ -54,6 +53,8 @@
#include "rawstr.h"
#include "curl_base64.h"
#include "http_ntlm.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_wb.h"
#include "url.h"
#include "strerror.h"
#include "curl_gethostname.h"
@@ -124,326 +125,6 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
return result;
}
-#ifdef NTLM_WB_ENABLED
-static void ntlm_wb_cleanup(struct connectdata *conn)
-{
- if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
- sclose(conn->ntlm_auth_hlpr_socket);
- conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
- }
-
- if(conn->ntlm_auth_hlpr_pid) {
- int i;
- for(i = 0; i < 4; i++) {
- pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
- if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
- break;
- switch(i) {
- case 0:
- kill(conn->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:
- kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
- break;
- case 3:
- break;
- }
- }
- conn->ntlm_auth_hlpr_pid = 0;
- }
-
- Curl_safefree(conn->challenge_header);
- conn->challenge_header = NULL;
- Curl_safefree(conn->response_header);
- conn->response_header = NULL;
-}
-
-static CURLcode ntlm_wb_init(struct connectdata *conn, 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;
- int error;
-
- /* Return if communication with ntlm_auth already set up */
- if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
- conn->ntlm_auth_hlpr_pid)
- return CURLE_OK;
-
- username = userp;
- slash = strpbrk(username, "\\/");
- if(slash) {
- if((domain = strdup(username)) == NULL)
- 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) {
- error = ERRNO;
- failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
- ntlm_auth, error, Curl_strerror(conn, error));
- goto done;
- }
-
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
- error = ERRNO;
- failf(conn->data, "Could not open socket pair. errno %d: %s",
- error, Curl_strerror(conn, error));
- goto done;
- }
-
- child_pid = fork();
- if(child_pid == -1) {
- error = ERRNO;
- sclose(sockfds[0]);
- sclose(sockfds[1]);
- failf(conn->data, "Could not fork. errno %d: %s",
- error, Curl_strerror(conn, error));
- goto done;
- }
- else if(!child_pid) {
- /*
- * child process
- */
-
- sclose(sockfds[0]);
-
- if(dup2(sockfds[1], STDIN_FILENO) == -1) {
- error = ERRNO;
- failf(conn->data, "Could not redirect child stdin. errno %d: %s",
- error, Curl_strerror(conn, error));
- exit(1);
- }
-
- if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
- error = ERRNO;
- failf(conn->data, "Could not redirect child stdout. errno %d: %s",
- error, Curl_strerror(conn, error));
- 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);
-
- error = ERRNO;
- sclose(sockfds[1]);
- failf(conn->data, "Could not execl(). errno %d: %s",
- error, Curl_strerror(conn, error));
- exit(1);
- }
-
- sclose(sockfds[1]);
- conn->ntlm_auth_hlpr_socket = sockfds[0];
- conn->ntlm_auth_hlpr_pid = child_pid;
- Curl_safefree(domain);
- Curl_safefree(ntlm_auth_alloc);
- return CURLE_OK;
-
-done:
- Curl_safefree(domain);
- Curl_safefree(ntlm_auth_alloc);
- return CURLE_REMOTE_ACCESS_DENIED;
-}
-
-static CURLcode ntlm_wb_response(struct connectdata *conn,
- const char *input, curlntlm state)
-{
- ssize_t size;
- char buf[200]; /* enough, type 1, 3 message length is less then 200 */
- char *tmpbuf = buf;
- size_t len_in = strlen(input), len_out = sizeof(buf);
-
- while(len_in > 0) {
- ssize_t written = swrite(conn->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 */
- while(len_out > 0) {
- size = sread(conn->ntlm_auth_hlpr_socket, tmpbuf, len_out);
- if(size == -1) {
- if(errno == EINTR)
- continue;
- goto done;
- }
- else if(size == 0)
- goto done;
- else if(tmpbuf[size - 1] == '\n') {
- tmpbuf[size - 1] = '\0';
- goto wrfinish;
- }
- tmpbuf += size;
- len_out -= size;
- }
- goto done;
-wrfinish:
- /* Samba/winbind installed but not configured */
- if(state == NTLMSTATE_TYPE1 &&
- size == 3 &&
- buf[0] == 'P' && buf[1] == 'W')
- return CURLE_REMOTE_ACCESS_DENIED;
- /* invalid response */
- if(size < 4)
- goto done;
- if(state == NTLMSTATE_TYPE1 &&
- (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
- goto done;
- if(state == NTLMSTATE_TYPE2 &&
- (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
- (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
- goto done;
-
- conn->response_header = aprintf("NTLM %.*s", size - 4, buf + 3);
- return CURLE_OK;
-done:
- return CURLE_REMOTE_ACCESS_DENIED;
-}
-
-/*
- * 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 correct struct with this */
- struct ntlmdata *ntlm;
- struct auth *authp;
-
- CURLcode res = CURLE_OK;
- char *input;
-
- DEBUGASSERT(conn);
- DEBUGASSERT(conn->data);
-
- if(proxy) {
- allocuserpwd = &conn->allocptr.proxyuserpwd;
- userp = conn->proxyuser;
- ntlm = &conn->proxyntlm;
- authp = &conn->data->state.authproxy;
- }
- else {
- allocuserpwd = &conn->allocptr.userpwd;
- userp = conn->user;
- ntlm = &conn->ntlm;
- authp = &conn->data->state.authhost;
- }
- authp->done = FALSE;
-
- /* not set means empty */
- if(!userp)
- userp="";
-
- switch(ntlm->state) {
- case NTLMSTATE_TYPE1:
- default:
- /* Use Samba's 'winbind' daemon to support NTLM authentication,
- * by delegating the NTLM challenge/response protocal to a helper
- * in ntlm_auth.
- * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
- * http://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
- * http://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 */
- res = ntlm_wb_init(conn, userp);
- if(res)
- return res;
- res = ntlm_wb_response(conn, "YR\n", ntlm->state);
- if(res)
- return res;
-
- Curl_safefree(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
- proxy ? "Proxy-" : "",
- conn->response_header);
- DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
- Curl_safefree(conn->response_header);
- conn->response_header = NULL;
- break;
- case NTLMSTATE_TYPE2:
- input = aprintf("TT %s", conn->challenge_header);
- if(!input)
- return CURLE_OUT_OF_MEMORY;
- res = ntlm_wb_response(conn, input, ntlm->state);
- free(input);
- input = NULL;
- if(res)
- return res;
-
- Curl_safefree(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
- proxy ? "Proxy-" : "",
- conn->response_header);
- DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
- ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
- authp->done = TRUE;
- ntlm_wb_cleanup(conn);
- break;
- case NTLMSTATE_TYPE3:
- /* connection is already authenticated,
- * don't send a header in future requests */
- if(*allocuserpwd) {
- free(*allocuserpwd);
- *allocuserpwd=NULL;
- }
- authp->done = TRUE;
- break;
- }
-
- return CURLE_OK;
-}
-#endif /* NTLM_WB_ENABLED */
-
/*
* This is for creating ntlm header output
*/
@@ -563,11 +244,10 @@ void Curl_http_ntlm_cleanup(struct connectdata *conn)
Curl_ntlm_sspi_cleanup(&conn->ntlm);
Curl_ntlm_sspi_cleanup(&conn->proxyntlm);
#elif defined(NTLM_WB_ENABLED)
- ntlm_wb_cleanup(conn);
+ Curl_ntlm_wb_cleanup(conn);
#else
(void)conn;
#endif
}
#endif /* USE_NTLM */
-#endif /* !CURL_DISABLE_HTTP */
diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h
index 635d6313b..a074380a3 100644
--- a/lib/http_ntlm.h
+++ b/lib/http_ntlm.h
@@ -22,6 +22,8 @@
*
***************************************************************************/
+#ifdef USE_NTLM
+
/* this is for ntlm header input */
CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
const char *header);
@@ -29,18 +31,12 @@ CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
-#ifdef NTLM_WB_ENABLED
-/* 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);
-#endif
-
-#ifdef USE_NTLM
void Curl_http_ntlm_cleanup(struct connectdata *conn);
+
#else
-#define Curl_http_ntlm_cleanup(x)
-#endif
-#include "curl_ntlm.h"
+#define Curl_http_ntlm_cleanup(a)
+
+#endif
#endif /* HEADER_CURL_HTTP_NTLM_H */
diff --git a/lib/setup.h b/lib/setup.h
index f90cf8f31..c821bc6b4 100644
--- a/lib/setup.h
+++ b/lib/setup.h
@@ -568,6 +568,7 @@ int netware_init(void);
#define USE_HTTP_NEGOTIATE
#endif
+/* Single point where USE_NTLM definition might be done */
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM)
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) || \
defined(USE_GNUTLS) || defined(USE_NSS)
diff --git a/packages/Symbian/group/libcurl.mmp b/packages/Symbian/group/libcurl.mmp
index 8793892d0..1420ce886 100644
--- a/packages/Symbian/group/libcurl.mmp
+++ b/packages/Symbian/group/libcurl.mmp
@@ -36,7 +36,7 @@ SOURCE \
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c polarssl.c \
curl_rtmp.c openldap.c curl_gethostname.c gopher.c axtls.c \
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
- asyn-ares.c asyn-thread.c curl_ntlm.c
+ asyn-ares.c asyn-thread.c curl_ntlm.c curl_ntlm_wb.c
USERINCLUDE ../../../lib ../../../include/curl
#ifdef ENABLE_SSL