Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: Load and dispatch login/default collection/keyring #142

Merged
merged 2 commits into from
Oct 24, 2024
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

7 changes: 7 additions & 0 deletions client/src/portal/secret.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rand::Rng;
use zeroize::{Zeroize, ZeroizeOnDrop};

/// Secret used to unlock the keyring.
Expand All @@ -17,3 +18,9 @@ impl std::ops::Deref for Secret {
&self.0
}
}

impl Secret {
pub fn random() -> Self {
Self(rand::thread_rng().gen::<[u8; 8]>().to_vec())
}
}
2 changes: 2 additions & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ rust-version.workspace = true
version.workspace = true

[dependencies]
clap.workspace = true
oo7 = { workspace = true, features = ["unstable"] }
rpassword = "7.3"
serde.workspace = true
tokio = { workspace = true, features = ["full"] }
tracing = "0.1"
Expand Down
28 changes: 22 additions & 6 deletions server/src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ use std::{
time::{Duration, SystemTime},
};

use oo7::dbus::api::{Properties, SecretInner};
use oo7::{
dbus::{
api::{Properties, SecretInner},
ServiceError,
},
portal::Keyring,
};
use tokio::sync::{Mutex, RwLock};
use zbus::{interface, zvariant};
use zvariant::{ObjectPath, OwnedObjectPath};

use super::Result;
use crate::{item, service_manager::ServiceManager};

#[derive(Debug)]
Expand All @@ -25,6 +30,8 @@ pub struct Collection {
modified: Mutex<Duration>,
// Other attributes
alias: Mutex<String>,
#[allow(unused)]
keyring: Arc<Keyring>,
manager: Arc<Mutex<ServiceManager>>,
n_items: RwLock<i32>,
path: OwnedObjectPath,
Expand All @@ -33,12 +40,15 @@ pub struct Collection {
#[interface(name = "org.freedesktop.Secret.Collection")]
impl Collection {
#[zbus(out_args("prompt"))]
pub async fn delete(&self) -> Result<ObjectPath> {
pub async fn delete(&self) -> Result<ObjectPath, ServiceError> {
todo!()
}

#[zbus(out_args("results"))]
pub async fn search_items(&self, _attributes: HashMap<String, String>) -> Vec<OwnedObjectPath> {
pub async fn search_items(
&self,
_attributes: HashMap<String, String>,
) -> Result<Vec<OwnedObjectPath>, ServiceError> {
todo!()
}

Expand All @@ -48,13 +58,18 @@ impl Collection {
_properties: Properties,
_secret: SecretInner,
_replace: bool,
) -> Result<(OwnedObjectPath, ObjectPath)> {
) -> Result<(OwnedObjectPath, ObjectPath), ServiceError> {
todo!()
}
}

impl Collection {
pub fn new(label: &str, alias: &str, manager: Arc<Mutex<ServiceManager>>) -> Self {
pub fn new(
label: &str,
alias: &str,
manager: Arc<Mutex<ServiceManager>>,
keyring: Arc<Keyring>,
) -> Self {
let created = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
Expand All @@ -73,6 +88,7 @@ impl Collection {
.unwrap(),
created,
manager,
keyring,
}
}

Expand Down
42 changes: 42 additions & 0 deletions server/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::fmt;

#[derive(Debug)]
pub enum Error {
// File backend error
Portal(oo7::portal::Error),
// Zbus error
Zbus(zbus::Error),
// IO error
IO(std::io::Error),
// Empty password error
EmptyPassword,
}

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

impl From<oo7::portal::Error> for Error {
fn from(err: oo7::portal::Error) -> Self {
Self::Portal(err)
}
}

impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::IO(err)
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Portal(err) => write!(f, "Portal error {err}"),
Self::Zbus(err) => write!(f, "Zbus error {err}"),
Self::IO(err) => write!(f, "IO error {err}"),
Self::EmptyPassword => write!(f, "Login password can't be empty"),
}
}
}
10 changes: 4 additions & 6 deletions server/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
// org.freedesktop.Secret.Item

use oo7::dbus::api::SecretInner;
use oo7::dbus::{api::SecretInner, ServiceError};
use zbus::zvariant::ObjectPath;

use super::Result;

#[derive(Debug)]
pub struct Item {}

#[zbus::interface(name = "org.freedesktop.Secret.Item")]
impl Item {
#[zbus(out_args("prompt"))]
pub async fn delete(&self) -> Result<ObjectPath> {
pub async fn delete(&self) -> Result<ObjectPath, ServiceError> {
todo!()
}

#[zbus(out_args("secret"))]
pub async fn get_secret(&self, _session: ObjectPath<'_>) -> Result<SecretInner> {
pub async fn get_secret(&self, _session: ObjectPath<'_>) -> Result<SecretInner, ServiceError> {
todo!()
}

pub async fn set_secret(&self, _secret: SecretInner) -> Result<()> {
pub async fn set_secret(&self, _secret: SecretInner) -> Result<(), ServiceError> {
todo!()
}
}
35 changes: 32 additions & 3 deletions server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,49 @@
mod collection;
mod error;
mod item;
mod prompt;
mod service;
mod service_manager;
mod session;

use service::{Result, Service};
use clap::Parser;
use oo7::portal::Secret;
use service::Service;

use crate::error::Error;

const BINARY_NAME: &str = env!("CARGO_BIN_NAME");

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Args {
#[arg(
short = 'l',
long,
default_value_t = false,
help = "Read a password from stdin, and use it to unlock the login keyring."
)]
login: bool,
}

#[tokio::main]
async fn main() -> Result<()> {
async fn main() -> Result<(), Error> {
tracing_subscriber::fmt::init();
let args = Args::parse();
let mut secret: Option<Secret> = None;

if args.login {
let password = rpassword::prompt_password("Enter the login password: ")?;
if password.is_empty() {
tracing::error!("Login password can't be empty.");
return Err(Error::EmptyPassword);
}
secret = Some(Secret::from(password.into_bytes()));
}

tracing::info!("Starting {}", BINARY_NAME);

Service::run().await?;
Service::run(secret).await?;

std::future::pending::<()>().await;

Expand Down
7 changes: 3 additions & 4 deletions server/src/prompt.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// org.freedesktop.Secret.Prompt

use oo7::dbus::ServiceError;
use zbus::interface;

use super::Result;

#[derive(Debug)]
pub struct Prompt {}

#[interface(name = "org.freedesktop.Secret.Prompt")]
impl Prompt {
pub async fn prompt(&self, _window_id: &str) -> Result<()> {
pub async fn prompt(&self, _window_id: &str) -> Result<(), ServiceError> {
todo!()
}

pub async fn dismiss(&self) -> Result<()> {
pub async fn dismiss(&self) -> Result<(), ServiceError> {
todo!()
}
}
Loading