36a902e5a0eecac25b44e7ece50deec93b29b8b3
[platform/upstream/curl.git] / tests / secureserver.pl
1 #!/usr/bin/env perl
2 #***************************************************************************
3 #                                  _   _ ____  _
4 #  Project                     ___| | | |  _ \| |
5 #                             / __| | | | |_) | |
6 #                            | (__| |_| |  _ <| |___
7 #                             \___|\___/|_| \_\_____|
8 #
9 # Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
10 #
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://curl.haxx.se/docs/copyright.html.
14 #
15 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 # copies of the Software, and permit persons to whom the Software is
17 # furnished to do so, under the terms of the COPYING file.
18 #
19 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 # KIND, either express or implied.
21 #
22 #***************************************************************************
23
24 # This is the HTTPS, FTPS, POP3S, IMAPS, SMTPS, server used for curl test
25 # harness. Actually just a layer that runs stunnel properly using the
26 # non-secure test harness servers.
27
28 BEGIN {
29     push(@INC, $ENV{'srcdir'}) if(defined $ENV{'srcdir'});
30     push(@INC, ".");
31 }
32
33 use strict;
34 use warnings;
35 use Cwd;
36
37 use serverhelp qw(
38     server_pidfilename
39     server_logfilename
40     );
41
42 my $stunnel = "stunnel";
43
44 my $verbose=0; # set to 1 for debugging
45
46 my $accept_port = 8991; # just our default, weird enough
47 my $target_port = 8999; # default test http-server port
48
49 my $stuncert;
50
51 my $ver_major;
52 my $ver_minor;
53 my $stunnel_version;
54 my $socketopt;
55 my $cmd;
56
57 my $pidfile;          # stunnel pid file
58 my $logfile;          # stunnel log file
59 my $loglevel = 5;     # stunnel log level
60 my $ipvnum = 4;       # default IP version of stunneled server
61 my $idnum = 1;        # dafault stunneled server instance number
62 my $proto = 'https';  # default secure server protocol
63 my $conffile;         # stunnel configuration file
64 my $certfile;         # certificate chain PEM file
65
66 #***************************************************************************
67 # stunnel requires full path specification for several files.
68 #
69 my $path   = getcwd();
70 my $srcdir = $path;
71 my $logdir = $path .'/log';
72
73 #***************************************************************************
74 # Signal handler to remove our stunnel 4.00 and newer configuration file.
75 #
76 sub exit_signal_handler {
77     my $signame = shift;
78     local $!; # preserve errno
79     local $?; # preserve exit status
80     unlink($conffile) if($conffile && (-f $conffile));
81     exit;
82 }
83
84 #***************************************************************************
85 # Process command line options
86 #
87 while(@ARGV) {
88     if($ARGV[0] eq '--verbose') {
89         $verbose = 1;
90     }
91     elsif($ARGV[0] eq '--proto') {
92         if($ARGV[1]) {
93             $proto = $ARGV[1];
94             shift @ARGV;
95         }
96     }
97     elsif($ARGV[0] eq '--accept') {
98         if($ARGV[1]) {
99             if($ARGV[1] =~ /^(\d+)$/) {
100                 $accept_port = $1;
101                 shift @ARGV;
102             }
103         }
104     }
105     elsif($ARGV[0] eq '--connect') {
106         if($ARGV[1]) {
107             if($ARGV[1] =~ /^(\d+)$/) {
108                 $target_port = $1;
109                 shift @ARGV;
110             }
111         }
112     }
113     elsif($ARGV[0] eq '--stunnel') {
114         if($ARGV[1]) {
115             $stunnel = $ARGV[1];
116             shift @ARGV;
117         }
118     }
119     elsif($ARGV[0] eq '--srcdir') {
120         if($ARGV[1]) {
121             $srcdir = $ARGV[1];
122             shift @ARGV;
123         }
124     }
125     elsif($ARGV[0] eq '--certfile') {
126         if($ARGV[1]) {
127             $stuncert = $ARGV[1];
128             shift @ARGV;
129         }
130     }
131     elsif($ARGV[0] eq '--id') {
132         if($ARGV[1]) {
133             if($ARGV[1] =~ /^(\d+)$/) {
134                 $idnum = $1 if($1 > 0);
135                 shift @ARGV;
136             }
137         }
138     }
139     elsif($ARGV[0] eq '--ipv4') {
140         $ipvnum = 4;
141     }
142     elsif($ARGV[0] eq '--ipv6') {
143         $ipvnum = 6;
144     }
145     elsif($ARGV[0] eq '--pidfile') {
146         if($ARGV[1]) {
147             $pidfile = "$path/". $ARGV[1];
148             shift @ARGV;
149         }
150     }
151     elsif($ARGV[0] eq '--logfile') {
152         if($ARGV[1]) {
153             $logfile = "$path/". $ARGV[1];
154             shift @ARGV;
155         }
156     }
157     else {
158         print STDERR "\nWarning: secureserver.pl unknown parameter: $ARGV[0]\n";
159     }
160     shift @ARGV;
161 }
162
163 #***************************************************************************
164 # Initialize command line option dependant variables
165 #
166 if(!$pidfile) {
167     $pidfile = "$path/". server_pidfilename($proto, $ipvnum, $idnum);
168 }
169 if(!$logfile) {
170     $logfile = server_logfilename($logdir, $proto, $ipvnum, $idnum);
171 }
172
173 $conffile = "$path/stunnel.conf";
174
175 $certfile = "$srcdir/". ($stuncert?"certs/$stuncert":"stunnel.pem");
176
177 my $ssltext = uc($proto) ." SSL/TLS:";
178
179 #***************************************************************************
180 # Find out version info for the given stunnel binary
181 #
182 foreach my $veropt (('-version', '-V')) {
183     foreach my $verstr (qx($stunnel $veropt 2>&1)) {
184         if($verstr =~ /^stunnel (\d+)\.(\d+) on /) {
185             $ver_major = $1;
186             $ver_minor = $2;
187             last;
188         }
189     }
190     last if($ver_major);
191 }
192 if((!$ver_major) || (!$ver_minor)) {
193     if(-x "$stunnel" && ! -d "$stunnel") {
194         print "$ssltext Unknown stunnel version\n";
195     }
196     else {
197         print "$ssltext No stunnel\n";
198     }
199     exit 1;
200 }
201 $stunnel_version = (100*$ver_major) + $ver_minor;
202
203 #***************************************************************************
204 # Verify minimmum stunnel required version
205 #
206 if($stunnel_version < 310) {
207     print "$ssltext Unsupported stunnel version $ver_major.$ver_minor\n";
208     exit 1;
209 }
210
211 #***************************************************************************
212 # Build command to execute for stunnel 3.X versions
213 #
214 if($stunnel_version < 400) {
215     if($stunnel_version >= 319) {
216         $socketopt = "-O a:SO_REUSEADDR=1";
217     }
218     $cmd  = "$stunnel -p $certfile -P $pidfile ";
219     $cmd .= "-d $accept_port -r $target_port -f -D $loglevel ";
220     $cmd .= ($socketopt) ? "$socketopt " : "";
221     $cmd .= ">$logfile 2>&1";
222     if($verbose) {
223         print uc($proto) ." server (stunnel $ver_major.$ver_minor)\n";
224         print "cmd: $cmd\n";
225         print "pem cert file: $certfile\n";
226         print "pid file: $pidfile\n";
227         print "log file: $logfile\n";
228         print "log level: $loglevel\n";
229         print "listen on port: $accept_port\n";
230         print "connect to port: $target_port\n";
231     }
232 }
233
234 #***************************************************************************
235 # Build command to execute for stunnel 4.00 and newer
236 #
237 if($stunnel_version >= 400) {
238     $socketopt = "a:SO_REUSEADDR=1";
239     $cmd  = "$stunnel $conffile ";
240     $cmd .= ">$logfile 2>&1";
241     # setup signal handler
242     $SIG{INT} = \&exit_signal_handler;
243     $SIG{TERM} = \&exit_signal_handler;
244     # stunnel configuration file
245     if(open(STUNCONF, ">$conffile")) {
246         print STUNCONF "
247         CApath = $path
248         cert = $certfile
249         pid = $pidfile
250         debug = $loglevel
251         output = $logfile
252         socket = $socketopt
253         foreground = yes
254         
255         [curltest]
256         accept = $accept_port
257         connect = $target_port
258         ";
259         if(!close(STUNCONF)) {
260             print "$ssltext Error closing file $conffile\n";
261             exit 1;
262         }
263     }
264     else {
265         print "$ssltext Error writing file $conffile\n";
266         exit 1;
267     }
268     if($verbose) {
269         print uc($proto) ." server (stunnel $ver_major.$ver_minor)\n";
270         print "cmd: $cmd\n";
271         print "CApath = $path\n";
272         print "cert = $certfile\n";
273         print "pid = $pidfile\n";
274         print "debug = $loglevel\n";
275         print "output = $logfile\n";
276         print "socket = $socketopt\n";
277         print "foreground = yes\n";
278         print "\n";
279         print "[curltest]\n";
280         print "accept = $accept_port\n";
281         print "connect = $target_port\n";
282     }
283 }
284
285 #***************************************************************************
286 # Set file permissions on certificate pem file.
287 #
288 chmod(0600, $certfile) if(-f $certfile);
289
290 #***************************************************************************
291 # Run stunnel.
292 #
293 my $rc = system($cmd);
294
295 $rc >>= 8;
296
297 unlink($conffile) if($conffile && -f $conffile);
298
299 exit $rc;