Skip to content

Commit

Permalink
gen_smtp_client: Add support for fallback to HELO.
Browse files Browse the repository at this point in the history
  • Loading branch information
Arjan Scherpenisse committed Jul 19, 2011
1 parent 0cb4aca commit 0b709ce
Showing 1 changed file with 50 additions and 5 deletions.
55 changes: 50 additions & 5 deletions src/gen_smtp_client.erl
Expand Up @@ -394,11 +394,31 @@ do_AUTH_each(Socket, Username, Password, [_Type | Tail]) ->

-spec try_EHLO(Socket :: socket:socket(), Options :: list()) -> {ok, list()}.
try_EHLO(Socket, Options) ->
socket:send(Socket, ["EHLO ", proplists:get_value(hostname, Options, smtp_util:guess_FQDN()), "\r\n"]),
%% TODO handle fallback to HELO!
{ok, Reply} = read_possible_multiline_reply(Socket),
Extensions = parse_extensions(Reply),
{ok, Extensions}.
ok = socket:send(Socket, ["EHLO ", proplists:get_value(hostname, Options, smtp_util:guess_FQDN()), "\r\n"]),
case read_possible_multiline_reply(Socket) of
{ok, <<"500", _Rest/binary>>} ->
% Unrecognized command, fall back to HELO
try_HELO(Socket, Options);
{ok, <<"4", _Rest/binary>> = Msg} ->
quit(Socket),
throw({temporary_failure, Msg});
{ok, Reply} ->
{ok, parse_extensions(Reply)}
end.

-spec try_HELO(Socket :: socket:socket(), Options :: list()) -> {ok, list()}.
try_HELO(Socket, Options) ->
ok = socket:send(Socket, ["HELO ", proplists:get_value(hostname, Options, smtp_util:guess_FQDN()), "\r\n"]),
case read_possible_multiline_reply(Socket) of
{ok, <<"250", _Rest/binary>>} ->
{ok, []};
{ok, <<"4", _Rest/binary>> = Msg} ->
quit(Socket),
throw({temporary_failure, Msg});
{ok, Msg} ->
quit(Socket),
throw({permanent_failure, Msg})
end.

% check if we should try to do TLS
-spec try_STARTTLS(Socket :: socket:socket(), Options :: list(), Extensions :: list()) -> {socket:socket(), list()}.
Expand Down Expand Up @@ -686,6 +706,31 @@ session_start_test_() ->
end
}
end,
fun({ListenSock}) ->
{"retry with HELO when EHLO not accepted",
fun() ->
Options = [{relay, "localhost"}, {port, 9876}, {hostname, "testing"}],
{ok, _Pid} = send({"test@foo.com", ["foo@bar.com"], "hello world"}, Options),
{ok, X} = socket:accept(ListenSock, 1000),
socket:send(X, "220 \r\n"),
?assertMatch({ok, "EHLO testing\r\n"}, socket:recv(X, 0, 1000)),
socket:send(X, "500 5.3.3 Unrecognized command\r\n"),
?assertMatch({ok, "HELO testing\r\n"}, socket:recv(X, 0, 1000)),
socket:send(X, "250 Some banner\r\n"),
?assertMatch({ok, "MAIL FROM: <test@foo.com>\r\n"}, socket:recv(X, 0, 1000)),
socket:send(X, "250 ok\r\n"),
?assertMatch({ok, "RCPT TO: <foo@bar.com>\r\n"}, socket:recv(X, 0, 1000)),
socket:send(X, "250 ok\r\n"),
?assertMatch({ok, "DATA\r\n"}, socket:recv(X, 0, 1000)),
socket:send(X, "354 ok\r\n"),
?assertMatch({ok, "hello world\r\n"}, socket:recv(X, 0, 1000)),
?assertMatch({ok, ".\r\n"}, socket:recv(X, 0, 1000)),
socket:send(X, "250 ok\r\n"),
?assertMatch({ok, "QUIT\r\n"}, socket:recv(X, 0, 1000)),
ok
end
}
end,
fun({ListenSock}) ->
{"a valid complete transaction without TLS advertised should succeed",
fun() ->
Expand Down

0 comments on commit 0b709ce

Please sign in to comment.