1 parent
96a32ea8fb
commit
a643e7e3ab
106 files changed
+2223
-4669
No files matched your search
+3
-10
@@ -19,7 +19,7 @@ pub const MAX_SCRIPT_BYTES: usize = 1024 * 1024;
|
||||
pub struct SieveCredentials {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
/// `starttls`, `implicit`, or `none`.
|
||||
|
||||
pub tls_mode: String,
|
||||
pub allow_insecure_auth: bool,
|
||||
pub username: String,
|
||||
@@ -84,16 +84,12 @@ impl ManageSieveClient {
|
||||
let reply = read_response(&mut tcp, creds.timeout).await?;
|
||||
ensure_ok(&reply)?;
|
||||
|
||||
// Do not buffer beyond the STARTTLS response. read_response() consumes
|
||||
// exactly one protocol line at a time, preventing plaintext bytes from
|
||||
// being replayed into the TLS stream.
|
||||
let tls = async_native_tls::TlsConnector::new();
|
||||
let mut tls_stream = timeout(creds.timeout, tls.connect(&creds.host, tcp))
|
||||
.await
|
||||
.map_err(|_| SieveError::Timeout)?
|
||||
.map_err(|e| SieveError::TlsFailed(e.to_string()))?;
|
||||
|
||||
// RFC 5804 requires the server to re-issue capabilities after TLS.
|
||||
let greeting = read_response(&mut tls_stream, creds.timeout).await?;
|
||||
(SieveStream::Tls(tls_stream), greeting)
|
||||
}
|
||||
@@ -212,7 +208,6 @@ impl ManageSieveClient {
|
||||
return Err(SieveError::ScriptTooLarge);
|
||||
}
|
||||
|
||||
// RFC 5804 recommends HAVESPACE before PUTSCRIPT for larger scripts.
|
||||
let have_space = format!("HAVESPACE {} {}\r\n", quote(name)?, script.len());
|
||||
let response = self.command(&have_space).await?;
|
||||
ensure_ok(&response)?;
|
||||
@@ -362,7 +357,7 @@ impl ProtocolResponse {
|
||||
}
|
||||
|
||||
let text = format!("{}{}", self.final_line.before, self.final_line.after);
|
||||
// Prefer a quoted human-readable string, falling back to the full status line.
|
||||
|
||||
if let Some(pos) = text.rfind('"') {
|
||||
let prefix = &text[..pos];
|
||||
if let Some(start) = prefix.rfind('"') {
|
||||
@@ -436,8 +431,6 @@ async fn read_wire_line<S: AsyncRead + Unpin>(stream: &mut S) -> Result<WireLine
|
||||
.await
|
||||
.map_err(|e| SieveError::ConnectionFailed(e.to_string()))?;
|
||||
|
||||
// A literal is a token inside the response line. The bytes following it,
|
||||
// including an optional ` ACTIVE`, continue until the response CRLF.
|
||||
let after_bytes = read_crlf_line(stream).await?;
|
||||
let after = String::from_utf8(after_bytes)
|
||||
.map_err(|_| SieveError::Protocol("literal suffix is not UTF-8".into()))?;
|
||||
@@ -477,7 +470,7 @@ fn trailing_literal_size(line: &str) -> Result<Option<usize>, SieveError> {
|
||||
return Ok(None);
|
||||
}
|
||||
let raw = &trimmed[open + 1..trimmed.len() - 1];
|
||||
// Server-to-client literals do not use the non-synchronizing + form.
|
||||
|
||||
if raw.ends_with('+') {
|
||||
return Err(SieveError::Protocol(
|
||||
"server sent an invalid non-synchronizing literal".into(),
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ impl fmt::Display for SieveError {
|
||||
write!(f, "ManageSieve server rejected the command: {msg}")
|
||||
}
|
||||
Self::Timeout => write!(f, "ManageSieve operation timed out"),
|
||||
Self::ScriptTooLarge => write!(f, "Sieve script exceeds the RustBox 0.0.4 size limit"),
|
||||
Self::ScriptTooLarge => write!(f, "Sieve script exceeds the RustBox 0.0.5 size limit"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user