sshserver.pl 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  1. #!/usr/bin/env perl
  2. #***************************************************************************
  3. # _ _ ____ _
  4. # Project ___| | | | _ \| |
  5. # / __| | | | |_) | |
  6. # | (__| |_| | _ <| |___
  7. # \___|\___/|_| \_\_____|
  8. #
  9. # Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  10. #
  11. # This software is licensed as described in the file COPYING, which
  12. # you should have received as part of this distribution. The terms
  13. # are also available at https://curl.haxx.se/docs/copyright.html.
  14. #
  15. # You may opt to use, copy, modify, merge, publish, distribute and/or sell
  16. # copies of the Software, and permit persons to whom the Software is
  17. # furnished to do so, under the terms of the COPYING file.
  18. #
  19. # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  20. # KIND, either express or implied.
  21. #
  22. #***************************************************************************
  23. # Starts sshd for use in the SCP and SFTP curl test harness tests.
  24. # Also creates the ssh configuration files needed for these tests.
  25. use strict;
  26. use warnings;
  27. use Cwd;
  28. use Cwd 'abs_path';
  29. #***************************************************************************
  30. # Variables and subs imported from sshhelp module
  31. #
  32. use sshhelp qw(
  33. $sshdexe
  34. $sshexe
  35. $sftpsrvexe
  36. $sftpexe
  37. $sshkeygenexe
  38. $sshdconfig
  39. $sshconfig
  40. $sftpconfig
  41. $knownhosts
  42. $sshdlog
  43. $sshlog
  44. $sftplog
  45. $sftpcmds
  46. $hstprvkeyf
  47. $hstpubkeyf
  48. $cliprvkeyf
  49. $clipubkeyf
  50. display_sshdconfig
  51. display_sshconfig
  52. display_sftpconfig
  53. display_sshdlog
  54. display_sshlog
  55. display_sftplog
  56. dump_array
  57. find_sshd
  58. find_ssh
  59. find_sftpsrv
  60. find_sftp
  61. find_sshkeygen
  62. logmsg
  63. sshversioninfo
  64. );
  65. #***************************************************************************
  66. # Subs imported from serverhelp module
  67. #
  68. use serverhelp qw(
  69. server_pidfilename
  70. server_logfilename
  71. );
  72. use pathhelp;
  73. #***************************************************************************
  74. my $verbose = 0; # set to 1 for debugging
  75. my $debugprotocol = 0; # set to 1 for protocol debugging
  76. my $port = 8999; # our default SCP/SFTP server port
  77. my $listenaddr = '127.0.0.1'; # default address on which to listen
  78. my $ipvnum = 4; # default IP version of listener address
  79. my $idnum = 1; # default ssh daemon instance number
  80. my $proto = 'ssh'; # protocol the ssh daemon speaks
  81. my $path = getcwd(); # current working directory
  82. my $logdir = $path .'/log'; # directory for log files
  83. my $username = $ENV{USER}; # default user
  84. my $pidfile; # ssh daemon pid file
  85. my $identity = 'curl_client_key'; # default identity file
  86. my $error;
  87. my @cfgarr;
  88. #***************************************************************************
  89. # Parse command line options
  90. #
  91. while(@ARGV) {
  92. if($ARGV[0] eq '--verbose') {
  93. $verbose = 1;
  94. }
  95. elsif($ARGV[0] eq '--debugprotocol') {
  96. $verbose = 1;
  97. $debugprotocol = 1;
  98. }
  99. elsif($ARGV[0] eq '--user') {
  100. if($ARGV[1]) {
  101. $username = $ARGV[1];
  102. shift @ARGV;
  103. }
  104. }
  105. elsif($ARGV[0] eq '--id') {
  106. if($ARGV[1]) {
  107. if($ARGV[1] =~ /^(\d+)$/) {
  108. $idnum = $1 if($1 > 0);
  109. shift @ARGV;
  110. }
  111. }
  112. }
  113. elsif($ARGV[0] eq '--ipv4') {
  114. $ipvnum = 4;
  115. $listenaddr = '127.0.0.1' if($listenaddr eq '::1');
  116. }
  117. elsif($ARGV[0] eq '--ipv6') {
  118. $ipvnum = 6;
  119. $listenaddr = '::1' if($listenaddr eq '127.0.0.1');
  120. }
  121. elsif($ARGV[0] eq '--addr') {
  122. if($ARGV[1]) {
  123. my $tmpstr = $ARGV[1];
  124. if($tmpstr =~ /^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/) {
  125. $listenaddr = "$1.$2.$3.$4" if($ipvnum == 4);
  126. shift @ARGV;
  127. }
  128. elsif($ipvnum == 6) {
  129. $listenaddr = $tmpstr;
  130. $listenaddr =~ s/^\[(.*)\]$/$1/;
  131. shift @ARGV;
  132. }
  133. }
  134. }
  135. elsif($ARGV[0] eq '--pidfile') {
  136. if($ARGV[1]) {
  137. $pidfile = "$path/". $ARGV[1];
  138. shift @ARGV;
  139. }
  140. }
  141. elsif($ARGV[0] eq '--sshport') {
  142. if($ARGV[1]) {
  143. if($ARGV[1] =~ /^(\d+)$/) {
  144. $port = $1;
  145. shift @ARGV;
  146. }
  147. }
  148. }
  149. else {
  150. print STDERR "\nWarning: sshserver.pl unknown parameter: $ARGV[0]\n";
  151. }
  152. shift @ARGV;
  153. }
  154. #***************************************************************************
  155. # Default ssh daemon pid file name
  156. #
  157. if(!$pidfile) {
  158. $pidfile = "$path/". server_pidfilename($proto, $ipvnum, $idnum);
  159. }
  160. #***************************************************************************
  161. # ssh and sftp server log file names
  162. #
  163. $sshdlog = server_logfilename($logdir, 'ssh', $ipvnum, $idnum);
  164. $sftplog = server_logfilename($logdir, 'sftp', $ipvnum, $idnum);
  165. #***************************************************************************
  166. # Logging level for ssh server and client
  167. #
  168. my $loglevel = $debugprotocol?'DEBUG3':'DEBUG2';
  169. #***************************************************************************
  170. # Validate username
  171. #
  172. if(!$username) {
  173. $error = 'Will not run ssh server without a user name';
  174. }
  175. elsif($username eq 'root') {
  176. $error = 'Will not run ssh server as root to mitigate security risks';
  177. }
  178. if($error) {
  179. logmsg $error;
  180. exit 1;
  181. }
  182. #***************************************************************************
  183. # Find out ssh daemon canonical file name
  184. #
  185. my $sshd = find_sshd();
  186. if(!$sshd) {
  187. logmsg "cannot find $sshdexe";
  188. exit 1;
  189. }
  190. #***************************************************************************
  191. # Find out ssh daemon version info
  192. #
  193. my ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
  194. if(!$sshdid) {
  195. # Not an OpenSSH or SunSSH ssh daemon
  196. logmsg $sshderror if($verbose);
  197. logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
  198. exit 1;
  199. }
  200. logmsg "ssh server found $sshd is $sshdverstr" if($verbose);
  201. #***************************************************************************
  202. # ssh daemon command line options we might use and version support
  203. #
  204. # -e: log stderr : OpenSSH 2.9.0 and later
  205. # -f: sshd config file : OpenSSH 1.2.1 and later
  206. # -D: no daemon forking : OpenSSH 2.5.0 and later
  207. # -o: command-line option : OpenSSH 3.1.0 and later
  208. # -t: test config file : OpenSSH 2.9.9 and later
  209. # -?: sshd version info : OpenSSH 1.2.1 and later
  210. #
  211. # -e: log stderr : SunSSH 1.0.0 and later
  212. # -f: sshd config file : SunSSH 1.0.0 and later
  213. # -D: no daemon forking : SunSSH 1.0.0 and later
  214. # -o: command-line option : SunSSH 1.0.0 and later
  215. # -t: test config file : SunSSH 1.0.0 and later
  216. # -?: sshd version info : SunSSH 1.0.0 and later
  217. #***************************************************************************
  218. # Verify minimum ssh daemon version
  219. #
  220. if((($sshdid =~ /OpenSSH/) && ($sshdvernum < 299)) ||
  221. (($sshdid =~ /SunSSH/) && ($sshdvernum < 100))) {
  222. logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
  223. exit 1;
  224. }
  225. #***************************************************************************
  226. # Find out sftp server plugin canonical file name
  227. #
  228. my $sftpsrv = find_sftpsrv();
  229. if(!$sftpsrv) {
  230. logmsg "cannot find $sftpsrvexe";
  231. exit 1;
  232. }
  233. logmsg "sftp server plugin found $sftpsrv" if($verbose);
  234. #***************************************************************************
  235. # Find out sftp client canonical file name
  236. #
  237. my $sftp = find_sftp();
  238. if(!$sftp) {
  239. logmsg "cannot find $sftpexe";
  240. exit 1;
  241. }
  242. logmsg "sftp client found $sftp" if($verbose);
  243. #***************************************************************************
  244. # Find out ssh keygen canonical file name
  245. #
  246. my $sshkeygen = find_sshkeygen();
  247. if(!$sshkeygen) {
  248. logmsg "cannot find $sshkeygenexe";
  249. exit 1;
  250. }
  251. logmsg "ssh keygen found $sshkeygen" if($verbose);
  252. #***************************************************************************
  253. # Find out ssh client canonical file name
  254. #
  255. my $ssh = find_ssh();
  256. if(!$ssh) {
  257. logmsg "cannot find $sshexe";
  258. exit 1;
  259. }
  260. #***************************************************************************
  261. # Find out ssh client version info
  262. #
  263. my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
  264. if(!$sshid) {
  265. # Not an OpenSSH or SunSSH ssh client
  266. logmsg $ssherror if($verbose);
  267. logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
  268. exit 1;
  269. }
  270. logmsg "ssh client found $ssh is $sshverstr" if($verbose);
  271. #***************************************************************************
  272. # ssh client command line options we might use and version support
  273. #
  274. # -D: dynamic app port forwarding : OpenSSH 2.9.9 and later
  275. # -F: ssh config file : OpenSSH 2.9.9 and later
  276. # -N: no shell/command : OpenSSH 2.1.0 and later
  277. # -p: connection port : OpenSSH 1.2.1 and later
  278. # -v: verbose messages : OpenSSH 1.2.1 and later
  279. # -vv: increase verbosity : OpenSSH 2.3.0 and later
  280. # -V: ssh version info : OpenSSH 1.2.1 and later
  281. #
  282. # -D: dynamic app port forwarding : SunSSH 1.0.0 and later
  283. # -F: ssh config file : SunSSH 1.0.0 and later
  284. # -N: no shell/command : SunSSH 1.0.0 and later
  285. # -p: connection port : SunSSH 1.0.0 and later
  286. # -v: verbose messages : SunSSH 1.0.0 and later
  287. # -vv: increase verbosity : SunSSH 1.0.0 and later
  288. # -V: ssh version info : SunSSH 1.0.0 and later
  289. #***************************************************************************
  290. # Verify minimum ssh client version
  291. #
  292. if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
  293. (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
  294. logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
  295. exit 1;
  296. }
  297. #***************************************************************************
  298. # ssh keygen command line options we actually use and version support
  299. #
  300. # -C: identity comment : OpenSSH 1.2.1 and later
  301. # -f: key filename : OpenSSH 1.2.1 and later
  302. # -N: new passphrase : OpenSSH 1.2.1 and later
  303. # -q: quiet keygen : OpenSSH 1.2.1 and later
  304. # -t: key type : OpenSSH 2.5.0 and later
  305. #
  306. # -C: identity comment : SunSSH 1.0.0 and later
  307. # -f: key filename : SunSSH 1.0.0 and later
  308. # -N: new passphrase : SunSSH 1.0.0 and later
  309. # -q: quiet keygen : SunSSH 1.0.0 and later
  310. # -t: key type : SunSSH 1.0.0 and later
  311. #***************************************************************************
  312. # Generate host and client key files for curl's tests
  313. #
  314. if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) ||
  315. (! -e $hstpubkeyf) || (! -s $hstpubkeyf) ||
  316. (! -e $cliprvkeyf) || (! -s $cliprvkeyf) ||
  317. (! -e $clipubkeyf) || (! -s $clipubkeyf)) {
  318. # Make sure all files are gone so ssh-keygen doesn't complain
  319. unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf);
  320. logmsg 'generating host keys...' if($verbose);
  321. if(system "\"$sshkeygen\" -q -t rsa -f $hstprvkeyf -C 'curl test server' -N ''") {
  322. logmsg 'Could not generate host key';
  323. exit 1;
  324. }
  325. logmsg 'generating client keys...' if($verbose);
  326. if(system "\"$sshkeygen\" -q -t rsa -f $cliprvkeyf -C 'curl test client' -N ''") {
  327. logmsg 'Could not generate client key';
  328. exit 1;
  329. }
  330. }
  331. #***************************************************************************
  332. # Convert paths for curl's tests running on Windows with Cygwin/Msys OpenSSH
  333. #
  334. my $clipubkeyf_config = abs_path("$path/$clipubkeyf");
  335. my $hstprvkeyf_config = abs_path("$path/$hstprvkeyf");
  336. my $pidfile_config = $pidfile;
  337. my $sftpsrv_config = $sftpsrv;
  338. if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys') {
  339. # Ensure to use MinGW/Cygwin paths
  340. $clipubkeyf_config = pathhelp::build_sys_abs_path($clipubkeyf_config);
  341. $hstprvkeyf_config = pathhelp::build_sys_abs_path($hstprvkeyf_config);
  342. $pidfile_config = pathhelp::build_sys_abs_path($pidfile_config);
  343. $sftpsrv_config = "internal-sftp";
  344. }
  345. if ($sshdid =~ /OpenSSH-Windows/) {
  346. # Ensure to use native Windows paths with OpenSSH for Windows
  347. $clipubkeyf_config = pathhelp::sys_native_abs_path($clipubkeyf);
  348. $hstprvkeyf_config = pathhelp::sys_native_abs_path($hstprvkeyf);
  349. $pidfile_config = pathhelp::sys_native_abs_path($pidfile);
  350. $sftpsrv_config = pathhelp::sys_native_abs_path($sftpsrv);
  351. $sshdconfig = pathhelp::sys_native_abs_path($sshdconfig);
  352. $sshconfig = pathhelp::sys_native_abs_path($sshconfig);
  353. $sftpconfig = pathhelp::sys_native_abs_path($sftpconfig);
  354. }
  355. #***************************************************************************
  356. # ssh daemon configuration file options we might use and version support
  357. #
  358. # AFSTokenPassing : OpenSSH 1.2.1 and later [1]
  359. # AcceptEnv : OpenSSH 3.9.0 and later
  360. # AddressFamily : OpenSSH 4.0.0 and later
  361. # AllowGroups : OpenSSH 1.2.1 and later
  362. # AllowTcpForwarding : OpenSSH 2.3.0 and later
  363. # AllowUsers : OpenSSH 1.2.1 and later
  364. # AuthorizedKeysFile : OpenSSH 2.9.9 and later
  365. # AuthorizedKeysFile2 : OpenSSH 2.9.9 and later
  366. # Banner : OpenSSH 2.5.0 and later
  367. # ChallengeResponseAuthentication : OpenSSH 2.5.0 and later
  368. # Ciphers : OpenSSH 2.1.0 and later [3]
  369. # ClientAliveCountMax : OpenSSH 2.9.0 and later
  370. # ClientAliveInterval : OpenSSH 2.9.0 and later
  371. # Compression : OpenSSH 3.3.0 and later
  372. # DenyGroups : OpenSSH 1.2.1 and later
  373. # DenyUsers : OpenSSH 1.2.1 and later
  374. # ForceCommand : OpenSSH 4.4.0 and later [3]
  375. # GatewayPorts : OpenSSH 2.1.0 and later
  376. # GSSAPIAuthentication : OpenSSH 3.7.0 and later [1]
  377. # GSSAPICleanupCredentials : OpenSSH 3.8.0 and later [1]
  378. # GSSAPIKeyExchange : SunSSH 1.0.0 and later [1]
  379. # GSSAPIStoreDelegatedCredentials : SunSSH 1.0.0 and later [1]
  380. # GSSCleanupCreds : SunSSH 1.0.0 and later [1]
  381. # GSSUseSessionCredCache : SunSSH 1.0.0 and later [1]
  382. # HostbasedAuthentication : OpenSSH 2.9.0 and later
  383. # HostbasedUsesNameFromPacketOnly : OpenSSH 2.9.0 and later
  384. # HostKey : OpenSSH 1.2.1 and later
  385. # IgnoreRhosts : OpenSSH 1.2.1 and later
  386. # IgnoreUserKnownHosts : OpenSSH 1.2.1 and later
  387. # KbdInteractiveAuthentication : OpenSSH 2.3.0 and later
  388. # KeepAlive : OpenSSH 1.2.1 and later
  389. # KerberosAuthentication : OpenSSH 1.2.1 and later [1]
  390. # KerberosGetAFSToken : OpenSSH 3.8.0 and later [1]
  391. # KerberosOrLocalPasswd : OpenSSH 1.2.1 and later [1]
  392. # KerberosTgtPassing : OpenSSH 1.2.1 and later [1]
  393. # KerberosTicketCleanup : OpenSSH 1.2.1 and later [1]
  394. # KeyRegenerationInterval : OpenSSH 1.2.1 and later
  395. # ListenAddress : OpenSSH 1.2.1 and later
  396. # LoginGraceTime : OpenSSH 1.2.1 and later
  397. # LogLevel : OpenSSH 1.2.1 and later
  398. # LookupClientHostnames : SunSSH 1.0.0 and later
  399. # MACs : OpenSSH 2.5.0 and later [3]
  400. # Match : OpenSSH 4.4.0 and later [3]
  401. # MaxAuthTries : OpenSSH 3.9.0 and later
  402. # MaxStartups : OpenSSH 2.2.0 and later
  403. # PAMAuthenticationViaKbdInt : OpenSSH 2.9.0 and later [2]
  404. # PasswordAuthentication : OpenSSH 1.2.1 and later
  405. # PermitEmptyPasswords : OpenSSH 1.2.1 and later
  406. # PermitOpen : OpenSSH 4.4.0 and later [3]
  407. # PermitRootLogin : OpenSSH 1.2.1 and later
  408. # PermitTunnel : OpenSSH 4.3.0 and later
  409. # PermitUserEnvironment : OpenSSH 3.5.0 and later
  410. # PidFile : OpenSSH 2.1.0 and later
  411. # Port : OpenSSH 1.2.1 and later
  412. # PrintLastLog : OpenSSH 2.9.0 and later
  413. # PrintMotd : OpenSSH 1.2.1 and later
  414. # Protocol : OpenSSH 2.1.0 and later
  415. # PubkeyAuthentication : OpenSSH 2.5.0 and later
  416. # RhostsAuthentication : OpenSSH 1.2.1 and later
  417. # RhostsRSAAuthentication : OpenSSH 1.2.1 and later
  418. # RSAAuthentication : OpenSSH 1.2.1 and later
  419. # ServerKeyBits : OpenSSH 1.2.1 and later
  420. # SkeyAuthentication : OpenSSH 1.2.1 and later [1]
  421. # StrictModes : OpenSSH 1.2.1 and later
  422. # Subsystem : OpenSSH 2.2.0 and later
  423. # SyslogFacility : OpenSSH 1.2.1 and later
  424. # TCPKeepAlive : OpenSSH 3.8.0 and later
  425. # UseDNS : OpenSSH 3.7.0 and later
  426. # UseLogin : OpenSSH 1.2.1 and later
  427. # UsePAM : OpenSSH 3.7.0 and later [1][2]
  428. # UsePrivilegeSeparation : OpenSSH 3.2.2 and later
  429. # VerifyReverseMapping : OpenSSH 3.1.0 and later
  430. # X11DisplayOffset : OpenSSH 1.2.1 and later [3]
  431. # X11Forwarding : OpenSSH 1.2.1 and later
  432. # X11UseLocalhost : OpenSSH 3.1.0 and later
  433. # XAuthLocation : OpenSSH 2.1.1 and later [3]
  434. #
  435. # [1] Option only available if activated at compile time
  436. # [2] Option specific for portable versions
  437. # [3] Option not used in our ssh server config file
  438. #***************************************************************************
  439. # Initialize sshd config with options actually supported in OpenSSH 2.9.9
  440. #
  441. logmsg 'generating ssh server config file...' if($verbose);
  442. @cfgarr = ();
  443. push @cfgarr, '# This is a generated file. Do not edit.';
  444. push @cfgarr, "# $sshdverstr sshd configuration file for curl testing";
  445. push @cfgarr, '#';
  446. # AllowUsers and DenyUsers options should use lowercase on Windows
  447. # and do not support quotes around values for some unknown reason.
  448. if ($sshdid =~ /OpenSSH-Windows/) {
  449. my $username_lc = lc $username;
  450. push @cfgarr, "DenyUsers !$username_lc";
  451. push @cfgarr, "AllowUsers $username_lc";
  452. } else {
  453. push @cfgarr, "DenyUsers !$username";
  454. push @cfgarr, "AllowUsers $username";
  455. }
  456. push @cfgarr, 'DenyGroups';
  457. push @cfgarr, 'AllowGroups';
  458. push @cfgarr, '#';
  459. push @cfgarr, "AuthorizedKeysFile $clipubkeyf_config";
  460. push @cfgarr, "AuthorizedKeysFile2 $clipubkeyf_config";
  461. push @cfgarr, "HostKey $hstprvkeyf_config";
  462. push @cfgarr, "PidFile $pidfile_config";
  463. push @cfgarr, '#';
  464. push @cfgarr, "Port $port";
  465. push @cfgarr, "ListenAddress $listenaddr";
  466. push @cfgarr, 'Protocol 2';
  467. push @cfgarr, '#';
  468. push @cfgarr, 'AllowTcpForwarding yes';
  469. push @cfgarr, 'Banner none';
  470. push @cfgarr, 'ChallengeResponseAuthentication no';
  471. push @cfgarr, 'ClientAliveCountMax 3';
  472. push @cfgarr, 'ClientAliveInterval 0';
  473. push @cfgarr, 'GatewayPorts no';
  474. push @cfgarr, 'HostbasedAuthentication no';
  475. push @cfgarr, 'HostbasedUsesNameFromPacketOnly no';
  476. push @cfgarr, 'IgnoreRhosts yes';
  477. push @cfgarr, 'IgnoreUserKnownHosts yes';
  478. push @cfgarr, 'KeyRegenerationInterval 0';
  479. push @cfgarr, 'LoginGraceTime 30';
  480. push @cfgarr, "LogLevel $loglevel";
  481. push @cfgarr, 'MaxStartups 5';
  482. push @cfgarr, 'PasswordAuthentication no';
  483. push @cfgarr, 'PermitEmptyPasswords no';
  484. push @cfgarr, 'PermitRootLogin no';
  485. push @cfgarr, 'PrintLastLog no';
  486. push @cfgarr, 'PrintMotd no';
  487. push @cfgarr, 'PubkeyAuthentication yes';
  488. push @cfgarr, 'RhostsRSAAuthentication no';
  489. push @cfgarr, 'RSAAuthentication no';
  490. push @cfgarr, 'ServerKeyBits 768';
  491. push @cfgarr, 'StrictModes no';
  492. push @cfgarr, "Subsystem sftp \"$sftpsrv_config\"";
  493. push @cfgarr, 'SyslogFacility AUTH';
  494. push @cfgarr, 'UseLogin no';
  495. push @cfgarr, 'X11Forwarding no';
  496. push @cfgarr, '#';
  497. #***************************************************************************
  498. # Write out initial sshd configuration file for curl's tests
  499. #
  500. $error = dump_array($sshdconfig, @cfgarr);
  501. if($error) {
  502. logmsg $error;
  503. exit 1;
  504. }
  505. #***************************************************************************
  506. # Verifies at run time if sshd supports a given configuration file option
  507. #
  508. sub sshd_supports_opt {
  509. my ($option, $value) = @_;
  510. my $err;
  511. #
  512. if((($sshdid =~ /OpenSSH/) && ($sshdvernum >= 310)) ||
  513. ($sshdid =~ /SunSSH/)) {
  514. # ssh daemon supports command line options -t -f and -o
  515. $err = grep /((Unsupported)|(Bad configuration)|(Deprecated)) option.*$option/,
  516. qx("$sshd" -t -f $sshdconfig -o "$option=$value" 2>&1);
  517. return !$err;
  518. }
  519. if(($sshdid =~ /OpenSSH/) && ($sshdvernum >= 299)) {
  520. # ssh daemon supports command line options -t and -f
  521. $err = dump_array($sshdconfig, (@cfgarr, "$option $value"));
  522. if($err) {
  523. logmsg $err;
  524. return 0;
  525. }
  526. $err = grep /((Unsupported)|(Bad configuration)|(Deprecated)) option.*$option/,
  527. qx("$sshd" -t -f $sshdconfig 2>&1);
  528. unlink $sshdconfig;
  529. return !$err;
  530. }
  531. return 0;
  532. }
  533. #***************************************************************************
  534. # Kerberos Authentication support may have not been built into sshd
  535. #
  536. if(sshd_supports_opt('KerberosAuthentication','no')) {
  537. push @cfgarr, 'KerberosAuthentication no';
  538. }
  539. if(sshd_supports_opt('KerberosGetAFSToken','no')) {
  540. push @cfgarr, 'KerberosGetAFSToken no';
  541. }
  542. if(sshd_supports_opt('KerberosOrLocalPasswd','no')) {
  543. push @cfgarr, 'KerberosOrLocalPasswd no';
  544. }
  545. if(sshd_supports_opt('KerberosTgtPassing','no')) {
  546. push @cfgarr, 'KerberosTgtPassing no';
  547. }
  548. if(sshd_supports_opt('KerberosTicketCleanup','yes')) {
  549. push @cfgarr, 'KerberosTicketCleanup yes';
  550. }
  551. #***************************************************************************
  552. # Andrew File System support may have not been built into sshd
  553. #
  554. if(sshd_supports_opt('AFSTokenPassing','no')) {
  555. push @cfgarr, 'AFSTokenPassing no';
  556. }
  557. #***************************************************************************
  558. # S/Key authentication support may have not been built into sshd
  559. #
  560. if(sshd_supports_opt('SkeyAuthentication','no')) {
  561. push @cfgarr, 'SkeyAuthentication no';
  562. }
  563. #***************************************************************************
  564. # GSSAPI Authentication support may have not been built into sshd
  565. #
  566. my $sshd_builtwith_GSSAPI;
  567. if(sshd_supports_opt('GSSAPIAuthentication','no')) {
  568. push @cfgarr, 'GSSAPIAuthentication no';
  569. $sshd_builtwith_GSSAPI = 1;
  570. }
  571. if(sshd_supports_opt('GSSAPICleanupCredentials','yes')) {
  572. push @cfgarr, 'GSSAPICleanupCredentials yes';
  573. }
  574. if(sshd_supports_opt('GSSAPIKeyExchange','no')) {
  575. push @cfgarr, 'GSSAPIKeyExchange no';
  576. }
  577. if(sshd_supports_opt('GSSAPIStoreDelegatedCredentials','no')) {
  578. push @cfgarr, 'GSSAPIStoreDelegatedCredentials no';
  579. }
  580. if(sshd_supports_opt('GSSCleanupCreds','yes')) {
  581. push @cfgarr, 'GSSCleanupCreds yes';
  582. }
  583. if(sshd_supports_opt('GSSUseSessionCredCache','no')) {
  584. push @cfgarr, 'GSSUseSessionCredCache no';
  585. }
  586. push @cfgarr, '#';
  587. #***************************************************************************
  588. # Options that might be supported or not in sshd OpenSSH 2.9.9 and later
  589. #
  590. if(sshd_supports_opt('AcceptEnv','')) {
  591. push @cfgarr, 'AcceptEnv';
  592. }
  593. if(sshd_supports_opt('AddressFamily','any')) {
  594. # Address family must be specified before ListenAddress
  595. splice @cfgarr, 14, 0, 'AddressFamily any';
  596. }
  597. if(sshd_supports_opt('Compression','no')) {
  598. push @cfgarr, 'Compression no';
  599. }
  600. if(sshd_supports_opt('KbdInteractiveAuthentication','no')) {
  601. push @cfgarr, 'KbdInteractiveAuthentication no';
  602. }
  603. if(sshd_supports_opt('KeepAlive','no')) {
  604. push @cfgarr, 'KeepAlive no';
  605. }
  606. if(sshd_supports_opt('LookupClientHostnames','no')) {
  607. push @cfgarr, 'LookupClientHostnames no';
  608. }
  609. if(sshd_supports_opt('MaxAuthTries','10')) {
  610. push @cfgarr, 'MaxAuthTries 10';
  611. }
  612. if(sshd_supports_opt('PAMAuthenticationViaKbdInt','no')) {
  613. push @cfgarr, 'PAMAuthenticationViaKbdInt no';
  614. }
  615. if(sshd_supports_opt('PermitTunnel','no')) {
  616. push @cfgarr, 'PermitTunnel no';
  617. }
  618. if(sshd_supports_opt('PermitUserEnvironment','no')) {
  619. push @cfgarr, 'PermitUserEnvironment no';
  620. }
  621. if(sshd_supports_opt('RhostsAuthentication','no')) {
  622. push @cfgarr, 'RhostsAuthentication no';
  623. }
  624. if(sshd_supports_opt('TCPKeepAlive','no')) {
  625. push @cfgarr, 'TCPKeepAlive no';
  626. }
  627. if(sshd_supports_opt('UseDNS','no')) {
  628. push @cfgarr, 'UseDNS no';
  629. }
  630. if(sshd_supports_opt('UsePAM','no')) {
  631. push @cfgarr, 'UsePAM no';
  632. }
  633. if($sshdid =~ /OpenSSH/) {
  634. # http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6492415
  635. if(sshd_supports_opt('UsePrivilegeSeparation','no')) {
  636. push @cfgarr, 'UsePrivilegeSeparation no';
  637. }
  638. }
  639. if(sshd_supports_opt('VerifyReverseMapping','no')) {
  640. push @cfgarr, 'VerifyReverseMapping no';
  641. }
  642. if(sshd_supports_opt('X11UseLocalhost','yes')) {
  643. push @cfgarr, 'X11UseLocalhost yes';
  644. }
  645. push @cfgarr, '#';
  646. #***************************************************************************
  647. # Write out resulting sshd configuration file for curl's tests
  648. #
  649. $error = dump_array($sshdconfig, @cfgarr);
  650. if($error) {
  651. logmsg $error;
  652. exit 1;
  653. }
  654. #***************************************************************************
  655. # Verify that sshd actually supports our generated configuration file
  656. #
  657. if(system "\"$sshd\" -t -f $sshdconfig > $sshdlog 2>&1") {
  658. logmsg "sshd configuration file $sshdconfig failed verification";
  659. display_sshdlog();
  660. display_sshdconfig();
  661. exit 1;
  662. }
  663. #***************************************************************************
  664. # Generate ssh client host key database file for curl's tests
  665. #
  666. if((! -e $knownhosts) || (! -s $knownhosts)) {
  667. logmsg 'generating ssh client known hosts file...' if($verbose);
  668. unlink($knownhosts);
  669. if(open(RSAKEYFILE, "<$hstpubkeyf")) {
  670. my @rsahostkey = do { local $/ = ' '; <RSAKEYFILE> };
  671. if(close(RSAKEYFILE)) {
  672. if(open(KNOWNHOSTS, ">$knownhosts")) {
  673. print KNOWNHOSTS "$listenaddr ssh-rsa $rsahostkey[1]\n";
  674. if(!close(KNOWNHOSTS)) {
  675. $error = "Error: cannot close file $knownhosts";
  676. }
  677. }
  678. else {
  679. $error = "Error: cannot write file $knownhosts";
  680. }
  681. }
  682. else {
  683. $error = "Error: cannot close file $hstpubkeyf";
  684. }
  685. }
  686. else {
  687. $error = "Error: cannot read file $hstpubkeyf";
  688. }
  689. if($error) {
  690. logmsg $error;
  691. exit 1;
  692. }
  693. }
  694. #***************************************************************************
  695. # Convert paths for curl's tests running on Windows using Cygwin OpenSSH
  696. #
  697. my $identity_config = abs_path("$path/$identity");
  698. my $knownhosts_config = abs_path("$path/$knownhosts");
  699. if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys') {
  700. # Ensure to use MinGW/Cygwin paths
  701. $identity_config = pathhelp::build_sys_abs_path($identity_config);
  702. $knownhosts_config = pathhelp::build_sys_abs_path($knownhosts_config);
  703. }
  704. if ($sshdid =~ /OpenSSH-Windows/) {
  705. # Ensure to use native Windows paths with OpenSSH for Windows
  706. $identity_config = pathhelp::sys_native_abs_path($identity);
  707. $knownhosts_config = pathhelp::sys_native_abs_path($knownhosts);
  708. }
  709. #***************************************************************************
  710. # ssh client configuration file options we might use and version support
  711. #
  712. # AddressFamily : OpenSSH 3.7.0 and later
  713. # BatchMode : OpenSSH 1.2.1 and later
  714. # BindAddress : OpenSSH 2.9.9 and later
  715. # ChallengeResponseAuthentication : OpenSSH 2.5.0 and later
  716. # CheckHostIP : OpenSSH 1.2.1 and later
  717. # Cipher : OpenSSH 1.2.1 and later [3]
  718. # Ciphers : OpenSSH 2.1.0 and later [3]
  719. # ClearAllForwardings : OpenSSH 2.9.9 and later
  720. # Compression : OpenSSH 1.2.1 and later
  721. # CompressionLevel : OpenSSH 1.2.1 and later [3]
  722. # ConnectionAttempts : OpenSSH 1.2.1 and later
  723. # ConnectTimeout : OpenSSH 3.7.0 and later
  724. # ControlMaster : OpenSSH 3.9.0 and later
  725. # ControlPath : OpenSSH 3.9.0 and later
  726. # DisableBanner : SunSSH 1.2.0 and later
  727. # DynamicForward : OpenSSH 2.9.0 and later
  728. # EnableSSHKeysign : OpenSSH 3.6.0 and later
  729. # EscapeChar : OpenSSH 1.2.1 and later [3]
  730. # ExitOnForwardFailure : OpenSSH 4.4.0 and later
  731. # ForwardAgent : OpenSSH 1.2.1 and later
  732. # ForwardX11 : OpenSSH 1.2.1 and later
  733. # ForwardX11Trusted : OpenSSH 3.8.0 and later
  734. # GatewayPorts : OpenSSH 1.2.1 and later
  735. # GlobalKnownHostsFile : OpenSSH 1.2.1 and later
  736. # GSSAPIAuthentication : OpenSSH 3.7.0 and later [1]
  737. # GSSAPIDelegateCredentials : OpenSSH 3.7.0 and later [1]
  738. # HashKnownHosts : OpenSSH 4.0.0 and later
  739. # Host : OpenSSH 1.2.1 and later
  740. # HostbasedAuthentication : OpenSSH 2.9.0 and later
  741. # HostKeyAlgorithms : OpenSSH 2.9.0 and later [3]
  742. # HostKeyAlias : OpenSSH 2.5.0 and later [3]
  743. # HostName : OpenSSH 1.2.1 and later
  744. # IdentitiesOnly : OpenSSH 3.9.0 and later
  745. # IdentityFile : OpenSSH 1.2.1 and later
  746. # IgnoreIfUnknown : SunSSH 1.2.0 and later
  747. # KeepAlive : OpenSSH 1.2.1 and later
  748. # KbdInteractiveAuthentication : OpenSSH 2.3.0 and later
  749. # KbdInteractiveDevices : OpenSSH 2.3.0 and later [3]
  750. # LocalCommand : OpenSSH 4.3.0 and later [3]
  751. # LocalForward : OpenSSH 1.2.1 and later [3]
  752. # LogLevel : OpenSSH 1.2.1 and later
  753. # MACs : OpenSSH 2.5.0 and later [3]
  754. # NoHostAuthenticationForLocalhost : OpenSSH 3.0.0 and later
  755. # NumberOfPasswordPrompts : OpenSSH 1.2.1 and later
  756. # PasswordAuthentication : OpenSSH 1.2.1 and later
  757. # PermitLocalCommand : OpenSSH 4.3.0 and later
  758. # Port : OpenSSH 1.2.1 and later
  759. # PreferredAuthentications : OpenSSH 2.5.2 and later
  760. # Protocol : OpenSSH 2.1.0 and later
  761. # ProxyCommand : OpenSSH 1.2.1 and later [3]
  762. # PubkeyAuthentication : OpenSSH 2.5.0 and later
  763. # RekeyLimit : OpenSSH 3.7.0 and later
  764. # RemoteForward : OpenSSH 1.2.1 and later [3]
  765. # RhostsRSAAuthentication : OpenSSH 1.2.1 and later
  766. # RSAAuthentication : OpenSSH 1.2.1 and later
  767. # SendEnv : OpenSSH 3.9.0 and later
  768. # ServerAliveCountMax : OpenSSH 3.8.0 and later
  769. # ServerAliveInterval : OpenSSH 3.8.0 and later
  770. # SmartcardDevice : OpenSSH 2.9.9 and later [1][3]
  771. # StrictHostKeyChecking : OpenSSH 1.2.1 and later
  772. # TCPKeepAlive : OpenSSH 3.8.0 and later
  773. # Tunnel : OpenSSH 4.3.0 and later
  774. # TunnelDevice : OpenSSH 4.3.0 and later [3]
  775. # UsePAM : OpenSSH 3.7.0 and later [1][2][3]
  776. # UsePrivilegedPort : OpenSSH 1.2.1 and later
  777. # User : OpenSSH 1.2.1 and later
  778. # UserKnownHostsFile : OpenSSH 1.2.1 and later
  779. # VerifyHostKeyDNS : OpenSSH 3.8.0 and later
  780. # XAuthLocation : OpenSSH 2.1.1 and later [3]
  781. #
  782. # [1] Option only available if activated at compile time
  783. # [2] Option specific for portable versions
  784. # [3] Option not used in our ssh client config file
  785. #***************************************************************************
  786. # Initialize ssh config with options actually supported in OpenSSH 2.9.9
  787. #
  788. logmsg 'generating ssh client config file...' if($verbose);
  789. @cfgarr = ();
  790. push @cfgarr, '# This is a generated file. Do not edit.';
  791. push @cfgarr, "# $sshverstr ssh client configuration file for curl testing";
  792. push @cfgarr, '#';
  793. push @cfgarr, 'Host *';
  794. push @cfgarr, '#';
  795. push @cfgarr, "Port $port";
  796. push @cfgarr, "HostName $listenaddr";
  797. push @cfgarr, "User $username";
  798. push @cfgarr, 'Protocol 2';
  799. push @cfgarr, '#';
  800. # BindAddress option is not supported by OpenSSH for Windows
  801. if (!($sshdid =~ /OpenSSH-Windows/)) {
  802. push @cfgarr, "BindAddress $listenaddr";
  803. }
  804. push @cfgarr, '#';
  805. push @cfgarr, "IdentityFile $identity_config";
  806. push @cfgarr, "UserKnownHostsFile $knownhosts_config";
  807. push @cfgarr, '#';
  808. push @cfgarr, 'BatchMode yes';
  809. push @cfgarr, 'ChallengeResponseAuthentication no';
  810. push @cfgarr, 'CheckHostIP no';
  811. push @cfgarr, 'ClearAllForwardings no';
  812. push @cfgarr, 'Compression no';
  813. push @cfgarr, 'ConnectionAttempts 3';
  814. push @cfgarr, 'ForwardAgent no';
  815. push @cfgarr, 'ForwardX11 no';
  816. push @cfgarr, 'GatewayPorts no';
  817. push @cfgarr, 'GlobalKnownHostsFile /dev/null';
  818. push @cfgarr, 'HostbasedAuthentication no';
  819. push @cfgarr, 'KbdInteractiveAuthentication no';
  820. push @cfgarr, "LogLevel $loglevel";
  821. push @cfgarr, 'NumberOfPasswordPrompts 0';
  822. push @cfgarr, 'PasswordAuthentication no';
  823. push @cfgarr, 'PreferredAuthentications publickey';
  824. push @cfgarr, 'PubkeyAuthentication yes';
  825. # RSA authentication options are not supported by OpenSSH for Windows
  826. if (!($sshdid =~ /OpenSSH-Windows/)) {
  827. push @cfgarr, 'RhostsRSAAuthentication no';
  828. push @cfgarr, 'RSAAuthentication no';
  829. }
  830. # Disabled StrictHostKeyChecking since it makes the tests fail on my
  831. # OpenSSH_6.0p1 on Debian Linux / Daniel
  832. push @cfgarr, 'StrictHostKeyChecking no';
  833. push @cfgarr, 'UsePrivilegedPort no';
  834. push @cfgarr, '#';
  835. #***************************************************************************
  836. # Options supported in ssh client newer than OpenSSH 2.9.9
  837. #
  838. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) {
  839. push @cfgarr, 'AddressFamily any';
  840. }
  841. if((($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) ||
  842. (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
  843. push @cfgarr, 'ConnectTimeout 30';
  844. }
  845. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
  846. push @cfgarr, 'ControlMaster no';
  847. }
  848. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 420)) {
  849. push @cfgarr, 'ControlPath none';
  850. }
  851. if(($sshid =~ /SunSSH/) && ($sshvernum >= 120)) {
  852. push @cfgarr, 'DisableBanner yes';
  853. }
  854. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 360)) {
  855. push @cfgarr, 'EnableSSHKeysign no';
  856. }
  857. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 440)) {
  858. push @cfgarr, 'ExitOnForwardFailure yes';
  859. }
  860. if((($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) ||
  861. (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
  862. push @cfgarr, 'ForwardX11Trusted no';
  863. }
  864. if(($sshd_builtwith_GSSAPI) && ($sshdid eq $sshid) &&
  865. ($sshdvernum == $sshvernum)) {
  866. push @cfgarr, 'GSSAPIAuthentication no';
  867. push @cfgarr, 'GSSAPIDelegateCredentials no';
  868. if($sshid =~ /SunSSH/) {
  869. push @cfgarr, 'GSSAPIKeyExchange no';
  870. }
  871. }
  872. if((($sshid =~ /OpenSSH/) && ($sshvernum >= 400)) ||
  873. (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
  874. push @cfgarr, 'HashKnownHosts no';
  875. }
  876. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
  877. push @cfgarr, 'IdentitiesOnly yes';
  878. }
  879. if(($sshid =~ /SunSSH/) && ($sshvernum >= 120)) {
  880. push @cfgarr, 'IgnoreIfUnknown no';
  881. }
  882. if((($sshid =~ /OpenSSH/) && ($sshvernum < 380)) ||
  883. ($sshid =~ /SunSSH/)) {
  884. push @cfgarr, 'KeepAlive no';
  885. }
  886. if((($sshid =~ /OpenSSH/) && ($sshvernum >= 300)) ||
  887. ($sshid =~ /SunSSH/)) {
  888. push @cfgarr, 'NoHostAuthenticationForLocalhost no';
  889. }
  890. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 430)) {
  891. push @cfgarr, 'PermitLocalCommand no';
  892. }
  893. if((($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) ||
  894. (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
  895. push @cfgarr, 'RekeyLimit 1G';
  896. }
  897. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
  898. push @cfgarr, 'SendEnv';
  899. }
  900. if((($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) ||
  901. (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
  902. push @cfgarr, 'ServerAliveCountMax 3';
  903. push @cfgarr, 'ServerAliveInterval 0';
  904. }
  905. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) {
  906. push @cfgarr, 'TCPKeepAlive no';
  907. }
  908. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 430)) {
  909. push @cfgarr, 'Tunnel no';
  910. }
  911. if(($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) {
  912. push @cfgarr, 'VerifyHostKeyDNS no';
  913. }
  914. push @cfgarr, '#';
  915. #***************************************************************************
  916. # Write out resulting ssh client configuration file for curl's tests
  917. #
  918. $error = dump_array($sshconfig, @cfgarr);
  919. if($error) {
  920. logmsg $error;
  921. exit 1;
  922. }
  923. #***************************************************************************
  924. # Initialize client sftp config with options actually supported.
  925. #
  926. logmsg 'generating sftp client config file...' if($verbose);
  927. splice @cfgarr, 1, 1, "# $sshverstr sftp client configuration file for curl testing";
  928. #
  929. for(my $i = scalar(@cfgarr) - 1; $i > 0; $i--) {
  930. if($cfgarr[$i] =~ /^DynamicForward/) {
  931. splice @cfgarr, $i, 1;
  932. next;
  933. }
  934. if($cfgarr[$i] =~ /^ClearAllForwardings/) {
  935. splice @cfgarr, $i, 1, "ClearAllForwardings yes";
  936. next;
  937. }
  938. }
  939. #***************************************************************************
  940. # Write out resulting sftp client configuration file for curl's tests
  941. #
  942. $error = dump_array($sftpconfig, @cfgarr);
  943. if($error) {
  944. logmsg $error;
  945. exit 1;
  946. }
  947. @cfgarr = ();
  948. #***************************************************************************
  949. # Generate client sftp commands batch file for sftp server verification
  950. #
  951. logmsg 'generating sftp client commands file...' if($verbose);
  952. push @cfgarr, 'pwd';
  953. push @cfgarr, 'quit';
  954. $error = dump_array($sftpcmds, @cfgarr);
  955. if($error) {
  956. logmsg $error;
  957. exit 1;
  958. }
  959. @cfgarr = ();
  960. #***************************************************************************
  961. # Start the ssh server daemon without forking it
  962. #
  963. logmsg "SCP/SFTP server listening on port $port" if($verbose);
  964. my $rc = system "\"$sshd\" -e -D -f $sshdconfig > $sshdlog 2>&1";
  965. if($rc == -1) {
  966. logmsg "\"$sshd\" failed with: $!";
  967. }
  968. elsif($rc & 127) {
  969. logmsg sprintf("\"$sshd\" died with signal %d, and %s coredump",
  970. ($rc & 127), ($rc & 128)?'a':'no');
  971. }
  972. elsif($verbose && ($rc >> 8)) {
  973. logmsg sprintf("\"$sshd\" exited with %d", $rc >> 8);
  974. }
  975. #***************************************************************************
  976. # Clean up once the server has stopped
  977. #
  978. unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf, $knownhosts);
  979. unlink($sshdconfig, $sshconfig, $sftpconfig);
  980. exit 0;