use super::*;
use rmux_ipc::PeerIdentity;
use rmux_os::identity::UserIdentity;
use crate::server_access::AccessMode;
const FIRST_UID: u32 = 18_300;
const SECOND_UID: u32 = 18_301;
fn peer(pid: u32, uid: u32) -> PeerIdentity {
PeerIdentity {
pid,
uid,
user: UserIdentity::Uid(uid),
}
}
fn admit(
handler: &RequestHandler,
peer: &PeerIdentity,
) -> crate::server_access::ServerAccessAdmission {
handler
.set_test_access_mode_for_uid(peer.uid, AccessMode::ReadWrite)
.expect("the delegated peer can be granted access");
handler
.server_access_admission_for_peer(peer)
.expect("the granted peer is admitted")
}
#[tokio::test]
async fn conflicting_authenticated_peers_fail_closed_rather_than_becoming_the_owner() {
let handler = RequestHandler::new();
let shared_pid = 60_190;
let first = peer(shared_pid, FIRST_UID);
let second = peer(shared_pid, SECOND_UID);
let first_admission = admit(&handler, &first);
let second_admission = admit(&handler, &second);
let owner = handler.server_owner_identity();
assert!(
owner != first.user && owner != second.user,
"this test only means something while neither peer is the server owner"
);
let (_, user) = handler
.attaching_client_identity(shared_pid)
.expect("an in-process dispatch resolves");
assert_eq!(
user, owner,
"an unauthenticated requester is still the owner"
);
let first_scope = handler.begin_authenticated_peer_access(&first, first_admission);
let (uid, user) = handler
.attaching_client_identity(shared_pid)
.expect("one authenticated peer resolves");
assert_eq!(
(uid, user),
(first.uid, first.user.clone()),
"a single authenticated connection still names its own peer"
);
let second_scope = handler.begin_authenticated_peer_access(&second, second_admission);
let error = handler
.attaching_client_identity(shared_pid)
.expect_err("two peers on one pid cannot name one attaching client");
assert!(
matches!(&error, RmuxError::Server(message) if message.contains("ambiguous")),
"the refusal must say why, got {error:?}"
);
drop(second_scope);
let (uid, user) = handler
.attaching_client_identity(shared_pid)
.expect("the surviving peer resolves");
assert_eq!(
(uid, user),
(first.uid, first.user.clone()),
"closing the colliding connection restores the survivor's identity"
);
drop(first_scope);
}
#[tokio::test]
async fn a_pid_with_one_authenticated_peer_is_never_reported_as_conflicting() {
let handler = RequestHandler::new();
let shared_pid = 60_191;
let only = peer(shared_pid, FIRST_UID);
let admission = admit(&handler, &only);
let outer = handler.begin_authenticated_peer_access(&only, admission);
let inner = handler
.begin_inherited_detached_requester_access(shared_pid)
.await;
let (uid, user) = handler
.attaching_client_identity(shared_pid)
.expect("nested scopes of one peer resolve");
assert_eq!(
(uid, user),
(only.uid, only.user.clone()),
"a nested scope must not erase the peer it inherited"
);
drop(inner);
drop(outer);
}