Skip to content

Commit b118363

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 764ddb9 commit b118363

File tree

5 files changed

+98
-9
lines changed

5 files changed

+98
-9
lines changed

server/src/collection.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ impl Collection {
157157
self.alias.lock().await.clone()
158158
}
159159

160+
pub async fn get_item_from_path(&self, path: &OwnedObjectPath) -> Option<item::Item> {
161+
let items = self.items.lock().await;
162+
163+
for item in items.iter() {
164+
if item.path() == path {
165+
return Some(item.clone());
166+
}
167+
}
168+
169+
None
170+
}
171+
160172
pub async fn dispatch_items(&self) -> Result<(), Error> {
161173
let keyring_items = self.keyring.items().await;
162174
let mut items = self.items.lock().await;

server/src/item.rs

Lines changed: 43 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,47 @@ 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(
44+
"The session does not exist.".to_string(),
45+
));
46+
};
47+
48+
if self.is_locked().await {
49+
tracing::error!("Cannot get secret of a locked object.");
50+
return Err(ServiceError::IsLocked(
51+
"Cannot get secret of a locked object.".to_string(),
52+
));
53+
}
54+
55+
let inner = self.inner.lock().await;
56+
let secret = inner.secret();
57+
let mut iv = Vec::new();
58+
let key = session.aes_key();
59+
let encrypted;
60+
61+
if let Some(key) = key {
62+
iv = oo7::crypto::generate_iv();
63+
encrypted = oo7::crypto::encrypt(secret, &key, &iv);
64+
} else {
65+
encrypted = secret.to_vec();
66+
};
67+
68+
tracing::info!("Secret retrieved from the item: {}.", self.path);
69+
70+
Ok((SecretInner(
71+
session.path().clone(),
72+
iv,
73+
encrypted,
74+
"text/plain".to_string(),
75+
),))
3776
}
3877

3978
pub async fn set_secret(&self, _secret: SecretInner) -> Result<(), ServiceError> {
@@ -94,7 +133,7 @@ impl Item {
94133
locked: Arc::new(AtomicBool::new(locked)),
95134
inner: Arc::new(Mutex::new(item)),
96135
path: OwnedObjectPath::try_from(format!("{}/{}", collection_path, item_index)).unwrap(),
97-
_manager: manager,
136+
manager,
98137
}
99138
}
100139

server/src/service.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,40 @@ impl Service {
107107
#[zbus(out_args("secrets"))]
108108
pub async fn get_secrets(
109109
&self,
110-
_items: Vec<OwnedObjectPath>,
111-
_session: ObjectPath<'_>,
110+
items: Vec<OwnedObjectPath>,
111+
session: OwnedObjectPath,
112112
) -> Result<HashMap<OwnedObjectPath, SecretInner>, ServiceError> {
113-
todo!()
113+
let mut secrets = HashMap::new();
114+
let collections = self.collections.lock().await;
115+
116+
'outer: for collection in collections.iter() {
117+
for item in &items {
118+
if let Some(item) = collection.get_item_from_path(item).await {
119+
match item.get_secret(session.clone()).await {
120+
Ok(secret) => {
121+
secrets.insert(item.path().clone(), secret.0);
122+
if secrets.len() == items.len() {
123+
break 'outer;
124+
}
125+
}
126+
Err(ServiceError::NoSession(err)) => {
127+
return Err(ServiceError::NoSession(err));
128+
}
129+
Err(err) => {
130+
return Err(err);
131+
}
132+
};
133+
} else {
134+
tracing::info!(
135+
"Item: {:?} does not exist in collection: {}",
136+
item,
137+
collection.path().clone()
138+
);
139+
}
140+
}
141+
}
142+
143+
Ok(secrets)
114144
}
115145

116146
#[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)