upgrade to rustls

This commit is contained in:
Daniella / Tove 2022-10-27 09:32:39 +02:00
parent 00421ef00d
commit de421e9688
4 changed files with 53 additions and 96 deletions

63
Cargo.lock generated
View file

@ -389,21 +389,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form-data-builder"
version = "1.0.1"
@ -919,45 +904,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-sys"
version = "0.9.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "ordered-float"
version = "2.10.0"
@ -1111,11 +1057,12 @@ version = "0.1.0"
dependencies = [
"form-data-builder",
"gif",
"openssl",
"png",
"rustls",
"serenity",
"songbird",
"tokio",
"webpki-roots",
]
[[package]]
@ -1910,12 +1857,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"

View file

@ -9,7 +9,8 @@ edition = "2021"
tokio = {version="1.21.2", features=["full"]}
serenity = {version="0.11.5", features=["builder", "cache", "client", "framework", "gateway", "http", "model", "standard_framework", "utils", "rustls_backend", "voice"]}
songbird = {version="0.3.0", features=["driver", "serenity-rustls"]}
openssl = "0.10.42"
form-data-builder = "1.0.1"
png = "0.17.6"
gif = "0.11.4"
rustls = "0.20"
form-data-builder = "1.0"
png = "0.17"
gif = "0.11"
webpki-roots = "0.22"

View file

@ -1,16 +1,17 @@
use form_data_builder::FormData;
use openssl::ssl::{Ssl, SslContext, SslMethod, SslStream};
use rustls::{OwnedTrustAnchor, RootCertStore, ClientConfig, ClientConnection, Stream};
use std::{
ffi::OsStr,
io::{Cursor, Read, Write},
net::{Shutdown, TcpStream},
time::Duration,
time::Duration, sync::Arc,
};
pub struct Frame {
pub bytes: Vec<u8>,
pub channel: u64,
cache_stream: Option<SslStream<TcpStream>>,
tcp_stream: Option<TcpStream>,
cache_stream: Option<ClientConnection>,
byte_to_write: Option<u8>,
}
@ -19,18 +20,28 @@ impl Frame {
Frame {
bytes,
channel,
tcp_stream: None,
cache_stream: None,
byte_to_write: None,
}
}
pub fn cache_frame(&mut self, message: u64, content: &str, token: &str) {
let ssl_context = SslContext::builder(SslMethod::tls_client())
.expect("ssl: context init failed")
.build();
let ssl = Ssl::new(&ssl_context).expect("ssl: init failed");
let tcp_stream = TcpStream::connect("discord.com:443").expect("api: connect error");
let mut stream = SslStream::new(ssl, tcp_stream).expect("ssl: stream init failed");
let mut root_store = RootCertStore::empty();
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
}));
let client_config = Arc::new(ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth());
let mut tcp_stream = TcpStream::connect("discord.com:443").expect("api: connect error");
let mut connection = ClientConnection::new(client_config, "discord.com".try_into().unwrap()).expect("ssl: context init failed");
let mut stream: Stream<ClientConnection, TcpStream> = Stream::new(&mut connection, &mut tcp_stream);
let mut form = FormData::new(Vec::new());
@ -61,7 +72,6 @@ impl Frame {
.expect("form: attachment failed");
let mut data = form.finish().expect("form: finish failed");
stream.connect().expect("api: connection failed");
stream
.write_all(
format!(
@ -100,33 +110,38 @@ impl Frame {
.expect("api: write failed");
stream.flush().expect("api: flush failed");
self.cache_stream = Some(stream);
self.cache_stream = Some(connection);
self.tcp_stream = Some(tcp_stream);
// now the frame is ready to send the next part
}
pub fn complete_send(&mut self) {
let cache_stream = &mut self.cache_stream;
let byte_to_write = &self.byte_to_write;
if let Some(stream) = cache_stream {
let tcp_stream = &mut self.tcp_stream;
if let Some(connection) = cache_stream {
if let Some(byte) = byte_to_write {
stream
.write_all(&[*byte])
.expect("api: write failed at complete_send");
stream.flush().expect("api: flush failed");
stream
.get_ref()
.set_read_timeout(Some(Duration::from_millis(500)))
.expect("tcp: unable to set timeout");
let mut buf = Vec::new();
let _ = stream.read_to_end(&mut buf); // failure is normal
stream.shutdown().expect("ssl: shutdown failed");
stream
.get_ref()
.shutdown(Shutdown::Both)
.expect("tcp: shutdown failed");
self.cache_stream = None;
self.byte_to_write = None;
return;
if let Some(tcp_stream) = tcp_stream {
let mut stream: Stream<ClientConnection, TcpStream> = Stream::new(connection, tcp_stream);
stream
.write_all(&[*byte])
.expect("api: write failed at complete_send");
stream.flush().expect("api: flush failed");
stream.sock
.set_read_timeout(Some(Duration::from_millis(500)))
.expect("tcp: unable to set timeout");
let mut buf = Vec::new();
let _ = stream.read_to_end(&mut buf); // failure is normal
stream.conn.send_close_notify();
stream.conn.write_tls(stream.sock).expect("ssl: unable to close connection");
stream.sock.flush().expect("ssl: unable to flush");
stream.sock
.shutdown(Shutdown::Both)
.expect("tcp: shutdown failed");
self.cache_stream = None;
self.byte_to_write = None;
return;
}
}
}
panic!("complete_send called on uncached frame!");

View file

@ -98,7 +98,7 @@ async fn send_video(message: Message, ctx: Context) {
+ (api_time as i64
* str::parse::<i64>(
env::var("PROJBOTV3_API_TIME_FACTOR")
.unwrap_or_else(|_| "3".into())
.unwrap_or_else(|_| "5".into())
.as_str(),
)
.unwrap()) as u64,