Skip to content

Commit

Permalink
g3proxy: disable on-deman mail relay by default
Browse files Browse the repository at this point in the history
  • Loading branch information
zh-jq-b committed May 17, 2024
1 parent afbb2f4 commit b9f26bc
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 13 deletions.
8 changes: 7 additions & 1 deletion g3proxy/src/inspect/smtp/forward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ pub(super) enum ForwardNextAction {

pub(super) struct Forward {
local_ip: IpAddr,
allow_odmr: bool,
auth_end: bool,
}

impl Forward {
pub(super) fn new(local_ip: IpAddr) -> Self {
pub(super) fn new(local_ip: IpAddr, allow_odmr: bool) -> Self {
Forward {
local_ip,
allow_odmr,
auth_end: false,
}
}
Expand Down Expand Up @@ -84,6 +86,9 @@ impl Forward {
}
}
Command::AuthenticatedTurn => {
if !self.allow_odmr {
return Some(ResponseEncoder::COMMAND_NOT_IMPLEMENTED);
}
if !self.auth_end {
return Some(ResponseEncoder::AUTHENTICATION_REQUIRED);
}
Expand Down Expand Up @@ -112,6 +117,7 @@ impl Forward {
.await?;
}
Command::AuthenticatedTurn => {
// a max 10min timeout according to RFC2645
let rsp = self.recv_relay_rsp(&mut rsp_recv_buf, ups_r, clt_w).await?;
if rsp == ReplyCode::OK {
return Ok(ForwardNextAction::ReverseConnection);
Expand Down
31 changes: 25 additions & 6 deletions g3proxy/src/inspect/smtp/initiation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use std::str;

use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};

use g3_dpi::SmtpInterceptionConfig;
use g3_io_ext::LineRecvBuf;
use g3_smtp_proto::command::Command;
use g3_smtp_proto::response::{ReplyCode, ResponseEncoder, ResponseParser};
Expand All @@ -27,21 +28,36 @@ use g3_types::net::Host;
use super::{CommandLineRecvExt, ResponseLineRecvExt, ResponseParseExt};
use crate::serve::{ServerTaskError, ServerTaskResult};

pub struct Initiation {
#[derive(Default)]
pub(super) struct InitializedExtensions {
odmr: bool,
}

impl InitializedExtensions {
pub(super) fn allow_odmr(&self, config: &SmtpInterceptionConfig) -> bool {
self.odmr && config.allow_on_demand_mail_relay
}
}

pub(super) struct Initiation<'a> {
config: &'a SmtpInterceptionConfig,
local_ip: IpAddr,
client_host: Host,
server_ext: InitializedExtensions,
}

impl Initiation {
pub(super) fn new(local_ip: IpAddr) -> Self {
impl<'a> Initiation<'a> {
pub(super) fn new(config: &'a SmtpInterceptionConfig, local_ip: IpAddr) -> Self {
Initiation {
config,
local_ip,
client_host: Host::empty(),
server_ext: InitializedExtensions::default(),
}
}

pub(super) fn into_parts(self) -> Host {
self.client_host
pub(super) fn into_parts(self) -> (Host, InitializedExtensions) {
(self.client_host, self.server_ext)
}

pub(super) async fn relay<CR, CW, UR, UW>(
Expand Down Expand Up @@ -225,7 +241,10 @@ impl Initiation {
// LIMITS, RFC9422
"LIMITS" => true,
// On-Demand Mail Relay, RFC2645, change the protocol
"ATRN" => true,
"ATRN" => {
self.server_ext.odmr = true;
self.config.allow_on_demand_mail_relay
}
_ => false,
}
}
Expand Down
31 changes: 25 additions & 6 deletions g3proxy/src/inspect/smtp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,40 @@ impl<SC: ServerConfig> SmtpInterceptObject<SC> {
mut ups_w: BoxAsyncWrite,
) -> ServerTaskResult<()> {
let local_ip = self.ctx.task_notes.server_addr.ip();
let interception_config = self.ctx.smtp_interception();

let mut initiation = Initiation::new(local_ip);
let mut initiation = Initiation::new(interception_config, local_ip);
initiation
.relay(&mut clt_r, &mut clt_w, &mut ups_r, &mut ups_w)
.await?;
self.client_host = Some(initiation.into_parts());
let (client_host, server_ext) = initiation.into_parts();
self.client_host = Some(client_host);

let allow_odmr = server_ext.allow_odmr(interception_config);

let mut forward = Forward::new(local_ip);
let mut forward = Forward::new(local_ip, allow_odmr);
let next_action = forward
.relay(&mut clt_r, &mut clt_w, &mut ups_r, &mut ups_w)
.await?;
match next_action {
ForwardNextAction::StartTls => {}
ForwardNextAction::ReverseConnection => {}
ForwardNextAction::MailTransport(_param) => {}
ForwardNextAction::StartTls => {
// TODO
}
ForwardNextAction::ReverseConnection => {
return crate::inspect::stream::transit_transparent(
clt_r,
clt_w,
ups_r,
ups_w,
&self.ctx.server_config,
&self.ctx.server_quit_policy,
self.ctx.user(),
)
.await;
}
ForwardNextAction::MailTransport(_param) => {
// TODO
}
}

crate::inspect::stream::transit_transparent(
Expand Down
2 changes: 2 additions & 0 deletions lib/g3-dpi/src/config/smtp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ use std::time::Duration;
pub struct SmtpInterceptionConfig {
pub greeting_timeout: Duration,
pub quit_wait_timeout: Duration,
pub allow_on_demand_mail_relay: bool,
}

impl Default for SmtpInterceptionConfig {
fn default() -> Self {
SmtpInterceptionConfig {
greeting_timeout: Duration::from_secs(300),
quit_wait_timeout: Duration::from_secs(60),
allow_on_demand_mail_relay: false,
}
}
}
4 changes: 4 additions & 0 deletions lib/g3-yaml/src/value/dpi/smtp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ pub fn as_smtp_interception_config(value: &Yaml) -> anyhow::Result<SmtpIntercept
.context(format!("invalid humanize duration value for key {k}"))?;
Ok(())
}
"allow_on_demand_mail_relay" | "allow_odmr" => {
config.allow_on_demand_mail_relay = crate::value::as_bool(v)?;
Ok(())
}
_ => Err(anyhow!("invalid key {k}")),
})?;

Expand Down

0 comments on commit b9f26bc

Please sign in to comment.