From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id F166368F58 for ; Mon, 3 Aug 2020 14:11:02 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EF1082DB82 for ; Mon, 3 Aug 2020 14:11:02 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 5D3012DB78 for ; Mon, 3 Aug 2020 14:11:02 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 27BD043390 for ; Mon, 3 Aug 2020 14:11:02 +0200 (CEST) From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= To: pbs-devel@lists.proxmox.com Date: Mon, 3 Aug 2020 14:10:45 +0200 Message-Id: <20200803121046.3623216-4-f.gruenbichler@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200803121046.3623216-1-f.gruenbichler@proxmox.com> References: <20200803121046.3623216-1-f.gruenbichler@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.043 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 3/4] sync: verify size and checksum of pulled archives X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Aug 2020 12:11:03 -0000 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?; } -- 2.20.1