diff -urN ../swaks-20240103.0.orig/swaks ./swaks --- ../swaks-20240103.0.orig/swaks 2024-01-03 22:40:21.000000000 +0200 +++ ./swaks 2024-02-06 00:54:58.372023000 +0200 @@ -86,7 +86,7 @@ # XXX hash that we can pass verbatim here open_link(); -sendmail($opts->{from}, $opts->{env_to}, $opts->{helo}, $opts->{data}, +sendmail($opts->{from}, $opts->{from_size}, $opts->{from_envid}, $opts->{env_to}, $opts->{to_notify}, $opts->{to_orcpt}, $opts->{helo}, $opts->{data}, $opts->{a_user}, $opts->{a_pass}, $opts->{a_type}); teardown_link(); @@ -196,7 +196,11 @@ sub sendmail { my $from = shift; # envelope-from + my $from_size = shift; # envelope-from size parameter + my $from_envid = shift; # envelope-from envid parameter my $to = shift; # envelope-to + my $to_notify = shift; # envelope-to notify parameter + my $to_orcpt = shift; # envelope-to notify parameter my $helo = shift; # who am I? my $data = shift; # body of message (content after DATA command) my $a_user = shift; # what user to auth with? @@ -315,7 +319,7 @@ # 0 = mail succeeded # 1 = prdr required but not advertised $G::drop_before_read = 1 if ($G::drop_after_send eq 'mail'); - my $result = do_smtp_mail($ehlo, $from); # failures in this handled by smtp_mail_callback + my $result = do_smtp_mail($ehlo, $from, $from_size, $from_envid); # failures in this handled by smtp_mail_callback if ($result == 1) { ptrans(12, "Host did not advertise PRDR support"); do_smtp_quit(1, 30); @@ -325,7 +329,7 @@ # send RCPT (sub handles multiple, comma-delimited recips) $G::drop_before_read = 1 if ($G::drop_after_send eq 'rcpt'); - do_smtp_rcpt($to); # failures in this handled by smtp_rcpt_callback + do_smtp_rcpt($to, $to_notify, $to_orcpt); # failures in this handled by smtp_rcpt_callback # note that smtp_rcpt_callback increments # $G::smtp_rcpt_failures at every failure. This and # $G::smtp_rcpt_total are used after DATA for LMTP @@ -1240,6 +1244,8 @@ my $e = shift; # ehlo response my $a = shift; # from address my $m = "MAIL FROM:<$a>"; + my $mail_from_size = shift; # from size parameter + my $mail_from_envid = shift; # from envid parameter if ($G::prdr) { if (!$e->{PRDR}) { @@ -1249,7 +1255,7 @@ } } - transact(cxn_string => $m, expect => '250', defer => 1, fail_callback => \&smtp_mail_callback); + transact(cxn_string => $m.($mail_from_size ? " SIZE=$mail_from_size" : "").($mail_from_envid ? " ENVID=$mail_from_envid" : ""), expect => '250', defer => 1, fail_callback => \&smtp_mail_callback); return(0); # the callback handles failures, so just return here } @@ -1262,12 +1268,16 @@ sub do_smtp_rcpt { my $m = shift; # string of comma separated recipients + my $rcpt_to_notify = shift; # to notify parameter + my $rcpt_to_orcpt = shift; # to orcpt parameter my $f = 0; # The number of failures we've experienced my @a = split(/,/, $m); + my @orcpt = split(/,/, $rcpt_to_orcpt); $G::smtp_rcpt_total = scalar(@a); foreach my $addr (@a) { - transact(cxn_string => 'RCPT TO:<' . $addr . '>', expect => '250', defer => 1, + my $orcpt_addr = shift(@orcpt); + transact(cxn_string => "RCPT TO:<$addr>".($rcpt_to_notify ? " NOTIFY=$rcpt_to_notify" : "").($orcpt_addr ? " ORCPT=$orcpt_addr" : ""), expect => '250', defer => 1, fail_callback => \&smtp_rcpt_callback); } @@ -1984,6 +1994,14 @@ cfgs => OP_ARG_REQ|OP_FROM_PROMPT, prompt => 'From: ', match => '^.*$', okey => 'mail_from', type => 'scalar', }, + # envelope-from size parameter + { opts => ['from-size'], suffix => ':s', + cfgs => OP_ARG_OPT, + okey => 'from_size', type => 'scalar', }, + # envelope-from envid parameter + { opts => ['from-envid'], suffix => ':s', + cfgs => OP_ARG_OPT, + okey => 'from_envid', type => 'scalar', }, # (t)o address(es) (will be added to envelope recipients) { opts => ['to', 't'], suffix => ':s', cfgs => OP_ARG_REQ|OP_FROM_PROMPT, @@ -1999,6 +2017,14 @@ cfgs => OP_ARG_REQ|OP_FROM_PROMPT, prompt => 'Bcc: ', match => '^.+$', okey => 'mail_bcc', type => 'scalar', }, + # envelope-to address notify parameter + { opts => ['to-notify'], suffix => ':s', + cfgs => OP_ARG_OPT, + okey => 'to_notify', type => 'scalar', }, + # envelope-to address orcpt parameter + { opts => ['to-orcpt'], suffix => ':s', + cfgs => OP_ARG_OPT, + okey => 'to_orcpt', type => 'scalar', }, # (h)elo string { opts => ['helo', 'ehlo', 'lhlo', 'h'], suffix => ':s', cfgs => OP_ARG_REQ|OP_FROM_PROMPT, @@ -3140,6 +3166,10 @@ } } $n{from} = '' if ($n{from} eq '<>'); + $n{from_size} = get_arg('from_size', $o); + $n{from_envid} = get_arg('from_envid', $o); + $n{to_notify} = get_arg('to_notify', $o); + $n{to_orcpt} = get_arg('to_orcpt', $o); # local interface and port ($G::link{lint},$G::link{lport}) = parse_server(get_arg('lint', $o), get_arg('lport', $o));