server: fix is_dmarc check
This commit is contained in:
parent
5c42d04598
commit
1f75627fd2
@ -27,6 +27,8 @@ use crate::{
|
|||||||
linkify_html, InlineStyle, Query, SanitizeHtml, Transformer,
|
linkify_html, InlineStyle, Query, SanitizeHtml, Transformer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const APPLICATION_GZIP: &'static str = "application/gzip";
|
||||||
|
|
||||||
const APPLICATION_ZIP: &'static str = "application/zip";
|
const APPLICATION_ZIP: &'static str = "application/zip";
|
||||||
const IMAGE_JPEG: &'static str = "image/jpeg";
|
const IMAGE_JPEG: &'static str = "image/jpeg";
|
||||||
const IMAGE_PJPEG: &'static str = "image/pjpeg";
|
const IMAGE_PJPEG: &'static str = "image/pjpeg";
|
||||||
@ -351,9 +353,7 @@ pub async fn thread(
|
|||||||
for i in 0..archive.len() {
|
for i in 0..archive.len() {
|
||||||
if let Ok(mut file) = archive.by_index(i) {
|
if let Ok(mut file) = archive.by_index(i) {
|
||||||
let name = file.name().to_lowercase();
|
let name = file.name().to_lowercase();
|
||||||
if name.ends_with(".xml")
|
if is_dmarc_report_filename(&name) {
|
||||||
&& (name.contains("dmarc") || name.starts_with("google.com!"))
|
|
||||||
{
|
|
||||||
let mut xml = String::new();
|
let mut xml = String::new();
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
if file.read_to_string(&mut xml).is_ok() {
|
if file.read_to_string(&mut xml).is_ok() {
|
||||||
@ -564,8 +564,6 @@ fn extract_body(m: &ParsedMail, part_addr: &mut Vec<String>) -> Result<Body, Ser
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
const APPLICATION_GZIP: &'static str = "application/gzip";
|
|
||||||
|
|
||||||
fn extract_zip(m: &ParsedMail) -> Result<Body, ServerError> {
|
fn extract_zip(m: &ParsedMail) -> Result<Body, ServerError> {
|
||||||
if let Ok(zip_bytes) = m.get_body_raw() {
|
if let Ok(zip_bytes) = m.get_body_raw() {
|
||||||
if let Ok(mut archive) = ZipArchive::new(Cursor::new(&zip_bytes)) {
|
if let Ok(mut archive) = ZipArchive::new(Cursor::new(&zip_bytes)) {
|
||||||
@ -574,16 +572,14 @@ fn extract_zip(m: &ParsedMail) -> Result<Body, ServerError> {
|
|||||||
let name = file.name().to_lowercase();
|
let name = file.name().to_lowercase();
|
||||||
// Google DMARC reports are typically named like "google.com!example.com!...xml"
|
// Google DMARC reports are typically named like "google.com!example.com!...xml"
|
||||||
// and may or may not contain "dmarc" in the filename.
|
// and may or may not contain "dmarc" in the filename.
|
||||||
if name.ends_with(".xml")
|
if is_dmarc_report_filename(&name) {
|
||||||
&& (name.contains("dmarc") || name.starts_with("google.com!"))
|
|
||||||
{
|
|
||||||
let mut xml = String::new();
|
let mut xml = String::new();
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
if file.read_to_string(&mut xml).is_ok() {
|
if file.read_to_string(&mut xml).is_ok() {
|
||||||
match parse_dmarc_report(&xml) {
|
match parse_dmarc_report(&xml) {
|
||||||
Ok(report) => {
|
Ok(report) => {
|
||||||
return Ok(Body::html(format!(
|
return Ok(Body::html(format!(
|
||||||
"<div class=\"dmarc-report\">Google DMARC report summary:<br>{}</div>",
|
"<div class=\"dmarc-report\">DMARC report summary:<br>{}</div>",
|
||||||
report
|
report
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -605,23 +601,30 @@ fn extract_zip(m: &ParsedMail) -> Result<Body, ServerError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn extract_gzip(m: &ParsedMail) -> Result<Body, ServerError> {
|
fn extract_gzip(m: &ParsedMail) -> Result<Body, ServerError> {
|
||||||
if let Ok(gz_bytes) = m.get_body_raw() {
|
let pcd = m.get_content_disposition();
|
||||||
let mut decoder = flate2::read::GzDecoder::new(&gz_bytes[..]);
|
let filename = pcd.params.get("filename").map(|s| s.to_lowercase());
|
||||||
let mut xml = String::new();
|
|
||||||
use std::io::Read;
|
let is_dmarc_xml_file = filename.map_or(false, |name| is_dmarc_report_filename(&name));
|
||||||
if decoder.read_to_string(&mut xml).is_ok() {
|
|
||||||
match parse_dmarc_report(&xml) {
|
if is_dmarc_xml_file {
|
||||||
Ok(report) => {
|
if let Ok(gz_bytes) = m.get_body_raw() {
|
||||||
return Ok(Body::html(format!(
|
let mut decoder = flate2::read::GzDecoder::new(&gz_bytes[..]);
|
||||||
"<div class=\"dmarc-report\">Microsoft DMARC report summary:<br>{}</div>",
|
let mut xml = String::new();
|
||||||
report
|
use std::io::Read;
|
||||||
)));
|
if decoder.read_to_string(&mut xml).is_ok() {
|
||||||
}
|
match parse_dmarc_report(&xml) {
|
||||||
Err(e) => {
|
Ok(report) => {
|
||||||
return Ok(Body::html(format!(
|
return Ok(Body::html(format!(
|
||||||
"<div class=\"dmarc-report-error\">Failed to parse DMARC report XML: {}</div>",
|
"<div class=\"dmarc-report\">DMARC report summary:<br>{}</div>",
|
||||||
e
|
report
|
||||||
)));
|
)));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Ok(Body::html(format!(
|
||||||
|
"<div class=\"dmarc-report-error\">Failed to parse DMARC report XML: {}</div>",
|
||||||
|
e
|
||||||
|
)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -752,6 +755,10 @@ fn extract_unhandled(m: &ParsedMail) -> Result<Body, ServerError> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_dmarc_report_filename(name: &str) -> bool {
|
||||||
|
(name.ends_with(".xml.gz") || name.ends_with(".xml")) && name.contains("!")
|
||||||
|
}
|
||||||
|
|
||||||
// multipart/alternative defines multiple representations of the same message, and clients should
|
// multipart/alternative defines multiple representations of the same message, and clients should
|
||||||
// show the fanciest they can display. For this program, the priority is text/html, text/plain,
|
// show the fanciest they can display. For this program, the priority is text/html, text/plain,
|
||||||
// then give up.
|
// then give up.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user