mirror of
https://github.com/aramperes/nut-rs.git
synced 2025-09-09 13:38:30 -04:00
Clippy. Re-add blocking SSL config
This commit is contained in:
parent
ff03f27b49
commit
07034d2cec
3 changed files with 53 additions and 21 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::blocking::stream::ConnectionStream;
|
use crate::blocking::stream::ConnectionStream;
|
||||||
use crate::proto::{ClientSentences, Sentence, ServerSentences};
|
use crate::proto::{ClientSentences, Sentence, ServerSentences};
|
||||||
use crate::{Config, Host, TcpHost};
|
use crate::{Config, Error, Host, NutError, TcpHost};
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
|
||||||
/// A synchronous NUT client.
|
/// A synchronous NUT client.
|
||||||
|
@ -45,13 +45,46 @@ impl Client {
|
||||||
// Expect the OK
|
// Expect the OK
|
||||||
self.stream
|
self.stream
|
||||||
.read_sentence::<ClientSentences>()?
|
.read_sentence::<ClientSentences>()?
|
||||||
.as_exactly(ClientSentences::StartTLSOk {})?;
|
.exactly(ClientSentences::StartTLSOk {})?;
|
||||||
|
|
||||||
|
// Initialize SSL configurations
|
||||||
|
let mut ssl_config = rustls::ClientConfig::new();
|
||||||
|
let sess = if self.config.ssl_insecure {
|
||||||
|
ssl_config
|
||||||
|
.dangerous()
|
||||||
|
.set_certificate_verifier(std::sync::Arc::new(
|
||||||
|
crate::ssl::InsecureCertificateValidator::new(&self.config),
|
||||||
|
));
|
||||||
|
|
||||||
|
let dns_name = webpki::DNSNameRef::try_from_ascii_str("www.google.com").unwrap();
|
||||||
|
|
||||||
|
rustls::ClientSession::new(&std::sync::Arc::new(ssl_config), dns_name)
|
||||||
|
} else {
|
||||||
|
// Try to get hostname as given (e.g. localhost can be used for strict SSL, but not 127.0.0.1)
|
||||||
|
let hostname = self
|
||||||
|
.config
|
||||||
|
.host
|
||||||
|
.hostname()
|
||||||
|
.ok_or(Error::Nut(NutError::SslInvalidHostname))?;
|
||||||
|
|
||||||
|
let dns_name = webpki::DNSNameRef::try_from_ascii_str(&hostname)
|
||||||
|
.map_err(|_| Error::Nut(NutError::SslInvalidHostname))?;
|
||||||
|
|
||||||
|
ssl_config
|
||||||
|
.root_store
|
||||||
|
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||||
|
|
||||||
|
rustls::ClientSession::new(&std::sync::Arc::new(ssl_config), dns_name)
|
||||||
|
};
|
||||||
|
|
||||||
// Un-buffer to get back underlying stream
|
// Un-buffer to get back underlying stream
|
||||||
self.stream = self.stream.unbuffered();
|
self.stream = self.stream.unbuffered();
|
||||||
|
|
||||||
// TODO: Un-buffer
|
// Upgrade to SSL
|
||||||
// TODO: Do the upgrade
|
self.stream = self.stream.upgrade_ssl_client(sess)?;
|
||||||
|
|
||||||
|
// Re-buffer
|
||||||
|
self.stream = self.stream.buffered();
|
||||||
}
|
}
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl ConnectionStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the current stream with a `BufReader`.
|
/// Wraps the current stream with a `BufReader`.
|
||||||
pub fn buffered(mut self) -> ConnectionStream {
|
pub fn buffered(self) -> ConnectionStream {
|
||||||
Self::Buffered(Box::new(BufReader::new(self)))
|
Self::Buffered(Box::new(BufReader::new(self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +137,11 @@ impl ConnectionStream {
|
||||||
/// If the current stream is not buffered, it returns itself (no-op).
|
/// If the current stream is not buffered, it returns itself (no-op).
|
||||||
///
|
///
|
||||||
/// Note that, if the stream is buffered, any un-consumed data will be discarded.
|
/// Note that, if the stream is buffered, any un-consumed data will be discarded.
|
||||||
pub fn unbuffered(mut self) -> ConnectionStream {
|
pub fn unbuffered(self) -> ConnectionStream {
|
||||||
match self {
|
if let Self::Buffered(buf) = self {
|
||||||
Self::Buffered(buf) => buf.into_inner(),
|
buf.into_inner()
|
||||||
_ => self,
|
} else {
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,9 +173,8 @@ impl BufRead for ConnectionStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consume(&mut self, amt: usize) {
|
fn consume(&mut self, amt: usize) {
|
||||||
match self {
|
if let Self::Buffered(reader) = self {
|
||||||
Self::Buffered(reader) => reader.consume(amt),
|
reader.consume(amt)
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,12 +215,11 @@ impl Write for ConnectionStream {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::ConnectionStream;
|
use super::ConnectionStream;
|
||||||
use crate::proto::{ClientSentences, Sentence, ServerSentences};
|
use crate::proto::{ClientSentences, Sentence, ServerSentences};
|
||||||
use std::io::{Read, Write};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn read_write_sentence() {
|
fn read_write_sentence() {
|
||||||
let mut client_stream = mockstream::SharedMockStream::new();
|
let client_stream = mockstream::SharedMockStream::new();
|
||||||
let mut server_stream = client_stream.clone();
|
let server_stream = client_stream.clone();
|
||||||
|
|
||||||
let mut client_stream = ConnectionStream::Mock(client_stream).buffered();
|
let mut client_stream = ConnectionStream::Mock(client_stream).buffered();
|
||||||
let mut server_stream = ConnectionStream::Mock(server_stream).buffered();
|
let mut server_stream = ConnectionStream::Mock(server_stream).buffered();
|
||||||
|
@ -253,10 +252,10 @@ mod tests {
|
||||||
.expect("Failed to write UPS LIST");
|
.expect("Failed to write UPS LIST");
|
||||||
|
|
||||||
// Client reads list of UPS devices.
|
// Client reads list of UPS devices.
|
||||||
let sentence = client_stream
|
client_stream
|
||||||
.read_sentence::<ClientSentences>()
|
.read_sentence::<ClientSentences>()
|
||||||
.expect("Failed to read BEGIN LIST UPS")
|
.expect("Failed to read BEGIN LIST UPS")
|
||||||
.as_exactly(ClientSentences::BeginListUps {})
|
.exactly(ClientSentences::BeginListUps {})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let sentences: Vec<ClientSentences> = client_stream
|
let sentences: Vec<ClientSentences> = client_stream
|
||||||
|
@ -285,10 +284,10 @@ mod tests {
|
||||||
.expect("Failed to write LOGIN nutdev0");
|
.expect("Failed to write LOGIN nutdev0");
|
||||||
|
|
||||||
// Server receives login
|
// Server receives login
|
||||||
let sentence = server_stream
|
let _sentence = server_stream
|
||||||
.read_sentence::<ServerSentences>()
|
.read_sentence::<ServerSentences>()
|
||||||
.expect("Failed to read LOGIN nutdev0")
|
.expect("Failed to read LOGIN nutdev0")
|
||||||
.as_exactly(ServerSentences::ExecLogin {
|
.exactly(ServerSentences::ExecLogin {
|
||||||
ups_name: "nutdev0".into(),
|
ups_name: "nutdev0".into(),
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -113,7 +113,7 @@ pub trait Sentence: Eq + Sized + Into<crate::Result<Self>> {
|
||||||
fn encode(&self) -> Vec<&str>;
|
fn encode(&self) -> Vec<&str>;
|
||||||
|
|
||||||
/// Returns an error if the sentence does not match what was expected.
|
/// Returns an error if the sentence does not match what was expected.
|
||||||
fn as_matching<F: FnOnce(&Self) -> bool>(self, matcher: F) -> crate::Result<Self> {
|
fn matching<F: FnOnce(&Self) -> bool>(self, matcher: F) -> crate::Result<Self> {
|
||||||
if matcher(&self) {
|
if matcher(&self) {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,7 +122,7 @@ pub trait Sentence: Eq + Sized + Into<crate::Result<Self>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an error if the sentence is not equal to what was expected.
|
/// Returns an error if the sentence is not equal to what was expected.
|
||||||
fn as_exactly(self, expected: Self) -> crate::Result<Self> {
|
fn exactly(self, expected: Self) -> crate::Result<Self> {
|
||||||
if expected == self {
|
if expected == self {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue