Skip to content

Commit b1faa18

Browse files
committed
Add an SChannel TlsStream implementation
Closes sfackler#214
1 parent 2e5e99f commit b1faa18

File tree

4 files changed

+60
-5
lines changed

4 files changed

+60
-5
lines changed

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ with-eui48 = ["eui48"]
2727
with-openssl = ["openssl"]
2828
with-native-tls = ["native-tls"]
2929
with-rustc-serialize = ["rustc-serialize"]
30+
with-schannel = ["schannel"]
3031
with-security-framework = ["security-framework"]
3132
with-serde_json = ["serde_json"]
3233
with-time = ["time"]
@@ -47,6 +48,7 @@ eui48 = { version = "0.1", optional = true }
4748
openssl = { version = "0.9", optional = true }
4849
native-tls = { version = "0.1", optional = true }
4950
rustc-serialize = { version = "0.3", optional = true }
51+
schannel = { version = "0.1", optional = true }
5052
security-framework = { version = "0.1.2", optional = true }
5153
serde_json = { version = ">= 0.6, < 0.9", optional = true }
5254
time = { version = "0.1.14", optional = true }

src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
//!
4444
//! This crate supports TLS secured connections. The `TlsMode` enum is passed to connection methods
4545
//! and indicates if the connection will not, may, or must be secured by TLS. The TLS implementation
46-
//! is pluggable through the `TlsHandshake` trait. Implementations for OpenSSL and OSX's Secure
47-
//! Transport are provided behind the `with-openssl`, `with-security-framework`, and
48-
//! `with-native-tls` feature flags respectively.
46+
//! is pluggable through the `TlsHandshake` trait. Implementations for OpenSSL, Secure Transport,
47+
//! SChannel, and the `native-tls` crate are provided behind the `with-openssl`,
48+
//! `with-security-framework`, `with-schannel`, and `with-native-tls` feature flags respectively.
4949
//!
5050
//! ## Examples
5151
//!

src/tls/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ use std::error::Error;
55
use std::io::prelude::*;
66
use std::fmt;
77

8+
#[cfg(feature = "with-native-tls")]
9+
pub mod native_tls;
810
#[cfg(feature = "with-openssl")]
911
pub mod openssl;
12+
#[cfg(feature = "with-schannel")]
13+
pub mod schannel;
1014
#[cfg(feature = "with-security-framework")]
1115
pub mod security_framework;
12-
#[cfg(feature = "with-native-tls")]
13-
pub mod native_tls;
1416

1517
/// A trait implemented by TLS streams.
1618
pub trait TlsStream: fmt::Debug + Read + Write + Send {

src/tls/schannel.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//! SChannel support.
2+
3+
extern crate schannel;
4+
5+
use std::error::Error;
6+
use std::fmt;
7+
8+
use self::schannel::schannel_cred::{SchannelCred, Direction};
9+
use self::schannel::tls_stream;
10+
use tls::{TlsStream, Stream, TlsHandshake};
11+
12+
impl TlsStream for tls_stream::TlsStream<Stream> {
13+
fn get_ref(&self) -> &Stream {
14+
self.get_ref()
15+
}
16+
17+
fn get_mut(&mut self) -> &mut Stream {
18+
self.get_mut()
19+
}
20+
}
21+
22+
/// A `TlsHandshake` implementation that uses the `schannel` crate.
23+
///
24+
/// Requires the `with-schannel` feature.
25+
pub struct Schannel(());
26+
27+
impl fmt::Debug for Schannel {
28+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
29+
fmt.debug_struct("Schannel").finish()
30+
}
31+
}
32+
33+
impl Schannel {
34+
/// Constructs a new `SChannel` with a default configuration.
35+
pub fn new() -> Schannel {
36+
Schannel(())
37+
}
38+
}
39+
40+
impl TlsHandshake for Schannel {
41+
fn tls_handshake(&self,
42+
host: &str,
43+
stream: Stream)
44+
-> Result<Box<TlsStream>, Box<Error + Sync + Send>> {
45+
let creds = try!(SchannelCred::builder().acquire(Direction::Outbound));
46+
let stream = try!(tls_stream::Builder::new()
47+
.domain(host)
48+
.connect(creds, stream));
49+
Ok(Box::new(stream))
50+
}
51+
}

0 commit comments

Comments
 (0)