sshserver.pl 34 KB

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