#!/usr/bin/perl -I../../../../.. use strict; use Pos::Webtop::Toolbox; use Pos::Webtop::WebtopConnection; use Digest::MD5 qw(md5 md5_hex); package Pos::Webtop::Web::ContentModule::Mail::Smtp; our @ISA = qw( Pos::Webtop::WebtopConnection ); sub new { my $this = shift; my $class = ref($this) || $this; my ($self,$db,$tb) = @{{@_}}{qw/self db tb/}; if ( not defined $self ) { $self = {}; bless($self,$class); } $self->{'db'} = $db; $self->{'tb'} = $tb; # Save the userId my $client = $tb->getClient; $self->{'userId'} = $client->getUserId; $self->{'sessionId'} = $client->getSessionId; $self->{'companyId'} = $client->getCustomerId; # setup base class my %args = @_; $args{'tb'} = $tb; Pos::Webtop::WebtopConnection->new( %args ); return $self; } sub DESTROY { my $self = shift; $self->disconnect; } sub startMessage { my $self = shift; my ($to,$cc,$bcc,$subject,$body,$attachments) = @{{@_}}{qw/to cc bcc subject body attachments/}; $self->{'to'} = $to; $self->{'cc'} = $cc; $self->{'bcc'} = $bcc; $self->{'subject'} = $subject; $self->{'body'} = $body; $self->{'attachments'} = $attachments; if (defined($attachments) and scalar(@{ $attachments }) > 0) { $self->{'hasAttachments'} = 1; } else { $self->{'hasAttachments'} = 0; } my ($from) = $self->{'db'}->query(sql => " select email_address from user_email_addresses where email_type_id = ( select primary_user_email_id from users where user_id = '" . $self->{'userId'} . "' ) AND user_id = '" . $self->{'userId'} . "' "); if (not defined($from)) { $from = "unknown\@webtop.positivenetworks.net"; } $self->{'from'} = $from; return 1; } sub transmit { my $self = shift; my ($host, $port) = @{{@_}}{qw/host port/}; if (not defined($port)) { $port = 25; } if (not defined($self->connect(companyId => $self->{'companyId'}, host => $host, port => $port))) { print STDERR "SMTP: Could not connect to $host:$port\n"; return undef; } # Read the banner from the SMTP connection if (not defined($self->readResponseWantCode(code => 220))) { print STDERR "SMTP:1: Did not get banner.\n"; return undef; } # Write HELO $self->writeLine(text => "HELO positive"); # Read the response to the HELO if (not defined($self->readResponseWantCode(code => 250))) { print STDERR "SMTP:2: Did not get HELO response.\n"; return undef; } # Write MAIL FROM: blah@blah.com $self->writeLine(text => "MAIL FROM: " . $self->{'from'}); # Read the response to the MAIL FROM if (not defined($self->readResponseWantCode(code => 250))) { print STDERR "SMTP:3: Did not get MAIL FROM response.\n"; return undef; } # Write RCPT TO: blah@blah.com $self->writeLine(text => "RCPT TO: " . $self->{'to'}); # Read the response to the RCPT TO if (not defined($self->readResponseWantCode(code => 250))) { print STDERR "SMTP:4: Did not get MAIL FROM response.\n"; return undef; } # Write DATA $self->writeLine(text => "DATA"); # Read the response to the DATA if (not defined($self->readResponseWantCode(code => 354))) { print STDERR "SMTP:5: Did not get DATA response.\n"; return undef; } $self->transmitBody; # Read the response to the DATA transmission if (not defined($self->readResponseWantCode(code => 250))) { print STDERR "SMTP:6: Did not get DATA response.\n"; return undef; } # Disconnect, we're done. $self->disconnect; return 1; } sub transmitBody { my $self = shift; my $messageId = "WEBTOP-" . scalar(time) . "-" . $self->{'userId'} . $self->{'sessionId'}; # Write our header information $self->writeLine(text => "From: " . $self->{'from'}); $self->writeLine(text => "To: " . $self->{'to'}); $self->writeLine(text => "Subject: " . $self->{'subject'}); $self->writeLine(text => "Message-Id: $messageId"); # Write our body if (not defined($self->{'body'})) { $self->{'body'} = ""; } # If we don't have attachments, finish our header and write our body if (!$self->{'hasAttachments'}) { $self->writeLine(text => ""); $self->writeLine(text => $self->{'body'}); } else { # Otherwise, we have some attachments. We need to send multipart information my $boundary = $self->{'userId'} . $self->{'sessionId'} . "-BND"; $self->writeLine(text => "Content-Type: MULTIPART/MIXED; BOUNDARY=\"$boundary\""); $self->writeLine(text => ""); # Now for the multipart body $self->writeLine(text => "--$boundary"); $self->writeLine(text => "Content-Type: TEXT/PLAIN"); $self->writeLine(text => ""); $self->writeLine(text => $self->{'body'}); # Now for the attachments foreach my $attachment (@{ $self->{'attachments'} }) { my %hash = %{ $attachment }; $self->writeLine(text => "--$boundary"); my $raw = $hash{'ATTACHMENT_RAW_BUFFER'}; $self->writeLine(text => $$raw); } $self->writeLine(text => "--$boundary--"); } $self->writeLine(text => "."); } sub readResponseWantCode { my $self = shift; my ($code) = @{{@_}}{qw/code/}; my $line = $self->readLine; my ($realCode) = split / /, $line; if ($realCode ne $code) { print STDERR "SMTP: readResponseWantCode mismatch ($realCode!=$code): $line\n"; return undef; } return 1; } 1;