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