Migrate tor-dirmgr from chrono to time 0.3
(This appears to be the emerging consensus of how to handle RUSTSEC-2020-0159.)
This commit is contained in:
parent
4893e9a15f
commit
968ffa3d6c
|
@ -483,19 +483,6 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono"
|
|
||||||
version = "0.4.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
"time 0.1.44",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cipher"
|
name = "cipher"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -2030,13 +2017,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e2aebd07fccf5c0d3f1458219965b0861d45f5db9f9b2617277fa7f85179213"
|
checksum = "6e2aebd07fccf5c0d3f1458219965b0861d45f5db9f9b2617277fa7f85179213"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"fallible-streaming-iterator",
|
"fallible-streaming-iterator",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"libsqlite3-sys",
|
"libsqlite3-sys",
|
||||||
"memchr",
|
"memchr",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2260,7 +2247,7 @@ dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time 0.3.3",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2390,17 +2377,6 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "time"
|
|
||||||
version = "0.1.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -2658,7 +2634,6 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
|
||||||
"derive_builder",
|
"derive_builder",
|
||||||
"digest",
|
"digest",
|
||||||
"fslock",
|
"fslock",
|
||||||
|
@ -2677,6 +2652,7 @@ dependencies = [
|
||||||
"signature",
|
"signature",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"time",
|
||||||
"tor-checkable",
|
"tor-checkable",
|
||||||
"tor-circmgr",
|
"tor-circmgr",
|
||||||
"tor-consdiff",
|
"tor-consdiff",
|
||||||
|
@ -2789,7 +2765,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"signature",
|
"signature",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time 0.3.3",
|
"time",
|
||||||
"tor-bytes",
|
"tor-bytes",
|
||||||
"tor-cert",
|
"tor-cert",
|
||||||
"tor-checkable",
|
"tor-checkable",
|
||||||
|
|
|
@ -28,7 +28,6 @@ tor-rtcompat = { path="../tor-rtcompat", version="0.0.0" }
|
||||||
|
|
||||||
async-trait = "0.1.48"
|
async-trait = "0.1.48"
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
chrono = { version = "0.4.19", default-features = false }
|
|
||||||
derive_builder = "0.10.2"
|
derive_builder = "0.10.2"
|
||||||
digest = "0.9.0"
|
digest = "0.9.0"
|
||||||
futures = "0.3.13"
|
futures = "0.3.13"
|
||||||
|
@ -39,10 +38,11 @@ tracing = "0.1.26"
|
||||||
memmap2 = { version = "0.5.0", optional = true }
|
memmap2 = { version = "0.5.0", optional = true }
|
||||||
postage = { version="0.4.1", default-features=false, features=["futures-traits"] }
|
postage = { version="0.4.1", default-features=false, features=["futures-traits"] }
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
rusqlite = { version = "0.26.0", features = ["chrono"] }
|
rusqlite = { version = "0.26.0", features = ["time"] }
|
||||||
serde = { version = "1.0.124", features = ["derive"] }
|
serde = { version = "1.0.124", features = ["derive"] }
|
||||||
signature = "1.3.1"
|
signature = "1.3.1"
|
||||||
thiserror = "1.0.24"
|
thiserror = "1.0.24"
|
||||||
|
time = { version = "0.3.3", features = ["formatting", "parsing"] }
|
||||||
humantime-serde = "1.0.1"
|
humantime-serde = "1.0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
//! [`bootstrap`](crate::bootstrap) module for functions that actually
|
//! [`bootstrap`](crate::bootstrap) module for functions that actually
|
||||||
//! load or download directory information.
|
//! load or download directory information.
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::{Mutex, Weak};
|
use std::sync::{Mutex, Weak};
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
use time::OffsetDateTime;
|
||||||
use tor_netdir::{MdReceiver, NetDir, PartialNetDir};
|
use tor_netdir::{MdReceiver, NetDir, PartialNetDir};
|
||||||
use tor_netdoc::doc::netstatus::Lifetime;
|
use tor_netdoc::doc::netstatus::Lifetime;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
@ -682,9 +682,9 @@ fn pick_download_time(lifetime: &Lifetime) -> SystemTime {
|
||||||
let zero = Duration::new(0, 0);
|
let zero = Duration::new(0, 0);
|
||||||
let t = lowbound + rand::thread_rng().gen_range(zero..uncertainty);
|
let t = lowbound + rand::thread_rng().gen_range(zero..uncertainty);
|
||||||
info!("The current consensus is fresh until {}, and valid until {}. I've picked {} as the earliest time to replace it.",
|
info!("The current consensus is fresh until {}, and valid until {}. I've picked {} as the earliest time to replace it.",
|
||||||
DateTime::<Utc>::from(lifetime.fresh_until()),
|
OffsetDateTime::from(lifetime.fresh_until()),
|
||||||
DateTime::<Utc>::from(lifetime.valid_until()),
|
OffsetDateTime::from(lifetime.valid_until()),
|
||||||
DateTime::<Utc>::from(t));
|
OffsetDateTime::from(t));
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,8 @@ use std::convert::TryInto;
|
||||||
use std::path::{self, Path, PathBuf};
|
use std::path::{self, Path, PathBuf};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use chrono::prelude::*;
|
|
||||||
use chrono::Duration as CDuration;
|
|
||||||
use rusqlite::{params, OpenFlags, OptionalExtension, Transaction};
|
use rusqlite::{params, OpenFlags, OptionalExtension, Transaction};
|
||||||
|
use time::OffsetDateTime;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
|
@ -263,7 +262,7 @@ impl SqliteStore {
|
||||||
doctype: &str,
|
doctype: &str,
|
||||||
dtype: &str,
|
dtype: &str,
|
||||||
digest: &[u8],
|
digest: &[u8],
|
||||||
expires: DateTime<Utc>,
|
expires: OffsetDateTime,
|
||||||
) -> Result<SavedBlobHandle<'_>> {
|
) -> Result<SavedBlobHandle<'_>> {
|
||||||
let digest = hex::encode(digest);
|
let digest = hex::encode(digest);
|
||||||
let digeststr = format!("{}-{}", dtype, digest);
|
let digeststr = format!("{}-{}", dtype, digest);
|
||||||
|
@ -292,7 +291,7 @@ impl SqliteStore {
|
||||||
doctype: &str,
|
doctype: &str,
|
||||||
dtype: &str,
|
dtype: &str,
|
||||||
digest: &[u8],
|
digest: &[u8],
|
||||||
expires: DateTime<Utc>,
|
expires: OffsetDateTime,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let h = self.save_blob_internal(contents, doctype, dtype, digest, expires)?;
|
let h = self.save_blob_internal(contents, doctype, dtype, digest, expires)?;
|
||||||
let SavedBlobHandle {
|
let SavedBlobHandle {
|
||||||
|
@ -318,13 +317,16 @@ impl SqliteStore {
|
||||||
let lifetime = cmeta.lifetime();
|
let lifetime = cmeta.lifetime();
|
||||||
let sha3_of_signed = cmeta.sha3_256_of_signed();
|
let sha3_of_signed = cmeta.sha3_256_of_signed();
|
||||||
let sha3_of_whole = cmeta.sha3_256_of_whole();
|
let sha3_of_whole = cmeta.sha3_256_of_whole();
|
||||||
let valid_after: DateTime<Utc> = lifetime.valid_after().into();
|
let valid_after: OffsetDateTime = lifetime.valid_after().into();
|
||||||
let fresh_until: DateTime<Utc> = lifetime.fresh_until().into();
|
let fresh_until: OffsetDateTime = lifetime.fresh_until().into();
|
||||||
let valid_until: DateTime<Utc> = lifetime.valid_until().into();
|
let valid_until: OffsetDateTime = lifetime.valid_until().into();
|
||||||
|
|
||||||
|
/// How long to keep a consensus around after it has expired
|
||||||
|
const CONSENSUS_LIFETIME: time::Duration = time::Duration::days(4);
|
||||||
|
|
||||||
// After a few days have passed, a consensus is no good for
|
// After a few days have passed, a consensus is no good for
|
||||||
// anything at all, not even diffs.
|
// anything at all, not even diffs.
|
||||||
let expires = valid_until + CDuration::days(4);
|
let expires = valid_until + CONSENSUS_LIFETIME;
|
||||||
|
|
||||||
let doctype = format!("con:{}", flavor.name());
|
let doctype = format!("con:{}", flavor.name());
|
||||||
|
|
||||||
|
@ -370,7 +372,7 @@ impl SqliteStore {
|
||||||
/// Return the valid-after time for the latest non non-pending consensus,
|
/// Return the valid-after time for the latest non non-pending consensus,
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
// We should revise the tests to use latest_consensus_meta instead.
|
// We should revise the tests to use latest_consensus_meta instead.
|
||||||
fn latest_consensus_time(&self, flavor: ConsensusFlavor) -> Result<Option<DateTime<Utc>>> {
|
fn latest_consensus_time(&self, flavor: ConsensusFlavor) -> Result<Option<OffsetDateTime>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.latest_consensus_meta(flavor)?
|
.latest_consensus_meta(flavor)?
|
||||||
.map(|m| m.lifetime().valid_after().into()))
|
.map(|m| m.lifetime().valid_after().into()))
|
||||||
|
@ -388,7 +390,7 @@ impl SqliteStore {
|
||||||
pending: Option<bool>,
|
pending: Option<bool>,
|
||||||
) -> Result<Option<InputString>> {
|
) -> Result<Option<InputString>> {
|
||||||
trace!(?flavor, ?pending, "Loading latest consensus from cache");
|
trace!(?flavor, ?pending, "Loading latest consensus from cache");
|
||||||
let rv: Option<(DateTime<Utc>, DateTime<Utc>, String)>;
|
let rv: Option<(OffsetDateTime, OffsetDateTime, String)>;
|
||||||
rv = match pending {
|
rv = match pending {
|
||||||
None => self
|
None => self
|
||||||
.conn
|
.conn
|
||||||
|
@ -482,8 +484,8 @@ impl SqliteStore {
|
||||||
let ids = meta.key_ids();
|
let ids = meta.key_ids();
|
||||||
let id_digest = hex::encode(ids.id_fingerprint.as_bytes());
|
let id_digest = hex::encode(ids.id_fingerprint.as_bytes());
|
||||||
let sk_digest = hex::encode(ids.sk_fingerprint.as_bytes());
|
let sk_digest = hex::encode(ids.sk_fingerprint.as_bytes());
|
||||||
let published: DateTime<Utc> = meta.published().into();
|
let published: OffsetDateTime = meta.published().into();
|
||||||
let expires: DateTime<Utc> = meta.expires().into();
|
let expires: OffsetDateTime = meta.expires().into();
|
||||||
stmt.execute(params![id_digest, sk_digest, published, expires, content])?;
|
stmt.execute(params![id_digest, sk_digest, published, expires, content])?;
|
||||||
}
|
}
|
||||||
stmt.finalize()?;
|
stmt.finalize()?;
|
||||||
|
@ -572,7 +574,7 @@ impl SqliteStore {
|
||||||
{
|
{
|
||||||
let tx = self.conn.transaction()?;
|
let tx = self.conn.transaction()?;
|
||||||
let mut stmt = tx.prepare(UPDATE_MD_LISTED)?;
|
let mut stmt = tx.prepare(UPDATE_MD_LISTED)?;
|
||||||
let when: DateTime<Utc> = when.into();
|
let when: OffsetDateTime = when.into();
|
||||||
|
|
||||||
for md_digest in input.into_iter() {
|
for md_digest in input.into_iter() {
|
||||||
let h_digest = hex::encode(md_digest);
|
let h_digest = hex::encode(md_digest);
|
||||||
|
@ -590,7 +592,7 @@ impl SqliteStore {
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = (&'a str, &'a MdDigest)>,
|
I: IntoIterator<Item = (&'a str, &'a MdDigest)>,
|
||||||
{
|
{
|
||||||
let when: DateTime<Utc> = when.into();
|
let when: OffsetDateTime = when.into();
|
||||||
|
|
||||||
let tx = self.conn.transaction()?;
|
let tx = self.conn.transaction()?;
|
||||||
let mut stmt = tx.prepare(INSERT_MD)?;
|
let mut stmt = tx.prepare(INSERT_MD)?;
|
||||||
|
@ -614,7 +616,7 @@ impl SqliteStore {
|
||||||
let mut stmt = tx.prepare(INSERT_RD)?;
|
let mut stmt = tx.prepare(INSERT_RD)?;
|
||||||
|
|
||||||
for (content, when, rd_digest) in input.into_iter() {
|
for (content, when, rd_digest) in input.into_iter() {
|
||||||
let when: DateTime<Utc> = when.into();
|
let when: OffsetDateTime = when.into();
|
||||||
let h_digest = hex::encode(rd_digest);
|
let h_digest = hex::encode(rd_digest);
|
||||||
stmt.execute(params![h_digest, when, content])?;
|
stmt.execute(params![h_digest, when, content])?;
|
||||||
}
|
}
|
||||||
|
@ -691,9 +693,9 @@ fn digest_from_dstr(s: &str) -> Result<[u8; 32]> {
|
||||||
/// Create a ConsensusMeta from a `Row` returned by one of
|
/// Create a ConsensusMeta from a `Row` returned by one of
|
||||||
/// `FIND_LATEST_CONSENSUS_META` or `FIND_CONSENSUS_AND_META_BY_DIGEST`.
|
/// `FIND_LATEST_CONSENSUS_META` or `FIND_CONSENSUS_AND_META_BY_DIGEST`.
|
||||||
fn cmeta_from_row(row: &rusqlite::Row<'_>) -> Result<ConsensusMeta> {
|
fn cmeta_from_row(row: &rusqlite::Row<'_>) -> Result<ConsensusMeta> {
|
||||||
let va: DateTime<Utc> = row.get(0)?;
|
let va: OffsetDateTime = row.get(0)?;
|
||||||
let fu: DateTime<Utc> = row.get(1)?;
|
let fu: OffsetDateTime = row.get(1)?;
|
||||||
let vu: DateTime<Utc> = row.get(2)?;
|
let vu: OffsetDateTime = row.get(2)?;
|
||||||
let d_signed: String = row.get(3)?;
|
let d_signed: String = row.get(3)?;
|
||||||
let d_all: String = row.get(4)?;
|
let d_all: String = row.get(4)?;
|
||||||
let lifetime = Lifetime::new(va.into(), fu.into(), vu.into())?;
|
let lifetime = Lifetime::new(va.into(), fu.into(), vu.into())?;
|
||||||
|
@ -927,6 +929,7 @@ mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
|
use time::ext::NumericalDuration;
|
||||||
|
|
||||||
fn new_empty() -> Result<(TempDir, SqliteStore)> {
|
fn new_empty() -> Result<(TempDir, SqliteStore)> {
|
||||||
let tmp_dir = tempdir().unwrap();
|
let tmp_dir = tempdir().unwrap();
|
||||||
|
@ -988,8 +991,8 @@ mod test {
|
||||||
fn blobs() -> Result<()> {
|
fn blobs() -> Result<()> {
|
||||||
let (tmp_dir, mut store) = new_empty()?;
|
let (tmp_dir, mut store) = new_empty()?;
|
||||||
|
|
||||||
let now = Utc::now();
|
let now = OffsetDateTime::now_utc();
|
||||||
let one_week = CDuration::weeks(1);
|
let one_week = 1.weeks();
|
||||||
|
|
||||||
let fname1 = store.save_blob(
|
let fname1 = store.save_blob(
|
||||||
b"Hello world",
|
b"Hello world",
|
||||||
|
@ -1049,8 +1052,8 @@ mod test {
|
||||||
use tor_netdoc::doc::netstatus;
|
use tor_netdoc::doc::netstatus;
|
||||||
|
|
||||||
let (_tmp_dir, mut store) = new_empty()?;
|
let (_tmp_dir, mut store) = new_empty()?;
|
||||||
let now = Utc::now();
|
let now = OffsetDateTime::now_utc();
|
||||||
let one_hour = CDuration::hours(1);
|
let one_hour = 1.hours();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
store.latest_consensus_time(ConsensusFlavor::Microdesc)?,
|
store.latest_consensus_time(ConsensusFlavor::Microdesc)?,
|
||||||
|
@ -1147,8 +1150,8 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn authcerts() -> Result<()> {
|
fn authcerts() -> Result<()> {
|
||||||
let (_tmp_dir, mut store) = new_empty()?;
|
let (_tmp_dir, mut store) = new_empty()?;
|
||||||
let now = Utc::now();
|
let now = OffsetDateTime::now_utc();
|
||||||
let one_hour = CDuration::hours(1);
|
let one_hour = 1.hours();
|
||||||
|
|
||||||
let keyids = AuthCertKeyIds {
|
let keyids = AuthCertKeyIds {
|
||||||
id_fingerprint: [3; 20].into(),
|
id_fingerprint: [3; 20].into(),
|
||||||
|
@ -1174,21 +1177,22 @@ mod test {
|
||||||
fn microdescs() -> Result<()> {
|
fn microdescs() -> Result<()> {
|
||||||
let (_tmp_dir, mut store) = new_empty()?;
|
let (_tmp_dir, mut store) = new_empty()?;
|
||||||
|
|
||||||
let now = Utc::now();
|
let now = OffsetDateTime::now_utc();
|
||||||
let one_day = CDuration::days(1);
|
let one_day = 1.days();
|
||||||
|
|
||||||
let d1 = [5_u8; 32];
|
let d1 = [5_u8; 32];
|
||||||
let d2 = [7; 32];
|
let d2 = [7; 32];
|
||||||
let d3 = [42; 32];
|
let d3 = [42; 32];
|
||||||
let d4 = [99; 32];
|
let d4 = [99; 32];
|
||||||
|
|
||||||
|
let long_ago: OffsetDateTime = now - one_day * 100;
|
||||||
store.store_microdescs(
|
store.store_microdescs(
|
||||||
vec![
|
vec![
|
||||||
("Fake micro 1", &d1),
|
("Fake micro 1", &d1),
|
||||||
("Fake micro 2", &d2),
|
("Fake micro 2", &d2),
|
||||||
("Fake micro 3", &d3),
|
("Fake micro 3", &d3),
|
||||||
],
|
],
|
||||||
(now - one_day * 100).into(),
|
long_ago.into(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
store.update_microdescs_listed(&[d2], now.into())?;
|
store.update_microdescs_listed(&[d2], now.into())?;
|
||||||
|
@ -1213,9 +1217,9 @@ mod test {
|
||||||
fn routerdescs() -> Result<()> {
|
fn routerdescs() -> Result<()> {
|
||||||
let (_tmp_dir, mut store) = new_empty()?;
|
let (_tmp_dir, mut store) = new_empty()?;
|
||||||
|
|
||||||
let now = Utc::now();
|
let now = OffsetDateTime::now_utc();
|
||||||
let one_day = CDuration::days(1);
|
let one_day = 1.days();
|
||||||
let long_ago = now - one_day * 100;
|
let long_ago: OffsetDateTime = now - one_day * 100;
|
||||||
let recently = now - one_day;
|
let recently = now - one_day;
|
||||||
|
|
||||||
let d1 = [5_u8; 20];
|
let d1 = [5_u8; 20];
|
||||||
|
|
Loading…
Reference in New Issue