fix: scope server pins by port (fumi-core rev 1468f3c)
This commit is contained in:
parent
996e879509
commit
7d2a147fec
16 changed files with 109 additions and 79 deletions
2
native/Cargo.lock
generated
2
native/Cargo.lock
generated
|
|
@ -271,7 +271,7 @@ checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484"
|
|||
[[package]]
|
||||
name = "fumi-core"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@code.randogoth.com:2222/randogoth/fumi.git?rev=2d65d66#2d65d66012fa40121e4dc3d8d15db9ffc486569a"
|
||||
source = "git+ssh://git@code.randogoth.com:2222/randogoth/fumi.git?rev=1468f3c#1468f3cbc0a89a0cb073f46a985911c0327885d1"
|
||||
dependencies = [
|
||||
"chacha20poly1305",
|
||||
"data-encoding",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
|||
crate-type = ["lib", "cdylib"]
|
||||
|
||||
[dependencies]
|
||||
fumi-core = { git = "ssh://git@code.randogoth.com:2222/randogoth/fumi.git", rev = "2d65d66" }
|
||||
fumi-core = { git = "ssh://git@code.randogoth.com:2222/randogoth/fumi.git", rev = "1468f3c" }
|
||||
rand_core = { version = "0.6", features = ["getrandom"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
|
|
|||
|
|
@ -126,22 +126,29 @@ struct ErrorJson {
|
|||
/// The raw byte behind an UNKNOWN_STATUS (code 11).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
status: Option<u8>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
port: Option<u16>,
|
||||
}
|
||||
|
||||
impl ErrorJson {
|
||||
fn of(error: &Error) -> ErrorJson {
|
||||
let message = error.to_string();
|
||||
let (host, pinned, presented, address, known, offered, status) = match error {
|
||||
let (host, pinned, presented, address, known, offered, status, port) = match error {
|
||||
Error::UnknownStatus(status, _) => {
|
||||
(None, None, None, None, None, None, Some(*status))
|
||||
(None, None, None, None, None, None, Some(*status), None)
|
||||
}
|
||||
Error::NotPinned { host, port } => {
|
||||
(Some(host.clone()), None, None, None, None, None, None, Some(*port))
|
||||
}
|
||||
Error::Unreachable { host, .. } => {
|
||||
(Some(host.clone()), None, None, None, None, None, None, None)
|
||||
}
|
||||
Error::NotPinned { host } => (Some(host.clone()), None, None, None, None, None, None),
|
||||
Error::Unreachable { host, .. } => (Some(host.clone()), None, None, None, None, None, None),
|
||||
Error::HandshakeRefused { host, .. } => {
|
||||
(Some(host.clone()), None, None, None, None, None, None)
|
||||
(Some(host.clone()), None, None, None, None, None, None, None)
|
||||
}
|
||||
Error::PinMismatch {
|
||||
host,
|
||||
port,
|
||||
pinned,
|
||||
presented,
|
||||
} => (
|
||||
|
|
@ -152,6 +159,7 @@ impl ErrorJson {
|
|||
None,
|
||||
None,
|
||||
None,
|
||||
Some(*port),
|
||||
),
|
||||
Error::KeyChanged {
|
||||
address,
|
||||
|
|
@ -165,8 +173,9 @@ impl ErrorJson {
|
|||
Some(b32(known)),
|
||||
Some(b32(offered)),
|
||||
None,
|
||||
None,
|
||||
),
|
||||
_ => (None, None, None, None, None, None, None),
|
||||
_ => (None, None, None, None, None, None, None, None),
|
||||
};
|
||||
ErrorJson {
|
||||
code: code_of(error),
|
||||
|
|
@ -178,6 +187,7 @@ impl ErrorJson {
|
|||
known,
|
||||
offered,
|
||||
status,
|
||||
port,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -383,23 +393,24 @@ pub extern "C" fn smol_pin_server(
|
|||
store: *mut Store,
|
||||
host: *const c_char,
|
||||
key_b32: *const c_char,
|
||||
port: u16,
|
||||
) -> i32 {
|
||||
status(|| {
|
||||
let store = unsafe { store.as_ref().ok_or_else(|| Error::Other("store handle is null".into()))? };
|
||||
let key: [u8; KEY_LEN] = unb32(text(key_b32)?)?
|
||||
.try_into()
|
||||
.map_err(|_| Error::Other("server key must decode to 32 bytes".into()))?;
|
||||
store.pin_server(text(host)?, &key)
|
||||
store.pin_server(text(host)?, port, &key)
|
||||
})
|
||||
}
|
||||
|
||||
/// The pinned key for a host, base32. Empty string: none pinned. Null: error.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn smol_server_pin(store: *mut Store, host: *const c_char) -> *mut c_char {
|
||||
pub extern "C" fn smol_server_pin(store: *mut Store, host: *const c_char, port: u16) -> *mut c_char {
|
||||
match guarded(|| {
|
||||
let store = unsafe { store.as_ref().ok_or_else(|| Error::Other("store handle is null".into()))? };
|
||||
Ok(store
|
||||
.server_pin(text(host)?)?
|
||||
.server_pin(text(host)?, port)?
|
||||
.map(|key| b32(&key))
|
||||
.unwrap_or_default())
|
||||
}) {
|
||||
|
|
@ -426,12 +437,13 @@ pub extern "C" fn smol_contact_save(
|
|||
})
|
||||
}
|
||||
|
||||
/// Removes a pin: the next session against that host is trust on first use.
|
||||
/// Removes a pin: the next session against that host and port is trust on
|
||||
/// first use.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn smol_unpin_server(store: *mut Store, host: *const c_char) -> i32 {
|
||||
pub extern "C" fn smol_unpin_server(store: *mut Store, host: *const c_char, port: u16) -> i32 {
|
||||
status(|| {
|
||||
let store = unsafe { store.as_ref().ok_or_else(|| Error::Other("store handle is null".into()))? };
|
||||
store.unpin_server(text(host)?)
|
||||
store.unpin_server(text(host)?, port)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1178,6 +1190,7 @@ mod tests {
|
|||
let json: serde_json::Value = serde_json::from_str(&slot).unwrap();
|
||||
assert_eq!(json["code"], NOT_PINNED);
|
||||
assert_eq!(json["host"], "127.0.0.1");
|
||||
assert_eq!(json["port"], 19619);
|
||||
|
||||
// Strings returned on success must be freed without double-free.
|
||||
assert_eq!(take(smol_store_account(store)), "");
|
||||
|
|
@ -1193,7 +1206,8 @@ mod tests {
|
|||
fn mail_and_contacts_render_as_json() {
|
||||
let store = smol_store_memory();
|
||||
let s = unsafe { &*store };
|
||||
s.pin_server("example.org", &[1u8; KEY_LEN]).unwrap();
|
||||
s.pin_server("example.org", fumi_core::address::DEFAULT_PORT, &[1u8; KEY_LEN])
|
||||
.unwrap();
|
||||
s.save_contact("alice@example.org", &[2u8; KEY_LEN], true).unwrap();
|
||||
s.save_history("alice@example.org", &[9u8; KEY_LEN], 500).unwrap();
|
||||
s.store_inbox(&[3u8; ID_LEN], b"sealed", 7, false, true).unwrap();
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ mod tests {
|
|||
let alice_addr =
|
||||
Address::parse(&format!("a{run}@127.0.0.1:19619")).unwrap();
|
||||
let bob_addr = Address::parse(&format!("b{run}@127.0.0.1:19619")).unwrap();
|
||||
alice_store.pin_server("127.0.0.1", &server).unwrap();
|
||||
bob_store.pin_server("127.0.0.1", &server).unwrap();
|
||||
alice_store.pin_server("127.0.0.1", 19619, &server).unwrap();
|
||||
bob_store.pin_server("127.0.0.1", 19619, &server).unwrap();
|
||||
|
||||
register(&alice_store, &alice_addr, &alice, None, 5).unwrap();
|
||||
register(&bob_store, &bob_addr, &bob, None, 5).unwrap();
|
||||
|
|
@ -168,8 +168,8 @@ mod tests {
|
|||
let run = fumi_core::crypto::b32(&suffix);
|
||||
let alice_addr = Address::parse(&format!("a{run}@127.0.0.1:19619")).unwrap();
|
||||
let bob_addr = Address::parse(&format!("b{run}@127.0.0.1:19619")).unwrap();
|
||||
alice_store.pin_server("127.0.0.1", &server).unwrap();
|
||||
bob_store.pin_server("127.0.0.1", &server).unwrap();
|
||||
alice_store.pin_server("127.0.0.1", 19619, &server).unwrap();
|
||||
bob_store.pin_server("127.0.0.1", 19619, &server).unwrap();
|
||||
register(&alice_store, &alice_addr, &alice, None, 5).unwrap();
|
||||
register(&bob_store, &bob_addr, &bob, None, 5).unwrap();
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ mod tests {
|
|||
fumi_core::address::Address::parse(&format!("u{run}@{host}:19619"))
|
||||
.unwrap()
|
||||
.with_dial("127.0.0.1");
|
||||
store.pin_server(&host, &server).unwrap();
|
||||
store.pin_server(&host, 19619, &server).unwrap();
|
||||
register(&store, &addr, &account, None, 5).unwrap();
|
||||
assert_eq!(store.account().unwrap().unwrap().short(),
|
||||
format!("u{run}@{host}:19619"));
|
||||
|
|
@ -296,7 +296,10 @@ mod tests {
|
|||
|
||||
let unpinned = Store::open_in_memory().unwrap();
|
||||
match connect(&unpinned, &addr, true, 5) {
|
||||
Err(Error::NotPinned { host }) => assert_eq!(host, "127.0.0.1"),
|
||||
Err(Error::NotPinned { host, port }) => {
|
||||
assert_eq!(host, "127.0.0.1");
|
||||
assert_eq!(port, 19619);
|
||||
}
|
||||
Err(err) => panic!("expected NotPinned, got {err}"),
|
||||
Ok(_) => panic!("expected NotPinned, connected"),
|
||||
}
|
||||
|
|
@ -304,7 +307,7 @@ mod tests {
|
|||
let mut wrong = [0u8; KEY_LEN];
|
||||
OsRng.fill_bytes(&mut wrong);
|
||||
let mismatched = Store::open_in_memory().unwrap();
|
||||
mismatched.pin_server("127.0.0.1", &wrong).unwrap();
|
||||
mismatched.pin_server("127.0.0.1", 19619, &wrong).unwrap();
|
||||
match connect(&mismatched, &addr, true, 5) {
|
||||
Err(Error::PinMismatch { .. }) => {}
|
||||
Err(err) => panic!("expected PinMismatch, got {err}"),
|
||||
|
|
@ -348,8 +351,8 @@ mod tests {
|
|||
let run = fumi_core::crypto::b32(&suffix);
|
||||
let carol_addr = Address::parse(&format!("c{run}@127.0.0.1:19619")).unwrap();
|
||||
let alice_addr = Address::parse(&format!("d{run}@127.0.0.1:19619")).unwrap();
|
||||
carol_store.pin_server("127.0.0.1", &server).unwrap();
|
||||
alice_store.pin_server("127.0.0.1", &server).unwrap();
|
||||
carol_store.pin_server("127.0.0.1", 19619, &server).unwrap();
|
||||
alice_store.pin_server("127.0.0.1", 19619, &server).unwrap();
|
||||
register(&carol_store, &carol_addr, &carol, None, 5).unwrap();
|
||||
register(&alice_store, &alice_addr, &alice, None, 5).unwrap();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue