From 3b77f57f3a33bef81e407be3e9dab8641b255a59 Mon Sep 17 00:00:00 2001 From: Julian Doherty Date: Mon, 22 Apr 2024 11:04:15 +1000 Subject: [PATCH 1/7] add MIX_CACERTFILE environment variable Allow specifying a custom cacertfile for mix operations that need to make HTTPS requests. This allows mix operations to run in corporate environments that have a managed network with an SSL proxy that requires use of a custom cert file instead of the system default. --- lib/mix/lib/mix.ex | 3 +++ lib/mix/lib/mix/utils.ex | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 24566195ed7..95ce6b0d6e5 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -337,6 +337,9 @@ defmodule Mix do written to. For example, "_build". If `MIX_BUILD_PATH` is set, this option is ignored. + * `MIX_CACERTFILE` - use specified CA certificate file instead of default + system CA certificates. See [Erlang `ssl` module documentation](https://www.erlang.org/doc/man/ssl#type-client_cafile) + * `MIX_DEBUG` - outputs debug information about each task before running it * `MIX_DEPS_PATH` - sets the project `Mix.Project.deps_path/0` config for the diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index e28a80245a9..bdca0638ef9 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -655,11 +655,19 @@ defmodule Mix.Utils do headers = [{~c"user-agent", ~c"Mix/#{System.version()}"}] request = {:binary.bin_to_list(path), headers} + # allow override of system CA certs to support running on managed networks + # using an SSL proxy etc + cacert_opt = + case System.get_env("MIX_CACERTFILE") do + nil -> {:cacerts, :public_key.cacerts_get()} + file -> {:cacertfile, file} + end + # Use the system certificates # TODO: use `ssl_options = :httpc.ssl_verify_host_options(true)` on Erlang/OTP 26+ ssl_options = [ + cacert_opt, verify: :verify_peer, - cacerts: :public_key.cacerts_get(), customize_hostname_check: [match_fun: :public_key.pkix_verify_hostname_match_fun(:https)] ] From a3b98706b70306c08edaa414f431c5b3578d09c7 Mon Sep 17 00:00:00 2001 From: Julian Doherty Date: Wed, 24 Apr 2024 11:50:53 +1000 Subject: [PATCH 2/7] use HEX_CACERTS_PATH instead of MIX_CERTFILE --- lib/mix/lib/mix.ex | 8 ++++++-- lib/mix/lib/mix/utils.ex | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 95ce6b0d6e5..20dd1ce3297 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -337,8 +337,6 @@ defmodule Mix do written to. For example, "_build". If `MIX_BUILD_PATH` is set, this option is ignored. - * `MIX_CACERTFILE` - use specified CA certificate file instead of default - system CA certificates. See [Erlang `ssl` module documentation](https://www.erlang.org/doc/man/ssl#type-client_cafile) * `MIX_DEBUG` - outputs debug information about each task before running it @@ -373,6 +371,12 @@ defmodule Mix do than `MIX_XDG`. If none of the variables are set, the default directory `~/.mix` will be used + In addition, Mix also uses the following environment variables defined by other libraries + + * `HEX_CACERTS_PATH` - use specified CA certificate file instead of default + system CA certificates. This configures how HTTPS calls are made via [Erlang `ssl` module](https://www.erlang.org/doc/man/ssl#type-client_cafile) + to fetch remote archives and packages. See [`mix hex.config`](https://hexdocs.pm/hex/Mix.Tasks.Hex.Config.html#module-config-keys) + for more details. Environment variables that are not meant to hold a value (and act basically as flags) should be set to either `1` or `true`, for example: diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index bdca0638ef9..b3a28e10f12 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -656,9 +656,11 @@ defmodule Mix.Utils do request = {:binary.bin_to_list(path), headers} # allow override of system CA certs to support running on managed networks - # using an SSL proxy etc + # using an SSL proxy etc. Piggy back on Hex defined environment variable + # rather than creating a new one, as these are almost always going to be + # set and used together. cacert_opt = - case System.get_env("MIX_CACERTFILE") do + case System.get_env("HEX_CACERTS_PATH") do nil -> {:cacerts, :public_key.cacerts_get()} file -> {:cacertfile, file} end From b11fb506361a91a8d661c013e879fc3e8a0340eb Mon Sep 17 00:00:00 2001 From: Julian Doherty Date: Wed, 24 Apr 2024 11:57:02 +1000 Subject: [PATCH 3/7] whitespace --- lib/mix/lib/mix.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 20dd1ce3297..412ce43b095 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -337,7 +337,6 @@ defmodule Mix do written to. For example, "_build". If `MIX_BUILD_PATH` is set, this option is ignored. - * `MIX_DEBUG` - outputs debug information about each task before running it * `MIX_DEPS_PATH` - sets the project `Mix.Project.deps_path/0` config for the From 74a405b421dbc1bb6b5a89641aaea6f37994f040 Mon Sep 17 00:00:00 2001 From: Julian Doherty Date: Wed, 24 Apr 2024 12:02:08 +1000 Subject: [PATCH 4/7] whitespace --- lib/mix/lib/mix.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 412ce43b095..f3b0990ed76 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -375,7 +375,8 @@ defmodule Mix do * `HEX_CACERTS_PATH` - use specified CA certificate file instead of default system CA certificates. This configures how HTTPS calls are made via [Erlang `ssl` module](https://www.erlang.org/doc/man/ssl#type-client_cafile) to fetch remote archives and packages. See [`mix hex.config`](https://hexdocs.pm/hex/Mix.Tasks.Hex.Config.html#module-config-keys) - for more details. + for more details. + Environment variables that are not meant to hold a value (and act basically as flags) should be set to either `1` or `true`, for example: From 2adc98253028d3a2b3a55d3c7836588e537b01ea Mon Sep 17 00:00:00 2001 From: Julian Doherty Date: Wed, 24 Apr 2024 12:03:20 +1000 Subject: [PATCH 5/7] move additional variables list to end --- lib/mix/lib/mix.ex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index f3b0990ed76..e6c3b32d277 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -370,17 +370,17 @@ defmodule Mix do than `MIX_XDG`. If none of the variables are set, the default directory `~/.mix` will be used + Environment variables that are not meant to hold a value (and act basically as + flags) should be set to either `1` or `true`, for example: + + $ MIX_DEBUG=1 mix compile + In addition, Mix also uses the following environment variables defined by other libraries * `HEX_CACERTS_PATH` - use specified CA certificate file instead of default system CA certificates. This configures how HTTPS calls are made via [Erlang `ssl` module](https://www.erlang.org/doc/man/ssl#type-client_cafile) to fetch remote archives and packages. See [`mix hex.config`](https://hexdocs.pm/hex/Mix.Tasks.Hex.Config.html#module-config-keys) for more details. - - Environment variables that are not meant to hold a value (and act basically as - flags) should be set to either `1` or `true`, for example: - - $ MIX_DEBUG=1 mix compile """ @mix_install_project __MODULE__.InstallProject From d5ace1a5985fc02561cfec333bc62d659045df79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 24 Apr 2024 09:17:44 +0200 Subject: [PATCH 6/7] Update lib/mix/lib/mix.ex --- lib/mix/lib/mix.ex | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index e6c3b32d277..2d489258167 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -378,9 +378,10 @@ defmodule Mix do In addition, Mix also uses the following environment variables defined by other libraries * `HEX_CACERTS_PATH` - use specified CA certificate file instead of default - system CA certificates. This configures how HTTPS calls are made via [Erlang `ssl` module](https://www.erlang.org/doc/man/ssl#type-client_cafile) - to fetch remote archives and packages. See [`mix hex.config`](https://hexdocs.pm/hex/Mix.Tasks.Hex.Config.html#module-config-keys) - for more details. + system CA certificates. This configures how HTTPS calls are made via + [Erlang `ssl` module](https://www.erlang.org/doc/man/ssl#type-client_cafile) + to fetch remote archives and packages. For more details, see + [`mix hex.config`](https://hexdocs.pm/hex/Mix.Tasks.Hex.Config.html#module-config-keys). """ @mix_install_project __MODULE__.InstallProject From e4679d014e4113a5342993a1f3291e52c057a034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 24 Apr 2024 09:38:34 +0200 Subject: [PATCH 7/7] Update lib/mix/lib/mix/utils.ex Co-authored-by: Jean Klingler --- lib/mix/lib/mix/utils.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index b3a28e10f12..63933c6a943 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -666,7 +666,6 @@ defmodule Mix.Utils do end # Use the system certificates - # TODO: use `ssl_options = :httpc.ssl_verify_host_options(true)` on Erlang/OTP 26+ ssl_options = [ cacert_opt, verify: :verify_peer,