xref: /openbsd-src/gnu/usr.bin/perl/cpan/libnet/lib/Net/SMTP.pm (revision e068048151d29f2562a32185e21a8ba885482260)
1b8851fccSafresh1# Net::SMTP.pm
2b8851fccSafresh1#
35759b3d2Safresh1# Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
4eac174f2Safresh1# Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
5b8851fccSafresh1# This module is free software; you can redistribute it and/or modify it under
6b8851fccSafresh1# the same terms as Perl itself, i.e. under the terms of either the GNU General
7b8851fccSafresh1# Public License or the Artistic License, as specified in the F<LICENCE> file.
8b8851fccSafresh1
9b8851fccSafresh1package Net::SMTP;
10b8851fccSafresh1
11b8851fccSafresh1use 5.008001;
12b8851fccSafresh1
13b8851fccSafresh1use strict;
14b8851fccSafresh1use warnings;
15b8851fccSafresh1
16b8851fccSafresh1use Carp;
17b8851fccSafresh1use IO::Socket;
18b8851fccSafresh1use Net::Cmd;
19b8851fccSafresh1use Net::Config;
20b8851fccSafresh1use Socket;
21b8851fccSafresh1
22*e0680481Safresh1our $VERSION = "3.15";
23b8851fccSafresh1
24b8851fccSafresh1# Code for detecting if we can use SSL
25b8851fccSafresh1my $ssl_class = eval {
26b8851fccSafresh1  require IO::Socket::SSL;
27b8851fccSafresh1  # first version with default CA on most platforms
28b8851fccSafresh1  no warnings 'numeric';
29b8851fccSafresh1  IO::Socket::SSL->VERSION(2.007);
30b8851fccSafresh1} && 'IO::Socket::SSL';
31b8851fccSafresh1
32b8851fccSafresh1my $nossl_warn = !$ssl_class &&
33b8851fccSafresh1  'To use SSL please install IO::Socket::SSL with version>=2.007';
34b8851fccSafresh1
35b8851fccSafresh1# Code for detecting if we can use IPv6
36b8851fccSafresh1my $family_key = 'Domain';
37b8851fccSafresh1my $inet6_class = eval {
38b8851fccSafresh1  require IO::Socket::IP;
39b8851fccSafresh1  no warnings 'numeric';
405759b3d2Safresh1  IO::Socket::IP->VERSION(0.25) || die;
41b8851fccSafresh1  $family_key = 'Family';
42b8851fccSafresh1} && 'IO::Socket::IP' || eval {
43b8851fccSafresh1  require IO::Socket::INET6;
44b8851fccSafresh1  no warnings 'numeric';
45b8851fccSafresh1  IO::Socket::INET6->VERSION(2.62);
46b8851fccSafresh1} && 'IO::Socket::INET6';
47b8851fccSafresh1
48b8851fccSafresh1sub can_ssl   { $ssl_class };
49b8851fccSafresh1sub can_inet6 { $inet6_class };
50b8851fccSafresh1
51b8851fccSafresh1our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
52b8851fccSafresh1
53b8851fccSafresh1sub new {
54b8851fccSafresh1  my $self = shift;
55b8851fccSafresh1  my $type = ref($self) || $self;
56b8851fccSafresh1  my ($host, %arg);
57b8851fccSafresh1  if (@_ % 2) {
58b8851fccSafresh1    $host = shift;
59b8851fccSafresh1    %arg  = @_;
60b8851fccSafresh1  }
61b8851fccSafresh1  else {
62b8851fccSafresh1    %arg  = @_;
63b8851fccSafresh1    $host = delete $arg{Host};
64b8851fccSafresh1  }
65b8851fccSafresh1
66b8851fccSafresh1  if ($arg{SSL}) {
67b8851fccSafresh1    # SSL from start
68b8851fccSafresh1    die $nossl_warn if !$ssl_class;
69b8851fccSafresh1    $arg{Port} ||= 465;
70b8851fccSafresh1  }
71b8851fccSafresh1
72b8851fccSafresh1  my $hosts = defined $host ? $host : $NetConfig{smtp_hosts};
73b8851fccSafresh1  my $obj;
74b8851fccSafresh1
75b8851fccSafresh1  $arg{Timeout} = 120 if ! defined $arg{Timeout};
76b8851fccSafresh1
77b8851fccSafresh1  foreach my $h (@{ref($hosts) ? $hosts : [$hosts]}) {
78b8851fccSafresh1    $obj = $type->SUPER::new(
79b8851fccSafresh1      PeerAddr => ($host = $h),
80b8851fccSafresh1      PeerPort => $arg{Port} || 'smtp(25)',
81b8851fccSafresh1      LocalAddr => $arg{LocalAddr},
82b8851fccSafresh1      LocalPort => $arg{LocalPort},
83b8851fccSafresh1      $family_key => $arg{Domain} || $arg{Family},
84b8851fccSafresh1      Proto     => 'tcp',
85b8851fccSafresh1      Timeout   => $arg{Timeout}
86b8851fccSafresh1      )
87b8851fccSafresh1      and last;
88b8851fccSafresh1  }
89b8851fccSafresh1
90b8851fccSafresh1  return
91b8851fccSafresh1    unless defined $obj;
92b8851fccSafresh1
93b8851fccSafresh1  ${*$obj}{'net_smtp_arg'} = \%arg;
94b8851fccSafresh1  ${*$obj}{'net_smtp_host'} = $host;
95b8851fccSafresh1
96b8851fccSafresh1  if ($arg{SSL}) {
97b8851fccSafresh1    Net::SMTP::_SSL->start_SSL($obj,%arg)
98b8851fccSafresh1      or return;
99b8851fccSafresh1  }
100b8851fccSafresh1
101b8851fccSafresh1  $obj->autoflush(1);
102b8851fccSafresh1
103b8851fccSafresh1  $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
104b8851fccSafresh1
105b8851fccSafresh1  unless ($obj->response() == CMD_OK) {
106b8851fccSafresh1    my $err = ref($obj) . ": " . $obj->code . " " . $obj->message;
107b8851fccSafresh1    $obj->close();
108b8851fccSafresh1    $@ = $err;
109b8851fccSafresh1    return;
110b8851fccSafresh1  }
111b8851fccSafresh1
112b8851fccSafresh1  ${*$obj}{'net_smtp_exact_addr'} = $arg{ExactAddresses};
113b8851fccSafresh1
114b8851fccSafresh1  (${*$obj}{'net_smtp_banner'}) = $obj->message;
115b8851fccSafresh1  (${*$obj}{'net_smtp_domain'}) = $obj->message =~ /\A\s*(\S+)/;
116b8851fccSafresh1
117b8851fccSafresh1  if (!exists $arg{SendHello} || $arg{SendHello}) {
118b8851fccSafresh1    unless ($obj->hello($arg{Hello} || "")) {
119b8851fccSafresh1      my $err = ref($obj) . ": " . $obj->code . " " . $obj->message;
120b8851fccSafresh1      $obj->close();
121b8851fccSafresh1      $@ = $err;
122b8851fccSafresh1      return;
123b8851fccSafresh1    }
124b8851fccSafresh1  }
125b8851fccSafresh1
126b8851fccSafresh1  $obj;
127b8851fccSafresh1}
128b8851fccSafresh1
129b8851fccSafresh1
130b8851fccSafresh1sub host {
131b8851fccSafresh1  my $me = shift;
132b8851fccSafresh1  ${*$me}{'net_smtp_host'};
133b8851fccSafresh1}
134b8851fccSafresh1
135b8851fccSafresh1##
136b8851fccSafresh1## User interface methods
137b8851fccSafresh1##
138b8851fccSafresh1
139b8851fccSafresh1
140b8851fccSafresh1sub banner {
141b8851fccSafresh1  my $me = shift;
142b8851fccSafresh1
143b8851fccSafresh1  return ${*$me}{'net_smtp_banner'} || undef;
144b8851fccSafresh1}
145b8851fccSafresh1
146b8851fccSafresh1
147b8851fccSafresh1sub domain {
148b8851fccSafresh1  my $me = shift;
149b8851fccSafresh1
150b8851fccSafresh1  return ${*$me}{'net_smtp_domain'} || undef;
151b8851fccSafresh1}
152b8851fccSafresh1
153b8851fccSafresh1
154b8851fccSafresh1sub etrn {
155b8851fccSafresh1  my $self = shift;
156b8851fccSafresh1  defined($self->supports('ETRN', 500, ["Command unknown: 'ETRN'"]))
157b8851fccSafresh1    && $self->_ETRN(@_);
158b8851fccSafresh1}
159b8851fccSafresh1
160b8851fccSafresh1
161b8851fccSafresh1sub auth {
162b8851fccSafresh1  my ($self, $username, $password) = @_;
163b8851fccSafresh1
164b8851fccSafresh1  eval {
165b8851fccSafresh1    require MIME::Base64;
166b8851fccSafresh1    require Authen::SASL;
167b8851fccSafresh1  } or $self->set_status(500, ["Need MIME::Base64 and Authen::SASL todo auth"]), return 0;
168b8851fccSafresh1
169b8851fccSafresh1  my $mechanisms = $self->supports('AUTH', 500, ["Command unknown: 'AUTH'"]);
170b8851fccSafresh1  return unless defined $mechanisms;
171b8851fccSafresh1
172b8851fccSafresh1  my $sasl;
173b8851fccSafresh1
174b8851fccSafresh1  if (ref($username) and UNIVERSAL::isa($username, 'Authen::SASL')) {
175b8851fccSafresh1    $sasl = $username;
176b8851fccSafresh1    my $requested_mechanisms = $sasl->mechanism();
177b8851fccSafresh1    if (! defined($requested_mechanisms) || $requested_mechanisms eq '') {
178b8851fccSafresh1      $sasl->mechanism($mechanisms);
179b8851fccSafresh1    }
180b8851fccSafresh1  }
181b8851fccSafresh1  else {
182b8851fccSafresh1    die "auth(username, password)" if not length $username;
183b8851fccSafresh1    $sasl = Authen::SASL->new(
184b8851fccSafresh1      mechanism => $mechanisms,
185b8851fccSafresh1      callback  => {
186b8851fccSafresh1        user     => $username,
187b8851fccSafresh1        pass     => $password,
188b8851fccSafresh1        authname => $username,
189b8851fccSafresh1      },
190b8851fccSafresh1      debug => $self->debug
191b8851fccSafresh1    );
192b8851fccSafresh1  }
193b8851fccSafresh1
194b8851fccSafresh1  my $client;
195b8851fccSafresh1  my $str;
196b8851fccSafresh1  do {
197b8851fccSafresh1    if ($client) {
198b8851fccSafresh1      # $client mechanism failed, so we need to exclude this mechanism from list
199b8851fccSafresh1      my $failed_mechanism = $client->mechanism;
200b8851fccSafresh1      return unless defined $failed_mechanism;
201b8851fccSafresh1      $self->debug_text("Auth mechanism failed: $failed_mechanism")
202b8851fccSafresh1        if $self->debug;
203b8851fccSafresh1      $mechanisms =~ s/\b\Q$failed_mechanism\E\b//;
204b8851fccSafresh1      return unless $mechanisms =~ /\S/;
205b8851fccSafresh1      $sasl->mechanism($mechanisms);
206b8851fccSafresh1    }
207b8851fccSafresh1
208b8851fccSafresh1    # We should probably allow the user to pass the host, but I don't
209b8851fccSafresh1    # currently know and SASL mechanisms that are used by smtp that need it
210b8851fccSafresh1
211b8851fccSafresh1    $client = $sasl->client_new('smtp', ${*$self}{'net_smtp_host'}, 0);
212b8851fccSafresh1    $str    = $client->client_start;
213b8851fccSafresh1  } while (!defined $str);
214b8851fccSafresh1
215b8851fccSafresh1  # We don't support sasl mechanisms that encrypt the socket traffic.
216b8851fccSafresh1  # todo that we would really need to change the ISA hierarchy
217b8851fccSafresh1  # so we don't inherit from IO::Socket, but instead hold it in an attribute
218b8851fccSafresh1
219b8851fccSafresh1  my @cmd = ("AUTH", $client->mechanism);
220b8851fccSafresh1  my $code;
221b8851fccSafresh1
222b8851fccSafresh1  push @cmd, MIME::Base64::encode_base64($str, '')
223b8851fccSafresh1    if defined $str and length $str;
224b8851fccSafresh1
225b8851fccSafresh1  while (($code = $self->command(@cmd)->response()) == CMD_MORE) {
2265759b3d2Safresh1    my $str2 = MIME::Base64::decode_base64(($self->message)[0]);
2275759b3d2Safresh1    $self->debug_print(0, "(decoded) " . $str2 . "\n") if $self->debug;
2285759b3d2Safresh1
2295759b3d2Safresh1    $str = $client->client_step($str2);
230b8851fccSafresh1    @cmd = (
2315759b3d2Safresh1      MIME::Base64::encode_base64($str, '')
232b8851fccSafresh1    );
2335759b3d2Safresh1
2345759b3d2Safresh1    $self->debug_print(1, "(decoded) " . $str . "\n") if $self->debug;
235b8851fccSafresh1  }
236b8851fccSafresh1
237b8851fccSafresh1  $code == CMD_OK;
238b8851fccSafresh1}
239b8851fccSafresh1
240b8851fccSafresh1
241b8851fccSafresh1sub hello {
242b8851fccSafresh1  my $me     = shift;
243b8851fccSafresh1  my $domain = shift || "localhost.localdomain";
244b8851fccSafresh1  my $ok     = $me->_EHLO($domain);
245b8851fccSafresh1  my @msg    = $me->message;
246b8851fccSafresh1
247b8851fccSafresh1  if ($ok) {
248b8851fccSafresh1    my $h = ${*$me}{'net_smtp_esmtp'} = {};
249b8851fccSafresh1    foreach my $ln (@msg) {
250b8851fccSafresh1      $h->{uc $1} = $2
251b8851fccSafresh1        if $ln =~ /([-\w]+)\b[= \t]*([^\n]*)/;
252b8851fccSafresh1    }
253b8851fccSafresh1  }
254b8851fccSafresh1  elsif ($me->status == CMD_ERROR) {
255b8851fccSafresh1    @msg = $me->message
256b8851fccSafresh1      if $ok = $me->_HELO($domain);
257b8851fccSafresh1  }
258b8851fccSafresh1
259b8851fccSafresh1  return unless $ok;
260b8851fccSafresh1  ${*$me}{net_smtp_hello_domain} = $domain;
261b8851fccSafresh1
262b8851fccSafresh1  $msg[0] =~ /\A\s*(\S+)/;
263b8851fccSafresh1  return ($1 || " ");
264b8851fccSafresh1}
265b8851fccSafresh1
266b8851fccSafresh1sub starttls {
267b8851fccSafresh1  my $self = shift;
268b8851fccSafresh1  $ssl_class or die $nossl_warn;
269b8851fccSafresh1  $self->_STARTTLS or return;
270b8851fccSafresh1  Net::SMTP::_SSL->start_SSL($self,
271b8851fccSafresh1    %{ ${*$self}{'net_smtp_arg'} }, # (ssl) args given in new
272b8851fccSafresh1    @_   # more (ssl) args
273b8851fccSafresh1  ) or return;
274b8851fccSafresh1
275b8851fccSafresh1  # another hello after starttls to read new ESMTP capabilities
276b8851fccSafresh1  return $self->hello(${*$self}{net_smtp_hello_domain});
277b8851fccSafresh1}
278b8851fccSafresh1
279b8851fccSafresh1
280b8851fccSafresh1sub supports {
281b8851fccSafresh1  my $self = shift;
282b8851fccSafresh1  my $cmd  = uc shift;
283b8851fccSafresh1  return ${*$self}{'net_smtp_esmtp'}->{$cmd}
284b8851fccSafresh1    if exists ${*$self}{'net_smtp_esmtp'}->{$cmd};
285b8851fccSafresh1  $self->set_status(@_)
286b8851fccSafresh1    if @_;
287b8851fccSafresh1  return;
288b8851fccSafresh1}
289b8851fccSafresh1
290b8851fccSafresh1
291b8851fccSafresh1sub _addr {
292b8851fccSafresh1  my $self = shift;
293b8851fccSafresh1  my $addr = shift;
294b8851fccSafresh1  $addr = "" unless defined $addr;
295b8851fccSafresh1
296b8851fccSafresh1  if (${*$self}{'net_smtp_exact_addr'}) {
297b8851fccSafresh1    return $1 if $addr =~ /^\s*(<.*>)\s*$/s;
298b8851fccSafresh1  }
299b8851fccSafresh1  else {
300b8851fccSafresh1    return $1 if $addr =~ /(<[^>]*>)/;
301b8851fccSafresh1    $addr =~ s/^\s+|\s+$//sg;
302b8851fccSafresh1  }
303b8851fccSafresh1
304b8851fccSafresh1  "<$addr>";
305b8851fccSafresh1}
306b8851fccSafresh1
307b8851fccSafresh1
308b8851fccSafresh1sub mail {
309b8851fccSafresh1  my $me   = shift;
310b8851fccSafresh1  my $addr = _addr($me, shift);
311b8851fccSafresh1  my $opts = "";
312b8851fccSafresh1
313b8851fccSafresh1  if (@_) {
314b8851fccSafresh1    my %opt = @_;
315b8851fccSafresh1    my ($k, $v);
316b8851fccSafresh1
317b8851fccSafresh1    if (exists ${*$me}{'net_smtp_esmtp'}) {
318b8851fccSafresh1      my $esmtp = ${*$me}{'net_smtp_esmtp'};
319b8851fccSafresh1
320b8851fccSafresh1      if (defined($v = delete $opt{Size})) {
321b8851fccSafresh1        if (exists $esmtp->{SIZE}) {
322b8851fccSafresh1          $opts .= sprintf " SIZE=%d", $v + 0;
323b8851fccSafresh1        }
324b8851fccSafresh1        else {
325b8851fccSafresh1          carp 'Net::SMTP::mail: SIZE option not supported by host';
326b8851fccSafresh1        }
327b8851fccSafresh1      }
328b8851fccSafresh1
329b8851fccSafresh1      if (defined($v = delete $opt{Return})) {
330b8851fccSafresh1        if (exists $esmtp->{DSN}) {
331b8851fccSafresh1          $opts .= " RET=" . ((uc($v) eq "FULL") ? "FULL" : "HDRS");
332b8851fccSafresh1        }
333b8851fccSafresh1        else {
334b8851fccSafresh1          carp 'Net::SMTP::mail: DSN option not supported by host';
335b8851fccSafresh1        }
336b8851fccSafresh1      }
337b8851fccSafresh1
338b8851fccSafresh1      if (defined($v = delete $opt{Bits})) {
339b8851fccSafresh1        if ($v eq "8") {
340b8851fccSafresh1          if (exists $esmtp->{'8BITMIME'}) {
341b8851fccSafresh1            $opts .= " BODY=8BITMIME";
342b8851fccSafresh1          }
343b8851fccSafresh1          else {
344b8851fccSafresh1            carp 'Net::SMTP::mail: 8BITMIME option not supported by host';
345b8851fccSafresh1          }
346b8851fccSafresh1        }
347b8851fccSafresh1        elsif ($v eq "binary") {
348b8851fccSafresh1          if (exists $esmtp->{'BINARYMIME'} && exists $esmtp->{'CHUNKING'}) {
349b8851fccSafresh1            $opts .= " BODY=BINARYMIME";
350b8851fccSafresh1            ${*$me}{'net_smtp_chunking'} = 1;
351b8851fccSafresh1          }
352b8851fccSafresh1          else {
353b8851fccSafresh1            carp 'Net::SMTP::mail: BINARYMIME option not supported by host';
354b8851fccSafresh1          }
355b8851fccSafresh1        }
356b8851fccSafresh1        elsif (exists $esmtp->{'8BITMIME'} or exists $esmtp->{'BINARYMIME'}) {
357b8851fccSafresh1          $opts .= " BODY=7BIT";
358b8851fccSafresh1        }
359b8851fccSafresh1        else {
360b8851fccSafresh1          carp 'Net::SMTP::mail: 8BITMIME and BINARYMIME options not supported by host';
361b8851fccSafresh1        }
362b8851fccSafresh1      }
363b8851fccSafresh1
364b8851fccSafresh1      if (defined($v = delete $opt{Transaction})) {
365b8851fccSafresh1        if (exists $esmtp->{CHECKPOINT}) {
366b8851fccSafresh1          $opts .= " TRANSID=" . _addr($me, $v);
367b8851fccSafresh1        }
368b8851fccSafresh1        else {
369b8851fccSafresh1          carp 'Net::SMTP::mail: CHECKPOINT option not supported by host';
370b8851fccSafresh1        }
371b8851fccSafresh1      }
372b8851fccSafresh1
373b8851fccSafresh1      if (defined($v = delete $opt{Envelope})) {
374b8851fccSafresh1        if (exists $esmtp->{DSN}) {
375b8851fccSafresh1          $v =~ s/([^\041-\176]|=|\+)/sprintf "+%02X", ord($1)/sge;
376b8851fccSafresh1          $opts .= " ENVID=$v";
377b8851fccSafresh1        }
378b8851fccSafresh1        else {
379b8851fccSafresh1          carp 'Net::SMTP::mail: DSN option not supported by host';
380b8851fccSafresh1        }
381b8851fccSafresh1      }
382b8851fccSafresh1
383b8851fccSafresh1      if (defined($v = delete $opt{ENVID})) {
384b8851fccSafresh1
385b8851fccSafresh1        # expected to be in a format as required by RFC 3461, xtext-encoded
386b8851fccSafresh1        if (exists $esmtp->{DSN}) {
387b8851fccSafresh1          $opts .= " ENVID=$v";
388b8851fccSafresh1        }
389b8851fccSafresh1        else {
390b8851fccSafresh1          carp 'Net::SMTP::mail: DSN option not supported by host';
391b8851fccSafresh1        }
392b8851fccSafresh1      }
393b8851fccSafresh1
394b8851fccSafresh1      if (defined($v = delete $opt{AUTH})) {
395b8851fccSafresh1
396b8851fccSafresh1        # expected to be in a format as required by RFC 2554,
397b8851fccSafresh1        # rfc2821-quoted and xtext-encoded, or <>
398b8851fccSafresh1        if (exists $esmtp->{AUTH}) {
399b8851fccSafresh1          $v = '<>' if !defined($v) || $v eq '';
400b8851fccSafresh1          $opts .= " AUTH=$v";
401b8851fccSafresh1        }
402b8851fccSafresh1        else {
403b8851fccSafresh1          carp 'Net::SMTP::mail: AUTH option not supported by host';
404b8851fccSafresh1        }
405b8851fccSafresh1      }
406b8851fccSafresh1
407b8851fccSafresh1      if (defined($v = delete $opt{XVERP})) {
408b8851fccSafresh1        if (exists $esmtp->{'XVERP'}) {
409b8851fccSafresh1          $opts .= " XVERP";
410b8851fccSafresh1        }
411b8851fccSafresh1        else {
412b8851fccSafresh1          carp 'Net::SMTP::mail: XVERP option not supported by host';
413b8851fccSafresh1        }
414b8851fccSafresh1      }
415b8851fccSafresh1
416b8851fccSafresh1      carp 'Net::SMTP::recipient: unknown option(s) ' . join(" ", keys %opt) . ' - ignored'
417b8851fccSafresh1        if scalar keys %opt;
418b8851fccSafresh1    }
419b8851fccSafresh1    else {
420b8851fccSafresh1      carp 'Net::SMTP::mail: ESMTP not supported by host - options discarded :-(';
421b8851fccSafresh1    }
422b8851fccSafresh1  }
423b8851fccSafresh1
424b8851fccSafresh1  $me->_MAIL("FROM:" . $addr . $opts);
425b8851fccSafresh1}
426b8851fccSafresh1
427b8851fccSafresh1
428b8851fccSafresh1sub send          { my $me = shift; $me->_SEND("FROM:" . _addr($me, $_[0])) }
429b8851fccSafresh1sub send_or_mail  { my $me = shift; $me->_SOML("FROM:" . _addr($me, $_[0])) }
430b8851fccSafresh1sub send_and_mail { my $me = shift; $me->_SAML("FROM:" . _addr($me, $_[0])) }
431b8851fccSafresh1
432b8851fccSafresh1
433b8851fccSafresh1sub reset {
434b8851fccSafresh1  my $me = shift;
435b8851fccSafresh1
436b8851fccSafresh1  $me->dataend()
437b8851fccSafresh1    if (exists ${*$me}{'net_smtp_lastch'});
438b8851fccSafresh1
439b8851fccSafresh1  $me->_RSET();
440b8851fccSafresh1}
441b8851fccSafresh1
442b8851fccSafresh1
443b8851fccSafresh1sub recipient {
444b8851fccSafresh1  my $smtp     = shift;
445b8851fccSafresh1  my $opts     = "";
446b8851fccSafresh1  my $skip_bad = 0;
447b8851fccSafresh1
448b8851fccSafresh1  if (@_ && ref($_[-1])) {
449b8851fccSafresh1    my %opt = %{pop(@_)};
450b8851fccSafresh1    my $v;
451b8851fccSafresh1
452b8851fccSafresh1    $skip_bad = delete $opt{'SkipBad'};
453b8851fccSafresh1
454b8851fccSafresh1    if (exists ${*$smtp}{'net_smtp_esmtp'}) {
455b8851fccSafresh1      my $esmtp = ${*$smtp}{'net_smtp_esmtp'};
456b8851fccSafresh1
457b8851fccSafresh1      if (defined($v = delete $opt{Notify})) {
458b8851fccSafresh1        if (exists $esmtp->{DSN}) {
459b8851fccSafresh1          $opts .= " NOTIFY=" . join(",", map { uc $_ } @$v);
460b8851fccSafresh1        }
461b8851fccSafresh1        else {
462b8851fccSafresh1          carp 'Net::SMTP::recipient: DSN option not supported by host';
463b8851fccSafresh1        }
464b8851fccSafresh1      }
465b8851fccSafresh1
466b8851fccSafresh1      if (defined($v = delete $opt{ORcpt})) {
467b8851fccSafresh1        if (exists $esmtp->{DSN}) {
468b8851fccSafresh1          $opts .= " ORCPT=" . $v;
469b8851fccSafresh1        }
470b8851fccSafresh1        else {
471b8851fccSafresh1          carp 'Net::SMTP::recipient: DSN option not supported by host';
472b8851fccSafresh1        }
473b8851fccSafresh1      }
474b8851fccSafresh1
475b8851fccSafresh1      carp 'Net::SMTP::recipient: unknown option(s) ' . join(" ", keys %opt) . ' - ignored'
476b8851fccSafresh1        if scalar keys %opt;
477b8851fccSafresh1    }
478b8851fccSafresh1    elsif (%opt) {
479b8851fccSafresh1      carp 'Net::SMTP::recipient: ESMTP not supported by host - options discarded :-(';
480b8851fccSafresh1    }
481b8851fccSafresh1  }
482b8851fccSafresh1
483b8851fccSafresh1  my @ok;
484b8851fccSafresh1  foreach my $addr (@_) {
485b8851fccSafresh1    if ($smtp->_RCPT("TO:" . _addr($smtp, $addr) . $opts)) {
486b8851fccSafresh1      push(@ok, $addr) if $skip_bad;
487b8851fccSafresh1    }
488b8851fccSafresh1    elsif (!$skip_bad) {
489b8851fccSafresh1      return 0;
490b8851fccSafresh1    }
491b8851fccSafresh1  }
492b8851fccSafresh1
493b8851fccSafresh1  return $skip_bad ? @ok : 1;
494b8851fccSafresh1}
495b8851fccSafresh1
496b8851fccSafresh1BEGIN {
497b8851fccSafresh1  *to  = \&recipient;
498b8851fccSafresh1  *cc  = \&recipient;
499b8851fccSafresh1  *bcc = \&recipient;
500b8851fccSafresh1}
501b8851fccSafresh1
502b8851fccSafresh1
503b8851fccSafresh1sub data {
504b8851fccSafresh1  my $me = shift;
505b8851fccSafresh1
506b8851fccSafresh1  if (exists ${*$me}{'net_smtp_chunking'}) {
507b8851fccSafresh1    carp 'Net::SMTP::data: CHUNKING extension in use, must call bdat instead';
508b8851fccSafresh1  }
509b8851fccSafresh1  else {
510b8851fccSafresh1    my $ok = $me->_DATA() && $me->datasend(@_);
511b8851fccSafresh1
512b8851fccSafresh1    $ok && @_
513b8851fccSafresh1      ? $me->dataend
514b8851fccSafresh1      : $ok;
515b8851fccSafresh1  }
516b8851fccSafresh1}
517b8851fccSafresh1
518b8851fccSafresh1
519b8851fccSafresh1sub bdat {
520b8851fccSafresh1  my $me = shift;
521b8851fccSafresh1
522b8851fccSafresh1  if (exists ${*$me}{'net_smtp_chunking'}) {
523b8851fccSafresh1    my $data = shift;
524b8851fccSafresh1
525b8851fccSafresh1    $me->_BDAT(length $data)
526b8851fccSafresh1      && $me->rawdatasend($data)
527b8851fccSafresh1      && $me->response() == CMD_OK;
528b8851fccSafresh1  }
529b8851fccSafresh1  else {
530b8851fccSafresh1    carp 'Net::SMTP::bdat: CHUNKING extension is not in use, call data instead';
531b8851fccSafresh1  }
532b8851fccSafresh1}
533b8851fccSafresh1
534b8851fccSafresh1
535b8851fccSafresh1sub bdatlast {
536b8851fccSafresh1  my $me = shift;
537b8851fccSafresh1
538b8851fccSafresh1  if (exists ${*$me}{'net_smtp_chunking'}) {
539b8851fccSafresh1    my $data = shift;
540b8851fccSafresh1
541b8851fccSafresh1    $me->_BDAT(length $data, "LAST")
542b8851fccSafresh1      && $me->rawdatasend($data)
543b8851fccSafresh1      && $me->response() == CMD_OK;
544b8851fccSafresh1  }
545b8851fccSafresh1  else {
546b8851fccSafresh1    carp 'Net::SMTP::bdat: CHUNKING extension is not in use, call data instead';
547b8851fccSafresh1  }
548b8851fccSafresh1}
549b8851fccSafresh1
550b8851fccSafresh1
551b8851fccSafresh1sub datafh {
552b8851fccSafresh1  my $me = shift;
553b8851fccSafresh1  return unless $me->_DATA();
554b8851fccSafresh1  return $me->tied_fh;
555b8851fccSafresh1}
556b8851fccSafresh1
557b8851fccSafresh1
558b8851fccSafresh1sub expand {
559b8851fccSafresh1  my $me = shift;
560b8851fccSafresh1
561b8851fccSafresh1  $me->_EXPN(@_)
562b8851fccSafresh1    ? ($me->message)
563b8851fccSafresh1    : ();
564b8851fccSafresh1}
565b8851fccSafresh1
566b8851fccSafresh1
567b8851fccSafresh1sub verify { shift->_VRFY(@_) }
568b8851fccSafresh1
569b8851fccSafresh1
570b8851fccSafresh1sub help {
571b8851fccSafresh1  my $me = shift;
572b8851fccSafresh1
573b8851fccSafresh1  $me->_HELP(@_)
574b8851fccSafresh1    ? scalar $me->message
575b8851fccSafresh1    : undef;
576b8851fccSafresh1}
577b8851fccSafresh1
578b8851fccSafresh1
579b8851fccSafresh1sub quit {
580b8851fccSafresh1  my $me = shift;
581b8851fccSafresh1
582b8851fccSafresh1  $me->_QUIT;
583b8851fccSafresh1  $me->close;
584b8851fccSafresh1}
585b8851fccSafresh1
586b8851fccSafresh1
587b8851fccSafresh1sub DESTROY {
588b8851fccSafresh1
589b8851fccSafresh1  # ignore
590b8851fccSafresh1}
591b8851fccSafresh1
592b8851fccSafresh1##
593b8851fccSafresh1## RFC821 commands
594b8851fccSafresh1##
595b8851fccSafresh1
596b8851fccSafresh1
597b8851fccSafresh1sub _EHLO { shift->command("EHLO", @_)->response() == CMD_OK }
598b8851fccSafresh1sub _HELO { shift->command("HELO", @_)->response() == CMD_OK }
599b8851fccSafresh1sub _MAIL { shift->command("MAIL", @_)->response() == CMD_OK }
600b8851fccSafresh1sub _RCPT { shift->command("RCPT", @_)->response() == CMD_OK }
601b8851fccSafresh1sub _SEND { shift->command("SEND", @_)->response() == CMD_OK }
602b8851fccSafresh1sub _SAML { shift->command("SAML", @_)->response() == CMD_OK }
603b8851fccSafresh1sub _SOML { shift->command("SOML", @_)->response() == CMD_OK }
604b8851fccSafresh1sub _VRFY { shift->command("VRFY", @_)->response() == CMD_OK }
605b8851fccSafresh1sub _EXPN { shift->command("EXPN", @_)->response() == CMD_OK }
606b8851fccSafresh1sub _HELP { shift->command("HELP", @_)->response() == CMD_OK }
607b8851fccSafresh1sub _RSET { shift->command("RSET")->response() == CMD_OK }
608b8851fccSafresh1sub _NOOP { shift->command("NOOP")->response() == CMD_OK }
609b8851fccSafresh1sub _QUIT { shift->command("QUIT")->response() == CMD_OK }
610b8851fccSafresh1sub _DATA { shift->command("DATA")->response() == CMD_MORE }
611b8851fccSafresh1sub _BDAT { shift->command("BDAT", @_) }
612b8851fccSafresh1sub _TURN { shift->unsupported(@_); }
613b8851fccSafresh1sub _ETRN { shift->command("ETRN", @_)->response() == CMD_OK }
614b8851fccSafresh1sub _AUTH { shift->command("AUTH", @_)->response() == CMD_OK }
615b8851fccSafresh1sub _STARTTLS { shift->command("STARTTLS")->response() == CMD_OK }
616b8851fccSafresh1
617b8851fccSafresh1
618b8851fccSafresh1{
619b8851fccSafresh1  package Net::SMTP::_SSL;
620b8851fccSafresh1  our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::SMTP' );
621b8851fccSafresh1  sub starttls { die "SMTP connection is already in SSL mode" }
622b8851fccSafresh1  sub start_SSL {
623b8851fccSafresh1    my ($class,$smtp,%arg) = @_;
624b8851fccSafresh1    delete @arg{ grep { !m{^SSL_} } keys %arg };
625b8851fccSafresh1    ( $arg{SSL_verifycn_name} ||= $smtp->host )
626b8851fccSafresh1        =~s{(?<!:):[\w()]+$}{}; # strip port
627b8851fccSafresh1    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
628b8851fccSafresh1        if ! defined $arg{SSL_hostname} && $class->can_client_sni;
629b8851fccSafresh1    $arg{SSL_verifycn_scheme} ||= 'smtp';
630b8851fccSafresh1    my $ok = $class->SUPER::start_SSL($smtp,%arg);
631b8851fccSafresh1    $@ = $ssl_class->errstr if !$ok;
632b8851fccSafresh1    return $ok;
633b8851fccSafresh1  }
634b8851fccSafresh1}
635b8851fccSafresh1
636b8851fccSafresh1
637b8851fccSafresh1
638b8851fccSafresh11;
639b8851fccSafresh1
640b8851fccSafresh1__END__
641b8851fccSafresh1
642b8851fccSafresh1=head1 NAME
643b8851fccSafresh1
644b8851fccSafresh1Net::SMTP - Simple Mail Transfer Protocol Client
645b8851fccSafresh1
646b8851fccSafresh1=head1 SYNOPSIS
647b8851fccSafresh1
648b8851fccSafresh1    use Net::SMTP;
649b8851fccSafresh1
650b8851fccSafresh1    # Constructors
651b8851fccSafresh1    $smtp = Net::SMTP->new('mailhost');
652b8851fccSafresh1    $smtp = Net::SMTP->new('mailhost', Timeout => 60);
653b8851fccSafresh1
654b8851fccSafresh1=head1 DESCRIPTION
655b8851fccSafresh1
656b8851fccSafresh1This module implements a client interface to the SMTP and ESMTP
657b8851fccSafresh1protocol, enabling a perl5 application to talk to SMTP servers. This
658b8851fccSafresh1documentation assumes that you are familiar with the concepts of the
659b8851fccSafresh1SMTP protocol described in RFC2821.
660b8851fccSafresh1With L<IO::Socket::SSL> installed it also provides support for implicit and
661b8851fccSafresh1explicit TLS encryption, i.e. SMTPS or SMTP+STARTTLS.
662b8851fccSafresh1
663b8851fccSafresh1The Net::SMTP class is a subclass of Net::Cmd and (depending on avaibility) of
664b8851fccSafresh1IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
665b8851fccSafresh1
666eac174f2Safresh1=head2 Class Methods
667b8851fccSafresh1
668b8851fccSafresh1=over 4
669b8851fccSafresh1
670eac174f2Safresh1=item C<new([$host][, %options])>
671b8851fccSafresh1
672eac174f2Safresh1This is the constructor for a new Net::SMTP object. C<$host> is the
673b8851fccSafresh1name of the remote host to which an SMTP connection is required.
674b8851fccSafresh1
675b8851fccSafresh1On failure C<undef> will be returned and C<$@> will contain the reason
676b8851fccSafresh1for the failure.
677b8851fccSafresh1
678eac174f2Safresh1C<$host> is optional. If C<$host> is not given then it may instead be
679b8851fccSafresh1passed as the C<Host> option described below. If neither is given then
680b8851fccSafresh1the C<SMTP_Hosts> specified in C<Net::Config> will be used.
681b8851fccSafresh1
682eac174f2Safresh1C<%options> are passed in a hash like fashion, using key and value pairs.
683b8851fccSafresh1Possible options are:
684b8851fccSafresh1
685b8851fccSafresh1B<Hello> - SMTP requires that you identify yourself. This option
686b8851fccSafresh1specifies a string to pass as your mail domain. If not given localhost.localdomain
687b8851fccSafresh1will be used.
688b8851fccSafresh1
689b8851fccSafresh1B<SendHello> - If false then the EHLO (or HELO) command that is normally sent
690b8851fccSafresh1when constructing the object will not be sent. In that case the command will
691b8851fccSafresh1have to be sent manually by calling C<hello()> instead.
692b8851fccSafresh1
693b8851fccSafresh1B<Host> - SMTP host to connect to. It may be a single scalar (hostname[:port]),
694b8851fccSafresh1as defined for the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
695b8851fccSafresh1an array with hosts to try in turn. The L</host> method will return the value
696b8851fccSafresh1which was used to connect to the host.
697b8851fccSafresh1Format - C<PeerHost> from L<IO::Socket::INET> new method.
698b8851fccSafresh1
699b8851fccSafresh1B<Port> - port to connect to.
700b8851fccSafresh1Default - 25 for plain SMTP and 465 for immediate SSL.
701b8851fccSafresh1
702b8851fccSafresh1B<SSL> - If the connection should be done from start with SSL, contrary to later
703b8851fccSafresh1upgrade with C<starttls>.
704b8851fccSafresh1You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
705b8851fccSafresh1usually use the right arguments already.
706b8851fccSafresh1
707b8851fccSafresh1B<LocalAddr> and B<LocalPort> - These parameters are passed directly
708b8851fccSafresh1to IO::Socket to allow binding the socket to a specific local address and port.
709b8851fccSafresh1
710b8851fccSafresh1B<Domain> - This parameter is passed directly to IO::Socket and makes it
711b8851fccSafresh1possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
712b8851fccSafresh1class. Alternatively B<Family> can be used.
713b8851fccSafresh1
714b8851fccSafresh1B<Timeout> - Maximum time, in seconds, to wait for a response from the
715b8851fccSafresh1SMTP server (default: 120)
716b8851fccSafresh1
717eac174f2Safresh1B<ExactAddresses> - If true then all C<$address> arguments must be as
718b8851fccSafresh1defined by C<addr-spec> in RFC2822. If not given, or false, then
719b8851fccSafresh1Net::SMTP will attempt to extract the address from the value passed.
720b8851fccSafresh1
721b8851fccSafresh1B<Debug> - Enable debugging information
722b8851fccSafresh1
723b8851fccSafresh1Example:
724b8851fccSafresh1
725b8851fccSafresh1    $smtp = Net::SMTP->new('mailhost',
726b8851fccSafresh1                           Hello => 'my.mail.domain',
727b8851fccSafresh1                           Timeout => 30,
728b8851fccSafresh1                           Debug   => 1,
729b8851fccSafresh1                          );
730b8851fccSafresh1
731b8851fccSafresh1    # the same
732b8851fccSafresh1    $smtp = Net::SMTP->new(
733b8851fccSafresh1                           Host => 'mailhost',
734b8851fccSafresh1                           Hello => 'my.mail.domain',
735b8851fccSafresh1                           Timeout => 30,
736b8851fccSafresh1                           Debug   => 1,
737b8851fccSafresh1                          );
738b8851fccSafresh1
739b8851fccSafresh1    # the same with direct SSL
740b8851fccSafresh1    $smtp = Net::SMTP->new('mailhost',
741b8851fccSafresh1                           Hello => 'my.mail.domain',
742b8851fccSafresh1                           Timeout => 30,
743b8851fccSafresh1                           Debug   => 1,
744b8851fccSafresh1                           SSL     => 1,
745b8851fccSafresh1                          );
746b8851fccSafresh1
747b8851fccSafresh1    # Connect to the default server from Net::config
748b8851fccSafresh1    $smtp = Net::SMTP->new(
749b8851fccSafresh1                           Hello => 'my.mail.domain',
750b8851fccSafresh1                           Timeout => 30,
751b8851fccSafresh1                          );
752b8851fccSafresh1
753b8851fccSafresh1=back
754b8851fccSafresh1
755eac174f2Safresh1=head1 Object Methods
756b8851fccSafresh1
757b8851fccSafresh1Unless otherwise stated all methods return either a I<true> or I<false>
758b8851fccSafresh1value, with I<true> meaning that the operation was a success. When a method
759b8851fccSafresh1states that it returns a value, failure will be returned as I<undef> or an
760b8851fccSafresh1empty list.
761b8851fccSafresh1
762b8851fccSafresh1C<Net::SMTP> inherits from C<Net::Cmd> so methods defined in C<Net::Cmd> may
763b8851fccSafresh1be used to send commands to the remote SMTP server in addition to the methods
764b8851fccSafresh1documented here.
765b8851fccSafresh1
766b8851fccSafresh1=over 4
767b8851fccSafresh1
768eac174f2Safresh1=item C<banner()>
769b8851fccSafresh1
770b8851fccSafresh1Returns the banner message which the server replied with when the
771b8851fccSafresh1initial connection was made.
772b8851fccSafresh1
773eac174f2Safresh1=item C<domain()>
774b8851fccSafresh1
775b8851fccSafresh1Returns the domain that the remote SMTP server identified itself as during
776b8851fccSafresh1connection.
777b8851fccSafresh1
778eac174f2Safresh1=item C<hello($domain)>
779b8851fccSafresh1
780b8851fccSafresh1Tell the remote server the mail domain which you are in using the EHLO
781b8851fccSafresh1command (or HELO if EHLO fails).  Since this method is invoked
782b8851fccSafresh1automatically when the Net::SMTP object is constructed the user should
783b8851fccSafresh1normally not have to call it manually.
784b8851fccSafresh1
785eac174f2Safresh1=item C<host()>
786b8851fccSafresh1
787b8851fccSafresh1Returns the value used by the constructor, and passed to IO::Socket::INET,
788b8851fccSafresh1to connect to the host.
789b8851fccSafresh1
790eac174f2Safresh1=item C<etrn($domain)>
791b8851fccSafresh1
792eac174f2Safresh1Request a queue run for the C<$domain> given.
793b8851fccSafresh1
794eac174f2Safresh1=item C<starttls(%sslargs)>
795b8851fccSafresh1
796b8851fccSafresh1Upgrade existing plain connection to SSL.
797b8851fccSafresh1You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
798b8851fccSafresh1usually use the right arguments already.
799b8851fccSafresh1
800eac174f2Safresh1=item C<auth($username, $password)>
801b8851fccSafresh1
802eac174f2Safresh1=item C<auth($sasl)>
803b8851fccSafresh1
804b8851fccSafresh1Attempt SASL authentication. Requires Authen::SASL module. The first form
805b8851fccSafresh1constructs a new Authen::SASL object using the given username and password;
806b8851fccSafresh1the second form uses the given Authen::SASL object.
807b8851fccSafresh1
808eac174f2Safresh1=item C<mail($address[, %options])>
809b8851fccSafresh1
810eac174f2Safresh1=item C<send($address)>
811b8851fccSafresh1
812eac174f2Safresh1=item C<send_or_mail($address)>
813b8851fccSafresh1
814eac174f2Safresh1=item C<send_and_mail($address)>
815b8851fccSafresh1
816eac174f2Safresh1Send the appropriate command to the server MAIL, SEND, SOML or SAML. C<$address>
817b8851fccSafresh1is the address of the sender. This initiates the sending of a message. The
818b8851fccSafresh1method C<recipient> should be called for each address that the message is to
819b8851fccSafresh1be sent to.
820b8851fccSafresh1
821eac174f2Safresh1The C<mail> method can take some additional ESMTP C<%options> which is passed
822b8851fccSafresh1in hash like fashion, using key and value pairs.  Possible options are:
823b8851fccSafresh1
824b8851fccSafresh1 Size        => <bytes>
825b8851fccSafresh1 Return      => "FULL" | "HDRS"
826b8851fccSafresh1 Bits        => "7" | "8" | "binary"
827b8851fccSafresh1 Transaction => <ADDRESS>
828b8851fccSafresh1 Envelope    => <ENVID>     # xtext-encodes its argument
829b8851fccSafresh1 ENVID       => <ENVID>     # similar to Envelope, but expects argument encoded
830b8851fccSafresh1 XVERP       => 1
831b8851fccSafresh1 AUTH        => <submitter> # encoded address according to RFC 2554
832b8851fccSafresh1
833b8851fccSafresh1The C<Return> and C<Envelope> parameters are used for DSN (Delivery
834b8851fccSafresh1Status Notification).
835b8851fccSafresh1
836b8851fccSafresh1The submitter address in C<AUTH> option is expected to be in a format as
837b8851fccSafresh1required by RFC 2554, in an RFC2821-quoted form and xtext-encoded, or <> .
838b8851fccSafresh1
839eac174f2Safresh1=item C<reset()>
840b8851fccSafresh1
841b8851fccSafresh1Reset the status of the server. This may be called after a message has been
842b8851fccSafresh1initiated, but before any data has been sent, to cancel the sending of the
843b8851fccSafresh1message.
844b8851fccSafresh1
845eac174f2Safresh1=item C<recipient($address[, $address[, ...]][, %options])>
846b8851fccSafresh1
847b8851fccSafresh1Notify the server that the current message should be sent to all of the
848b8851fccSafresh1addresses given. Each address is sent as a separate command to the server.
849b8851fccSafresh1Should the sending of any address result in a failure then the process is
850b8851fccSafresh1aborted and a I<false> value is returned. It is up to the user to call
851b8851fccSafresh1C<reset> if they so desire.
852b8851fccSafresh1
853eac174f2Safresh1The C<recipient> method can also pass additional case-sensitive C<%options> as an
854b8851fccSafresh1anonymous hash using key and value pairs.  Possible options are:
855b8851fccSafresh1
856b8851fccSafresh1  Notify  => ['NEVER'] or ['SUCCESS','FAILURE','DELAY']  (see below)
857b8851fccSafresh1  ORcpt   => <ORCPT>
858b8851fccSafresh1  SkipBad => 1        (to ignore bad addresses)
859b8851fccSafresh1
860b8851fccSafresh1If C<SkipBad> is true the C<recipient> will not return an error when a bad
861b8851fccSafresh1address is encountered and it will return an array of addresses that did
862b8851fccSafresh1succeed.
863b8851fccSafresh1
864b8851fccSafresh1  $smtp->recipient($recipient1,$recipient2);  # Good
865b8851fccSafresh1  $smtp->recipient($recipient1,$recipient2, { SkipBad => 1 });  # Good
866b8851fccSafresh1  $smtp->recipient($recipient1,$recipient2, { Notify => ['FAILURE','DELAY'], SkipBad => 1 });  # Good
867b8851fccSafresh1  @goodrecips=$smtp->recipient(@recipients, { Notify => ['FAILURE'], SkipBad => 1 });  # Good
868b8851fccSafresh1  $smtp->recipient("$recipient,$recipient2"); # BAD
869b8851fccSafresh1
870b8851fccSafresh1Notify is used to request Delivery Status Notifications (DSNs), but your
871b8851fccSafresh1SMTP/ESMTP service may not respect this request depending upon its version and
872b8851fccSafresh1your site's SMTP configuration.
873b8851fccSafresh1
874b8851fccSafresh1Leaving out the Notify option usually defaults an SMTP service to its default
875b8851fccSafresh1behavior equivalent to ['FAILURE'] notifications only, but again this may be
876b8851fccSafresh1dependent upon your site's SMTP configuration.
877b8851fccSafresh1
878b8851fccSafresh1The NEVER keyword must appear by itself if used within the Notify option and "requests
879b8851fccSafresh1that a DSN not be returned to the sender under any conditions."
880b8851fccSafresh1
881b8851fccSafresh1  {Notify => ['NEVER']}
882b8851fccSafresh1
883b8851fccSafresh1  $smtp->recipient(@recipients, { Notify => ['NEVER'], SkipBad => 1 });  # Good
884b8851fccSafresh1
885b8851fccSafresh1You may use any combination of these three values 'SUCCESS','FAILURE','DELAY' in
886eac174f2Safresh1the anonymous array reference as defined by RFC3461 (see
887eac174f2Safresh1L<https://www.ietf.org/rfc/rfc3461.txt> for more information.  Note: quotations
888eac174f2Safresh1in this topic from same.).
889b8851fccSafresh1
890b8851fccSafresh1A Notify parameter of 'SUCCESS' or 'FAILURE' "requests that a DSN be issued on
891b8851fccSafresh1successful delivery or delivery failure, respectively."
892b8851fccSafresh1
893b8851fccSafresh1A Notify parameter of 'DELAY' "indicates the sender's willingness to receive
894b8851fccSafresh1delayed DSNs.  Delayed DSNs may be issued if delivery of a message has been
895b8851fccSafresh1delayed for an unusual amount of time (as determined by the Message Transfer
896b8851fccSafresh1Agent (MTA) at which the message is delayed), but the final delivery status
897b8851fccSafresh1(whether successful or failure) cannot be determined.  The absence of the DELAY
898b8851fccSafresh1keyword in a NOTIFY parameter requests that a "delayed" DSN NOT be issued under
899b8851fccSafresh1any conditions."
900b8851fccSafresh1
901b8851fccSafresh1  {Notify => ['SUCCESS','FAILURE','DELAY']}
902b8851fccSafresh1
903b8851fccSafresh1  $smtp->recipient(@recipients, { Notify => ['FAILURE','DELAY'], SkipBad => 1 });  # Good
904b8851fccSafresh1
905b8851fccSafresh1ORcpt is also part of the SMTP DSN extension according to RFC3461.
906b8851fccSafresh1It is used to pass along the original recipient that the mail was first
907b8851fccSafresh1sent to.  The machine that generates a DSN will use this address to inform
908b8851fccSafresh1the sender, because he can't know if recipients get rewritten by mail servers.
909b8851fccSafresh1It is expected to be in a format as required by RFC3461, xtext-encoded.
910b8851fccSafresh1
911eac174f2Safresh1=item C<to($address[, $address[, ...]])>
912b8851fccSafresh1
913eac174f2Safresh1=item C<cc($address[, $address[, ...]])>
914b8851fccSafresh1
915eac174f2Safresh1=item C<bcc($address[, $address[, ...]])>
916b8851fccSafresh1
917b8851fccSafresh1Synonyms for C<recipient>.
918b8851fccSafresh1
919eac174f2Safresh1=item C<data([$data])>
920b8851fccSafresh1
921b8851fccSafresh1Initiate the sending of the data from the current message.
922b8851fccSafresh1
923eac174f2Safresh1C<$data> may be a reference to a list or a list and must be encoded by the
924b8851fccSafresh1caller to octets of whatever encoding is required, e.g. by using the Encode
925b8851fccSafresh1module's C<encode()> function.
926b8851fccSafresh1
927eac174f2Safresh1If specified the contents of C<$data> and a termination string C<".\r\n"> is
928b8851fccSafresh1sent to the server. The result will be true if the data was accepted.
929b8851fccSafresh1
930eac174f2Safresh1If C<$data> is not specified then the result will indicate that the server
931b8851fccSafresh1wishes the data to be sent. The data must then be sent using the C<datasend>
932b8851fccSafresh1and C<dataend> methods described in L<Net::Cmd>.
933b8851fccSafresh1
934eac174f2Safresh1=item C<bdat($data)>
935b8851fccSafresh1
936eac174f2Safresh1=item C<bdatlast($data)>
937b8851fccSafresh1
938eac174f2Safresh1Use the alternate C<$data> command "BDAT" of the data chunking service extension
939b8851fccSafresh1defined in RFC1830 for efficiently sending large MIME messages.
940b8851fccSafresh1
941eac174f2Safresh1=item C<expand($address)>
942b8851fccSafresh1
943b8851fccSafresh1Request the server to expand the given address Returns an array
944b8851fccSafresh1which contains the text read from the server.
945b8851fccSafresh1
946eac174f2Safresh1=item C<verify($address)>
947b8851fccSafresh1
948eac174f2Safresh1Verify that C<$address> is a legitimate mailing address.
949b8851fccSafresh1
950b8851fccSafresh1Most sites usually disable this feature in their SMTP service configuration.
951b8851fccSafresh1Use "Debug => 1" option under new() to see if disabled.
952b8851fccSafresh1
953eac174f2Safresh1=item C<help([$subject])>
954b8851fccSafresh1
955b8851fccSafresh1Request help text from the server. Returns the text or undef upon failure
956b8851fccSafresh1
957eac174f2Safresh1=item C<quit()>
958b8851fccSafresh1
959b8851fccSafresh1Send the QUIT command to the remote SMTP server and close the socket connection.
960b8851fccSafresh1
961eac174f2Safresh1=item C<can_inet6()>
962b8851fccSafresh1
963b8851fccSafresh1Returns whether we can use IPv6.
964b8851fccSafresh1
965eac174f2Safresh1=item C<can_ssl()>
966b8851fccSafresh1
967b8851fccSafresh1Returns whether we can use SSL.
968b8851fccSafresh1
969b8851fccSafresh1=back
970b8851fccSafresh1
971eac174f2Safresh1=head2 Addresses
972b8851fccSafresh1
973b8851fccSafresh1Net::SMTP attempts to DWIM with addresses that are passed. For
974b8851fccSafresh1example an application might extract The From: line from an email
975b8851fccSafresh1and pass that to mail(). While this may work, it is not recommended.
976b8851fccSafresh1The application should really use a module like L<Mail::Address>
977b8851fccSafresh1to extract the mail address and pass that.
978b8851fccSafresh1
979b8851fccSafresh1If C<ExactAddresses> is passed to the constructor, then addresses
980b8851fccSafresh1should be a valid rfc2821-quoted address, although Net::SMTP will
981b8851fccSafresh1accept the address surrounded by angle brackets.
982b8851fccSafresh1
983b8851fccSafresh1 funny user@domain      WRONG
984b8851fccSafresh1 "funny user"@domain    RIGHT, recommended
985b8851fccSafresh1 <"funny user"@domain>  OK
986b8851fccSafresh1
987eac174f2Safresh1=head1 EXAMPLES
988eac174f2Safresh1
989eac174f2Safresh1This example prints the mail domain name of the SMTP server known as mailhost:
990eac174f2Safresh1
991eac174f2Safresh1    #!/usr/local/bin/perl -w
992eac174f2Safresh1
993eac174f2Safresh1    use Net::SMTP;
994eac174f2Safresh1
995eac174f2Safresh1    $smtp = Net::SMTP->new('mailhost');
996eac174f2Safresh1    print $smtp->domain,"\n";
997eac174f2Safresh1    $smtp->quit;
998eac174f2Safresh1
999eac174f2Safresh1This example sends a small message to the postmaster at the SMTP server
1000eac174f2Safresh1known as mailhost:
1001eac174f2Safresh1
1002eac174f2Safresh1    #!/usr/local/bin/perl -w
1003eac174f2Safresh1
1004eac174f2Safresh1    use Net::SMTP;
1005eac174f2Safresh1
1006eac174f2Safresh1    my $smtp = Net::SMTP->new('mailhost');
1007eac174f2Safresh1
1008eac174f2Safresh1    $smtp->mail($ENV{USER});
1009eac174f2Safresh1    if ($smtp->to('postmaster')) {
1010eac174f2Safresh1     $smtp->data();
1011eac174f2Safresh1     $smtp->datasend("To: postmaster\n");
1012eac174f2Safresh1     $smtp->datasend("\n");
1013eac174f2Safresh1     $smtp->datasend("A simple test message\n");
1014eac174f2Safresh1     $smtp->dataend();
1015eac174f2Safresh1    } else {
1016eac174f2Safresh1     print "Error: ", $smtp->message();
1017eac174f2Safresh1    }
1018eac174f2Safresh1
1019eac174f2Safresh1    $smtp->quit;
1020eac174f2Safresh1
1021eac174f2Safresh1=head1 EXPORTS
1022eac174f2Safresh1
1023eac174f2Safresh1I<None>.
1024eac174f2Safresh1
1025eac174f2Safresh1=head1 KNOWN BUGS
1026eac174f2Safresh1
1027eac174f2Safresh1See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
1028eac174f2Safresh1
1029b8851fccSafresh1=head1 SEE ALSO
1030b8851fccSafresh1
1031b8851fccSafresh1L<Net::Cmd>,
1032eac174f2Safresh1L<IO::Socket::SSL>.
1033b8851fccSafresh1
1034b8851fccSafresh1=head1 AUTHOR
1035b8851fccSafresh1
1036eac174f2Safresh1Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
1037b8851fccSafresh1
1038eac174f2Safresh1Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
1039eac174f2Safresh1libnet as of version 1.22_02.
1040b8851fccSafresh1
1041b8851fccSafresh1=head1 COPYRIGHT
1042b8851fccSafresh1
10435759b3d2Safresh1Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
10445759b3d2Safresh1
1045eac174f2Safresh1Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
10465759b3d2Safresh1
10475759b3d2Safresh1=head1 LICENCE
1048b8851fccSafresh1
1049b8851fccSafresh1This module is free software; you can redistribute it and/or modify it under the
1050b8851fccSafresh1same terms as Perl itself, i.e. under the terms of either the GNU General Public
1051b8851fccSafresh1License or the Artistic License, as specified in the F<LICENCE> file.
1052b8851fccSafresh1
1053eac174f2Safresh1=head1 VERSION
1054eac174f2Safresh1
1055*e0680481Safresh1Version 3.15
1056eac174f2Safresh1
1057eac174f2Safresh1=head1 DATE
1058eac174f2Safresh1
1059*e0680481Safresh120 March 2023
1060eac174f2Safresh1
1061eac174f2Safresh1=head1 HISTORY
1062eac174f2Safresh1
1063eac174f2Safresh1See the F<Changes> file.
1064eac174f2Safresh1
1065b8851fccSafresh1=cut
1066