summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJustus Winter <justus@pep-project.org>2017-12-13 16:17:36 +0100
committerJustus Winter <justus@pep-project.org>2017-12-14 12:12:16 +0100
commit2aeb3b157638423d14976cbeaa4727769761067e (patch)
tree7304b7d5f05d7ce96fe6a3ecd4991cb00adda9b9 /core
parent49160feb334029b0e8c1406de0b49f938447420e (diff)
Add network policy.
- The network policy determines how Sequoia connects to remote servers. - Add a policy field in the context. - Add an error indicating a policy violation. - Honor the policy in the net module. - Add ffi glue.
Diffstat (limited to 'core')
-rw-r--r--core/src/lib.rs114
1 files changed, 114 insertions, 0 deletions
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 12085a11..1ac45c33 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -30,6 +30,7 @@ pub struct Context {
domain: String,
home: PathBuf,
lib: PathBuf,
+ network_policy: NetworkPolicy,
}
/// Returns $PREXIX, or a reasonable default prefix.
@@ -63,6 +64,7 @@ impl Context {
home: env::home_dir().unwrap_or(env::temp_dir())
.join(".sequoia"),
lib: prefix().join("lib").join("sequoia"),
+ network_policy: NetworkPolicy::Encrypted,
})
}
@@ -80,6 +82,12 @@ impl Context {
pub fn lib(&self) -> &Path {
&self.lib
}
+
+ /// Returns the network policy.
+ pub fn network_policy(&self) -> &NetworkPolicy {
+ &self.network_policy
+ }
+
}
/// Represents a `Context` configuration.
@@ -124,6 +132,17 @@ impl Config {
pub fn set_lib<P: AsRef<Path>>(&mut self, lib: P) {
self.0.lib = PathBuf::new().join(lib);
}
+
+ /// Sets the network policy.
+ pub fn network_policy(mut self, policy: NetworkPolicy) -> Self {
+ self.set_network_policy(policy);
+ self
+ }
+
+ /// Sets the network policy.
+ pub fn set_network_policy(&mut self, policy: NetworkPolicy) {
+ self.0.network_policy = policy;
+ }
}
/* Error handling. */
@@ -134,6 +153,8 @@ pub type Result<T> = ::std::result::Result<T, Error>;
/// Errors for Sequoia.
#[derive(Debug)]
pub enum Error {
+ /// The network policy was violated by the given action.
+ NetworkPolicyViolation(NetworkPolicy),
/// An `io::Error` occured.
IoError(io::Error),
}
@@ -143,3 +164,96 @@ impl From<io::Error> for Error {
Error::IoError(error)
}
}
+
+/* Network policy. */
+
+/// Network policy for Sequoia.
+///
+/// With this policy you can control how Sequoia accesses remote
+/// systems.
+#[derive(PartialEq, PartialOrd, Debug, Copy, Clone)]
+pub enum NetworkPolicy {
+ /// Do not contact remote systems.
+ Offline,
+
+ /// Only contact remote systems using anonymization techniques
+ /// like TOR.
+ Anonymized,
+
+ /// Only contact remote systems using transports offering
+ /// encryption and authentication like TLS.
+ Encrypted,
+
+ /// Contact remote systems even with insecure transports.
+ Insecure,
+}
+
+impl NetworkPolicy {
+ pub fn assert(&self, action: NetworkPolicy) -> Result<()> {
+ if action > *self {
+ Err(Error::NetworkPolicyViolation(action))
+ } else {
+ Ok(())
+ }
+ }
+}
+
+#[cfg(test)]
+mod network_policy_test {
+ use super::{Error, NetworkPolicy};
+
+ macro_rules! assert_match {
+ ( $result:expr, $error: pat ) => {
+ if let $error = $result {
+ /* Pass. */
+ } else {
+ panic!("Expected {}, got {:?}.", stringify!($error), $result);
+ }
+ };
+ }
+
+
+ #[test]
+ fn offline() {
+ let p = NetworkPolicy::Offline;
+ assert_match!(p.assert(NetworkPolicy::Anonymized),
+ Err(Error::NetworkPolicyViolation(_)));
+ assert_match!(p.assert(NetworkPolicy::Encrypted),
+ Err(Error::NetworkPolicyViolation(_)));
+ assert_match!(p.assert(NetworkPolicy::Insecure),
+ Err(Error::NetworkPolicyViolation(_)));
+ }
+
+ #[test]
+ fn anonymized() {
+ let p = NetworkPolicy::Anonymized;
+ assert_match!(p.assert(NetworkPolicy::Anonymized),
+ Ok(()));
+ assert_match!(p.assert(NetworkPolicy::Encrypted),
+ Err(Error::NetworkPolicyViolation(_)));
+ assert_match!(p.assert(NetworkPolicy::Insecure),
+ Err(Error::NetworkPolicyViolation(_)));
+ }
+
+ #[test]
+ fn encrypted() {
+ let p = NetworkPolicy::Encrypted;
+ assert_match!(p.assert(NetworkPolicy::Anonymized),
+ Ok(()));
+ assert_match!(p.assert(NetworkPolicy::Encrypted),
+ Ok(()));
+ assert_match!(p.assert(NetworkPolicy::Insecure),
+ Err(Error::NetworkPolicyViolation(_)));
+ }
+
+ #[test]
+ fn insecure() {
+ let p = NetworkPolicy::Insecure;
+ assert_match!(p.assert(NetworkPolicy::Anonymized),
+ Ok(()));
+ assert_match!(p.assert(NetworkPolicy::Encrypted),
+ Ok(()));
+ assert_match!(p.assert(NetworkPolicy::Insecure),
+ Ok(()));
+ }
+}