Changeset 21439


Ignore:
Timestamp:
2010-05-13T02:47:17+02:00 (8 years ago)
Author:
nico
Message:

[packages] stunnel: update to 4.33 (closes: #7296)

Location:
packages/net/stunnel
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • packages/net/stunnel/Makefile

    r19859 r21439  
     1# 
     2# Copyright (C) 2006-2010 OpenWrt.org 
     3# 
     4# This is free software, licensed under the GNU General Public License v2. 
     5# See /LICENSE for more information. 
     6# 
    17 
    28include $(TOPDIR)/rules.mk 
    39 
    410PKG_NAME:=stunnel 
    5 PKG_VERSION:=4.29 
    6 PKG_RELEASE:=4 
     11PKG_VERSION:=4.33 
     12PKG_RELEASE:=1 
    713 
    8 PKG_MD5SUM:=14dc3f8412947f0548975cbce74d6863 
     14PKG_MD5SUM:=559a864066d8cc4afd8a97682c90d41c 
    915PKG_SOURCE_URL:=http://www.stunnel.org/download/stunnel/src/ 
    1016PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 
  • packages/net/stunnel/patches/100-cross-compile.patch

    r17193 r21439  
    11--- a/configure 
    22+++ b/configure 
    3 @@ -21536,56 +21536,56 @@ _ACEOF 
     3@@ -21552,56 +21552,56 @@ _ACEOF 
    44 fi 
    55 rm -f conftest* 
     
    101101  
    102102 { echo "$as_me:$LINENO: **************************************** entropy" >&5 
    103 @@ -24033,8 +24033,8 @@ _ACEOF 
     103@@ -24049,8 +24049,8 @@ _ACEOF 
    104104  
    105105  
  • packages/net/stunnel/patches/101-no-comp.patch

    r18703 r21439  
    11--- a/src/ssl.c 
    22+++ b/src/ssl.c 
    3 @@ -63,13 +63,16 @@ void ssl_init(void) { /* init SSL before 
     3@@ -72,14 +72,17 @@ int ssl_configure(void) { /* configure g 
     4     s_log(LOG_NOTICE, "FIPS mode %s", 
     5         global_options.option.fips ? "enabled" : "disabled"); 
     6 #endif /* USE_FIPS */ 
     7+#ifndef OPENSSL_NO_COMP    
     8     if(global_options.compression!=COMP_NONE && !init_compression()) 
     9         return 0; 
     10+#endif 
     11     if(!init_prng()) 
     12         return 0; 
     13     s_log(LOG_DEBUG, "PRNG seeded successfully"); 
     14     return 1; /* SUCCESS */ 
    415 } 
    516  
    6  void ssl_configure(void) { /* configure global SSL settings */ 
    717+#ifndef OPENSSL_NO_COMP 
    8      if(options.compression!=COMP_NONE) 
    9          init_compression(); 
    10 +#endif 
    11      if(!init_prng()) 
    12          s_log(LOG_DEBUG, "PRNG seeded successfully"); 
    13  } 
    14   
    15  static void init_compression(void) { 
    16 +#ifndef OPENSSL_NO_COMP 
     18 static int init_compression(void) { 
    1719     int id=0; 
    1820     COMP_METHOD *cm=NULL; 
    19      char *name="unknown"; 
    20 @@ -98,6 +101,7 @@ static void init_compression(void) { 
    21          die(1); 
    22      } 
     21@@ -111,6 +114,7 @@ static int init_compression(void) { 
    2322     s_log(LOG_INFO, "Compression enabled using %s method", name); 
     23     return 1; 
     24 } 
    2425+#endif 
    25  } 
    2626  
    2727 static int init_prng(void) { 
     28     int totbytes=0; 
  • packages/net/stunnel/patches/102-no-ssl2.patch

    r18703 r21439  
    11--- a/src/options.c 
    22+++ b/src/options.c 
    3 @@ -1198,8 +1198,10 @@ static char *service_options(CMD cmd, LO 
     3@@ -1234,8 +1234,10 @@ static char *parse_service_option(CMD cm 
    44             section->client_method=(SSL_METHOD *)SSLv23_client_method(); 
    55             section->server_method=(SSL_METHOD *)SSLv23_server_method(); 
  • packages/net/stunnel/patches/103-no-zlib-link.patch

    r18703 r21439  
    22--- a/configure 
    33+++ b/configure 
    4 @@ -23001,7 +23001,7 @@ if test $ac_cv_lib_z_inflateEnd = yes; t 
     4@@ -23017,7 +23017,7 @@ if test $ac_cv_lib_z_inflateEnd = yes; t 
    55 #define HAVE_LIBZ 1 
    66 _ACEOF 
  • packages/net/stunnel/patches/104-fix-paths.patch

    r18703 r21439  
    22--- a/tools/stunnel.conf-sample.in 
    33+++ b/tools/stunnel.conf-sample.in 
    4 @@ -3,14 +3,14 @@ 
    5  ; Please make sure you understand them (especially the effect of the chroot jail) 
     4@@ -4,15 +4,15 @@ 
     5 ; please read the manual and make sure you understand them 
    66  
    7  ; Certificate/key is needed in server mode and optional in client mode 
     7 ; certificate/key is needed in server mode and optional in client mode 
    88-cert = @prefix@/etc/stunnel/mail.pem 
    99-;key = @prefix@/etc/stunnel/mail.pem 
     
    1111+;key = @sysconfdir@/stunnel/stunnel.pem 
    1212  
    13  ; Protocol version (all, SSLv2, SSLv3, TLSv1) 
     13 ; protocol version (all, SSLv2, SSLv3, TLSv1) 
    1414 sslVersion = SSLv3 
    1515  
    16  ; Some security enhancements for UNIX systems - comment them out on Win32 
     16 ; security enhancements for UNIX systems - comment them out on Win32 
     17 ; for chroot a copy of some devices and files is needed within the jail 
    1718-chroot = @prefix@/var/lib/stunnel/ 
    1819+chroot = @localstatedir@ 
     
    2021 setgid = @DEFAULT_GROUP@ 
    2122 ; PID is created inside the chroot jail 
    22 @@ -30,16 +30,16 @@ socket = r:TCP_NODELAY=1 
     23@@ -33,16 +33,16 @@ socket = r:TCP_NODELAY=1 
    2324 ; CApath is located inside chroot jail 
    2425 ;CApath = /certs 
    25  ; It's often easier to use CAfile 
     26 ; it's often easier to use CAfile 
    2627-;CAfile = @prefix@/etc/stunnel/certs.pem 
    2728+;CAfile = @sysconfdir@/stunnel/certs.pem 
    28  ; Don't forget to c_rehash CRLpath 
     29 ; don't forget to c_rehash CRLpath 
    2930 ; CRLpath is located inside chroot jail 
    3031 ;CRLpath = /crls 
    31  ; Alternatively you can use CRLfile 
     32 ; alternatively CRLfile can be used 
    3233-;CRLfile = @prefix@/etc/stunnel/crls.pem 
    3334+;CRLfile = @sysconfdir@/stunnel/crls.pem 
    3435  
    35  ; Some debugging stuff useful for troubleshooting 
     36 ; debugging stuff (may useful for troubleshooting) 
    3637 ;debug = 7 
    3738-;output = stunnel.log 
    3839+;output = @localstatedir@/log/stunnel.log 
    3940  
    40  ; Use it for client mode 
     41 ; SSL client mode 
    4142 ;client = yes 
  • packages/net/stunnel/patches/105-stunnel-conf.patch

    r18703 r21439  
    11--- a/tools/stunnel.conf-sample.in 
    22+++ b/tools/stunnel.conf-sample.in 
    3 @@ -7,7 +7,7 @@ cert = @sysconfdir@/stunnel/stunnel.pem 
     3@@ -8,7 +8,7 @@ cert = @sysconfdir@/stunnel/stunnel.pem 
    44 ;key = @sysconfdir@/stunnel/stunnel.pem 
    55  
    6  ; Protocol version (all, SSLv2, SSLv3, TLSv1) 
     6 ; protocol version (all, SSLv2, SSLv3, TLSv1) 
    77-sslVersion = SSLv3 
    88+sslVersion = all 
    99  
    10  ; Some security enhancements for UNIX systems - comment them out on Win32 
    11  chroot = @localstatedir@ 
    12 @@ -46,21 +46,26 @@ socket = r:TCP_NODELAY=1 
     10 ; security enhancements for UNIX systems - comment them out on Win32 
     11 ; for chroot a copy of some devices and files is needed within the jail 
     12@@ -49,21 +49,26 @@ socket = r:TCP_NODELAY=1 
    1313  
    14  ; Service-level configuration 
     14 ; service-level configuration 
    1515  
    1616-[pop3s] 
  • packages/net/stunnel/patches/106-stunnel-xforwardedfor.patch

    r19859 r21439  
    11--- a/doc/stunnel.8 
    22+++ b/doc/stunnel.8 
    3 @@ -497,7 +497,10 @@ time to keep an idle connection 
     3@@ -504,7 +504,10 @@ time to keep an idle connection 
    44 .IP "\fBtransparent\fR = yes | no (Unix only)" 4 
    55 .IX Item "transparent = yes | no (Unix only)" 
     
    1313 from the \s-1SSL\s0 client machine instead of the machine running \fBstunnel\fR. 
    1414 .Sp 
    15 --- /dev/null 
    16 +++ b/doc/stunnel.8.orig 
    17 @@ -0,0 +1,729 @@ 
    18 +.\" Automatically generated by Pod::Man 2.1801 (Pod::Simple 3.05) 
    19 +.\" 
    20 +.\" Standard preamble: 
    21 +.\" ======================================================================== 
    22 +.de Sp \" Vertical space (when we can't use .PP) 
    23 +.if t .sp .5v 
    24 +.if n .sp 
    25 +.. 
    26 +.de Vb \" Begin verbatim text 
    27 +.ft CW 
    28 +.nf 
    29 +.ne \\$1 
    30 +.. 
    31 +.de Ve \" End verbatim text 
    32 +.ft R 
    33 +.fi 
    34 +.. 
    35 +.\" Set up some character translations and predefined strings.  \*(-- will 
    36 +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left 
    37 +.\" double quote, and \*(R" will give a right double quote.  \*(C+ will 
    38 +.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and 
    39 +.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff, 
    40 +.\" nothing in troff, for use with C<>. 
    41 +.tr \(*W- 
    42 +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 
    43 +.ie n \{\ 
    44 +.    ds -- \(*W- 
    45 +.    ds PI pi 
    46 +.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 
    47 +.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch 
    48 +.    ds L" "" 
    49 +.    ds R" "" 
    50 +.    ds C` "" 
    51 +.    ds C' "" 
    52 +'br\} 
    53 +.el\{\ 
    54 +.    ds -- \|\(em\| 
    55 +.    ds PI \(*p 
    56 +.    ds L" `` 
    57 +.    ds R" '' 
    58 +'br\} 
    59 +.\" 
    60 +.\" Escape single quotes in literal strings from groff's Unicode transform. 
    61 +.ie \n(.g .ds Aq \(aq 
    62 +.el       .ds Aq ' 
    63 +.\" 
    64 +.\" If the F register is turned on, we'll generate index entries on stderr for 
    65 +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index 
    66 +.\" entries marked with X<> in POD.  Of course, you'll have to process the 
    67 +.\" output yourself in some meaningful fashion. 
    68 +.ie \nF \{\ 
    69 +.    de IX 
    70 +.    tm Index:\\$1\t\\n%\t"\\$2" 
    71 +.. 
    72 +.    nr % 0 
    73 +.    rr F 
    74 +.\} 
    75 +.el \{\ 
    76 +.    de IX 
    77 +.. 
    78 +.\} 
    79 +.\" ======================================================================== 
    80 +.\" 
    81 +.IX Title "STUNNEL 8" 
    82 +.TH STUNNEL 8 "2009.11.20" "4.29" "stunnel" 
    83 +.\" For nroff, turn off justification.  Always turn off hyphenation; it makes 
    84 +.\" way too many mistakes in technical documents. 
    85 +.if n .ad l 
    86 +.nh 
    87 +.SH "NAME" 
    88 +stunnel \- universal SSL tunnel 
    89 +.SH "SYNOPSIS" 
    90 +.IX Header "SYNOPSIS" 
    91 +.IP "\fBUnix:\fR" 4 
    92 +.IX Item "Unix:" 
    93 +\&\fBstunnel\fR [<filename>] | \-fd n | \-help | \-version | \-sockets 
    94 +.IP "\fB\s-1WIN32:\s0\fR" 4 
    95 +.IX Item "WIN32:" 
    96 +\&\fBstunnel\fR [ [\-install | \-uninstall | \-start | \-stop] 
    97 +    [\-quiet] [<filename>] ] | \-help | \-version | \-sockets 
    98 +.SH "DESCRIPTION" 
    99 +.IX Header "DESCRIPTION" 
    100 +The \fBstunnel\fR program is designed to work as \fI\s-1SSL\s0\fR encryption wrapper  
    101 +between remote clients and local (\fIinetd\fR\-startable) or remote 
    102 +servers. The concept is that having non-SSL aware daemons running on 
    103 +your system you can easily set them up to communicate with clients over 
    104 +secure \s-1SSL\s0 channels. 
    105 +.PP 
    106 +\&\fBstunnel\fR can be used to add \s-1SSL\s0 functionality to commonly used \fIInetd\fR 
    107 +daemons like \s-1POP\-2\s0, \s-1POP\-3\s0, and \s-1IMAP\s0 servers, to standalone daemons like 
    108 +\&\s-1NNTP\s0, \s-1SMTP\s0 and \s-1HTTP\s0, and in tunneling \s-1PPP\s0 over network sockets without 
    109 +changes to the source code. 
    110 +.PP 
    111 +This product includes cryptographic software written by 
    112 +Eric Young (eay@cryptsoft.com) 
    113 +.SH "OPTIONS" 
    114 +.IX Header "OPTIONS" 
    115 +.IP "<\fBfilename\fR>" 4 
    116 +.IX Item "<filename>" 
    117 +Use specified configuration file 
    118 +.IP "\fB\-fd n\fR (Unix only)" 4 
    119 +.IX Item "-fd n (Unix only)" 
    120 +Read the config file from specified file descriptor 
    121 +.IP "\fB\-help\fR" 4 
    122 +.IX Item "-help" 
    123 +Print \fBstunnel\fR help menu 
    124 +.IP "\fB\-version\fR" 4 
    125 +.IX Item "-version" 
    126 +Print \fBstunnel\fR version and compile time defaults 
    127 +.IP "\fB\-sockets\fR" 4 
    128 +.IX Item "-sockets" 
    129 +Print default socket options 
    130 +.IP "\fB\-install\fR (\s-1NT/2000/XP\s0 only)" 4 
    131 +.IX Item "-install (NT/2000/XP only)" 
    132 +Install \s-1NT\s0 Service 
    133 +.IP "\fB\-uninstall\fR (\s-1NT/2000/XP\s0 only)" 4 
    134 +.IX Item "-uninstall (NT/2000/XP only)" 
    135 +Uninstall \s-1NT\s0 Service 
    136 +.IP "\fB\-start\fR (\s-1NT/2000/XP\s0 only)" 4 
    137 +.IX Item "-start (NT/2000/XP only)" 
    138 +Start \s-1NT\s0 Service 
    139 +.IP "\fB\-stop\fR (\s-1NT/2000/XP\s0 only)" 4 
    140 +.IX Item "-stop (NT/2000/XP only)" 
    141 +Stop \s-1NT\s0 Service 
    142 +.IP "\fB\-quiet\fR (\s-1NT/2000/XP\s0 only)" 4 
    143 +.IX Item "-quiet (NT/2000/XP only)" 
    144 +Don't display a message box when successfully installed or uninstalled \s-1NT\s0 service 
    145 +.SH "CONFIGURATION FILE" 
    146 +.IX Header "CONFIGURATION FILE" 
    147 +Each line of the configuration file can be either: 
    148 +.IP "\(bu" 4 
    149 +an empty line (ignored) 
    150 +.IP "\(bu" 4 
    151 +a comment starting with ';' (ignored) 
    152 +.IP "\(bu" 4 
    153 +an 'option_name = option_value' pair 
    154 +.IP "\(bu" 4 
    155 +\&'[service_name]' indicating a start of a service definition 
    156 +.SS "\s-1GLOBAL\s0 \s-1OPTIONS\s0" 
    157 +.IX Subsection "GLOBAL OPTIONS" 
    158 +.IP "\fBchroot\fR = directory (Unix only)" 4 
    159 +.IX Item "chroot = directory (Unix only)" 
    160 +directory to chroot \fBstunnel\fR process 
    161 +.Sp 
    162 +\&\fBchroot\fR keeps \fBstunnel\fR in chrooted jail.  \fICApath\fR, \fICRLpath\fR, \fIpid\fR 
    163 +and \fIexec\fR are located inside the jail and the patches have to be relative 
    164 +to the directory specified with \fBchroot\fR. 
    165 +.Sp 
    166 +To have libwrap (\s-1TCP\s0 Wrappers) control effective in a chrooted environment 
    167 +you also have to copy its configuration files (/etc/hosts.allow and 
    168 +/etc/hosts.deny) there. 
    169 +.IP "\fBcompression\fR = zlib | rle" 4 
    170 +.IX Item "compression = zlib | rle" 
    171 +select data compression algorithm 
    172 +.Sp 
    173 +default: no compression 
    174 +.Sp 
    175 +zlib compression of OpenSSL 0.9.8 or above is not backward compatible with 
    176 +OpenSSL 0.9.7. 
    177 +.Sp 
    178 +rle compression is currently not implemented by the OpenSSL library. 
    179 +.IP "\fBdebug\fR = [facility.]level" 4 
    180 +.IX Item "debug = [facility.]level" 
    181 +debugging level 
    182 +.Sp 
    183 +Level is a one of the syslog level names or numbers 
    184 +emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), 
    185 +info (6), or debug (7).  All logs for the specified level and 
    186 +all levels numerically less than it will be shown.  Use \fBdebug = debug\fR or 
    187 +\&\fBdebug = 7\fR for greatest debugging output.  The default is notice (5). 
    188 +.Sp 
    189 +The syslog facility 'daemon' will be used unless a facility name is supplied. 
    190 +(Facilities are not supported on Win32.) 
    191 +.Sp 
    192 +Case is ignored for both facilities and levels. 
    193 +.IP "\fB\s-1EGD\s0\fR = egd path (Unix only)" 4 
    194 +.IX Item "EGD = egd path (Unix only)" 
    195 +path to Entropy Gathering Daemon socket 
    196 +.Sp 
    197 +Entropy Gathering Daemon socket to use to feed OpenSSL random number 
    198 +generator.  (Available only if compiled with OpenSSL 0.9.5a or higher) 
    199 +.IP "\fBengine\fR = auto | <engine id>" 4 
    200 +.IX Item "engine = auto | <engine id>" 
    201 +select hardware engine 
    202 +.Sp 
    203 +default: software-only cryptography 
    204 +.Sp 
    205 +There's an example in '\s-1EXAMPLES\s0' section. 
    206 +.IP "\fBengineCtrl\fR = command[:parameter]" 4 
    207 +.IX Item "engineCtrl = command[:parameter]" 
    208 +control hardware engine 
    209 +.Sp 
    210 +Special commands \*(L"\s-1LOAD\s0\*(R" and \*(L"\s-1INIT\s0\*(R" can be used to load and initialize the 
    211 +engine cryptogaphic module. 
    212 +.IP "\fBfips\fR = yes | no" 4 
    213 +.IX Item "fips = yes | no" 
    214 +Enable or disable \s-1FIPS\s0 140\-2 mode. 
    215 +.Sp 
    216 +This option allows to disable entering \s-1FIPS\s0 mode if stunnel was compiled with 
    217 +\&\s-1FIPS\s0 140\-2 support. 
    218 +.Sp 
    219 +default: yes 
    220 +.IP "\fBforeground\fR = yes | no (Unix only)" 4 
    221 +.IX Item "foreground = yes | no (Unix only)" 
    222 +foreground mode 
    223 +.Sp 
    224 +Stay in foreground (don't fork) and log to stderr 
    225 +instead of via syslog (unless \fBoutput\fR is specified). 
    226 +.Sp 
    227 +default: background in daemon mode 
    228 +.IP "\fBoutput\fR = file" 4 
    229 +.IX Item "output = file" 
    230 +append log messages to a file instead of using syslog 
    231 +.Sp 
    232 +/dev/stdout device can be used to redirect log messages to the standard 
    233 +output (for example to log them with daemontools splogger). 
    234 +.IP "\fBpid\fR = file (Unix only)" 4 
    235 +.IX Item "pid = file (Unix only)" 
    236 +pid file location 
    237 +.Sp 
    238 +If the argument is empty, then no pid file will be created. 
    239 +.Sp 
    240 +\&\fIpid\fR path is relative to \fIchroot\fR directory if specified. 
    241 +.IP "\fBRNDbytes\fR = bytes" 4 
    242 +.IX Item "RNDbytes = bytes" 
    243 +bytes to read from random seed files 
    244 +.Sp 
    245 +Number of bytes of data read from random seed files.  With \s-1SSL\s0 versions 
    246 +less than 0.9.5a, also determines how many bytes of data are considered 
    247 +sufficient to seed the \s-1PRNG\s0.  More recent OpenSSL versions have a builtin 
    248 +function to determine when sufficient randomness is available. 
    249 +.IP "\fBRNDfile\fR = file" 4 
    250 +.IX Item "RNDfile = file" 
    251 +path to file with random seed data 
    252 +.Sp 
    253 +The \s-1SSL\s0 library will use data from this file first to seed the random 
    254 +number generator. 
    255 +.IP "\fBRNDoverwrite\fR = yes | no" 4 
    256 +.IX Item "RNDoverwrite = yes | no" 
    257 +overwrite the random seed files with new random data 
    258 +.Sp 
    259 +default: yes 
    260 +.IP "\fBservice\fR = servicename" 4 
    261 +.IX Item "service = servicename" 
    262 +use specified string as the service name 
    263 +.Sp 
    264 +\&\fBOn Unix:\fR \fIinetd\fR mode service name for \s-1TCP\s0 Wrapper library. 
    265 +.Sp 
    266 +\&\fBOn \s-1NT/2000/XP:\s0\fR \s-1NT\s0 service name in the Control Panel. 
    267 +.Sp 
    268 +default: stunnel 
    269 +.IP "\fBsetgid\fR = groupname (Unix only)" 4 
    270 +.IX Item "setgid = groupname (Unix only)" 
    271 +\&\fIsetgid()\fR to groupname in daemon mode and clears all other groups 
    272 +.IP "\fBsetuid\fR = username (Unix only)" 4 
    273 +.IX Item "setuid = username (Unix only)" 
    274 +\&\fIsetuid()\fR to username in daemon mode 
    275 +.IP "\fBsocket\fR = a|l|r:option=value[:value]" 4 
    276 +.IX Item "socket = a|l|r:option=value[:value]" 
    277 +Set an option on accept/local/remote socket 
    278 +.Sp 
    279 +The values for linger option are l_onof:l_linger. 
    280 +The values for time are tv_sec:tv_usec. 
    281 +.Sp 
    282 +Examples: 
    283 +.Sp 
    284 +.Vb 11 
    285 +\&    socket = l:SO_LINGER=1:60 
    286 +\&        set one minute timeout for closing local socket 
    287 +\&    socket = r:TCP_NODELAY=1 
    288 +\&        turn off the Nagle algorithm for remote sockets 
    289 +\&    socket = r:SO_OOBINLINE=1 
    290 +\&        place out\-of\-band data directly into the 
    291 +\&        receive data stream for remote sockets 
    292 +\&    socket = a:SO_REUSEADDR=0 
    293 +\&        disable address reuse (enabled by default) 
    294 +\&    socket = a:SO_BINDTODEVICE=lo 
    295 +\&        only accept connections on loopback interface 
    296 +.Ve 
    297 +.IP "\fBsyslog\fR = yes | no (Unix only)" 4 
    298 +.IX Item "syslog = yes | no (Unix only)" 
    299 +enable logging via syslog 
    300 +.Sp 
    301 +default: yes 
    302 +.IP "\fBtaskbar\fR = yes | no (\s-1WIN32\s0 only)" 4 
    303 +.IX Item "taskbar = yes | no (WIN32 only)" 
    304 +enable the taskbar icon 
    305 +.Sp 
    306 +default: yes 
    307 +.SS "SERVICE-LEVEL \s-1OPTIONS\s0" 
    308 +.IX Subsection "SERVICE-LEVEL OPTIONS" 
    309 +Each configuration section begins with service name in square brackets. 
    310 +The service name is used for libwrap (\s-1TCP\s0 Wrappers) access control and lets 
    311 +you distinguish \fBstunnel\fR services in your log files. 
    312 +.PP 
    313 +Note that if you wish to run \fBstunnel\fR in \fIinetd\fR mode (where it 
    314 +is provided a network socket by a server such as \fIinetd\fR, \fIxinetd\fR, 
    315 +or \fItcpserver\fR) then you should read the section entitled \fI\s-1INETD\s0 \s-1MODE\s0\fR 
    316 +below. 
    317 +.IP "\fBaccept\fR = [host:]port" 4 
    318 +.IX Item "accept = [host:]port" 
    319 +accept connections on specified host:port 
    320 +.Sp 
    321 +If no host specified, defaults to all \s-1IP\s0 addresses for the local host. 
    322 +.IP "\fBCApath\fR = directory" 4 
    323 +.IX Item "CApath = directory" 
    324 +Certificate Authority directory 
    325 +.Sp 
    326 +This is the directory in which \fBstunnel\fR will look for certificates when using 
    327 +the \fIverify\fR. Note that the certificates in this directory should be named 
    328 +\&\s-1XXXXXXXX\s0.0 where \s-1XXXXXXXX\s0 is the hash value of the \s-1DER\s0 encoded subject of the 
    329 +cert (the first 4 bytes of the \s-1MD5\s0 hash in least significant byte order). 
    330 +.Sp 
    331 +\&\fICApath\fR path is relative to \fIchroot\fR directory if specified. 
    332 +.IP "\fBCAfile\fR = certfile" 4 
    333 +.IX Item "CAfile = certfile" 
    334 +Certificate Authority file 
    335 +.Sp 
    336 +This file contains multiple \s-1CA\s0 certificates, used with the \fIverify\fR. 
    337 +.IP "\fBcert\fR = pemfile" 4 
    338 +.IX Item "cert = pemfile" 
    339 +certificate chain \s-1PEM\s0 file name 
    340 +.Sp 
    341 +A \s-1PEM\s0 is always needed in server mode. 
    342 +Specifying this flag in client mode will use this certificate chain 
    343 +as a client side certificate chain.  Using client side certs is optional. 
    344 +The certificates must be in \s-1PEM\s0 format and must be sorted starting with the 
    345 +certificate to the highest level (root \s-1CA\s0). 
    346 +.IP "\fBciphers\fR = cipherlist" 4 
    347 +.IX Item "ciphers = cipherlist" 
    348 +Select permitted \s-1SSL\s0 ciphers 
    349 +.Sp 
    350 +A colon delimited list of the ciphers to allow in the \s-1SSL\s0 connection. 
    351 +For example \s-1DES\-CBC3\-SHA:IDEA\-CBC\-MD5\s0 
    352 +.IP "\fBclient\fR = yes | no" 4 
    353 +.IX Item "client = yes | no" 
    354 +client mode (remote service uses \s-1SSL\s0) 
    355 +.Sp 
    356 +default: no (server mode) 
    357 +.IP "\fBconnect\fR = [host:]port" 4 
    358 +.IX Item "connect = [host:]port" 
    359 +connect to a remote host:port 
    360 +.Sp 
    361 +If no host is specified, the host defaults to localhost. 
    362 +.Sp 
    363 +Multiple \fBconnect\fR options are allowed in a single service section. 
    364 +.Sp 
    365 +If host resolves to multiple addresses and/or if multiple \fBconnect\fR 
    366 +options are specified, then the remote address is chosen using a 
    367 +round-robin algorithm. 
    368 +.IP "\fBCRLpath\fR = directory" 4 
    369 +.IX Item "CRLpath = directory" 
    370 +Certificate Revocation Lists directory 
    371 +.Sp 
    372 +This is the directory in which \fBstunnel\fR will look for CRLs when 
    373 +using the \fIverify\fR. Note that the CRLs in this directory should 
    374 +be named \s-1XXXXXXXX\s0.0 where \s-1XXXXXXXX\s0 is the hash value of the \s-1CRL\s0. 
    375 +.Sp 
    376 +\&\fICRLpath\fR path is relative to \fIchroot\fR directory if specified. 
    377 +.IP "\fBCRLfile\fR = certfile" 4 
    378 +.IX Item "CRLfile = certfile" 
    379 +Certificate Revocation Lists file 
    380 +.Sp 
    381 +This file contains multiple CRLs, used with the \fIverify\fR. 
    382 +.IP "\fBdelay\fR = yes | no" 4 
    383 +.IX Item "delay = yes | no" 
    384 +delay \s-1DNS\s0 lookup for 'connect' option 
    385 +.IP "\fBengineNum\fR = engine number" 4 
    386 +.IX Item "engineNum = engine number" 
    387 +select engine number to read private key 
    388 +.Sp 
    389 +The engines are numbered starting from 1. 
    390 +.IP "\fBexec\fR = executable_path (Unix only)" 4 
    391 +.IX Item "exec = executable_path (Unix only)" 
    392 +execute local inetd-type program 
    393 +.Sp 
    394 +\&\fIexec\fR path is relative to \fIchroot\fR directory if specified. 
    395 +.ie n .IP "\fBexecargs\fR = $0 $1 $2 ... (Unix only)" 4 
    396 +.el .IP "\fBexecargs\fR = \f(CW$0\fR \f(CW$1\fR \f(CW$2\fR ... (Unix only)" 4 
    397 +.IX Item "execargs = $0 $1 $2 ... (Unix only)" 
    398 +arguments for \fIexec\fR including program name ($0) 
    399 +.Sp 
    400 +Quoting is currently not supported. 
    401 +Arguments are separated with arbitrary number of whitespaces. 
    402 +.IP "\fBfailover\fR = rr | prio" 4 
    403 +.IX Item "failover = rr | prio" 
    404 +Failover strategy for multiple \*(L"connect\*(R" targets. 
    405 +.Sp 
    406 +.Vb 2 
    407 +\&    rr (round robin) \- fair load distribution 
    408 +\&    prio (priority) \- use the order specified in config file 
    409 +.Ve 
    410 +.Sp 
    411 +default: rr 
    412 +.IP "\fBident\fR = username" 4 
    413 +.IX Item "ident = username" 
    414 +use \s-1IDENT\s0 (\s-1RFC\s0 1413) username checking 
    415 +.IP "\fBkey\fR = keyfile" 4 
    416 +.IX Item "key = keyfile" 
    417 +private key for certificate specified with \fIcert\fR option 
    418 +.Sp 
    419 +Private key is needed to authenticate certificate owner. 
    420 +Since this file should be kept secret it should only be readable 
    421 +to its owner.  On Unix systems you can use the following command: 
    422 +.Sp 
    423 +.Vb 1 
    424 +\&    chmod 600 keyfile 
    425 +.Ve 
    426 +.Sp 
    427 +default: value of \fIcert\fR option 
    428 +.IP "\fBlocal\fR = host" 4 
    429 +.IX Item "local = host" 
    430 +\&\s-1IP\s0 of the outgoing interface is used as source for remote connections. 
    431 +Use this option to bind a static local \s-1IP\s0 address, instead. 
    432 +.IP "\fB\s-1OCSP\s0\fR = url" 4 
    433 +.IX Item "OCSP = url" 
    434 +select \s-1OCSP\s0 server for certificate verification 
    435 +.IP "\fBOCSPflag\fR = flag" 4 
    436 +.IX Item "OCSPflag = flag" 
    437 +specify \s-1OCSP\s0 server flag 
    438 +.Sp 
    439 +Several \fIOCSPflag\fR can be used to specify multiple flags. 
    440 +.Sp 
    441 +currently supported flags: \s-1NOCERTS\s0, \s-1NOINTERN\s0 \s-1NOSIGS\s0, \s-1NOCHAIN\s0, \s-1NOVERIFY\s0, 
    442 +\&\s-1NOEXPLICIT\s0, \s-1NOCASIGN\s0, \s-1NODELEGATED\s0, \s-1NOCHECKS\s0, \s-1TRUSTOTHER\s0, \s-1RESPID_KEY\s0, \s-1NOTIME\s0 
    443 +.IP "\fBoptions\fR = SSL_options" 4 
    444 +.IX Item "options = SSL_options" 
    445 +OpenSSL library options 
    446 +.Sp 
    447 +The parameter is the OpenSSL option name as described in the 
    448 +\&\fI\fISSL_CTX_set_options\fI\|(3ssl)\fR manual, but without \fI\s-1SSL_OP_\s0\fR prefix. 
    449 +Several \fIoptions\fR can be used to specify multiple options. 
    450 +.Sp 
    451 +For example for compatibility with erroneous Eudora \s-1SSL\s0 implementation 
    452 +the following option can be used: 
    453 +.Sp 
    454 +.Vb 1 
    455 +\&    options = DONT_INSERT_EMPTY_FRAGMENTS 
    456 +.Ve 
    457 +.IP "\fBprotocol\fR = proto" 4 
    458 +.IX Item "protocol = proto" 
    459 +application protocol to negotiate \s-1SSL\s0 
    460 +.Sp 
    461 +currently supported: cifs, connect, imap, nntp, pop3, smtp, pgsql 
    462 +.IP "\fBprotocolAuthentication\fR = auth_type" 4 
    463 +.IX Item "protocolAuthentication = auth_type" 
    464 +authentication type for protocol negotiations 
    465 +.Sp 
    466 +currently supported: basic, \s-1NTLM\s0 
    467 +.Sp 
    468 +Currently authentication type only applies to 'connect' protocol. 
    469 +.Sp 
    470 +default: basic 
    471 +.IP "\fBprotocolHost\fR = host:port" 4 
    472 +.IX Item "protocolHost = host:port" 
    473 +destination address for protocol negotiations 
    474 +.IP "\fBprotocolPassword\fR = password" 4 
    475 +.IX Item "protocolPassword = password" 
    476 +password for protocol negotiations 
    477 +.IP "\fBprotocolUsername\fR = username" 4 
    478 +.IX Item "protocolUsername = username" 
    479 +username for protocol negotiations 
    480 +.IP "\fBpty\fR = yes | no (Unix only)" 4 
    481 +.IX Item "pty = yes | no (Unix only)" 
    482 +allocate pseudo terminal for 'exec' option 
    483 +.IP "\fBretry\fR = yes | no (Unix only)" 4 
    484 +.IX Item "retry = yes | no (Unix only)" 
    485 +reconnect a connect+exec section after it's disconnected 
    486 +.Sp 
    487 +default: no 
    488 +.IP "\fBsession\fR = timeout" 4 
    489 +.IX Item "session = timeout" 
    490 +session cache timeout 
    491 +.IP "\fBsessiond\fR = host:port" 4 
    492 +.IX Item "sessiond = host:port" 
    493 +address of sessiond \s-1SSL\s0 cache server 
    494 +.IP "\fBsslVersion\fR = version" 4 
    495 +.IX Item "sslVersion = version" 
    496 +select version of \s-1SSL\s0 protocol 
    497 +.Sp 
    498 +Allowed options: all, SSLv2, SSLv3, TLSv1 
    499 +.IP "\fBstack\fR = bytes (except for \s-1FORK\s0 model)" 4 
    500 +.IX Item "stack = bytes (except for FORK model)" 
    501 +thread stack size 
    502 +.IP "\fBTIMEOUTbusy\fR = seconds" 4 
    503 +.IX Item "TIMEOUTbusy = seconds" 
    504 +time to wait for expected data 
    505 +.IP "\fBTIMEOUTclose\fR = seconds" 4 
    506 +.IX Item "TIMEOUTclose = seconds" 
    507 +time to wait for close_notify (set to 0 for buggy \s-1MSIE\s0) 
    508 +.IP "\fBTIMEOUTconnect\fR = seconds" 4 
    509 +.IX Item "TIMEOUTconnect = seconds" 
    510 +time to wait to connect a remote host 
    511 +.IP "\fBTIMEOUTidle\fR = seconds" 4 
    512 +.IX Item "TIMEOUTidle = seconds" 
    513 +time to keep an idle connection 
    514 +.IP "\fBtransparent\fR = yes | no (Unix only)" 4 
    515 +.IX Item "transparent = yes | no (Unix only)" 
    516 +transparent proxy mode 
    517 +.Sp 
    518 +Re-write address to appear as if wrapped daemon is connecting 
    519 +from the \s-1SSL\s0 client machine instead of the machine running \fBstunnel\fR. 
    520 +.Sp 
    521 +This option is currently available in: 
    522 +.Sp 
    523 +.Vb 3 
    524 +\&    remote mode (I<connect> option) on Linux >=2.6.28 
    525 +\&    remote mode (I<connect> option) 2.2.x 
    526 +\&    local mode (I<exec> option) 
    527 +.Ve 
    528 +.Sp 
    529 +\&\fBRemote mode\fR (either 2.2.x and >=2.6.28) requires stunnel to be executed as 
    530 +root.  \fBsetuid\fR option will also break this functionality. 
    531 +.Sp 
    532 +\&\fBLinux >=2.6.28\fR requires the following setup for iptables and routing 
    533 +(possibly in /etc/rc.local or equivalent file): 
    534 +.Sp 
    535 +.Vb 6 
    536 +\&    iptables \-t mangle \-N DIVERT 
    537 +\&    iptables \-t mangle \-A PREROUTING \-p tcp \-m socket \-j DIVERT 
    538 +\&    iptables \-t mangle \-A DIVERT \-j MARK \-\-set\-mark 1 
    539 +\&    iptables \-t mangle \-A DIVERT \-j ACCEPT 
    540 +\&    ip rule add fwmark 1 lookup 100 
    541 +\&    ip route add local 0.0.0.0/0 dev lo table 100 
    542 +.Ve 
    543 +.Sp 
    544 +\&\fBLinux 2.2.x\fR requires kernel to be compiled with \fItransparent proxy\fR option. 
    545 +Connected service must be installed on a separate host. 
    546 +Routing towards the clients has to go through the stunnel box. 
    547 +.Sp 
    548 +\&\fBLocal mode\fR works by LD_PRELOADing env.so shared library. 
    549 +.IP "\fBverify\fR = level" 4 
    550 +.IX Item "verify = level" 
    551 +verify peer certificate 
    552 +.Sp 
    553 +.Vb 4 
    554 +\&    level 1 \- verify peer certificate if present 
    555 +\&    level 2 \- verify peer certificate 
    556 +\&    level 3 \- verify peer with locally installed certificate 
    557 +\&    default \- no verify 
    558 +.Ve 
    559 +.Sp 
    560 +It is important to understand, that this option was solely designed for access 
    561 +control and not for authorization.  Specifically for level 2 every non-revoked 
    562 +certificate is accepted regardless of its Common Name.  For this reason a 
    563 +dedicated \s-1CA\s0 should be used with level 2, and not a generic \s-1CA\s0 commonly used 
    564 +for webservers.  Level 3 is preferred for point-to-point connections. 
    565 +.SH "RETURN VALUE" 
    566 +.IX Header "RETURN VALUE" 
    567 +\&\fBstunnel\fR returns zero on success, non-zero on error. 
    568 +.SH "EXAMPLES" 
    569 +.IX Header "EXAMPLES" 
    570 +In order to provide \s-1SSL\s0 encapsulation to your local \fIimapd\fR service, use 
    571 +.PP 
    572 +.Vb 4 
    573 +\&    [imapd] 
    574 +\&    accept = 993 
    575 +\&    exec = /usr/sbin/imapd 
    576 +\&    execargs = imapd 
    577 +.Ve 
    578 +.PP 
    579 +If you want to provide tunneling to your \fIpppd\fR daemon on port 2020, 
    580 +use something like 
    581 +.PP 
    582 +.Vb 5 
    583 +\&    [vpn] 
    584 +\&    accept = 2020 
    585 +\&    exec = /usr/sbin/pppd 
    586 +\&    execargs = pppd local 
    587 +\&    pty = yes 
    588 +.Ve 
    589 +.PP 
    590 +If you want to use \fBstunnel\fR in \fIinetd\fR mode to launch your imapd 
    591 +process, you'd use this \fIstunnel.conf\fR. 
    592 +Note there must be no \fI[service_name]\fR section. 
    593 +.PP 
    594 +.Vb 2 
    595 +\&    exec = /usr/sbin/imapd 
    596 +\&    execargs = imapd 
    597 +.Ve 
    598 +.PP 
    599 +Here is an example of advanced engine configuration to read private key from an 
    600 +OpenSC engine 
    601 +.PP 
    602 +.Vb 7 
    603 +\&    engine=dynamic 
    604 +\&    engineCtrl=SO_PATH:/usr/lib/opensc/engine_pkcs11.so 
    605 +\&    engineCtrl=ID:pkcs11 
    606 +\&    engineCtrl=LIST_ADD:1 
    607 +\&    engineCtrl=LOAD 
    608 +\&    engineCtrl=MODULE_PATH:/usr/lib/pkcs11/opensc\-pkcs11.so 
    609 +\&    engineCtrl=INIT 
    610 +\& 
    611 +\&    [service] 
    612 +\&    engineNum=1 
    613 +\&    key=id_45 
    614 +.Ve 
    615 +.SH "FILES" 
    616 +.IX Header "FILES" 
    617 +.IP "\fIstunnel.conf\fR" 4 
    618 +.IX Item "stunnel.conf" 
    619 +\&\fBstunnel\fR configuration file 
    620 +.IP "\fIstunnel.pem\fR" 4 
    621 +.IX Item "stunnel.pem" 
    622 +\&\fBstunnel\fR certificate and private key 
    623 +.SH "BUGS" 
    624 +.IX Header "BUGS" 
    625 +Option \fIexecargs\fR does not support quoting. 
    626 +.SH "RESTRICTIONS" 
    627 +.IX Header "RESTRICTIONS" 
    628 +\&\fBstunnel\fR cannot be used for the \s-1FTP\s0 daemon because of the nature 
    629 +of the \s-1FTP\s0 protocol which utilizes multiple ports for data transfers. 
    630 +There are available \s-1SSL\s0 enabled versions of \s-1FTP\s0 and telnet daemons, however. 
    631 +.SH "NOTES" 
    632 +.IX Header "NOTES" 
    633 +.SS "\s-1INETD\s0 \s-1MODE\s0" 
    634 +.IX Subsection "INETD MODE" 
    635 +The most common use of \fBstunnel\fR is to listen on a network 
    636 +port and establish communication with either a new port 
    637 +via the connect option, or a new program via the \fIexec\fR option. 
    638 +However there is a special case when you wish to have 
    639 +some other program accept incoming connections and 
    640 +launch \fBstunnel\fR, for example with \fIinetd\fR, \fIxinetd\fR, 
    641 +or \fItcpserver\fR. 
    642 +.PP 
    643 +For example, if you have the following line in \fIinetd.conf\fR: 
    644 +.PP 
    645 +.Vb 1 
    646 +\&    imaps stream tcp nowait root /usr/bin/stunnel stunnel /etc/stunnel/imaps.conf 
    647 +.Ve 
    648 +.PP 
    649 +In these cases, the \fIinetd\fR\-style program is responsible 
    650 +for binding a network socket (\fIimaps\fR above) and handing 
    651 +it to \fBstunnel\fR when a connection is received. 
    652 +Thus you do not want \fBstunnel\fR to have any \fIaccept\fR option. 
    653 +All the \fIService Level Options\fR should be placed in the 
    654 +global options section, and no \fI[service_name]\fR section 
    655 +will be present.  See the \fI\s-1EXAMPLES\s0\fR section for example 
    656 +configurations. 
    657 +.SS "\s-1CERTIFICATES\s0" 
    658 +.IX Subsection "CERTIFICATES" 
    659 +Each \s-1SSL\s0 enabled daemon needs to present a valid X.509 certificate 
    660 +to the peer. It also needs a private key to decrypt the incoming 
    661 +data. The easiest way to obtain a certificate and a key is to  
    662 +generate them with the free \fIOpenSSL\fR package. You can find more 
    663 +information on certificates generation on pages listed below. 
    664 +.PP 
    665 +The order of contents of the \fI.pem\fR file is important.  It should contain the 
    666 +unencrypted private key first, then a signed certificate (not certificate 
    667 +request).  There should be also empty lines after certificate and private key. 
    668 +Plaintext certificate information appended on the top of generated certificate 
    669 +should be discarded. So the file should look like this: 
    670 +.PP 
    671 +.Vb 8 
    672 +\&    \-\-\-\-\-BEGIN RSA PRIVATE KEY\-\-\-\-\- 
    673 +\&    [encoded key] 
    674 +\&    \-\-\-\-\-END RSA PRIVATE KEY\-\-\-\-\- 
    675 +\&    [empty line] 
    676 +\&    \-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\- 
    677 +\&    [encoded certificate] 
    678 +\&    \-\-\-\-\-END CERTIFICATE\-\-\-\-\- 
    679 +\&    [empty line] 
    680 +.Ve 
    681 +.SS "\s-1RANDOMNESS\s0" 
    682 +.IX Subsection "RANDOMNESS" 
    683 +\&\fBstunnel\fR needs to seed the \s-1PRNG\s0 (pseudo random number generator) in 
    684 +order for \s-1SSL\s0 to use good randomness.  The following sources are loaded 
    685 +in order until sufficient random data has been gathered: 
    686 +.IP "\(bu" 4 
    687 +The file specified with the \fIRNDfile\fR flag. 
    688 +.IP "\(bu" 4 
    689 +The file specified by the \s-1RANDFILE\s0 environment variable, if set. 
    690 +.IP "\(bu" 4 
    691 +The file .rnd in your home directory, if \s-1RANDFILE\s0 not set. 
    692 +.IP "\(bu" 4 
    693 +The file specified with '\-\-with\-random' at compile time. 
    694 +.IP "\(bu" 4 
    695 +The contents of the screen if running on Windows. 
    696 +.IP "\(bu" 4 
    697 +The egd socket specified with the \fI\s-1EGD\s0\fR flag. 
    698 +.IP "\(bu" 4 
    699 +The egd socket specified with '\-\-with\-egd\-sock' at compile time. 
    700 +.IP "\(bu" 4 
    701 +The /dev/urandom device. 
    702 +.PP 
    703 +With recent (>=OpenSSL 0.9.5a) version of \s-1SSL\s0 it will stop loading 
    704 +random data automatically when sufficient entropy has been gathered. 
    705 +With previous versions it will continue to gather from all the above 
    706 +sources since no \s-1SSL\s0 function exists to tell when enough data is available. 
    707 +.PP 
    708 +Note that on Windows machines that do not have console user interaction 
    709 +(mouse movements, creating windows, etc) the screen contents are not 
    710 +variable enough to be sufficient, and you should provide a random file 
    711 +for use with the \fIRNDfile\fR flag. 
    712 +.PP 
    713 +Note that the file specified with the \fIRNDfile\fR flag should contain 
    714 +random data \*(-- that means it should contain different information 
    715 +each time \fBstunnel\fR is run.  This is handled automatically 
    716 +unless the \fIRNDoverwrite\fR flag is used.  If you wish to update this file 
    717 +manually, the \fIopenssl rand\fR command in recent versions of OpenSSL, 
    718 +would be useful. 
    719 +.PP 
    720 +One important note \*(-- if /dev/urandom is available, OpenSSL has a habit of 
    721 +seeding the \s-1PRNG\s0 with it even when checking the random state, so on 
    722 +systems with /dev/urandom you're likely to use it even though it's listed 
    723 +at the very bottom of the list above.  This isn't \fBstunnel's\fR behaviour, it's 
    724 +OpenSSLs. 
    725 +.SH "SEE ALSO" 
    726 +.IX Header "SEE ALSO" 
    727 +.IP "\fItcpd\fR\|(8)" 4 
    728 +.IX Item "tcpd" 
    729 +access control facility for internet services 
    730 +.IP "\fIinetd\fR\|(8)" 4 
    731 +.IX Item "inetd" 
    732 +internet 'super\-server' 
    733 +.IP "\fIhttp://stunnel.mirt.net/\fR" 4 
    734 +.IX Item "http://stunnel.mirt.net/" 
    735 +\&\fBstunnel\fR homepage 
    736 +.IP "\fIhttp://www.stunnel.org/\fR" 4 
    737 +.IX Item "http://www.stunnel.org/" 
    738 +\&\fBstunnel\fR Frequently Asked Questions 
    739 +.IP "\fIhttp://www.openssl.org/\fR" 4 
    740 +.IX Item "http://www.openssl.org/" 
    741 +OpenSSL project website 
    742 +.SH "AUTHOR" 
    743 +.IX Header "AUTHOR" 
    744 +.IP "Michal Trojnara" 4 
    745 +.IX Item "Michal Trojnara" 
    746 +<\fIMichal.Trojnara@mirt.net\fR> 
    74715--- a/doc/stunnel.fr.8 
    74816+++ b/doc/stunnel.fr.8 
     
    76028--- a/src/client.c 
    76129+++ b/src/client.c 
    762 @@ -90,6 +90,12 @@ CLI *alloc_client_session(LOCAL_OPTIONS  
     30@@ -86,6 +86,12 @@ CLI *alloc_client_session(SERVICE_OPTION 
    76331         return NULL; 
    76432     } 
     
    77341     c->local_wfd.fd=wfd; 
    77442     return c; 
    775 @@ -382,6 +388,29 @@ static void init_ssl(CLI *c) { 
     43@@ -376,6 +382,29 @@ static void init_ssl(CLI *c) { 
    77644     } 
    77745 } 
     
    80371 /* is socket/SSL open for read/write? */ 
    80472 #define sock_rd (c->sock_rfd->rd) 
    805 @@ -416,13 +445,16 @@ static void transfer(CLI *c) { 
     73@@ -410,13 +439,16 @@ static void transfer(CLI *c) { 
    80674         check_SSL_pending=0; 
    80775  
     
    82290         if(SSL_read_wants_read || 
    82391                 SSL_write_wants_read || 
    824 @@ -521,7 +553,8 @@ static void transfer(CLI *c) { 
     92@@ -515,7 +547,8 @@ static void transfer(CLI *c) { 
    82593                 break; 
    82694             default: 
     
    832100                 c->ssl_ptr-=num; 
    833101                 c->sock_bytes+=num; 
    834 @@ -581,7 +614,8 @@ static void transfer(CLI *c) { 
     102@@ -577,7 +610,8 @@ static void transfer(CLI *c) { 
    835103         /****************************** read from socket */ 
    836104         if(sock_rd && sock_can_rd) { 
     
    842110             case -1: 
    843111                 parse_socket_error(c, "readsocket"); 
    844 @@ -601,10 +635,73 @@ static void transfer(CLI *c) { 
     112@@ -597,10 +631,73 @@ static void transfer(CLI *c) { 
    845113                 (SSL_read_wants_write && ssl_can_wr) || 
    846114                 (check_SSL_pending && SSL_pending(c->ssl))) { 
     
    917185                 break; 
    918186             case SSL_ERROR_WANT_WRITE: 
    919 --- /dev/null 
    920 +++ b/src/client.c.orig 
    921 @@ -0,0 +1,1042 @@ 
    922 +/* 
    923 + *   stunnel       Universal SSL tunnel 
    924 + *   Copyright (C) 1998-2009 Michal Trojnara <Michal.Trojnara@mirt.net> 
    925 + * 
    926 + *   This program is free software; you can redistribute it and/or modify it 
    927 + *   under the terms of the GNU General Public License as published by the 
    928 + *   Free Software Foundation; either version 2 of the License, or (at your 
    929 + *   option) any later version. 
    930 + *  
    931 + *   This program is distributed in the hope that it will be useful, 
    932 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
    933 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    934 + *   See the GNU General Public License for more details. 
    935 + *  
    936 + *   You should have received a copy of the GNU General Public License along 
    937 + *   with this program; if not, see <http://www.gnu.org/licenses>. 
    938 + *  
    939 + *   Linking stunnel statically or dynamically with other modules is making 
    940 + *   a combined work based on stunnel. Thus, the terms and conditions of 
    941 + *   the GNU General Public License cover the whole combination. 
    942 + *  
    943 + *   In addition, as a special exception, the copyright holder of stunnel 
    944 + *   gives you permission to combine stunnel with free software programs or 
    945 + *   libraries that are released under the GNU LGPL and with code included 
    946 + *   in the standard release of OpenSSL under the OpenSSL License (or 
    947 + *   modified versions of such code, with unchanged license). You may copy 
    948 + *   and distribute such a system following the terms of the GNU GPL for 
    949 + *   stunnel and the licenses of the other code concerned. 
    950 + *  
    951 + *   Note that people who make modified versions of stunnel are not obligated 
    952 + *   to grant this special exception for their modified versions; it is their 
    953 + *   choice whether to do so. The GNU General Public License gives permission 
    954 + *   to release a modified version without this exception; this exception 
    955 + *   also makes it possible to release a modified version which carries 
    956 + *   forward this exception. 
    957 + */ 
    958 + 
    959 +/* Undefine if you have problems with make_sockets() */ 
    960 +#define INET_SOCKET_PAIR 
    961 + 
    962 +#include "common.h" 
    963 +#include "prototypes.h" 
    964 + 
    965 +#ifndef SHUT_RD 
    966 +#define SHUT_RD 0 
    967 +#endif 
    968 +#ifndef SHUT_WR 
    969 +#define SHUT_WR 1 
    970 +#endif 
    971 +#ifndef SHUT_RDWR 
    972 +#define SHUT_RDWR 2 
    973 +#endif 
    974 + 
    975 +#if SSLEAY_VERSION_NUMBER >= 0x0922 
    976 +static char *sid_ctx="stunnel SID"; 
    977 +    /* const allowed here */ 
    978 +#endif 
    979 + 
    980 +static void do_client(CLI *); 
    981 +static void run_client(CLI *); 
    982 +static void init_local(CLI *); 
    983 +static void init_remote(CLI *); 
    984 +static void init_ssl(CLI *); 
    985 +static void transfer(CLI *); 
    986 +static void parse_socket_error(CLI *, const char *); 
    987 + 
    988 +static void print_cipher(CLI *); 
    989 +static void auth_user(CLI *); 
    990 +static int connect_local(CLI *); 
    991 +#ifndef USE_WIN32 
    992 +static void make_sockets(CLI *, int [2]); 
    993 +#endif 
    994 +static int connect_remote(CLI *); 
    995 +static void local_bind(CLI *c); 
    996 +static void print_bound_address(CLI *); 
    997 +static void reset(int, char *); 
    998 + 
    999 +int max_clients; 
    1000 +#ifndef USE_WIN32 
    1001 +int max_fds; 
    1002 +#endif 
    1003 + 
    1004 +/* Allocate local data structure for the new thread */ 
    1005 +CLI *alloc_client_session(LOCAL_OPTIONS *opt, int rfd, int wfd) { 
    1006 +    CLI *c; 
    1007 + 
    1008 +    c=calloc(1, sizeof(CLI)); 
    1009 +    if(!c) { 
    1010 +        s_log(LOG_ERR, "Memory allocation failed"); 
    1011 +        return NULL; 
    1012 +    } 
    1013 +    c->opt=opt; 
    1014 +    c->local_rfd.fd=rfd; 
    1015 +    c->local_wfd.fd=wfd; 
    1016 +    return c; 
    1017 +} 
    1018 + 
    1019 +void *client(void *arg) { 
    1020 +    CLI *c=arg; 
    1021 + 
    1022 +#ifdef DEBUG_STACK_SIZE 
    1023 +    stack_info(1); /* initialize */ 
    1024 +#endif 
    1025 +    s_log(LOG_DEBUG, "%s started", c->opt->servname); 
    1026 +#ifndef USE_WIN32 
    1027 +    if(c->opt->option.remote && c->opt->option.program) { 
    1028 +            /* connect and exec options specified together */ 
    1029 +            /* -> spawn a local program instead of stdio */ 
    1030 +        while((c->local_rfd.fd=c->local_wfd.fd=connect_local(c))>=0) { 
    1031 +            run_client(c); 
    1032 +            if(!c->opt->option.retry) 
    1033 +                break; 
    1034 +            sleep(1); /* FIXME: not a good idea in ucontext threading */ 
    1035 +        } 
    1036 +    } else 
    1037 +#endif 
    1038 +    { 
    1039 +        if(alloc_fd(c->local_rfd.fd)) 
    1040 +            return NULL; 
    1041 +        if(c->local_wfd.fd!=c->local_rfd.fd) 
    1042 +            if(alloc_fd(c->local_wfd.fd)) 
    1043 +                return NULL; 
    1044 +        run_client(c); 
    1045 +    } 
    1046 +    free(c); 
    1047 +#ifdef DEBUG_STACK_SIZE 
    1048 +    stack_info(0); /* display computed value */ 
    1049 +#endif 
    1050 +#if defined(USE_WIN32) && !defined(_WIN32_WCE) 
    1051 +    _endthread(); 
    1052 +#endif 
    1053 +#ifdef USE_UCONTEXT 
    1054 +    s_log(LOG_DEBUG, "Context %ld closed", ready_head->id); 
    1055 +    s_poll_wait(NULL, 0, 0); /* wait on poll() */ 
    1056 +    s_log(LOG_ERR, "INTERNAL ERROR: failed to drop context"); 
    1057 +#endif 
    1058 +    return NULL; 
    1059 +} 
    1060 + 
    1061 +static void run_client(CLI *c) { 
    1062 +    int error; 
    1063 + 
    1064 +    c->remote_fd.fd=-1; 
    1065 +    c->fd=-1; 
    1066 +    c->ssl=NULL; 
    1067 +    c->sock_bytes=c->ssl_bytes=0; 
    1068 + 
    1069 +    error=setjmp(c->err); 
    1070 +    if(!error) 
    1071 +        do_client(c); 
    1072 + 
    1073 +    s_log(LOG_NOTICE, 
    1074 +        "Connection %s: %d bytes sent to SSL, %d bytes sent to socket", 
    1075 +         error==1 ? "reset" : "closed", c->ssl_bytes, c->sock_bytes); 
    1076 + 
    1077 +        /* Cleanup IDENT socket */ 
    1078 +    if(c->fd>=0) 
    1079 +        closesocket(c->fd); 
    1080 + 
    1081 +        /* Cleanup SSL */ 
    1082 +    if(c->ssl) { /* SSL initialized */ 
    1083 +        SSL_set_shutdown(c->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 
    1084 +        SSL_free(c->ssl); 
    1085 +        ERR_remove_state(0); 
    1086 +    } 
    1087 + 
    1088 +        /* Cleanup remote socket */ 
    1089 +    if(c->remote_fd.fd>=0) { /* Remote socket initialized */ 
    1090 +        if(error==1 && c->remote_fd.is_socket) 
    1091 +            reset(c->remote_fd.fd, "linger (remote)"); 
    1092 +        closesocket(c->remote_fd.fd); 
    1093 +    } 
    1094 + 
    1095 +        /* Cleanup local socket */ 
    1096 +    if(c->local_rfd.fd>=0) { /* Local socket initialized */ 
    1097 +        if(c->local_rfd.fd==c->local_wfd.fd) { 
    1098 +            if(error==1 && c->local_rfd.is_socket) 
    1099 +                reset(c->local_rfd.fd, "linger (local)"); 
    1100 +            closesocket(c->local_rfd.fd); 
    1101 +        } else { /* STDIO */ 
    1102 +            if(error==1 && c->local_rfd.is_socket) 
    1103 +                reset(c->local_rfd.fd, "linger (local_rfd)"); 
    1104 +            if(error==1 && c->local_wfd.is_socket) 
    1105 +                reset(c->local_wfd.fd, "linger (local_wfd)"); 
    1106 +       } 
    1107 +    } 
    1108 +#ifdef USE_FORK 
    1109 +    if(!c->opt->option.remote) /* 'exec' specified */ 
    1110 +        child_status(); /* null SIGCHLD handler was used */ 
    1111 +#else 
    1112 +    enter_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */ 
    1113 +    s_log(LOG_DEBUG, "%s finished (%d left)", c->opt->servname, 
    1114 +        --num_clients); 
    1115 +    leave_critical_section(CRIT_CLIENTS); 
    1116 +#endif 
    1117 +} 
    1118 + 
    1119 +static void do_client(CLI *c) { 
    1120 +    init_local(c); 
    1121 +    if(!c->opt->option.client && !c->opt->protocol) { 
    1122 +        /* Server mode and no protocol negotiation needed */ 
    1123 +        init_ssl(c); 
    1124 +        init_remote(c); 
    1125 +    } else { 
    1126 +        init_remote(c); 
    1127 +        negotiate(c); 
    1128 +        init_ssl(c); 
    1129 +    } 
    1130 +    transfer(c); 
    1131 +} 
    1132 + 
    1133 +static void init_local(CLI *c) { 
    1134 +    SOCKADDR_UNION addr; 
    1135 +    socklen_t addrlen; 
    1136 + 
    1137 +    addrlen=sizeof addr; 
    1138 +    if(getpeername(c->local_rfd.fd, &addr.sa, &addrlen)<0) { 
    1139 +        strcpy(c->accepted_address, "NOT A SOCKET"); 
    1140 +        c->local_rfd.is_socket=0; 
    1141 +        c->local_wfd.is_socket=0; /* TODO: It's not always true */ 
    1142 +#ifdef USE_WIN32 
    1143 +        if(get_last_socket_error()!=ENOTSOCK) { 
    1144 +#else 
    1145 +        if(c->opt->option.transparent || get_last_socket_error()!=ENOTSOCK) { 
    1146 +#endif 
    1147 +            sockerror("getpeerbyname"); 
    1148 +            longjmp(c->err, 1); 
    1149 +        } 
    1150 +        /* Ignore ENOTSOCK error so 'local' doesn't have to be a socket */ 
    1151 +    } else { /* success */ 
    1152 +        /* copy addr to c->peer_addr */ 
    1153 +        memcpy(&c->peer_addr.addr[0], &addr, sizeof addr); 
    1154 +        c->peer_addr.num=1; 
    1155 +        s_ntop(c->accepted_address, &c->peer_addr.addr[0]); 
    1156 +        c->local_rfd.is_socket=1; 
    1157 +        c->local_wfd.is_socket=1; /* TODO: It's not always true */ 
    1158 +        /* It's a socket: lets setup options */ 
    1159 +        if(set_socket_options(c->local_rfd.fd, 1)<0) 
    1160 +            longjmp(c->err, 1); 
    1161 +#ifdef USE_LIBWRAP 
    1162 +        auth_libwrap(c); 
    1163 +#endif /* USE_LIBWRAP */ 
    1164 +        auth_user(c); 
    1165 +        s_log(LOG_NOTICE, "%s accepted connection from %s", 
    1166 +            c->opt->servname, c->accepted_address); 
    1167 +    } 
    1168 +} 
    1169 + 
    1170 +static void init_remote(CLI *c) { 
    1171 +    /* create connection to host/service */ 
    1172 +    if(c->opt->source_addr.num) 
    1173 +        memcpy(&c->bind_addr, &c->opt->source_addr, sizeof(SOCKADDR_LIST)); 
    1174 +#ifndef USE_WIN32 
    1175 +    else if(c->opt->option.transparent) 
    1176 +        memcpy(&c->bind_addr, &c->peer_addr, sizeof(SOCKADDR_LIST)); 
    1177 +#endif 
    1178 +    else { 
    1179 +        c->bind_addr.num=0; /* don't bind connecting socket */ 
    1180 +    } 
    1181 + 
    1182 +    /* setup c->remote_fd, now */ 
    1183 +    if(c->opt->option.remote) { 
    1184 +        c->remote_fd.fd=connect_remote(c); 
    1185 +    } else /* NOT in remote mode */ 
    1186 +        c->remote_fd.fd=connect_local(c); 
    1187 +    c->remote_fd.is_socket=1; /* Always! */ 
    1188 +#ifndef USE_WIN32 
    1189 +    if(c->remote_fd.fd>=max_fds) { 
    1190 +        s_log(LOG_ERR, "Remote file descriptor out of range (%d>=%d)", 
    1191 +            c->remote_fd.fd, max_fds); 
    1192 +        longjmp(c->err, 1); 
    1193 +    } 
    1194 +#endif 
    1195 +    s_log(LOG_DEBUG, "Remote FD=%d initialized", c->remote_fd.fd); 
    1196 +    if(set_socket_options(c->remote_fd.fd, 2)<0) 
    1197 +        longjmp(c->err, 1); 
    1198 +} 
    1199 + 
    1200 +static void init_ssl(CLI *c) { 
    1201 +    int i, err; 
    1202 +    SSL_SESSION *old_session; 
    1203 + 
    1204 +    if(!(c->ssl=SSL_new(c->opt->ctx))) { 
    1205 +        sslerror("SSL_new"); 
    1206 +        longjmp(c->err, 1); 
    1207 +    } 
    1208 +    SSL_set_ex_data(c->ssl, cli_index, c); /* for callbacks */ 
    1209 +#if SSLEAY_VERSION_NUMBER >= 0x0922 
    1210 +    SSL_set_session_id_context(c->ssl, (unsigned char *)sid_ctx, 
    1211 +        strlen(sid_ctx)); 
    1212 +#endif 
    1213 +    if(c->opt->option.client) { 
    1214 +        if(c->opt->session) { 
    1215 +            enter_critical_section(CRIT_SESSION); 
    1216 +            SSL_set_session(c->ssl, c->opt->session); 
    1217 +            leave_critical_section(CRIT_SESSION); 
    1218 +        } 
    1219 +        SSL_set_fd(c->ssl, c->remote_fd.fd); 
    1220 +        SSL_set_connect_state(c->ssl); 
    1221 +    } else { 
    1222 +        if(c->local_rfd.fd==c->local_wfd.fd) 
    1223 +            SSL_set_fd(c->ssl, c->local_rfd.fd); 
    1224 +        else { 
    1225 +           /* Does it make sence to have SSL on STDIN/STDOUT? */ 
    1226 +            SSL_set_rfd(c->ssl, c->local_rfd.fd); 
    1227 +            SSL_set_wfd(c->ssl, c->local_wfd.fd); 
    1228 +        } 
    1229 +        SSL_set_accept_state(c->ssl); 
    1230 +    } 
    1231 + 
    1232 +    /* Setup some values for transfer() function */ 
    1233 +    if(c->opt->option.client) { 
    1234 +        c->sock_rfd=&(c->local_rfd); 
    1235 +        c->sock_wfd=&(c->local_wfd); 
    1236 +        c->ssl_rfd=c->ssl_wfd=&(c->remote_fd); 
    1237 +    } else { 
    1238 +        c->sock_rfd=c->sock_wfd=&(c->remote_fd); 
    1239 +        c->ssl_rfd=&(c->local_rfd); 
    1240 +        c->ssl_wfd=&(c->local_wfd); 
    1241 +    } 
    1242 + 
    1243 +    while(1) { 
    1244 +        /* crude workaround for random MT-safety problems in OpenSSL */ 
    1245 +        /* performance penalty is not huge, as it's a non-blocking code */ 
    1246 +        enter_critical_section(CRIT_SSL); 
    1247 +        if(c->opt->option.client) 
    1248 +            i=SSL_connect(c->ssl); 
    1249 +        else 
    1250 +            i=SSL_accept(c->ssl); 
    1251 +        leave_critical_section(CRIT_SSL); 
    1252 +        err=SSL_get_error(c->ssl, i); 
    1253 +        if(err==SSL_ERROR_NONE) 
    1254 +            break; /* ok -> done */ 
    1255 +        if(err==SSL_ERROR_WANT_READ || err==SSL_ERROR_WANT_WRITE) { 
    1256 +            s_poll_init(&c->fds); 
    1257 +            s_poll_add(&c->fds, c->ssl_rfd->fd, 
    1258 +                err==SSL_ERROR_WANT_READ, 
    1259 +                err==SSL_ERROR_WANT_WRITE); 
    1260 +            switch(s_poll_wait(&c->fds, c->opt->timeout_busy, 0)) { 
    1261 +            case -1: 
    1262 +                sockerror("init_ssl: s_poll_wait"); 
    1263 +                longjmp(c->err, 1); 
    1264 +            case 0: 
    1265 +                s_log(LOG_INFO, "init_ssl: s_poll_wait timeout"); 
    1266 +                longjmp(c->err, 1); 
    1267 +            case 1: 
    1268 +                break; /* OK */ 
    1269 +            default: 
    1270 +                s_log(LOG_ERR, "init_ssl: s_poll_wait unknown result"); 
    1271 +                longjmp(c->err, 1); 
    1272 +            } 
    1273 +            continue; /* ok -> retry */ 
    1274 +        } 
    1275 +        if(err==SSL_ERROR_SYSCALL) { 
    1276 +            switch(get_last_socket_error()) { 
    1277 +            case EINTR: 
    1278 +            case EAGAIN: 
    1279 +                continue; 
    1280 +            } 
    1281 +        } 
    1282 +        if(c->opt->option.client) 
    1283 +            sslerror("SSL_connect"); 
    1284 +        else 
    1285 +            sslerror("SSL_accept"); 
    1286 +        longjmp(c->err, 1); 
    1287 +    } 
    1288 +    if(SSL_session_reused(c->ssl)) { 
    1289 +        s_log(LOG_INFO, "SSL %s: previous session reused", 
    1290 +            c->opt->option.client ? "connected" : "accepted"); 
    1291 +    } else { /* a new session was negotiated */ 
    1292 +        if(c->opt->option.client) { 
    1293 +            s_log(LOG_INFO, "SSL connected: new session negotiated"); 
    1294 +            enter_critical_section(CRIT_SESSION); 
    1295 +            old_session=c->opt->session; 
    1296 +            c->opt->session=SSL_get1_session(c->ssl); /* store it */ 
    1297 +            if(old_session) 
    1298 +                SSL_SESSION_free(old_session); /* release the old one */ 
    1299 +            leave_critical_section(CRIT_SESSION); 
    1300 +        } else 
    1301 +            s_log(LOG_INFO, "SSL accepted: new session negotiated"); 
    1302 +        print_cipher(c); 
    1303 +    } 
    1304 +} 
    1305 + 
    1306 +/****************************** some defines for transfer() */ 
    1307 +/* is socket/SSL open for read/write? */ 
    1308 +#define sock_rd (c->sock_rfd->rd) 
    1309 +#define sock_wr (c->sock_wfd->wr) 
    1310 +#define ssl_rd  (c->ssl_rfd->rd) 
    1311 +#define ssl_wr  (c->ssl_wfd->wr) 
    1312 +/* NOTE: above defines are related to the logical data stream, 
    1313 + * not the underlying file descriptors */ 
    1314 + 
    1315 +/* is socket/SSL ready for read/write? */ 
    1316 +#define sock_can_rd (s_poll_canread(&c->fds, c->sock_rfd->fd)) 
    1317 +#define sock_can_wr (s_poll_canwrite(&c->fds, c->sock_wfd->fd)) 
    1318 +#define ssl_can_rd  (s_poll_canread(&c->fds, c->ssl_rfd->fd)) 
    1319 +#define ssl_can_wr  (s_poll_canwrite(&c->fds, c->ssl_wfd->fd)) 
    1320 + 
    1321 +/****************************** transfer data */ 
    1322 +static void transfer(CLI *c) { 
    1323 +    int watchdog=0; /* a counter to detect an infinite loop */ 
    1324 +    int error; 
    1325 +    socklen_t optlen; 
    1326 +    int num, err, check_SSL_pending; 
    1327 +    int SSL_shutdown_wants_read=0, SSL_shutdown_wants_write=0; 
    1328 +    int SSL_write_wants_read=0, SSL_write_wants_write=0; 
    1329 +    int SSL_read_wants_read=0, SSL_read_wants_write=0; 
    1330 + 
    1331 +    c->sock_ptr=c->ssl_ptr=0; 
    1332 +    sock_rd=sock_wr=ssl_rd=ssl_wr=1; 
    1333 + 
    1334 +    do { /* main loop */ 
    1335 +        /* set flag to try and read any buffered SSL data 
    1336 +         * if we made room in the buffer by writing to the socket */ 
    1337 +        check_SSL_pending=0; 
    1338 + 
    1339 +        SSL_read_wants_read= 
    1340 +            ssl_rd && c->ssl_ptr<BUFFSIZE && !SSL_read_wants_write; 
    1341 +        SSL_write_wants_write= 
    1342 +            ssl_wr && c->sock_ptr && !SSL_write_wants_read; 
    1343 + 
    1344 +        /****************************** setup c->fds structure */ 
    1345 +        s_poll_init(&c->fds); /* initialize the structure */ 
    1346 +        if(sock_rd && c->sock_ptr<BUFFSIZE) 
    1347 +            s_poll_add(&c->fds, c->sock_rfd->fd, 1, 0); 
    1348 +        if(SSL_read_wants_read || 
    1349 +                SSL_write_wants_read || 
    1350 +                SSL_shutdown_wants_read) 
    1351 +            s_poll_add(&c->fds, c->ssl_rfd->fd, 1, 0); 
    1352 +        if(sock_wr && c->ssl_ptr) 
    1353 +            s_poll_add(&c->fds, c->sock_wfd->fd, 0, 1); 
    1354 +        if(SSL_read_wants_write || 
    1355 +                SSL_write_wants_write || 
    1356 +                SSL_shutdown_wants_write) 
    1357 +            s_poll_add(&c->fds, c->ssl_wfd->fd, 0, 1); 
    1358 + 
    1359 +        /****************************** wait for an event */ 
    1360 +        err=s_poll_wait(&c->fds, (sock_rd && ssl_rd) /* both peers open */ || 
    1361 +            c->ssl_ptr /* data buffered to write to socket */ || 
    1362 +            c->sock_ptr /* data buffered to write to SSL */ ? 
    1363 +            c->opt->timeout_idle : c->opt->timeout_close, 0); 
    1364 +        switch(err) { 
    1365 +        case -1: 
    1366 +            sockerror("transfer: s_poll_wait"); 
    1367 +            longjmp(c->err, 1); 
    1368 +        case 0: /* timeout */ 
    1369 +            if((sock_rd && ssl_rd) || c->ssl_ptr || c->sock_ptr) { 
    1370 +                s_log(LOG_INFO, "s_poll_wait timeout: connection reset"); 
    1371 +                longjmp(c->err, 1); 
    1372 +            } else { /* already closing connection */ 
    1373 +                s_log(LOG_INFO, "s_poll_wait timeout: connection close"); 
    1374 +                return; /* OK */ 
    1375 +            } 
    1376 +        } 
    1377 +        if(!(sock_can_rd || sock_can_wr || ssl_can_rd || ssl_can_wr)) { 
    1378 +            s_log(LOG_ERR, "INTERNAL ERROR: " 
    1379 +                "s_poll_wait returned %d, but no descriptor is ready", err); 
    1380 +            longjmp(c->err, 1); 
    1381 +        } 
    1382 +        if(!sock_rd && sock_can_rd) { 
    1383 +            optlen=sizeof error; 
    1384 +            if(getsockopt(c->sock_rfd->fd, SOL_SOCKET, SO_ERROR, 
    1385 +                    (void *)&error, &optlen)) 
    1386 +                error=get_last_socket_error(); /* failed -> ask why */ 
    1387 +            if(error) { /* really an error? */ 
    1388 +                s_log(LOG_ERR, "Closed socket ready to read: %s (%d)", 
    1389 +                    my_strerror(error), error); 
    1390 +                longjmp(c->err, 1); 
    1391 +            } 
    1392 +            if(c->ssl_ptr) { /* anything left to write */ 
    1393 +                s_log(LOG_ERR, "Closed socket ready to read - reset"); 
    1394 +                longjmp(c->err, 1); 
    1395 +            } 
    1396 +            s_log(LOG_INFO, "Closed socket ready to read - write close"); 
    1397 +            sock_wr=0; /* no further write allowed */ 
    1398 +            shutdown(c->sock_wfd->fd, SHUT_WR); /* send TCP FIN */ 
    1399 +        } 
    1400 + 
    1401 +        /****************************** send SSL close_notify message */ 
    1402 +        if(SSL_shutdown_wants_read || SSL_shutdown_wants_write) { 
    1403 +            SSL_shutdown_wants_read=SSL_shutdown_wants_write=0; 
    1404 +            num=SSL_shutdown(c->ssl); /* send close_notify */ 
    1405 +            if(num<0) /* -1 - not completed */ 
    1406 +                err=SSL_get_error(c->ssl, num); 
    1407 +            else /* 0 or 1 - success */ 
    1408 +                err=SSL_ERROR_NONE; 
    1409 +            switch(err) { 
    1410 +            case SSL_ERROR_NONE: /* the shutdown was successfully completed */ 
    1411 +                s_log(LOG_INFO, "SSL_shutdown successfully sent close_notify"); 
    1412 +                break; 
    1413 +            case SSL_ERROR_WANT_WRITE: 
    1414 +                s_log(LOG_DEBUG, "SSL_shutdown returned WANT_WRITE: retrying"); 
    1415 +                SSL_shutdown_wants_write=1; 
    1416 +                break; 
    1417 +            case SSL_ERROR_WANT_READ: 
    1418 +                s_log(LOG_DEBUG, "SSL_shutdown returned WANT_READ: retrying"); 
    1419 +                SSL_shutdown_wants_read=1; 
    1420 +                break; 
    1421 +            case SSL_ERROR_SYSCALL: /* socket error */ 
    1422 +                parse_socket_error(c, "SSL_shutdown"); 
    1423 +                break; 
    1424 +            case SSL_ERROR_SSL: /* SSL error */ 
    1425 +                sslerror("SSL_shutdown"); 
    1426 +                longjmp(c->err, 1); 
    1427 +            default: 
    1428 +                s_log(LOG_ERR, "SSL_shutdown/SSL_get_error returned %d", err); 
    1429 +                longjmp(c->err, 1); 
    1430 +            } 
    1431 +        } 
    1432 + 
    1433 +        /****************************** write to socket */ 
    1434 +        if(sock_wr && sock_can_wr) { 
    1435 +            num=writesocket(c->sock_wfd->fd, c->ssl_buff, c->ssl_ptr); 
    1436 +            switch(num) { 
    1437 +            case -1: /* error */ 
    1438 +                parse_socket_error(c, "writesocket"); 
    1439 +                break; 
    1440 +            case 0: 
    1441 +                s_log(LOG_DEBUG, "No data written to the socket: retrying"); 
    1442 +                break; 
    1443 +            default: 
    1444 +                memmove(c->ssl_buff, c->ssl_buff+num, c->ssl_ptr-num); 
    1445 +                if(c->ssl_ptr==BUFFSIZE) /* buffer was previously full */ 
    1446 +                    check_SSL_pending=1; /* check for data buffered by SSL */ 
    1447 +                c->ssl_ptr-=num; 
    1448 +                c->sock_bytes+=num; 
    1449 +                watchdog=0; /* reset watchdog */ 
    1450 +            } 
    1451 +        } 
    1452 + 
    1453 +        /****************************** write to SSL */ 
    1454 +        if((SSL_write_wants_read && ssl_can_rd) || 
    1455 +                (SSL_write_wants_write && ssl_can_wr)) { 
    1456 +            SSL_write_wants_read=0; 
    1457 +            num=SSL_write(c->ssl, c->sock_buff, c->sock_ptr); 
    1458 +            switch(err=SSL_get_error(c->ssl, num)) { 
    1459 +            case SSL_ERROR_NONE: 
    1460 +                memmove(c->sock_buff, c->sock_buff+num, c->sock_ptr-num); 
    1461 +                c->sock_ptr-=num; 
    1462 +                c->ssl_bytes+=num; 
    1463 +                watchdog=0; /* reset watchdog */ 
    1464 +                break; 
    1465 +            case SSL_ERROR_WANT_WRITE: /* nothing unexpected */ 
    1466 +                break; 
    1467 +            case SSL_ERROR_WANT_READ: 
    1468 +                s_log(LOG_DEBUG, "SSL_write returned WANT_READ: retrying"); 
    1469 +                SSL_write_wants_read=1; 
    1470 +                break; 
    1471 +            case SSL_ERROR_WANT_X509_LOOKUP: 
    1472 +                s_log(LOG_DEBUG, 
    1473 +                    "SSL_write returned WANT_X509_LOOKUP: retrying"); 
    1474 +                break; 
    1475 +            case SSL_ERROR_SYSCALL: /* socket error */ 
    1476 +                if(!num) { /* EOF */ 
    1477 +                    if(c->sock_ptr) { 
    1478 +                        s_log(LOG_ERR, 
    1479 +                            "SSL socket closed on SSL_write " 
    1480 +                                "with %d byte(s) in buffer", 
    1481 +                            c->sock_ptr); 
    1482 +                        longjmp(c->err, 1); /* reset the socket */ 
    1483 +                    } 
    1484 +                    s_log(LOG_DEBUG, "SSL socket closed on SSL_write"); 
    1485 +                    ssl_rd=ssl_wr=0; /* buggy or SSLv2 peer: no close_notify */ 
    1486 +                } else 
    1487 +                    parse_socket_error(c, "SSL_write"); 
    1488 +                break; 
    1489 +            case SSL_ERROR_ZERO_RETURN: /* close_notify received */ 
    1490 +                s_log(LOG_DEBUG, "SSL closed on SSL_write"); 
    1491 +                ssl_rd=0; 
    1492 +                break; 
    1493 +            case SSL_ERROR_SSL: 
    1494 +                sslerror("SSL_write"); 
    1495 +                longjmp(c->err, 1); 
    1496 +            default: 
    1497 +                s_log(LOG_ERR, "SSL_write/SSL_get_error returned %d", err); 
    1498 +                longjmp(c->err, 1); 
    1499 +            } 
    1500 +        } 
    1501 + 
    1502 +        /****************************** read from socket */ 
    1503 +        if(sock_rd && sock_can_rd) { 
    1504 +            num=readsocket(c->sock_rfd->fd, 
    1505 +                c->sock_buff+c->sock_ptr, BUFFSIZE-c->sock_ptr); 
    1506 +            switch(num) { 
    1507 +            case -1: 
    1508 +                parse_socket_error(c, "readsocket"); 
    1509 +                break; 
    1510 +            case 0: /* close */ 
    1511 +                s_log(LOG_DEBUG, "Socket closed on read"); 
    1512 +                sock_rd=0; 
    1513 +                break; 
    1514 +            default: 
    1515 +                c->sock_ptr+=num; 
    1516 +                watchdog=0; /* reset watchdog */ 
    1517 +            } 
    1518 +        } 
    1519 + 
    1520 +        /****************************** read from SSL */ 
    1521 +        if((SSL_read_wants_read && ssl_can_rd) || 
    1522 +                (SSL_read_wants_write && ssl_can_wr) || 
    1523 +                (check_SSL_pending && SSL_pending(c->ssl))) { 
    1524 +            SSL_read_wants_write=0; 
    1525 +            num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr); 
    1526 +            switch(err=SSL_get_error(c->ssl, num)) { 
    1527 +            case SSL_ERROR_NONE: 
    1528 +                c->ssl_ptr+=num; 
    1529 +                watchdog=0; /* reset watchdog */ 
    1530 +                break; 
    1531 +            case SSL_ERROR_WANT_WRITE: 
    1532 +                s_log(LOG_DEBUG, "SSL_read returned WANT_WRITE: retrying"); 
    1533 +                SSL_read_wants_write=1; 
    1534 +                break; 
    1535 +            case SSL_ERROR_WANT_READ: /* nothing unexpected */ 
    1536 +                break; 
    1537 +            case SSL_ERROR_WANT_X509_LOOKUP: 
    1538 +                s_log(LOG_DEBUG, 
    1539 +                    "SSL_read returned WANT_X509_LOOKUP: retrying"); 
    1540 +                break; 
    1541 +            case SSL_ERROR_SYSCALL: 
    1542 +                if(!num) { /* EOF */ 
    1543 +                    if(c->sock_ptr) { 
    1544 +                        s_log(LOG_ERR, 
    1545 +                            "SSL socket closed on SSL_read " 
    1546 +                                "with %d byte(s) in buffer", 
    1547 +                            c->sock_ptr); 
    1548 +                        longjmp(c->err, 1); /* reset the socket */ 
    1549 +                    } 
    1550 +                    s_log(LOG_DEBUG, "SSL socket closed on SSL_read"); 
    1551 +                    ssl_rd=ssl_wr=0; /* buggy or SSLv2 peer: no close_notify */ 
    1552 +                } else 
    1553 +                    parse_socket_error(c, "SSL_read"); 
    1554 +                break; 
    1555 +            case SSL_ERROR_ZERO_RETURN: /* close_notify received */ 
    1556 +                s_log(LOG_DEBUG, "SSL closed on SSL_read"); 
    1557 +                ssl_rd=0; 
    1558 +                break; 
    1559 +            case SSL_ERROR_SSL: 
    1560 +                sslerror("SSL_read"); 
    1561 +                longjmp(c->err, 1); 
    1562 +            default: 
    1563 +                s_log(LOG_ERR, "SSL_read/SSL_get_error returned %d", err); 
    1564 +                longjmp(c->err, 1); 
    1565 +            } 
    1566 +        } 
    1567 + 
    1568 +        /****************************** check write shutdown conditions */ 
    1569 +        if(sock_wr && !ssl_rd && !c->ssl_ptr) { 
    1570 +            s_log(LOG_DEBUG, "Socket write shutdown"); 
    1571 +            sock_wr=0; /* no further write allowed */ 
    1572 +            shutdown(c->sock_wfd->fd, SHUT_WR); /* send TCP FIN */ 
    1573 +        } 
    1574 +        if(ssl_wr && !sock_rd && !c->sock_ptr) { 
    1575 +            s_log(LOG_DEBUG, "SSL write shutdown"); 
    1576 +            ssl_wr=0; /* no further write allowed */ 
    1577 +            if(strcmp(SSL_get_version(c->ssl), "SSLv2")) { /* SSLv3, TLSv1 */ 
    1578 +                SSL_shutdown_wants_write=1; /* initiate close_notify */ 
    1579 +            } else { /* no alerts in SSLv2 including close_notify alert */ 
    1580 +                shutdown(c->sock_rfd->fd, SHUT_RD); /* notify the kernel */ 
    1581 +                shutdown(c->sock_wfd->fd, SHUT_WR); /* send TCP FIN */ 
    1582 +                SSL_set_shutdown(c->ssl, /* notify the OpenSSL library */ 
    1583 +                    SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 
    1584 +                ssl_rd=0; /* no further read allowed */ 
    1585 +            } 
    1586 +        } 
    1587 + 
    1588 +        /****************************** check watchdog */ 
    1589 +        if(++watchdog>100) { /* loop executes without transferring any data */ 
    1590 +            s_log(LOG_ERR, 
    1591 +                "transfer() loop executes not transferring any data"); 
    1592 +            s_log(LOG_ERR, 
    1593 +                "please report the problem to Michal.Trojnara@mirt.net"); 
    1594 +            s_log(LOG_ERR, "socket open: rd=%s wr=%s, ssl open: rd=%s wr=%s", 
    1595 +                sock_rd ? "yes" : "no", sock_wr ? "yes" : "no", 
    1596 +                ssl_rd ? "yes" : "no", ssl_wr ? "yes" : "no"); 
    1597 +            s_log(LOG_ERR, "socket ready: rd=%s wr=%s, ssl ready: rd=%s wr=%s", 
    1598 +                sock_can_rd ? "yes" : "no", sock_can_wr ? "yes" : "no", 
    1599 +                ssl_can_rd ? "yes" : "no", ssl_can_wr ? "yes" : "no"); 
    1600 +            s_log(LOG_ERR, 
    1601 +                "wants: SSL_read rd=%s wr=%s, " 
    1602 +                "SSL_write rd=%s wr=%s, " 
    1603 +                "SSL_shutdown rd=%s wr=%s", 
    1604 +                SSL_read_wants_read ? "yes" : "no", 
    1605 +                SSL_read_wants_write ? "yes" : "no", 
    1606 +                SSL_write_wants_read ? "yes" : "no", 
    1607 +                SSL_write_wants_write ? "yes" : "no", 
    1608 +                SSL_shutdown_wants_read ? "yes" : "no", 
    1609 +                SSL_shutdown_wants_write ? "yes" : "no"); 
    1610 +            s_log(LOG_ERR, "socket input buffer: %d byte(s), " 
    1611 +                "ssl input buffer: %d byte(s)", c->sock_ptr, c->ssl_ptr); 
    1612 +            s_log(LOG_ERR, "check_SSL_pending=%d", check_SSL_pending); 
    1613 +            longjmp(c->err, 1); 
    1614 +        } 
    1615 + 
    1616 +    } while(sock_wr || ssl_wr || 
    1617 +            SSL_shutdown_wants_read || SSL_shutdown_wants_write); 
    1618 +} 
    1619 + 
    1620 +static void parse_socket_error(CLI *c, const char *text) { 
    1621 +    switch(get_last_socket_error()) { 
    1622 +    case EINTR: 
    1623 +        s_log(LOG_DEBUG, "%s interrupted by a signal: retrying", text); 
    1624 +        return; 
    1625 +    case EWOULDBLOCK: 
    1626 +        s_log(LOG_NOTICE, "%s would block: retrying", text); 
    1627 +        sleep(1); /* Microsoft bug KB177346 */ 
    1628 +        return; 
    1629 +#if EAGAIN!=EWOULDBLOCK 
    1630 +    case EAGAIN: 
    1631 +        s_log(LOG_DEBUG, "%s temporary lack of resources: retrying", text); 
    1632 +        return; 
    1633 +#endif 
    1634 +    default: 
    1635 +        sockerror(text); 
    1636 +        longjmp(c->err, 1); 
    1637 +    } 
    1638 +} 
    1639 + 
    1640 +static void print_cipher(CLI *c) { /* print negotiated cipher */ 
    1641 +#if SSLEAY_VERSION_NUMBER <= 0x0800 
    1642 +    s_log(LOG_INFO, "%s opened with SSLv%d, cipher %s", 
    1643 +        c->opt->servname, ssl->session->ssl_version, SSL_get_cipher(c->ssl)); 
    1644 +#else 
    1645 +    SSL_CIPHER *cipher; 
    1646 +    char buf[STRLEN], *i, *j; 
    1647 + 
    1648 +    cipher=(SSL_CIPHER *)SSL_get_current_cipher(c->ssl); 
    1649 +    SSL_CIPHER_description(cipher, buf, STRLEN); 
    1650 +    i=j=buf; 
    1651 +    do { 
    1652 +        switch(*i) { 
    1653 +        case ' ': 
    1654 +            *j++=' '; 
    1655 +            while(i[1]==' ') 
    1656 +                ++i; 
    1657 +            break; 
    1658 +        case '\n': 
    1659 +            break; 
    1660 +        default: 
    1661 +            *j++=*i; 
    1662 +        } 
    1663 +    } while(*i++); 
    1664 +    s_log(LOG_INFO, "Negotiated ciphers: %s", buf); 
    1665 +#endif 
    1666 +} 
    1667 + 
    1668 +static void auth_user(CLI *c) { 
    1669 +#ifndef _WIN32_WCE 
    1670 +    struct servent *s_ent;    /* structure for getservbyname */ 
    1671 +#endif 
    1672 +    SOCKADDR_UNION ident;     /* IDENT socket name */ 
    1673 +    char name[STRLEN]; 
    1674 + 
    1675 +    if(!c->opt->username) 
    1676 +        return; /* -u option not specified */ 
    1677 +    if((c->fd= 
    1678 +            socket(c->peer_addr.addr[0].sa.sa_family, SOCK_STREAM, 0))<0) { 
    1679 +        sockerror("socket (auth_user)"); 
    1680 +        longjmp(c->err, 1); 
    1681 +    } 
    1682 +    if(alloc_fd(c->fd)) 
    1683 +        longjmp(c->err, 1); 
    1684 +    memcpy(&ident, &c->peer_addr.addr[0], sizeof ident); 
    1685 +#ifndef _WIN32_WCE 
    1686 +    s_ent=getservbyname("auth", "tcp"); 
    1687 +    if(s_ent) { 
    1688 +        ident.in.sin_port=s_ent->s_port; 
    1689 +    } else 
    1690 +#endif 
    1691 +    { 
    1692 +        s_log(LOG_WARNING, "Unknown service 'auth': using default 113"); 
    1693 +        ident.in.sin_port=htons(113); 
    1694 +    } 
    1695 +    if(connect_blocking(c, &ident, addr_len(ident))) 
    1696 +        longjmp(c->err, 1); 
    1697 +    s_log(LOG_DEBUG, "IDENT server connected"); 
    1698 +    fdprintf(c, c->fd, "%u , %u", 
    1699 +        ntohs(c->peer_addr.addr[0].in.sin_port), 
    1700 +        ntohs(c->opt->local_addr.addr[0].in.sin_port)); 
    1701 +    if(fdscanf(c, c->fd, "%*[^:]: USERID :%*[^:]:%s", name)!=1) { 
    1702 +        s_log(LOG_ERR, "Incorrect data from IDENT server"); 
    1703 +        longjmp(c->err, 1); 
    1704 +    } 
    1705 +    closesocket(c->fd); 
    1706 +    c->fd=-1; /* avoid double close on cleanup */ 
    1707 +    if(strcmp(name, c->opt->username)) { 
    1708 +        safestring(name); 
    1709 +        s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user %s)", 
    1710 +            c->accepted_address, name); 
    1711 +        longjmp(c->err, 1); 
    1712 +    } 
    1713 +    s_log(LOG_INFO, "IDENT authentication passed"); 
    1714 +} 
    1715 + 
    1716 +static int connect_local(CLI *c) { /* spawn local process */ 
    1717 +#if defined (USE_WIN32) || defined (__vms) 
    1718 +    s_log(LOG_ERR, "LOCAL MODE NOT SUPPORTED ON WIN32 and OpenVMS PLATFORM"); 
    1719 +    longjmp(c->err, 1); 
    1720 +    return -1; /* some C compilers require a return value */ 
    1721 +#else /* USE_WIN32, __vms */ 
    1722 +    char env[3][STRLEN], name[STRLEN], *portname; 
    1723 +    int fd[2], pid; 
    1724 +    X509 *peer; 
    1725 +#ifdef HAVE_PTHREAD_SIGMASK 
    1726 +    sigset_t newmask; 
    1727 +#endif 
    1728 + 
    1729 +    if (c->opt->option.pty) { 
    1730 +        char tty[STRLEN]; 
    1731 + 
    1732 +        if(pty_allocate(fd, fd+1, tty, STRLEN)) 
    1733 +            longjmp(c->err, 1); 
    1734 +        s_log(LOG_DEBUG, "%s allocated", tty); 
    1735 +    } else 
    1736 +        make_sockets(c, fd); 
    1737 +    pid=fork(); 
    1738 +    c->pid=(unsigned long)pid; 
    1739 +    switch(pid) { 
    1740 +    case -1:    /* error */ 
    1741 +        closesocket(fd[0]); 
    1742 +        closesocket(fd[1]); 
    1743 +        ioerror("fork"); 
    1744 +        longjmp(c->err, 1); 
    1745 +    case  0:    /* child */ 
    1746 +        closesocket(fd[0]); 
    1747 +        dup2(fd[1], 0); 
    1748 +        dup2(fd[1], 1); 
    1749 +        if(!options.option.foreground) 
    1750 +            dup2(fd[1], 2); 
    1751 +        closesocket(fd[1]); 
    1752 +        safecopy(env[0], "REMOTE_HOST="); 
    1753 +        safeconcat(env[0], c->accepted_address); 
    1754 +        portname=strrchr(env[0], ':'); 
    1755 +        if(portname) /* strip the port name */ 
    1756 +            *portname='\0'; 
    1757 +        putenv(env[0]); 
    1758 +        if(c->opt->option.transparent) { 
    1759 +            putenv("LD_PRELOAD=" LIBDIR "/libstunnel.so"); 
    1760 +            /* For Tru64 _RLD_LIST is used instead */ 
    1761 +            putenv("_RLD_LIST=" LIBDIR "/libstunnel.so:DEFAULT"); 
    1762 +        } 
    1763 +        if(c->ssl) { 
    1764 +            peer=SSL_get_peer_certificate(c->ssl); 
    1765 +            if(peer) { 
    1766 +                safecopy(env[1], "SSL_CLIENT_DN="); 
    1767 +                X509_NAME_oneline(X509_get_subject_name(peer), name, STRLEN); 
    1768 +                safestring(name); 
    1769 +                safeconcat(env[1], name); 
    1770 +                putenv(env[1]); 
    1771 +                safecopy(env[2], "SSL_CLIENT_I_DN="); 
    1772 +                X509_NAME_oneline(X509_get_issuer_name(peer), name, STRLEN); 
    1773 +                safestring(name); 
    1774 +                safeconcat(env[2], name); 
    1775 +                putenv(env[2]); 
    1776 +                X509_free(peer); 
    1777 +            } 
    1778 +        } 
    1779 +#ifdef HAVE_PTHREAD_SIGMASK 
    1780 +        sigemptyset(&newmask); 
    1781 +        sigprocmask(SIG_SETMASK, &newmask, NULL); 
    1782 +#endif 
    1783 +        execvp(c->opt->execname, c->opt->execargs); 
    1784 +        ioerror(c->opt->execname); /* execv failed */ 
    1785 +        _exit(1); 
    1786 +    default: 
    1787 +        break; 
    1788 +    } 
    1789 +    /* parent */ 
    1790 +    s_log(LOG_INFO, "Local mode child started (PID=%lu)", c->pid); 
    1791 +    closesocket(fd[1]); 
    1792 +#ifdef FD_CLOEXEC 
    1793 +    fcntl(fd[0], F_SETFD, FD_CLOEXEC); 
    1794 +#endif 
    1795 +    return fd[0]; 
    1796 +#endif /* USE_WIN32,__vms */ 
    1797 +} 
    1798 + 
    1799 +#ifndef USE_WIN32 
    1800 + 
    1801 +static void make_sockets(CLI *c, int fd[2]) { /* make a pair of connected sockets */ 
    1802 +#ifdef INET_SOCKET_PAIR 
    1803 +    SOCKADDR_UNION addr; 
    1804 +    socklen_t addrlen; 
    1805 +    int s; /* temporary socket awaiting for connection */ 
    1806 + 
    1807 +    if((s=socket(AF_INET, SOCK_STREAM, 0))<0) { 
    1808 +        sockerror("socket#1"); 
    1809 +        longjmp(c->err, 1); 
    1810 +    } 
    1811 +    if((fd[1]=socket(AF_INET, SOCK_STREAM, 0))<0) { 
    1812 +        sockerror("socket#2"); 
    1813 +        longjmp(c->err, 1); 
    1814 +    } 
    1815 +    addrlen=sizeof addr; 
    1816 +    memset(&addr, 0, addrlen); 
    1817 +    addr.in.sin_family=AF_INET; 
    1818 +    addr.in.sin_addr.s_addr=htonl(INADDR_LOOPBACK); 
    1819 +    addr.in.sin_port=htons(0); /* dynamic port allocation */ 
    1820 +    if(bind(s, &addr.sa, addrlen)) 
    1821 +        log_error(LOG_DEBUG, get_last_socket_error(), "bind#1"); 
    1822 +    if(bind(fd[1], &addr.sa, addrlen)) 
    1823 +        log_error(LOG_DEBUG, get_last_socket_error(), "bind#2"); 
    1824 +    if(listen(s, 5)) { 
    1825 +        sockerror("listen"); 
    1826 +        longjmp(c->err, 1); 
    1827 +    } 
    1828 +    if(getsockname(s, &addr.sa, &addrlen)) { 
    1829 +        sockerror("getsockname"); 
    1830 +        longjmp(c->err, 1); 
    1831 +    } 
    1832 +    if(connect(fd[1], &addr.sa, addrlen)) { 
    1833 +        sockerror("connect"); 
    1834 +        longjmp(c->err, 1); 
    1835 +    } 
    1836 +    if((fd[0]=accept(s, &addr.sa, &addrlen))<0) { 
    1837 +        sockerror("accept"); 
    1838 +        longjmp(c->err, 1); 
    1839 +    } 
    1840 +    closesocket(s); /* don't care about the result */ 
    1841 +#else 
    1842 +    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { 
    1843 +        sockerror("socketpair"); 
    1844 +        longjmp(c->err, 1); 
    1845 +    } 
    1846 +#endif 
    1847 +} 
    1848 +#endif 
    1849 + 
    1850 +static int connect_remote(CLI *c) { /* connect to remote host */ 
    1851 +    SOCKADDR_UNION addr; 
    1852 +    SOCKADDR_LIST resolved_list, *address_list; 
    1853 +    int fd, ind_try, ind_cur; 
    1854 + 
    1855 +    /* setup address_list */ 
    1856 +    if(c->opt->option.delayed_lookup) { 
    1857 +        resolved_list.num=0; 
    1858 +        if(!name2addrlist(&resolved_list, 
    1859 +                c->opt->remote_address, DEFAULT_LOOPBACK)) { 
    1860 +            s_log(LOG_ERR, "No host resolved"); 
    1861 +            longjmp(c->err, 1); 
    1862 +        } 
    1863 +        address_list=&resolved_list; 
    1864 +    } else /* use pre-resolved addresses */ 
    1865 +        address_list=&c->opt->remote_addr; 
    1866 + 
    1867 +    /* try to connect each host from the list */ 
    1868 +    for(ind_try=0; ind_try<address_list->num; ind_try++) { 
    1869 +        if(c->opt->failover==FAILOVER_RR) { 
    1870 +            ind_cur=address_list->cur; 
    1871 +            /* the race condition here can be safely ignored */ 
    1872 +            address_list->cur=(ind_cur+1)%address_list->num; 
    1873 +        } else { /* FAILOVER_PRIO */ 
    1874 +            ind_cur=ind_try; /* ignore address_list->cur */ 
    1875 +        } 
    1876 +        memcpy(&addr, address_list->addr+ind_cur, sizeof addr); 
    1877 + 
    1878 +        if((c->fd=socket(addr.sa.sa_family, SOCK_STREAM, 0))<0) { 
    1879 +            sockerror("remote socket"); 
    1880 +            longjmp(c->err, 1); 
    1881 +        } 
    1882 +        if(alloc_fd(c->fd)) 
    1883 +            longjmp(c->err, 1); 
    1884 + 
    1885 +        if(c->bind_addr.num) /* explicit local bind or transparent proxy */ 
    1886 +            local_bind(c); 
    1887 + 
    1888 +        if(connect_blocking(c, &addr, addr_len(addr))) { 
    1889 +            closesocket(c->fd); 
    1890 +            c->fd=-1; 
    1891 +            continue; /* next IP */ 
    1892 +        } 
    1893 +        print_bound_address(c); 
    1894 +        fd=c->fd; 
    1895 +        c->fd=-1; 
    1896 +        return fd; /* success! */ 
    1897 +    } 
    1898 +    longjmp(c->err, 1); 
    1899 +    return -1; /* some C compilers require a return value */ 
    1900 +} 
    1901 + 
    1902 +static void local_bind(CLI *c) { 
    1903 +    SOCKADDR_UNION addr; 
    1904 + 
    1905 +#ifdef IP_TRANSPARENT 
    1906 +    int on=1; 
    1907 +    if(setsockopt(c->fd, SOL_IP, IP_TRANSPARENT, &on, sizeof on)) 
    1908 +        sockerror("setsockopt IP_TRANSPARENT"); 
    1909 +    /* ignore the error to retain Linux 2.2 compatibility */ 
    1910 +    /* the error will be handled by bind(), anyway */ 
    1911 +#endif /* IP_TRANSPARENT */ 
    1912 + 
    1913 +    memcpy(&addr, &c->bind_addr.addr[0], sizeof addr); 
    1914 +    if(ntohs(addr.in.sin_port)>=1024) { /* security check */ 
    1915 +        if(!bind(c->fd, &addr.sa, addr_len(addr))) { 
    1916 +            s_log(LOG_INFO, "local_bind succeeded on the original port"); 
    1917 +            return; /* success */ 
    1918 +        } 
    1919 +        if(get_last_socket_error()!=EADDRINUSE 
    1920 +#ifndef USE_WIN32 
    1921 +                || !c->opt->option.transparent 
    1922 +#endif /* USE_WIN32 */ 
    1923 +                ) { 
    1924 +            sockerror("local_bind (original port)"); 
    1925 +            longjmp(c->err, 1); 
    1926 +        } 
    1927 +    } 
    1928 + 
    1929 +    addr.in.sin_port=htons(0); /* retry with ephemeral port */ 
    1930 +    if(!bind(c->fd, &addr.sa, addr_len(addr))) { 
    1931 +        s_log(LOG_INFO, "local_bind succeeded on an ephemeral port"); 
    1932 +        return; /* success */ 
    1933 +    } 
    1934 +    sockerror("local_bind (ephemeral port)"); 
    1935 +    longjmp(c->err, 1); 
    1936 +} 
    1937 + 
    1938 +static void print_bound_address(CLI *c) { 
    1939 +    char txt[IPLEN]; 
    1940 +    SOCKADDR_UNION addr; 
    1941 +    socklen_t addrlen=sizeof addr; 
    1942 + 
    1943 +    memset(&addr, 0, addrlen); 
    1944 +    if(getsockname(c->fd, (struct sockaddr *)&addr, &addrlen)) { 
    1945 +        sockerror("getsockname"); 
    1946 +    } else { 
    1947 +        s_ntop(txt, &addr); 
    1948 +        s_log(LOG_NOTICE,"%s connected remote server from %s", 
    1949 +            c->opt->servname, txt); 
    1950 +    } 
    1951 +} 
    1952 + 
    1953 +static void reset(int fd, char *txt) { 
    1954 +    /* Set lingering on a socket if needed*/ 
    1955 +    struct linger l; 
    1956 + 
    1957 +    l.l_onoff=1; 
    1958 +    l.l_linger=0; 
    1959 +    if(setsockopt(fd, SOL_SOCKET, SO_LINGER, (void *)&l, sizeof l)) 
    1960 +        log_error(LOG_DEBUG, get_last_socket_error(), txt); 
    1961 +} 
    1962 + 
    1963 +/* End of client.c */ 
    1964187--- a/src/common.h 
    1965188+++ b/src/common.h 
     
    1969192  
    1970193+/* maximum space reserved for header insertion in BUFFSIZE */ 
    1971 +#define BUFF_RESERVED  1024 
    1972 + 
    1973  /* Length of strings (including the terminating '\0' character) */ 
    1974  /* It can't be lower than 256 bytes or NTLM authentication will break */ 
     194+#define BUFF_RESERVED  1024 
     195+ 
     196 /* length of strings (including the terminating '\0' character) */ 
     197 /* it can't be lower than 256 bytes or NTLM authentication will break */ 
    1975198 #define STRLEN 256 
    1976 --- /dev/null 
    1977 +++ b/src/common.h.orig 
    1978 @@ -0,0 +1,429 @@ 
    1979 +/* 
    1980 + *   stunnel       Universal SSL tunnel 
    1981 + *   Copyright (C) 1998-2009 Michal Trojnara <Michal.Trojnara@mirt.net> 
    1982 + * 
    1983 + *   This program is free software; you can redistribute it and/or modify it 
    1984 + *   under the terms of the GNU General Public License as published by the 
    1985 + *   Free Software Foundation; either version 2 of the License, or (at your 
    1986 + *   option) any later version. 
    1987 + *  
    1988 + *   This program is distributed in the hope that it will be useful, 
    1989 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
    1990 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    1991 + *   See the GNU General Public License for more details. 
    1992 + *  
    1993 + *   You should have received a copy of the GNU General Public License along 
    1994 + *   with this program; if not, see <http://www.gnu.org/licenses>. 
    1995 + *  
    1996 + *   Linking stunnel statically or dynamically with other modules is making 
    1997 + *   a combined work based on stunnel. Thus, the terms and conditions of 
    1998 + *   the GNU General Public License cover the whole combination. 
    1999 + *  
    2000 + *   In addition, as a special exception, the copyright holder of stunnel 
    2001 + *   gives you permission to combine stunnel with free software programs or 
    2002 + *   libraries that are released under the GNU LGPL and with code included 
    2003 + *   in the standard release of OpenSSL under the OpenSSL License (or 
    2004 + *   modified versions of such code, with unchanged license). You may copy 
    2005 + *   and distribute such a system following the terms of the GNU GPL for 
    2006 + *   stunnel and the licenses of the other code concerned. 
    2007 + *  
    2008 + *   Note that people who make modified versions of stunnel are not obligated 
    2009 + *   to grant this special exception for their modified versions; it is their 
    2010 + *   choice whether to do so. The GNU General Public License gives permission 
    2011 + *   to release a modified version without this exception; this exception 
    2012 + *   also makes it possible to release a modified version which carries 
    2013 + *   forward this exception. 
    2014 + */ 
    2015 + 
    2016 +#ifndef COMMON_H 
    2017 +#define COMMON_H 
    2018 + 
    2019 +#ifndef VERSION 
    2020 +#define VERSION "unknown" 
    2021 +#endif 
    2022 + 
    2023 +/**************************************** Common constants */ 
    2024 + 
    2025 +#define LIBWRAP_CLIENTS 5 
    2026 + 
    2027 +/* CPU stack size */ 
    2028 +#define DEFAULT_STACK_SIZE 65536 
    2029 +/* #define DEBUG_STACK_SIZE */ 
    2030 + 
    2031 +/* I/O buffer size */ 
    2032 +#define BUFFSIZE 16384 
    2033 + 
    2034 +/* Length of strings (including the terminating '\0' character) */ 
    2035 +/* It can't be lower than 256 bytes or NTLM authentication will break */ 
    2036 +#define STRLEN 256 
    2037 + 
    2038 +/* IP address and TCP port textual representation length */ 
    2039 +#define IPLEN 128 
    2040 + 
    2041 +/* How many bytes of random input to read from files for PRNG */ 
    2042 +/* OpenSSL likes at least 128 bits, so 64 bytes seems plenty. */ 
    2043 +#define RANDOM_BYTES 64 
    2044 + 
    2045 +/* For FormatGuard */ 
    2046 +/* #define __NO_FORMATGUARD_ */ 
    2047 + 
    2048 +/**************************************** Platform */ 
    2049 + 
    2050 +#ifdef USE_WIN32 
    2051 +#define USE_IPv6 
    2052 +/* #define USE_FIPS */ 
    2053 +#endif 
    2054 + 
    2055 +#ifdef _WIN32_WCE 
    2056 +#define USE_WIN32 
    2057 +typedef int socklen_t; 
    2058 +#define EINTR WSAEINTR 
    2059 +#define EMFILE WSAEMFILE 
    2060 +#endif 
    2061 + 
    2062 +#ifdef USE_WIN32 
    2063 +#define HAVE_OPENSSL 
    2064 +#define HAVE_OSSL_ENGINE_H 
    2065 +/* prevent including wincrypt.h, as it defines it's own OCSP_RESPONSE */ 
    2066 +#define __WINCRYPT_H__ 
    2067 +#endif 
    2068 + 
    2069 +/**************************************** Generic headers */ 
    2070 + 
    2071 +#ifdef __vms 
    2072 +#include <starlet.h> 
    2073 +#endif /* __vms */ 
    2074 + 
    2075 +/* For nsr-tandem-nsk architecture */ 
    2076 +#ifdef __TANDEM 
    2077 +#include <floss.h> 
    2078 +#endif 
    2079 + 
    2080 +/* threads model */ 
    2081 +#ifdef USE_UCONTEXT 
    2082 +#define __MAKECONTEXT_V2_SOURCE 
    2083 +#include <ucontext.h> 
    2084 +#endif 
    2085 + 
    2086 +#ifdef USE_PTHREAD 
    2087 +#define THREADS 
    2088 +#define _REENTRANT 
    2089 +#define _THREAD_SAFE 
    2090 +#include <pthread.h> 
    2091 +#endif 
    2092 + 
    2093 +/* TCP wrapper */ 
    2094 +#if HAVE_TCPD_H && HAVE_LIBWRAP 
    2095 +#define USE_LIBWRAP 
    2096 +#endif 
    2097 + 
    2098 +/* Must be included before sys/stat.h for Ultrix */ 
    2099 +#include <sys/types.h>   /* u_short, u_long */ 
    2100 +/* General headers */ 
    2101 +#include <stdio.h> 
    2102 +/* Must be included before sys/stat.h for Ultrix */ 
    2103 +#ifndef _WIN32_WCE 
    2104 +#include <errno.h> 
    2105 +#endif 
    2106 +#include <stdlib.h> 
    2107 +#include <stdarg.h>      /* va_ */ 
    2108 +#include <string.h> 
    2109 +#include <ctype.h>       /* isalnum */ 
    2110 +#include <time.h> 
    2111 +#include <sys/stat.h>    /* stat */ 
    2112 +#include <setjmp.h> 
    2113 + 
    2114 +/**************************************** WIN32 headers */ 
    2115 + 
    2116 +#ifdef USE_WIN32 
    2117 + 
    2118 +#ifndef HOST 
    2119 +#ifdef __MINGW32__ 
    2120 +#define HOST "x86-pc-mingw32-gnu" 
    2121 +#else 
    2122 +#ifdef _MSC_VER 
    2123 +#define _QUOTEME(x) #x 
    2124 +#define QUOTEME(x) _QUOTEME(x) 
    2125 +#define HOST "x86-pc-msvc-" ## QUOTEME(_MSC_VER) 
    2126 +#else 
    2127 +#define HOST "x86-pc-unknown" 
    2128 +#endif 
    2129 +#endif 
    2130 +#endif 
    2131 + 
    2132 +typedef unsigned char u8; 
    2133 +typedef unsigned short u16; 
    2134 +typedef unsigned long u32; 
    2135 + 
    2136 +#define HAVE_SNPRINTF 
    2137 +#define snprintf _snprintf 
    2138 +#define HAVE_VSNPRINTF 
    2139 +#define vsnprintf _vsnprintf 
    2140 +#define strcasecmp _stricmp 
    2141 +#define strncasecmp _strnicmp 
    2142 +#define sleep(c) Sleep(1000*(c)) 
    2143 + 
    2144 +#define get_last_socket_error() WSAGetLastError() 
    2145 +#define get_last_error()        GetLastError() 
    2146 +#define readsocket(s,b,n)       recv((s),(b),(n),0) 
    2147 +#define writesocket(s,b,n)      send((s),(b),(n),0) 
    2148 + 
    2149 +/* #define FD_SETSIZE 4096 */ 
    2150 +/* #define Win32_Winsock */ 
    2151 +#define __USE_W32_SOCKETS 
    2152 + 
    2153 +/* Winsock2 header for IPv6 definitions */ 
    2154 +#ifdef _WIN32_WCE 
    2155 +#include <winsock.h> 
    2156 +#else 
    2157 +#include <winsock2.h> 
    2158 +#include <ws2tcpip.h> 
    2159 +#endif 
    2160 +#include <windows.h> 
    2161 + 
    2162 +#define ECONNRESET WSAECONNRESET 
    2163 +#define ENOTSOCK WSAENOTSOCK 
    2164 +#define ENOPROTOOPT WSAENOPROTOOPT 
    2165 +#define EINPROGRESS WSAEINPROGRESS 
    2166 +#define EWOULDBLOCK WSAEWOULDBLOCK 
    2167 +#define EISCONN WSAEISCONN 
    2168 +#define EADDRINUSE WSAEADDRINUSE 
    2169 + 
    2170 +#ifdef EINVAL 
    2171 +#undef EINVAL 
    2172 +#endif 
    2173 +#define EINVAL WSAEINVAL 
    2174 + 
    2175 +#include <process.h>     /* _beginthread */ 
    2176 +#include <tchar.h> 
    2177 + 
    2178 +#define NO_IDEA 
    2179 +#define OPENSSL_NO_IDEA 
    2180 + 
    2181 +/**************************************** non-WIN32 headers */ 
    2182 + 
    2183 +#else /* USE_WIN32 */ 
    2184 + 
    2185 +#if SIZEOF_UNSIGNED_CHAR == 1 
    2186 +typedef unsigned char u8; 
    2187 +#endif 
    2188 + 
    2189 +#if SIZEOF_UNSIGNED_SHORT == 2 
    2190 +typedef unsigned short u16; 
    2191 +#else 
    2192 +typedef unsigned int u16; 
    2193 +#endif 
    2194 + 
    2195 +#if SIZEOF_UNSIGNED_INT == 4 
    2196 +typedef unsigned int u32; 
    2197 +#else 
    2198 +typedef unsigned long u32; 
    2199 +#endif 
    2200 + 
    2201 +#ifdef __INNOTEK_LIBC__ 
    2202 +# define get_last_socket_error() sock_errno() 
    2203 +# define get_last_error()        errno 
    2204 +# define readsocket(s,b,n)       recv((s),(b),(n),0) 
    2205 +# define writesocket(s,b,n)      send((s),(b),(n),0) 
    2206 +# define closesocket(s)          close(s) 
    2207 +# define ioctlsocket(a,b,c)      so_ioctl((a),(b),(c)) 
    2208 +#else 
    2209 +#define get_last_socket_error() errno 
    2210 +#define get_last_error()        errno 
    2211 +#define readsocket(s,b,n)       read((s),(b),(n)) 
    2212 +#define writesocket(s,b,n)      write((s),(b),(n)) 
    2213 +#define closesocket(s)          close(s) 
    2214 +#define ioctlsocket(a,b,c)      ioctl((a),(b),(c)) 
    2215 +#endif 
    2216 +    /* OpenVMS compatibility */ 
    2217 +#ifdef __vms 
    2218 +#define libdir "__NA__" 
    2219 +#define PIDFILE "SYS$LOGIN:STUNNEL.PID" 
    2220 +#ifdef __alpha 
    2221 +#define HOST "alpha-openvms" 
    2222 +#else 
    2223 +#define HOST "vax-openvms" 
    2224 +#endif 
    2225 +#include <inet.h> 
    2226 +#include <unistd.h> 
    2227 +#else   /* __vms */ 
    2228 +#include <syslog.h> 
    2229 +#endif  /* __vms */ 
    2230 + 
    2231 +    /* Unix-specific headers */ 
    2232 +#include <signal.h>      /* signal */ 
    2233 +#include <sys/wait.h>    /* wait */ 
    2234 +#ifdef HAVE_SYS_RESOURCE_H 
    2235 +#include <sys/resource.h> /* getrlimit */ 
    2236 +#endif 
    2237 +#ifdef HAVE_UNISTD_H 
    2238 +#include <unistd.h>      /* getpid, fork, execvp, exit */ 
    2239 +#endif 
    2240 +#ifdef HAVE_STROPTS_H 
    2241 +#include <stropts.h> 
    2242 +#endif 
    2243 +#ifdef HAVE_SYS_SELECT_H 
    2244 +#include <sys/select.h>  /* for aix */ 
    2245 +#endif 
    2246 + 
    2247 +#ifndef BROKEN_POLL 
    2248 +#ifdef HAVE_POLL_H 
    2249 +#include <poll.h> 
    2250 +#define USE_POLL 
    2251 +#else /* HAVE_POLL_H */ 
    2252 +#ifdef HAVE_SYS_POLL_H 
    2253 +#include <sys/poll.h> 
    2254 +#define USE_POLL 
    2255 +#endif /* HAVE_SYS_POLL_H */ 
    2256 +#endif /* HAVE_POLL_H */ 
    2257 +#endif /* BROKEN_POLL */ 
    2258 + 
    2259 +#ifdef HAVE_SYS_FILIO_H 
    2260 +#include <sys/filio.h>   /* for FIONBIO */ 
    2261 +#endif 
    2262 +#include <pwd.h> 
    2263 +#ifdef HAVE_GRP_H 
    2264 +#include <grp.h> 
    2265 +#endif 
    2266 +#ifdef __BEOS__ 
    2267 +#include <posix/grp.h> 
    2268 +#endif 
    2269 +#include <fcntl.h> 
    2270 + 
    2271 +#include <netinet/in.h>  /* struct sockaddr_in */ 
    2272 +#include <sys/socket.h>  /* getpeername */ 
    2273 +#include <arpa/inet.h>   /* inet_ntoa */ 
    2274 +#include <sys/time.h>    /* select */ 
    2275 +#include <sys/ioctl.h>   /* ioctl */ 
    2276 +#include <netinet/tcp.h> 
    2277 +#include <netdb.h> 
    2278 +#ifndef INADDR_ANY 
    2279 +#define INADDR_ANY       (u32)0x00000000 
    2280 +#endif 
    2281 +#ifndef INADDR_LOOPBACK 
    2282 +#define INADDR_LOOPBACK  (u32)0x7F000001 
    2283 +#endif 
    2284 + 
    2285 +#if defined(HAVE_WAITPID) 
    2286 +/* For SYSV systems */ 
    2287 +#define wait_for_pid(a, b, c) waitpid((a), (b), (c)) 
    2288 +#define HAVE_WAIT_FOR_PID 1 
    2289 +#elif defined(HAVE_WAIT4) 
    2290 +/* For BSD systems */ 
    2291 +#define wait_for_pid(a, b, c) wait4((a), (b), (c), NULL) 
    2292 +#define HAVE_WAIT_FOR_PID 1 
    2293 +#endif 
    2294 + 
    2295 +/* SunOS 4 */ 
    2296 +#if defined(sun) && !defined(__svr4__) && !defined(__SVR4) 
    2297 +#define atexit(a) on_exit((a), NULL) 
    2298 +extern int sys_nerr; 
    2299 +extern char *sys_errlist[]; 
    2300 +#define strerror(num) ((num)==0 ? "No error" : \ 
    2301 +    ((num)>=sys_nerr ? "Unknown error" : sys_errlist[num])) 
    2302 +#endif /* SunOS 4 */ 
    2303 + 
    2304 +/* AIX does not have SOL_TCP defined */ 
    2305 +#ifndef SOL_TCP 
    2306 +#define SOL_TCP SOL_SOCKET 
    2307 +#endif /* SOL_TCP */ 
    2308 + 
    2309 +/* Linux */ 
    2310 +#ifdef __linux__ 
    2311 +#ifndef IP_TRANSPARENT 
    2312 +/* old kernel headers without IP_TRANSPARENT definition */ 
    2313 +#define IP_TRANSPARENT 19 
    2314 +#endif /* IP_TRANSPARENT */ 
    2315 +#endif /* __linux__ */ 
    2316 + 
    2317 +#endif /* USE_WIN32 */ 
    2318 + 
    2319 +/**************************************** OpenSSL headers */ 
    2320 + 
    2321 +#ifdef HAVE_OPENSSL 
    2322 + 
    2323 +#define OPENSSL_THREAD_DEFINES 
    2324 +#include <openssl/opensslconf.h> 
    2325 +#if !defined(OPENSSL_THREADS) && defined(USE_PTHREAD) 
    2326 +#error OpenSSL library compiled without thread support 
    2327 +#endif /* !OPENSSL_THREADS && USE_PTHREAD */ 
    2328 + 
    2329 +#include <openssl/lhash.h> 
    2330 +#include <openssl/ssl.h> 
    2331 +#include <openssl/err.h> 
    2332 +#include <openssl/crypto.h> /* for CRYPTO_* and SSLeay_version */ 
    2333 +#include <openssl/rand.h> 
    2334 +#include <openssl/md4.h> 
    2335 +#include <openssl/des.h> 
    2336 + 
    2337 +#ifdef HAVE_OSSL_ENGINE_H 
    2338 +#include <openssl/engine.h> 
    2339 +#endif /* HAVE_OSSL_ENGINE_H */ 
    2340 + 
    2341 +#if SSLEAY_VERSION_NUMBER >= 0x00907000L 
    2342 +#include <openssl/ocsp.h> 
    2343 +#endif /* OpenSSL-0.9.7 */ 
    2344 + 
    2345 +#ifdef USE_FIPS 
    2346 +#include <openssl/fips.h> 
    2347 +#include <openssl/fips_rand.h> 
    2348 +#endif /* USE_FIPS */ 
    2349 + 
    2350 +#else /* HAVE_OPENSSL */ 
    2351 + 
    2352 +#include <lhash.h> 
    2353 +#include <ssl.h> 
    2354 +#include <err.h> 
    2355 +#include <crypto.h> 
    2356 +#include <md4.h> 
    2357 +#include <des.h> 
    2358 + 
    2359 +#endif /* HAVE_OPENSSL */ 
    2360 + 
    2361 +/**************************************** Other defines */ 
    2362 + 
    2363 +/* Safe copy for strings declarated as char[STRLEN] */ 
    2364 +#define safecopy(dst, src) \ 
    2365 +    (dst[STRLEN-1]='\0', strncpy((dst), (src), STRLEN-1)) 
    2366 +#define safeconcat(dst, src) \ 
    2367 +    (dst[STRLEN-1]='\0', strncat((dst), (src), STRLEN-strlen(dst)-1)) 
    2368 +/* change all non-printable characters to '.' */ 
    2369 +#define safestring(s) \ 
    2370 +    do {unsigned char *p; for(p=(unsigned char *)(s); *p; p++) \ 
    2371 +        if(!isprint((int)*p)) *p='.';} while(0) 
    2372 +/* change all unsafe characters to '.' */ 
    2373 +#define safename(s) \ 
    2374 +    do {unsigned char *p; for(p=(s); *p; p++) \ 
    2375 +        if(!isalnum((int)*p)) *p='.';} while(0) 
    2376 + 
    2377 +/* Some definitions for IPv6 support */ 
    2378 +#if defined(USE_IPv6) 
    2379 +#define addr_len(x) ((x).sa.sa_family==AF_INET ? \ 
    2380 +    sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) 
    2381 +#else 
    2382 +#define addr_len(x) (sizeof(struct sockaddr_in)) 
    2383 +#endif 
    2384 + 
    2385 +/* Always use IPv4 defaults! */ 
    2386 +#define DEFAULT_LOOPBACK "127.0.0.1" 
    2387 +#define DEFAULT_ANY "0.0.0.0" 
    2388 +#if 0 
    2389 +#define DEFAULT_LOOPBACK "::1" 
    2390 +#define DEFAULT_ANY "::" 
    2391 +#endif 
    2392 + 
    2393 +#if defined (USE_WIN32) || defined (__vms) 
    2394 +#define LOG_EMERG       0 
    2395 +#define LOG_ALERT       1 
    2396 +#define LOG_CRIT        2 
    2397 +#define LOG_ERR         3 
    2398 +#define LOG_WARNING     4 
    2399 +#define LOG_NOTICE      5 
    2400 +#define LOG_INFO        6 
    2401 +#define LOG_DEBUG       7 
    2402 +#endif /* defined (USE_WIN32) || defined (__vms) */ 
    2403 +#define LOG_RAW         -1 
    2404 + 
    2405 +#endif /* defined COMMON_H */ 
    2406 + 
    2407 +/* End of common.h */ 
    2408199--- a/src/options.c 
    2409200+++ b/src/options.c 
    2410 @@ -781,6 +781,28 @@ static char *service_options(CMD cmd, LO 
     201@@ -792,6 +792,28 @@ static char *parse_service_option(CMD cm 
    2411202     } 
    2412203 #endif 
     
    2435226+ 
    2436227     /* exec */ 
    2437  #ifndef USE_WIN32 
    2438228     switch(cmd) { 
    2439 --- /dev/null 
    2440 +++ b/src/options.c.orig 
    2441 @@ -0,0 +1,1994 @@ 
    2442 +/* 
    2443 + *   stunnel       Universal SSL tunnel 
    2444 + *   Copyright (C) 1998-2009 Michal Trojnara <Michal.Trojnara@mirt.net> 
    2445 + * 
    2446 + *   This program is free software; you can redistribute it and/or modify it 
    2447 + *   under the terms of the GNU General Public License as published by the 
    2448 + *   Free Software Foundation; either version 2 of the License, or (at your 
    2449 + *   option) any later version. 
    2450 + *  
    2451 + *   This program is distributed in the hope that it will be useful, 
    2452 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
    2453 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    2454 + *   See the GNU General Public License for more details. 
    2455 + *  
    2456 + *   You should have received a copy of the GNU General Public License along 
    2457 + *   with this program; if not, see <http://www.gnu.org/licenses>. 
    2458 + *  
    2459 + *   Linking stunnel statically or dynamically with other modules is making 
    2460 + *   a combined work based on stunnel. Thus, the terms and conditions of 
    2461 + *   the GNU General Public License cover the whole combination. 
    2462 + *  
    2463 + *   In addition, as a special exception, the copyright holder of stunnel 
    2464 + *   gives you permission to combine stunnel with free software programs or 
    2465 + *   libraries that are released under the GNU LGPL and with code included 
    2466 + *   in the standard release of OpenSSL under the OpenSSL License (or 
    2467 + *   modified versions of such code, with unchanged license). You may copy 
    2468 + *   and distribute such a system following the terms of the GNU GPL for 
    2469 + *   stunnel and the licenses of the other code concerned. 
    2470 + *  
    2471 + *   Note that people who make modified versions of stunnel are not obligated 
    2472 + *   to grant this special exception for their modified versions; it is their 
    2473 + *   choice whether to do so. The GNU General Public License gives permission 
    2474 + *   to release a modified version without this exception; this exception 
    2475 + *   also makes it possible to release a modified version which carries 
    2476 + *   forward this exception. 
    2477 + */ 
    2478 + 
    2479 +#include "common.h" 
    2480 +#include "prototypes.h" 
    2481 + 
    2482 +#if defined(_WIN32_WCE) && !defined(CONFDIR) 
    2483 +#define CONFDIR "\\stunnel" 
    2484 +#endif 
    2485 + 
    2486 +#ifdef USE_WIN32 
    2487 +#define CONFSEPARATOR "\\" 
    2488 +#else 
    2489 +#define CONFSEPARATOR "/" 
    2490 +#endif 
    2491 + 
    2492 +#define CONFLINELEN (16*1024) 
    2493 + 
    2494 +static void section_validate(char *, int, LOCAL_OPTIONS *, int); 
    2495 +static void config_error(char *, int, char *); 
    2496 +static char *stralloc(char *); 
    2497 +#ifndef USE_WIN32 
    2498 +static char **argalloc(char *); 
    2499 +#endif 
    2500 + 
    2501 +static int parse_debug_level(char *); 
    2502 +static int parse_ssl_option(char *); 
    2503 +static int print_socket_options(void); 
    2504 +static void print_option(char *, int, OPT_UNION *); 
    2505 +static int parse_socket_option(char *); 
    2506 +static char *parse_ocsp_url(LOCAL_OPTIONS *, char *); 
    2507 +static unsigned long parse_ocsp_flag(char *); 
    2508 + 
    2509 +GLOBAL_OPTIONS options; 
    2510 +LOCAL_OPTIONS local_options; 
    2511 + 
    2512 +typedef enum { 
    2513 +    CMD_INIT, /* initialize */ 
    2514 +    CMD_EXEC, 
    2515 +    CMD_DEFAULT, 
    2516 +    CMD_HELP 
    2517 +} CMD; 
    2518 + 
    2519 +static char *option_not_found= 
    2520 +    "Specified option name is not valid here"; 
    2521 + 
    2522 +static char *global_options(CMD cmd, char *opt, char *arg) { 
    2523 +    char *tmpstr; 
    2524 +#ifndef USE_WIN32 
    2525 +    struct group *gr; 
    2526 +    struct passwd *pw; 
    2527 +#endif 
    2528 + 
    2529 +    if(cmd==CMD_DEFAULT || cmd==CMD_HELP) { 
    2530 +        s_log(LOG_RAW, "Global options"); 
    2531 +    } 
    2532 + 
    2533 +    /* chroot */ 
    2534 +#ifdef HAVE_CHROOT 
    2535 +    switch(cmd) { 
    2536 +    case CMD_INIT: 
    2537 +        options.chroot_dir=NULL; 
    2538 +        break; 
    2539 +    case CMD_EXEC: 
    2540 +        if(strcasecmp(opt, "chroot")) 
    2541 +            break; 
    2542 +        options.chroot_dir=stralloc(arg); 
    2543 +        return NULL; /* OK */ 
    2544 +    case CMD_DEFAULT: 
    2545 +        break; 
    2546 +    case CMD_HELP: 
    2547 +        s_log(LOG_RAW, "%-15s = directory to chroot stunnel process", "chroot"); 
    2548 +        break; 
    2549 +    } 
    2550 +#endif /* HAVE_CHROOT */ 
    2551 + 
    2552 +    /* compression */ 
    2553 +    switch(cmd) { 
    2554 +    case CMD_INIT: 
    2555 +        options.compression=COMP_NONE; 
    2556 +        break; 
    2557 +    case CMD_EXEC: 
    2558 +        if(strcasecmp(opt, "compression")) 
    2559 +            break; 
    2560 +        if(!strcasecmp(arg, "zlib")) 
    2561 +            options.compression=COMP_ZLIB; 
    2562 +        else if(!strcasecmp(arg, "rle")) 
    2563 +            options.compression=COMP_RLE; 
    2564 +        else 
    2565 +            return "Compression type should be either 'zlib' or 'rle'"; 
    2566 +        return NULL; /* OK */ 
    2567 +    case CMD_DEFAULT: 
    2568 +        break; 
    2569 +    case CMD_HELP: 
    2570 +        s_log(LOG_RAW, "%-15s = zlib|rle compression type", 
    2571 +            "compression"); 
    2572 +        break; 
    2573 +    } 
    2574 + 
    2575 +    /* debug */ 
    2576 +    switch(cmd) { 
    2577 +    case CMD_INIT: 
    2578 +        options.debug_level=5; 
    2579 +#if !defined (USE_WIN32) && !defined (__vms) 
    2580 +        options.facility=LOG_DAEMON; 
    2581 +#endif 
    2582 +        break; 
    2583 +    case CMD_EXEC: 
    2584 +        if(strcasecmp(opt, "debug")) 
    2585 +            break; 
    2586 +        if(!parse_debug_level(arg)) 
    2587 +            return "Illegal debug argument"; 
    2588 +        return NULL; /* OK */ 
    2589 +    case CMD_DEFAULT: 
    2590 +        s_log(LOG_RAW, "%-15s = %d", "debug", options.debug_level); 
    2591 +        break; 
    2592 +    case CMD_HELP: 
    2593 +        s_log(LOG_RAW, "%-15s = [facility].level (e.g. daemon.info)", "debug"); 
    2594 +        break; 
    2595 +    } 
    2596 + 
    2597 +    /* EGD is only supported when compiled with OpenSSL 0.9.5a or later */ 
    2598 +#if SSLEAY_VERSION_NUMBER >= 0x0090581fL 
    2599 +    switch(cmd) { 
    2600 +    case CMD_INIT: 
    2601 +        options.egd_sock=NULL; 
    2602 +        break; 
    2603 +    case CMD_EXEC: 
    2604 +        if(strcasecmp(opt, "EGD")) 
    2605 +            break; 
    2606 +        options.egd_sock=stralloc(arg); 
    2607 +        return NULL; /* OK */ 
    2608 +    case CMD_DEFAULT: 
    2609 +#ifdef EGD_SOCKET 
    2610 +        s_log(LOG_RAW, "%-15s = %s", "EGD", EGD_SOCKET); 
    2611 +#endif 
    2612 +        break; 
    2613 +    case CMD_HELP: 
    2614 +        s_log(LOG_RAW, "%-15s = path to Entropy Gathering Daemon socket", "EGD"); 
    2615 +        break; 
    2616 +    } 
    2617 +#endif /* OpenSSL 0.9.5a */ 
    2618 + 
    2619 +#ifdef HAVE_OSSL_ENGINE_H 
    2620 +    /* engine */ 
    2621 +    switch(cmd) { 
    2622 +    case CMD_INIT: 
    2623 +        break; 
    2624 +    case CMD_EXEC: 
    2625 +        if(strcasecmp(opt, "engine")) 
    2626 +            break; 
    2627 +        open_engine(arg); 
    2628 +        return NULL; /* OK */ 
    2629 +    case CMD_DEFAULT: 
    2630 +        break; 
    2631 +    case CMD_HELP: 
    2632 +        s_log(LOG_RAW, "%-15s = auto|engine_id", 
    2633 +            "engine"); 
    2634 +        break; 
    2635 +    } 
    2636 + 
    2637 +    /* engineCtrl */ 
    2638 +    switch(cmd) { 
    2639 +    case CMD_INIT: 
    2640 +        break; 
    2641 +    case CMD_EXEC: 
    2642 +        if(strcasecmp(opt, "engineCtrl")) 
    2643 +            break; 
    2644 +        tmpstr=strchr(arg, ':'); 
    2645 +        if(tmpstr) 
    2646 +            *tmpstr++='\0'; 
    2647 +        ctrl_engine(arg, tmpstr); 
    2648 +        return NULL; /* OK */ 
    2649 +    case CMD_DEFAULT: 
    2650 +        break; 
    2651 +    case CMD_HELP: 
    2652 +        s_log(LOG_RAW, "%-15s = cmd[:arg]", 
    2653 +            "engineCtrl"); 
    2654 +        break; 
    2655 +    } 
    2656 +#endif 
    2657 + 
    2658 +    /* fips */ 
    2659 +#ifdef USE_FIPS 
    2660 +    switch(cmd) { 
    2661 +    case CMD_INIT: 
    2662 +        options.option.fips=1; 
    2663 +        break; 
    2664 +    case CMD_EXEC: 
    2665 +        if(strcasecmp(opt, "fips")) 
    2666 +            break; 
    2667 +        if(!strcasecmp(arg, "yes")) 
    2668 +            options.option.fips=1; 
    2669 +        else if(!strcasecmp(arg, "no")) 
    2670 +            options.option.fips=0; 
    2671 +        else 
    2672 +            return "Argument should be either 'yes' or 'no'"; 
    2673 +        return NULL; /* OK */ 
    2674 +    case CMD_DEFAULT: 
    2675 +        break; 
    2676 +    case CMD_HELP: 
    2677 +        s_log(LOG_RAW, "%-15s = yes|no FIPS 140-2 mode", 
    2678 +            "fips"); 
    2679 +        break; 
    2680 +    } 
    2681 +#endif /* USE_FIPS */ 
    2682 + 
    2683 +    /* foreground */ 
    2684 +#ifndef USE_WIN32 
    2685 +    switch(cmd) { 
    2686 +    case CMD_INIT: 
    2687 +        options.option.foreground=0; 
    2688 +        break; 
    2689 +    case CMD_EXEC: 
    2690 +        if(strcasecmp(opt, "foreground")) 
    2691 +            break; 
    2692 +        if(!strcasecmp(arg, "yes")) 
    2693 +            options.option.foreground=1; 
    2694 +        else if(!strcasecmp(arg, "no")) 
    2695 +            options.option.foreground=0; 
    2696 +        else 
    2697 +            return "Argument should be either 'yes' or 'no'"; 
    2698 +        return NULL; /* OK */ 
    2699 +    case CMD_DEFAULT: 
    2700 +        break; 
    2701 +    case CMD_HELP: 
    2702 +        s_log(LOG_RAW, "%-15s = yes|no foreground mode (don't fork, log to stderr)", 
    2703 +            "foreground"); 
    2704 +        break; 
    2705 +    } 
    2706 +#endif 
    2707 + 
    2708 +    /* output */ 
    2709 +    switch(cmd) { 
    2710 +    case CMD_INIT: 
    2711 +        options.output_file=NULL; 
    2712 +        break; 
    2713 +    case CMD_EXEC: 
    2714 +        if(strcasecmp(opt, "output")) 
    2715 +            break; 
    2716 +        options.output_file=stralloc(arg); 
    2717 +        return NULL; /* OK */ 
    2718 +    case CMD_DEFAULT: 
    2719 +        break; 
    2720 +    case CMD_HELP: 
    2721 +        s_log(LOG_RAW, "%-15s = file to append log messages", "output"); 
    2722 +        break; 
    2723 +    } 
    2724 + 
    2725 +    /* pid */ 
    2726 +#ifndef USE_WIN32 
    2727 +    switch(cmd) { 
    2728 +    case CMD_INIT: 
    2729 +        options.pidfile=PIDFILE; 
    2730 +        break; 
    2731 +    case CMD_EXEC: 
    2732 +        if(strcasecmp(opt, "pid")) 
    2733 +            break; 
    2734 +        if(arg[0]) /* is argument not empty? */ 
    2735 +            options.pidfile=stralloc(arg); 
    2736 +        else 
    2737 +            options.pidfile=NULL; /* empty -> do not create a pid file */ 
    2738 +        return NULL; /* OK */ 
    2739 +    case CMD_DEFAULT: 
    2740 +        s_log(LOG_RAW, "%-15s = %s", "pid", PIDFILE); 
    2741 +        break; 
    2742 +    case CMD_HELP: 
    2743 +        s_log(LOG_RAW, "%-15s = pid file (empty to disable creating)", "pid"); 
    2744 +        break; 
    2745 +    } 
    2746 +#endif 
    2747 + 
    2748 +    /* RNDbytes */ 
    2749 +    switch(cmd) { 
    2750 +    case CMD_INIT: 
    2751 +        options.random_bytes=RANDOM_BYTES; 
    2752 +        break; 
    2753 +    case CMD_EXEC: 
    2754 +        if(strcasecmp(opt, "RNDbytes")) 
    2755 +            break; 
    2756 +        options.random_bytes=atoi(arg); 
    2757 +        return NULL; /* OK */ 
    2758 +    case CMD_DEFAULT: 
    2759 +        s_log(LOG_RAW, "%-15s = %d", "RNDbytes", RANDOM_BYTES); 
    2760 +        break; 
    2761 +    case CMD_HELP: 
    2762 +        s_log(LOG_RAW, "%-15s = bytes to read from random seed files", "RNDbytes"); 
    2763 +        break; 
    2764 +    } 
    2765 + 
    2766 +    /* RNDfile */ 
    2767 +    switch(cmd) { 
    2768 +    case CMD_INIT: 
    2769 +        options.rand_file=NULL; 
    2770 +        break; 
    2771 +    case CMD_EXEC: 
    2772 +        if(strcasecmp(opt, "RNDfile")) 
    2773 +            break; 
    2774 +        options.rand_file=stralloc(arg); 
    2775 +        return NULL; /* OK */ 
    2776 +    case CMD_DEFAULT: 
    2777 +#ifdef RANDOM_FILE 
    2778 +        s_log(LOG_RAW, "%-15s = %s", "RNDfile", RANDOM_FILE); 
    2779 +#endif 
    2780 +        break; 
    2781 +    case CMD_HELP: 
    2782 +        s_log(LOG_RAW, "%-15s = path to file with random seed data", "RNDfile"); 
    2783 +        break; 
    2784 +    } 
    2785 + 
    2786 +    /* RNDoverwrite */ 
    2787 +    switch(cmd) { 
    2788 +    case CMD_INIT: 
    2789 +        options.option.rand_write=1; 
    2790 +        break; 
    2791 +    case CMD_EXEC: 
    2792 +        if(strcasecmp(opt, "RNDoverwrite")) 
    2793 +            break; 
    2794 +        if(!strcasecmp(arg, "yes")) 
    2795 +            options.option.rand_write=1; 
    2796 +        else if(!strcasecmp(arg, "no")) 
    2797 +            options.option.rand_write=0; 
    2798 +        else 
    2799 +            return "Argument should be either 'yes' or 'no'"; 
    2800 +        return NULL; /* OK */ 
    2801 +    case CMD_DEFAULT: 
    2802 +        s_log(LOG_RAW, "%-15s = yes", "RNDoverwrite"); 
    2803 +        break; 
    2804 +    case CMD_HELP: 
    2805 +        s_log(LOG_RAW, "%-15s = yes|no overwrite seed datafiles with new random data", 
    2806 +            "RNDoverwrite"); 
    2807 +        break; 
    2808 +    } 
    2809 + 
    2810 +    /* service */ 
    2811 +    switch(cmd) { 
    2812 +    case CMD_INIT: 
    2813 +        local_options.servname=stralloc("stunnel"); 
    2814 +#if defined(USE_WIN32) && !defined(_WIN32_WCE) 
    2815 +        options.win32_service="stunnel"; 
    2816 +#endif 
    2817 +        break; 
    2818 +    case CMD_EXEC: 
    2819 +        if(strcasecmp(opt, "service")) 
    2820 +            break; 
    2821 +        local_options.servname=stralloc(arg); 
    2822 +#if defined(USE_WIN32) && !defined(_WIN32_WCE) 
    2823 +        options.win32_service=stralloc(arg); 
    2824 +#endif 
    2825 +        return NULL; /* OK */ 
    2826 +    case CMD_DEFAULT: 
    2827 +#if defined(USE_WIN32) && !defined(_WIN32_WCE) 
    2828 +        s_log(LOG_RAW, "%-15s = %s", "service", options.win32_service); 
    2829 +#endif 
    2830 +        break; 
    2831 +    case CMD_HELP: 
    2832 +        s_log(LOG_RAW, "%-15s = service name", "service"); 
    2833 +        break; 
    2834 +    } 
    2835 + 
    2836 +#ifndef USE_WIN32 
    2837 +    /* setgid */ 
    2838 +    switch(cmd) { 
    2839 +    case CMD_INIT: 
    2840 +        options.gid=0; 
    2841 +        break; 
    2842 +    case CMD_EXEC: 
    2843 +        if(strcasecmp(opt, "setgid")) 
    2844 +            break; 
    2845 +        gr=getgrnam(arg); 
    2846 +        if(gr) 
    2847 +            options.gid=gr->gr_gid; 
    2848 +        else if(atoi(arg)) /* numerical? */ 
    2849 +            options.gid=atoi(arg); 
    2850 +        else 
    2851 +            return "Illegal GID"; 
    2852 +        return NULL; /* OK */ 
    2853 +    case CMD_DEFAULT: 
    2854 +        break; 
    2855 +    case CMD_HELP: 
    2856 +        s_log(LOG_RAW, "%-15s = groupname for setgid()", "setgid"); 
    2857 +        break; 
    2858 +    } 
    2859 +#endif 
    2860 + 
    2861 +#ifndef USE_WIN32 
    2862 +    /* setuid */ 
    2863 +    switch(cmd) { 
    2864 +    case CMD_INIT: 
    2865 +        options.uid=0; 
    2866 +        break; 
    2867 +    case CMD_EXEC: 
    2868 +        if(strcasecmp(opt, "setuid")) 
    2869 +            break; 
    2870 +        pw=getpwnam(arg); 
    2871 +        if(pw) 
    2872 +            options.uid=pw->pw_uid; 
    2873 +        else if(atoi(arg)) /* numerical? */ 
    2874 +            options.uid=atoi(arg); 
    2875 +        else 
    2876 +            return "Illegal UID"; 
    2877 +        return NULL; /* OK */ 
    2878 +    case CMD_DEFAULT: 
    2879 +        break; 
    2880 +    case CMD_HELP: 
    2881 +        s_log(LOG_RAW, "%-15s = username for setuid()", "setuid"); 
    2882 +        break; 
    2883 +    } 
    2884 +#endif 
    2885 + 
    2886 +    /* socket */ 
    2887 +    switch(cmd) { 
    2888 +    case CMD_INIT: 
    2889 +        break; 
    2890 +    case CMD_EXEC: 
    2891 +        if(strcasecmp(opt, "socket")) 
    2892 +            break; 
    2893 +        if(!parse_socket_option(arg)) 
    2894 +            return "Illegal socket option"; 
    2895 +        return NULL; /* OK */ 
    2896 +    case CMD_DEFAULT: 
    2897 +        break; 
    2898 +    case CMD_HELP: 
    2899 +        s_log(LOG_RAW, "%-15s = a|l|r:option=value[:value]", "socket"); 
    2900 +        s_log(LOG_RAW, "%18sset an option on accept/local/remote socket", ""); 
    2901 +        break; 
    2902 +    } 
    2903 + 
    2904 +    /* syslog */ 
    2905 +#ifndef USE_WIN32 
    2906 +    switch(cmd) { 
    2907 +    case CMD_INIT: 
    2908 +        options.option.syslog=1; 
    2909 +        break; 
    2910 +    case CMD_EXEC: 
    2911 +        if(strcasecmp(opt, "syslog")) 
    2912 +            break; 
    2913 +        if(!strcasecmp(arg, "yes")) 
    2914 +            options.option.syslog=1; 
    2915 +        else if(!strcasecmp(arg, "no")) 
    2916 +            options.option.syslog=0; 
    2917 +        else 
    2918 +            return "Argument should be either 'yes' or 'no'"; 
    2919 +        return NULL; /* OK */ 
    2920 +    case CMD_DEFAULT: 
    2921 +        break; 
    2922 +    case CMD_HELP: 
    2923 +        s_log(LOG_RAW, "%-15s = yes|no send logging messages to syslog", 
    2924 +            "syslog"); 
    2925 +        break; 
    2926 +    } 
    2927 +#endif 
    2928 + 
    2929 +    /* taskbar */ 
    2930 +#ifdef USE_WIN32 
    2931 +    switch(cmd) { 
    2932 +    case CMD_INIT: 
    2933 +        options.option.taskbar=1; 
    2934 +        break; 
    2935 +    case CMD_EXEC: 
    2936 +        if(strcasecmp(opt, "taskbar")) 
    2937 +            break; 
    2938 +        if(!strcasecmp(arg, "yes")) 
    2939 +            options.option.taskbar=1; 
    2940 +        else if(!strcasecmp(arg, "no")) 
    2941 +            options.option.taskbar=0; 
    2942 +        else 
    2943 +            return "Argument should be either 'yes' or 'no'"; 
    2944 +        return NULL; /* OK */ 
    2945 +    case CMD_DEFAULT: 
    2946 +        s_log(LOG_RAW, "%-15s = yes", "taskbar"); 
    2947 +        break; 
    2948 +    case CMD_HELP: 
    2949 +        s_log(LOG_RAW, "%-15s = yes|no enable the taskbar icon", "taskbar"); 
    2950 +        break; 
    2951 +    } 
    2952 +#endif 
    2953 + 
    2954 +    if(cmd==CMD_EXEC) 
    2955 +        return option_not_found; 
    2956 +    return NULL; /* OK */ 
    2957 +} 
    2958 + 
    2959 +static char *service_options(CMD cmd, LOCAL_OPTIONS *section, 
    2960 +        char *opt, char *arg) { 
    2961 +    int tmpnum; 
    2962 + 
    2963 +    if(cmd==CMD_DEFAULT || cmd==CMD_HELP) { 
    2964 +        s_log(LOG_RAW, " "); 
    2965 +        s_log(LOG_RAW, "Service-level options"); 
    2966 +    } 
    2967 + 
    2968 +    /* accept */ 
    2969 +    switch(cmd) { 
    2970 +    case CMD_INIT: 
    2971 +        section->option.accept=0; 
    2972 +        memset(&section->local_addr, 0, sizeof(SOCKADDR_LIST)); 
    2973 +        section->local_addr.addr[0].in.sin_family=AF_INET; 
    2974 +        break; 
    2975 +    case CMD_EXEC: 
    2976 +        if(strcasecmp(opt, "accept")) 
    2977 +            break; 
    2978 +        section->option.accept=1; 
    2979 +        if(!name2addrlist(&section->local_addr, arg, DEFAULT_ANY)) 
    2980 +            return "Failed to resolve accepting address"; 
    2981 +        return NULL; /* OK */ 
    2982 +    case CMD_DEFAULT: 
    2983 +        break; 
    2984 +    case CMD_HELP: 
    2985 +        s_log(LOG_RAW, "%-15s = [host:]port accept connections on specified host:port", 
    2986 +            "accept"); 
    2987 +        break; 
    2988 +    } 
    2989 + 
    2990 +    /* CApath */ 
    2991 +    switch(cmd) { 
    2992 +    case CMD_INIT: 
    2993 +#if 0 
    2994 +        section->ca_dir=(char *)X509_get_default_cert_dir(); 
    2995 +#endif 
    2996 +        section->ca_dir=NULL; 
    2997 +        break; 
    2998 +    case CMD_EXEC: 
    2999 +        if(strcasecmp(opt, "CApath")) 
    3000 +            break; 
    3001 +        if(arg[0]) /* not empty */ 
    3002 +            section->ca_dir=stralloc(arg); 
    3003 +        else 
    3004 +            section->ca_dir=NULL; 
    3005 +        return NULL; /* OK */ 
    3006 +    case CMD_DEFAULT: 
    3007 +#if 0 
    3008 +        s_log(LOG_RAW, "%-15s = %s", "CApath", 
    3009 +            section->ca_dir ? section->ca_dir : "(none)"); 
    3010 +#endif 
    3011 +        break; 
    3012 +    case CMD_HELP: 
    3013 +        s_log(LOG_RAW, "%-15s = CA certificate directory for 'verify' option", 
    3014 +            "CApath"); 
    3015 +        break; 
    3016 +    } 
    3017 + 
    3018 +    /* CAfile */ 
    3019 +    switch(cmd) { 
    3020 +    case CMD_INIT: 
    3021 +#if 0 
    3022 +        section->ca_file=(char *)X509_get_default_certfile(); 
    3023 +#endif 
    3024 +        section->ca_file=NULL; 
    3025 +        break; 
    3026 +    case CMD_EXEC: 
    3027 +        if(strcasecmp(opt, "CAfile")) 
    3028 +            break; 
    3029 +        if(arg[0]) /* not empty */ 
    3030 +            section->ca_file=stralloc(arg); 
    3031 +        else 
    3032 +            section->ca_file=NULL; 
    3033 +        return NULL; /* OK */ 
    3034 +    case CMD_DEFAULT: 
    3035 +#if 0 
    3036 +        s_log(LOG_RAW, "%-15s = %s", "CAfile", 
    3037 +            section->ca_file ? section->ca_file : "(none)"); 
    3038 +#endif 
    3039 +        break; 
    3040 +    case CMD_HELP: 
    3041 +        s_log(LOG_RAW, "%-15s = CA certificate file for 'verify' option", 
    3042 +            "CAfile"); 
    3043 +        break; 
    3044 +    } 
    3045 + 
    3046 +    /* cert */ 
    3047 +    switch(cmd) { 
    3048 +    case CMD_INIT: 
    3049 +#ifdef CONFDIR 
    3050 +        section->cert=CONFDIR CONFSEPARATOR "stunnel.pem"; 
    3051 +#else 
    3052 +        section->cert="stunnel.pem"; 
    3053 +#endif 
    3054 +        break; 
    3055 +    case CMD_EXEC: 
    3056 +        if(strcasecmp(opt, "cert")) 
    3057 +            break; 
    3058 +        section->cert=stralloc(arg); 
    3059 +        section->option.cert=1; 
    3060 +        return NULL; /* OK */ 
    3061 +    case CMD_DEFAULT: 
    3062 +        s_log(LOG_RAW, "%-15s = %s", "cert", section->cert); 
    3063 +        break; 
    3064 +    case CMD_HELP: 
    3065 +        s_log(LOG_RAW, "%-15s = certificate chain", "cert"); 
    3066 +        break; 
    3067 +    } 
    3068 + 
    3069 +    /* ciphers */ 
    3070 +#ifdef USE_FIPS 
    3071 +#define STUNNEL_DEFAULT_CIPHER_LIST "FIPS" 
    3072 +#else 
    3073 +#define STUNNEL_DEFAULT_CIPHER_LIST SSL_DEFAULT_CIPHER_LIST 
    3074 +#endif /* USE_FIPS */ 
    3075 +    switch(cmd) { 
    3076 +    case CMD_INIT: 
    3077 +        section->cipher_list=STUNNEL_DEFAULT_CIPHER_LIST; 
    3078 +        break; 
    3079 +    case CMD_EXEC: 
    3080 +        if(strcasecmp(opt, "ciphers")) 
    3081 +            break; 
    3082 +        section->cipher_list=stralloc(arg); 
    3083 +        return NULL; /* OK */ 
    3084 +    case CMD_DEFAULT: 
    3085 +        s_log(LOG_RAW, "%-15s = %s", "ciphers", STUNNEL_DEFAULT_CIPHER_LIST); 
    3086 +        break; 
    3087 +    case CMD_HELP: 
    3088 +        s_log(LOG_RAW, "%-15s = list of permitted SSL ciphers", "ciphers"); 
    3089 +        break; 
    3090 +    } 
    3091 + 
    3092 +    /* client */ 
    3093 +    switch(cmd) { 
    3094 +    case CMD_INIT: 
    3095 +        section->option.client=0; 
    3096 +        break; 
    3097 +    case CMD_EXEC: 
    3098 +        if(strcasecmp(opt, "client")) 
    3099 +            break; 
    3100 +        if(!strcasecmp(arg, "yes")) 
    3101 +            section->option.client=1; 
    3102 +        else if(!strcasecmp(arg, "no")) 
    3103 +            section->option.client=0; 
    3104 +        else 
    3105 +            return "Argument should be either 'yes' or 'no'"; 
    3106 +        return NULL; /* OK */ 
    3107 +    case CMD_DEFAULT: 
    3108 +        break; 
    3109 +    case CMD_HELP: 
    3110 +        s_log(LOG_RAW, "%-15s = yes|no client mode (remote service uses SSL)", 
    3111 +            "client"); 
    3112 +        break; 
    3113 +    } 
    3114 + 
    3115 +    /* connect */ 
    3116 +    switch(cmd) { 
    3117 +    case CMD_INIT: 
    3118 +        section->option.remote=0; 
    3119 +        section->remote_address=NULL; 
    3120 +        section->remote_addr.num=0; 
    3121 +        break; 
    3122 +    case CMD_EXEC: 
    3123 +        if(strcasecmp(opt, "connect")) 
    3124 +            break; 
    3125 +        section->option.remote=1; 
    3126 +        section->remote_address=stralloc(arg); 
    3127 +        if(!section->option.delayed_lookup && 
    3128 +                !name2addrlist(&section->remote_addr, arg, DEFAULT_LOOPBACK)) { 
    3129 +            s_log(LOG_RAW, "Cannot resolve '%s' - delaying DNS lookup", arg); 
    3130 +            section->option.delayed_lookup=1; 
    3131 +        } 
    3132 +        return NULL; /* OK */ 
    3133 +    case CMD_DEFAULT: 
    3134 +        break; 
    3135 +    case CMD_HELP: 
    3136 +        s_log(LOG_RAW, "%-15s = [host:]port connect remote host:port", 
    3137 +            "connect"); 
    3138 +        break; 
    3139 +    } 
    3140 + 
    3141 +    /* CRLpath */ 
    3142 +    switch(cmd) { 
    3143 +    case CMD_INIT: 
    3144 +        section->crl_dir=NULL; 
    3145 +        break; 
    3146 +    case CMD_EXEC: 
    3147 +        if(strcasecmp(opt, "CRLpath")) 
    3148 +            break; 
    3149 +        if(arg[0]) /* not empty */ 
    3150 +            section->crl_dir=stralloc(arg); 
    3151 +        else 
    3152 +            section->crl_dir=NULL; 
    3153 +        return NULL; /* OK */ 
    3154 +    case CMD_DEFAULT: 
    3155 +        break; 
    3156 +    case CMD_HELP: 
    3157 +        s_log(LOG_RAW, "%-15s = CRL directory", "CRLpath"); 
    3158 +        break; 
    3159 +    } 
    3160 + 
    3161 +    /* CRLfile */ 
    3162 +    switch(cmd) { 
    3163 +    case CMD_INIT: 
    3164 +        section->crl_file=NULL; 
    3165 +        break; 
    3166 +    case CMD_EXEC: 
    3167 +        if(strcasecmp(opt, "CRLfile")) 
    3168 +            break; 
    3169 +        if(arg[0]) /* not empty */ 
    3170 +            section->crl_file=stralloc(arg); 
    3171 +        else 
    3172 +            section->crl_file=NULL; 
    3173 +        return NULL; /* OK */ 
    3174 +    case CMD_DEFAULT: 
    3175 +        break; 
    3176 +    case CMD_HELP: 
    3177 +        s_log(LOG_RAW, "%-15s = CRL file", "CRLfile"); 
    3178 +        break; 
    3179 +    } 
    3180 + 
    3181 +    /* delay */ 
    3182 +    switch(cmd) { 
    3183 +    case CMD_INIT: 
    3184 +        section->option.delayed_lookup=0; 
    3185 +        break; 
    3186 +    case CMD_EXEC: 
    3187 +        if(strcasecmp(opt, "delay")) 
    3188 +            break; 
    3189 +        if(!strcasecmp(arg, "yes")) 
    3190 +            section->option.delayed_lookup=1; 
    3191 +        else if(!strcasecmp(arg, "no")) 
    3192 +            section->option.delayed_lookup=0; 
    3193 +        else 
    3194 +            return "Argument should be either 'yes' or 'no'"; 
    3195 +        return NULL; /* OK */ 
    3196 +    case CMD_DEFAULT: 
    3197 +        break; 
    3198 +    case CMD_HELP: 
    3199 +        s_log(LOG_RAW, "%-15s = yes|no delay DNS lookup for 'connect' option", 
    3200 +            "delay"); 
    3201 +        break; 
    3202 +    } 
    3203 + 
    3204 +#ifdef HAVE_OSSL_ENGINE_H 
    3205 +    /* engineNum */ 
    3206 +    switch(cmd) { 
    3207 +    case CMD_INIT: 
    3208 +        break; 
    3209 +    case CMD_EXEC: 
    3210 +        if(strcasecmp(opt, "engineNum")) 
    3211 +            break; 
    3212 +        section->engine=get_engine(atoi(arg)); 
    3213 +        if(!section->engine) 
    3214 +            return "Illegal engine number"; 
    3215 +        return NULL; /* OK */ 
    3216 +    case CMD_DEFAULT: 
    3217 +        break; 
    3218 +    case CMD_HELP: 
    3219 +        s_log(LOG_RAW, "%-15s = number of engine to read the key from", 
    3220 +            "engineNum"); 
    3221 +        break; 
    3222 +    } 
    3223 +#endif 
    3224 + 
    3225 +    /* exec */ 
    3226 +#ifndef USE_WIN32 
    3227 +    switch(cmd) { 
    3228 +    case CMD_INIT: 
    3229 +        section->option.program=0; 
    3230 +        section->execname=NULL; 
    3231 +        break; 
    3232 +    case CMD_EXEC: 
    3233 +        if(strcasecmp(opt, "exec")) 
    3234 +            break; 
    3235 +        section->option.program=1; 
    3236 +        section->execname=stralloc(arg); 
    3237 +        if(!section->execargs) { 
    3238 +            section->execargs=calloc(2, sizeof(char *)); 
    3239 +            section->execargs[0]=section->execname; 
    3240 +            section->execargs[1]=NULL; /* to show that it's null-terminated */ 
    3241 +        } 
    3242 +        return NULL; /* OK */ 
    3243 +    case CMD_DEFAULT: 
    3244 +        break; 
    3245 +    case CMD_HELP: 
    3246 +        s_log(LOG_RAW, "%-15s = file execute local inetd-type program", 
    3247 +            "exec"); 
    3248 +        break; 
    3249 +    } 
    3250 +#endif 
    3251 + 
    3252 +    /* execargs */ 
    3253 +#ifndef USE_WIN32 
    3254 +    switch(cmd) { 
    3255 +    case CMD_INIT: 
    3256 +        section->execargs=NULL; 
    3257 +        break; 
    3258 +    case CMD_EXEC: 
    3259 +        if(strcasecmp(opt, "execargs")) 
    3260 +            break; 
    3261 +        section->execargs=argalloc(arg); 
    3262 +        return NULL; /* OK */ 
    3263 +    case CMD_DEFAULT: 
    3264 +        break; 
    3265 +    case CMD_HELP: 
    3266 +        s_log(LOG_RAW, "%-15s = arguments for 'exec' (including $0)", 
    3267 +            "execargs"); 
    3268 +        break; 
    3269 +    } 
    3270 +#endif 
    3271 + 
    3272 +    /* failover */ 
    3273 +    switch(cmd) { 
    3274 +    case CMD_INIT: 
    3275 +        section->failover=FAILOVER_RR; 
    3276 +        break; 
    3277 +    case CMD_EXEC: 
    3278 +        if(strcasecmp(opt, "failover")) 
    3279 +            break; 
    3280 +        if(!strcasecmp(arg, "rr")) 
    3281 +            section->failover=FAILOVER_RR; 
    3282 +        else if(!strcasecmp(arg, "prio")) 
    3283 +            section->failover=FAILOVER_PRIO; 
    3284 +        else 
    3285 +            return "Argument should be either 'rr' or 'prio'"; 
    3286 +        return NULL; /* OK */ 
    3287 +    case CMD_DEFAULT: 
    3288 +        break; 
    3289 +    case CMD_HELP: 
    3290 +        s_log(LOG_RAW, "%-15s = rr|prio chose failover strategy", 
    3291 +            "failover"); 
    3292 +        break; 
    3293 +    } 
    3294 + 
    3295 +    /* ident */ 
    3296 +    switch(cmd) { 
    3297 +    case CMD_INIT: 
    3298 +        section->username=NULL; 
    3299 +        break; 
    3300 +    case CMD_EXEC: 
    3301 +        if(strcasecmp(opt, "ident")) 
    3302 +            break; 
    3303 +        section->username=stralloc(arg); 
    3304 +        return NULL; /* OK */ 
    3305 +    case CMD_DEFAULT: 
    3306 +        break; 
    3307 +    case CMD_HELP: 
    3308 +        s_log(LOG_RAW, "%-15s = username for IDENT (RFC 1413) checking", "ident"); 
    3309 +        break; 
    3310 +    } 
    3311 + 
    3312 +    /* key */ 
    3313 +    switch(cmd) { 
    3314 +    case CMD_INIT: 
    3315 +        section->key=NULL; 
    3316 +        break; 
    3317 +    case CMD_EXEC: 
    3318 +        if(strcasecmp(opt, "key")) 
    3319 +            break; 
    3320 +        section->key=stralloc(arg); 
    3321 +        return NULL; /* OK */ 
    3322 +    case CMD_DEFAULT: 
    3323 +        s_log(LOG_RAW, "%-15s = %s", "key", section->cert); /* set in stunnel.c */ 
    3324 +        break; 
    3325 +    case CMD_HELP: 
    3326 +        s_log(LOG_RAW, "%-15s = certificate private key", "key"); 
    3327 +        break; 
    3328 +    } 
    3329 + 
    3330 +    /* local */ 
    3331 +    switch(cmd) { 
    3332 +    case CMD_INIT: 
    3333 +        memset(&section->source_addr, 0, sizeof(SOCKADDR_LIST)); 
    3334 +        section->source_addr.addr[0].in.sin_family=AF_INET; 
    3335 +        break; 
    3336 +    case CMD_EXEC: 
    3337 +        if(strcasecmp(opt, "local")) 
    3338 +            break; 
    3339 +        if(!hostport2addrlist(&section->source_addr, arg, "0")) 
    3340 +            return "Failed to resolve local address"; 
    3341 +        return NULL; /* OK */ 
    3342 +    case CMD_DEFAULT: 
    3343 +        break; 
    3344 +    case CMD_HELP: 
    3345 +        s_log(LOG_RAW, "%-15s = IP address to be used as source for remote" 
    3346 +            " connections", "local"); 
    3347 +        break; 
    3348 +    } 
    3349 + 
    3350 +#if SSLEAY_VERSION_NUMBER >= 0x00907000L 
    3351 +    /* OCSP */ 
    3352 +    switch(cmd) { 
    3353 +    case CMD_INIT: 
    3354 +        section->option.ocsp=0; 
    3355 +        memset(&section->ocsp_addr, 0, sizeof(SOCKADDR_LIST)); 
    3356 +        section->ocsp_addr.addr[0].in.sin_family=AF_INET; 
    3357 +        break; 
    3358 +    case CMD_EXEC: 
    3359 +        if(strcasecmp(opt, "ocsp")) 
    3360 +            break; 
    3361 +        section->option.ocsp=1; 
    3362 +        return parse_ocsp_url(section, arg); 
    3363 +    case CMD_DEFAULT: 
    3364 +        break; 
    3365 +    case CMD_HELP: 
    3366 +        s_log(LOG_RAW, "%-15s = OCSP server URL", "ocsp"); 
    3367 +        break; 
    3368 +    } 
    3369 + 
    3370 +    /* OCSPflag */ 
    3371 +    switch(cmd) { 
    3372 +    case CMD_INIT: 
    3373 +        section->ocsp_flags=0; 
    3374 +        break; 
    3375 +    case CMD_EXEC: 
    3376 +        if(strcasecmp(opt, "OCSPflag")) 
    3377 +            break; 
    3378 +        tmpnum=parse_ocsp_flag(arg); 
    3379 +        if(!tmpnum) 
    3380 +            return "Illegal OCSP flag"; 
    3381 +        section->ocsp_flags|=tmpnum; 
    3382 +        return NULL; 
    3383 +    case CMD_DEFAULT: 
    3384 +        break; 
    3385 +    case CMD_HELP: 
    3386 +        s_log(LOG_RAW, "%-15s = OCSP server flags", "OCSPflag"); 
    3387 +        break; 
    3388 +    } 
    3389 +#endif /* OpenSSL-0.9.7 */ 
    3390 + 
    3391 +    /* options */ 
    3392 +    switch(cmd) { 
    3393 +    case CMD_INIT: 
    3394 +        section->ssl_options=0; 
    3395 +        break; 
    3396 +    case CMD_EXEC: 
    3397 +        if(strcasecmp(opt, "options")) 
    3398 +            break; 
    3399 +        tmpnum=parse_ssl_option(arg); 
    3400 +        if(!tmpnum) 
    3401 +            return "Illegal SSL option"; 
    3402 +        section->ssl_options|=tmpnum; 
    3403 +        return NULL; /* OK */ 
    3404 +    case CMD_DEFAULT: 
    3405 +        break; 
    3406 +    case CMD_HELP: 
    3407 +        s_log(LOG_RAW, "%-15s = SSL option", "options"); 
    3408 +        s_log(LOG_RAW, "%18sset an SSL option", ""); 
    3409 +        break; 
    3410 +    } 
    3411 + 
    3412 +    /* protocol */ 
    3413 +    switch(cmd) { 
    3414 +    case CMD_INIT: 
    3415 +        section->protocol=NULL; 
    3416 +        break; 
    3417 +    case CMD_EXEC: 
    3418 +        if(strcasecmp(opt, "protocol")) 
    3419 +            break; 
    3420 +        section->protocol=stralloc(arg); 
    3421 +        return NULL; /* OK */ 
    3422 +    case CMD_DEFAULT: 
    3423 +        break; 
    3424 +    case CMD_HELP: 
    3425 +        s_log(LOG_RAW, "%-15s = protocol to negotiate before SSL initialization", 
    3426 +            "protocol"); 
    3427 +        s_log(LOG_RAW, "%18scurrently supported: cifs, connect, nntp, pop3, smtp", ""); 
    3428 +        break; 
    3429 +    } 
    3430 + 
    3431 +    /* protocolAuthentication */ 
    3432 +    switch(cmd) { 
    3433 +    case CMD_INIT: 
    3434 +        section->protocol_authentication="basic"; 
    3435 +        break; 
    3436 +    case CMD_EXEC: 
    3437 +        if(strcasecmp(opt, "protocolAuthentication")) 
    3438 +            break; 
    3439 +        section->protocol_authentication=stralloc(arg); 
    3440 +        return NULL; /* OK */ 
    3441 +    case CMD_DEFAULT: 
    3442 +        break; 
    3443 +    case CMD_HELP: 
    3444 +        s_log(LOG_RAW, "%-15s = authentication type for protocol negotiations", 
    3445 +            "protocolAuthentication"); 
    3446 +        break; 
    3447 +    } 
    3448 + 
    3449 +    /* protocolHost */ 
    3450 +    switch(cmd) { 
    3451 +    case CMD_INIT: 
    3452 +        section->protocol_host=NULL; 
    3453 +        break; 
    3454 +    case CMD_EXEC: 
    3455 +        if(strcasecmp(opt, "protocolHost")) 
    3456 +            break; 
    3457 +        section->protocol_host=stralloc(arg); 
    3458 +        return NULL; /* OK */ 
    3459 +    case CMD_DEFAULT: 
    3460 +        break; 
    3461 +    case CMD_HELP: 
    3462 +        s_log(LOG_RAW, "%-15s = host:port for protocol negotiations", 
    3463 +            "protocolHost"); 
    3464 +        break; 
    3465 +    } 
    3466 + 
    3467 +    /* protocolPassword */ 
    3468 +    switch(cmd) { 
    3469 +    case CMD_INIT: 
    3470 +        section->protocol_password=NULL; 
    3471 +        break; 
    3472 +    case CMD_EXEC: 
    3473 +        if(strcasecmp(opt, "protocolPassword")) 
    3474 +            break; 
    3475 +        section->protocol_password=stralloc(arg); 
    3476 +        return NULL; /* OK */ 
    3477 +    case CMD_DEFAULT: 
    3478 +        break; 
    3479 +    case CMD_HELP: 
    3480 +        s_log(LOG_RAW, "%-15s = password for protocol negotiations", 
    3481 +            "protocolPassword"); 
    3482 +        break; 
    3483 +    } 
    3484 + 
    3485 +    /* protocolUsername */ 
    3486 +    switch(cmd) { 
    3487 +    case CMD_INIT: 
    3488 +        section->protocol_username=NULL; 
    3489 +        break; 
    3490 +    case CMD_EXEC: 
    3491 +        if(strcasecmp(opt, "protocolUsername")) 
    3492 +            break; 
    3493 +        section->protocol_username=stralloc(arg); 
    3494 +        return NULL; /* OK */ 
    3495 +    case CMD_DEFAULT: 
    3496 +        break; 
    3497 +    case CMD_HELP: 
    3498 +        s_log(LOG_RAW, "%-15s = username for protocol negotiations", 
    3499 +            "protocolUsername"); 
    3500 +        break; 
    3501 +    } 
    3502 + 
    3503 +    /* pty */ 
    3504 +#ifndef USE_WIN32 
    3505 +    switch(cmd) { 
    3506 +    case CMD_INIT: 
    3507 +        section->option.pty=0; 
    3508 +        break; 
    3509 +    case CMD_EXEC: 
    3510 +        if(strcasecmp(opt, "pty")) 
    3511 +            break; 
    3512 +        if(!strcasecmp(arg, "yes")) 
    3513 +            section->option.pty=1; 
    3514 +        else if(!strcasecmp(arg, "no")) 
    3515 +            section->option.pty=0; 
    3516 +        else 
    3517 +            return "Argument should be either 'yes' or 'no'"; 
    3518 +        return NULL; /* OK */ 
    3519 +    case CMD_DEFAULT: 
    3520 +        break; 
    3521 +    case CMD_HELP: 
    3522 +        s_log(LOG_RAW, "%-15s = yes|no allocate pseudo terminal for 'exec' option", 
    3523 +            "pty"); 
    3524 +        break; 
    3525 +    } 
    3526 +#endif 
    3527 + 
    3528 +    /* retry */ 
    3529 +#ifndef USE_WIN32 
    3530 +    switch(cmd) { 
    3531 +    case CMD_INIT: 
    3532 +        section->option.retry=0; 
    3533 +        break; 
    3534 +    case CMD_EXEC: 
    3535 +        if(strcasecmp(opt, "retry")) 
    3536 +            break; 
    3537 +        if(!strcasecmp(arg, "yes")) 
    3538 +            section->option.retry=1; 
    3539 +        else if(!strcasecmp(arg, "no")) 
    3540 +            section->option.retry=0; 
    3541 +        else 
    3542 +            return "Argument should be either 'yes' or 'no'"; 
    3543 +        return NULL; /* OK */ 
    3544 +    case CMD_DEFAULT: 
    3545 +        break; 
    3546 +    case CMD_HELP: 
    3547 +        s_log(LOG_RAW, "%-15s = yes|no retry connect+exec section", 
    3548 +            "retry"); 
    3549 +        break; 
    3550 +    } 
    3551 +#endif 
    3552 + 
    3553 +    /* session */ 
    3554 +    switch(cmd) { 
    3555 +    case CMD_INIT: 
    3556 +        section->session_timeout=300; 
    3557 +        break; 
    3558 +    case CMD_EXEC: 
    3559 +        if(strcasecmp(opt, "session")) 
    3560 +            break; 
    3561 +        if(atoi(arg)>0) 
    3562 +            section->session_timeout=atoi(arg); 
    3563 +        else 
    3564 +            return "Illegal session timeout"; 
    3565 +        return NULL; /* OK */ 
    3566 +    case CMD_DEFAULT: 
    3567 +        s_log(LOG_RAW, "%-15s = %ld seconds", "session", section->session_timeout); 
    3568 +        break; 
    3569 +    case CMD_HELP: 
    3570 +        s_log(LOG_RAW, "%-15s = session cache timeout (in seconds)", "session"); 
    3571 +        break; 
    3572 +    } 
    3573 + 
    3574 +    /* sessiond */ 
    3575 +    switch(cmd) { 
    3576 +    case CMD_INIT: 
    3577 +        section->option.sessiond=0; 
    3578 +        memset(&section->sessiond_addr, 0, sizeof(SOCKADDR_LIST)); 
    3579 +        section->sessiond_addr.addr[0].in.sin_family=AF_INET; 
    3580 +        break; 
    3581 +    case CMD_EXEC: 
    3582 +        if(strcasecmp(opt, "sessiond")) 
    3583 +            break; 
    3584 +        section->option.sessiond=1; 
    3585 +#ifdef SSL_OP_NO_TICKET 
    3586 +        /* disable RFC4507 support introduced in OpenSSL 0.9.8f */ 
    3587 +        /* this prevents session callbacks from beeing executed */ 
    3588 +        section->ssl_options|=SSL_OP_NO_TICKET; 
    3589 +#endif 
    3590 +        if(!name2addrlist(&section->sessiond_addr, arg, DEFAULT_LOOPBACK)) 
    3591 +            return "Failed to resolve sessiond server address"; 
    3592 +        return NULL; /* OK */ 
    3593 +    case CMD_DEFAULT: 
    3594 +        break; 
    3595 +    case CMD_HELP: 
    3596 +        s_log(LOG_RAW, "%-15s = [host:]port use sessiond at host:port", 
    3597 +            "sessiond"); 
    3598 +        break; 
    3599 +    } 
    3600 + 
    3601 +#ifndef USE_FORK 
    3602 +    /* stack */ 
    3603 +    switch(cmd) { 
    3604 +    case CMD_INIT: 
    3605 +        section->stack_size=DEFAULT_STACK_SIZE; 
    3606 +        break; 
    3607 +    case CMD_EXEC: 
    3608 +        if(strcasecmp(opt, "stack")) 
    3609 +            break; 
    3610 +        if(atoi(arg)>0) 
    3611 +            section->stack_size=atoi(arg); 
    3612 +        else 
    3613 +            return "Illegal thread stack size"; 
    3614 +        return NULL; /* OK */ 
    3615 +    case CMD_DEFAULT: 
    3616 +        s_log(LOG_RAW, "%-15s = %d bytes", "stack", section->stack_size); 
    3617 +        break; 
    3618 +    case CMD_HELP: 
    3619 +        s_log(LOG_RAW, "%-15s = thread stack size (in bytes)", "stack"); 
    3620 +        break; 
    3621 +    } 
    3622 +#endif 
    3623 + 
    3624 +    /* sslVersion */ 
    3625 +    switch(cmd) { 
    3626 +    case CMD_INIT: 
    3627 +#ifdef USE_FIPS 
    3628 +        section->client_method=(SSL_METHOD *)TLSv1_client_method(); 
    3629 +        section->server_method=(SSL_METHOD *)TLSv1_server_method(); 
    3630 +#else 
    3631 +        section->client_method=(SSL_METHOD *)SSLv3_client_method(); 
    3632 +        section->server_method=(SSL_METHOD *)SSLv23_server_method(); 
    3633 +#endif 
    3634 +        break; 
    3635 +    case CMD_EXEC: 
    3636 +        if(strcasecmp(opt, "sslVersion")) 
    3637 +            break; 
    3638 +        if(!strcasecmp(arg, "all")) { 
    3639 +            section->client_method=(SSL_METHOD *)SSLv23_client_method(); 
    3640 +            section->server_method=(SSL_METHOD *)SSLv23_server_method(); 
    3641 +        } else if(!strcasecmp(arg, "SSLv2")) { 
    3642 +            section->client_method=(SSL_METHOD *)SSLv2_client_method(); 
    3643 +            section->server_method=(SSL_METHOD *)SSLv2_server_method(); 
    3644 +        } else if(!strcasecmp(arg, "SSLv3")) { 
    3645 +            section->client_method=(SSL_METHOD *)SSLv3_client_method(); 
    3646 +            section->server_method=(SSL_METHOD *)SSLv3_server_method(); 
    3647 +        } else if(!strcasecmp(arg, "TLSv1")) { 
    3648 +            section->client_method=(SSL_METHOD *)TLSv1_client_method(); 
    3649 +            section->server_method=(SSL_METHOD *)TLSv1_server_method(); 
    3650 +        } else 
    3651 +            return "Incorrect version of SSL protocol"; 
    3652 +        return NULL; /* OK */ 
    3653 +    case CMD_DEFAULT: 
    3654 +#ifdef USE_FIPS 
    3655 +        s_log(LOG_RAW, "%-15s = TLSv1", "sslVersion"); 
    3656 +#else 
    3657 +        s_log(LOG_RAW, "%-15s = SSLv3 for client, all for server", "sslVersion"); 
    3658 +#endif 
    3659 +        break; 
    3660 +    case CMD_HELP: 
    3661 +        s_log(LOG_RAW, "%-15s = all|SSLv2|SSLv3|TLSv1 SSL method", "sslVersion"); 
    3662 +        break; 
    3663 +    } 
    3664 + 
    3665 +    /* TIMEOUTbusy */ 
    3666 +    switch(cmd) { 
    3667 +    case CMD_INIT: 
    3668 +        section->timeout_busy=300; /* 5 minutes */ 
    3669 +        break; 
    3670 +    case CMD_EXEC: 
    3671 +        if(strcasecmp(opt, "TIMEOUTbusy")) 
    3672 +            break; 
    3673 +        if(atoi(arg)>0) 
    3674 +            section->timeout_busy=atoi(arg); 
    3675 +        else 
    3676 +            return "Illegal busy timeout"; 
    3677 +        return NULL; /* OK */ 
    3678 +    case CMD_DEFAULT: 
    3679 +        s_log(LOG_RAW, "%-15s = %d seconds", "TIMEOUTbusy", section->timeout_busy); 
    3680 +        break; 
    3681 +    case CMD_HELP: 
    3682 +        s_log(LOG_RAW, "%-15s = seconds to wait for expected data", "TIMEOUTbusy"); 
    3683 +        break; 
    3684 +    } 
    3685 + 
    3686 +    /* TIMEOUTclose */ 
    3687 +    switch(cmd) { 
    3688 +    case CMD_INIT: 
    3689 +        section->timeout_close=60; /* 1 minute */ 
    3690 +        break; 
    3691 +    case CMD_EXEC: 
    3692 +        if(strcasecmp(opt, "TIMEOUTclose")) 
    3693 +            break; 
    3694 +        if(atoi(arg)>0 || !strcmp(arg, "0")) 
    3695 +            section->timeout_close=atoi(arg); 
    3696 +        else 
    3697 +            return "Illegal close timeout"; 
    3698 +        return NULL; /* OK */ 
    3699 +    case CMD_DEFAULT: 
    3700 +        s_log(LOG_RAW, "%-15s = %d seconds", "TIMEOUTclose", section->timeout_close); 
    3701 +        break; 
    3702 +    case CMD_HELP: 
    3703 +        s_log(LOG_RAW, "%-15s = seconds to wait for close_notify" 
    3704 +            " (set to 0 for buggy MSIE)", "TIMEOUTclose"); 
    3705 +        break; 
    3706 +    } 
    3707 + 
    3708 +    /* TIMEOUTconnect */ 
    3709 +    switch(cmd) { 
    3710 +    case CMD_INIT: 
    3711 +        section->timeout_connect=10; /* 10 seconds */ 
    3712 +        break; 
    3713 +    case CMD_EXEC: 
    3714 +        if(strcasecmp(opt, "TIMEOUTconnect")) 
    3715 +            break; 
    3716 +        if(atoi(arg)>0 || !strcmp(arg, "0")) 
    3717 +            section->timeout_connect=atoi(arg); 
    3718 +        else 
    3719 +            return "Illegal connect timeout"; 
    3720 +        return NULL; /* OK */ 
    3721 +    case CMD_DEFAULT: 
    3722 +        s_log(LOG_RAW, "%-15s = %d seconds", "TIMEOUTconnect", 
    3723 +            section->timeout_connect); 
    3724 +        break; 
    3725 +    case CMD_HELP: 
    3726 +        s_log(LOG_RAW, "%-15s = seconds to connect remote host", "TIMEOUTconnect"); 
    3727 +        break; 
    3728 +    } 
    3729 + 
    3730 +    /* TIMEOUTidle */ 
    3731 +    switch(cmd) { 
    3732 +    case CMD_INIT: 
    3733 +        section->timeout_idle=43200; /* 12 hours */ 
    3734 +        break; 
    3735 +    case CMD_EXEC: 
    3736 +        if(strcasecmp(opt, "TIMEOUTidle")) 
    3737 +            break; 
    3738 +        if(atoi(arg)>0) 
    3739 +            section->timeout_idle=atoi(arg); 
    3740 +        else 
    3741 +            return "Illegal idle timeout"; 
    3742 +        return NULL; /* OK */ 
    3743 +    case CMD_DEFAULT: 
    3744 +        s_log(LOG_RAW, "%-15s = %d seconds", "TIMEOUTidle", section->timeout_idle); 
    3745 +        break; 
    3746 +    case CMD_HELP: 
    3747 +        s_log(LOG_RAW, "%-15s = seconds to keep an idle connection", "TIMEOUTidle"); 
    3748 +        break; 
    3749 +    } 
    3750 + 
    3751 +    /* transparent */ 
    3752 +#ifndef USE_WIN32 
    3753 +    switch(cmd) { 
    3754 +    case CMD_INIT: 
    3755 +        section->option.transparent=0; 
    3756 +        break; 
    3757 +    case CMD_EXEC: 
    3758 +        if(strcasecmp(opt, "transparent")) 
    3759 +            break; 
    3760 +        if(!strcasecmp(arg, "yes")) 
    3761 +            section->option.transparent=1; 
    3762 +        else if(!strcasecmp(arg, "no")) 
    3763 +            section->option.transparent=0; 
    3764 +        else 
    3765 +            return "Argument should be either 'yes' or 'no'"; 
    3766 +        return NULL; /* OK */ 
    3767 +    case CMD_DEFAULT: 
    3768 +        break; 
    3769 +    case CMD_HELP: 
    3770 +        s_log(LOG_RAW, "%-15s = yes|no transparent proxy mode", 
    3771 +            "transparent"); 
    3772 +        break; 
    3773 +    } 
    3774 +#endif 
    3775 + 
    3776 +    /* verify */ 
    3777 +    switch(cmd) { 
    3778 +    case CMD_INIT: 
    3779 +        section->verify_level=-1; 
    3780 +        section->verify_use_only_my=0; 
    3781 +        break; 
    3782 +    case CMD_EXEC: 
    3783 +        if(strcasecmp(opt, "verify")) 
    3784 +            break; 
    3785 +        section->verify_level=SSL_VERIFY_NONE; 
    3786 +        switch(atoi(arg)) { 
    3787 +        case 3: 
    3788 +            section->verify_use_only_my=1; 
    3789 +        case 2: 
    3790 +            section->verify_level|=SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 
    3791 +        case 1: 
    3792 +            section->verify_level|=SSL_VERIFY_PEER; 
    3793 +        case 0: 
    3794 +            return NULL; /* OK */ 
    3795 +        default: 
    3796 +            return "Bad verify level"; 
    3797 +        } 
    3798 +    case CMD_DEFAULT: 
    3799 +        s_log(LOG_RAW, "%-15s = none", "verify"); 
    3800 +        break; 
    3801 +    case CMD_HELP: 
    3802 +        s_log(LOG_RAW, "%-15s = level of peer certificate verification", "verify"); 
    3803 +        s_log(LOG_RAW, "%18slevel 1 - verify peer certificate if present", ""); 
    3804 +        s_log(LOG_RAW, "%18slevel 2 - require valid peer certificate always", ""); 
    3805 +        s_log(LOG_RAW, "%18slevel 3 - verify peer with locally installed certificate", 
    3806 +        ""); 
    3807 +        break; 
    3808 +    } 
    3809 + 
    3810 +    if(cmd==CMD_EXEC) 
    3811 +        return option_not_found; 
    3812 +    return NULL; /* OK */ 
    3813 +} 
    3814 + 
    3815 +static void syntax(char *confname) { 
    3816 +    s_log(LOG_RAW, " "); 
    3817 +    s_log(LOG_RAW, "Syntax:"); 
    3818 +    s_log(LOG_RAW, "stunnel " 
    3819 +#ifdef USE_WIN32 
    3820 +#ifndef _WIN32_WCE 
    3821 +        "[ [-install | -uninstall] " 
    3822 +#endif 
    3823 +        "[-quiet] " 
    3824 +#endif 
    3825 +        "[<filename>] ] " 
    3826 +#ifndef USE_WIN32 
    3827 +        "-fd <n> " 
    3828 +#endif 
    3829 +        "| -help | -version | -sockets"); 
    3830 +    s_log(LOG_RAW, "    <filename>  - use specified config file instead of %s", 
    3831 +        confname); 
    3832 +#ifdef USE_WIN32 
    3833 +#ifndef _WIN32_WCE 
    3834 +    s_log(LOG_RAW, "    -install    - install NT service"); 
    3835 +    s_log(LOG_RAW, "    -uninstall  - uninstall NT service"); 
    3836 +#endif 
    3837 +    s_log(LOG_RAW, "    -quiet      - don't display a message box on success"); 
    3838 +#else 
    3839 +    s_log(LOG_RAW, "    -fd <n>     - read the config file from a file descriptor"); 
    3840 +#endif 
    3841 +    s_log(LOG_RAW, "    -help       - get config file help"); 
    3842 +    s_log(LOG_RAW, "    -version    - display version and defaults"); 
    3843 +    s_log(LOG_RAW, "    -sockets    - display default socket options"); 
    3844 +    die(1); 
    3845 +} 
    3846 + 
    3847 +void parse_config(char *name, char *parameter) { 
    3848 +#ifdef CONFDIR 
    3849 +    char *default_config_file=CONFDIR CONFSEPARATOR "stunnel.conf"; 
    3850 +#else 
    3851 +    char *default_config_file="stunnel.conf"; 
    3852 +#endif 
    3853 +    DISK_FILE *df; 
    3854 +    char confline[CONFLINELEN], *arg, *opt, *errstr, *filename; 
    3855 +    int line_number, i; 
    3856 +#ifdef MAX_FD 
    3857 +    int sections=0; 
    3858 +#endif 
    3859 +    LOCAL_OPTIONS *section, *new_section; 
    3860 + 
    3861 +    memset(&options, 0, sizeof(GLOBAL_OPTIONS)); /* reset global options */ 
    3862 + 
    3863 +    memset(&local_options, 0, sizeof(LOCAL_OPTIONS)); /* reset local options */ 
    3864 +    local_options.next=NULL; 
    3865 +    section=&local_options; 
    3866 + 
    3867 +    global_options(CMD_INIT, NULL, NULL); 
    3868 +    service_options(CMD_INIT, section, NULL, NULL); 
    3869 +    if(!name) 
    3870 +        name=default_config_file; 
    3871 +    if(!strcasecmp(name, "-help")) { 
    3872 +        global_options(CMD_HELP, NULL, NULL); 
    3873 +        service_options(CMD_HELP, section, NULL, NULL); 
    3874 +        die(1); 
    3875 +    } 
    3876 +    if(!strcasecmp(name, "-version")) { 
    3877 +        stunnel_info(1); 
    3878 +        s_log(LOG_RAW, " "); 
    3879 +        global_options(CMD_DEFAULT, NULL, NULL); 
    3880 +        service_options(CMD_DEFAULT, section, NULL, NULL); 
    3881 +        die(1); 
    3882 +    } 
    3883 +    if(!strcasecmp(name, "-sockets")) { 
    3884 +        print_socket_options(); 
    3885 +        die(1); 
    3886 +    } 
    3887 +#ifndef USE_WIN32 
    3888 +    if(!strcasecmp(name, "-fd")) { 
    3889 +        if(!parameter) { 
    3890 +            s_log(LOG_RAW, "No file descriptor specified"); 
    3891 +            syntax(default_config_file); 
    3892 +        } 
    3893 +        for(arg=parameter, i=0; *arg; ++arg) { 
    3894 +            if(*arg<'0' || *arg>'9') { 
    3895 +                s_log(LOG_RAW, "Invalid file descriptor %s", parameter); 
    3896 +                syntax(default_config_file); 
    3897 +            } 
    3898 +            i=10*i+*arg-'0'; 
    3899 +        } 
    3900 +        df=file_fdopen(i); 
    3901 +        if(!df) { 
    3902 +            s_log(LOG_RAW, "Invalid file descriptor %s", parameter); 
    3903 +            syntax(default_config_file); 
    3904 +        } 
    3905 +        filename="descriptor"; 
    3906 +    } else 
    3907 +#endif 
    3908 +    { 
    3909 +        df=file_open(name, 0); 
    3910 +        if(!df) 
    3911 +            syntax(default_config_file); 
    3912 +        filename=name; 
    3913 +    } 
    3914 +    line_number=0; 
    3915 +    while(file_getline(df, confline, CONFLINELEN)) { 
    3916 +        ++line_number; 
    3917 +        opt=confline; 
    3918 +        while(isspace((unsigned char)*opt)) 
    3919 +            ++opt; /* remove initial whitespaces */ 
    3920 +        for(i=strlen(opt)-1; i>=0 && isspace((unsigned char)opt[i]); --i) 
    3921 +            opt[i]='\0'; /* remove trailing whitespaces */ 
    3922 +        if(opt[0]=='\0' || opt[0]=='#' || opt[0]==';') /* empty or comment */ 
    3923 +            continue; 
    3924 +        if(opt[0]=='[' && opt[strlen(opt)-1]==']') { /* new section */ 
    3925 +            section_validate(filename, line_number, section, 0); 
    3926 +            ++opt; 
    3927 +            opt[strlen(opt)-1]='\0'; 
    3928 +            new_section=calloc(1, sizeof(LOCAL_OPTIONS)); 
    3929 +            if(!new_section) { 
    3930 +                s_log(LOG_RAW, "Fatal memory allocation error"); 
    3931 +                die(2); 
    3932 +            } 
    3933 +            memcpy(new_section, &local_options, sizeof(LOCAL_OPTIONS)); 
    3934 +            new_section->servname=stralloc(opt); 
    3935 +            new_section->session=NULL; 
    3936 +            new_section->next=NULL; 
    3937 +            section->next=new_section; 
    3938 +            section=new_section; 
    3939 +#ifdef MAX_FD 
    3940 +            if(++sections>MAX_FD) 
    3941 +                config_error(filename, line_number, "Too many sections"); 
    3942 +#endif 
    3943 +            continue; 
    3944 +        } 
    3945 +        arg=strchr(confline, '='); 
    3946 +        if(!arg) 
    3947 +            config_error(filename, line_number, "No '=' found"); 
    3948 +        *arg++='\0'; /* split into option name and argument value */ 
    3949 +        for(i=strlen(opt)-1; i>=0 && isspace((unsigned char)opt[i]); --i) 
    3950 +            opt[i]='\0'; /* remove trailing whitespaces */ 
    3951 +        while(isspace((unsigned char)*arg)) 
    3952 +            ++arg; /* remove initial whitespaces */ 
    3953 +        errstr=service_options(CMD_EXEC, section, opt, arg); 
    3954 +        if(section==&local_options && errstr==option_not_found) 
    3955 +            errstr=global_options(CMD_EXEC, opt, arg); 
    3956 +        config_error(filename, line_number, errstr); 
    3957 +    } 
    3958 +    section_validate(filename, line_number, section, 1); 
    3959 +    file_close(df); 
    3960 +    if(!local_options.next) { /* inetd mode */ 
    3961 +        if (section->option.accept) { 
    3962 +            s_log(LOG_RAW, "accept option is not allowed in inetd mode"); 
    3963 +            s_log(LOG_RAW, "remove accept option or define a [section]"); 
    3964 +            die(1); 
    3965 +        } 
    3966 +        if (!section->option.remote && !section->execname) { 
    3967 +            s_log(LOG_RAW, "inetd mode must define a remote host or an executable"); 
    3968 +            die(1); 
    3969 +        } 
    3970 +    } 
    3971 +} 
    3972 + 
    3973 +static void section_validate(char *filename, int line_number, 
    3974 +        LOCAL_OPTIONS *section, int final) { 
    3975 +    if(section==&local_options) { /* global options just configured */ 
    3976 +#ifdef HAVE_OSSL_ENGINE_H 
    3977 +        close_engine(); 
    3978 +#endif 
    3979 +        ssl_configure(); /* configure global SSL settings */ 
    3980 +        if(!final) /* no need to validate defaults */ 
    3981 +            return; 
    3982 +    } 
    3983 +    if(!section->option.client) 
    3984 +        section->option.cert=1; /* Server always needs a certificate */ 
    3985 +    context_init(section); /* initialize SSL context */ 
    3986 + 
    3987 +    if(section==&local_options) { /* inetd mode */ 
    3988 +        if(section->option.accept) 
    3989 +            config_error(filename, line_number, 
    3990 +                "accept is not allowed in inetd mode"); 
    3991 +        /* TODO: some additional checks could be useful 
    3992 +        if((unsigned int)section->option.program + 
    3993 +                (unsigned int)section->option.remote != 1) 
    3994 +            config_error(filename, line_number, 
    3995 +                "Single endpoint is required in inetd mode"); 
    3996 +        */ 
    3997 +        return; 
    3998 +    } 
    3999 + 
    4000 +    /* standalone mode */ 
    4001 +#ifdef USE_WIN32 
    4002 +    if(!section->option.accept || !section->option.remote) 
    4003 +#else 
    4004 +    if((unsigned int)section->option.accept + 
    4005 +            (unsigned int)section->option.program + 
    4006 +            (unsigned int)section->option.remote != 2) 
    4007 +#endif 
    4008 +        config_error(filename, line_number, 
    4009 +            "Each service section must define exactly two endpoints"); 
    4010 +    return; /* All tests passed -- continue program execution */ 
    4011 +} 
    4012 + 
    4013 +static void config_error(char *name, int num, char *str) { 
    4014 +    if(!str) /* NULL -> no error */ 
    4015 +        return; 
    4016 +    s_log(LOG_RAW, "file %s line %d: %s", name, num, str); 
    4017 +    die(1); 
    4018 +} 
    4019 + 
    4020 +static char *stralloc(char *str) { /* Allocate static string */ 
    4021 +    char *retval; 
    4022 + 
    4023 +    retval=calloc(strlen(str)+1, 1); 
    4024 +    if(!retval) { 
    4025 +        s_log(LOG_RAW, "Fatal memory allocation error"); 
    4026 +        die(2); 
    4027 +    } 
    4028 +    strcpy(retval, str); 
    4029 +    return retval; 
    4030 +} 
    4031 + 
    4032 +#ifndef USE_WIN32 
    4033 +static char **argalloc(char *str) { /* Allocate 'exec' argumets */ 
    4034 +    int max_arg, i; 
    4035 +    char *ptr, **retval; 
    4036 + 
    4037 +    max_arg=strlen(str)/2+1; 
    4038 +    ptr=stralloc(str); 
    4039 +    retval=calloc(max_arg+1, sizeof(char *)); 
    4040 +    if(!retval) { 
    4041 +        s_log(LOG_RAW, "Fatal memory allocation error"); 
    4042 +        die(2); 
    4043 +    } 
    4044 +    i=0; 
    4045 +    while(*ptr && i<max_arg) { 
    4046 +        retval[i++]=ptr; 
    4047 +        while(*ptr && !isspace((unsigned char)*ptr)) 
    4048 +            ++ptr; 
    4049 +        while(*ptr && isspace((unsigned char)*ptr)) 
    4050 +            *ptr++='\0'; 
    4051 +    } 
    4052 +    retval[i]=NULL; /* to show that it's null-terminated */ 
    4053 +    return retval; 
    4054 +} 
    4055 +#endif 
    4056 + 
    4057 +/* Parse out the facility/debug level stuff */ 
    4058 + 
    4059 +typedef struct { 
    4060 +    char *name; 
    4061 +    int value; 
    4062 +} facilitylevel; 
    4063 + 
    4064 +static int parse_debug_level(char *arg) { 
    4065 +    char arg_copy[STRLEN]; 
    4066 +    char *string; 
    4067 +    facilitylevel *fl; 
    4068 + 
    4069 +/* Facilities only make sense on unix */ 
    4070 +#if !defined (USE_WIN32) && !defined (__vms) 
    4071 +    facilitylevel facilities[] = { 
    4072 +        {"auth", LOG_AUTH},     {"cron", LOG_CRON},     {"daemon", LOG_DAEMON}, 
    4073 +        {"kern", LOG_KERN},     {"lpr", LOG_LPR},       {"mail", LOG_MAIL}, 
    4074 +        {"news", LOG_NEWS},     {"syslog", LOG_SYSLOG}, {"user", LOG_USER}, 
    4075 +        {"uucp", LOG_UUCP},     {"local0", LOG_LOCAL0}, {"local1", LOG_LOCAL1}, 
    4076 +        {"local2", LOG_LOCAL2}, {"local3", LOG_LOCAL3}, {"local4", LOG_LOCAL4}, 
    4077 +        {"local5", LOG_LOCAL5}, {"local6", LOG_LOCAL6}, {"local7", LOG_LOCAL7}, 
    4078 + 
    4079 +        /* Some that are not on all unicies */ 
    4080 +#ifdef LOG_AUTHPRIV 
    4081 +        {"authpriv", LOG_AUTHPRIV}, 
    4082 +#endif 
    4083 +#ifdef LOG_FTP 
    4084 +        {"ftp", LOG_FTP}, 
    4085 +#endif 
    4086 +#ifdef LOG_NTP 
    4087 +        {"ntp", LOG_NTP}, 
    4088 +#endif 
    4089 +        {NULL, 0} 
    4090 +    }; 
    4091 +#endif /* USE_WIN32, __vms */ 
    4092 + 
    4093 +    facilitylevel levels[] = { 
    4094 +        {"emerg", LOG_EMERG},     {"alert", LOG_ALERT}, 
    4095 +        {"crit", LOG_CRIT},       {"err", LOG_ERR}, 
    4096 +        {"warning", LOG_WARNING}, {"notice", LOG_NOTICE}, 
    4097 +        {"info", LOG_INFO},       {"debug", LOG_DEBUG}, 
    4098 +        {NULL, -1} 
    4099 +    }; 
    4100 + 
    4101 +    safecopy(arg_copy, arg); 
    4102 +    string = arg_copy; 
    4103 + 
    4104 +/* Facilities only make sense on Unix */ 
    4105 +#if !defined (USE_WIN32) && !defined (__vms) 
    4106 +    if(strchr(string, '.')) { /* We have a facility specified */ 
    4107 +        options.facility=-1; 
    4108 +        string=strtok(arg_copy, "."); /* break it up */ 
    4109 + 
    4110 +        for(fl=facilities; fl->name; ++fl) { 
    4111 +            if(!strcasecmp(fl->name, string)) { 
    4112 +                options.facility = fl->value; 
    4113 +                break; 
    4114 +            } 
    4115 +        } 
    4116 +        if(options.facility==-1) 
    4117 +            return 0; /* FAILED */ 
    4118 +        string=strtok(NULL, ".");    /* set to the remainder */ 
    4119 +    } 
    4120 +#endif /* USE_WIN32, __vms */ 
    4121 + 
    4122 +    /* Time to check the syslog level */ 
    4123 +    if(string && strlen(string)==1 && *string>='0' && *string<='7') { 
    4124 +        options.debug_level=*string-'0'; 
    4125 +        return 1; /* OK */ 
    4126 +    } 
    4127 +    options.debug_level=8;    /* illegal level */ 
    4128 +    for(fl=levels; fl->name; ++fl) { 
    4129 +        if(!strcasecmp(fl->name, string)) { 
    4130 +            options.debug_level=fl->value; 
    4131 +            break; 
    4132 +        } 
    4133 +    } 
    4134 +    if (options.debug_level==8) 
    4135 +        return 0; /* FAILED */ 
    4136 +    return 1; /* OK */ 
    4137 +} 
    4138 + 
    4139 +/* Parse out SSL options stuff */ 
    4140 + 
    4141 +static int parse_ssl_option(char *arg) { 
    4142 +    struct { 
    4143 +        char *name; 
    4144 +        long value; 
    4145 +    } ssl_opts[] = { 
    4146 +        {"MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG}, 
    4147 +        {"NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG}, 
    4148 +        {"NETSCAPE_REUSE_CIPHER_CHANGE_BUG", 
    4149 +            SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG}, 
    4150 +        {"SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG}, 
    4151 +        {"MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER}, 
    4152 +        {"MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING}, 
    4153 +        {"SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG}, 
    4154 +        {"TLS_D5_BUG", SSL_OP_TLS_D5_BUG}, 
    4155 +        {"TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG}, 
    4156 +        {"DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS}, 
    4157 +#ifdef SSL_OP_NO_QUERY_MTU 
    4158 +        {"NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU}, 
    4159 +#endif 
    4160 +#ifdef SSL_OP_COOKIE_EXCHANGE 
    4161 +        {"COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE}, 
    4162 +#endif 
    4163 +#ifdef SSL_OP_NO_TICKET 
    4164 +        {"NO_TICKET", SSL_OP_NO_TICKET}, 
    4165 +#endif 
    4166 +        {"NO_SESSION_RESUMPTION_ON_RENEGOTIATION", 
    4167 +            SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION}, 
    4168 +#ifdef SSL_OP_NO_COMPRESSION 
    4169 +        {"NO_COMPRESSION", SSL_OP_NO_COMPRESSION}, 
    4170 +#endif 
    4171 +#ifdef SSL_OP_SINGLE_ECDH_USE 
    4172 +        {"SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE}, 
    4173 +#endif 
    4174 +        {"SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE}, 
    4175 +        {"EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA}, 
    4176 +        {"CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE}, 
    4177 +        {"TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG}, 
    4178 +        {"NO_SSLv2", SSL_OP_NO_SSLv2}, 
    4179 +        {"NO_SSLv3", SSL_OP_NO_SSLv3}, 
    4180 +        {"NO_TLSv1", SSL_OP_NO_TLSv1}, 
    4181 +        {"PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1}, 
    4182 +        {"PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2}, 
    4183 +        {"NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG}, 
    4184 +        {"NETSCAPE_DEMO_CIPHER_CHANGE_BUG", 
    4185 +            SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG}, 
    4186 +#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG 
    4187 +        {"CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG}, 
    4188 +#endif 
    4189 +        {"ALL", SSL_OP_ALL}, 
    4190 +        {NULL, 0} 
    4191 +    }, *option; 
    4192 + 
    4193 +    for(option=ssl_opts; option->name; ++option) 
    4194 +        if(!strcasecmp(option->name, arg)) 
    4195 +            return option->value; 
    4196 +    return 0; /* FAILED */ 
    4197 +} 
    4198 + 
    4199 +/* Parse out the socket options stuff */ 
    4200 + 
    4201 +static int on=1; 
    4202 + 
    4203 +#define DEF_VALS {NULL, NULL, NULL} 
    4204 +#define DEF_ACCEPT {(void *)&on, NULL, NULL} 
    4205 + 
    4206 +SOCK_OPT sock_opts[] = { 
    4207 +    {"SO_DEBUG",        SOL_SOCKET,  SO_DEBUG,        TYPE_FLAG,    DEF_VALS}, 
    4208 +    {"SO_DONTROUTE",    SOL_SOCKET,  SO_DONTROUTE,    TYPE_FLAG,    DEF_VALS}, 
    4209 +    {"SO_KEEPALIVE",    SOL_SOCKET,  SO_KEEPALIVE,    TYPE_FLAG,    DEF_VALS}, 
    4210 +    {"SO_LINGER",       SOL_SOCKET,  SO_LINGER,       TYPE_LINGER,  DEF_VALS}, 
    4211 +    {"SO_OOBINLINE",    SOL_SOCKET,  SO_OOBINLINE,    TYPE_FLAG,    DEF_VALS}, 
    4212 +    {"SO_RCVBUF",       SOL_SOCKET,  SO_RCVBUF,       TYPE_INT,     DEF_VALS}, 
    4213 +    {"SO_SNDBUF",       SOL_SOCKET,  SO_SNDBUF,       TYPE_INT,     DEF_VALS}, 
    4214 +#ifdef SO_RCVLOWAT 
    4215 +    {"SO_RCVLOWAT",     SOL_SOCKET,  SO_RCVLOWAT,     TYPE_INT,     DEF_VALS}, 
    4216 +#endif 
    4217 +#ifdef SO_SNDLOWAT 
    4218 +    {"SO_SNDLOWAT",     SOL_SOCKET,  SO_SNDLOWAT,     TYPE_INT,     DEF_VALS}, 
    4219 +#endif 
    4220 +#ifdef SO_RCVTIMEO 
    4221 +    {"SO_RCVTIMEO",     SOL_SOCKET,  SO_RCVTIMEO,     TYPE_TIMEVAL, DEF_VALS}, 
    4222 +#endif 
    4223 +#ifdef SO_SNDTIMEO 
    4224 +    {"SO_SNDTIMEO",     SOL_SOCKET,  SO_SNDTIMEO,     TYPE_TIMEVAL, DEF_VALS}, 
    4225 +#endif 
    4226 +    {"SO_REUSEADDR",    SOL_SOCKET,  SO_REUSEADDR,    TYPE_FLAG,    DEF_ACCEPT}, 
    4227 +#ifdef SO_BINDTODEVICE 
    4228 +    {"SO_BINDTODEVICE", SOL_SOCKET,  SO_BINDTODEVICE, TYPE_STRING,  DEF_VALS}, 
    4229 +#endif 
    4230 +#ifdef TCP_KEEPCNT 
    4231 +    {"TCP_KEEPCNT",     SOL_TCP,     TCP_KEEPCNT,     TYPE_INT,     DEF_VALS}, 
    4232 +#endif 
    4233 +#ifdef TCP_KEEPIDLE 
    4234 +    {"TCP_KEEPIDLE",    SOL_TCP,     TCP_KEEPIDLE,    TYPE_INT,     DEF_VALS}, 
    4235 +#endif 
    4236 +#ifdef TCP_KEEPINTVL 
    4237 +    {"TCP_KEEPINTVL",   SOL_TCP,     TCP_KEEPINTVL,   TYPE_INT,     DEF_VALS}, 
    4238 +#endif 
    4239 +#ifdef IP_TOS 
    4240 +    {"IP_TOS",          IPPROTO_IP,  IP_TOS,          TYPE_INT,     DEF_VALS}, 
    4241 +#endif 
    4242 +#ifdef IP_TTL 
    4243 +    {"IP_TTL",          IPPROTO_IP,  IP_TTL,          TYPE_INT,     DEF_VALS}, 
    4244 +#endif 
    4245 +#ifdef IP_MAXSEG 
    4246 +    {"TCP_MAXSEG",      IPPROTO_TCP, TCP_MAXSEG,      TYPE_INT,     DEF_VALS}, 
    4247 +#endif 
    4248 +    {"TCP_NODELAY",     IPPROTO_TCP, TCP_NODELAY,     TYPE_FLAG,    DEF_VALS}, 
    4249 +    {NULL,              0,           0,               TYPE_NONE,    DEF_VALS} 
    4250 +}; 
    4251 + 
    4252 +static int print_socket_options(void) { 
    4253 +    int fd; 
    4254 +    socklen_t optlen; 
    4255 +    SOCK_OPT *ptr; 
    4256 +    OPT_UNION val; 
    4257 +    char line[STRLEN]; 
    4258 + 
    4259 +    fd=socket(AF_INET, SOCK_STREAM, 0); 
    4260 + 
    4261 +    s_log(LOG_RAW, "Socket option defaults:"); 
    4262 +    s_log(LOG_RAW, "    %-16s%-10s%-10s%-10s%-10s", 
    4263 +        "Option", "Accept", "Local", "Remote", "OS default"); 
    4264 +    for(ptr=sock_opts; ptr->opt_str; ++ptr) { 
    4265 +        /* display option name */ 
    4266 +        sprintf(line, "    %-16s", ptr->opt_str); 
    4267 +        /* display stunnel default values */ 
    4268 +        print_option(line, ptr->opt_type, ptr->opt_val[0]); 
    4269 +        print_option(line, ptr->opt_type, ptr->opt_val[1]); 
    4270 +        print_option(line, ptr->opt_type, ptr->opt_val[2]); 
    4271 +        /* display OS default value */ 
    4272 +        optlen=sizeof val; 
    4273 +        if(getsockopt(fd, ptr->opt_level, 
    4274 +                ptr->opt_name, (void *)&val, &optlen)) { 
    4275 +            if(get_last_socket_error()!=ENOPROTOOPT) { 
    4276 +                s_log(LOG_RAW, "%s", line); /* dump the name and assigned values */ 
    4277 +                sockerror("getsockopt"); 
    4278 +                return 0; /* FAILED */ 
    4279 +            } 
    4280 +            safeconcat(line, "    --    "); /* write-only value */ 
    4281 +        } else 
    4282 +            print_option(line, ptr->opt_type, &val); 
    4283 +        s_log(LOG_RAW, "%s", line); 
    4284 +    } 
    4285 +    return 1; /* OK */ 
    4286 +} 
    4287 + 
    4288 +static void print_option(char *line, int type, OPT_UNION *val) { 
    4289 +    char text[STRLEN]; 
    4290 + 
    4291 +    if(!val) { 
    4292 +        safecopy(text, "    --    "); 
    4293 +    } else { 
    4294 +        switch(type) { 
    4295 +        case TYPE_FLAG: 
    4296 +        case TYPE_INT: 
    4297 +            sprintf(text, "%10d", val->i_val); 
    4298 +            break; 
    4299 +        case TYPE_LINGER: 
    4300 +            sprintf(text, "%d:%-8d", 
    4301 +                val->linger_val.l_onoff, val->linger_val.l_linger); 
    4302 +            break; 
    4303 +        case TYPE_TIMEVAL: 
    4304 +            sprintf(text, "%6d:%-3d", 
    4305 +                (int)val->timeval_val.tv_sec, (int)val->timeval_val.tv_usec); 
    4306 +            break; 
    4307 +        case TYPE_STRING: 
    4308 +            sprintf(text, "%10s", val->c_val); 
    4309 +            break; 
    4310 +        default: 
    4311 +            safecopy(text, "  Ooops?  "); /* Internal error? */ 
    4312 +        } 
    4313 +    } 
    4314 +    safeconcat(line, text); 
    4315 +} 
    4316 + 
    4317 +static int parse_socket_option(char *arg) { 
    4318 +    int socket_type; /* 0-accept, 1-local, 2-remote */ 
    4319 +    char *opt_val_str, *opt_val2_str; 
    4320 +    SOCK_OPT *ptr; 
    4321 + 
    4322 +    if(arg[1]!=':') 
    4323 +        return 0; /* FAILED */ 
    4324 +    switch(arg[0]) { 
    4325 +    case 'a': 
    4326 +        socket_type=0; break; 
    4327 +    case 'l': 
    4328 +        socket_type=1; break; 
    4329 +    case 'r': 
    4330 +        socket_type=2; break; 
    4331 +    default: 
    4332 +        return 0; /* FAILED */ 
    4333 +    } 
    4334 +    arg+=2; 
    4335 +    opt_val_str=strchr(arg, '='); 
    4336 +    if(!opt_val_str) /* No '='? */ 
    4337 +        return 0; /* FAILED */ 
    4338 +    *opt_val_str++='\0'; 
    4339 +    ptr=sock_opts; 
    4340 +    for(;;) { 
    4341 +        if(!ptr->opt_str) 
    4342 +            return 0; /* FAILED */ 
    4343 +        if(!strcmp(arg, ptr->opt_str)) 
    4344 +            break; /* option name found */ 
    4345 +        ++ptr; 
    4346 +    } 
    4347 +    ptr->opt_val[socket_type]=calloc(1, sizeof(OPT_UNION)); 
    4348 +    switch(ptr->opt_type) { 
    4349 +    case TYPE_FLAG: 
    4350 +    case TYPE_INT: 
    4351 +        ptr->opt_val[socket_type]->i_val=atoi(opt_val_str); 
    4352 +        return 1; /* OK */ 
    4353 +    case TYPE_LINGER: 
    4354 +        opt_val2_str=strchr(opt_val_str, ':'); 
    4355 +        if(opt_val2_str) { 
    4356 +            *opt_val2_str++='\0'; 
    4357 +            ptr->opt_val[socket_type]->linger_val.l_linger=atoi(opt_val2_str); 
    4358 +        } else { 
    4359 +            ptr->opt_val[socket_type]->linger_val.l_linger=0; 
    4360 +        } 
    4361 +        ptr->opt_val[socket_type]->linger_val.l_onoff=atoi(opt_val_str); 
    4362 +        return 1; /* OK */ 
    4363 +    case TYPE_TIMEVAL: 
    4364 +        opt_val2_str=strchr(opt_val_str, ':'); 
    4365 +        if(opt_val2_str) { 
    4366 +            *opt_val2_str++='\0'; 
    4367 +            ptr->opt_val[socket_type]->timeval_val.tv_usec=atoi(opt_val2_str); 
    4368 +        } else { 
    4369 +            ptr->opt_val[socket_type]->timeval_val.tv_usec=0; 
    4370 +        } 
    4371 +        ptr->opt_val[socket_type]->timeval_val.tv_sec=atoi(opt_val_str); 
    4372 +        return 1; /* OK */ 
    4373 +    case TYPE_STRING: 
    4374 +        if(strlen(opt_val_str)+1>sizeof(OPT_UNION)) 
    4375 +            return 0; /* FAILED */ 
    4376 +        strcpy(ptr->opt_val[socket_type]->c_val, opt_val_str); 
    4377 +        return 1; /* OK */ 
    4378 +    default: 
    4379 +        ; /* ANSI C compiler needs it */ 
    4380 +    } 
    4381 +    return 0; /* FAILED */ 
    4382 +} 
    4383 + 
    4384 +/* Parse out OCSP URL */ 
    4385 + 
    4386 +static char *parse_ocsp_url(LOCAL_OPTIONS *section, char *arg) { 
    4387 +    char *host, *port, *path; 
    4388 +    int ssl; 
    4389 + 
    4390 +    if(!OCSP_parse_url(arg, &host, &port, &path, &ssl)) 
    4391 +        return "Failed to parse OCSP URL"; 
    4392 +    if(ssl) 
    4393 +        return "SSL not supported for OCSP" 
    4394 +            " - additional stunnel service needs to be defined"; 
    4395 +    if(!hostport2addrlist(&section->ocsp_addr, host, port)) 
    4396 +        return "Failed to resolve OCSP server address"; 
    4397 +    section->ocsp_path=stralloc(path); 
    4398 +    if(host) 
    4399 +        OPENSSL_free(host); 
    4400 +    if(port) 
    4401 +        OPENSSL_free(port); 
    4402 +    if(path) 
    4403 +        OPENSSL_free(path); 
    4404 +    return NULL; /* OK! */ 
    4405 +} 
    4406 + 
    4407 +/* Parse out OCSP flags stuff */ 
    4408 + 
    4409 +static unsigned long parse_ocsp_flag(char *arg) { 
    4410 +    struct { 
    4411 +        char *name; 
    4412 +        unsigned long value; 
    4413 +    } ocsp_opts[] = { 
    4414 +        {"NOCERTS", OCSP_NOCERTS}, 
    4415 +        {"NOINTERN", OCSP_NOINTERN}, 
    4416 +        {"NOSIGS", OCSP_NOSIGS}, 
    4417 +        {"NOCHAIN", OCSP_NOCHAIN}, 
    4418 +        {"NOVERIFY", OCSP_NOVERIFY}, 
    4419 +        {"NOEXPLICIT", OCSP_NOEXPLICIT}, 
    4420 +        {"NOCASIGN", OCSP_NOCASIGN}, 
    4421 +        {"NODELEGATED", OCSP_NODELEGATED}, 
    4422 +        {"NOCHECKS", OCSP_NOCHECKS}, 
    4423 +        {"TRUSTOTHER", OCSP_TRUSTOTHER}, 
    4424 +        {"RESPID_KEY", OCSP_RESPID_KEY}, 
    4425 +        {"NOTIME", OCSP_NOTIME}, 
    4426 +        {NULL, 0} 
    4427 +    }, *option; 
    4428 + 
    4429 +    for(option=ocsp_opts; option->name; ++option) 
    4430 +        if(!strcasecmp(option->name, arg)) 
    4431 +            return option->value; 
    4432 +    return 0; /* FAILED */ 
    4433 +} 
    4434 + 
    4435 +/* End of options.c */ 
     229     case CMD_INIT: 
    4436230--- a/src/prototypes.h 
    4437231+++ b/src/prototypes.h 
    4438 @@ -231,6 +231,7 @@ typedef struct local_options { 
     232@@ -177,6 +177,7 @@ typedef struct service_options_struct { 
    4439233         unsigned int remote:1; 
    4440234         unsigned int retry:1; /* loop remote+program */ 
    4441235         unsigned int sessiond:1; 
    4442 +                               unsigned int xforwardedfor:1; 
     236+        unsigned int xforwardedfor:1; 
     237         unsigned int program:1; 
    4443238 #ifndef USE_WIN32 
    4444          unsigned int program:1; 
    4445239         unsigned int pty:1; 
    4446 @@ -334,6 +335,8 @@ typedef struct { 
    4447      FD *ssl_rfd, *ssl_wfd; /* Read and write SSL descriptors */ 
    4448      int sock_bytes, ssl_bytes; /* Bytes written to socket and ssl */ 
    4449      s_poll_set fds; /* File descriptors */ 
    4450 +               int buffsize;  /* current buffer size, may be lower than BUFFSIZE */ 
    4451 +               int crlf_seen; /* the number of successive CRLF seen */ 
     240@@ -351,6 +352,8 @@ typedef struct { 
     241     FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */ 
     242     int sock_bytes, ssl_bytes; /* bytes written to socket and ssl */ 
     243     s_poll_set fds; /* file descriptors */ 
     244+    int buffsize;  /* current buffer size, may be lower than BUFFSIZE */ 
     245+    int crlf_seen; /* the number of successive CRLF seen */ 
    4452246 } CLI; 
    4453247  
    4454  extern int max_clients; 
    4455 --- /dev/null 
    4456 +++ b/src/prototypes.h.orig 
    4457 @@ -0,0 +1,470 @@ 
    4458 +/* 
    4459 + *   stunnel       Universal SSL tunnel 
    4460 + *   Copyright (C) 1998-2009 Michal Trojnara <Michal.Trojnara@mirt.net> 
    4461 + * 
    4462 + *   This program is free software; you can redistribute it and/or modify it 
    4463 + *   under the terms of the GNU General Public License as published by the 
    4464 + *   Free Software Foundation; either version 2 of the License, or (at your 
    4465 + *   option) any later version. 
    4466 + *  
    4467 + *   This program is distributed in the hope that it will be useful, 
    4468 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
    4469 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    4470 + *   See the GNU General Public License for more details. 
    4471 + *  
    4472 + *   You should have received a copy of the GNU General Public License along 
    4473 + *   with this program; if not, see <http://www.gnu.org/licenses>. 
    4474 + *  
    4475 + *   Linking stunnel statically or dynamically with other modules is making 
    4476 + *   a combined work based on stunnel. Thus, the terms and conditions of 
    4477 + *   the GNU General Public License cover the whole combination. 
    4478 + *  
    4479 + *   In addition, as a special exception, the copyright holder of stunnel 
    4480 + *   gives you permission to combine stunnel with free software programs or 
    4481 + *   libraries that are released under the GNU LGPL and with code included 
    4482 + *   in the standard release of OpenSSL under the OpenSSL License (or 
    4483 + *   modified versions of such code, with unchanged license). You may copy 
    4484 + *   and distribute such a system following the terms of the GNU GPL for 
    4485 + *   stunnel and the licenses of the other code concerned. 
    4486 + *  
    4487 + *   Note that people who make modified versions of stunnel are not obligated 
    4488 + *   to grant this special exception for their modified versions; it is their 
    4489 + *   choice whether to do so. The GNU General Public License gives permission 
    4490 + *   to release a modified version without this exception; this exception 
    4491 + *   also makes it possible to release a modified version which carries 
    4492 + *   forward this exception. 
    4493 + */ 
    4494 + 
    4495 +#ifndef PROTOTYPES_H 
    4496 +#define PROTOTYPES_H 
    4497 + 
    4498 +#include "common.h" 
    4499 + 
    4500 +/**************************************** Network data structure */ 
    4501 + 
    4502 +#define MAX_HOSTS 16 
    4503 + 
    4504 +typedef union sockaddr_union { 
    4505 +    struct sockaddr sa; 
    4506 +    struct sockaddr_in in; 
    4507 +#if defined(USE_IPv6) 
    4508 +    struct sockaddr_in6 in6; 
    4509 +#endif 
    4510 +} SOCKADDR_UNION; 
    4511 + 
    4512 +typedef struct sockaddr_list {      /* list of addresses */ 
    4513 +    SOCKADDR_UNION addr[MAX_HOSTS]; /* the list of addresses */ 
    4514 +    u16 cur;                        /* current address for round-robin */ 
    4515 +    u16 num;                        /* how many addresses are used */ 
    4516 +} SOCKADDR_LIST; 
    4517 + 
    4518 +#ifdef __INNOTEK_LIBC__ 
    4519 +#define socklen_t    __socklen_t 
    4520 +#define strcasecmp   stricmp 
    4521 +#define strncasecmp  strnicmp 
    4522 +#define NI_NUMERICHOST 1 
    4523 +#define NI_NUMERICSERV 2 
    4524 +#endif 
    4525 + 
    4526 + 
    4527 +/**************************************** Prototypes for stunnel.c */ 
    4528 + 
    4529 +extern volatile int num_clients; 
    4530 + 
    4531 +void main_initialize(char *, char *); 
    4532 +void main_execute(void); 
    4533 +#if !defined (USE_WIN32) && !defined (__vms) && !defined(USE_OS2) 
    4534 +void drop_privileges(void); 
    4535 +#endif 
    4536 +void stunnel_info(int); 
    4537 +void die(int); 
    4538 + 
    4539 +/**************************************** Prototypes for log.c */ 
    4540 + 
    4541 +void log_open(void); 
    4542 +void log_close(void); 
    4543 +void log_flush(void); 
    4544 +void s_log(int, const char *, ...) 
    4545 +#ifdef __GNUC__ 
    4546 +    __attribute__ ((format (printf, 2, 3))); 
    4547 +#else 
    4548 +    ; 
    4549 +#endif 
    4550 +void ioerror(const char *); 
    4551 +void sockerror(const char *); 
    4552 +void log_error(int, int, const char *); 
    4553 +char *my_strerror(int); 
    4554 + 
    4555 +/**************************************** Prototypes for pty.c */ 
    4556 +/* Based on Public Domain code by Tatu Ylonen <ylo@cs.hut.fi>  */ 
    4557 + 
    4558 +int pty_allocate(int *, int *, char *, int); 
    4559 +#if 0 
    4560 +void pty_release(char *); 
    4561 +void pty_make_controlling_tty(int *, char *); 
    4562 +#endif 
    4563 + 
    4564 +/**************************************** Prototypes for ssl.c */ 
    4565 + 
    4566 +typedef enum { 
    4567 +    COMP_NONE, COMP_ZLIB, COMP_RLE 
    4568 +} COMP_TYPE; 
    4569 + 
    4570 +extern int cli_index, opt_index;; 
    4571 + 
    4572 +void ssl_init(void); 
    4573 +void ssl_configure(void); 
    4574 +#ifdef HAVE_OSSL_ENGINE_H 
    4575 +void open_engine(const char *); 
    4576 +void ctrl_engine(const char *, const char *); 
    4577 +void close_engine(void); 
    4578 +ENGINE *get_engine(int); 
    4579 +#endif 
    4580 + 
    4581 +/**************************************** Prototypes for options.c */ 
    4582 + 
    4583 +typedef struct { 
    4584 +        /* some data for SSL initialization in ssl.c */ 
    4585 +    COMP_TYPE compression;                               /* compression type */ 
    4586 +    char *egd_sock;                       /* entropy gathering daemon socket */ 
    4587 +    char *rand_file;                                /* file with random data */ 
    4588 +    int random_bytes;                       /* how many random bytes to read */ 
    4589 + 
    4590 +        /* some global data for stunnel.c */ 
    4591 +#ifndef USE_WIN32 
    4592 +#ifdef HAVE_CHROOT 
    4593 +    char *chroot_dir; 
    4594 +#endif 
    4595 +    unsigned long dpid; 
    4596 +    char *pidfile; 
    4597 +    int uid, gid; 
    4598 +#endif 
    4599 + 
    4600 +        /* Win32 specific data for gui.c */ 
    4601 +#if defined(USE_WIN32) && !defined(_WIN32_WCE) 
    4602 +    char *win32_service; 
    4603 +#endif 
    4604 + 
    4605 +        /* logging-support data for log.c */ 
    4606 +    int debug_level;                              /* debug level for logging */ 
    4607 +#ifndef USE_WIN32 
    4608 +    int facility;                               /* debug facility for syslog */ 
    4609 +#endif 
    4610 +    char *output_file; 
    4611 + 
    4612 +        /* on/off switches */ 
    4613 +    struct { 
    4614 +        unsigned int rand_write:1;                    /* overwrite rand_file */ 
    4615 +#ifdef USE_WIN32 
    4616 +        unsigned int taskbar:1;                   /* enable the taskbar icon */ 
    4617 +#else /* !USE_WIN32 */ 
    4618 +        unsigned int foreground:1; 
    4619 +        unsigned int syslog:1; 
    4620 +#endif 
    4621 +#ifdef USE_FIPS 
    4622 +        unsigned int fips:1;                       /* enable FIPS 140-2 mode */ 
    4623 +#endif 
    4624 +    } option; 
    4625 +} GLOBAL_OPTIONS; 
    4626 + 
    4627 +extern GLOBAL_OPTIONS options; 
    4628 + 
    4629 +typedef struct local_options { 
    4630 +    SSL_CTX *ctx;                                            /*  SSL context */ 
    4631 +    X509_STORE *revocation_store;             /* cert store for CRL checking */ 
    4632 +#ifdef HAVE_OSSL_ENGINE_H 
    4633 +    ENGINE *engine;                        /* engine to read the private key */ 
    4634 +#endif 
    4635 +    struct local_options *next;            /* next node in the services list */ 
    4636 +    char *servname;        /* service name for logging & permission checking */ 
    4637 +    SSL_SESSION *session;                           /* jecently used session */ 
    4638 +    char local_address[IPLEN];             /* dotted-decimal address to bind */ 
    4639 +#ifndef USE_FORK 
    4640 +    int stack_size;                            /* stack size for this thread */ 
    4641 +#endif 
    4642 + 
    4643 +        /* service-specific data for ctx.c */ 
    4644 +    char *ca_dir;                              /* directory for hashed certs */ 
    4645 +    char *ca_file;                       /* file containing bunches of certs */ 
    4646 +    char *crl_dir;                              /* directory for hashed CRLs */ 
    4647 +    char *crl_file;                       /* file containing bunches of CRLs */ 
    4648 +    char *cipher_list; 
    4649 +    char *cert;                                             /* cert filename */ 
    4650 +    char *key;                               /* pem (priv key/cert) filename */ 
    4651 +    long session_timeout; 
    4652 +    int verify_level; 
    4653 +    int verify_use_only_my; 
    4654 +    long ssl_options; 
    4655 +#if SSLEAY_VERSION_NUMBER >= 0x00907000L 
    4656 +    SOCKADDR_LIST ocsp_addr; 
    4657 +    char *ocsp_path; 
    4658 +    unsigned long ocsp_flags; 
    4659 +#endif /* OpenSSL-0.9.7 */ 
    4660 +    SSL_METHOD *client_method, *server_method; 
    4661 +    SOCKADDR_LIST sessiond_addr; 
    4662 + 
    4663 +        /* service-specific data for client.c */ 
    4664 +    int fd;        /* file descriptor accepting connections for this service */ 
    4665 +    char *execname, **execargs; /* program name and arguments for local mode */ 
    4666 +    SOCKADDR_LIST local_addr, remote_addr, source_addr; 
    4667 +    char *username; 
    4668 +    char *remote_address; 
    4669 +    int timeout_busy; /* maximum waiting for data time */ 
    4670 +    int timeout_close; /* maximum close_notify time */ 
    4671 +    int timeout_connect; /* maximum connect() time */ 
    4672 +    int timeout_idle; /* maximum idle connection time */ 
    4673 +    enum {FAILOVER_RR, FAILOVER_PRIO} failover; /* failover strategy */ 
    4674 + 
    4675 +        /* protocol name for protocol.c */ 
    4676 +    char *protocol; 
    4677 +    char *protocol_host; 
    4678 +    char *protocol_username; 
    4679 +    char *protocol_password; 
    4680 +    char *protocol_authentication; 
    4681 + 
    4682 +        /* on/off switches */ 
    4683 +    struct { 
    4684 +        unsigned int cert:1; 
    4685 +        unsigned int client:1; 
    4686 +        unsigned int delayed_lookup:1; 
    4687 +        unsigned int accept:1; 
    4688 +        unsigned int remote:1; 
    4689 +        unsigned int retry:1; /* loop remote+program */ 
    4690 +        unsigned int sessiond:1; 
    4691 +#ifndef USE_WIN32 
    4692 +        unsigned int program:1; 
    4693 +        unsigned int pty:1; 
    4694 +        unsigned int transparent:1; 
    4695 +#endif 
    4696 +#if SSLEAY_VERSION_NUMBER >= 0x00907000L 
    4697 +        unsigned int ocsp:1; 
    4698 +#endif 
    4699 +    } option; 
    4700 +} LOCAL_OPTIONS; 
    4701 + 
    4702 +extern LOCAL_OPTIONS local_options; 
    4703 + 
    4704 +typedef enum { 
    4705 +    TYPE_NONE, TYPE_FLAG, TYPE_INT, TYPE_LINGER, TYPE_TIMEVAL, TYPE_STRING 
    4706 +} VAL_TYPE; 
    4707 + 
    4708 +typedef union { 
    4709 +    int            i_val; 
    4710 +    long           l_val; 
    4711 +    char           c_val[16]; 
    4712 +    struct linger  linger_val; 
    4713 +    struct timeval timeval_val; 
    4714 +} OPT_UNION; 
    4715 + 
    4716 +typedef struct { 
    4717 +    char *opt_str; 
    4718 +    int  opt_level; 
    4719 +    int  opt_name; 
    4720 +    VAL_TYPE opt_type; 
    4721 +    OPT_UNION *opt_val[3]; 
    4722 +} SOCK_OPT; 
    4723 + 
    4724 +void parse_config(char *, char *); 
    4725 + 
    4726 +/**************************************** Prototypes for ctx.c */ 
    4727 + 
    4728 +void context_init(LOCAL_OPTIONS *); 
    4729 +void sslerror(char *); 
    4730 + 
    4731 +/**************************************** Prototypes for verify.c */ 
    4732 + 
    4733 +void verify_init(LOCAL_OPTIONS *); 
    4734 + 
    4735 +/**************************************** Prototypes for network.c */ 
    4736 + 
    4737 +#ifdef USE_POLL 
    4738 +#define MAX_FD 256 
    4739 +#endif 
    4740 + 
    4741 +typedef struct { 
    4742 +#ifdef USE_POLL 
    4743 +    struct pollfd ufds[MAX_FD]; 
    4744 +    unsigned int nfds; 
    4745 +#else 
    4746 +    fd_set irfds, iwfds, orfds, owfds; 
    4747 +    int max; 
    4748 +#endif 
    4749 +} s_poll_set; 
    4750 + 
    4751 +void s_poll_init(s_poll_set *); 
    4752 +void s_poll_add(s_poll_set *, int, int, int); 
    4753 +int s_poll_canread(s_poll_set *, int); 
    4754 +int s_poll_canwrite(s_poll_set *, int); 
    4755 +int s_poll_wait(s_poll_set *, int, int); 
    4756 + 
    4757 +#ifndef USE_WIN32 
    4758 +int signal_pipe_init(void); 
    4759 +void child_status(void);  /* dead libwrap or 'exec' process detected */ 
    4760 +#endif 
    4761 +int set_socket_options(int, int); 
    4762 +int alloc_fd(int); 
    4763 +void setnonblock(int, unsigned long); 
    4764 + 
    4765 +/**************************************** Prototypes for client.c */ 
    4766 + 
    4767 +typedef struct { 
    4768 +    int fd; /* File descriptor */ 
    4769 +    int rd; /* Open for read */ 
    4770 +    int wr; /* Open for write */ 
    4771 +    int is_socket; /* File descriptor is a socket */ 
    4772 +} FD; 
    4773 + 
    4774 +typedef struct { 
    4775 +    LOCAL_OPTIONS *opt; 
    4776 +    char accepted_address[IPLEN]; /* text */ 
    4777 +    SOCKADDR_LIST peer_addr; /* Peer address */ 
    4778 +    FD local_rfd, local_wfd; /* Read and write local descriptors */ 
    4779 +    FD remote_fd; /* Remote file descriptor */ 
    4780 +    SSL *ssl; /* SSL Connection */ 
    4781 +    SOCKADDR_LIST bind_addr; 
    4782 +        /* IP for explicit local bind or transparent proxy */ 
    4783 +    unsigned long pid; /* PID of local process */ 
    4784 +    int fd; /* Temporary file descriptor */ 
    4785 +    jmp_buf err; 
    4786 + 
    4787 +    char sock_buff[BUFFSIZE]; /* Socket read buffer */ 
    4788 +    char ssl_buff[BUFFSIZE]; /* SSL read buffer */ 
    4789 +    int sock_ptr, ssl_ptr; /* Index of first unused byte in buffer */ 
    4790 +    FD *sock_rfd, *sock_wfd; /* Read and write socket descriptors */ 
    4791 +    FD *ssl_rfd, *ssl_wfd; /* Read and write SSL descriptors */ 
    4792 +    int sock_bytes, ssl_bytes; /* Bytes written to socket and ssl */ 
    4793 +    s_poll_set fds; /* File descriptors */ 
    4794 +} CLI; 
    4795 + 
    4796 +extern int max_clients; 
    4797 +#ifndef USE_WIN32 
    4798 +extern int max_fds; 
    4799 +#endif 
    4800 + 
    4801 +CLI *alloc_client_session(LOCAL_OPTIONS *, int, int); 
    4802 +void *client(void *); 
    4803 + 
    4804 +/**************************************** Prototypes for network.c */ 
    4805 + 
    4806 +int connect_blocking(CLI *, SOCKADDR_UNION *, socklen_t); 
    4807 +void write_blocking(CLI *, int fd, void *, int); 
    4808 +void read_blocking(CLI *, int fd, void *, int); 
    4809 +void fdputline(CLI *, int, const char *); 
    4810 +void fdgetline(CLI *, int, char *); 
    4811 +/* descriptor versions of fprintf/fscanf */ 
    4812 +int fdprintf(CLI *, int, const char *, ...) 
    4813 +#ifdef __GNUC__ 
    4814 +       __attribute__ ((format (printf, 3, 4))); 
    4815 +#else 
    4816 +       ; 
    4817 +#endif 
    4818 +int fdscanf(CLI *, int, const char *, char *) 
    4819 +#ifdef __GNUC__ 
    4820 +       __attribute__ ((format (scanf, 3, 0))); 
    4821 +#else 
    4822 +       ; 
    4823 +#endif 
    4824 + 
    4825 +/**************************************** Prototype for protocol.c */ 
    4826 + 
    4827 +void negotiate(CLI *c); 
    4828 + 
    4829 +/**************************************** Prototypes for resolver.c */ 
    4830 + 
    4831 +int name2addrlist(SOCKADDR_LIST *, char *, char *); 
    4832 +int hostport2addrlist(SOCKADDR_LIST *, char *, char *); 
    4833 +char *s_ntop(char *, SOCKADDR_UNION *); 
    4834 + 
    4835 +/**************************************** Prototypes for sthreads.c */ 
    4836 + 
    4837 +typedef enum { 
    4838 +    CRIT_KEYGEN, CRIT_INET, CRIT_CLIENTS, CRIT_WIN_LOG, CRIT_SESSION, 
    4839 +    CRIT_LIBWRAP, CRIT_SSL, CRIT_SECTIONS 
    4840 +} SECTION_CODE; 
    4841 + 
    4842 +void enter_critical_section(SECTION_CODE); 
    4843 +void leave_critical_section(SECTION_CODE); 
    4844 +void sthreads_init(void); 
    4845 +unsigned long stunnel_process_id(void); 
    4846 +unsigned long stunnel_thread_id(void); 
    4847 +int create_client(int, int, CLI *, void *(*)(void *)); 
    4848 +#ifdef USE_UCONTEXT 
    4849 +typedef struct CONTEXT_STRUCTURE { 
    4850 +    char *stack; /* CPU stack for this thread */ 
    4851 +    unsigned long id; 
    4852 +    ucontext_t ctx; 
    4853 +    s_poll_set *fds; 
    4854 +    int ready; /* number of ready file descriptors */ 
    4855 +    time_t finish; /* when to finish poll() for this context */ 
    4856 +    struct CONTEXT_STRUCTURE *next; /* next context on a list */ 
    4857 +} CONTEXT; 
    4858 +extern CONTEXT *ready_head, *ready_tail; 
    4859 +extern CONTEXT *waiting_head, *waiting_tail; 
    4860 +#endif 
    4861 +#ifdef _WIN32_WCE 
    4862 +int _beginthread(void (*)(void *), int, void *); 
    4863 +void _endthread(void); 
    4864 +#endif 
    4865 +#ifdef DEBUG_STACK_SIZE 
    4866 +void stack_info(int); 
    4867 +#endif 
    4868 + 
    4869 +/**************************************** Prototypes for gui.c */ 
    4870 + 
    4871 +typedef struct { 
    4872 +    LOCAL_OPTIONS *section; 
    4873 +    char pass[PEM_BUFSIZE]; 
    4874 +} UI_DATA; 
    4875 + 
    4876 +#ifdef USE_WIN32 
    4877 +void win_log(char *); 
    4878 +void exit_win32(int); 
    4879 +int passwd_cb(char *, int, int, void *); 
    4880 +#ifdef HAVE_OSSL_ENGINE_H 
    4881 +int pin_cb(UI *, UI_STRING *); 
    4882 +#endif 
    4883 + 
    4884 +#ifndef _WIN32_WCE 
    4885 +typedef int (CALLBACK * GETADDRINFO) (const char *, 
    4886 +    const char *, const struct addrinfo *, struct addrinfo **); 
    4887 +typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo FAR *); 
    4888 +typedef int (CALLBACK * GETNAMEINFO) (const struct sockaddr *, socklen_t, 
    4889 +    char *, size_t, char *, size_t, int); 
    4890 +extern GETADDRINFO s_getaddrinfo; 
    4891 +extern FREEADDRINFO s_freeaddrinfo; 
    4892 +extern GETNAMEINFO s_getnameinfo; 
    4893 +#endif /* ! _WIN32_WCE */ 
    4894 +#endif /* USE_WIN32 */ 
    4895 + 
    4896 +/**************************************** Prototypes for file.c */ 
    4897 + 
    4898 +typedef struct disk_file { 
    4899 +#ifdef USE_WIN32 
    4900 +    HANDLE fh; 
    4901 +#else 
    4902 +    int fd; 
    4903 +#endif 
    4904 +    /* the inteface is prepared to easily implement buffering if needed */ 
    4905 +} DISK_FILE; 
    4906 + 
    4907 +#ifndef USE_WIN32 
    4908 +DISK_FILE *file_fdopen(int); 
    4909 +#endif 
    4910 +DISK_FILE *file_open(char *, int); 
    4911 +void file_close(DISK_FILE *); 
    4912 +int file_getline(DISK_FILE *, char *, int); 
    4913 +int file_putline(DISK_FILE *, char *); 
    4914 + 
    4915 +#ifdef USE_WIN32 
    4916 +LPTSTR str2tstr(const LPSTR); 
    4917 +LPSTR tstr2str(const LPTSTR); 
    4918 +#endif 
    4919 + 
    4920 +/**************************************** Prototypes for libwrap.c */ 
    4921 + 
    4922 +void libwrap_init(int); 
    4923 +void auth_libwrap(CLI *); 
    4924 + 
    4925 +#endif /* defined PROTOTYPES_H */ 
    4926 + 
    4927 +/* End of prototypes.h */ 
     248 extern int max_fds, max_clients; 
Note: See TracChangeset for help on using the changeset viewer.