summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2016-05-24 21:12:49 -0400
committerFred Hebert <mononcqc@ferd.ca>2016-05-24 21:17:53 -0400
commit351b757a0eb03e2d2e8714d0f5f447531446aa68 (patch)
tree8d4a76cdddd927390be042327e436ed5d563c0e0
parent9a7ede0196c78224c15d1e9c8d13bed84743dacf (diff)
Validate checksums expected vs obtained
-rw-r--r--src/rebar_fetch.erl6
-rw-r--r--src/rebar_pkg_resource.erl17
2 files changed, 16 insertions, 7 deletions
diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl
index b80c125..47bfe1d 100644
--- a/src/rebar_fetch.erl
+++ b/src/rebar_fetch.erl
@@ -67,6 +67,12 @@ needs_update(AppDir, Source, State) ->
format_error({bad_download, CachePath}) ->
io_lib:format("Download of package does not match md5sum from server: ~s", [CachePath]);
+format_error({unexpected_hash, CachePath, Expected, Found}) ->
+ io_lib:format("The checksum for package at ~s (~s) does not match the "
+ "checksum previously locked (~s). Either unlock or "
+ "upgrade the package, or make sure you fetched it from "
+ "the same index from which it was initially fetched.",
+ [CachePath, Found, Expected]);
format_error({failed_extract, CachePath}) ->
io_lib:format("Failed to extract package: ~s", [CachePath]);
format_error({bad_etag, Source}) ->
diff --git a/src/rebar_pkg_resource.erl b/src/rebar_pkg_resource.erl
index 257df21..5817817 100644
--- a/src/rebar_pkg_resource.erl
+++ b/src/rebar_pkg_resource.erl
@@ -58,17 +58,20 @@ cached_download(TmpDir, CachePath, Pkg={pkg, Name, Vsn, _Hash}, Url, ETag, State
serve_from_cache(TmpDir, CachePath, Pkg, State) ->
{Files, Contents, Version, Meta} = extract(TmpDir, CachePath),
case checksums(Pkg, Files, Contents, Version, Meta, State) of
- {Chk, Chk, Chk} ->
+ {Chk, Chk, Chk, Chk} ->
ok = erl_tar:extract({binary, Contents}, [{cwd, TmpDir}, compressed]),
{ok, true};
- {_Bin, Chk, Chk} ->
+ {_Hash, Chk, Chk, Chk} ->
+ ?DEBUG("Expected hash ~p does not match checksums ~p", [_Hash, Chk]),
+ {unexpected_hash, CachePath, _Hash, Chk};
+ {Chk, _Bin, Chk, Chk} ->
?DEBUG("Checksums: registry: ~p, pkg: ~p", [Chk, _Bin]),
{failed_extract, CachePath};
- {Chk, _Reg, Chk} ->
+ {Chk, Chk, _Reg, Chk} ->
?DEBUG("Checksums: registry: ~p, pkg: ~p", [_Reg, Chk]),
{bad_registry_checksum, CachePath};
- {_Bin, _Reg, _Tar} ->
- ?DEBUG("Checksums: registry: ~p, pkg: ~p, meta: ~p", [_Reg, _Bin, _Tar]),
+ {_Hash, _Bin, _Reg, _Tar} ->
+ ?DEBUG("Checksums: expected: ~p, registry: ~p, pkg: ~p, meta: ~p", [_Hash, _Reg, _Bin, _Tar]),
{bad_checksum, CachePath}
end.
@@ -92,13 +95,13 @@ extract(TmpDir, CachePath) ->
{"metadata.config", Meta} = lists:keyfind("metadata.config", 1, Files),
{Files, Contents, Version, Meta}.
-checksums(Pkg, Files, Contents, Version, Meta, State) ->
+checksums(Pkg={pkg, _Name, _Vsn, Hash}, Files, Contents, Version, Meta, State) ->
Blob = <<Version/binary, Meta/binary, Contents/binary>>,
<<X:256/big-unsigned>> = crypto:hash(sha256, Blob),
BinChecksum = list_to_binary(string:to_upper(lists:flatten(io_lib:format("~64.16.0b", [X])))),
RegistryChecksum = rebar_packages:registry_checksum(Pkg, State),
{"CHECKSUM", TarChecksum} = lists:keyfind("CHECKSUM", 1, Files),
- {BinChecksum, RegistryChecksum, TarChecksum}.
+ {Hash, BinChecksum, RegistryChecksum, TarChecksum}.
make_vsn(_) ->
{error, "Replacing version of type pkg not supported."}.