From a25ef6974e0ba3989f6205c19a1f9ccfc81db584 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Wed, 15 May 2019 16:28:11 +0200 Subject: core, store, tool: Use realm instead of domain. - Remove the domain parameter from core::Context. - Replace it with a realm to be passed in when opening a store. - For sq, merge store name and realm into the --store parameter. - Fixes #105. --- core/src/lib.rs | 33 ++---- examples/guide-the-keystore.rs | 5 +- ffi/examples/configure.c | 2 +- ffi/examples/keyserver.c | 2 +- ffi/include/sequoia/core.h | 19 +--- ffi/include/sequoia/store.h | 26 +++-- ffi/lang/python/Makefile | 2 +- ffi/lang/python/examples/decrypt.py | 3 +- ffi/lang/python/sequoia/core.py | 4 +- ffi/lang/python/sequoia/glue.py | 4 + ffi/lang/python/sequoia/store.py | 12 +- ffi/lang/python/tests/test_armor.py | 3 +- ffi/lang/python/tests/test_packet_parser.py | 3 +- ffi/lang/python/tests/test_store.py | 16 +-- ffi/lang/python/tests/test_tpk.py | 24 ++-- ffi/src/core.rs | 32 +----- ffi/src/net.rs | 2 +- ffi/src/store.rs | 22 ++-- ipc/src/lib.rs | 2 +- net/src/lib.rs | 6 +- net/tests/hkp.rs | 4 +- store/src/backend/mod.rs | 30 ++--- store/src/lib.rs | 167 +++++++++++++++------------- store/src/store_protocol.capnp | 6 +- store/tests/ipc-policy.rs | 18 +-- tool/src/sq.rs | 39 ++++--- tool/src/sq_cli.rs | 11 +- 27 files changed, 235 insertions(+), 262 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index a3b6010e..540ae34a 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -13,7 +13,7 @@ /// # use sequoia_core::{Context, Result}; /// # f().unwrap(); /// # fn f() -> Result<()> { -/// let c = Context::new("org.example.webmail")?; +/// let c = Context::new(); /// # Ok(()) /// # } /// ``` @@ -39,7 +39,7 @@ use tempdir::TempDir; /// # use sequoia_core::{Context, Result}; /// # f().unwrap(); /// # fn f() -> Result<()> { -/// let c = Context::new("org.example.webmail")?; +/// let c = Context::new()?; /// # Ok(()) /// # } /// ``` @@ -51,7 +51,7 @@ use tempdir::TempDir; /// # use sequoia_core::{Context, NetworkPolicy, Result}; /// # f().unwrap(); /// # fn f() -> Result<()> { -/// let c = Context::configure("org.example.webmail") +/// let c = Context::configure() /// # .ephemeral() /// .network_policy(NetworkPolicy::Offline) /// .build()?; @@ -59,7 +59,6 @@ use tempdir::TempDir; /// # } /// ``` pub struct Context { - domain: String, home: PathBuf, lib: PathBuf, network_policy: NetworkPolicy, @@ -71,7 +70,6 @@ pub struct Context { impl Clone for Context { fn clone(&self) -> Self { Context { - domain: self.domain.clone(), home: self.home.clone(), lib: self.lib.clone(), network_policy: self.network_policy, @@ -100,26 +98,17 @@ fn prefix() -> PathBuf { impl Context { /// Creates a Context with reasonable defaults. - /// - /// `domain` should uniquely identify your application, it is - /// strongly suggested to use a reversed fully qualified domain - /// name that is associated with your application. - pub fn new(domain: &str) -> Result { - Self::configure(domain).build() + pub fn new() -> Result { + Self::configure().build() } /// Creates a Context that can be configured. /// - /// `domain` should uniquely identify your application, it is - /// strongly suggested to use a reversed fully qualified domain - /// name that is associated with your application. - /// /// The configuration is seeded like in `Context::new`, but can be /// modified. A configuration has to be finalized using /// `.build()` in order to turn it into a Context. - pub fn configure(domain: &str) -> Config { + pub fn configure() -> Config { Config(Context { - domain: String::from(domain), home: PathBuf::from(""), // Defer computation of default. lib: prefix().join("lib").join("sequoia"), network_policy: NetworkPolicy::Encrypted, @@ -129,11 +118,6 @@ impl Context { }) } - /// Returns the domain of the context. - pub fn domain(&self) -> &str { - &self.domain - } - /// Returns the directory containing shared state. pub fn home(&self) -> &Path { &self.home @@ -169,7 +153,7 @@ impl Context { /// # use sequoia_core::{Context, NetworkPolicy, Result}; /// # f().unwrap(); /// # fn f() -> Result<()> { -/// let c = Context::configure("org.example.webmail") +/// let c = Context::configure() /// # .ephemeral() /// .network_policy(NetworkPolicy::Offline) /// .build()?; @@ -185,8 +169,7 @@ impl Context { /// # use std::path::Path; /// # f().unwrap(); /// # fn f() -> Result<()> { -/// let c = Context::configure("org.example.my.test") -/// .ephemeral().build()?; +/// let c = Context::configure().ephemeral().build()?; /// let ephemeral_home = c.home().to_path_buf(); /// // Do some tests. /// drop(c); diff --git a/examples/guide-the-keystore.rs b/examples/guide-the-keystore.rs index b4c5b15b..4748ad6b 100644 --- a/examples/guide-the-keystore.rs +++ b/examples/guide-the-keystore.rs @@ -39,13 +39,14 @@ fn main() { -----END PGP PUBLIC KEY BLOCK-----"; // Provide some context. - let ctx = core::Context::new("org.sequoia-pgp.guide").unwrap(); + let ctx = core::Context::new().unwrap(); // Parse TPK. let tpk = openpgp::TPK::from_bytes(tpk).unwrap(); // Open a store. - let store = store::Store::open(&ctx, "default").unwrap(); + let store = + store::Store::open(&ctx, store::REALM_CONTACTS, "default").unwrap(); // Store the TPK. store.import("Ἀριστοτέλης", &tpk).unwrap(); diff --git a/ffi/examples/configure.c b/ffi/examples/configure.c index 23e243ac..37401047 100644 --- a/ffi/examples/configure.c +++ b/ffi/examples/configure.c @@ -24,7 +24,7 @@ main (int argc, char **argv) sq_context_t ctx; sq_keyserver_t ks; - cfg = sq_context_configure ("org.sequoia-pgp.example"); + cfg = sq_context_configure (); sq_config_network_policy (cfg, SQ_NETWORK_POLICY_OFFLINE); ctx = sq_config_build (cfg, &err); if (ctx == NULL) diff --git a/ffi/examples/keyserver.c b/ffi/examples/keyserver.c index 1e6ca135..3a0acae7 100644 --- a/ffi/examples/keyserver.c +++ b/ffi/examples/keyserver.c @@ -24,7 +24,7 @@ main (int argc, char **argv) sq_keyserver_t ks; pgp_tpk_t tpk; - ctx = sq_context_new ("org.sequoia-pgp.example", &err); + ctx = sq_context_new (&err); if (ctx == NULL) error (1, 0, "Initializing sequoia failed: %s", pgp_error_to_string (err)); diff --git a/ffi/include/sequoia/core.h b/ffi/include/sequoia/core.h index d34f8985..c7f73f45 100644 --- a/ffi/include/sequoia/core.h +++ b/ffi/include/sequoia/core.h @@ -14,7 +14,7 @@ /// # Example /// /// ```c -/// struct sq_context *ctx sq_context_new("org.sequoia-pgp.example"); +/// struct sq_context *ctx sq_context_new(); /// if (ctx == NULL) { ... } /// ``` /*/ @@ -125,14 +125,10 @@ typedef enum sq_ipc_policy { /*/ /// Creates a Context with reasonable defaults. /// -/// `domain` should uniquely identify your application, it is strongly -/// suggested to use a reversed fully qualified domain name that is -/// associated with your application. `domain` must not be `NULL`. -/// /// Returns `NULL` on errors. If `errp` is not `NULL`, the error is /// stored there. /*/ -sq_context_t sq_context_new(const char *domain, pgp_error_t *errp); +sq_context_t sq_context_new(pgp_error_t *errp); /*/ /// Frees a context. @@ -142,20 +138,11 @@ void sq_context_free(sq_context_t context); /*/ /// Creates a Context that can be configured. /// -/// `domain` should uniquely identify your application, it is strongly -/// suggested to use a reversed fully qualified domain name that is -/// associated with your application. `domain` must not be `NULL`. -/// /// The configuration is seeded like in `sq_context_new`, but can be /// modified. A configuration has to be finalized using /// `sq_config_build()` in order to turn it into a Context. /*/ -sq_config_t sq_context_configure(const char *domain); - -/*/ -/// Returns the domain of the context. -/*/ -const char *sq_context_domain(const sq_context_t ctx); +sq_config_t sq_context_configure(void); /*/ /// Returns the directory containing shared state. diff --git a/ffi/include/sequoia/store.h b/ffi/include/sequoia/store.h index 343e52ab..47b581b1 100644 --- a/ffi/include/sequoia/store.h +++ b/ffi/include/sequoia/store.h @@ -3,6 +3,16 @@ #include +/*/ +/// Keys used for communications. +/*/ +const char *SQ_REALM_CONTACTS = "org.sequoia-pgp.contacts"; + +/*/ +/// Keys used for signing software updates. +/*/ +const char *SQ_REALM_SOFTWARE_UPDATES = "org.sequoia-pgp.software-updates"; + /*/ /// A public key store. /*/ @@ -156,13 +166,13 @@ typedef struct sq_store_iter *sq_store_iter_t; /*/ /// Returns the next store. /// -/// Returns `NULL` on exhaustion. If `domainp` is not `NULL`, the -/// stores domain is stored there. If `namep` is not `NULL`, the +/// Returns `NULL` on exhaustion. If `realmp` is not `NULL`, the +/// stores realm is stored there. If `namep` is not `NULL`, the /// stores name is stored there. If `policyp` is not `NULL`, the /// stores network policy is stored there. /*/ sq_store_t sq_store_iter_next (sq_store_iter_t iter, - char **domainp, + char **realmp, char **namep, uint8_t *policyp); @@ -242,17 +252,17 @@ sq_key_iter_t sq_store_list_keys (sq_context_t ctx); /*/ /// Opens a store. /// -/// Opens a store with the given name. If the store does not -/// exist, it is created. Stores are handles for objects -/// maintained by a background service. The background service -/// associates state with this name. +/// Opens a store with the given name in the given realm. If the +/// store does not exist, it is created. Stores are handles for +/// objects maintained by a background service. The background +/// service associates state with this name. /// /// The store updates TPKs in compliance with the network policy /// of the context that created the store in the first place. /// Opening the store with a different network policy is /// forbidden. /*/ -sq_store_t sq_store_open (sq_context_t ctx, const char *name); +sq_store_t sq_store_open (sq_context_t ctx, const char *realm, const char *name); /*/ /// Adds a key identified by fingerprint to the store. diff --git a/ffi/lang/python/Makefile b/ffi/lang/python/Makefile index f398c0c2..429a133e 100644 --- a/ffi/lang/python/Makefile +++ b/ffi/lang/python/Makefile @@ -50,7 +50,7 @@ ifneq "$(PYTHON)" "disable" cp build/*/_sequoia.abi*.so . # XXX can we get setuptools to do that? LDFLAGS=-L$(CARGO_TARGET_DIR)/debug LD_LIBRARY_PATH=$(CARGO_TARGET_DIR)/debug \ $(IPYTHON) -i -c \ -'from sequoia.prelude import *; ctx = Context("org.sequoia-pgp.tests.interactive")' +'from sequoia.prelude import *; ctx = Context()' endif # Installation. diff --git a/ffi/lang/python/examples/decrypt.py b/ffi/lang/python/examples/decrypt.py index c65f151d..1f4109e1 100644 --- a/ffi/lang/python/examples/decrypt.py +++ b/ffi/lang/python/examples/decrypt.py @@ -5,8 +5,7 @@ from enum import Enum, auto from sequoia.core import Context, NetworkPolicy from sequoia.openpgp import Tag, PacketParser -ctx = Context("org.sequoia-pgp.examples", - network_policy=NetworkPolicy.Offline, +ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) class State(Enum): diff --git a/ffi/lang/python/sequoia/core.py b/ffi/lang/python/sequoia/core.py index a7e12808..b985247b 100644 --- a/ffi/lang/python/sequoia/core.py +++ b/ffi/lang/python/sequoia/core.py @@ -18,12 +18,12 @@ class IPCPolicy(Enum): class Context(SQObject): _del = lib.sq_context_free - def __init__(self, domain, + def __init__(self, home=None, network_policy=NetworkPolicy.Encrypted, ipc_policy=IPCPolicy.Robust, ephemeral=False): - cfg = lib.sq_context_configure(domain.encode()) + cfg = lib.sq_context_configure() if home: lib.sq_config_home(cfg, home.encode()) lib.sq_config_network_policy(cfg, network_policy.value) diff --git a/ffi/lang/python/sequoia/glue.py b/ffi/lang/python/sequoia/glue.py index ea40d20c..cca3a71d 100644 --- a/ffi/lang/python/sequoia/glue.py +++ b/ffi/lang/python/sequoia/glue.py @@ -109,6 +109,10 @@ def sq_str(s): return t _str = sq_str +def sq_static_str(s): + return ffi.string(s).decode() +_static_str = sq_static_str + def sq_iterator(iterator, next_fn, map=lambda x: x): while True: entry = next_fn(iterator) diff --git a/ffi/lang/python/sequoia/store.py b/ffi/lang/python/sequoia/store.py index 4a7a41a9..c9ce84e8 100644 --- a/ffi/lang/python/sequoia/store.py +++ b/ffi/lang/python/sequoia/store.py @@ -1,12 +1,18 @@ from _sequoia import ffi, lib from .error import Error -from .glue import _str, SQObject, sq_iterator, sq_time +from .glue import _str, _static_str, SQObject, sq_iterator, sq_time from .openpgp import Fingerprint, TPK class Store(SQObject): _del = lib.sq_store_free + # Keys used for communications. + REALM_CONTACTS = _static_str(lib.SQ_REALM_CONTACTS) + + # Keys used for signing software updates. + REALM_SOFTWARE_UPDATES = _static_str(lib.SQ_REALM_SOFTWARE_UPDATES) + @classmethod def server_log(cls, ctx): yield from sq_iterator( @@ -34,8 +40,8 @@ class Store(SQObject): next_fn) @classmethod - def open(cls, ctx, name): - return Store(lib.sq_store_open(ctx.ref(), name.encode()), context=ctx) + def open(cls, ctx, realm=REALM_CONTACTS, name="default"): + return Store(lib.sq_store_open(ctx.ref(), realm.encode(), name.encode()), context=ctx) def add(self, label, fingerprint): diff --git a/ffi/lang/python/tests/test_armor.py b/ffi/lang/python/tests/test_armor.py index e439f612..93486703 100644 --- a/ffi/lang/python/tests/test_armor.py +++ b/ffi/lang/python/tests/test_armor.py @@ -7,8 +7,7 @@ from sequoia.openpgp import ArmorReader, ArmorWriter, Kind TEST_VECTORS = [0, 1, 2, 3, 47, 48, 49, 50, 51] -ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, +ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) def fn_bin(t): diff --git a/ffi/lang/python/tests/test_packet_parser.py b/ffi/lang/python/tests/test_packet_parser.py index de126bc3..e50a58f5 100644 --- a/ffi/lang/python/tests/test_packet_parser.py +++ b/ffi/lang/python/tests/test_packet_parser.py @@ -6,8 +6,7 @@ pgp = "../../../openpgp/tests/data/messages/encrypted-aes128-password-123456789. plain = "../../../openpgp/tests/data/messages/a-cypherpunks-manifesto.txt" def test_decryption(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) class State(Enum): diff --git a/ffi/lang/python/tests/test_store.py b/ffi/lang/python/tests/test_store.py index 0c86a689..454afb7d 100644 --- a/ffi/lang/python/tests/test_store.py +++ b/ffi/lang/python/tests/test_store.py @@ -1,18 +1,18 @@ from sequoia.prelude import Context, Store, Fingerprint def test_open(): - c = Context("org.sequoia-pgp.tests", ephemeral=True) - Store.open(c, "default") + c = Context(ephemeral=True) + Store.open(c) def test_add(): - c = Context("org.sequoia-pgp.tests", ephemeral=True) - s = Store.open(c, "default") + c = Context(ephemeral=True) + s = Store.open(c) fp = Fingerprint.from_hex("7DCA58B54EB143169DDEE15F247F6DABC84914FE") s.add("Ἀριστοτέλης", fp) def test_iterate(): - c = Context("org.sequoia-pgp.tests", ephemeral=True) - s = Store.open(c, "default") + c = Context(ephemeral=True) + s = Store.open(c) fp = Fingerprint.from_hex("7DCA58B54EB143169DDEE15F247F6DABC84914FE") s.add("Ἀριστοτέλης", fp) l = list(s.iter()) @@ -23,8 +23,8 @@ def test_iterate(): assert fpi == fp def test_logs(): - c = Context("org.sequoia-pgp.tests", ephemeral=True) - s = Store.open(c, "default") + c = Context(ephemeral=True) + s = Store.open(c) fp = Fingerprint.from_hex("7DCA58B54EB143169DDEE15F247F6DABC84914FE") b = s.add("Ἀριστοτέλης", fp) l = list(s.iter()) diff --git a/ffi/lang/python/tests/test_tpk.py b/ffi/lang/python/tests/test_tpk.py index c630798f..5e06bd93 100644 --- a/ffi/lang/python/tests/test_tpk.py +++ b/ffi/lang/python/tests/test_tpk.py @@ -9,16 +9,14 @@ asc = "../../../openpgp/tests/data/keys/testy.asc" fp = Fingerprint.from_hex("3E8877C877274692975189F5D03F6F865226FE8B") def test_from_reader(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) r = Reader.open(ctx, pgp) t = TPK.from_reader(ctx, r) assert t.fingerprint() == fp def test_from_armor_reader(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) k = open(asc, "rb").read() r = Reader.from_bytes(ctx, k) @@ -27,30 +25,26 @@ def test_from_armor_reader(): assert t.fingerprint() == fp def test_from_file(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) t = TPK.open(ctx, pgp) assert t.fingerprint() == fp def test_from_packet_pile(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) r = PacketPile.open(ctx, pgp) t = TPK.from_packet_pile(ctx, r) assert t.fingerprint() == fp def test_from_bytes(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) t = TPK.from_bytes(ctx, open(pgp, "rb").read()) assert t.fingerprint() == fp def test_from_serialize(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) with TemporaryDirectory() as tmp: sink = join(tmp, "a") @@ -63,8 +57,7 @@ def test_from_serialize(): assert t.fingerprint() == fp def test_equals(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) b = open(pgp, "rb").read() t = TPK.from_bytes(ctx, b) @@ -72,8 +65,7 @@ def test_equals(): assert t == u def test_clone(): - ctx = Context("org.sequoia-pgp.tests", - network_policy=NetworkPolicy.Offline, + ctx = Context(network_policy=NetworkPolicy.Offline, ephemeral=True) a = TPK.open(ctx, pgp) b = a.copy() diff --git a/ffi/src/core.rs b/ffi/src/core.rs index 5b139fb4..830391d6 100644 --- a/ffi/src/core.rs +++ b/ffi/src/core.rs @@ -13,7 +13,7 @@ //! #include //! //! sq_context_t ctx; -//! ctx = sq_context_new ("org.sequoia-pgp.example", NULL); +//! ctx = sq_context_new (NULL); //! //! /* Use Sequoia. */ //! @@ -29,7 +29,7 @@ //! sq_config_t cfg; //! sq_context_t ctx; //! -//! cfg = sq_context_configure ("org.sequoia-pgp.example"); +//! cfg = sq_context_configure (); //! sq_config_network_policy (cfg, SQ_NETWORK_POLICY_OFFLINE); //! ctx = sq_config_build (cfg, NULL); //! @@ -72,20 +72,13 @@ fn sq_context_last_error(ctx: *mut Context) -> *mut ::error::Error { /// Creates a Context with reasonable defaults. /// -/// `domain` should uniquely identify your application, it is strongly -/// suggested to use a reversed fully qualified domain name that is -/// associated with your application. `domain` must not be `NULL`. -/// /// Returns `NULL` on errors. If `errp` is not `NULL`, the error is /// stored there. #[::ffi_catch_abort] #[no_mangle] pub extern "C" -fn sq_context_new(domain: *const c_char, - errp: Option<&mut *mut ::error::Error>) +fn sq_context_new(errp: Option<&mut *mut ::error::Error>) -> *mut Context { ffi_make_fry_from_errp!(errp); - let domain = ffi_param_cstr!(domain).to_string_lossy(); - - ffi_try_box!(core::Context::new(&domain).map(|ctx| Context::new(ctx))) + ffi_try_box!(core::Context::new().map(|ctx| Context::new(ctx))) } /// Frees a context. @@ -96,25 +89,12 @@ fn sq_context_free(context: Option<&mut Context>) { /// Creates a Context that can be configured. /// -/// `domain` should uniquely identify your application, it is strongly -/// suggested to use a reversed fully qualified domain name that is -/// associated with your application. `domain` must not be `NULL`. -/// /// The configuration is seeded like in `sq_context_new`, but can be /// modified. A configuration has to be finalized using /// `sq_config_build()` in order to turn it into a Context. #[::ffi_catch_abort] #[no_mangle] pub extern "C" -fn sq_context_configure(domain: *const c_char) -> *mut Config { - let domain = ffi_param_cstr!(domain).to_string_lossy(); - - Box::into_raw(Box::new(core::Context::configure(&domain))) -} - -/// Returns the domain of the context. -#[::ffi_catch_abort] #[no_mangle] pub extern "C" -fn sq_context_domain(ctx: *const Context) -> *const c_char { - let ctx = ffi_param_ref!(ctx); - ctx.c.domain().as_bytes().as_ptr() as *const c_char +fn sq_context_configure() -> *mut Config { + Box::into_raw(Box::new(core::Context::configure())) } /// Returns the directory containing shared state. diff --git a/ffi/src/net.rs b/ffi/src/net.rs index 06942739..93ea61cc 100644 --- a/ffi/src/net.rs +++ b/ffi/src/net.rs @@ -21,7 +21,7 @@ //! sq_keyserver_t ks; //! pgp_tpk_t tpk; //! -//! ctx = sq_context_new ("org.sequoia-pgp.example", NULL); +//! ctx = sq_context_new (NULL); //! ks = sq_keyserver_sks_pool (ctx); //! id = pgp_keyid_from_bytes ((uint8_t *) "\x24\x7F\x6D\xAB\xC8\x49\x14\xFE"); //! tpk = sq_keyserver_get (ctx, ks, id); diff --git a/ffi/src/store.rs b/ffi/src/store.rs index 2a2c18cf..3aef93a7 100644 --- a/ffi/src/store.rs +++ b/ffi/src/store.rs @@ -46,32 +46,32 @@ use Maybe; /// Lists all stores with the given prefix. #[::ffi_catch_abort] #[no_mangle] pub extern "C" fn sq_store_list_stores(ctx: *mut Context, - domain_prefix: *const c_char) + realm_prefix: *const c_char) -> *mut StoreIter { let ctx = ffi_param_ref_mut!(ctx); ffi_make_fry_from_ctx!(ctx); - let domain_prefix = ffi_param_cstr!(domain_prefix).to_string_lossy(); + let realm_prefix = ffi_param_cstr!(realm_prefix).to_string_lossy(); - ffi_try_box!(Store::list(&ctx.c, &domain_prefix)) + ffi_try_box!(Store::list(&ctx.c, &realm_prefix)) } /// Returns the next store. /// -/// Returns `NULL` on exhaustion. If `domainp` is not `NULL`, the -/// stores domain is stored there. If `namep` is not `NULL`, the +/// Returns `NULL` on exhaustion. If `realmp` is not `NULL`, the +/// stores realm is stored there. If `namep` is not `NULL`, the /// stores name is stored there. If `policyp` is not `NULL`, the /// stores network policy is stored there. #[::ffi_catch_abort] #[no_mangle] pub extern "C" fn sq_store_iter_next(iter: *mut StoreIter, - domainp: Option<&mut *mut c_char>, + realmp: Option<&mut *mut c_char>, namep: Option<&mut *mut c_char>, policyp: Option<&mut uint8_t>) -> *mut Store { let iter = ffi_param_ref_mut!(iter); match iter.next() { - Some((domain, name, policy, store)) => { - if domainp.is_some() { - *domainp.unwrap() = ffi_return_maybe_string!(domain); + Some((realm, name, policy, store)) => { + if realmp.is_some() { + *realmp.unwrap() = ffi_return_maybe_string!(realm); } if namep.is_some() { @@ -191,13 +191,15 @@ fn sq_log_iter_free(iter: Option<&mut LogIter>) { /// forbidden. #[::ffi_catch_abort] #[no_mangle] pub extern "C" fn sq_store_open(ctx: *mut Context, + realm: *const c_char, name: *const c_char) -> *mut Store { let ctx = ffi_param_ref_mut!(ctx); ffi_make_fry_from_ctx!(ctx); + let realm = ffi_param_cstr!(realm).to_string_lossy(); let name = ffi_param_cstr!(name).to_string_lossy(); - ffi_try_box!(Store::open(&ctx.c, &name)) + ffi_try_box!(Store::open(&ctx.c, &realm, &name)) } /// Frees a sq_store_t. diff --git a/ipc/src/lib.rs b/ipc/src/lib.rs index a9a89b82..74a6fb29 100644 --- a/ipc/src/lib.rs +++ b/ipc/src/lib.rs @@ -311,7 +311,7 @@ impl Server { --ephemeral true|false", args[0])); } - let mut cfg = core::Context::configure("org.sequoia.api.server") + let mut cfg = core::Context::configure() .home(&args[2]).lib(&args[4]); if let Ok(ephemeral) = args[6].parse() { diff --git a/net/src/lib.rs b/net/src/lib.rs index db52333d..c9f7cd0a 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -22,7 +22,7 @@ //! # use sequoia_net::{KeyServer, Result}; //! # fn main() { f().unwrap(); } //! # fn f() -> Result<()> { -//! let ctx = Context::new("org.sequoia-pgp.example")?; +//! let ctx = Context::new()?; //! let mut ks = KeyServer::sks_pool(&ctx)?; //! let keyid = KeyID::from_hex("31855247603831FD").unwrap(); //! println!("{:?}", ks.get(&keyid)); @@ -195,7 +195,7 @@ mod tests { #[test] fn uris() { - let ctx = Context::configure("foo") + let ctx = Context::configure() .network_policy(sequoia_core::NetworkPolicy::Insecure) .build().unwrap(); @@ -203,7 +203,7 @@ mod tests { assert!(KeyServer::new(&ctx, "hkp://keys.openpgp.org").is_ok()); assert!(KeyServer::new(&ctx, "hkps://keys.openpgp.org").is_ok()); - let ctx = Context::configure("foo") + let ctx = Context::configure() .network_policy(sequoia_core::NetworkPolicy::Encrypted) .build().unwrap(); diff --git a/net/tests/hkp.rs b/net/tests/hkp.rs index bbdf8f43..0faf40a5 100644 --- a/net/tests/hkp.rs +++ b/net/tests/hkp.rs @@ -142,7 +142,7 @@ fn start_server() -> SocketAddr { #[test] fn get() { - let ctx = Context::configure("org.sequoia-pgp.api.tests") + let ctx = Context::configure() .ephemeral() .network_policy(NetworkPolicy::Insecure) .build().unwrap(); @@ -161,7 +161,7 @@ fn get() { #[test] fn send() { - let ctx = Context::configure("org.sequoia-pgp.api.tests") + let ctx = Context::configure() .ephemeral() .network_policy(NetworkPolicy::Insecure) .build().unwrap(); diff --git a/store/src/backend/mod.rs b/store/src/backend/mod.rs index 0cb8d2cb..6891babe 100644 --- a/store/src/backend/mod.rs +++ b/store/src/backend/mod.rs @@ -146,7 +146,7 @@ impl node::Server for NodeServer { // XXX maybe check ephemeral and use in-core sqlite db let store = sry!(StoreServer::open(self.c.clone(), - pry!(params.get_domain()), + pry!(params.get_realm()), pry!(params.get_network_policy()).into(), pry!(params.get_name()))); pry!(pry!(results.get().get_result()).set_ok( @@ -159,7 +159,7 @@ impl node::Server for NodeServer { mut results: node::IterResults) -> Promise<(), capnp::Error> { bind_results!(results); - let prefix = pry!(pry!(params.get()).get_domain_prefix()); + let prefix = pry!(pry!(params.get()).get_realm_prefix()); let iter = StoreIterServer::new(self.c.clone(), prefix); pry!(pry!(results.get().get_result()).set_ok( node::store_iter::ToClient::new(iter).into_client::())); @@ -277,7 +277,7 @@ impl Query for StoreServer { fn slug(&self) -> String { self.c.query_row( - "SELECT domain, name FROM stores WHERE id = ?1", + "SELECT realm, name FROM stores WHERE id = ?1", &[&self.id], |row| -> String { format!("{}:{}", row.get::<_, String>(0), row.get::<_, String>(1)) }) @@ -292,18 +292,18 @@ impl StoreServer { StoreServer{c: c, id: id} } - fn open(c: Rc, domain: &str, policy: core::NetworkPolicy, name: &str) + fn open(c: Rc, realm: &str, policy: core::NetworkPolicy, name: &str) -> Result { // We cannot implement ToSql and friends for // core::NetworkPolicy, hence we need to do it by foot. let p: u8 = (&policy).into(); c.execute( - "INSERT OR IGNORE INTO stores (domain, network_policy, name) VALUES (?1, ?2, ?3)", - &[&domain, &p, &name])?; + "INSERT OR IGNORE INTO stores (realm, network_policy, name) VALUES (?1, ?2, ?3)", + &[&realm, &p, &name])?; let (id, store_policy): (ID, i64) = c.query_row( - "SELECT id, network_policy FROM stores WHERE domain = ?1 AND name = ?2", - &[&domain, &name], |row| (row.get(0), row.get(1)))?; + "SELECT id, network_policy FROM stores WHERE realm = ?1 AND name = ?2", + &[&realm, &name], |row| (row.get(0), row.get(1)))?; // We cannot implement FromSql and friends for // core::NetworkPolicy, hence we need to do it by foot. @@ -894,7 +894,7 @@ impl KeyServer { let fingerprint = openpgp::Fingerprint::from_hex(&fingerprint) .map_err(|_| node::Error::SystemError)?; - let ctx = core::Context::configure("org.sequoia-pgp.store") + let ctx = core::Context::configure() .network_policy(network_policy).build()?; let keyserver = net::async::KeyServer::sks_pool(&ctx, handle)?; @@ -1129,10 +1129,10 @@ impl node::store_iter::Server for StoreIterServer { mut results: node::store_iter::NextResults) -> Promise<(), capnp::Error> { bind_results!(results); - let (id, domain, name, network_policy): (ID, String, String, i64) = + let (id, realm, name, network_policy): (ID, String, String, i64) = sry!(self.c.query_row( - "SELECT id, domain, name, network_policy FROM stores - WHERE id > ?1 AND domain like ?2 + "SELECT id, realm, name, network_policy FROM stores + WHERE id > ?1 AND realm like ?2 ORDER BY id LIMIT 1", &[&self.n, &self.prefix], |row| (row.get(0), row.get(1), row.get(2), row.get(3)))); @@ -1145,7 +1145,7 @@ impl node::store_iter::Server for StoreIterServer { let network_policy = core::NetworkPolicy::from(network_policy as u8); let mut entry = pry!(results.get().get_result()).init_ok(); - entry.set_domain(&domain); + entry.set_realm(&realm); entry.set_name(&name); entry.set_network_policy(network_policy.into()); entry.set_store(node::store::ToClient::new( @@ -1359,10 +1359,10 @@ INSERT INTO version (id, version) VALUES (1, 1); CREATE TABLE stores ( id INTEGER PRIMARY KEY, - domain TEXT NOT NULL, + realm TEXT NOT NULL, network_policy INTEGER NOT NULL, name TEXT NOT NULL, - UNIQUE (domain, name)); + UNIQUE (realm, name)); CREATE TABLE bindings ( id INTEGER PRIMARY KEY, diff --git a/store/src/lib.rs b/store/src/lib.rs index 50dca7de..d9063bf7 100644 --- a/store/src/lib.rs +++ b/store/src/lib.rs @@ -24,14 +24,14 @@ //! # extern crate sequoia_store; //! # use openpgp::Fingerprint; //! # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; -//! # use sequoia_store::{Store, Result}; +//! # use sequoia_store::*; //! # fn main() { f().unwrap(); } //! # fn f() -> Result<()> { -//! # let ctx = Context::configure("org.sequoia-pgp.demo.store") +//! # let ctx = Context::configure() //! # .network_policy(NetworkPolicy::Offline) //! # .ipc_policy(IPCPolicy::Internal) //! # .ephemeral().build()?; -//! let store = Store::open(&ctx, "default")?; +//! let store = Store::open(&ctx, REALM_CONTACTS, "default")?; //! //! let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); //! let binding = store.add("Mister B.", &fp)?; @@ -107,6 +107,14 @@ pub fn descriptor(c: &Context) -> ipc::Descriptor { ) } +/// Keys used for communications. +pub const REALM_CONTACTS: &'static str = + "org.sequoia-pgp.contacts"; + +/// Keys used for signing software updates. +pub const REALM_SOFTWARE_UPDATES: &'static str = + "org.sequoia-pgp.software-updates"; + /// The common key pool. pub struct Pool { } @@ -126,7 +134,7 @@ impl Pool { /// # use sequoia_store::{Pool, Result}; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -162,7 +170,7 @@ impl Pool { /// # use sequoia_store::{Pool, Result}; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -197,7 +205,7 @@ impl Pool { /// # use sequoia_store::{Pool, Result}; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -233,7 +241,7 @@ impl Pool { /// # use sequoia_store::{Pool, Result}; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -313,11 +321,11 @@ impl Store { /// of the context that created the store in the first place. /// Opening the store with a different network policy is /// forbidden. - pub fn open(c: &Context, name: &str) -> Result { + pub fn open(c: &Context, realm: &str, name: &str) -> Result { let (mut core, client) = Self::connect(c)?; let mut request = client.open_request(); - request.get().set_domain(c.domain()); + request.get().set_realm(realm); request.get().set_network_policy(c.network_policy().into()); request.get().set_ephemeral(c.ephemeral()); request.get().set_name(name); @@ -331,10 +339,10 @@ impl Store { } /// Lists all stores with the given prefix. - pub fn list(c: &Context, domain_prefix: &str) -> Result { + pub fn list(c: &Context, realm_prefix: &str) -> Result { let (mut core, client) = Self::connect(c)?; let mut request = client.iter_request(); - request.get().set_domain_prefix(domain_prefix); + request.get().set_realm_prefix(realm_prefix); let iter = make_request!(&mut core, request)?; Ok(StoreIter{core: Rc::new(RefCell::new(core)), iter: iter}) } @@ -365,14 +373,14 @@ impl Store { /// # extern crate sequoia_store; /// # use openpgp::Fingerprint; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); /// store.add("Mister B.", &fp)?; /// # Ok(()) @@ -397,16 +405,16 @@ impl Store { /// # use openpgp::TPK; /// # use openpgp::parse::Parse; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; /// # let tpk = TPK::from_bytes( /// # include_bytes!("../../openpgp/tests/data/keys/testy.pgp")).unwrap(); - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// store.import("Testy McTestface", &tpk)?; /// # Ok(()) /// # } @@ -431,19 +439,19 @@ impl Store { /// # extern crate sequoia_store; /// # use openpgp::Fingerprint; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); /// store.add("Mister B.", &fp)?; /// drop(store); /// // ... - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let binding = store.lookup("Mister B.")?; /// # Ok(()) /// # } @@ -468,17 +476,17 @@ impl Store { /// # use openpgp::{TPK, KeyID}; /// # use openpgp::parse::Parse; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; /// # let tpk = TPK::from_bytes( /// # include_bytes!("../../openpgp/tests/data/keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp")) /// # .unwrap(); - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// store.import("Emmelie", &tpk)?; /// /// // Lookup by the primary key's KeyID. @@ -512,19 +520,19 @@ impl Store { /// # extern crate sequoia_store; /// # use openpgp::Fingerprint; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result, Error}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); /// store.add("Mister B.", &fp)?; /// store.delete()?; /// // ... - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let binding = store.lookup("Mister B."); /// assert!(binding.is_err()); // not found /// # Ok(()) @@ -604,14 +612,14 @@ impl Binding { /// # extern crate sequoia_store; /// # use openpgp::Fingerprint; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// /// let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); /// let binding = store.add("Mister B.", &fp)?; @@ -668,10 +676,10 @@ impl Binding { /// # use openpgp::TPK; /// # use openpgp::parse::Parse; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result, Error}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -679,7 +687,7 @@ impl Binding { /// # include_bytes!("../../openpgp/tests/data/keys/testy.pgp")).unwrap(); /// # let new = TPK::from_bytes( /// # include_bytes!("../../openpgp/tests/data/keys/testy-new.pgp")).unwrap(); - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// store.import("Testy McTestface", &old)?; /// // later... /// let binding = store.lookup("Testy McTestface")?; @@ -723,10 +731,10 @@ impl Binding { /// # use openpgp::TPK; /// # use openpgp::parse::Parse; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result, Error}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -734,7 +742,7 @@ impl Binding { /// # include_bytes!("../../openpgp/tests/data/keys/testy.pgp")).unwrap(); /// # let new = TPK::from_bytes( /// # include_bytes!("../../openpgp/tests/data/keys/testy-new.pgp")).unwrap(); - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// store.import("Testy McTestface", &old)?; /// // later... /// let binding = store.lookup("Testy McTestface")?; @@ -767,14 +775,14 @@ impl Binding { /// # extern crate sequoia_store; /// # use openpgp::Fingerprint; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result, Error}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); /// let binding = store.add("Mister B.", &fp)?; /// binding.delete()?; @@ -875,10 +883,10 @@ impl Key { /// # use openpgp::TPK; /// # use openpgp::parse::Parse; /// # use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; - /// # use sequoia_store::{Store, Result, Error}; + /// # use sequoia_store::*; /// # fn main() { f().unwrap(); } /// # fn f() -> Result<()> { - /// # let ctx = Context::configure("org.sequoia-pgp.demo.store") + /// # let ctx = Context::configure() /// # .network_policy(NetworkPolicy::Offline) /// # .ipc_policy(IPCPolicy::Internal) /// # .ephemeral().build()?; @@ -886,7 +894,7 @@ impl Key { /// # include_bytes!("../../openpgp/tests/data/keys/testy.pgp")).unwrap(); /// # let new = TPK::from_bytes( /// # include_bytes!("../../openpgp/tests/data/keys/testy-new.pgp")).unwrap(); - /// let store = Store::open(&ctx, "default")?; + /// let store = Store::open(&ctx, REALM_CONTACTS, "default")?; /// let fp = Fingerprint::from_hex("3E8877C877274692975189F5D03F6F865226FE8B").unwrap(); /// let binding = store.add("Testy McTestface", &fp)?; /// let key = binding.key()?; @@ -1066,7 +1074,7 @@ impl Iterator for StoreIter { self.core.borrow_mut(), request, |r: node::store_iter::item::Reader| Ok(( - r.get_domain()?.into(), + r.get_realm()?.into(), r.get_name()?.into(), r.get_network_policy()?.into(), Store::new(self.core.clone(), r.get_name()?, r.get_store()?)))) @@ -1225,7 +1233,7 @@ impl From for Error { #[cfg(test)] mod test { - use super::{core, Store, Error, TPK, Fingerprint}; + use super::*; use openpgp::parse::Parse; macro_rules! bytes { @@ -1234,32 +1242,32 @@ mod test { #[test] fn store_network_policy_mismatch() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); // Create store. - Store::open(&ctx, "default").unwrap(); + Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); - let ctx2 = core::Context::configure("org.sequoia-pgp.tests") + let ctx2 = core::Context::configure() .home(ctx.home()) .network_policy(core::NetworkPolicy::Encrypted) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx2, "default"); + let store = Store::open(&ctx2, REALM_CONTACTS, "default"); assert_match!(core::Error::NetworkPolicyViolation(_) = store.err().unwrap().downcast::().unwrap()); } #[test] fn import_key() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let tpk = TPK::from_bytes(bytes!("testy.pgp")).unwrap(); store.import("Mr. McTestface", &tpk).unwrap(); let binding = store.lookup("Mr. McTestface").unwrap(); @@ -1269,12 +1277,12 @@ mod test { #[test] fn key_not_found() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let r = store.lookup("I do not exist"); assert_match!(Error::NotFound = r.err().unwrap().downcast::().unwrap()); @@ -1282,12 +1290,12 @@ mod test { #[test] fn add_then_import_wrong_key() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let tpk = TPK::from_bytes(bytes!("testy.pgp")).unwrap(); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); let binding = store.add("Mister B.", &fp).unwrap(); @@ -1298,12 +1306,12 @@ mod test { #[test] fn add_then_add_different_key() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let b = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); store.add("Mister B.", &b).unwrap(); let c = Fingerprint::from_bytes(b"cccccccccccccccccccc"); @@ -1314,26 +1322,26 @@ mod test { #[test] fn delete_store_twice() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let s0 = Store::open(&ctx, "default").unwrap(); - let s1 = Store::open(&ctx, "default").unwrap(); + let s0 = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); + let s1 = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); s0.delete().unwrap(); s1.delete().unwrap(); } #[test] fn delete_store_then_use() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let s0 = Store::open(&ctx, "default").unwrap(); - let s1 = Store::open(&ctx, "default").unwrap(); + let s0 = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); + let s1 = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); s0.delete().unwrap(); let binding = s1.lookup("Foobarbaz"); assert_match!(Error::NotFound @@ -1346,12 +1354,12 @@ mod test { #[test] fn delete_binding_twice() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); let b0 = store.add("Mister B.", &fp).unwrap(); let b1 = store.lookup("Mister B.").unwrap(); @@ -1361,12 +1369,12 @@ mod test { #[test] fn delete_binding_then_use() { - let ctx = core::Context::configure("org.sequoia-pgp.tests") + let ctx = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); let b0 = store.add("Mister B.", &fp).unwrap(); let b1 = store.lookup("Mister B.").unwrap(); @@ -1378,24 +1386,25 @@ mod test { } fn make_some_stores() -> core::Context { - let ctx0 = core::Context::configure("org.sequoia-pgp.tests.foo") + let ctx0 = core::Context::configure() .ephemeral() .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx0, "default").unwrap(); + let store = Store::open(&ctx0, REALM_CONTACTS, "default").unwrap(); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); store.add("Mister B.", &fp).unwrap(); store.add("B4", &fp).unwrap(); - Store::open(&ctx0, "another store").unwrap(); + Store::open(&ctx0, REALM_CONTACTS, "another store").unwrap(); - let ctx1 = core::Context::configure("org.sequoia-pgp.tests.bar") + let ctx1 = core::Context::configure() .home(ctx0.home()) .network_policy(core::NetworkPolicy::Offline) .ipc_policy(core::IPCPolicy::Internal) .build().unwrap(); - let store = Store::open(&ctx1, "default").unwrap(); + let store = + Store::open(&ctx1, REALM_SOFTWARE_UPDATES, "default").unwrap(); let fp = Fingerprint::from_bytes(b"cccccccccccccccccccc"); store.add("Mister C.", &fp).unwrap(); @@ -1405,7 +1414,7 @@ mod test { #[test] fn stats() { let ctx = make_some_stores(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); let binding = store.add("Mister B.", &fp).unwrap(); @@ -1441,15 +1450,15 @@ mod test { #[test] fn store_iterator() { let ctx = make_some_stores(); - let mut iter = Store::list(&ctx, "org.sequoia-pgp.tests.f").unwrap(); - let (domain, name, network_policy, store) = iter.next().unwrap(); - assert_eq!(domain, "org.sequoia-pgp.tests.foo"); + let mut iter = Store::list(&ctx, REALM_CONTACTS).unwrap(); + let (realm, name, network_policy, store) = iter.next().unwrap(); + assert_eq!(realm, REALM_CONTACTS); assert_eq!(name, "default"); assert_eq!(network_policy, core::NetworkPolicy::Offline); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); store.add("Mister B.", &fp).unwrap(); - let (domain, name, network_policy, store) = iter.next().unwrap(); - assert_eq!(domain, "org.sequoia-pgp.tests.foo"); + let (realm, name, network_policy, store) = iter.next().unwrap(); + assert_eq!(realm, REALM_CONTACTS); assert_eq!(name, "another store"); assert_eq!(network_policy, core::NetworkPolicy::Offline); store.add("Mister B.", &fp).unwrap(); @@ -1459,7 +1468,7 @@ mod test { #[test] fn binding_iterator() { let ctx = make_some_stores(); - let store = Store::open(&ctx, "default").unwrap(); + let store = Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); let mut iter = store.iter().unwrap(); let (label, fingerprint, binding) = iter.next().unwrap(); let fp = Fingerprint::from_bytes(b"bbbbbbbbbbbbbbbbbbbb"); diff --git a/store/src/store_protocol.capnp b/store/src/store_protocol.capnp index ded91ddf..3afe2bab 100644 --- a/store/src/store_protocol.capnp +++ b/store/src/store_protocol.capnp @@ -1,9 +1,9 @@ @0xf4bd406fa822c9db; interface Node { - open @0 (domain: Text, networkPolicy: NetworkPolicy, ephemeral: Bool, name: Text) + open @0 (realm: Text, networkPolicy: NetworkPolicy, ephemeral: Bool, name: Text) -> (result: Result(Store)); - iter @1 (domainPrefix: Text) -> (result: Result(StoreIter)); + iter @1 (realmPrefix: Text) -> (result: Result(StoreIter)); iterKeys @2 () -> (result: Result(KeyIter)); log @3 () -> (result: Result(LogIter)); import @4 (key: Data) -> (result: Result(Key)); @@ -43,7 +43,7 @@ interface Node { next @0 () -> (result: Result(Item)); struct Item { - domain @0 :Text; + realm @0 :Text; name @1 :Text; networkPolicy @2 :NetworkPolicy; store @3 :Store; diff --git a/store/tests/ipc-policy.rs b/store/tests/ipc-policy.rs index d6c4e996..9923aa80 100644 --- a/store/tests/ipc-policy.rs +++ b/store/tests/ipc-policy.rs @@ -5,45 +5,45 @@ use std::env::current_exe; use std::path::PathBuf; use sequoia_core::{Context, NetworkPolicy, IPCPolicy}; -use sequoia_store::Store; +use sequoia_store::{Store, REALM_CONTACTS}; #[test] fn ipc_policy_external() { - let ctx = Context::configure("org.sequoia-pgp.tests") + let ctx = Context::configure() .ephemeral() .lib(current_exe().unwrap().parent().unwrap().parent().unwrap()) .network_policy(NetworkPolicy::Offline) .ipc_policy(IPCPolicy::External) .build().unwrap(); - Store::open(&ctx, "default").unwrap(); + Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); } #[test] fn ipc_policy_internal() { - let ctx = Context::configure("org.sequoia-pgp.tests") + let ctx = Context::configure() .ephemeral() .lib(PathBuf::from("/i/do/not/exist")) .network_policy(NetworkPolicy::Offline) .ipc_policy(IPCPolicy::Internal) .build().unwrap(); - Store::open(&ctx, "default").unwrap(); + Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); } #[test] fn ipc_policy_robust() { - let ctx = Context::configure("org.sequoia-pgp.tests") + let ctx = Context::configure() .ephemeral() .lib(current_exe().unwrap().parent().unwrap().parent().unwrap()) .network_policy(NetworkPolicy::Offline) .ipc_policy(IPCPolicy::Robust) .build().unwrap(); - Store::open(&ctx, "default").unwrap(); + Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); - let ctx = Context::configure("org.sequoia-pgp.tests") + let ctx = Context::configure() .ephemeral() .lib(PathBuf::from("/i/do/not/exist")) .network_policy(NetworkPolicy::Offline) .ipc_policy(IPCPolicy::Robust) .build().unwrap(); - Store::open(&ctx, "default").unwrap(); + Store::open(&ctx, REALM_CONTACTS, "default").unwrap(); } diff --git a/tool/src/sq.rs b/tool/src/sq.rs index 1902e8bd..b18bada4 100644 --- a/tool/src/sq.rs +++ b/tool/src/sq.rs @@ -100,15 +100,20 @@ fn real_main() -> Result<(), failure::Error> { }, }; let force = matches.is_present("force"); - let domain_name = - matches.value_of("domain").unwrap_or("org.sequoia-pgp.sq"); - let mut builder = Context::configure(domain_name) + let (realm_name, store_name) = { + let s = matches.value_of("store").expect("has a default value"); + if let Some(i) = s.find('/') { + (&s[..i], &s[i+1..]) + } else { + (s, "default") + } + }; + let mut builder = Context::configure() .network_policy(policy); if let Some(dir) = matches.value_of("home") { builder = builder.home(dir); } let ctx = builder.build()?; - let store_name = matches.value_of("store").unwrap_or("default"); match matches.subcommand() { ("decrypt", Some(m)) => { @@ -122,7 +127,7 @@ fn real_main() -> Result<(), failure::Error> { let secrets = m.values_of("secret-key-file") .map(load_tpks) .unwrap_or(Ok(vec![]))?; - let mut store = Store::open(&ctx, store_name) + let mut store = Store::open(&ctx, realm_name, store_name) .context("Failed to open the store")?; commands::decrypt(&ctx, &mut store, &mut input, &mut output, @@ -140,7 +145,7 @@ fn real_main() -> Result<(), failure::Error> { } else { output }; - let mut store = Store::open(&ctx, store_name) + let mut store = Store::open(&ctx, realm_name, store_name) .context("Failed to open the store")?; let recipients = m.values_of("recipient") .map(|r| r.collect()) @@ -181,7 +186,7 @@ fn real_main() -> Result<(), failure::Error> { let tpks = m.values_of("public-key-file") .map(load_tpks) .unwrap_or(Ok(vec![]))?; - let mut store = Store::open(&ctx, store_name) + let mut store = Store::open(&ctx, realm_name, store_name) .context("Failed to open the store")?; commands::verify(&ctx, &mut store, &mut input, detached.as_mut().map(|r| r as &mut io::Read), @@ -335,12 +340,12 @@ fn real_main() -> Result<(), failure::Error> { } }, ("store", Some(m)) => { - let store = Store::open(&ctx, store_name) + let store = Store::open(&ctx, realm_name, store_name) .context("Failed to open the store")?; match m.subcommand() { ("list", Some(_)) => { - list_bindings(&store, domain_name, store_name)?; + list_bindings(&store, realm_name, store_name)?; }, ("add", Some(m)) => { let fp = Fingerprint::from_hex(m.value_of("fingerprint").unwrap()) @@ -403,12 +408,12 @@ fn real_main() -> Result<(), failure::Error> { ("stores", Some(m)) => { let mut table = Table::new(); table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE); - table.set_titles(row!["domain", "name", "network policy"]); + table.set_titles(row!["realm", "name", "network policy"]); - for (domain, name, network_policy, _) + for (realm, name, network_policy, _) in Store::list(&ctx, m.value_of("prefix").unwrap_or(""))? { table.add_row(Row::new(vec![ - Cell::new(&domain), + Cell::new(&realm), Cell::new(&name), Cell::new(&format!("{:?}", network_policy)) ])); @@ -417,9 +422,9 @@ fn real_main() -> Result<(), failure::Error> { table.printstd(); }, ("bindings", Some(m)) => { - for (domain, name, _, store) + for (realm, name, _, store) in Store::list(&ctx, m.value_of("prefix").unwrap_or(""))? { - list_bindings(&store, &domain, &name)?; + list_bindings(&store, &realm, &name)?; } }, ("keys", Some(_)) => { @@ -459,13 +464,13 @@ fn real_main() -> Result<(