diff options
| author | Steven Fackler <[email protected]> | 2018-02-16 22:37:14 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2018-02-16 22:37:14 -0800 |
| commit | b1e7bf4d54365bd53a19992f4089153b0d3b76a8 (patch) | |
| tree | fcc78f8952afb73d53450ae62ae3c5142428785b /openssl/src | |
| parent | Merge pull request #842 from nyradr/Documentation_fix_openssl_symm (diff) | |
| parent | Fix libressl (diff) | |
| download | rust-openssl-b1e7bf4d54365bd53a19992f4089153b0d3b76a8.tar.xz rust-openssl-b1e7bf4d54365bd53a19992f4089153b0d3b76a8.zip | |
Merge pull request #843 from sfackler/session-callback-2
Session callback 2
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/ssl/callbacks.rs | 54 | ||||
| -rw-r--r-- | openssl/src/ssl/mod.rs | 55 | ||||
| -rw-r--r-- | openssl/src/ssl/test.rs | 5 |
3 files changed, 102 insertions, 12 deletions
diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index 0a38952b..0e7299e3 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -5,7 +5,6 @@ use std::ptr; use std::slice; use std::mem; use foreign_types::ForeignTypeRef; -#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] use foreign_types::ForeignType; use error::ErrorStack; @@ -13,12 +12,11 @@ use dh::Dh; #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] use ec::EcKey; use pkey::Params; -use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslAlert, SslRef}; +use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslAlert, SslContextRef, SslRef, + SslSession, SslSessionRef}; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] use ssl::AlpnError; -#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] -use ssl::SslSession; use x509::X509StoreContextRef; pub extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int @@ -279,7 +277,6 @@ where } } -#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] pub unsafe extern "C" fn raw_new_session<F>( ssl: *mut ffi::SSL, session: *mut ffi::SSL_SESSION, @@ -299,3 +296,50 @@ where // the return code doesn't indicate error vs success, but whether or not we consumed the session 1 } + +pub unsafe extern "C" fn raw_remove_session<F>( + ctx: *mut ffi::SSL_CTX, + session: *mut ffi::SSL_SESSION, +) where + F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, +{ + let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>()); + let callback = &*(callback as *mut F); + + let ctx = SslContextRef::from_ptr(ctx); + let session = SslSessionRef::from_ptr(session); + + callback(ctx, session) +} + +#[cfg(any(ossl110, ossl111))] +type DataPtr = *const c_uchar; +#[cfg(not(any(ossl110, ossl111)))] +type DataPtr = *mut c_uchar; + +pub unsafe extern "C" fn raw_get_session<F>( + ssl: *mut ffi::SSL, + data: DataPtr, + len: c_int, + copy: *mut c_int, +) -> *mut ffi::SSL_SESSION +where + F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send, +{ + let ctx = ffi::SSL_get_SSL_CTX(ssl as *const _); + let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>()); + let callback = &*(callback as *mut F); + + let ssl = SslRef::from_ptr_mut(ssl); + let data = slice::from_raw_parts(data as *const u8, len as usize); + + match callback(ssl, data) { + Some(session) => { + let p = session.as_ptr(); + mem::forget(p); + *copy = 0; + p + } + None => ptr::null_mut(), + } +} diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index a589d6a3..98d982bb 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1177,12 +1177,9 @@ impl SslContextBuilder { /// /// This corresponds to [`SSL_CTX_sess_set_new_cb`]. /// - /// Requires OpenSSL 1.1.0 or 1.1.1 and the corresponding Cargo feature. - /// /// [`SslRef::session`]: struct.SslRef.html#method.session /// [`set_session_cache_mode`]: #method.set_session_cache_mode /// [`SSL_CTX_sess_set_new_cb`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html - #[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] pub fn set_new_session_callback<F>(&mut self, callback: F) where F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, @@ -1198,6 +1195,58 @@ impl SslContextBuilder { } } + /// Sets the callback which is called when sessions are removed from the context. + /// + /// Sessions can be removed because they have timed out or because they are considered faulty. + /// + /// This corresponds to [`SSL_CTX_sess_set_remove_cb`]. + /// + /// [`SSL_CTX_sess_set_remove_cb`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html + pub fn set_remove_session_callback<F>(&mut self, callback: F) + where + F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, + { + unsafe { + let callback = Box::new(callback); + ffi::SSL_CTX_set_ex_data( + self.as_ptr(), + get_callback_idx::<F>(), + Box::into_raw(callback) as *mut _, + ); + ffi::SSL_CTX_sess_set_remove_cb( + self.as_ptr(), + Some(callbacks::raw_remove_session::<F>), + ); + } + } + + /// Sets the callback which is called when a client proposed to resume a session but it was not + /// found in the internal cache. + /// + /// The callback is passed a reference to the session ID provided by the client. It should + /// return the session corresponding to that ID if available. This is only used for servers, not + /// clients. + /// + /// This corresponds to [`SSL_CTX_sess_set_get_cb`]. + /// + /// # Safety + /// + /// The returned `SslSession` must not be associated with a different `SslContext`. + /// + /// [`SSL_CTX_sess_set_get_cb`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html + pub unsafe fn set_get_session_callback<F>(&mut self, callback: F) + where + F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send, + { + let callback = Box::new(callback); + ffi::SSL_CTX_set_ex_data( + self.as_ptr(), + get_callback_idx::<F>(), + Box::into_raw(callback) as *mut _, + ); + ffi::SSL_CTX_sess_set_get_cb(self.as_ptr(), Some(callbacks::raw_get_session::<F>)); + } + /// Sets the session caching mode use for connections made with the context. /// /// Returns the previous session caching mode. diff --git a/openssl/src/ssl/test.rs b/openssl/src/ssl/test.rs index 17bc37d9..1913d835 100644 --- a/openssl/src/ssl/test.rs +++ b/openssl/src/ssl/test.rs @@ -19,9 +19,7 @@ use hash::MessageDigest; use ocsp::{OcspResponse, OcspResponseStatus}; use ssl; use ssl::{Error, HandshakeError, ShutdownResult, Ssl, SslAcceptor, SslConnector, SslContext, - SslFiletype, SslMethod, SslStream, SslVerifyMode, StatusType}; -#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] -use ssl::SslSessionCacheMode; + SslFiletype, SslMethod, SslSessionCacheMode, SslStream, SslVerifyMode, StatusType}; use x509::{X509, X509Name, X509StoreContext, X509VerifyResult}; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] @@ -1248,7 +1246,6 @@ fn status_callbacks() { } #[test] -#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] fn new_session_callback() { static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; |