From 2ce159343ba73dec317ece80b988832e05979762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Mon, 3 Aug 2020 14:10:45 +0200 Subject: [PATCH] sync: verify size and checksum of pulled archives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and not just of previously synced ones. we can't use BackupManifest::verify_file as the archive is still stored under the tmp path at this point. Signed-off-by: Fabian Grünbichler --- src/client/pull.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/client/pull.rs b/src/client/pull.rs index 629e8266..429ab458 100644 --- a/src/client/pull.rs +++ b/src/client/pull.rs @@ -62,15 +62,32 @@ async fn download_manifest( Ok(tmp_manifest_file) } +fn verify_archive( + info: &FileInfo, + csum: &[u8; 32], + size: u64, +) -> Result<(), Error> { + if size != info.size { + bail!("wrong size for file '{}' ({} != {})", info.filename, info.size, size); + } + + if csum != &info.csum { + bail!("wrong checksum for file '{}'", info.filename); + } + + Ok(()) +} + async fn pull_single_archive( worker: &WorkerTask, reader: &BackupReader, chunk_reader: &mut RemoteChunkReader, tgt_store: Arc, snapshot: &BackupDir, - archive_name: &str, + archive_info: &FileInfo, ) -> Result<(), Error> { + let archive_name = &archive_info.filename; let mut path = tgt_store.base_path(); path.push(snapshot.relative_path()); path.push(archive_name); @@ -91,16 +108,23 @@ async fn pull_single_archive( ArchiveType::DynamicIndex => { let index = DynamicIndexReader::new(tmpfile) .map_err(|err| format_err!("unable to read dynamic index {:?} - {}", tmp_path, err))?; + let (csum, size) = index.compute_csum(); + verify_archive(archive_info, &csum, size)?; pull_index_chunks(worker, chunk_reader, tgt_store.clone(), index).await?; } ArchiveType::FixedIndex => { let index = FixedIndexReader::new(tmpfile) .map_err(|err| format_err!("unable to read fixed index '{:?}' - {}", tmp_path, err))?; + let (csum, size) = index.compute_csum(); + verify_archive(archive_info, &csum, size)?; pull_index_chunks(worker, chunk_reader, tgt_store.clone(), index).await?; } - ArchiveType::Blob => { /* nothing to do */ } + ArchiveType::Blob => { + let (csum, size) = compute_file_csum(&mut tmpfile)?; + verify_archive(archive_info, &csum, size)?; + } } if let Err(err) = std::fs::rename(&tmp_path, &path) { bail!("Atomic rename file {:?} failed - {}", path, err); @@ -248,7 +272,7 @@ async fn pull_snapshot( &mut chunk_reader, tgt_store.clone(), snapshot, - &item.filename, + &item, ).await?; }