aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/inets/src/ftp/ftp.erl218
-rw-r--r--lib/inets/test/ftp_SUITE.erl49
-rw-r--r--lib/inets/test/ftp_SUITE_data/vsftpd.conf10
3 files changed, 146 insertions, 131 deletions
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index 98f4276eeb..df2ee7d201 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -18,7 +18,7 @@
%%
%%
%% Description: This module implements an ftp client, RFC 959.
-%% It also supports ipv6 RFC 2428.
+%% It also supports ipv6 RFC 2428 and starttls RFC 4217.
-module(ftp).
@@ -92,7 +92,7 @@
ipfamily, % inet | inet6 | inet6fb4
progress = ignore, % ignore | pid()
dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity
- tls_upgrading_data_connection = {false,undefined}
+ tls_upgrading_data_connection = false
}).
@@ -101,6 +101,8 @@
-type common_reason() :: 'econn' | 'eclosed' | term().
-type file_write_error_reason() :: term(). % See file:write for more info
+%%-define(DBG(F,A), 'n/a').
+-define(DBG(F,A), io:format(F,A)).
%%%=========================================================================
%%% API - CLIENT FUNCTIONS
@@ -1315,61 +1317,63 @@ handle_info(timeout, State) ->
{noreply, State};
%%% Data socket messages %%%
-handle_info({tcp, Socket, Data},
- #state{dsock = {tcp,Socket},
- caller = {recv_file, Fd}} = State0) ->
- io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]),
+handle_info({Trpt, Socket, Data},
+ #state{dsock = {Trpt,Socket},
+ caller = {recv_file, Fd}} = State0) when Trpt==tcp;Trpt==ssl ->
+ ?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]),
file_write(binary_to_list(Data), Fd),
progress_report({binary, Data}, State0),
State = activate_data_connection(State0),
{noreply, State};
-handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}, client = From,
+handle_info({Trpt, Socket, Data}, #state{dsock = {Trpt,Socket}, client = From,
caller = recv_chunk}
- = State) ->
- io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State]),
+ = State) when Trpt==tcp;Trpt==ssl ->
+ ?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State]),
gen_server:reply(From, {ok, Data}),
{noreply, State#state{client = undefined, data = <<>>}};
-handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}} = State0) ->
- io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]),
+handle_info({Trpt, Socket, Data}, #state{dsock = {Trpt,Socket}} = State0) when Trpt==tcp;Trpt==ssl ->
+ ?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]),
State = activate_data_connection(State0),
{noreply, State#state{data = <<(State#state.data)/binary,
Data/binary>>}};
-handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket},
+handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket},
caller = {recv_file, Fd}}
- = State) ->
+ = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
file_close(Fd),
progress_report({transfer_size, 0}, State),
activate_ctrl_connection(State),
{noreply, State#state{dsock = undefined, data = <<>>}};
-handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, client = From,
+handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, client = From,
caller = recv_chunk}
- = State) ->
+ = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
gen_server:reply(From, ok),
{noreply, State#state{dsock = undefined, client = undefined,
data = <<>>, caller = undefined,
chunk = false}};
-handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, caller = recv_bin,
- data = Data} = State) ->
+handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, caller = recv_bin,
+ data = Data} = State)
+ when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
activate_ctrl_connection(State),
{noreply, State#state{dsock = undefined, data = <<>>,
caller = {recv_bin, Data}}};
-handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, data = Data,
+handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, data = Data,
caller = {handle_dir_result, Dir}}
- = State) ->
+ = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
activate_ctrl_connection(State),
{noreply, State#state{dsock = undefined,
caller = {handle_dir_result, Dir, Data},
% data = <<?CR,?LF>>}};
data = <<>>}};
-
-handle_info({tcp_error, Socket, Reason}, #state{dsock = Socket,
- client = From} = State) ->
+
+handle_info({Err, Socket, Reason}, #state{dsock = {Trpt,Socket},
+ client = From} = State)
+ when {Err,Trpt}=={tcp_error,tcp} ; {Err,Trpt}=={ssl_error,ssl} ->
gen_server:reply(From, {error, Reason}),
close_data_connection(State),
{noreply, State#state{dsock = undefined, client = undefined,
@@ -1383,7 +1387,7 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket},
ctrl_data = {CtrlData, AccLines,
LineStatus}}
= State) ->
- io:format('--ctrl ~p ----> ~s~p~n',[Socket,<<CtrlData/binary, Data/binary>>,State]),
+ ?DBG('--ctrl ~p ----> ~s~p~n',[Socket,<<CtrlData/binary, Data/binary>>,State]),
case ftp_response:parse_lines(<<CtrlData/binary, Data/binary>>,
AccLines, LineStatus) of
{ok, Lines, NextMsgData} ->
@@ -1397,34 +1401,31 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket},
ctrl_data = {NextMsgData, [],
start}}};
_ ->
- io:format(' ...handle_ctrl_result(~p,...) ctrl_data=~p~n',[CtrlResult,{NextMsgData, [], start}]),
+ ?DBG(' ...handle_ctrl_result(~p,...) ctrl_data=~p~n',[CtrlResult,{NextMsgData, [], start}]),
handle_ctrl_result(CtrlResult,
State#state{ctrl_data =
{NextMsgData, [], start}})
end;
{continue, NewCtrlData} ->
- io:format(' ...Continue... ctrl_data=~p~n',[NewCtrlData]),
+ ?DBG(' ...Continue... ctrl_data=~p~n',[NewCtrlData]),
activate_ctrl_connection(State),
{noreply, State#state{ctrl_data = NewCtrlData}}
end;
%% If the server closes the control channel it is
%% the expected behavior that connection process terminates.
-handle_info({tcp_closed, Socket}, #state{csock = {tcp, Socket}}) ->
+handle_info({Cls, Socket}, #state{csock = {Trpt, Socket}})
+ when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
exit(normal); %% User will get error message from terminate/2
-handle_info({ssl_closed, Socket}, #state{csock = {ssl, Socket}}) ->
- exit(normal);
-handle_info({tcp_error, Socket, Reason}, _) ->
+handle_info({Err, Socket, Reason}, _) when Err==tcp_error ; Err==ssl_error ->
Report =
- io_lib:format("tcp_error on socket: ~p for reason: ~p~n",
- [Socket, Reason]),
+ io_lib:format("~p on socket: ~p for reason: ~p~n",
+ [Err, Socket, Reason]),
error_logger:error_report(Report),
%% If tcp does not work the only option is to terminate,
%% this is the expected behavior under these circumstances.
exit(normal); %% User will get error message from terminate/2
-handle_info({ssl_error, _Socket, _Reason}, _) ->
- exit(normal); %% TODO??
%% Monitor messages - if the process owning the ftp connection goes
%% down there is no point in continuing.
@@ -1592,44 +1593,36 @@ handle_user_account(Acc, State) ->
%%--------------------------------------------------------------------------
%% handle_ctrl_result
%%--------------------------------------------------------------------------
-%%--------------------------------------------------------------------------
-%% Handling of control connection setup
-handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, pbsz, _}} = State) ->
- send_ctrl_message(State, mk_cmd("PROT P", [])),
- activate_ctrl_connection(State),
- {noreply, State#state{tls_upgrading_data_connection = {true, prot, undefined}}};
-
-handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot, NextAction},
- dsock = {tcp, Socket}, client = From,
- tls_options = TLSOptions} = State0) ->
- io:format('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]),
- case ssl:connect(Socket, TLSOptions) of
- {ok, TLSSocket} ->
- State = State0#state{dsock = {ssl, TLSSocket},
- tls_upgrading_data_connection = {false, undefined}},
- next_action_after_tls_upgrade(NextAction, State);
- {error, _} = Error ->
- gen_server:reply(From, {Error, self()}),
- {stop, normal, State0#state{client = undefined,
- caller = undefined}}
- end;
-
handle_ctrl_result({tls_upgrade, _}, #state{csock = {tcp, Socket},
tls_options = TLSOptions,
caller = open, client = From}
- = State) ->
- io:format('<--ctrl ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State]),
+ = State0) ->
+ ?DBG('<--ctrl ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]),
case ssl:connect(Socket, TLSOptions) of
{ok, TLSSocket} ->
- gen_server:reply(From, {ok, self()}),
- {noreply, State#state{csock = {ssl, TLSSocket},
- client = undefined,
- caller = undefined }};
+ State = State0#state{csock = {ssl,TLSSocket}},
+ send_ctrl_message(State, mk_cmd("PBSZ 0", [])),
+ activate_ctrl_connection(State),
+ {noreply, State#state{tls_upgrading_data_connection = {true, pbsz}} };
{error, _} = Error ->
gen_server:reply(From, {Error, self()}),
- {stop, normal, State#state{client = undefined,
- caller = undefined}}
+ {stop, normal, State0#state{client = undefined,
+ caller = undefined,
+ tls_upgrading_data_connection = false}}
end;
+
+handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, pbsz}} = State) ->
+ send_ctrl_message(State, mk_cmd("PROT P", [])),
+ activate_ctrl_connection(State),
+ {noreply, State#state{tls_upgrading_data_connection = {true, prot}}};
+
+handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot},
+ client = From} = State) ->
+ gen_server:reply(From, {ok, self()}),
+ {noreply, State#state{client = undefined,
+ caller = undefined,
+ tls_upgrading_data_connection = false}};
+
handle_ctrl_result({pos_compl, _}, #state{caller = open, client = From}
= State) ->
gen_server:reply(From, {ok, self()}),
@@ -1676,7 +1669,7 @@ handle_ctrl_result({pos_compl, Lines},
#state{mode = passive,
ipfamily = inet,
client = From,
- caller = {setup_data_connection, Caller},
+ caller = {setup_data_connection, Caller},
timeout = Timeout} = State) ->
{_, [?LEFT_PAREN | Rest]} =
@@ -1688,9 +1681,10 @@ handle_ctrl_result({pos_compl, Lines},
string:tokens(NewPortAddr, [$,])),
IP = {A1, A2, A3, A4},
Port = (P1 * 256) + P2,
-io:format('tcp connect to ~p:~p, Caller=~p~n',[IP,Port,Caller]),
+
+ ?DBG('<--data tcp connect to ~p:~p, Caller=~p~n',[IP,Port,Caller]),
case connect(IP, Port, Timeout, State) of
- {ok, _, Socket} ->
+ {ok, _, Socket} ->
handle_caller(State#state{caller = Caller, dsock = {tcp,Socket}});
{error, _Reason} = Error ->
gen_server:reply(From, Error),
@@ -2132,25 +2126,46 @@ connect2(Host, Port, IpFam, Timeout) ->
accept_data_connection(#state{mode = active,
dtimeout = DTimeout,
+ tls_options = TLSOptions,
dsock = {lsock, LSock}} = State0) ->
case gen_tcp:accept(LSock, DTimeout) of
+ {ok, Socket} when is_list(TLSOptions) ->
+ gen_tcp:close(LSock),
+ ?DBG('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]),
+ case ssl:connect(Socket, TLSOptions) of
+ {ok, TLSSocket} ->
+ {ok, State0#state{dsock={ssl,TLSSocket}}};
+ {error, Reason} ->
+ {error, {ssl_connect_failed, Reason}}
+ end;
{ok, Socket} ->
gen_tcp:close(LSock),
- maybe_requests_tls_upgrade(State0#state{dsock = {tcp, Socket}});
+ {ok, State0#state{dsock={tcp,Socket}}};
{error, Reason} ->
{error, {data_connect_failed, Reason}}
end;
+accept_data_connection(#state{mode = passive,
+ dsock = {tcp,Socket},
+ tls_options = TLSOptions} = State) when is_list(TLSOptions) ->
+ ?DBG('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State]),
+ case ssl:connect(Socket, TLSOptions) of
+ {ok, TLSSocket} ->
+ {ok, State#state{dsock={ssl,TLSSocket}}};
+ {error, Reason} ->
+ {error, {ssl_connect_failed, Reason}}
+ end;
accept_data_connection(#state{mode = passive} = State) ->
- maybe_requests_tls_upgrade(State).
+ {ok,State}.
+
send_ctrl_message(S=#state{csock = Socket, verbose = Verbose}, Message) ->
verbose(lists:flatten(Message),Verbose,send),
- io:format('<--ctrl ~p ---- ~s~p~n',[Socket,Message,S]),
+ ?DBG('<--ctrl ~p ---- ~s~p~n',[Socket,Message,S]),
send_message(Socket, Message).
send_data_message(S=#state{dsock = Socket}, Message) ->
- io:format('<==data ~p ==== ~s~p~n',[Socket,Message,S]),
+ ?DBG('<==data ~p ==== ~s~p~n',[Socket,Message,S]),
case send_message(Socket, Message) of
ok ->
ok;
@@ -2173,34 +2188,28 @@ activate_ctrl_connection(#state{csock = Socket, ctrl_data = {<<>>, _, _}}) ->
activate_ctrl_connection(#state{csock = Socket}) ->
%% We have already received at least part of the next control message,
%% that has been saved in ctrl_data, process this first.
- self() ! {tcp, Socket, <<>>}.
+ self() ! {tcp, unwrap_socket(Socket), <<>>}.
-activate_data_connection(#state{tls_upgrading_data_connection = {false, _},
- dsock = Socket} = State) ->
+unwrap_socket({tcp,Socket}) -> Socket;
+unwrap_socket({ssl,Socket}) -> Socket;
+unwrap_socket(Socket) -> Socket.
+
+
+activate_data_connection(#state{dsock = Socket} = State) ->
activate_connection(Socket),
- State;
-activate_data_connection(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) ->
- State#state{tls_upgrading_data_connection = {true, CTRL, {?MODULE,activate_data_connection,undefined}}}.
+ State.
-activate_connection({tcp, Socket}) ->
- inet:setopts(Socket, [{active, once}]);
-activate_connection({ssl, Socket}) ->
- ssl:setopts(Socket, [{active, once}]).
+activate_connection({tcp, Socket}) -> inet:setopts(Socket, [{active, once}]);
+activate_connection({ssl, Socket}) -> ssl:setopts(Socket, [{active, once}]).
-close_ctrl_connection(#state{csock = undefined}) ->
- ok;
-close_ctrl_connection(#state{csock = Socket}) ->
- close_connection(Socket).
+close_ctrl_connection(#state{csock = undefined}) -> ok;
+close_ctrl_connection(#state{csock = Socket}) -> close_connection(Socket).
-close_data_connection(#state{dsock = undefined}) ->
- ok;
-close_data_connection(#state{dsock = Socket}) ->
- close_connection(Socket).
+close_data_connection(#state{dsock = undefined}) -> ok;
+close_data_connection(#state{dsock = Socket}) -> close_connection(Socket).
-close_connection({tcp, Socket}) ->
- gen_tcp:close(Socket);
-close_connection({ssl, Socket}) ->
- ssl:close(Socket).
+close_connection({tcp, Socket}) -> gen_tcp:close(Socket);
+close_connection({ssl, Socket}) -> ssl:close(Socket).
%% ------------ FILE HANDELING ----------------------------------------
send_file(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State, Fd) ->
@@ -2318,14 +2327,11 @@ millisec_time() ->
{A,B,C} = erlang:now(),
A*1000000000+B*1000+(C div 1000).
-peername({tcp, Socket}) ->
- inet:peername(Socket);
-peername({ssl, Socket}) ->
- ssl:peername(Socket).
-sockname({tcp, Socket}) ->
- inet:peername(Socket);
-sockname({ssl, Socket}) ->
- ssl:peername(Socket).
+peername({tcp, Socket}) -> inet:peername(Socket);
+peername({ssl, Socket}) -> ssl:peername(Socket).
+
+sockname({tcp, Socket}) -> inet:peername(Socket);
+sockname({ssl, Socket}) -> ssl:peername(Socket).
maybe_tls_upgrade(Pid, undefined) ->
{ok, Pid};
@@ -2333,18 +2339,6 @@ maybe_tls_upgrade(Pid, TLSOptions) ->
catch ssl:start(),
call(Pid, {open, tls_upgrade, TLSOptions}, plain).
-maybe_requests_tls_upgrade(#state{tls_options=undefined} = State) ->
- {ok, State};
-maybe_requests_tls_upgrade(State) ->
- send_ctrl_message(State, mk_cmd("PBSZ 0", [])),
- activate_ctrl_connection(State),
- {ok, State#state{tls_upgrading_data_connection = {true, pbsz, undefined}}}.
-
-next_action_after_tls_upgrade({M, F, undefined}, State) ->
- M:F(State);
-next_action_after_tls_upgrade({M, F, A}, State) ->
- M:F(State, A).
-
start_chunk(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) ->
State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, start_chunk, undefined}};
start_chunk(#state{client = From} = State) ->
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
index fcee2eddde..dea147fb56 100644
--- a/lib/inets/test/ftp_SUITE.erl
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -32,15 +32,18 @@
-compile(export_all).
-define(FTP_USER, "anonymous").
--define(FTP_PASS, (fun({ok,__H}) -> "ftp_SUITE@" ++ __H;
- (_) -> "ftp_SUITE@localhost"
- end)(inet:gethostname())
+-define(FTP_PASS(Cmnt), (fun({ok,__H}) -> "ftp_SUITE_"++Cmnt++"@" ++ __H;
+ (_) -> "ftp_SUITE_"++Cmnt++"@localhost"
+ end)(inet:gethostname())
).
-define(BAD_HOST, "badhostname").
-define(BAD_USER, "baduser").
-define(BAD_DIR, "baddirectory").
+go() -> ct:run_test([{suite,"ftp_SUITE"}, {logdir,"LOG"}]).
+gos() -> ct:run_test([{suite,"ftp_SUITE"}, {group,ftps_passive}, {logdir,"LOG"}]).
+
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
@@ -112,14 +115,24 @@ ftp_tests()->
[{"vsftpd",
fun(__CONF__) ->
%% make_config_file(vsftpd, Conf),
- ConfFile = filename:join(?config(data_dir,__CONF__), "vsftpd.conf"),
+ DataDir = ?config(data_dir,__CONF__),
+ ConfFile = filename:join(DataDir, "vsftpd.conf"),
AnonRoot = ?config(priv_dir,__CONF__),
- Cmd = ["vsftpd \"",ConfFile,"\"",
+ Cmd = ["vsftpd "++filename:join(DataDir,"vsftpd.conf"),
" -oftpd_banner=erlang_otp_testing",
- " -oanon_root=\"",AnonRoot,"\""
+ " -oanon_root=\"",AnonRoot,"\"",
+ " -orsa_cert_file=\"",filename:join(DataDir,"cert.pem"),"\"",
+ " -orsa_private_key_file=\"",filename:join(DataDir,"key.pem"),"\""
],
- ct:log("~s",[Cmd]),
- case os:cmd(Cmd) of
+ Result = os:cmd(Cmd),
+ ct:log("Config file:~n~s~n~nServer start command:~n ~s~nResult:~n ~p",
+ [case file:read_file(ConfFile) of
+ {ok,X} -> X;
+ _ -> ""
+ end,
+ Cmd, Result
+ ]),
+ case Result of
[] -> {ok,'dont care'};
[Msg] -> {error,Msg}
end
@@ -154,7 +167,7 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
ps_ftpd(Config),
-%% stop_ftpd(Config),
+ stop_ftpd(Config),
ps_ftpd(Config),
ok.
@@ -171,19 +184,23 @@ init_per_testcase(Case, Config0) ->
catch
_:_-> ok
end,
+ TLS = [{tls,[{reuse_sessions,true}]}],
+ ACTIVE = [{mode,active}],
+ PASSIVE = [{mode,passive}],
+ ExtraOpts = [verbose],
Config =
case Group of
- ftp_active -> ftp__open(Config0, [{mode,active}]);
- ftps_active -> ftp__open(Config0, [{mode,active}]);
- ftp_passive -> ftp__open(Config0, [{mode,passive}]);
- ftps_passive -> ftp__open(Config0, [{mode,passive}])
+ ftp_active -> ftp__open(Config0, ACTIVE ++ExtraOpts);
+ ftps_active -> ftp__open(Config0, TLS++ ACTIVE ++ExtraOpts);
+ ftp_passive -> ftp__open(Config0, PASSIVE ++ExtraOpts);
+ ftps_passive -> ftp__open(Config0, TLS++PASSIVE ++ExtraOpts)
end,
case Case of
user -> Config;
bad_user -> Config;
_ ->
Pid = ?config(ftp,Config),
- ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS(atom_to_list(Group)++"-"++atom_to_list(Case)) ),
ok = ftp:cd(Pid, ?config(priv_dir,Config)),
Config
end.
@@ -199,7 +216,7 @@ end_per_testcase(_Case, Config) -> ftp__close(Config).
user(doc) -> ["Open an ftp connection to a host, and logon as anonymous ftp, then logoff"];
user(Config) ->
Pid = ?config(ftp, Config),
- ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), % logon
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS("")),% logon
ok = ftp:close(Pid), % logoff
{error,eclosed} = ftp:pwd(Pid), % check logoff result
ok.
@@ -208,7 +225,7 @@ user(Config) ->
bad_user(doc) -> ["Open an ftp connection to a host, and logon with bad user."];
bad_user(Config) ->
Pid = ?config(ftp, Config),
- {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS),
+ {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS("")),
ok.
%%-------------------------------------------------------------------------
diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf
index a7b260282c..4133f8f3b1 100644
--- a/lib/inets/test/ftp_SUITE_data/vsftpd.conf
+++ b/lib/inets/test/ftp_SUITE_data/vsftpd.conf
@@ -2,8 +2,10 @@
listen=YES
listen_port=9999
run_as_launching_user=YES
-#ssl_enable=YES
-#allow_anon_ssl=YES
+ssl_enable=YES
+allow_anon_ssl=YES
+
+#background=NO
background=YES
write_enable=YES
@@ -14,5 +16,7 @@ anon_other_write_enable=YES
anon_world_readable_only=NO
#rsa_cert_file=cert.pem
-#rsa_key_file=key.pem
+#rsa_private_key_file exists, not rsa_key_file=key.pem
+### Shouldn't be necessary....
+require_ssl_reuse=NO