Loading src/ssl/ffi.rs +23 −8 Original line number Diff line number Diff line #[doc(hidden)]; use std::libc::{c_int, c_void}; pub type SSL_CTX = c_void; pub type SSL_METHOD = c_void; pub type SSL = c_void; pub type BIO = c_void; pub type BIO_METHOD = c_void; #[link_args = "-lssl"] extern "C" { fn SSL_library_init() -> c_int; fn SSL_load_error_strings(); fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX; fn SSLv23_method() -> *SSL_METHOD; fn SSL_CTX_free(ctx: *SSL_CTX); } extern "C" { } externfn!(fn SSL_library_init() -> c_int) externfn!(fn SSL_load_error_strings()) externfn!(fn SSLv23_method() -> *SSL_METHOD) externfn!(fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX) externfn!(fn SSL_CTX_free(ctx: *SSL_CTX)) externfn!(fn SSL_new(ctx: *SSL_CTX) -> *SSL) externfn!(fn SSL_free(ssl: *SSL)) externfn!(fn SSL_set_bio(ssl: *SSL, rbio: *BIO, wbio: *BIO)) externfn!(fn SSL_set_connect_state(ssl: *SSL)) externfn!(fn SSL_do_handshake(ssl: *SSL)) externfn!(fn BIO_s_mem() -> *BIO_METHOD) externfn!(fn BIO_new(type_: *BIO_METHOD) -> *BIO) externfn!(fn BIO_free(a: *BIO) -> c_int) src/ssl/lib.rs +97 −5 Original line number Diff line number Diff line use std::rt::io::{Stream, Decorator}; use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release}; use std::task; use std::ptr; mod ffi; static mut STARTED_INIT: AtomicBool = INIT_ATOMIC_BOOL; static mut FINISHED_INIT: AtomicBool = INIT_ATOMIC_BOOL; #[fixed_stack_segment] pub fn init() { unsafe { if STARTED_INIT.swap(true, Acquire) { Loading @@ -27,7 +28,6 @@ pub enum SslMethod { } impl SslMethod { #[fixed_stack_segment] unsafe fn to_raw(&self) -> *ffi::SSL_METHOD { match *self { Sslv23 => ffi::SSLv23_method() Loading @@ -40,18 +40,110 @@ pub struct SslCtx { } impl Drop for SslCtx { #[fixed_stack_segment] fn drop(&mut self) { unsafe { ffi::SSL_CTX_free(self.ctx); } } } impl SslCtx { #[fixed_stack_segment] pub fn new(method: SslMethod) -> SslCtx { init(); let ctx = unsafe { ffi::SSL_CTX_new(method.to_raw()) }; assert!(ctx != ptr::null()); SslCtx { ctx: unsafe { ffi::SSL_CTX_new(method.to_raw()) } ctx: ctx } } } struct Ssl { ssl: *ffi::SSL } impl Drop for Ssl { fn drop(&mut self) { unsafe { ffi::SSL_free(self.ssl); } } } impl Ssl { fn new(ctx: &SslCtx) -> Ssl { let ssl = unsafe { ffi::SSL_new(ctx.ctx) }; assert!(ssl != ptr::null()); Ssl { ssl: ssl } } fn set_bio(&self, rbio: &MemBio, wbio: &MemBio) { unsafe { ffi::SSL_set_bio(self.ssl, rbio.bio, wbio.bio); } } fn set_connect_state(&self) { unsafe { ffi::SSL_set_connect_state(self.ssl); } } } struct MemBio { bio: *ffi::BIO } impl Drop for MemBio { fn drop(&mut self) { unsafe { ffi::BIO_free(self.bio); } } } impl MemBio { fn new() -> MemBio { let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; assert!(bio != ptr::null()); MemBio { bio: bio } } } pub struct SslStream<S> { priv ctx: SslCtx, priv ssl: Ssl, priv rbio: MemBio, priv wbio: MemBio, priv stream: S } impl<S: Stream> SslStream<S> { pub fn new(ctx: SslCtx, stream: S) -> SslStream<S> { let ssl = Ssl::new(&ctx); let rbio = MemBio::new(); let wbio = MemBio::new(); ssl.set_bio(&rbio, &wbio); ssl.set_connect_state(); let stream = SslStream { ctx: ctx, ssl: ssl, rbio: rbio, wbio: wbio, stream: stream } stream } } impl<S: Stream> Decorator<S> for SslStream<S> { fn inner(self) -> S { self.stream } fn inner_ref<'a>(&'a self) -> &'a S { &self.stream } fn inner_mut_ref<'a>(&'a mut self) -> &'a mut S { &mut self.stream } } src/ssl/test.rs +9 −1 Original line number Diff line number Diff line extern mod ssl; use ssl::{Sslv23, SslCtx}; use std::rt::io::net::tcp::TcpStream; use ssl::{Sslv23, SslCtx, SslStream}; #[test] fn test_new_ctx() { SslCtx::new(Sslv23); } #[test] fn test_new_sslstream() { let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()); let stream = SslStream::new(SslCtx::new(Sslv23), stream); } Loading
src/ssl/ffi.rs +23 −8 Original line number Diff line number Diff line #[doc(hidden)]; use std::libc::{c_int, c_void}; pub type SSL_CTX = c_void; pub type SSL_METHOD = c_void; pub type SSL = c_void; pub type BIO = c_void; pub type BIO_METHOD = c_void; #[link_args = "-lssl"] extern "C" { fn SSL_library_init() -> c_int; fn SSL_load_error_strings(); fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX; fn SSLv23_method() -> *SSL_METHOD; fn SSL_CTX_free(ctx: *SSL_CTX); } extern "C" { } externfn!(fn SSL_library_init() -> c_int) externfn!(fn SSL_load_error_strings()) externfn!(fn SSLv23_method() -> *SSL_METHOD) externfn!(fn SSL_CTX_new(method: *SSL_METHOD) -> *SSL_CTX) externfn!(fn SSL_CTX_free(ctx: *SSL_CTX)) externfn!(fn SSL_new(ctx: *SSL_CTX) -> *SSL) externfn!(fn SSL_free(ssl: *SSL)) externfn!(fn SSL_set_bio(ssl: *SSL, rbio: *BIO, wbio: *BIO)) externfn!(fn SSL_set_connect_state(ssl: *SSL)) externfn!(fn SSL_do_handshake(ssl: *SSL)) externfn!(fn BIO_s_mem() -> *BIO_METHOD) externfn!(fn BIO_new(type_: *BIO_METHOD) -> *BIO) externfn!(fn BIO_free(a: *BIO) -> c_int)
src/ssl/lib.rs +97 −5 Original line number Diff line number Diff line use std::rt::io::{Stream, Decorator}; use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release}; use std::task; use std::ptr; mod ffi; static mut STARTED_INIT: AtomicBool = INIT_ATOMIC_BOOL; static mut FINISHED_INIT: AtomicBool = INIT_ATOMIC_BOOL; #[fixed_stack_segment] pub fn init() { unsafe { if STARTED_INIT.swap(true, Acquire) { Loading @@ -27,7 +28,6 @@ pub enum SslMethod { } impl SslMethod { #[fixed_stack_segment] unsafe fn to_raw(&self) -> *ffi::SSL_METHOD { match *self { Sslv23 => ffi::SSLv23_method() Loading @@ -40,18 +40,110 @@ pub struct SslCtx { } impl Drop for SslCtx { #[fixed_stack_segment] fn drop(&mut self) { unsafe { ffi::SSL_CTX_free(self.ctx); } } } impl SslCtx { #[fixed_stack_segment] pub fn new(method: SslMethod) -> SslCtx { init(); let ctx = unsafe { ffi::SSL_CTX_new(method.to_raw()) }; assert!(ctx != ptr::null()); SslCtx { ctx: unsafe { ffi::SSL_CTX_new(method.to_raw()) } ctx: ctx } } } struct Ssl { ssl: *ffi::SSL } impl Drop for Ssl { fn drop(&mut self) { unsafe { ffi::SSL_free(self.ssl); } } } impl Ssl { fn new(ctx: &SslCtx) -> Ssl { let ssl = unsafe { ffi::SSL_new(ctx.ctx) }; assert!(ssl != ptr::null()); Ssl { ssl: ssl } } fn set_bio(&self, rbio: &MemBio, wbio: &MemBio) { unsafe { ffi::SSL_set_bio(self.ssl, rbio.bio, wbio.bio); } } fn set_connect_state(&self) { unsafe { ffi::SSL_set_connect_state(self.ssl); } } } struct MemBio { bio: *ffi::BIO } impl Drop for MemBio { fn drop(&mut self) { unsafe { ffi::BIO_free(self.bio); } } } impl MemBio { fn new() -> MemBio { let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; assert!(bio != ptr::null()); MemBio { bio: bio } } } pub struct SslStream<S> { priv ctx: SslCtx, priv ssl: Ssl, priv rbio: MemBio, priv wbio: MemBio, priv stream: S } impl<S: Stream> SslStream<S> { pub fn new(ctx: SslCtx, stream: S) -> SslStream<S> { let ssl = Ssl::new(&ctx); let rbio = MemBio::new(); let wbio = MemBio::new(); ssl.set_bio(&rbio, &wbio); ssl.set_connect_state(); let stream = SslStream { ctx: ctx, ssl: ssl, rbio: rbio, wbio: wbio, stream: stream } stream } } impl<S: Stream> Decorator<S> for SslStream<S> { fn inner(self) -> S { self.stream } fn inner_ref<'a>(&'a self) -> &'a S { &self.stream } fn inner_mut_ref<'a>(&'a mut self) -> &'a mut S { &mut self.stream } }
src/ssl/test.rs +9 −1 Original line number Diff line number Diff line extern mod ssl; use ssl::{Sslv23, SslCtx}; use std::rt::io::net::tcp::TcpStream; use ssl::{Sslv23, SslCtx, SslStream}; #[test] fn test_new_ctx() { SslCtx::new(Sslv23); } #[test] fn test_new_sslstream() { let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()); let stream = SslStream::new(SslCtx::new(Sslv23), stream); }