Skip to content

Commit

Permalink
handle SSL validation on platforms that support it
Browse files Browse the repository at this point in the history
R14/R15 doesn't support the option `server_name_indication`, on these platform we only do simple certificate verificaton

Also document broken version of SSL modules in 17.3 and 17.3.1.

fix #141
  • Loading branch information
benoitc committed Dec 5, 2014
1 parent 5c55565 commit 586ff73
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 55 deletions.
83 changes: 43 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,34 @@ Main features:
- multipart support (streamed or not)
- chunked encoding support
- Can send files using the sendfile API
- Chunked encoding support
- Optional socket pool
- REST syntax: `hackney:Method(URL)` (where a method can be get, post, put, delete, ...)

Hackney uses [hackney_lib](http://github.com/benoitc/hackney_lib) to
handle any web protocols. If you want to manipulate headers, cookies,
multipart or any other thing related to web protocols this is the place
to go.
**Supported versions** of Erlang are R16B03-1, 17.3.4 and above. It is
reported to work with R14B04 and R15B03-1.

**WARNING**: Erlang 17.3 and 17.3.1 have a broken SSL module which
prevents the usage of SSL connection with some servers. You **must** upgrade
in that case to Erlang
[17.3.4](https://github.com/erlang/otp/commit/9417f044ee3c291c2ea343c203aebdcc40597226)
or superior.

> Note: This is a work in progress, see the
[TODO](http://github.com/benoitc/hackney/blob/master/TODO.md) for more
information on what still needs to be done.

#### Useful modules are:

- [`hackney`](http://github.com/benoitc/hackney/blob/master/doc/hackney.md): main module. It contains all HTTP client functions.
- [`hackney_http`](http://github.com/benoitc/hackney/blob/master/doc/hackney_http.md): HTTP parser in pure Erlang. This parser is able
- [`hackney`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney.md): main module. It contains all HTTP client functions.
- [`hackney_http`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_http.md): HTTP parser in pure Erlang. This parser is able
to parse HTTP responses and requests in a streaming fashion. If not set
it will be autodetected if it's a request or a response that's needed.

- [`hackney_headers`](http://github.com/benoitc/hackney/blob/master/doc/hackney_headers.md) Module to manipulate HTTP headers.
- [`hackney_cookie`](http://github.com/benoitc/hackney/blob/master/doc/hackney_cookie.md): Module to manipulate cookies.
- [`hackney_multipart`](http://github.com/benoitc/hackney/blob/master/doc/hackney_multipart.md): Module to encode/decode multipart.
- [`hackney_url`](http://github.com/benoitc/hackney/blob/master/doc/hackney_url.md): Module to parse and create URIs.
- [`hackney_date`](http://github.com/benoitc/hackney/blob/master/doc/hackney_date.md): Module to parse HTTP dates.
- [`hackney_headers`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_headers.md) Module to manipulate HTTP headers.
- [`hackney_cookie`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_cookie.md): Module to manipulate cookies.
- [`hackney_multipart`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_multipart.md): Module to encode/decode multipart.
- [`hackney_url`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_url.md): Module to parse and create URIs.
- [`hackney_date`](http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_date.md): Module to parse HTTP dates.

Read the [NEWS](https://raw.github.com/benoitc/hackney/master/NEWS.md) file
to get the last changelog.
Expand Down Expand Up @@ -503,32 +506,32 @@ $ kill `cat httpbin.pid`


<table width="100%" border="0" summary="list of modules">
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney.md" class="module">hackney</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_app.md" class="module">hackney_app</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_bstr.md" class="module">hackney_bstr</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_connect.md" class="module">hackney_connect</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_cookie.md" class="module">hackney_cookie</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_date.md" class="module">hackney_date</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_deps.md" class="module">hackney_deps</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_dummy_metrics.md" class="module">hackney_dummy_metrics</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_exometer_metrics.md" class="module">hackney_exometer_metrics</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_folsom_metrics.md" class="module">hackney_folsom_metrics</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_headers.md" class="module">hackney_headers</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_http.md" class="module">hackney_http</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_http_connect.md" class="module">hackney_http_connect</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_idna.md" class="module">hackney_idna</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_manager.md" class="module">hackney_manager</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_mimetypes.md" class="module">hackney_mimetypes</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_multipart.md" class="module">hackney_multipart</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_pool.md" class="module">hackney_pool</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_pool_handler.md" class="module">hackney_pool_handler</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_request.md" class="module">hackney_request</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_response.md" class="module">hackney_response</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_socks5.md" class="module">hackney_socks5</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_ssl_transport.md" class="module">hackney_ssl_transport</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_stream.md" class="module">hackney_stream</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_sup.md" class="module">hackney_sup</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_tcp_transport.md" class="module">hackney_tcp_transport</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_url.md" class="module">hackney_url</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/master/doc/hackney_util.md" class="module">hackney_util</a></td></tr></table>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney.md" class="module">hackney</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_app.md" class="module">hackney_app</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_bstr.md" class="module">hackney_bstr</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_connect.md" class="module">hackney_connect</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_cookie.md" class="module">hackney_cookie</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_date.md" class="module">hackney_date</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_deps.md" class="module">hackney_deps</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_dummy_metrics.md" class="module">hackney_dummy_metrics</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_exometer_metrics.md" class="module">hackney_exometer_metrics</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_folsom_metrics.md" class="module">hackney_folsom_metrics</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_headers.md" class="module">hackney_headers</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_http.md" class="module">hackney_http</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_http_connect.md" class="module">hackney_http_connect</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_idna.md" class="module">hackney_idna</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_manager.md" class="module">hackney_manager</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_mimetypes.md" class="module">hackney_mimetypes</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_multipart.md" class="module">hackney_multipart</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_pool.md" class="module">hackney_pool</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_pool_handler.md" class="module">hackney_pool_handler</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_request.md" class="module">hackney_request</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_response.md" class="module">hackney_response</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_socks5.md" class="module">hackney_socks5</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_ssl_transport.md" class="module">hackney_ssl_transport</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_stream.md" class="module">hackney_stream</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_sup.md" class="module">hackney_sup</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_tcp_transport.md" class="module">hackney_tcp_transport</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_url.md" class="module">hackney_url</a></td></tr>
<tr><td><a href="http://github.com/benoitc/hackney/blob/fix/141/doc/hackney_util.md" class="module">hackney_util</a></td></tr></table>

1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ todo of hackney
- Add support for custom authentication methods
- Add support for oauth2 ?
- Add support for HTTP digest auth
- Add tests
13 changes: 8 additions & 5 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ Main features:
- multipart support (streamed or not)
- chunked encoding support
- Can send files using the sendfile API
- Chunked encoding support
- Optional socket pool
- REST syntax: `hackney:Method(URL)` (where a method can be get, post, put, delete, ...)

Hackney uses [hackney_lib](http://github.com/benoitc/hackney_lib) to
handle any web protocols. If you want to manipulate headers, cookies,
multipart or any other thing related to web protocols this is the place
to go.
**Supported versions** of Erlang are R16B03-1, 17.3.4 and above. It is
reported to work with R14B04 and R15B03-1.

**WARNING**: Erlang 17.3 and 17.3.1 have a broken SSL module which
prevents the usage of SSL connection with some servers. You **must** upgrade
in that case to Erlang
[17.3.4](https://github.com/erlang/otp/commit/9417f044ee3c291c2ea343c203aebdcc40597226)
or superior.

> Note: This is a work in progress, see the
[TODO](http://github.com/benoitc/hackney/blob/master/TODO.md) for more
Expand Down
13 changes: 8 additions & 5 deletions doc/overview.edoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,19 @@ Main features:
- multipart support (streamed or not)
- chunked encoding support
- Can send files using the sendfile API
- Chunked encoding support
- Optional socket pool
- REST syntax: `hackney:Method(URL)' (where a method can be get, post, put, delete, ...)

Hackney uses [hackney_lib](http://github.com/benoitc/hackney_lib) to
handle any web protocols. If you want to manipulate headers, cookies,
multipart or any other thing related to web protocols this is the place
to go.
**Supported versions** of Erlang are R16B03-1, 17.3.4 and above. It is
reported to work with R14B04 and R15B03-1.


**WARNING**: Erlang 17.3 and 17.3.1 have a broken SSL module which
prevents the usage of SSL connection with some servers. You **must** upgrade
in that case to Erlang
[17.3.4](https://github.com/erlang/otp/commit/9417f044ee3c291c2ea343c203aebdcc40597226)
or superior.

> Note: This is a work in progress, see the
[TODO](http://github.com/benoitc/hackney/blob/master/TODO.md) for more
information on what still needs to be done.
Expand Down
4 changes: 3 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
%%{erl_first_files, ["hackney_pool_handler"]}.
{erl_opts, [
debug_info,
{platform_define, "R14", no_callback_support}
{platform_define, "R14", no_callback_support},
{platform_define, "R14", no_ssl_name_validation},
{platform_define, "R15", no_ssl_name_validation}
]}.

{xref_checks, [undefined_function_calls]}.
Expand Down
26 changes: 23 additions & 3 deletions src/hackney_connect/hackney_connect.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@

-include("hackney.hrl").

-ifdef(no_ssl_name_validation).
-define(VALIDATE_SSL, normal).
-else.
-define(VALIDATE_SSL, host).
-endif.


connect(Transport, Host, Port) ->
connect(Transport, Host, Port, []).
Expand Down Expand Up @@ -217,11 +223,14 @@ do_connect(Host, Port, Transport, #client{mod_metrics=Mod,

ConnectOpts = case {Transport, proplists:get_value(ssl_options, Opts)} of
{hackney_ssl_transport, undefined} ->
case proplists:get_value(insecure, Opts) of
true ->
Insecure = proplists:get_value(insecure, Opts),
ShouldValidate = should_validate_ssl(),

case {Insecure, ShouldValidate} of
{true, _} ->
ConnectOpts1 ++ [{verify, verify_none},
{reuse_sessions, true}];
_ ->
{_, host} ->
CACertFile = filename:join(hackney_util:privdir(),
"ca-bundle.crt"),
SslOpts = [{verify_fun, {fun ssl_verify_hostname:verify_fun/3,
Expand All @@ -230,6 +239,13 @@ do_connect(Host, Port, Transport, #client{mod_metrics=Mod,
{server_name_indication, Host},
{verify, verify_peer}, {depth, 99}],

ConnectOpts1 ++ SslOpts;
{_, normal} ->
CACertFile = filename:join(hackney_util:privdir(),
"ca-bundle.crt"),
SslOpts = [{cacertfile, CACertFile },
{verify, verify_peer}, {depth, 99}],

ConnectOpts1 ++ SslOpts
end;
{hackney_ssl_transport, SslOpts} ->
Expand Down Expand Up @@ -270,3 +286,7 @@ check_mod_metrics(#client{mod_metrics=Mod}=State)
State;
check_mod_metrics(State) ->
State#client{mod_metrics=hackney_util:mod_metrics()}.


should_validate_ssl() ->
?VALIDATE_SSL.

0 comments on commit 586ff73

Please sign in to comment.