Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ serde.workspace = true
serde_json.workspace = true
time = { version = "0.3", default-features = false, features = ["alloc", "formatting", "local-offset"] }
tokio = { workspace = true, features = ["macros", "rt"] }
zbus.workspace = true

[features]
default = ["native_crypto"]
Expand Down
55 changes: 51 additions & 4 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,38 @@ use time::{OffsetDateTime, UtcOffset};
const BINARY_NAME: &str = env!("CARGO_BIN_NAME");
const H_STYLE: anstyle::Style = anstyle::Style::new().bold().underline();

struct CliPrompter;

#[zbus::interface(name = "org.freedesktop.secrets.CliPrompter")]
impl CliPrompter {
async fn prompt(
&self,
_label: &str,
description: &str,
) -> zbus::fdo::Result<(zbus::zvariant::OwnedFd, bool)> {
let password = match rpassword::prompt_password(format!("{description}: ")) {
Ok(p) => p,
Err(e) => {
eprintln!("Failed to read password: {e}");
return Err(zbus::fdo::Error::Failed(e.to_string()));
}
};
let (read_fd, write_fd) = std::os::unix::net::UnixStream::pair()
.map_err(|e| zbus::fdo::Error::Failed(e.to_string()))?;
{
use std::io::Write;
(&write_fd)
.write_all(password.as_bytes())
.map_err(|e| zbus::fdo::Error::Failed(e.to_string()))?;
}
drop(write_fd);
Ok((
zbus::zvariant::OwnedFd::from(std::os::fd::OwnedFd::from(read_fd)),
true,
))
}
}

enum Error {
Owned(String),
Borrowed(&'static str),
Expand Down Expand Up @@ -49,6 +81,12 @@ impl From<oo7::dbus::Error> for Error {
}
}

impl From<zbus::Error> for Error {
fn from(err: zbus::Error) -> Error {
Self::Owned(err.to_string())
}
}

impl Error {
fn new(s: &'static str) -> Self {
Self::Borrowed(s)
Expand Down Expand Up @@ -377,12 +415,13 @@ impl Commands {
(None, None)
};

let keyring = match (path, secret) {
let (_prompter_conn, keyring) = match (path, secret) {
(Some(path), Some(secret)) => {
#[allow(unsafe_code)]
unsafe {
let keyring = unsafe {
Keyring::File(oo7::file::UnlockedKeyring::load_unchecked(path, secret).await?)
}
};
(None, keyring)
}

(Some(_), None) => {
Expand All @@ -400,7 +439,15 @@ impl Commands {
} else {
service.default_collection().await?
};
Keyring::Collection(collection)

let conn = zbus::Connection::session().await?;
conn.request_name("org.freedesktop.secrets.CliPrompter")
.await?;
conn.object_server()
.at("/org/freedesktop/secrets/CliPrompter", CliPrompter)
.await?;

(Some(conn), Keyring::Collection(collection))
}
};

Expand Down
14 changes: 14 additions & 0 deletions pam/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@ impl PamMessage {
data.deserialize().map(|(msg, _)| msg)
}
}

#[derive(Debug, Deserialize, Type)]
pub struct PamResponse {
pub success: bool,
pub error_message: String,
}

impl PamResponse {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, zvariant::Error> {
let ctxt = Context::new_dbus(zvariant::LE, 0);
let data = zvariant::serialized::Data::new(bytes, ctxt);
data.deserialize().map(|(msg, _)| msg)
}
}
Loading
Loading