From 1e2b6d49e9be24b9df18e1d63c04a6237efa24b8 Mon Sep 17 00:00:00 2001 From: Joseph Birr-Pixton Date: Fri, 26 Apr 2024 16:33:44 +0100 Subject: [PATCH] cache.rs: refuse to use sessions with wrong context --- rustls-libssl/src/cache.rs | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/rustls-libssl/src/cache.rs b/rustls-libssl/src/cache.rs index cf6f461..c88323a 100644 --- a/rustls-libssl/src/cache.rs +++ b/rustls-libssl/src/cache.rs @@ -232,6 +232,15 @@ impl ServerSessionStorage { Arc::new(SslSession::new(id, value, context, time_out)) } + /// Return `None` if `sess` has the wrong context value. + fn filter_session_context(&self, sess: Arc) -> Option> { + if self.get_context() != sess.context { + None + } else { + Some(sess) + } + } + fn insert(&self, new: Arc) -> bool { self.tick(); @@ -443,14 +452,21 @@ impl StoresServerSessions for SingleServerCache { } if self.parent.mode() & CACHE_MODE_NO_INTERNAL_LOOKUP == 0 { - let sess = self.parent.find_by_id(id); + let sess = self + .parent + .find_by_id(id) + .and_then(|sess| self.parent.filter_session_context(sess)); if let Some(sess) = sess { self.save_most_recent_session(sess.clone()); return Some(sess.value.clone()); } } - if let Some(sess) = self.parent.invoke_get_callback(id) { + if let Some(sess) = self + .parent + .invoke_get_callback(id) + .and_then(|sess| self.parent.filter_session_context(sess)) + { return Some(sess.value.clone()); } @@ -463,7 +479,10 @@ impl StoresServerSessions for SingleServerCache { } if self.parent.mode() & CACHE_MODE_NO_INTERNAL_LOOKUP == 0 { - let sess = self.parent.take(id); + let sess = self + .parent + .take(id) + .and_then(|sess| self.parent.filter_session_context(sess)); if let Some(sess) = sess { // inform external cache that this session is being consumed @@ -475,7 +494,11 @@ impl StoresServerSessions for SingleServerCache { } // look up in external cache - if let Some(sess) = self.parent.invoke_get_callback(id) { + if let Some(sess) = self + .parent + .invoke_get_callback(id) + .and_then(|sess| self.parent.filter_session_context(sess)) + { self.save_most_recent_session(sess.clone()); self.parent.invoke_remove_callback(sess.clone()); return Some(sess.value.clone()); @@ -610,4 +633,24 @@ mod tests { assert!(cache.find_by_id(&[5]).is_some()); assert!(cache.find_by_id(&[6]).is_some()); } + + #[test] + fn respects_context() { + let cache = ServerSessionStorage::new(5); + cache.set_context(b"hello"); + + assert!(cache + .insert(SslSession::new(vec![1], vec![], b"hello".to_vec(), ExpiryTime(10)).into())); + assert!(cache + .insert(SslSession::new(vec![2], vec![], b"goodbye".to_vec(), ExpiryTime(10)).into())); + + assert!(cache + .find_by_id(&[1]) + .and_then(|sess| cache.filter_session_context(sess)) + .is_some()); + assert!(cache + .find_by_id(&[2]) + .and_then(|sess| cache.filter_session_context(sess)) + .is_none()); + } }