docs/formatting
diff --git a/src/client.rs b/src/client.rs
index 60b1614..260a187 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -257,6 +257,16 @@
pub fn build() -> ConfigBuilder {
ConfigBuilder::default()
}
+
+ /// Return the optional maximum root metadata size.
+ pub fn max_root_size(&self) -> &Option<usize> {
+ &self.max_root_size
+ }
+
+ /// Return the optional maximum timestamp metadata size.
+ pub fn max_timestamp_size(&self) -> &Option<usize> {
+ &self.max_timestamp_size
+ }
}
/// Helper for building and validating a TUF `Config`.
diff --git a/src/crypto.rs b/src/crypto.rs
index 3e3b8b6..5ac145d 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -508,7 +508,7 @@
/// assert_eq!(HashValue::from_hex("abcd").unwrap().value(), &[0xab, 0xcd]);
/// ```
pub fn from_hex(s: &str) -> Result<Self> {
- Ok(HashValue(HEXLOWER.decode(s.as_bytes())?))
+ Ok(HashValue(HEXLOWER.decode(s.as_bytes())?))
}
/// Create a new `HashValue` from the given digest bytes.
diff --git a/src/error.rs b/src/error.rs
index 7c2e903..21ffff0 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -89,7 +89,7 @@
}
}
-impl From <tempfile::PersistError> for Error {
+impl From<tempfile::PersistError> for Error {
fn from(err: tempfile::PersistError) -> Error {
Error::Opaque(format!("Error persisting temp file: {:?}", err))
}
diff --git a/src/lib.rs b/src/lib.rs
index bdf4ad8..0f7a073 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -20,7 +20,8 @@
//! use tuf::Tuf;
//! use tuf::crypto::KeyId;
//! use tuf::client::{Client, Config};
-//! use tuf::metadata::{RootMetadata, Unverified, SignedMetadata};
+//! use tuf::metadata::{RootMetadata, Unverified, SignedMetadata, Role, MetadataPath,
+//! MetadataVersion};
//! use tuf::interchange::{DataInterchange, JsonDataInterchange};
//! use tuf::repository::{Repository, FileSystemRepository, HttpRepository};
//! use url::Url;
@@ -31,18 +32,11 @@
//! "85f6c314f168a8c3d92a57f2d9bb6ab495a4ac921f02d2e32befc7bc812bd904",
//! ];
//!
-//! fn get_original_root() -> File { unimplemented!() }
-//!
//! fn main() {
-//! let root: SignedMetadata<JsonDataInterchange, RootMetadata, Unverified> =
-//! JsonDataInterchange::from_reader(get_original_root()).unwrap();
-//!
//! let key_ids: Vec<KeyId> = TRUSTED_ROOT_KEY_IDS.iter()
//! .map(|k| KeyId::from_string(k).unwrap())
//! .collect();
//!
-//! let tuf = Tuf::<JsonDataInterchange>::from_root_pinned(root, &key_ids).unwrap();
-//!
//! let mut local = FileSystemRepository::new(PathBuf::from("~/.rustup"));
//!
//! let mut remote = HttpRepository::new(
@@ -51,6 +45,17 @@
//! Some("rustup/1.4.0".into()));
//!
//! let config = Config::build().finish().unwrap();
+//!
+//! // fetching this original root from the network is safe because
+//! // we are using trusted, pinned keys to verify it
+//! let root = remote.fetch_metadata(&Role::Root,
+//! &MetadataPath::from_role(&Role::Root),
+//! &MetadataVersion::None,
+//! config.max_root_size(),
+//! None).unwrap();
+//!
+//! let tuf = Tuf::<JsonDataInterchange>::from_root_pinned(root, &key_ids).unwrap();
+//!
//! let mut client = Client::new(tuf, config, local, remote).unwrap();
//! let _ = client.update_local().unwrap();
//! let _ = client.update_remote().unwrap();
diff --git a/src/metadata.rs b/src/metadata.rs
index 4fe2863..ffc1c62 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -24,7 +24,7 @@
];
static PATH_ILLEGAL_COMPONENTS_CASE_INSENSITIVE: &'static [&str] = &[
- // DOS device files
+ // DOS device files
"CON",
"PRN",
"AUX",
@@ -56,7 +56,7 @@
static PATH_ILLEGAL_STRINGS: &'static [&str] = &[
"\\", // for windows compatibility
- "<",
+ "<",
">",
"\"",
"|",
@@ -100,26 +100,32 @@
fn safe_path(path: &str) -> Result<()> {
if path.starts_with("/") {
- return Err(Error::IllegalArgument("Cannot start with '/'".into()))
+ return Err(Error::IllegalArgument("Cannot start with '/'".into()));
}
for bad_str in PATH_ILLEGAL_STRINGS {
if path.contains(bad_str) {
- return Err(Error::IllegalArgument(format!("Path cannot contain {:?}", bad_str)))
+ return Err(Error::IllegalArgument(
+ format!("Path cannot contain {:?}", bad_str),
+ ));
}
}
for component in path.split('/') {
for bad_str in PATH_ILLEGAL_COMPONENTS {
if component == *bad_str {
- return Err(Error::IllegalArgument(format!("Path cannot have component {:?}", component)))
+ return Err(Error::IllegalArgument(
+ format!("Path cannot have component {:?}", component),
+ ));
}
}
let component_lower = component.to_lowercase();
for bad_str in PATH_ILLEGAL_COMPONENTS_CASE_INSENSITIVE {
if component_lower.as_str() == *bad_str {
- return Err(Error::IllegalArgument(format!("Path cannot have component {:?}", component)))
+ return Err(Error::IllegalArgument(
+ format!("Path cannot have component {:?}", component),
+ ));
}
}
}
@@ -176,7 +182,7 @@
&Role::Timestamp if &path.0 == "timestamp" => true,
&Role::Targets if &path.0 == "targets" => true,
// TODO delegation support
- _ => false
+ _ => false,
}
}
}
@@ -597,9 +603,7 @@
impl<'de> Deserialize<'de> for MetadataPath {
fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
let s: String = Deserialize::deserialize(de)?;
- MetadataPath::new(s).map_err(|e| {
- DeserializeError::custom(format!("{:?}", e))
- })
+ MetadataPath::new(s).map_err(|e| DeserializeError::custom(format!("{:?}", e)))
}
}
@@ -834,9 +838,7 @@
impl<'de> Deserialize<'de> for TargetPath {
fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
let s: String = Deserialize::deserialize(de)?;
- TargetPath::new(s).map_err(|e| {
- DeserializeError::custom(format!("{:?}", e))
- })
+ TargetPath::new(s).map_err(|e| DeserializeError::custom(format!("{:?}", e)))
}
}
@@ -891,8 +893,14 @@
}
let mut hashes = HashMap::new();
- let _ = hashes.insert(HashAlgorithm::Sha256, HashValue::new(sha256.finish().as_ref().to_vec()));
- let _ = hashes.insert(HashAlgorithm::Sha512, HashValue::new(sha512.finish().as_ref().to_vec()));
+ let _ = hashes.insert(
+ HashAlgorithm::Sha256,
+ HashValue::new(sha256.finish().as_ref().to_vec()),
+ );
+ let _ = hashes.insert(
+ HashAlgorithm::Sha512,
+ HashValue::new(sha512.finish().as_ref().to_vec()),
+ );
Ok(TargetDescription {
length: length,
hashes: hashes,
diff --git a/src/repository.rs b/src/repository.rs
index 715d945..476ea1a 100644
--- a/src/repository.rs
+++ b/src/repository.rs
@@ -15,7 +15,8 @@
use Result;
use crypto::{self, HashAlgorithm, HashValue};
use error::Error;
-use metadata::{SignedMetadata, MetadataVersion, Unverified, Verified, Role, Metadata, TargetPath, TargetDescription, MetadataPath};
+use metadata::{SignedMetadata, MetadataVersion, Unverified, Verified, Role, Metadata, TargetPath,
+ TargetDescription, MetadataPath};
use interchange::DataInterchange;
/// Top-level trait that represents a TUF repository and contains all the ways it can be interacted
@@ -54,7 +55,12 @@
M: Metadata;
/// Store the given target.
- fn store_target<R>(&mut self, read: R, target_path: &TargetPath, target_description: &TargetDescription) -> Result<()>
+ fn store_target<R>(
+ &mut self,
+ read: R,
+ target_path: &TargetPath,
+ target_description: &TargetDescription,
+ ) -> Result<()>
where
R: Read;
@@ -66,7 +72,7 @@
/// Perform a sanity check that `M`, `Role`, and `MetadataPath` all desrcribe the same entity.
fn check<M>(role: &Role, meta_path: &MetadataPath) -> Result<()>
where
- M: Metadata
+ M: Metadata,
{
if role != &M::role() {
return Err(Error::IllegalArgument(format!(
@@ -77,10 +83,9 @@
}
if !role.fuzzy_matches_path(meta_path) {
- return Err(Error::IllegalArgument(format!(
- "Role {} does not match path {:?}",
- role,
- meta_path)))
+ return Err(Error::IllegalArgument(
+ format!("Role {} does not match path {:?}", role, meta_path),
+ ));
}
Ok(())
@@ -247,13 +252,23 @@
Ok(D::from_reader(&*out)?)
}
- fn store_target<R>(&mut self, read: R, target_path: &TargetPath, target_description: &TargetDescription) -> Result<()>
+ fn store_target<R>(
+ &mut self,
+ read: R,
+ target_path: &TargetPath,
+ target_description: &TargetDescription,
+ ) -> Result<()>
where
- R: Read
+ R: Read,
{
let mut temp_file = NamedTempFile::new_in(self.local_path.join("temp"))?;
let hash_data = crypto::hash_preference(target_description.hashes())?;
- Self::safe_read(read, &mut temp_file, Some(target_description.length() as i64), Some(hash_data))?;
+ Self::safe_read(
+ read,
+ &mut temp_file,
+ Some(target_description.length() as i64),
+ Some(hash_data),
+ )?;
let mut path = self.local_path.clone().join("targets");
path.extend(target_path.components());
@@ -267,7 +282,7 @@
path.extend(target_path.components());
if !path.exists() {
- return Err(Error::NotFound)
+ return Err(Error::NotFound);
}
Ok(File::open(&path)?)
@@ -313,7 +328,9 @@
let mut url = self.url.clone();
url.path_segments_mut()
- .map_err(|_| Error::IllegalArgument(format!("URL was 'cannot-be-a-base': {:?}", self.url)))?
+ .map_err(|_| {
+ Error::IllegalArgument(format!("URL was 'cannot-be-a-base': {:?}", self.url))
+ })?
.extend(components);
let req = self.client.get(url.clone()).headers(headers);
@@ -323,7 +340,9 @@
if resp.status == StatusCode::NotFound {
Err(Error::NotFound)
} else {
- Err(Error::Opaque(format!("Error getting {:?}: {:?}", url, resp)))
+ Err(Error::Opaque(
+ format!("Error getting {:?}: {:?}", url, resp),
+ ))
}
} else {
Ok(resp)
@@ -379,7 +398,7 @@
/// This always returns `Err` as storing over HTTP is not yet supported.
fn store_target<R>(&mut self, _: R, _: &TargetPath, _: &TargetDescription) -> Result<()>
where
- R: Read
+ R: Read,
{
Err(Error::Opaque(
"Http repo store not implemented".to_string(),
@@ -440,7 +459,10 @@
Self::check::<M>(role, meta_path)?;
let mut buf = Vec::new();
D::to_writer(&mut buf, metadata)?;
- let _ = self.metadata.insert((meta_path.clone(), version.clone()), buf);
+ let _ = self.metadata.insert(
+ (meta_path.clone(), version.clone()),
+ buf,
+ );
Ok(())
}
@@ -454,26 +476,41 @@
) -> Result<SignedMetadata<D, M, Unverified>>
where
M: Metadata,
- {
+ {
Self::check::<M>(role, meta_path)?;
match self.metadata.get(&(meta_path.clone(), version.clone())) {
Some(bytes) => {
let mut buf = Vec::new();
- Self::safe_read(bytes.as_slice(), &mut buf, max_size.map(|x| x as i64), hash_data)?;
+ Self::safe_read(
+ bytes.as_slice(),
+ &mut buf,
+ max_size.map(|x| x as i64),
+ hash_data,
+ )?;
D::from_reader(&*buf)
- },
+ }
None => Err(Error::NotFound),
}
}
- fn store_target<R>(&mut self, read: R, target_path: &TargetPath, target_description: &TargetDescription) -> Result<()>
+ fn store_target<R>(
+ &mut self,
+ read: R,
+ target_path: &TargetPath,
+ target_description: &TargetDescription,
+ ) -> Result<()>
where
- R: Read
+ R: Read,
{
let mut buf = Vec::new();
let hash_data = crypto::hash_preference(target_description.hashes())?;
- Self::safe_read(read, &mut buf, Some(target_description.length() as i64), Some(hash_data))?;
+ Self::safe_read(
+ read,
+ &mut buf,
+ Some(target_description.length() as i64),
+ Some(hash_data),
+ )?;
let _ = self.targets.insert(target_path.clone(), buf);
Ok(())
}
@@ -481,7 +518,7 @@
fn fetch_target(&mut self, target_path: &TargetPath) -> Result<Self::TargetRead> {
match self.targets.get(target_path) {
Some(bytes) => Ok(Cursor::new(bytes.clone())),
- None => Err(Error::NotFound)
+ None => Err(Error::NotFound),
}
}
}
@@ -508,7 +545,10 @@
assert_eq!(buf.as_slice(), data);
let bad_data: &[u8] = b"you're in a desert";
- assert!(repo.store_target(bad_data, &path, &target_description).is_err());
+ assert!(
+ repo.store_target(bad_data, &path, &target_description)
+ .is_err()
+ );
let mut read = repo.fetch_target(&path).unwrap();
let mut buf = Vec::new();
@@ -519,7 +559,8 @@
#[test]
fn file_system_repo_targets() {
let temp_dir = TempDir::new("rust-tuf").unwrap();
- let mut repo = FileSystemRepository::<JsonDataInterchange>::new(temp_dir.path().to_path_buf());
+ let mut repo =
+ FileSystemRepository::<JsonDataInterchange>::new(temp_dir.path().to_path_buf());
repo.initialize().unwrap();
let data: &[u8] = b"like tears in the rain";
@@ -534,7 +575,10 @@
assert_eq!(buf.as_slice(), data);
let bad_data: &[u8] = b"you're in a desert";
- assert!(repo.store_target(bad_data, &path, &target_description).is_err());
+ assert!(
+ repo.store_target(bad_data, &path, &target_description)
+ .is_err()
+ );
let mut read = repo.fetch_target(&path).unwrap();
let mut buf = Vec::new();
diff --git a/src/tuf.rs b/src/tuf.rs
index 7e97611..f81e14c 100644
--- a/src/tuf.rs
+++ b/src/tuf.rs
@@ -301,8 +301,9 @@
let _ = self.safe_snapshot_ref()?;
let targets = self.safe_targets_ref()?;
- targets.targets().get(target_path)
- .ok_or(Error::TargetUnavailable)
+ targets.targets().get(target_path).ok_or(
+ Error::TargetUnavailable,
+ )
// TODO include searching delegations
}