17814987d02a9bddb9ca8eab6e960426d72c5ffa
[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 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: Recipient <{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: Recipient <{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: Recipient <{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     $count{spam} = $opt{spam};
176     $count{virus} = $opt{virus};
177     $count{normal} = $opt{normal};
178     $user = $opt{user} if ($opt{user});
179     $pass = $opt{pass} if ($opt{pass});
180     $size = $opt{size} if ($opt{size});
181     if (defined $size) {
182         if ($size =~ /^([0-9]+)M$/) {
183             $size = $1 * 1024 * 1024;
184         } elsif ($size =~ /^([0-9]+)K$/) {
185             $size = $1 * 1024;
186         } elsif ($size =~ /^([0-9]+)$/) {
187             $size = $1;
188         } else {
189             die "Error, wrong size: $size\n";
190         }
191     }
192
193     # Open an smtp connection
194     $smtp = Net::SMTP->new($host, Debug => 0) or die "Couldn't connect to $host: $!\n";
195
196     # Authenticate if needed
197     if ($user && $pass) {
198         $smtp->auth($user, $pass) or error("Auth failed: $!\n");
199     }
200
201     # Send emails
202     foreach my $type (keys%count) {
203         my $i = 0;
204         while ($i < $count{$type}) {
205             print "Sending: $from -> $to, $type\n";
206             $smtp->mail($from) or error("From failed: $!\n");
207             $smtp->to($to) or error("To failed: $!\n");
208             $smtp->data() or error("Data failed: $!\n");
209             my $sent_size = 0;
210             my $body = $sample{$type};
211             $body =~ s/{TO}/$to/g;
212             $body =~ s/{FROM}/$from/g;
213             # Disable special virus mangling (needed for letting people using an http AV download this toool ;))
214             $body =~ s/{DEACTIVATED}//g;
215             $smtp->datasend($body) or error("Datasend failed: $!\n");
216             $sent_size += length($body); 
217             if ($size) {
218                 my $line = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
219                 while ($sent_size <= $size) {
220                     $smtp->datasend($line) or error("Datasend failed: $!\n");
221                     $sent_size += 72;
222                 }
223             }
224             $smtp->dataend() or error("Dataend failed: $!\n"); 
225             $i++;
226         }
227     }
228     $smtp->quit();
229 }
230
231
232 main();
233
234
235 # script documentation (POD style)
236
237 =head1 NAME
238
239 smtpt - simple command line for testing smtp server features
240
241 =head1 DESCRIPTION
242
243 This program let you send different kind of emails (spam, virus, normal) to a
244 specified smtp server. It can do smtp authentication and message size
245 adjustement.
246
247 =head1 COMMAND LINE PARAMETERS
248
249 Required command line parameters are:
250
251 =head2 B<--host>=I<HOST>
252     
253 The host to connect to.
254
255 =head2 B<--from>=I<FROM>
256     
257 The sender email.
258
259 =head2 B<--to>=I<TO>
260     
261 The recipient email.
262
263 =head2 B<--spam>=I<SPAM_COUNT>
264     
265 The count of spam emails to sent.
266
267 =head2 B<--virus>=I<VIRUS_COUNT>
268     
269 The count of virus emails to sent.
270
271 =head2 B<--normal>=I<NORMAL_COUNT>
272     
273 The count of nonspam/nonvirus emails to sent.
274
275
276 =head1 OPTIONS
277
278 =head2 B<--user>=I<AUTH_USER>
279     
280 An optionnal user for smtp authentication.
281
282 =head2 B<--pass>=I<AUTH_PASSWORD>
283     
284 An optionnal password for smtp authentication.
285
286 =head2 B<--size>=I<MESSAGE_SIZE>
287     
288 An optionnal message size (integer optionnaly followed 
289 by M for megabytes or K for kilobytes (default: bytes)).
290
291 =head2 B<--help>
292
293 Prints out command-line help.
294
295 =head2 B<--version>
296
297 Prints out version information.
298
299 =head1 AUTHOR
300
301 Emmanuel Lacour, elacour@home-dn.net
302
303 =cut