1313 *)  
1414(*  Copyright (C) 2007 XenSource Inc *) 
1515
16+ module  D = Debug. Make (struct  let  name= " stunnel" end )
17+ open  D 
18+ 
1619open  Printf 
1720open  Pervasiveext 
1821open  Xstringext 
@@ -33,6 +36,11 @@ let stunnel_logger = ref ignore
3336
3437let  timeoutidle =  ref  None 
3538
39+ let  legacy_protocol_and_ciphersuites_allowed =  ref  true 
40+ 
41+ let  is_legacy_protocol_and_ciphersuites_allowed  ()  = 
42+ 	! legacy_protocol_and_ciphersuites_allowed
43+ 
3644let  init_stunnel_path  ()  = 
3745	try  cached_stunnel_path :=  Some  (Unix. getenv " XE_STUNNEL" 
3846	with  Not_found  -> 
@@ -116,32 +124,56 @@ type t = { mutable pid: pid; fd: Unix.file_descr; host: string; port: int;
116124	   unique_id : int  option ; 
117125	   mutable  logfile : string ; 
118126	   verified : bool ; 
127+ 	   legacy : bool ; 
119128	 }
120129
121- let  config_file  verify_cert  extended_diagnosis  host  port  =  
122- 	let  lines =  [" client=yes" " foreground=yes" " socket = r:TCP_NODELAY=1" " socket = r:SO_KEEPALIVE=1" " socket = a:SO_KEEPALIVE=1" 
123- 							 (match  ! timeoutidle with  None  ->  " " |  Some  x  ->  Printf. sprintf " TIMEOUTidle = %d" 
124- 							 Printf. sprintf " connect=%s:%d" @ 
125-     (if  extended_diagnosis then 
126-        [" debug=4" 
127-      else 
128-        [] ) @ 
129-     (if  verify_cert then 
130-        [" verify=2" 
131-         sprintf " CApath=%s" 
132-         sprintf " CRLpath=%s" 
133-      else 
134-        [] )
130+ let  config_file  verify_cert  extended_diagnosis  host  port  legacy  = 
131+ 
132+     let  good_ciphers =  " !EXPORT:TLSv1.2" in 
133+     let  back_compat_ciphers =  " RSA+AES256-SHA:RSA+AES128-SHA:RSA+RC4-SHA:RSA+RC4-MD5:RSA+DES-CBC3-SHA" in 
134+ 
135+ 	let  lines =  [
136+ 		" client=yes" " foreground=yes" " socket = r:TCP_NODELAY=1" " socket = r:SO_KEEPALIVE=1" " socket = a:SO_KEEPALIVE=1" 
137+ 		(match  ! timeoutidle with  None  ->  " " |  Some  x  ->  Printf. sprintf " TIMEOUTidle = %d" 
138+ 		Printf. sprintf " connect=%s:%d" 
139+ 		" fips = no" (*  stunnel fips-mode stops us using sslVersion other than TLSv1 which means 1.0 only. *) 
140+ 	] @ 	(if  extended_diagnosis then 
141+ 			[" debug=4" 
142+ 		else 
143+ 			[] 
144+ 	) @  (
145+ 		if  verify_cert then 
146+ 			[" verify=2" 
147+ 			sprintf " CApath=%s" 
148+ 			sprintf " CRLpath=%s" 
149+ 		else 
150+ 			[] 
151+ 	) @  (
152+ 		if  legacy then  [
153+ 			" sslVersion = all" 
154+ 			" options = NO_SSLv2" 
155+ 			" options = NO_SSLv3" 
156+ 			" ciphers = " ^  good_ciphers ^  " :" ^  back_compat_ciphers;
157+ 		] else  [
158+ 			" sslVersion = TLSv1.2" 
159+ 			" ciphers = " ^  good_ciphers;
160+ 		]
161+ 	)
135162  in 
136163    String. concat " " List. map (fun  x  -> x ^  " \n " 
137164
165+ let  set_legacy_protocol_and_ciphersuites_allowed  b  = 
166+ 	legacy_protocol_and_ciphersuites_allowed :=  b;
167+ 	info " legacy-config %B; example: %s" 
168+ 		(String. escaped (config_file false  false  " dummyhost" 443  b))
169+ 
138170let  ignore_exn  f  x  =  try  f x with  _  ->  () 
139171
140- let  rec  disconnect  ?(wait  = true )  ?(force  = false )  x  =   
172+ let  rec  disconnect  ?(wait  = true )  ?(force  = false )  x  = 
141173  List. iter (ignore_exn Unix. close) [ x.fd ];
142174
143175  let  do_disc  waiter  pid  = 
144-     let  res =   
176+     let  res = 
145177      try  waiter () 
146178      with  Unix. Unix_error  (Unix. ECHILD, _ , _ ) ->  pid, Unix. WEXITED  0  in 
147179    match  res with 
@@ -151,18 +183,24 @@ let rec disconnect ?(wait = true) ?(force = false) x =
151183        disconnect ~wait: wait ~force: force x
152184    |  _  -> () 
153185  in 
186+   let  verbose =  x.legacy &&  not  (! legacy_protocol_and_ciphersuites_allowed) in 
154187  match  x.pid with 
155-     |  FEFork  pid  -> do_disc
156-         (fun  ()  -> 
157-            (if  wait then  Forkhelpers. waitpid 
158-             else  Forkhelpers. waitpid_nohang) pid)
159-         (Forkhelpers. getpid pid)
160-     |  StdFork  pid  -> do_disc
161-         (fun  ()  -> 
162-            (if  wait then  Unix. waitpid []  
163-             else  Unix. waitpid [Unix. WNOHANG ]) pid)
164-         pid
165-     |  Nopid  -> () 
188+     |  FEFork  fpid  ->
189+         let  pid_int =  Forkhelpers. getpid fpid in 
190+         if  verbose then  info " Disconnecting FEFork %d" 
191+         do_disc
192+           (fun  ()  ->
193+              (if  wait then  Forkhelpers. waitpid 
194+               else  Forkhelpers. waitpid_nohang) fpid)
195+           pid_int
196+     |  StdFork  pid  ->
197+         if  verbose then  info " Disconnecting StdFork %d" 
198+         do_disc
199+           (fun  ()  ->
200+              (if  wait then  Unix. waitpid [] 
201+               else  Unix. waitpid [Unix. WNOHANG ]) pid)
202+           pid
203+     |  Nopid  -> if  verbose then  info " Disconnecting Nopid" 
166204
167205(*  With some probability, stunnel fails during its startup code before it reads
168206   the config data from us. Therefore we get a SIGPIPE writing the config data. 
@@ -192,10 +230,13 @@ let attempt_one_connect ?unique_id ?(use_fork_exec_helper = true)
192230      [" -fd" if  use_fork_exec_helper then  config_out_uuid else  config_out_fd] 
193231    end  in  
194232  let  data_out,data_in =  Unix. socketpair Unix. PF_UNIX  Unix. SOCK_STREAM  0  in  
233+   (*  Dereference just once to ensure we are consistent in t and config_file *)  
234+   let  legacy =  ! legacy_protocol_and_ciphersuites_allowed in  
195235  let  t =   
196236    { pid =  Nopid ; fd =  data_out; host =  host; port =  port;  
197237      connected_time =  Unix. gettimeofday () ; unique_id =  unique_id;  
198-       logfile =  " " =  verify_cert } in  
238+       logfile =  " " =  verify_cert; 
239+ 	  legacy =  legacy } in  
199240  let  result =  Forkhelpers. with_logfile_fd " stunnel"  
200241    ~delete: (not  extended_diagnosis) 
201242    (fun  logfd  -> 
@@ -221,7 +262,7 @@ let attempt_one_connect ?unique_id ?(use_fork_exec_helper = true)
221262	       (fun  ()  -> 
222263            match  config_in with  
223264            |  Some  fd  -> begin  
224- 	              let  config =  config_file verify_cert extended_diagnosis host port in  
265+ 	              let  config =  config_file verify_cert extended_diagnosis host port legacy  in  
225266	              (*  Catch the occasional initialisation failure of stunnel: *)  
226267	              try  
227268	                let  n =  Unix. write fd config 0  (String. length config) in  
0 commit comments