Skip to content

Commit

Permalink
Updated websocket for TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosskii authored and d-e-s-o committed Jul 18, 2023
1 parent cd89682 commit a6b27ef
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ include = ["src/**/*", "LICENSE", "README.*", "CHANGELOG.*"]
[features]
default = ["gzip", "native-tls"]
gzip = ["async-compression/futures-io", "async-compression/gzip"]
native-tls = ["tungstenite/native-tls", "dep:hyper-tls"]
rustls = ["dep:hyper-rustls", "websocket-util/rustls", "tungstenite/__rustls-tls"]
native-tls = ["tungstenite/native-tls", "dep:hyper-tls", "dep:native-tls"]
rustls = ["dep:hyper-rustls", "websocket-util/rustls", "tungstenite/__rustls-tls", "dep:rustls", "dep:webpki-roots"]
vendored-openssl = ["hyper-tls?/vendored", "native-tls", "tungstenite/native-tls-vendored"]

[dependencies]
Expand All @@ -38,7 +38,9 @@ http-endpoint = "0.5"
hyper = {version = "0.14", features = ["client", "http1", "stream"]}
hyper-tls = {version = "0.5", default-features = false, optional = true}
num-decimal = {version = "0.2.4", default-features = false, features = ["num-v04", "serde"]}
native-tls = {version = "0.2.11", optional = true}
hyper-rustls = {version = "0.24", optional = true}
rustls = {version = "0.21.1", optional = true}
serde = {version = "1.0.103", features = ["derive"]}
serde_json = {version = "1.0", default-features = false, features = ["std"]}
serde_urlencoded = {version = "0.7", default-features = false}
Expand All @@ -51,6 +53,7 @@ tungstenite = {package = "tokio-tungstenite", version = "0.19", features = ["con
url = "2.0"
uuid = {version = "1.0", default-features = false, features = ["serde"]}
websocket-util = "0.11.0"
webpki-roots = {version = "0.23.1", optional = true}

[dev-dependencies]
serial_test = {version = "0.8.0", default-features = false}
Expand Down
49 changes: 48 additions & 1 deletion src/websocket.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (C) 2019-2023 The apca Developers
// SPDX-License-Identifier: GPL-3.0-or-later

use tungstenite::connect_async_tls_with_config;
use url::Url;

use tokio::net::TcpStream;
Expand Down Expand Up @@ -49,10 +50,56 @@ async fn connect_internal(url: &Url) -> Result<WebSocketStream<MaybeTlsStream<Tc
async move {
debug!(message = "connecting", url = display(url));

// Get a TLS connector depending on the feature settings.
#[cfg(feature = "native-tls")]
let connector = {
use native_tls::TlsConnector;

// TODO: This is a bit of a hack. We should probably be using
// a custom error message. This may be a breaking change though,
// so we'll leave it for now.
let connector = TlsConnector::new()
.map_err(|e| Error::Str("Failed to create TLS connector".into()))?;

tungstenite::Connector::NativeTls(connector)
};

#[cfg(feature = "rustls")]
let connector = {
use rustls::ClientConfig;
use rustls::RootCertStore;
use std::sync::Arc;

let mut root_store = RootCertStore::empty();
root_store.add_server_trust_anchors(
webpki_roots::TLS_SERVER_ROOTS
.0
.iter()
.map(|ta| rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
))
);

let client = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();

tungstenite::Connector::Rustls(Arc::new(client))
};

// We just ignore the response & headers that are sent along after
// the connection is made. Alpaca does not seem to be using them,
// really.
let (stream, response) = connect_async(url).await?;
let (stream, response) = connect_async_tls_with_config(
url,
None,
false,
Some(connector)
).await?;

debug!("connection successful");
trace!(response = debug(&response));

Expand Down

0 comments on commit a6b27ef

Please sign in to comment.