|
5 | 5 | defmodule Mix.Local do |
6 | 6 | @moduledoc false |
7 | 7 |
|
8 | | - @public_keys_html "https://builds.hex.pm/installs/public_keys.html" |
9 | | - |
10 | | - @in_memory_key """ |
11 | | - -----BEGIN PUBLIC KEY----- |
12 | | - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAslPz1mAfyAvRv8W8xOdv |
13 | | - HQMbDJkDKfRhsL4JBGwGH7qw0xh+TbaUlNaM3pF+i8VUjS/4FeXjT/OAUEAHu5Y2 |
14 | | - rBVlx00QcH8Dpbyf+H73XiCs0MXnTSecqDgzx6i6NMi8knklHT7yHySHtuuPmPuN |
15 | | - Po8QTKolCKftwPE/iNDeyZfwufd+hTCoCQdoTVcB01SElfNtvKRtoKbx35q80IPr |
16 | | - rOcGsALmr58+bWqCTY/51kFeRxzrPJ5LdcLU/AebyWddD4IUfPDxk16jTiCagMWA |
17 | | - JPSwo8NUrWDIBbD+rEUp06y0ek276rG5Tzm/3Bma56RN/u6nAqBTBE8F2Hu2QBKj |
18 | | - lQIDAQAB |
19 | | - -----END PUBLIC KEY----- |
20 | | - """ |
21 | | - |
22 | 8 | @doc """ |
23 | 9 | Returns the name for an archive or an escript, based on the project config. |
24 | 10 |
|
@@ -167,40 +153,16 @@ defmodule Mix.Local do |
167 | 153 |
|
168 | 154 | Used to install both Rebar and Hex from S3. |
169 | 155 | """ |
170 | | - def find_matching_versions_from_signed_csv!(name, version, path) do |
171 | | - ensure_applications!() |
172 | | - csv = read_unsafe_path!(name, path) |
173 | | - |
174 | | - signature = |
175 | | - read_unsafe_path!(name, path <> ".signed") |
176 | | - |> String.replace("\n", "") |
177 | | - |> Base.decode64!() |
178 | | - |
179 | | - verified? = |
180 | | - Enum.any?(public_keys(), fn {id, key} -> |
181 | | - :public_key.verify(csv, :sha512, signature, decode_pk!(id, key)) |
182 | | - end) |
183 | | - |
184 | | - if verified? do |
185 | | - result = |
186 | | - csv |
187 | | - |> parse_csv() |
188 | | - |> find_latest_eligible_version(version) |
189 | | - |
190 | | - result || Mix.raise("Could not find a version of #{name} matching: #{version}") |
191 | | - else |
192 | | - Mix.raise( |
193 | | - "Could not install #{name} because Mix could not verify authenticity " <> |
194 | | - "of metadata file at #{inspect(path)}. This may happen because a proxy or some " <> |
195 | | - "entity is interfering with the download or because you don't have a " <> |
196 | | - "public key to verify the download.\n\nYou may try again later or check " <> |
197 | | - "if a new public key has been released in our public keys page: #{@public_keys_html}" |
198 | | - ) |
199 | | - end |
| 156 | + def find_matching_versions!(name, version, path) do |
| 157 | + name |
| 158 | + |> read_path!(path) |
| 159 | + |> parse_csv() |
| 160 | + |> find_latest_eligible_version(version) |
| 161 | + |> Kernel.||(Mix.raise("Could not find a version of #{name} matching: #{version}")) |
200 | 162 | end |
201 | 163 |
|
202 | | - defp read_unsafe_path!(name, path) do |
203 | | - case Mix.Utils.read_path(path, unsafe_uri: true) do |
| 164 | + defp read_path!(name, path) do |
| 165 | + case Mix.Utils.read_path(path) do |
204 | 166 | {:ok, contents} -> |
205 | 167 | contents |
206 | 168 |
|
@@ -242,78 +204,20 @@ defmodule Mix.Local do |
242 | 204 | |> find_version(artifact_version, elixir_version) |
243 | 205 | end |
244 | 206 |
|
245 | | - defp find_version(entries, _artifact_version = nil, elixir_version) do |
246 | | - Enum.find_value(entries, &find_by_elixir_version(&1, elixir_version)) |
247 | | - end |
248 | | - |
249 | 207 | defp find_version(entries, artifact_version, elixir_version) do |
250 | | - Enum.find_value(entries, &find_by_artifact_version(&1, artifact_version, elixir_version)) |
251 | | - end |
252 | | - |
253 | | - defp find_by_elixir_version([artifact_version, digest | versions], elixir_version) do |
254 | | - if version = Enum.find(versions, &(Version.compare(&1, elixir_version) != :gt)) do |
255 | | - {version, artifact_version, digest} |
256 | | - end |
257 | | - end |
258 | | - |
259 | | - defp find_by_artifact_version( |
260 | | - [artifact_version, digest | versions], |
261 | | - artifact_version, |
262 | | - elixir_version |
263 | | - ) do |
264 | | - if version = Enum.find(versions, &(Version.compare(&1, elixir_version) != :gt)) do |
265 | | - {version, artifact_version, digest} |
266 | | - end |
267 | | - end |
268 | | - |
269 | | - defp find_by_artifact_version(_entry, _artifact_version, _elixir_version) do |
270 | | - nil |
271 | | - end |
272 | | - |
273 | | - ## Public keys |
274 | | - |
275 | | - @doc """ |
276 | | - Returns the file system path for public keys. |
277 | | - """ |
278 | | - def public_keys_path, do: Path.join(Mix.Utils.mix_home(), "public_keys") |
279 | | - |
280 | | - @doc """ |
281 | | - Returns all public keys as a list. |
282 | | - """ |
283 | | - def public_keys do |
284 | | - path = public_keys_path() |
285 | | - |
286 | | - [{"in-memory public key for Elixir v#{System.version()}", @in_memory_key}] ++ |
287 | | - case File.ls(path) do |
288 | | - {:ok, keys} -> Enum.map(keys, &{&1, File.read!(Path.join(path, &1))}) |
289 | | - {:error, _} -> [] |
| 208 | + entries = |
| 209 | + if artifact_version do |
| 210 | + Enum.filter(entries, &(hd(&1) == artifact_version)) |
| 211 | + else |
| 212 | + entries |
290 | 213 | end |
291 | | - end |
292 | 214 |
|
293 | | - @doc """ |
294 | | - Decodes a public key and raises if the key is invalid. |
295 | | - """ |
296 | | - def decode_pk!(id, key) do |
297 | | - ensure_applications!() |
298 | | - |
299 | | - try do |
300 | | - [rsa_public_key] = :public_key.pem_decode(key) |
301 | | - :public_key.pem_entry_decode(rsa_public_key) |
302 | | - rescue |
303 | | - _ -> |
304 | | - Mix.raise(""" |
305 | | - Could not decode public key: #{id}. The public key contents are shown below. |
306 | | -
|
307 | | - #{key} |
308 | | -
|
309 | | - Public keys must be valid and be in the PEM format |
310 | | - """) |
311 | | - end |
| 215 | + Enum.find_value(entries, &find_by_elixir_version(&1, elixir_version)) |
312 | 216 | end |
313 | 217 |
|
314 | | - defp ensure_applications! do |
315 | | - Mix.ensure_application!(:crypto) |
316 | | - Mix.ensure_application!(:asn1) |
317 | | - Mix.ensure_application!(:public_key) |
| 218 | + defp find_by_elixir_version([artifact_version, digest, hex_elixir_version | _], elixir_version) do |
| 219 | + if Version.compare(hex_elixir_version, elixir_version) != :gt do |
| 220 | + {hex_elixir_version, artifact_version, digest} |
| 221 | + end |
318 | 222 | end |
319 | 223 | end |
0 commit comments