Skip to content

Commit

Permalink
Bump dependencies, set rust-version
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Apr 12, 2023
1 parent d40e3ce commit 3e396f8
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 146 deletions.
64 changes: 33 additions & 31 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
[package]
name = "irc"
version = "0.15.0"
description = "the irc crate – usable, async IRC for Rust "
authors = ["Aaron Weiss <[email protected]>"]
edition = "2018"
rust-version = "1.60"
description = "the irc crate – usable, async IRC for Rust "
documentation = "https://docs.rs/irc/"
readme = "README.md"
repository = "https://github.com/aatxe/irc"
license = "MPL-2.0"
keywords = ["irc", "client", "thread-safe", "async", "tokio"]
categories = ["asynchronous", "network-programming"]
documentation = "https://docs.rs/irc/"
repository = "https://github.com/aatxe/irc"
readme = "README.md"
edition = "2018"


[badges]
Expand Down Expand Up @@ -37,46 +38,47 @@ yaml = ["yaml_config"]
proxy = ["tokio-socks"]

tls-native = ["native-tls", "tokio-native-tls"]
tls-rust = ["tokio-rustls", "webpki-roots"]
tls-rust = ["tokio-rustls", "webpki-roots", "rustls-pemfile"]


[dependencies]
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
encoding = "0.2.0"
futures-util = { version = "0.3.0", default-features = false, features = ["alloc", "sink"] }
chrono = { version = "0.4.24", default-features = false, features = ["clock", "std"] }
encoding = "0.2.33"
futures-util = { version = "0.3.28", default-features = false, features = ["alloc", "sink"] }
irc-proto = { version = "0.15.0", path = "irc-proto" }
log = "0.4.0"
parking_lot = "0.11.0"
thiserror = "1.0.0"
pin-project = "1.0.2"
tokio = { version = "1.0.0", features = ["net", "time", "sync"] }
tokio-stream = "0.1.0"
tokio-util = { version = "0.6.0", features = ["codec"] }
log = "0.4.17"
parking_lot = "0.12.1"
thiserror = "1.0.40"
pin-project = "1.0.12"
tokio = { version = "1.27.0", features = ["net", "time", "sync"] }
tokio-stream = "0.1.12"
tokio-util = { version = "0.7.7", features = ["codec"] }

# Feature - Config
serde = { version = "1.0.0", optional = true }
serde_derive = { version = "1.0.0", optional = true }
serde_json = { version = "1.0.0", optional = true }
serde_yaml = { version = "0.8.0", optional = true }
toml = { version = "0.5.0", optional = true }
serde = { version = "1.0.160", optional = true }
serde_derive = { version = "1.0.160", optional = true }
serde_json = { version = "1.0.95", optional = true }
serde_yaml = { version = "0.9.21", optional = true }
toml = { version = "0.7.3", optional = true }

# Feature - Proxy
tokio-socks = { version = "0.5.1", optional = true }

# Feature - TLS
native-tls = { version = "0.2.0", optional = true }
tokio-rustls = { version = "0.22.0", features = ["dangerous_configuration"], optional = true }
tokio-native-tls = { version = "0.3.0", optional = true }
webpki-roots = { version = "0.20.0", optional = true }
native-tls = { version = "0.2.11", optional = true }
tokio-rustls = { version = "0.24.0", features = ["dangerous_configuration"], optional = true }
rustls-pemfile = { version = "1.0.2", optional = true }
tokio-native-tls = { version = "0.3.1", optional = true }
webpki-roots = { version = "0.23.0", optional = true }


[dev-dependencies]
anyhow = "1.0.0"
args = "2.0.0"
env_logger = "0.7.0"
futures = "0.3.0"
getopts = "0.2.0"
tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros", "net", "time"] }
anyhow = "1.0.70"
args = "2.2.0"
env_logger = "0.10.0"
futures = "0.3.28"
getopts = "0.2.21"
tokio = { version = "1.27.0", features = ["rt", "rt-multi-thread", "macros", "net", "time"] }


[[example]]
Expand Down
19 changes: 10 additions & 9 deletions irc-proto/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
[package]
name = "irc-proto"
version = "0.15.0"
description = "The IRC protocol distilled."
authors = ["Aaron Weiss <[email protected]>"]
edition = "2018"
rust-version = "1.60"
description = "The IRC protocol distilled."
documentation = "https://docs.rs/irc-proto/"
repository = "https://github.com/aatxe/irc"
license = "MPL-2.0"
keywords = ["irc", "protocol", "tokio"]
categories = ["network-programming"]
documentation = "https://docs.rs/irc-proto/"
repository = "https://github.com/aatxe/irc"
edition = "2018"

[badges]
travis-ci = { repository = "aatxe/irc" }
Expand All @@ -17,9 +18,9 @@ travis-ci = { repository = "aatxe/irc" }
default = ["bytes", "tokio", "tokio-util"]

[dependencies]
encoding = "0.2.0"
thiserror = "1.0.0"
encoding = "0.2.33"
thiserror = "1.0.40"

bytes = { version = "1.0.0", optional = true }
tokio = { version = "1.0.0", optional = true }
tokio-util = { version = "0.6.0", features = ["codec"], optional = true }
bytes = { version = "1.4.0", optional = true }
tokio = { version = "1.27.0", optional = true }
tokio-util = { version = "0.7.7", features = ["codec"], optional = true }
6 changes: 2 additions & 4 deletions irc-proto/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,13 +550,11 @@ mod test {

#[test]
fn to_message_with_colon_in_suffix() {
let msg = "PRIVMSG #test ::test"
.parse::<Message>()
.unwrap();
let msg = "PRIVMSG #test ::test".parse::<Message>().unwrap();
let message = Message {
tags: None,
prefix: None,
command: PRIVMSG("#test".to_string(), ":test".to_string())
command: PRIVMSG("#test".to_string(), ":test".to_string()),
};
assert_eq!(msg, message);
}
Expand Down
157 changes: 99 additions & 58 deletions src/client/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,32 @@ use tokio_socks::tcp::Socks5Stream;
#[cfg(feature = "proxy")]
use crate::client::data::ProxyType;

#[cfg(feature = "tls-native")]
#[cfg(all(feature = "tls-native", not(feature = "tls-rust")))]
use std::{fs::File, io::Read};

#[cfg(feature = "tls-native")]
#[cfg(all(feature = "tls-native", not(feature = "tls-rust")))]
use native_tls::{Certificate, Identity, TlsConnector};

#[cfg(feature = "tls-native")]
#[cfg(all(feature = "tls-native", not(feature = "tls-rust")))]
use tokio_native_tls::{self, TlsStream};

#[cfg(feature = "tls-rust")]
use rustls_pemfile::certs;
#[cfg(feature = "tls-rust")]
use std::{
convert::TryFrom,
fs::File,
io::{BufReader, Error, ErrorKind},
sync::Arc,
};

#[cfg(feature = "tls-rust")]
use webpki_roots::TLS_SERVER_ROOTS;

use tokio_rustls::client::TlsStream;
#[cfg(feature = "tls-rust")]
use tokio_rustls::{
client::TlsStream,
rustls::{self, internal::pemfile::certs, ClientConfig, PrivateKey},
webpki::DNSNameRef,
rustls::client::{ServerCertVerified, ServerCertVerifier},
rustls::{
self, Certificate, ClientConfig, OwnedTrustAnchor, PrivateKey, RootCertStore, ServerName,
},
TlsConnector,
};

Expand Down Expand Up @@ -157,7 +159,7 @@ impl Connection {
Ok(Transport::new(&config, framed, tx))
}

#[cfg(feature = "tls-native")]
#[cfg(all(feature = "tls-native", not(feature = "tls-rust")))]
async fn new_secured_transport(
config: &Config,
tx: UnboundedSender<Message>,
Expand Down Expand Up @@ -221,44 +223,46 @@ impl Connection {
config: &Config,
tx: UnboundedSender<Message>,
) -> error::Result<Transport<TlsStream<TcpStream>>> {
let mut builder = ClientConfig::default();
builder
.root_store
.add_server_trust_anchors(&TLS_SERVER_ROOTS);

if let Some(cert_path) = config.cert_path() {
if let Ok(mut file) = File::open(cert_path) {
let mut cert_data = BufReader::new(file);
builder
.root_store
.add_pem_file(&mut cert_data)
.map_err(|_| {
error::Error::Io(Error::new(ErrorKind::InvalidInput, "invalid cert"))
})?;
log::info!("Added {} to trusted certificates.", cert_path);
} else {
return Err(error::Error::InvalidConfig {
path: config.path(),
cause: error::ConfigError::FileMissing {
file: cert_path.to_string(),
},
});
struct DangerousAcceptAllVerifier;

impl ServerCertVerifier for DangerousAcceptAllVerifier {
fn verify_server_cert(
&self,
_: &Certificate,
_: &[Certificate],
_: &ServerName,
_: &mut dyn Iterator<Item = &[u8]>,
_: &[u8],
_: std::time::SystemTime,
) -> Result<ServerCertVerified, rustls::Error> {
return Ok(ServerCertVerified::assertion());
}
}

if let Some(client_cert_path) = config.client_cert_path() {
if let Ok(mut file) = File::open(client_cert_path) {
enum ClientAuth {
SingleCert(Vec<Certificate>, PrivateKey),
NoClientAuth,
}

let client_auth = if let Some(client_cert_path) = config.client_cert_path() {
if let Ok(file) = File::open(client_cert_path) {
let client_cert_data = certs(&mut BufReader::new(file)).map_err(|_| {
error::Error::Io(Error::new(ErrorKind::InvalidInput, "invalid cert"))
})?;

let client_cert_data = client_cert_data
.into_iter()
.map(Certificate)
.collect::<Vec<_>>();

let client_cert_pass = PrivateKey(Vec::from(config.client_cert_pass()));
builder
.set_single_client_cert(client_cert_data, client_cert_pass)
.map_err(|err| error::Error::Io(Error::new(ErrorKind::InvalidInput, err)))?;

log::info!(
"Using {} for client certificate authentication.",
client_cert_path
);

ClientAuth::SingleCert(client_cert_data, client_cert_pass)
} else {
return Err(error::Error::InvalidConfig {
path: config.path(),
Expand All @@ -267,15 +271,68 @@ impl Connection {
},
});
}
} else {
ClientAuth::NoClientAuth
};

macro_rules! make_client_auth {
($builder:expr) => {
match client_auth {
ClientAuth::SingleCert(data, pass) => {
$builder.with_single_cert(data, pass).map_err(|err| {
error::Error::Io(Error::new(ErrorKind::InvalidInput, err))
})?
}
ClientAuth::NoClientAuth => $builder.with_no_client_auth(),
}
};
}

if config.dangerously_accept_invalid_certs() {
builder.dangerous().set_certificate_verifier(Arc::new(DangerousAcceptAllVerifier));
}
let builder = ClientConfig::builder()
.with_safe_default_cipher_suites()
.with_safe_default_kx_groups()
.with_safe_default_protocol_versions()?;

let tls_config = if config.dangerously_accept_invalid_certs() {
let builder =
builder.with_custom_certificate_verifier(Arc::new(DangerousAcceptAllVerifier));
make_client_auth!(builder)
} else {
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,
)
},
));

if let Some(cert_path) = config.cert_path() {
if let Ok(data) = std::fs::read(cert_path) {
root_store.add(&Certificate(data)).map_err(|_| {
error::Error::Io(Error::new(ErrorKind::InvalidInput, "invalid cert"))
})?;

let connector = TlsConnector::from(Arc::new(builder));
let domain = DNSNameRef::try_from_ascii_str(config.server()?)?;
log::info!("Added {} to trusted certificates.", cert_path);
} else {
return Err(error::Error::InvalidConfig {
path: config.path(),
cause: error::ConfigError::FileMissing {
file: cert_path.to_string(),
},
});
}
}

let builder = builder.with_root_certificates(root_store);
make_client_auth!(builder)
};

let connector = TlsConnector::from(Arc::new(tls_config));
let domain = ServerName::try_from(config.server()?)?;
let stream = Self::new_stream(config).await?;
let stream = connector.connect(domain, stream).await?;
let framed = Framed::new(stream, IrcCodec::new(config.encoding())?);
Expand Down Expand Up @@ -371,19 +428,3 @@ impl Sink<Message> for Connection {
}
}
}

#[cfg(feature = "tls-rust")]
struct DangerousAcceptAllVerifier;

#[cfg(feature = "tls-rust")]
impl rustls::ServerCertVerifier for DangerousAcceptAllVerifier {
fn verify_server_cert(
&self,
_: &rustls::RootCertStore,
_: &[rustls::Certificate],
_: DNSNameRef,
_: &[u8]
) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
return Ok(rustls::ServerCertVerified::assertion());
}
}
5 changes: 4 additions & 1 deletion src/client/data/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,10 @@ impl Config {
/// Gets whether or not to dangerously accept invalid certificates.
/// This defaults to `false` when not specified.
pub fn dangerously_accept_invalid_certs(&self) -> bool {
self.dangerously_accept_invalid_certs.as_ref().cloned().unwrap_or(false)
self.dangerously_accept_invalid_certs
.as_ref()
.cloned()
.unwrap_or(false)
}

/// Gets the path to the client authentication certificate in DER format if specified.
Expand Down
Loading

0 comments on commit 3e396f8

Please sign in to comment.