// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT OR Apache-2.0 use tempfile::TempDir; use test_utils::{dir_url, read_to_end, test_data}; use tough::{FilesystemTransport, Limits, Repository, RepositoryLoader, TargetName}; mod test_utils; /// Test that `tough` can process repositories generated by [`tuf`], the reference Python /// implementation using the `load_default` function. /// /// [`tuf`]: https://github.com/theupdateframework/tuf #[tokio::test] async fn test_tuf_reference_impl() { let base = test_data().join("tuf-reference-impl"); let repo = RepositoryLoader::new( &tokio::fs::read(base.join("metadata").join("1.root.json")) .await .unwrap(), dir_url(base.join("metadata")), dir_url(base.join("targets")), ) .load() .await .unwrap(); assert_tuf_reference_impl(&repo).await; } async fn assert_tuf_reference_impl(repo: &Repository) { let file1 = TargetName::new("file1.txt").unwrap(); let file2 = TargetName::new("file2.txt").unwrap(); let file3 = TargetName::new("file3.txt").unwrap(); assert_eq!( read_to_end(repo.read_target(&file1).await.unwrap().unwrap()).await, &b"This is an example target file."[..] ); assert_eq!( read_to_end(repo.read_target(&file2).await.unwrap().unwrap()).await, &b"This is an another example target file."[..] ); assert_eq!( repo.targets() .signed .targets .get(&file1) .unwrap() .custom .get("file_permissions") .unwrap(), "0644" ); assert!(repo .targets() .signed .delegations .as_ref() .unwrap() .target_is_delegated(&file3)); } /// Test that `tough` can process repositories generated by [`tuf`], the reference Python /// implementation using the `load` function with non-default [`Options`]. #[tokio::test] async fn test_tuf_reference_impl_default_transport() { let base = test_data().join("tuf-reference-impl"); let datastore = TempDir::new().unwrap(); let repo = RepositoryLoader::new( &tokio::fs::read(base.join("metadata").join("1.root.json")) .await .unwrap(), dir_url(base.join("metadata")), dir_url(base.join("targets")), ) .transport(FilesystemTransport) .limits(Limits { max_root_size: 1000, max_targets_size: 2000, max_timestamp_size: 3000, max_snapshot_size: 4000, max_root_updates: 1, }) .datastore(datastore.path()) .load() .await .unwrap(); assert_tuf_reference_impl(&repo).await; } /// Test that `tough` can load a repository that has some unusual delegate role names. This ensures /// that percent encoded role names are handled correctly and that path traversal characters in a /// role name do not cause `tough` to write outside of its datastore. #[tokio::test] async fn test_dubious_role_name() { let base = test_data().join("dubious-role-names"); let datastore = TempDir::new().unwrap(); let repo = RepositoryLoader::new( &tokio::fs::read(base.join("metadata").join("1.root.json")) .await .unwrap(), dir_url(base.join("metadata")), dir_url(base.join("targets")), ) .datastore(datastore.path()) .load() .await .unwrap(); // Prove that the role name has path traversal characters. let expected_rolename = "../../path/like/dubious"; assert_eq!( repo.delegated_role(expected_rolename).unwrap().name, expected_rolename ); // Prove that the the role's metadata filename has not been written outside of the datastore. let expected_filename = "..%2F..%2Fpath%2Flike%2Fdubious.json"; assert!(datastore.path().join(expected_filename).is_file()) }