Skip to content

Commit

Permalink
Added CastDevice::connect_without_host_verification to avoid issues w…
Browse files Browse the repository at this point in the history
…ith Chromecast self signed certificate.
  • Loading branch information
azasypkin committed Mar 8, 2017
1 parent 1acfb65 commit 0e472a3
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repository = "https://github.com/azasypkin/rust-cast"
readme = "README.md"
license = "MIT"
keywords = ["cast", "chromecast", "google"]
version = "0.8.2"
version = "0.9.0"
authors = ["Aleh Zasypkin <[email protected]>"]
exclude = ["protobuf/*"]
build = "build.rs"
Expand Down
90 changes: 73 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::borrow::Cow;
use std::net::TcpStream;
use std::rc::Rc;

use openssl::ssl::{SslConnectorBuilder, SslStream, SslMethod};
use openssl::ssl::{SslConnectorBuilder, SslStream, SslMethod, SSL_VERIFY_NONE};

use channels::heartbeat::{HeartbeatChannel, HeartbeatResponse};
use channels::connection::{ConnectionChannel, ConnectionResponse};
Expand Down Expand Up @@ -94,28 +94,56 @@ impl<'a> CastDevice<'a> {

let connector = try!(SslConnectorBuilder::new(SslMethod::tls())).build();
let tcp_stream = try!(TcpStream::connect((host.as_ref(), port)));
let ssl_stream = try!(connector.connect(host.as_ref(), tcp_stream));

debug!("Connection with {}:{} successfully established.", host, port);
CastDevice::connect_to_device(try!(connector.connect(host.as_ref(), tcp_stream)))
}

let message_manager_rc = Rc::new(MessageManager::new(ssl_stream));
/// Connects to the cast device using host name and port _without_ host verification. Use on
/// your own risk!
///
/// # Examples
///
/// ```
/// let device = try!(CastDevice::connect_without_host_verification(
/// args.flag_address.unwrap(), args.flag_port));
/// ```
///
/// # Arguments
///
/// * `host` - Cast device host name.
/// * `port` - Cast device port number.
///
/// # Errors
///
/// This method may fail if connection to Cast device can't be established for some reason
/// (e.g. wrong host name or port).
///
/// # Return value
///
/// Instance of `CastDevice` that allows you to manage connection.
pub fn connect_without_host_verification<S>(host: S, port: u16)
-> Result<CastDevice<'a>, Error> where S: Into<Cow<'a, str>> {
let host = host.into();

let heartbeat = HeartbeatChannel::new(DEFAULT_SENDER_ID, DEFAULT_RECEIVER_ID,
message_manager_rc.clone());
let connection = ConnectionChannel::new(DEFAULT_SENDER_ID, message_manager_rc.clone());
let receiver = ReceiverChannel::new(DEFAULT_SENDER_ID, DEFAULT_RECEIVER_ID,
message_manager_rc.clone());
let media = MediaChannel::new(DEFAULT_SENDER_ID, message_manager_rc.clone());
debug!("Establishing non-verified connection with cast device at {}:{}...", host, port);

Ok(CastDevice {
message_manager: message_manager_rc,
heartbeat: heartbeat,
connection: connection,
receiver: receiver,
media: media,
})
let mut builder = try!(SslConnectorBuilder::new(SslMethod::tls()));

{
let mut ctx_builder = builder.builder_mut();
ctx_builder.set_verify(SSL_VERIFY_NONE);
}

let connector = builder.build();
let tcp_stream = try!(TcpStream::connect((host.as_ref(), port)));

debug!("Connection with {}:{} successfully established.", host, port);

CastDevice::connect_to_device(
try!(connector.danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication(tcp_stream)))
}


/// Waits for any message returned by cast device (e.g. Chromecast) and returns its parsed
/// version.
///
Expand Down Expand Up @@ -158,4 +186,32 @@ impl<'a> CastDevice<'a> {

Ok(ChannelMessage::Raw(cast_message))
}

/// Connects to the cast device using provided ssl stream.
///
/// # Arguments
///
/// * `ssl_stream` - SSL Stream for the TCP connection established with the device.
///
/// # Return value
///
/// Instance of `CastDevice` that allows you to manage connection.
fn connect_to_device(ssl_stream: SslStream<TcpStream>) -> Result<CastDevice<'a>, Error> {
let message_manager_rc = Rc::new(MessageManager::new(ssl_stream));

let heartbeat = HeartbeatChannel::new(DEFAULT_SENDER_ID, DEFAULT_RECEIVER_ID,
message_manager_rc.clone());
let connection = ConnectionChannel::new(DEFAULT_SENDER_ID, message_manager_rc.clone());
let receiver = ReceiverChannel::new(DEFAULT_SENDER_ID, DEFAULT_RECEIVER_ID,
message_manager_rc.clone());
let media = MediaChannel::new(DEFAULT_SENDER_ID, message_manager_rc.clone());

Ok(CastDevice {
message_manager: message_manager_rc,
heartbeat: heartbeat,
connection: connection,
receiver: receiver,
media: media,
})
}
}

0 comments on commit 0e472a3

Please sign in to comment.