use strict; use warnings; use Qpsmtpd::Constants; use Qpsmtpd::DSN; use Net::LMTP; sub register { my ($self, $qp) = (shift, shift); $self->{lmtp_rcpt_based} = $qp->config("lmtp_rcpt_based") || 0; $self->{lmtp_host} = $qp->config("lmtp_host"); $self->{lmtp_port} = $qp->config("lmtp_port") || 24; $self->{qp}= $qp; $self->{enabled} = 1; if (!$self->{lmtp_rcpt_based} && !$self->{lmtp_host}) { $self->{enabled} = 0; $self->log(LOGERROR, "No LMTP host configured, disabling plugin\n"); return; } } sub lmtp_transfer { my ($self, $transaction, $lmtp_host, $lmtp_port, $lmtp_user) = @_; my $lmtp = Net::LMTP->new( $lmtp_host, Port => $lmtp_port, Timeout => 60, Hello => $self->qp->config("me"), ) || die $!; $lmtp->mail($transaction->sender->address || "") or return DECLINED, "Unable to queue message during mail($!)"; $lmtp->to($lmtp_user) or return DECLINED, "Unable to queue message during to($!)"; $lmtp->data() or return DECLINED, "Unable to queue message during data($!)"; $lmtp->datasend($transaction->header->as_string) or return DECLINED, "Unable to queue message during datasend ($!) "; $transaction->body_resetpos; while (my $line = $transaction->body_getline) { $lmtp->datasend($line) or return DECLINED, "Unable to queue message during datasendbody($!)"; } $lmtp->dataend() or return DECLINED, "Unable to queue message during dataend($!)"; my $qid = $lmtp->message(); my @list = split(' ', $qid); $qid = pop(@list); $lmtp->quit() or return DECLINED, "Unable to queue message during quit($!)"; $self->log(LOGINFO, "finished queueing"); return OK, "queued as $qid"; return DECLINED; } sub hook_queue { my ($self, $transaction) = @_; return DECLINED unless $self->{enabled}; my $lmtp_host; my $lmtp_port; my $lmtp_user; if ($self->{lmtp_rcpt_based}) { my $queue = $transaction->notes("queue"); $queue =~ /^lmtp:\/\/(.*):(\d+)$/; $lmtp_host=$1; $lmtp_port=$2; $lmtp_user = $transaction->notes("destination-user") || ""; } else { $lmtp_host = $self->{lmtp_host}; $lmtp_port = $self->{lmtp_port}; $lmtp_user = $transaction->sender->address || ""; } if (!$lmtp_user) { $self->log(LOGERROR, "No sender address found for transaction.\n"); return DECLINED; } $self->log(LOGNOTICE,"forwarding mail to LMTP host: $lmtp_host:$lmtp_port\n"); return $self->lmtp_transfer($transaction, $lmtp_host, $lmtp_port, $lmtp_user); }