Skip to content

Commit 8784f6d

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 8784f6d

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

3980
pub async fn set_secret(&self, _secret: SecretInner) -> Result<(), ServiceError> {
@@ -94,7 +135,7 @@ impl Item {
94135
locked: Arc::new(AtomicBool::new(locked)),
95136
inner: Arc::new(Mutex::new(item)),
96137
path: OwnedObjectPath::try_from(format!("{}/{}", collection_path, item_index)).unwrap(),
97-
_manager: manager,
138+
manager,
98139
}
99140
}
100141

server/src/service.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,38 @@ 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<OwnedObjectPath, SecretInner> = 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.item_inner(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(_) => (),
130+
};
131+
} else {
132+
tracing::info!(
133+
"Item: {:?} does not exist in collection: {}",
134+
item,
135+
collection.path().clone()
136+
);
137+
}
138+
}
139+
}
140+
141+
Ok(secrets)
114142
}
115143

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