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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 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]] [[package]]
name = "form-data-builder" name = "form-data-builder"
version = "1.0.1" version = "1.0.1"
@ -919,45 +904,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 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]] [[package]]
name = "ordered-float" name = "ordered-float"
version = "2.10.0" version = "2.10.0"
@ -1111,11 +1057,12 @@ version = "0.1.0"
dependencies = [ dependencies = [
"form-data-builder", "form-data-builder",
"gif", "gif",
"openssl",
"png", "png",
"rustls",
"serenity", "serenity",
"songbird", "songbird",
"tokio", "tokio",
"webpki-roots",
] ]
[[package]] [[package]]
@ -1910,12 +1857,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"

View file

@ -9,7 +9,8 @@ edition = "2021"
tokio = {version="1.21.2", features=["full"]} 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"]} 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"]} songbird = {version="0.3.0", features=["driver", "serenity-rustls"]}
openssl = "0.10.42" rustls = "0.20"
form-data-builder = "1.0.1" form-data-builder = "1.0"
png = "0.17.6" png = "0.17"
gif = "0.11.4" gif = "0.11"
webpki-roots = "0.22"

View file

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