aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--RELEASE-NOTES8
-rw-r--r--docs/curl.15
-rw-r--r--docs/libcurl/curl_easy_setopt.36
-rw-r--r--include/curl/curl.h7
-rw-r--r--lib/ftp.c16
-rw-r--r--lib/url.c4
-rw-r--r--lib/urldata.h4
-rw-r--r--src/main.c8
9 files changed, 55 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index d2c219bf4..29c2aa263 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,10 @@
Changelog
Daniel (26 July 2006)
+- Dan Nelson added the CURLOPT_FTP_ALTERNATIVE_TO_USER libcurl option and curl
+ tool option named --ftp-alternative-to-user. It provides a mean to send a
+ particular command if the normal USER/PASS approach fails.
+
- Michael Jerris added magic that builds lib/curllib.vcproj automatically for
newer MSVC.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 1eef7be4f..a29daea1a 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -2,8 +2,8 @@ Curl and libcurl 7.15.5
Public curl release number: 95
Releases counted from the very beginning: 122
- Available command line options: 112
- Available curl_easy_setopt() options: 132
+ Available command line options: 113
+ Available curl_easy_setopt() options: 133
Number of public functions in libcurl: 49
Amount of public web site mirrors: 33
Number of known libcurl bindings: 32
@@ -11,6 +11,8 @@ Curl and libcurl 7.15.5
This release includes the following changes:
+ o added CURLOPT_FTP_ALTERNATIVE_TO_USER and --ftp-alternative-to-user
+ o now includes a vcproj file for building libcurl
o added curl_formget()
o added CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE
o configure --enable-hidden-symbols
@@ -41,6 +43,6 @@ advice from friends like these:
Dan Fandrich, Peter Silva, Arve Knudsen, Michael Wallner, Toshiyuki Maezawa,
Ingmar Runge, Ates Goral, David McCreedy, Jari Sundell, Georg Horn,
- Gisle Vanem, Yang Tse
+ Gisle Vanem, Yang Tse, Michael Jerris, Dan Nelson
Thanks! (and sorry if I forgot to mention someone)
diff --git a/docs/curl.1 b/docs/curl.1
index d99fbceaa..de72eb5b6 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -396,6 +396,11 @@ in 7.11.0)
If this option is used several times, the following occurrences make no
difference.
+.IP "--ftp-alternative-to-user <command>"
+(FTP) If authenticating with the USER and PASS commands fails, send this
+command. When connecting to Tumbleweed's Secure Transport server over FTPS
+using a client certificate, using "SITE AUTH" will tell the server to retrieve
+the username from the certificate. (Added in 7.15.5)
.IP "--ftp-skip-pasv-ip"
(FTP) Tell curl to not use the IP address the server suggests in its response
to curl's PASV command when curl connects the data connection. Instead curl
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index c4b969577..6ac538a7a 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -859,6 +859,12 @@ waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It is
recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set
\fICURLOPT_FTP_RESPONSE_TIMEOUT\fP to a value smaller than
\fICURLOPT_TIMEOUT\fP. (Added in 7.10.8)
+.IP CURLOPT_FTP_ALTERNATIVE_TO_USER
+Pass a char * as parameter, pointing to a string which will be used to
+authenticate if the usual FTP "USER user" and "PASS password" negotiation
+fails. This is currently only known to be required when connecting to
+Tumbleweed's Secure Transport FTPS server using client certificates for
+authentication. (Added in 7.15.5)
.IP CURLOPT_FTP_SKIP_PASV_IP
Pass a long. If set to a non-zero value, it instructs libcurl to not use the
IP address the server suggests in its 227-response to libcurl's PASV command
diff --git a/include/curl/curl.h b/include/curl/curl.h
index b9b341dee..db14fe1f5 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -61,14 +61,14 @@ extern "C" {
#ifdef CURL_HIDDEN_SYMBOLS
/*
- * This definition is used to make external definitions visibile in the
+ * This definition is used to make external definitions visibile in the
* shared library when symbols are hidden by default. It makes no
* difference when compiling applications whether this is set or not,
* only when compiling the library.
*/
#define CURL_EXTERN CURL_EXTERN_SYMBOL
#else
-#define CURL_EXTERN
+#define CURL_EXTERN
#endif
#endif
@@ -979,6 +979,9 @@ typedef enum {
CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+ /* Pointer to command string to send if USER/PASS fails. */
+ CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff --git a/lib/ftp.c b/lib/ftp.c
index c27030504..c17d9fbaa 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -699,6 +699,7 @@ static CURLcode ftp_state_user(struct connectdata *conn)
NBFTPSENDF(conn, "USER %s", ftp->user?ftp->user:"");
state(conn, FTP_USER);
+ conn->data->state.ftp_trying_alternative = FALSE;
return CURLE_OK;
}
@@ -2302,8 +2303,19 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
530 User ... access denied
(the server denies to log the specified user) */
- failf(data, "Access denied: %03d", ftpcode);
- result = CURLE_LOGIN_DENIED;
+
+ if (conn->data->set.ftp_alternative_to_user &&
+ !conn->data->state.ftp_trying_alternative) {
+ /* Ok, USER failed. Let's try the supplied command. */
+ NBFTPSENDF(conn, "%s", conn->data->set.ftp_alternative_to_user);
+ conn->data->state.ftp_trying_alternative = TRUE;
+ state(conn, FTP_USER);
+ result = CURLE_OK;
+ }
+ else {
+ failf(data, "Access denied: %03d", ftpcode);
+ result = CURLE_LOGIN_DENIED;
+ }
}
return result;
}
diff --git a/lib/url.c b/lib/url.c
index 17e3a7f57..b25d02be8 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1546,6 +1546,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.connect_only = va_arg(param, long)?TRUE:FALSE;
break;
+ case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+ data->set.ftp_alternative_to_user = va_arg(param, char *);
+ break;
+
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_FAILED_INIT; /* correct this */
diff --git a/lib/urldata.h b/lib/urldata.h
index 63ccfe70a..c804105b6 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -937,6 +937,9 @@ struct UrlState {
/* a place to store the most recenlty set FTP entrypath */
char *most_recent_ftp_entrypath;
+ /* set after initial USER failure, to prevent an authentication loop */
+ bool ftp_trying_alternative;
+
#ifndef WIN32
/* do FTP line-end conversions on most platforms */
#define CURL_DO_LINEEND_CONV
@@ -1054,6 +1057,7 @@ struct UserDefined {
bool cookiesession; /* new cookie session? */
bool crlf; /* convert crlf on ftp upload(?) */
char *ftp_account; /* ftp account data */
+ char *ftp_alternative_to_user; /* command to send if USER/PASS fails */
struct curl_slist *quote; /* after connection is established */
struct curl_slist *postquote; /* after the transfer */
struct curl_slist *prequote; /* before the transfer, after type */
diff --git a/src/main.c b/src/main.c
index 3e717a3d2..af20a396c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -353,6 +353,7 @@ struct Configurable {
struct curl_slist *tp_postquote;
struct curl_slist *tp_prequote;
char *ftp_account; /* for ACCT */
+ char *ftp_alternative_to_user; /* send command if USER/PASS fails */
int ftp_filemethod;
bool ignorecl; /* --ignore-content-length */
@@ -1340,6 +1341,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"$r", "ftp-method", TRUE},
{"$s", "local-port", TRUE},
{"$t", "socks4", TRUE},
+ {"$u", "ftp-alternative-to-user", TRUE},
{"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE},
@@ -1776,6 +1778,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
}
}
break;
+ case 'u': /* --ftp-alternative-to-user */
+ GetStr(&config->ftp_alternative_to_user, nextarg);
+ break;
}
break;
case '#': /* --progress-bar */
@@ -3998,6 +4003,9 @@ operate(struct Configurable *config, int argc, char *argv[])
curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, config->localportrange);
}
+ /* curl x.xx.x */
+ curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, config->ftp_alternative_to_user);
+
retry_numretries = config->req_retry;
retrystart = curlx_tvnow();