-package Proxmox::SMTP;
+package PMG::SMTP;
use strict;
-use Carp;
+use warnings;
use IO::Socket;
-use Proxmox::SafeSyslog;
-use Proxmox::MailQueue;
-use Proxmox::License;
+use Encode;
+
+use PVE::SafeSyslog;
+
+use PMG::MailQueue;
-# New instance.
sub new {
my($this, $sock) = @_;
-
+
my $class = ref($this) || $this;
- croak("undefined socket: ERROR") if !defined($sock);
+ die("undefined socket: ERROR") if !defined($sock);
my $self = {};
$self->{sock} = $sock;
$self->{from} = undef;
$self->{to} = [];
$self->{queue} = undef;
+ delete $self->{smtputf8};
delete $self->{xforward};
delete $self->{status};
}
my ($self, $func, $data, $maxcount) = @_;
my($cmd, $args);
-
- my $sock = $self->{sock};
- my $reject = 0;
- my $lic = Proxmox::License->new ();
- if (!$lic->valid || $lic->expired_trial) {
- $reject = 1;
- }
+ my $sock = $self->{sock};
my $count = 0;
if ($cmd eq 'helo' || $cmd eq 'ehlo' || $cmd eq 'lhlo') {
$self->reset();
- if ($reject) {
- $self->reply ("500 5.5.1 Error: No valid License");
- last;
- }
-
$self->reply ("250-PIPELINING");
$self->reply ("250-ENHANCEDSTATUSCODES");
$self->reply ("250-8BITMIME");
+ $self->reply ("250-SMTPUTF8");
$self->reply ("250-XFORWARD NAME ADDR PROTO HELO");
$self->reply ("250 OK.");
$self->{lmtp} = 1 if ($cmd eq 'lhlo');
$self->reply ("250 2.5.0 OK");
next;
} elsif ($cmd eq 'mail') {
- if ($args =~ m/^from:\s*<(\S*)>/i) {
+ if ($args =~ m/^from:\s*<([^\s\>]*)>([^>]*)$/i) {
delete $self->{to};
- $self->{from} = $1;
+ my ($from, $opts) = ($1, $2);
+ if ($opts =~ m/\sSMTPUTF8/) {
+ $self->{smtputf8} = 1;
+ $from = decode('UTF-8', $from);
+ }
+ $self->{from} = $from;
$self->reply ('250 2.5.0 OK');
next;
} else {
next;
}
} elsif ($cmd eq 'rcpt') {
- if ($args =~ m/^to:\s*<(\S+)>/i) {
- push @{$self->{to}} , $1;
+ if ($args =~ m/^to:\s*<([^\s\>]+)>[^>]*$/i) {
+ my $to = $self->{smtputf8} ? decode('UTF-8', $1) : $1;
+ push @{$self->{to}} , $to;
$self->reply ('250 2.5.0 OK');
next;
} else {
- $self->reply ("501 5.5.2 Syntax: MAIL FROM: <address>");
+ $self->reply ("501 5.5.2 Syntax: RCPT TO: <address>");
next;
}
} elsif ($cmd eq 'data') {
if ($self->save_data ()) {
eval { &$func ($data, $self); };
- if ($@) {
+ if (my $err = $@) {
$data->{errors} = 1;
- syslog ('err', $@);
+ syslog ('err', $err);
}
if ($self->{lmtp}) {
last if $data->{errors}; # abort if we find errors
next;
}
-
+
$self->reply ("500 5.5.1 Error: unknown command");
}
sub save_data {
my $self = shift;
my $done = undef;
-
+
if(!defined($self->{from})) {
$self->reply ("503 5.5.1 Tell me who you are.");
return 0;
}
-
+
if(!defined($self->{to})) {
$self->reply ("503 5.5.1 Tell me who to send it.");
return 0;
my $queue;
eval {
- $queue = Proxmox::MailQueue->new ($self->{from}, $self->{to});
-
+ $queue = PMG::MailQueue->new ($self->{from}, $self->{to});
+
while(<$sock>) {
if(/^\.\015\012$/) {
$done = 1;
last;
}
-
+
# RFC 2821 compliance.
s/^\.\./\./;
- s/\015\012/\n/;
+ s/\015\012/\n/;
print {$queue->{fh}} $_;
$queue->{bytes} += length ($_);
$queue->{fh}->flush ();
- $self->{queue} = $queue;
+ $self->{queue} = $queue;
};
-
- if($@) {
- syslog ('err', $@);
- $self->reply ("451 4.5.0 Local delivery failed: $@");
+ if (my $err = $@) {
+ syslog ('err', $err);
+ $self->reply ("451 4.5.0 Local delivery failed: $err");
return 0;
}
if(!defined($done)) {
}
1;
-
-__END__