Skip to content

Commit 65d63ec

Browse files
committed
server: Add GetSecret and GetSecrets implementation
This change adds Secret Service method GetSecrets and Secret Item method GetSecret. Signed-off-by: Dhanuka Warusadura <dhanuka@gnome.org>
1 parent f097dc5 commit 65d63ec

File tree

5 files changed

+106
-9
lines changed

5 files changed

+106
-9
lines changed

server/src/collection.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ impl Collection {
193193
items
194194
}
195195

196+
pub async fn item_from_path(&self, path: &OwnedObjectPath) -> Option<item::Item> {
197+
let items = self.items.lock().await;
198+
199+
for item in items.iter() {
200+
if item.path() == path {
201+
return Some(item.clone());
202+
}
203+
}
204+
205+
None
206+
}
207+
196208
pub async fn dispatch_items(&self) -> Result<(), Error> {
197209
let keyring_items = self.keyring.items().await;
198210
let mut items = self.items.lock().await;

server/src/item.rs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub struct Item {
2020
locked: Arc<AtomicBool>,
2121
inner: Arc<Mutex<oo7::portal::Item>>,
2222
// Other attributes
23-
_manager: Arc<Mutex<ServiceManager>>,
23+
manager: Arc<Mutex<ServiceManager>>,
2424
path: OwnedObjectPath,
2525
}
2626

@@ -32,8 +32,52 @@ impl Item {
3232
}
3333

3434
#[zbus(out_args("secret"))]
35-
pub async fn get_secret(&self, _session: ObjectPath<'_>) -> Result<SecretInner, ServiceError> {
36-
todo!()
35+
pub async fn get_secret(
36+
&self,
37+
session: OwnedObjectPath,
38+
) -> Result<(SecretInner,), ServiceError> {
39+
let manager = self.manager.lock().await;
40+
41+
let Some(session) = manager.session(&session) else {
42+
tracing::error!("The session `{}` does not exist.", session);
43+
return Err(ServiceError::NoSession(format!(
44+
"The session `{}` does not exist.",
45+
session
46+
)));
47+
};
48+
49+
if self.is_locked().await {
50+
tracing::error!("Cannot get secret of a locked object.");
51+
return Err(ServiceError::IsLocked(format!(
52+
"Cannot get secret of a locked object `{}`.",
53+
self.path
54+
)));
55+
}
56+
57+
let inner = self.inner.lock().await;
58+
let secret = inner.secret();
59+
60+
tracing::debug!("Secret retrieved from the item: {}.", self.path);
61+
62+
match session.aes_key() {
63+
Some(key) => {
64+
let iv = oo7::crypto::generate_iv();
65+
let encrypted = oo7::crypto::encrypt(secret, &key, &iv);
66+
67+
Ok((SecretInner(
68+
session.path().clone(),
69+
iv,
70+
encrypted,
71+
"text/plain".to_owned(),
72+
),))
73+
}
74+
None => Ok((SecretInner(
75+
session.path().clone(),
76+
Vec::new(),
77+
secret.to_vec(),
78+
"text/plain".to_owned(),
79+
),)),
80+
}
3781
}
3882

3983
pub async fn set_secret(&self, _secret: SecretInner) -> Result<(), ServiceError> {
@@ -94,7 +138,7 @@ impl Item {
94138
locked: Arc::new(AtomicBool::new(locked)),
95139
inner: Arc::new(Mutex::new(item)),
96140
path: OwnedObjectPath::try_from(format!("{}/{}", collection_path, item_index)).unwrap(),
97-
_manager: manager,
141+
manager,
98142
}
99143
}
100144

server/src/service.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,43 @@ impl Service {
131131
#[zbus(out_args("secrets"))]
132132
pub async fn get_secrets(
133133
&self,
134-
_items: Vec<OwnedObjectPath>,
135-
_session: ObjectPath<'_>,
134+
items: Vec<OwnedObjectPath>,
135+
session: OwnedObjectPath,
136136
) -> Result<HashMap<OwnedObjectPath, SecretInner>, ServiceError> {
137-
todo!()
137+
let mut secrets = HashMap::new();
138+
let collections = self.collections.lock().await;
139+
140+
'outer: for collection in collections.iter() {
141+
for item in &items {
142+
if let Some(item) = collection.item_from_path(item).await {
143+
match item.get_secret(session.clone()).await {
144+
Ok(secret) => {
145+
secrets.insert(item.path().clone(), secret.0);
146+
if secrets.len() == items.len() {
147+
break 'outer;
148+
}
149+
}
150+
Err(ServiceError::NoSession(err)) => {
151+
return Err(ServiceError::NoSession(err));
152+
}
153+
Err(ServiceError::IsLocked(_)) => {
154+
continue;
155+
}
156+
Err(err) => {
157+
return Err(err);
158+
}
159+
};
160+
} else {
161+
tracing::debug!(
162+
"Item: {:?} does not exist in collection: {}",
163+
item,
164+
collection.path()
165+
);
166+
}
167+
}
168+
}
169+
170+
Ok(secrets)
138171
}
139172

140173
#[zbus(out_args("collection"))]

server/src/service_manager.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ impl ServiceManager {
2929
self.sessions.len()
3030
}
3131

32+
pub fn session(&self, path: &OwnedObjectPath) -> Option<Arc<Session>> {
33+
self.sessions.get(path).map(Arc::clone)
34+
}
35+
3236
pub fn insert_session(&mut self, path: OwnedObjectPath, session: Arc<Session>) {
3337
self.sessions.insert(path, session);
3438
}

server/src/session.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::service_manager::ServiceManager;
1010

1111
#[derive(Debug, Clone)]
1212
pub struct Session {
13-
_aes_key: Option<Arc<Key>>,
13+
aes_key: Option<Arc<Key>>,
1414
manager: Arc<Mutex<ServiceManager>>,
1515
path: OwnedObjectPath,
1616
}
@@ -34,12 +34,16 @@ impl Session {
3434
Self {
3535
path: OwnedObjectPath::try_from(format!("/org/freedesktop/secrets/session/s{index}"))
3636
.unwrap(),
37-
_aes_key: aes_key,
37+
aes_key,
3838
manager,
3939
}
4040
}
4141

4242
pub fn path(&self) -> &OwnedObjectPath {
4343
&self.path
4444
}
45+
46+
pub fn aes_key(&self) -> Option<Arc<Key>> {
47+
self.aes_key.as_ref().map(Arc::clone)
48+
}
4549
}

0 commit comments

Comments
 (0)