Skip to content

Commit

Permalink
fix: compare manifest hash before re-downloading channel update
Browse files Browse the repository at this point in the history
  • Loading branch information
Kha committed Apr 11, 2018
1 parent 5544b1c commit 942476d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 71 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "elan"
version = "0.2.0"
version = "0.2.1"
authors = [ "Sebastian Ullrich <[email protected]>" ]
description = "Manage multiple rust installations with ease"

Expand Down
33 changes: 27 additions & 6 deletions src/elan-dist/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::env;

use json;
use regex::Regex;
use sha2::{Sha256, Digest};

pub const DEFAULT_DIST_SERVER: &'static str = "https://static.lean-lang.org";

Expand Down Expand Up @@ -510,26 +511,46 @@ pub fn update_from_dist_<'a>(download: DownloadCfg<'a>,
});
}
};

let mut hasher = Sha256::new();
for url in &manifest {
hasher.input(url.as_bytes());
}
let hash = format!("{:x}", hasher.result());
let partial_hash = &hash[0..20];

if let Some(hash_file) = update_hash {
if utils::is_file(hash_file) {
if let Ok(contents) = utils::read_file("update hash", hash_file) {
if contents == partial_hash {
// Skip download, update hash matches
return Ok(None);
}
} /*else {
(self.notify_handler)(Notification::CantReadUpdateHash(hash_file));
}*/
} /*else {
(self.notify_handler)(Notification::NoUpdateHash(hash_file));
}*/
}

match manifestation.update_v1(&manifest,
update_hash,
&download.temp_cfg,
download.notify_handler.clone()) {
Ok(None) => Ok(None),
Ok(Some(hash)) => Ok(Some(hash)),
Ok(()) => Ok(()),
e @ Err(Error(ErrorKind::Utils(elan_utils::ErrorKind::DownloadNotExists { .. }), _)) => {
e.chain_err(|| {
format!("could not download nonexistent lean version `{}`",
toolchain_str)
})
}
Err(e) => Err(e),
}
}.map(|()| Some(partial_hash.to_string()))
}

fn dl_v1_manifest<'a>(download: DownloadCfg<'a>, toolchain: &ToolchainDesc) -> Result<Vec<String>> {
let manifest_url = toolchain.manifest_v1_url(download.dist_root);
let manifest_dl = try!(download.download_and_check(&manifest_url, None, ""));
let (manifest_file, _) = manifest_dl.unwrap();
let manifest_file = try!(download.download_and_check(&manifest_url, ""));
let manifest_str = try!(utils::read_file("manifest", &manifest_file));
let mut man_json = json::parse(&manifest_str).expect("failed to parse manifest");
if toolchain.channel == "nightly" && toolchain.date.is_none() {
Expand Down
57 changes: 3 additions & 54 deletions src/elan-dist/src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,70 +100,19 @@ impl<'a> DownloadCfg<'a> {
Ok(())
}

fn _download_hash(&self, url: &str) -> Result<String> {
let hash_url = try!(utils::parse_url(&(url.to_owned() + ".sha256")));
let hash_file = try!(self.temp_cfg.new_file());

try!(utils::download_file(&hash_url,
&hash_file,
None,
&|n| (self.notify_handler)(n.into())));

Ok(try!(utils::read_file("hash", &hash_file).map(|s| s[0..64].to_owned())))
}

/// Downloads a file, sourcing its hash from the same url with a `.sha256` suffix.
/// If `update_hash` is present, then that will be compared to the downloaded hash,
/// and if they match, the download is skipped.
pub fn download_and_check(&self,
url_str: &str,
_update_hash: Option<&Path>,
ext: &str)
-> Result<Option<(temp::File<'a>, String)>> {
/*let hash = try!(self.download_hash(url_str));
/let partial_hash: String = hash.chars().take(UPDATE_HASH_LEN).collect();
if let Some(hash_file) = update_hash {
if utils::is_file(hash_file) {
if let Ok(contents) = utils::read_file("update hash", hash_file) {
if contents == partial_hash {
// Skip download, update hash matches
return Ok(None);
}
} else {
(self.notify_handler)(Notification::CantReadUpdateHash(hash_file));
}
} else {
(self.notify_handler)(Notification::NoUpdateHash(hash_file));
}
}*/

-> Result<temp::File<'a>> {
let url = try!(utils::parse_url(url_str));
let file = try!(self.temp_cfg.new_file_with_ext("", ext));

let mut hasher = Sha256::new();
try!(utils::download_file(&url,
&file,
Some(&mut hasher),
None,
&|n| (self.notify_handler)(n.into())));
let actual_hash = format!("{:x}", hasher.result());

/*if hash != actual_hash {
// Incorrect hash
return Err(ErrorKind::ChecksumFailed {
url: url_str.to_owned(),
expected: hash,
calculated: actual_hash,
}
.into());
} else {
(self.notify_handler)(Notification::ChecksumValid(url_str));
}*/

// TODO: Check the signature of the file

Ok(Some((file, actual_hash)))
Ok(file)
}
}

Expand Down
12 changes: 3 additions & 9 deletions src/elan-dist/src/manifestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use notifications::*;
use elan_utils::utils;
use download::{DownloadCfg, File};
use prefix::InstallPrefix;
use std::path::Path;

pub const DIST_MANIFEST: &'static str = "multilean-channel-manifest.toml";
pub const CONFIG_FILE: &'static str = "multilean-config.toml";
Expand Down Expand Up @@ -303,9 +302,8 @@ impl Manifestation {
/// Installation using the legacy v1 manifest format
pub fn update_v1(&self,
new_manifest: &[String],
update_hash: Option<&Path>,
temp_cfg: &temp::Cfg,
notify_handler: &Fn(Notification)) -> Result<Option<String>> {
notify_handler: &Fn(Notification)) -> Result<()> {
let informal_target = match self.target_triple.0.as_str() {
"x86_64-unknown-linux-gnu" => Some("linux"),
"x86_64-apple-darwin" => Some("darwin"),
Expand Down Expand Up @@ -334,11 +332,7 @@ impl Manifestation {
notify_handler: notify_handler
};

let dl = try!(dlcfg.download_and_check(&url, update_hash, ".tar.gz"));
if dl.is_none() {
return Ok(None);
};
let (installer_file, installer_hash) = dl.unwrap();
let installer_file = try!(dlcfg.download_and_check(&url, ".tar.gz"));

let prefix = self.installation.prefix();

Expand Down Expand Up @@ -366,7 +360,7 @@ impl Manifestation {
// End transaction
tx.commit();

Ok(Some(installer_hash))
Ok(())
}

// If the previous installation was from a v1 manifest, then it
Expand Down

0 comments on commit 942476d

Please sign in to comment.