Update copyright dates
[manu/smtpt.git] / smtpt
1 #!/usr/bin/perl -w
2 # Send virus/spam/normal messages to a named host with named sender/recipients
3 # and optionnal message size or smtp auth
4 #
5 # Require perl modules: Net::SMTP, AppConfig
6 #
7 # Copyright (C) 2006-2010 Emmanuel Lacour <elacour@home-dn.net>
8 #
9 # This file is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by the
11 # Free Software Foundation; either version 2, or (at your option) any
12 # later version.
13 #
14 # This file is distributed in the hope that it will be
15 # useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this file; see the file COPYING.  If not, write to the Free
21 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 # 02110-1301, USA.
23 #
24
25 use strict;
26 use Net::SMTP;
27 use AppConfig qw(:expand :argcount);
28
29 my $NAME = 'smtpt';
30 my $VERSION = '0.1';
31 my $AUTHOR = 'Emmanuel Lacour, <elacour@home-dn.net>';
32
33 my %count;
34 my $smtp;
35 my $user;
36 my $pass;
37 my $size;
38 my %sample;
39
40 # Spam sample email
41 $sample{spam} = 'Subject: Test spam mail (GTUBE)
42 From: Sender <{FROM}>
43 To: {TO}
44 MIME-Version: 1.0
45 Content-Type: text/plain; charset=us-ascii
46 Content-Transfer-Encoding: 7bit
47
48 This is the GTUBE, the
49         Generic
50         Test for
51         Unsolicited
52         Bulk
53         Email
54
55 If your spam filter supports it, the GTUBE provides a test by which you
56 can verify that the filter is installed correctly and is detecting incoming
57 spam. You can send yourself a test mail containing the following string of
58 characters (in upper case and with no white spaces and line breaks):
59
60 XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
61
62 You should send this test mail from an account outside of your network.
63 ';
64
65 # Nospam/novirus sample email
66 $sample{normal} = 'Subject: Test mail nospam/novirus
67 From: Sender <{FROM}>
68 To: {TO}
69 MIME-Version: 1.0
70 Content-Type: text/plain; charset=us-ascii
71 Content-Transfer-Encoding: 7bit
72
73
74 Essai  nospam/novirus
75 ';
76
77 # Virus sample email
78 $sample{virus} = 'From: Sender <{FROM}>
79 To: {TO}
80 Subject: Test virus
81 Mime-Version: 1.0
82 Content-Type: multipart/mixed; boundary="C7zPtVaVf+AK4Oqc"
83 Content-Disposition: inline
84 Content-Transfer-Encoding: 8bit
85 Content-Length: 650
86
87
88 --C7zPtVaVf+AK4Oqc
89 Content-Type: text/plain; charset=iso-8859-1
90 Content-Disposition: inline
91 Content-Transfer-Encoding: 8bit
92
93 Test virus.
94
95 --C7zPtVaVf+AK4Oqc
96 Content-Type: application/x-msdos-program
97 Content-Disposition: attachment; filename="EICAR.COM"
98 Content-Transfer-Encoding: quoted-printable
99
100 X5O!P%@AP[4{DEACTIVATED}\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*=0A
101 --C7zPtVaVf+AK4Oqc--
102 ';
103
104 # Close properly smtp connection before exiting on error
105 sub error {
106     my $mesg = shift;
107     print STDERR "E: ", $mesg;
108     if ($smtp) {
109         $smtp->quit();
110     }
111     exit (1);
112 }
113
114 # Prints out version information
115 sub version {
116     print "$NAME $VERSION\n";
117     print "Written by $AUTHOR\n";
118     exit;
119 }
120
121 # Prints command-line help
122 sub usage {
123     print "Usage: $NAME ARGUMENTS [OPTIONNALS ARGUMENTS]
124
125 ARGUMENTS:
126  --host=HOST            the host to connect to
127  --from=FROM            the sender email
128  --to=TO                the recipient email
129  --spam=SPAM_COUNT      the number of spam emails to sent
130  --virus=VIRUS_COUNT    the number of virus emails to sent
131  --normal=NORMAL_COUNT  the number of nonspam/nonvirus emails to sent
132
133 OPTIONNALS ARGUMENTS:
134  --user=USER            an optionnal user for smtp authentication
135  --pass=PASS            an optionnal password for smtp authentication
136  --size=SIZE            an optionnal message size (integer optionnaly 
137                         followed by M for megabytes or K for kilobytes 
138                         (default: bytes))
139  --help                 prints out command-line help
140  --version              prints out version information\n";
141     exit(1);
142 }
143
144
145 sub main {
146
147     # Read command line arguments
148     my %opt = ();
149     my $appconfig = AppConfig->new(
150         'host=s', 
151         'from=s', 
152         'to=s@',
153         'spam=s', 
154         'virus=s', 
155         'normal=s', 
156         'user=s', 
157         'pass=s', 
158         'size=s', 
159         'help', 
160         'version'
161     ) or exit(1);
162     $appconfig->args();
163     %opt = $appconfig->varlist('^.*$');
164
165     # Check command line arguments
166     usage if (defined $opt{help});
167     version if (defined $opt{version});
168     usage if ((!defined $opt{host}) || (! defined $opt{from}) || (! defined $opt{to}) || (! defined $opt{spam}) || (! defined $opt{virus}) || (! defined $opt{normal}));
169     usage if ((defined $opt{user}) && (! defined $opt{pass}));
170     usage if ((defined $opt{pass}) && (! defined $opt{user}));
171
172     my $host = $opt{host};
173     my $from = $opt{from};
174     my @to = @{$opt{to}};
175     my $to_formatted = join(", ", @to);
176     $count{spam} = $opt{spam};
177     $count{virus} = $opt{virus};
178     $count{normal} = $opt{normal};
179     $user = $opt{user} if ($opt{user});
180     $pass = $opt{pass} if ($opt{pass});
181     $size = $opt{size} if ($opt{size});
182     if (defined $size) {
183         if ($size =~ /^([0-9]+)M$/) {
184             $size = $1 * 1024 * 1024;
185         } elsif ($size =~ /^([0-9]+)K$/) {
186             $size = $1 * 1024;
187         } elsif ($size =~ /^([0-9]+)$/) {
188             $size = $1;
189         } else {
190             die "Error, wrong size: $size\n";
191         }
192     }
193
194     # Open an smtp connection
195     $smtp = Net::SMTP->new($host, Debug => 0) or die "Couldn't connect to $host: $!\n";
196
197     # Authenticate if needed
198     if ($user && $pass) {
199         $smtp->auth($user, $pass) or error("Auth failed: $!\n");
200     }
201
202     # Send emails
203     foreach my $type (keys%count) {
204         my $i = 0;
205         while ($i < $count{$type}) {
206             print "Sending $type: $from -> $to_formatted\n";
207             $smtp->mail($from) or error("From failed: $!\n");
208             $smtp->to(@to) or error("To failed: $!\n");
209             $smtp->data() or error("Data failed: $!\n");
210             my $sent_size = 0;
211             my $body = $sample{$type};
212             $body =~ s/{TO}/$to_formatted/g;
213             $body =~ s/{FROM}/$from/g;
214             # Disable special virus mangling (needed for letting people using an http AV download this toool ;))
215             $body =~ s/{DEACTIVATED}//g;
216             $smtp->datasend($body) or error("Datasend failed: $!\n");
217             $sent_size += length($body); 
218             if ($size) {
219                 my $line = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
220                 while ($sent_size <= $size) {
221                     $smtp->datasend($line) or error("Datasend failed: $!\n");
222                     $sent_size += 72;
223                 }
224             }
225             $smtp->dataend() or error("Dataend failed: $!\n"); 
226             $i++;
227         }
228     }
229     $smtp->quit();
230 }
231
232
233 main();
234
235
236 # script documentation (POD style)
237
238 =head1 NAME
239
240 smtpt - simple command line for testing smtp server features
241
242 =head1 DESCRIPTION
243
244 This program let you send different kind of emails (spam, virus, normal) to a
245 specified smtp server. It can do smtp authentication and message size
246 adjustement.
247
248 =head1 COMMAND LINE PARAMETERS
249
250 Required command line parameters are:
251
252 =head2 B<--host>=I<HOST>
253     
254 The host to connect to.
255
256 =head2 B<--from>=I<FROM>
257     
258 The sender email.
259
260 =head2 B<--to>=I<TO>
261     
262 The recipient email.
263
264 =head2 B<--spam>=I<SPAM_COUNT>
265     
266 The count of spam emails to sent.
267
268 =head2 B<--virus>=I<VIRUS_COUNT>
269     
270 The count of virus emails to sent.
271
272 =head2 B<--normal>=I<NORMAL_COUNT>
273     
274 The count of nonspam/nonvirus emails to sent.
275
276
277 =head1 OPTIONS
278
279 =head2 B<--user>=I<AUTH_USER>
280     
281 An optionnal user for smtp authentication.
282
283 =head2 B<--pass>=I<AUTH_PASSWORD>
284     
285 An optionnal password for smtp authentication.
286
287 =head2 B<--size>=I<MESSAGE_SIZE>
288     
289 An optionnal message size (integer optionnaly followed 
290 by M for megabytes or K for kilobytes (default: bytes)).
291
292 =head2 B<--help>
293
294 Prints out command-line help.
295
296 =head2 B<--version>
297
298 Prints out version information.
299
300 =head1 AUTHOR
301
302 Emmanuel Lacour, elacour@home-dn.net
303
304 =cut