Fix compositor output routing and pointer hints; format imports
This commit is contained in:
1 parent
88e4f3c135
commit
46509f880a
108 files changed
+3682
-8371
No files matched your search
@@ -1,14 +1,11 @@
|
||||
mod prompt;
|
||||
mod session;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{
|
||||
Arc, Mutex,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
};
|
||||
use zbus::zvariant::{OwnedValue, Value};
|
||||
|
||||
const AGENT_PATH: &str = "/dev/ferese/PolkitAgent";
|
||||
@@ -45,9 +42,8 @@ impl Agent {
|
||||
cookie: String,
|
||||
identities: Vec<Identity>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
let uid = choose_identity(&identities).ok_or_else(|| {
|
||||
zbus::fdo::Error::Failed("No supported authentication identity".into())
|
||||
})?;
|
||||
let uid = choose_identity(&identities)
|
||||
.ok_or_else(|| zbus::fdo::Error::Failed("No supported authentication identity".into()))?;
|
||||
let cancelled = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
@@ -60,9 +56,7 @@ impl Agent {
|
||||
|
||||
let result = tokio::task::spawn_blocking({
|
||||
let cookie = cookie.clone();
|
||||
move || {
|
||||
session::authenticate(uid, message.chars().take(240).collect(), cookie, cancelled)
|
||||
}
|
||||
move || session::authenticate(uid, message.chars().take(240).collect(), cookie, cancelled)
|
||||
})
|
||||
.await
|
||||
.map_err(|error| zbus::fdo::Error::Failed(error.to_string()))?;
|
||||
@@ -116,10 +110,7 @@ fn session_subject() -> Result<(String, HashMap<String, Value<'static>>), String
|
||||
.map_err(|error| error.to_string())?;
|
||||
let mut details = HashMap::new();
|
||||
details.insert("pid".to_owned(), Value::from(std::process::id()));
|
||||
details.insert(
|
||||
"uid".to_owned(),
|
||||
Value::from(unsafe { libc::geteuid() } as i32),
|
||||
);
|
||||
details.insert("uid".to_owned(), Value::from(unsafe { libc::geteuid() } as i32));
|
||||
details.insert("start-time".to_owned(), Value::from(started));
|
||||
Ok(("unix-process".into(), details))
|
||||
}
|
||||
@@ -130,15 +121,11 @@ async fn run_agent() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.serve_at(AGENT_PATH, Agent::default())?
|
||||
.build()
|
||||
.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();
|
||||
|
||||
authority
|
||||
.call::<_, _, ()>(
|
||||
"RegisterAuthenticationAgent",
|
||||
&(subject, locale, AGENT_PATH),
|
||||
)
|
||||
.call::<_, _, ()>("RegisterAuthenticationAgent", &(subject, locale, AGENT_PATH))
|
||||
.await?;
|
||||
std::future::pending::<()>().await;
|
||||
|
||||
@@ -174,9 +161,6 @@ mod tests {
|
||||
HashMap::from([("uid".to_owned(), OwnedValue::from(uid))]),
|
||||
)
|
||||
};
|
||||
assert_eq!(
|
||||
choose_identity(&[identity(0), identity(current)]),
|
||||
Some(current)
|
||||
);
|
||||
assert_eq!(choose_identity(&[identity(0), identity(current)]), Some(current));
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,16 @@
|
||||
use crate::PromptEvent;
|
||||
use cosmic::{
|
||||
Element,
|
||||
app::{Core, Settings, Task},
|
||||
iced::{Alignment, Color, Length, Size, Subscription, window},
|
||||
theme,
|
||||
widget::{self, button, column, container, row},
|
||||
};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
io::{BufRead, BufReader, Write},
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
use std::collections::VecDeque;
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
use cosmic::app::{Core, Settings, Task};
|
||||
use cosmic::iced::{Alignment, Color, Length, Size, Subscription, window};
|
||||
use cosmic::widget::{button, column, container, row};
|
||||
use cosmic::{Element, theme, widget};
|
||||
use zeroize::{Zeroize, Zeroizing};
|
||||
|
||||
use crate::PromptEvent;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Appearance {
|
||||
surface: Color,
|
||||
@@ -103,9 +100,7 @@ fn content_height(description: &str, status: Option<&str>) -> f32 {
|
||||
.lines()
|
||||
.map(|line| line.chars().count().div_ceil(48).max(1))
|
||||
.sum();
|
||||
let status_height = status.map_or(0, |message| {
|
||||
14 + 18 * message.chars().count().div_ceil(48).clamp(1, 3)
|
||||
});
|
||||
let status_height = status.map_or(0, |message| 14 + 18 * message.chars().count().div_ceil(48).clamp(1, 3));
|
||||
(214 + 18 * lines.saturating_sub(1) + status_height).min(360) as f32
|
||||
}
|
||||
|
||||
@@ -163,10 +158,7 @@ fn focus() -> Task<Message> {
|
||||
|
||||
impl Prompt {
|
||||
fn resize_to_content(&mut self) -> Task<Message> {
|
||||
let height = content_height(
|
||||
&self.description,
|
||||
self.error.as_deref().or(self.info.as_deref()),
|
||||
);
|
||||
let height = content_height(&self.description, self.error.as_deref().or(self.info.as_deref()));
|
||||
if (height - self.height).abs() < 1.0 {
|
||||
return Task::none();
|
||||
}
|
||||
@@ -180,12 +172,7 @@ impl Prompt {
|
||||
|
||||
impl cosmic::Application for Prompt {
|
||||
type Executor = cosmic::executor::Default;
|
||||
type Flags = (
|
||||
Arc<Mutex<VecDeque<PromptEvent>>>,
|
||||
String,
|
||||
String,
|
||||
Appearance,
|
||||
);
|
||||
type Flags = (Arc<Mutex<VecDeque<PromptEvent>>>, String, String, Appearance);
|
||||
type Message = Message;
|
||||
const APP_ID: &'static str = "dev.ferese.Authentication";
|
||||
|
||||
@@ -198,21 +185,14 @@ impl cosmic::Application for Prompt {
|
||||
}
|
||||
|
||||
fn style(&self) -> Option<cosmic::iced::theme::Style> {
|
||||
Some(
|
||||
self.appearance
|
||||
.palette()
|
||||
.application_style(if self.material.is_some() {
|
||||
cosmic::iced::Color::TRANSPARENT
|
||||
} else {
|
||||
self.appearance.surface
|
||||
}),
|
||||
)
|
||||
Some(self.appearance.palette().application_style(if self.material.is_some() {
|
||||
cosmic::iced::Color::TRANSPARENT
|
||||
} else {
|
||||
self.appearance.surface
|
||||
}))
|
||||
}
|
||||
|
||||
fn init(
|
||||
mut core: Core,
|
||||
(incoming, description, user, appearance): Self::Flags,
|
||||
) -> (Self, Task<Message>) {
|
||||
fn init(mut core: Core, (incoming, description, user, appearance): Self::Flags) -> (Self, Task<Message>) {
|
||||
core.window.show_headerbar = false;
|
||||
core.window.border_padding = Some(0);
|
||||
core.window.content_container = false;
|
||||
@@ -257,11 +237,8 @@ impl cosmic::Application for Prompt {
|
||||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::WindowOpened(id) => {
|
||||
return cosmic::iced::window::run(
|
||||
id,
|
||||
ferese_theme::material::ModalMaterial::attach,
|
||||
)
|
||||
.map(|result| cosmic::Action::App(Message::MaterialAttached(result)));
|
||||
return cosmic::iced::window::run(id, ferese_theme::material::ModalMaterial::attach)
|
||||
.map(|result| cosmic::Action::App(Message::MaterialAttached(result)));
|
||||
}
|
||||
Message::MaterialAttached(result) => {
|
||||
self.material = result.ok();
|
||||
@@ -323,9 +300,7 @@ impl cosmic::Application for Prompt {
|
||||
.id(widget::Id::new("auth-response"))
|
||||
.font(palette.font)
|
||||
.padding([7, 12])
|
||||
.style(ferese_theme::controls::authentication_input(
|
||||
palette.palette(),
|
||||
));
|
||||
.style(ferese_theme::controls::authentication_input(palette.palette()));
|
||||
if !self.echo {
|
||||
input = input.password();
|
||||
}
|
||||
@@ -347,10 +322,7 @@ impl cosmic::Application for Prompt {
|
||||
.height(40)
|
||||
.center_x(40)
|
||||
.center_y(40)
|
||||
.class(ferese_theme::controls::surface(
|
||||
palette.accent.scale_alpha(0.13),
|
||||
12.,
|
||||
)),
|
||||
.class(ferese_theme::controls::surface(palette.accent.scale_alpha(0.13), 12.,)),
|
||||
column![
|
||||
ferese_theme::text("Authentication required", palette.font).size(18),
|
||||
ferese_theme::text(format!("Confirm as {}", self.user), palette.font)
|
||||
@@ -384,10 +356,7 @@ impl cosmic::Application for Prompt {
|
||||
body = body.push(
|
||||
row![
|
||||
button::custom(ferese_theme::text("Cancel", palette.font).size(13))
|
||||
.class(ferese_theme::controls::button_style(
|
||||
palette.palette(),
|
||||
false
|
||||
))
|
||||
.class(ferese_theme::controls::button_style(palette.palette(), false))
|
||||
.padding([8, 14])
|
||||
.on_press(Message::Cancel),
|
||||
action
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
use crate::PromptEvent;
|
||||
use std::ffi::{CStr, CString, c_char, c_int, c_void};
|
||||
use std::io::{BufRead, BufReader, BufWriter, Write};
|
||||
use std::process::{Child, ChildStdin, Command, Stdio};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, mpsc};
|
||||
use std::time::Duration;
|
||||
|
||||
use glib::gobject_ffi;
|
||||
use libloading::Library;
|
||||
use std::{
|
||||
ffi::{CStr, CString, c_char, c_int, c_void},
|
||||
io::{BufRead, BufReader, BufWriter, Write},
|
||||
process::{Child, ChildStdin, Command, Stdio},
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
mpsc::{self, Sender},
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::PromptEvent;
|
||||
|
||||
enum SessionEvent {
|
||||
Request(String, bool),
|
||||
Info(String),
|
||||
@@ -38,21 +36,15 @@ impl Api {
|
||||
unsafe {
|
||||
let agent = Library::new("libpolkit-agent-1.so.0").map_err(|e| e.to_string())?;
|
||||
let polkit = Library::new("libpolkit-gobject-1.so.0").map_err(|e| e.to_string())?;
|
||||
let user_new = *polkit
|
||||
.get(b"polkit_unix_user_new\0")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let session_new = *agent
|
||||
.get(b"polkit_agent_session_new\0")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let user_new = *polkit.get(b"polkit_unix_user_new\0").map_err(|e| e.to_string())?;
|
||||
let session_new = *agent.get(b"polkit_agent_session_new\0").map_err(|e| e.to_string())?;
|
||||
let initiate = *agent
|
||||
.get(b"polkit_agent_session_initiate\0")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let response = *agent
|
||||
.get(b"polkit_agent_session_response\0")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let cancel = *agent
|
||||
.get(b"polkit_agent_session_cancel\0")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let cancel = *agent.get(b"polkit_agent_session_cancel\0").map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(Self {
|
||||
_agent: agent,
|
||||
@@ -72,9 +64,7 @@ pub fn check() -> Result<(), String> {
|
||||
}
|
||||
|
||||
fn username(uid: u32) -> String {
|
||||
let output = Command::new("getent")
|
||||
.args(["passwd", &uid.to_string()])
|
||||
.output();
|
||||
let output = Command::new("getent").args(["passwd", &uid.to_string()]).output();
|
||||
output
|
||||
.ok()
|
||||
.filter(|output| output.status.success())
|
||||
@@ -122,32 +112,21 @@ fn prompt_process(
|
||||
Ok((child, writer, rx))
|
||||
}
|
||||
|
||||
unsafe extern "C" fn request(
|
||||
_session: Object,
|
||||
prompt: *const c_char,
|
||||
echo: c_int,
|
||||
data: *mut c_void,
|
||||
) {
|
||||
unsafe extern "C" fn request(_session: Object, prompt: *const c_char, echo: c_int, data: *mut c_void) {
|
||||
let tx = unsafe { &*(data as *const Sender<SessionEvent>) };
|
||||
let prompt = unsafe { CStr::from_ptr(prompt) }
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
let prompt = unsafe { CStr::from_ptr(prompt) }.to_string_lossy().into_owned();
|
||||
let _ = tx.send(SessionEvent::Request(prompt, echo != 0));
|
||||
}
|
||||
|
||||
unsafe extern "C" fn info(_session: Object, text: *const c_char, data: *mut c_void) {
|
||||
let tx = unsafe { &*(data as *const Sender<SessionEvent>) };
|
||||
let text = unsafe { CStr::from_ptr(text) }
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
let text = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned();
|
||||
let _ = tx.send(SessionEvent::Info(text));
|
||||
}
|
||||
|
||||
unsafe extern "C" fn error(_session: Object, text: *const c_char, data: *mut c_void) {
|
||||
let tx = unsafe { &*(data as *const Sender<SessionEvent>) };
|
||||
let text = unsafe { CStr::from_ptr(text) }
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
let text = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned();
|
||||
let _ = tx.send(SessionEvent::Error(text));
|
||||
}
|
||||
|
||||
@@ -156,12 +135,7 @@ unsafe extern "C" fn completed(_session: Object, success: c_int, data: *mut c_vo
|
||||
let _ = tx.send(SessionEvent::Completed(success != 0));
|
||||
}
|
||||
|
||||
unsafe fn connect(
|
||||
session: Object,
|
||||
name: &'static CStr,
|
||||
callback: gobject_ffi::GCallback,
|
||||
data: *mut c_void,
|
||||
) {
|
||||
unsafe fn connect(session: Object, name: &'static CStr, callback: gobject_ffi::GCallback, data: *mut c_void) {
|
||||
unsafe {
|
||||
gobject_ffi::g_signal_connect_data(
|
||||
session.cast(),
|
||||
@@ -215,7 +189,7 @@ fn run_session(
|
||||
unsafe extern "C" fn(Object, *const c_char, *mut c_void),
|
||||
unsafe extern "C" fn(),
|
||||
>(
|
||||
info as unsafe extern "C" fn(Object, *const c_char, *mut c_void),
|
||||
info as unsafe extern "C" fn(Object, *const c_char, *mut c_void)
|
||||
)),
|
||||
signal_data,
|
||||
);
|
||||
@@ -226,7 +200,7 @@ fn run_session(
|
||||
unsafe extern "C" fn(Object, *const c_char, *mut c_void),
|
||||
unsafe extern "C" fn(),
|
||||
>(
|
||||
error as unsafe extern "C" fn(Object, *const c_char, *mut c_void),
|
||||
error as unsafe extern "C" fn(Object, *const c_char, *mut c_void)
|
||||
)),
|
||||
signal_data,
|
||||
);
|
||||
@@ -237,7 +211,7 @@ fn run_session(
|
||||
unsafe extern "C" fn(Object, c_int, *mut c_void),
|
||||
unsafe extern "C" fn(),
|
||||
>(
|
||||
completed as unsafe extern "C" fn(Object, c_int, *mut c_void),
|
||||
completed as unsafe extern "C" fn(Object, c_int, *mut c_void)
|
||||
)),
|
||||
signal_data,
|
||||
);
|
||||
@@ -276,10 +250,7 @@ fn run_session(
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !stopped
|
||||
&& (cancelled.load(Ordering::Acquire)
|
||||
|| child.try_wait().map_err(|e| e.to_string())?.is_some())
|
||||
{
|
||||
if !stopped && (cancelled.load(Ordering::Acquire) || child.try_wait().map_err(|e| e.to_string())?.is_some()) {
|
||||
unsafe { (api.cancel)(session) };
|
||||
stopped = true;
|
||||
}
|
||||
@@ -293,12 +264,7 @@ fn run_session(
|
||||
Ok(outcome.filter(|_| !stopped))
|
||||
}
|
||||
|
||||
pub fn authenticate(
|
||||
uid: u32,
|
||||
message: String,
|
||||
cookie: String,
|
||||
cancelled: Arc<AtomicBool>,
|
||||
) -> Result<bool, String> {
|
||||
pub fn authenticate(uid: u32, message: String, cookie: String, cancelled: Arc<AtomicBool>) -> Result<bool, String> {
|
||||
let api = Api::load()?;
|
||||
let cookie = CString::new(cookie).map_err(|_| "Invalid authentication cookie")?;
|
||||
let context = glib::MainContext::new();
|
||||
|
||||
Reference in new issue
Block a user