Register native polkit agent for the login session
This commit is contained in:
1 parent
1cad509275
commit
6d8041a59a
3 files changed
+64
-3
No files matched your search
@@ -93,6 +93,9 @@ and `previous` links for switching between releases during updates and rollback.
|
|||||||
|
|
||||||
Your configuration, other desktop sessions and existing PAM policy stay in place, while
|
Your configuration, other desktop sessions and existing PAM policy stay in place, while
|
||||||
Ferese starts its authentication agent and portal services together with the session.
|
Ferese starts its authentication agent and portal services together with the session.
|
||||||
|
The authentication agent registers for the login session, so requests from desktop
|
||||||
|
apps use the Ferese dialog. Remove other polkit agents from your Ferese autostart
|
||||||
|
configuration to avoid competing session registrations.
|
||||||
|
|
||||||
### Initial configuration
|
### Initial configuration
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ fn choose_identity(identities: &[Identity]) -> Option<u32> {
|
|||||||
.or_else(|| available.first().copied())
|
.or_else(|| available.first().copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn session_subject() -> Result<(String, HashMap<String, Value<'static>>), String> {
|
fn process_subject() -> Result<(String, HashMap<String, Value<'static>>), String> {
|
||||||
let stat = std::fs::read_to_string("/proc/self/stat").map_err(|error| error.to_string())?;
|
let stat = std::fs::read_to_string("/proc/self/stat").map_err(|error| error.to_string())?;
|
||||||
let suffix = stat
|
let suffix = stat
|
||||||
.rsplit_once(") ")
|
.rsplit_once(") ")
|
||||||
@@ -115,12 +115,53 @@ fn session_subject() -> Result<(String, HashMap<String, Value<'static>>), String
|
|||||||
Ok(("unix-process".into(), details))
|
Ok(("unix-process".into(), details))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn session_subject(
|
||||||
|
connection: &zbus::Connection,
|
||||||
|
) -> Result<(String, HashMap<String, Value<'static>>), Box<dyn std::error::Error>> {
|
||||||
|
// Nested previews must not take over authentication for the host desktop.
|
||||||
|
if std::env::var("FERESE_SESSION_IMPORT_ENV").as_deref() == Ok("0") {
|
||||||
|
return process_subject().map_err(Into::into);
|
||||||
|
}
|
||||||
|
let manager = zbus::Proxy::new(
|
||||||
|
connection,
|
||||||
|
"org.freedesktop.login1",
|
||||||
|
"/org/freedesktop/login1",
|
||||||
|
"org.freedesktop.login1.Manager",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let path: zbus::zvariant::OwnedObjectPath = match manager.call("GetSessionByPID", &(std::process::id(),)).await {
|
||||||
|
Ok(path) => path,
|
||||||
|
Err(error) => {
|
||||||
|
// A launcher in the user manager can be outside the session cgroup
|
||||||
|
// while retaining the login session's environment.
|
||||||
|
let id = std::env::var("XDG_SESSION_ID").map_err(|_| error)?;
|
||||||
|
manager.call("GetSession", &(id,)).await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let session = zbus::Proxy::new(
|
||||||
|
connection,
|
||||||
|
"org.freedesktop.login1",
|
||||||
|
path,
|
||||||
|
"org.freedesktop.login1.Session",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let id: String = session.get_property("Id").await?;
|
||||||
|
Ok(login_session_subject(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn login_session_subject(id: String) -> (String, HashMap<String, Value<'static>>) {
|
||||||
|
(
|
||||||
|
"unix-session".into(),
|
||||||
|
HashMap::from([("session-id".into(), Value::from(id))]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_agent() -> Result<(), Box<dyn std::error::Error>> {
|
async fn run_agent() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let subject = session_subject()?;
|
|
||||||
let connection = zbus::connection::Builder::system()?
|
let connection = zbus::connection::Builder::system()?
|
||||||
.serve_at(AGENT_PATH, Agent::default())?
|
.serve_at(AGENT_PATH, Agent::default())?
|
||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
let subject = session_subject(&connection).await?;
|
||||||
let authority = zbus::Proxy::new(&connection, AUTHORITY, AUTHORITY_PATH, AUTHORITY_INTERFACE).await?;
|
let authority = zbus::Proxy::new(&connection, AUTHORITY, AUTHORITY_PATH, AUTHORITY_INTERFACE).await?;
|
||||||
let locale = std::env::var("LANG").unwrap_or_default();
|
let locale = std::env::var("LANG").unwrap_or_default();
|
||||||
|
|
||||||
@@ -152,6 +193,23 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn desktop_agent_registers_for_the_login_session() {
|
||||||
|
let (kind, details) = login_session_subject("test-session".into());
|
||||||
|
assert_eq!(kind, "unix-session");
|
||||||
|
assert_eq!(details.len(), 1);
|
||||||
|
assert_eq!(details["session-id"], Value::from("test-session"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn process_subject_has_required_identity_fields() {
|
||||||
|
let (kind, details) = process_subject().unwrap();
|
||||||
|
assert_eq!(kind, "unix-process");
|
||||||
|
assert_eq!(details["pid"], Value::from(std::process::id()));
|
||||||
|
assert_eq!(details["uid"], Value::from(unsafe { libc::geteuid() } as i32));
|
||||||
|
assert!(u64::try_from(details["start-time"].clone()).unwrap() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn chooses_current_identity_when_available() {
|
fn chooses_current_identity_when_available() {
|
||||||
let current = unsafe { libc::geteuid() };
|
let current = unsafe { libc::geteuid() };
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ fn prompt_process(
|
|||||||
.arg("--prompt")
|
.arg("--prompt")
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::null())
|
.stderr(Stdio::inherit())
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let stdin = child.stdin.take().ok_or("Prompt has no input")?;
|
let stdin = child.stdin.take().ok_or("Prompt has no input")?;
|
||||||
|
|||||||
Reference in new issue
Block a user