FTP: handle a 230 welcome response

...instead of the 220 we otherwise expect.

Made the ftpserver.pl support sending a custom "welcome" and then
created test 1219 to verify this fix with such a 230 welcome.

Bug: http://curl.haxx.se/mail/lib-2013-02/0102.html
Reported by: Anders Havn
This commit is contained in:
Daniel Stenberg
2013-02-18 23:40:29 +01:00
parent edddf394b8
commit c5ba0c2f54
5 changed files with 78 additions and 20 deletions

View File

@@ -2711,7 +2711,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* we have now received a full FTP server response */ /* we have now received a full FTP server response */
switch(ftpc->state) { switch(ftpc->state) {
case FTP_WAIT220: case FTP_WAIT220:
if(ftpcode != 220) { if(ftpcode == 230)
/* 230 User logged in - already! */
return ftp_state_user_resp(conn, ftpcode, ftpc->state);
else if(ftpcode != 220) {
failf(data, "Got a %03d ftp-server response when 220 was expected", failf(data, "Got a %03d ftp-server response when 220 was expected",
ftpcode); ftpcode);
return CURLE_FTP_WEIRD_SERVER_REPLY; return CURLE_FTP_WEIRD_SERVER_REPLY;

View File

@@ -107,6 +107,8 @@ For FTP/SMTP/POP/IMAP, these are supported:
REPLY [command] [return value] [response string] REPLY [command] [return value] [response string]
- Changes how the server responds to the [command]. [response string] is - Changes how the server responds to the [command]. [response string] is
evaluated as a perl string, so it can contain embedded \r\n, for example. evaluated as a perl string, so it can contain embedded \r\n, for example.
There's a special [command] named "welcome" (without quotes) which is the
string sent immediately on connect as a welcome.
COUNT [command] [num] COUNT [command] [num]
- Do the REPLY change for [command] only [num] times and then go back to the - Do the REPLY change for [command] only [num] times and then go back to the
built-in approach built-in approach

View File

@@ -89,7 +89,7 @@ test1128 test1129 test1130 test1131 test1132 test1133 \
\ \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \ test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \ test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
test1216 test1217 test1218 \ test1216 test1217 test1218 test1219 \
test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \ test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
\ \
test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \ test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \

49
tests/data/test1219 Normal file
View File

@@ -0,0 +1,49 @@
<testcase>
<info>
<keywords>
FTP
PASV
RETR
</keywords>
</info>
# Server-side
<reply>
<data>
data
to
see
that FTP
works
so does it?
</data>
<servercmd>
REPLY welcome 230 welcome without password
</servercmd>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP with no user+password required (230 response)
</name>
<command>
ftp://%HOSTIP:%FTPPORT/1219
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol>
PWD
EPSV
TYPE I
SIZE 1219
RETR 1219
QUIT
</protocol>
</verify>
</testcase>

View File

@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
# #
# This software is licensed as described in the file COPYING, which # This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms # you should have received as part of this distribution. The terms
@@ -124,7 +124,6 @@ my $sockfilt_timeout = 5; # default timeout for sockfilter eXsysreads
# #
my %commandfunc; # protocol command specific function callbacks my %commandfunc; # protocol command specific function callbacks
my %displaytext; # text returned to client before callback runs my %displaytext; # text returned to client before callback runs
my @welcome; # text returned to client upon connection
#********************************************************************** #**********************************************************************
# global vars customized for each test from the server commands file # global vars customized for each test from the server commands file
@@ -547,13 +546,12 @@ sub protocolsetup {
'NOOP' => '200 Yes, I\'m very good at doing nothing.', 'NOOP' => '200 Yes, I\'m very good at doing nothing.',
'PBSZ' => '500 PBSZ not implemented', 'PBSZ' => '500 PBSZ not implemented',
'PROT' => '500 PROT not implemented', 'PROT' => '500 PROT not implemented',
); 'welcome' => join("",
@welcome = (
'220- _ _ ____ _ '."\r\n", '220- _ _ ____ _ '."\r\n",
'220- ___| | | | _ \| | '."\r\n", '220- ___| | | | _ \| | '."\r\n",
'220- / __| | | | |_) | | '."\r\n", '220- / __| | | | |_) | | '."\r\n",
'220- | (__| |_| | _ <| |___ '."\r\n", '220- | (__| |_| | _ <| |___ '."\r\n",
'220 \___|\___/|_| \_\_____|'."\r\n" '220 \___|\___/|_| \_\_____|'."\r\n")
); );
} }
elsif($proto eq 'pop3') { elsif($proto eq 'pop3') {
@@ -567,14 +565,13 @@ sub protocolsetup {
'USER' => '+OK We are happy you popped in!', 'USER' => '+OK We are happy you popped in!',
'PASS' => '+OK Access granted', 'PASS' => '+OK Access granted',
'QUIT' => '+OK byebye', 'QUIT' => '+OK byebye',
); 'welcome' => join("",
@welcome = (
' _ _ ____ _ '."\r\n", ' _ _ ____ _ '."\r\n",
' ___| | | | _ \| | '."\r\n", ' ___| | | | _ \| | '."\r\n",
' / __| | | | |_) | | '."\r\n", ' / __| | | | |_) | | '."\r\n",
' | (__| |_| | _ <| |___ '."\r\n", ' | (__| |_| | _ <| |___ '."\r\n",
' \___|\___/|_| \_\_____|'."\r\n", ' \___|\___/|_| \_\_____|'."\r\n",
'+OK cURL POP3 server ready to serve'."\r\n" '+OK cURL POP3 server ready to serve'."\r\n")
); );
} }
elsif($proto eq 'imap') { elsif($proto eq 'imap') {
@@ -590,14 +587,13 @@ sub protocolsetup {
%displaytext = ( %displaytext = (
'LOGIN' => ' OK We are happy you popped in!', 'LOGIN' => ' OK We are happy you popped in!',
'LOGOUT' => ' OK thanks for the fish', 'LOGOUT' => ' OK thanks for the fish',
); 'welcome' => join("",
@welcome = (
' _ _ ____ _ '."\r\n", ' _ _ ____ _ '."\r\n",
' ___| | | | _ \| | '."\r\n", ' ___| | | | _ \| | '."\r\n",
' / __| | | | |_) | | '."\r\n", ' / __| | | | |_) | | '."\r\n",
' | (__| |_| | _ <| |___ '."\r\n", ' | (__| |_| | _ <| |___ '."\r\n",
' \___|\___/|_| \_\_____|'."\r\n", ' \___|\___/|_| \_\_____|'."\r\n",
'* OK cURL IMAP server ready to serve'."\r\n" '* OK cURL IMAP server ready to serve'."\r\n")
); );
} }
elsif($proto eq 'smtp') { elsif($proto eq 'smtp') {
@@ -610,13 +606,12 @@ sub protocolsetup {
'MAIL' => '200 Note taken', 'MAIL' => '200 Note taken',
'RCPT' => '200 Receivers accepted', 'RCPT' => '200 Receivers accepted',
'QUIT' => '200 byebye', 'QUIT' => '200 byebye',
); 'welcome' => join("",
@welcome = (
'220- _ _ ____ _ '."\r\n", '220- _ _ ____ _ '."\r\n",
'220- ___| | | | _ \| | '."\r\n", '220- ___| | | | _ \| | '."\r\n",
'220- / __| | | | |_) | | '."\r\n", '220- / __| | | | |_) | | '."\r\n",
'220- | (__| |_| | _ <| |___ '."\r\n", '220- | (__| |_| | _ <| |___ '."\r\n",
'220 \___|\___/|_| \_\_____|'."\r\n" '220 \___|\___/|_| \_\_____|'."\r\n")
); );
} }
} }
@@ -2157,7 +2152,18 @@ while(1) {
&customize(); # read test control instructions &customize(); # read test control instructions
sendcontrol @welcome; my $welcome = $customreply{"welcome"};
if(!$welcome) {
$welcome = $displaytext{"welcome"};
}
else {
# clear it after use
$customreply{"welcome"}="";
if($welcome !~ /\r\n\z/) {
$welcome .= "\r\n";
}
}
sendcontrol $welcome;
#remove global variables from last connection #remove global variables from last connection
if($ftplistparserstate) { if($ftplistparserstate) {
@@ -2168,9 +2174,7 @@ while(1) {
} }
if($verbose) { if($verbose) {
for(@welcome) { print STDERR "OUT: $welcome";
print STDERR "OUT: $_";
}
} }
my $full = ""; my $full = "";