1package ProFTPD::Tests::Modules::mod_sftp_sql; 2 3use lib qw(t/lib); 4use base qw(ProFTPD::TestSuite::Child); 5use strict; 6 7use Digest::MD5; 8use File::Copy; 9use File::Spec; 10use IO::Handle; 11use POSIX qw(:fcntl_h); 12 13use ProFTPD::TestSuite::Utils qw(:auth :config :features :running :test :testsuite); 14 15$| = 1; 16 17my $order = 0; 18 19my $TESTS = { 20 ssh2_auth_publickey_rsa_sql => { 21 order => ++$order, 22 test_class => [qw(forking ssh2)], 23 }, 24 25 ssh2_auth_publickey_rsa_sql_var_U => { 26 order => ++$order, 27 test_class => [qw(forking ssh2)], 28 }, 29 30 ssh2_auth_publickey_rsa_sql_var_u => { 31 order => ++$order, 32 test_class => [qw(forking ssh2)], 33 }, 34 35 ssh2_auth_publickey_dsa_sql => { 36 order => ++$order, 37 test_class => [qw(forking ssh2)], 38 }, 39 40 ssh2_auth_publickey_rsa_dsa_sql => { 41 order => ++$order, 42 test_class => [qw(forking ssh2)], 43 }, 44 45 ssh2_auth_publickey_rsa_sql_rfc4716 => { 46 order => ++$order, 47 test_class => [qw(forking ssh2)], 48 }, 49 50 ssh2_auth_publickey_rsa_sql_rfc4716_with_continued_line => { 51 order => ++$order, 52 test_class => [qw(forking ssh2)], 53 }, 54 55 ssh2_auth_publickey_dsa_sql_rfc4716 => { 56 order => ++$order, 57 test_class => [qw(forking ssh2)], 58 }, 59 60 ssh2_auth_publickey_rsa_dsa_sql_rfc4716 => { 61 order => ++$order, 62 test_class => [qw(forking ssh2)], 63 }, 64 65 ssh2_auth_publickey_multiple_keys_one_row_bug3942 => { 66 order => ++$order, 67 test_class => [qw(bug forking ssh2)], 68 }, 69 70 ssh2_auth_publickey_rsa_sql_fp_env_vars => { 71 order => ++$order, 72 test_class => [qw(forking ssh2)], 73 }, 74 75 ssh2_auth_publickey_rsa_sql_rfc4716_overlong_comment_bug4155 => { 76 order => ++$order, 77 test_class => [qw(bug forking ssh2)], 78 }, 79 80 ssh2_auth_publickey_rsa_sql_invalid_format_bug4350 => { 81 order => ++$order, 82 test_class => [qw(bug forking ssh2)], 83 }, 84 85}; 86 87sub new { 88 return shift()->SUPER::new(@_); 89} 90 91sub list_tests { 92 # Check for the required Perl modules: 93 # 94 # Net-SSH2 95 # Net-SSH2-SFTP 96 97 my $required = [qw( 98 Net::SSH2 99 Net::SSH2::SFTP 100 )]; 101 102 foreach my $req (@$required) { 103 eval "use $req"; 104 if ($@) { 105 print STDERR "\nWARNING:\n + Module '$req' not found, skipping all tests\n"; 106 107 if ($ENV{TEST_VERBOSE}) { 108 print STDERR "Unable to load $req: $@\n"; 109 } 110 111 return qw(testsuite_empty_test); 112 } 113 } 114 115# return testsuite_get_runnable_tests($TESTS); 116 return qw( 117 ssh2_auth_publickey_rsa_sql_invalid_format_bug4350 118 ); 119} 120 121sub set_up { 122 my $self = shift; 123 $self->SUPER::set_up(@_); 124 125 # Make sure that mod_sftp does not complain about permissions on the hostkey 126 # files. 127 128 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 129 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 130 131 unless (chmod(0400, $rsa_host_key, $dsa_host_key)) { 132 die("Can't set perms on $rsa_host_key, $dsa_host_key: $!"); 133 } 134} 135 136sub ssh2_auth_publickey_rsa_sql { 137 my $self = shift; 138 my $tmpdir = $self->{tmpdir}; 139 140 my $config_file = "$tmpdir/sftp.conf"; 141 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 142 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 143 144 my $log_file = test_get_logfile(); 145 146 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 147 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 148 149 my $user = 'proftpd'; 150 my $passwd = 'test'; 151 my $group = 'ftpd'; 152 my $home_dir = File::Spec->rel2abs($tmpdir); 153 my $uid = 500; 154 my $gid = 500; 155 156 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 157 158 my $rsa_data = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7jGx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00ydqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84uO6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMmef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPkByq2pv4VBo953gK7f1AQ=='; 159 160 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 161 162 my $fh; 163 if (open($fh, "> $db_script")) { 164 print $fh <<EOS; 165CREATE TABLE sftpuserkeys ( 166 name TEXT NOT NULL PRIMARY KEY, 167 key BLOB NOT NULL 168); 169 170INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_data'); 171 172CREATE TABLE users ( 173 userid TEXT NOT NULL PRIMARY KEY, 174 passwd TEXT, 175 uid INTEGER, 176 gid INTEGER, 177 homedir TEXT, 178 shell TEXT 179); 180 181EOS 182 unless (close($fh)) { 183 die("Can't write $db_script: $!"); 184 } 185 186 } else { 187 die("Can't open $db_script: $!"); 188 } 189 190 my $cmd = "sqlite3 $db_file < $db_script"; 191 if ($ENV{TEST_VERBOSE}) { 192 print STDERR "Executing sqlite3: $cmd\n"; 193 } 194 195 my @output = `$cmd`; 196 197 unlink($db_script); 198 199 # Make sure that, if we're running as root, that the home directory has 200 # permissions/privs set for the account we create 201 if ($< == 0) { 202 unless (chmod(0755, $home_dir)) { 203 die("Can't set perms on $home_dir to 0755: $!"); 204 } 205 206 unless (chown($uid, $gid, $home_dir)) { 207 die("Can't set owner of $home_dir to $uid/$gid: $!"); 208 } 209 } 210 211 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 212 '/bin/bash'); 213 auth_group_write($auth_group_file, $group, $gid, $user); 214 215 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 216 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 217 218 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key'); 219 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub'); 220 221 my $config = { 222 PidFile => $pid_file, 223 ScoreboardFile => $scoreboard_file, 224 SystemLog => $log_file, 225 TraceLog => $log_file, 226 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 227 228 AuthUserFile => $auth_user_file, 229 AuthGroupFile => $auth_group_file, 230 231 IfModules => { 232 'mod_delay.c' => { 233 DelayEngine => 'off', 234 }, 235 236 'mod_sql_sqlite.c' => { 237 SQLAuthenticate => 'users usersetfast', 238 SQLConnectInfo => $db_file, 239 SQLLogFile => $log_file, 240 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 241 }, 242 243 'mod_sftp.c' => [ 244 "SFTPEngine on", 245 "SFTPLog $log_file", 246 "SFTPHostKey $rsa_host_key", 247 "SFTPHostKey $dsa_host_key", 248 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 249 ], 250 }, 251 }; 252 253 my ($port, $config_user, $config_group) = config_write($config_file, $config); 254 255 # Open pipes, for use between the parent and child processes. Specifically, 256 # the child will indicate when it's done with its test by writing a message 257 # to the parent. 258 my ($rfh, $wfh); 259 unless (pipe($rfh, $wfh)) { 260 die("Can't open pipe: $!"); 261 } 262 263 require Net::SSH2; 264 265 my $ex; 266 267 # Fork child 268 $self->handle_sigchld(); 269 defined(my $pid = fork()) or die("Can't fork: $!"); 270 if ($pid) { 271 eval { 272 my $ssh2 = Net::SSH2->new(); 273 274 sleep(1); 275 276 unless ($ssh2->connect('127.0.0.1', $port)) { 277 my ($err_code, $err_name, $err_str) = $ssh2->error(); 278 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 279 } 280 281 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 282 my ($err_code, $err_name, $err_str) = $ssh2->error(); 283 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 284 } 285 286 $ssh2->disconnect(); 287 }; 288 289 if ($@) { 290 $ex = $@; 291 } 292 293 $wfh->print("done\n"); 294 $wfh->flush(); 295 296 } else { 297 eval { server_wait($config_file, $rfh) }; 298 if ($@) { 299 warn($@); 300 exit 1; 301 } 302 303 exit 0; 304 } 305 306 # Stop server 307 server_stop($pid_file); 308 309 $self->assert_child_ok($pid); 310 311 if ($ex) { 312 test_append_logfile($log_file, $ex); 313 unlink($log_file); 314 315 die($ex); 316 } 317 318 unlink($log_file, $db_file); 319} 320 321sub ssh2_auth_publickey_rsa_sql_var_U { 322 my $self = shift; 323 my $tmpdir = $self->{tmpdir}; 324 325 my $config_file = "$tmpdir/sftp.conf"; 326 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 327 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 328 329 my $log_file = test_get_logfile(); 330 331 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 332 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 333 334 my $user = 'proftpd'; 335 my $passwd = 'test'; 336 my $group = 'ftpd'; 337 my $home_dir = File::Spec->rel2abs($tmpdir); 338 my $uid = 500; 339 my $gid = 500; 340 341 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 342 343 my $rsa_data = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7jGx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00ydqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84uO6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMmef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPkByq2pv4VBo953gK7f1AQ=='; 344 345 # Make sure that, if we're running as root, that the home directory has 346 # permissions/privs set for the account we create 347 if ($< == 0) { 348 unless (chmod(0755, $home_dir)) { 349 die("Can't set perms on $home_dir to 0755: $!"); 350 } 351 352 unless (chown($uid, $gid, $home_dir)) { 353 die("Can't set owner of $home_dir to $uid/$gid: $!"); 354 } 355 } 356 357 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 358 '/bin/bash'); 359 auth_group_write($auth_group_file, $group, $gid, $user); 360 361 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 362 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 363 364 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key'); 365 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub'); 366 367 my $config = { 368 PidFile => $pid_file, 369 ScoreboardFile => $scoreboard_file, 370 SystemLog => $log_file, 371 TraceLog => $log_file, 372 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 373 374 AuthUserFile => $auth_user_file, 375 AuthGroupFile => $auth_group_file, 376 377 IfModules => { 378 'mod_delay.c' => { 379 DelayEngine => 'off', 380 }, 381 382 'mod_sql_sqlite.c' => { 383 SQLAuthenticate => 'users usersetfast', 384 SQLConnectInfo => $db_file, 385 SQLLogFile => $log_file, 386 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%U\'"', 387 }, 388 389 'mod_sftp.c' => [ 390 "SFTPEngine on", 391 "SFTPLog $log_file", 392 "SFTPHostKey $rsa_host_key", 393 "SFTPHostKey $dsa_host_key", 394 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 395 ], 396 }, 397 }; 398 399 my ($port, $config_user, $config_group) = config_write($config_file, $config); 400 401 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 402 403 my $fh; 404 if (open($fh, "> $db_script")) { 405 print $fh <<EOS; 406CREATE TABLE sftpuserkeys ( 407 name TEXT NOT NULL PRIMARY KEY, 408 key BLOB NOT NULL 409); 410 411INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_data'); 412INSERT INTO sftpuserkeys (name, key) VALUES ('$config_user', '$rsa_data'); 413 414CREATE TABLE users ( 415 userid TEXT NOT NULL PRIMARY KEY, 416 passwd TEXT, 417 uid INTEGER, 418 gid INTEGER, 419 homedir TEXT, 420 shell TEXT 421); 422 423EOS 424 unless (close($fh)) { 425 die("Can't write $db_script: $!"); 426 } 427 428 } else { 429 die("Can't open $db_script: $!"); 430 } 431 432 my $cmd = "sqlite3 $db_file < $db_script"; 433 if ($ENV{TEST_VERBOSE}) { 434 print STDERR "Executing sqlite3: $cmd\n"; 435 } 436 437 my @output = `$cmd`; 438 if (scalar(@output) && 439 $ENV{TEST_VERBOSE}) { 440 print STDERR "Output: ", join('', @output), "\n"; 441 } 442 443 unlink($db_script); 444 445 # Open pipes, for use between the parent and child processes. Specifically, 446 # the child will indicate when it's done with its test by writing a message 447 # to the parent. 448 my ($rfh, $wfh); 449 unless (pipe($rfh, $wfh)) { 450 die("Can't open pipe: $!"); 451 } 452 453 require Net::SSH2; 454 455 my $ex; 456 457 # Fork child 458 $self->handle_sigchld(); 459 defined(my $pid = fork()) or die("Can't fork: $!"); 460 if ($pid) { 461 eval { 462 my $ssh2 = Net::SSH2->new(); 463 464 sleep(1); 465 466 unless ($ssh2->connect('127.0.0.1', $port)) { 467 my ($err_code, $err_name, $err_str) = $ssh2->error(); 468 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 469 } 470 471 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 472 my ($err_code, $err_name, $err_str) = $ssh2->error(); 473 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 474 } 475 476 $ssh2->disconnect(); 477 }; 478 479 if ($@) { 480 $ex = $@; 481 } 482 483 $wfh->print("done\n"); 484 $wfh->flush(); 485 486 } else { 487 eval { server_wait($config_file, $rfh) }; 488 if ($@) { 489 warn($@); 490 exit 1; 491 } 492 493 exit 0; 494 } 495 496 # Stop server 497 server_stop($pid_file); 498 499 $self->assert_child_ok($pid); 500 501 if ($ex) { 502 test_append_logfile($log_file, $ex); 503 unlink($log_file); 504 505 die($ex); 506 } 507 508 unlink($log_file, $db_file); 509} 510 511sub ssh2_auth_publickey_rsa_sql_var_u { 512 my $self = shift; 513 my $tmpdir = $self->{tmpdir}; 514 515 my $config_file = "$tmpdir/sftp.conf"; 516 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 517 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 518 519 my $log_file = test_get_logfile(); 520 521 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 522 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 523 524 my $user = 'proftpd'; 525 my $passwd = 'test'; 526 my $group = 'ftpd'; 527 my $home_dir = File::Spec->rel2abs($tmpdir); 528 my $uid = 500; 529 my $gid = 500; 530 531 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 532 533 my $rsa_data = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7jGx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00ydqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84uO6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMmef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPkByq2pv4VBo953gK7f1AQ=='; 534 535 # Make sure that, if we're running as root, that the home directory has 536 # permissions/privs set for the account we create 537 if ($< == 0) { 538 unless (chmod(0755, $home_dir)) { 539 die("Can't set perms on $home_dir to 0755: $!"); 540 } 541 542 unless (chown($uid, $gid, $home_dir)) { 543 die("Can't set owner of $home_dir to $uid/$gid: $!"); 544 } 545 } 546 547 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 548 '/bin/bash'); 549 auth_group_write($auth_group_file, $group, $gid, $user); 550 551 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 552 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 553 554 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key'); my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub'); 555 556 my $config = { 557 PidFile => $pid_file, 558 ScoreboardFile => $scoreboard_file, 559 SystemLog => $log_file, 560 TraceLog => $log_file, 561 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 562 563 AuthUserFile => $auth_user_file, 564 AuthGroupFile => $auth_group_file, 565 566 IfModules => { 567 'mod_delay.c' => { 568 DelayEngine => 'off', 569 }, 570 571 'mod_sql_sqlite.c' => { 572 SQLAuthenticate => 'off', 573 SQLConnectInfo => $db_file, 574 SQLLogFile => $log_file, 575 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%u\'"', 576 }, 577 578 'mod_sftp.c' => [ 579 "SFTPEngine on", 580 "SFTPLog $log_file", 581 "SFTPHostKey $rsa_host_key", 582 "SFTPHostKey $dsa_host_key", 583 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 584 ], 585 }, 586 }; 587 588 my ($port, $config_user, $config_group) = config_write($config_file, $config); 589 590 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 591 592 my $fh; 593 if (open($fh, "> $db_script")) { 594 print $fh <<EOS; 595CREATE TABLE sftpuserkeys ( 596 name TEXT NOT NULL PRIMARY KEY, 597 key BLOB NOT NULL 598); 599 600INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_data'); 601INSERT INTO sftpuserkeys (name, key) VALUES ('$config_user', '$rsa_data'); 602EOS 603 unless (close($fh)) { 604 die("Can't write $db_script: $!"); 605 } 606 607 } else { 608 die("Can't open $db_script: $!"); 609 } 610 611 my $cmd = "sqlite3 $db_file < $db_script"; 612 if ($ENV{TEST_VERBOSE}) { 613 print STDERR "Executing sqlite3: $cmd\n"; 614 } 615 616 my @output = `$cmd`; 617 if (scalar(@output) && 618 $ENV{TEST_VERBOSE}) { 619 print STDERR "Output: ", join('', @output), "\n"; 620 } 621 622 unlink($db_script); 623 624 # Open pipes, for use between the parent and child processes. Specifically, 625 # the child will indicate when it's done with its test by writing a message 626 # to the parent. 627 my ($rfh, $wfh); 628 unless (pipe($rfh, $wfh)) { 629 die("Can't open pipe: $!"); 630 } 631 632 require Net::SSH2; 633 634 my $ex; 635 636 # Fork child 637 $self->handle_sigchld(); 638 defined(my $pid = fork()) or die("Can't fork: $!"); 639 if ($pid) { 640 eval { 641 my $ssh2 = Net::SSH2->new(); 642 643 sleep(1); 644 645 unless ($ssh2->connect('127.0.0.1', $port)) { 646 my ($err_code, $err_name, $err_str) = $ssh2->error(); 647 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 648 } 649 650 # This should fail, since %u will resolve to '-' (the user has not 651 # been authenticated yet). 652 if ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 653 die("RSA publickey authentication succeeded unexpectly"); 654 } 655 656 my ($err_code, $err_name, $err_str) = $ssh2->error(); 657 my $expected = 'LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED'; 658 $self->assert($expected eq $err_name, 659 test_msg("Expected error name '$expected', got '$err_name'")); 660 661 $ssh2->disconnect(); 662 }; 663 664 if ($@) { 665 $ex = $@; 666 } 667 668 $wfh->print("done\n"); 669 $wfh->flush(); 670 671 } else { 672 eval { server_wait($config_file, $rfh) }; 673 if ($@) { 674 warn($@); 675 exit 1; 676 } 677 678 exit 0; 679 } 680 681 # Stop server 682 server_stop($pid_file); 683 684 $self->assert_child_ok($pid); 685 686 if ($ex) { 687 test_append_logfile($log_file, $ex); 688 unlink($log_file); 689 690 die($ex); 691 } 692 693 unlink($log_file, $db_file); 694} 695 696sub ssh2_auth_publickey_dsa_sql { 697 my $self = shift; 698 my $tmpdir = $self->{tmpdir}; 699 700 my $config_file = "$tmpdir/sftp.conf"; 701 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 702 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 703 704 my $log_file = test_get_logfile(); 705 706 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 707 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 708 709 my $user = 'proftpd'; 710 my $passwd = 'test'; 711 my $group = 'ftpd'; 712 my $home_dir = File::Spec->rel2abs($tmpdir); 713 my $uid = 500; 714 my $gid = 500; 715 716 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 717 718 my $dsa_data = 'AAAAB3NzaC1kc3MAAACBAJWsBFKoQ1HdluDnVacaPm+PDPuXAMxwpplFYafjDCye5Y2FZEjSA8GlLAsEk3XCw6JK2+ciE0I/XXn3+3cAkrdjDKQDRn8IcAANatgLSSjxS9XN4oNzKtrjSs3hOhv5ADhwKMcIhwSSf0cVRH9sGjQF3IiJBVnQjz6i//v+97otAAAAFQDqbZr3aGXlY0Q3UYS3XRNV8ZdWLwAAAIBVZ00AvPF6Kh9GUvXdUAEtNfe1JIThzC4rSc2Fyz3/mQA+GLUHtEq1ZLpO5D4PCjxHcR7N1tIarqR1f0GGjDGvaPocPNtMpaVxCsLWTCnua5fhIgZ3H24mSzd/j2TSDqIeV0DWWiWsFOTF+UzbxSDAinfDjLGV0XQ1jRhgoHS3hAAAAIAfONFEnSPWVLEl0Hv9yAozdWBmkyDijkk0zWWGh17z/Ef4ZRo5bwjsOQCx3c3XswdjDacoqUjep8EMs8MI4LpOx8SybGOGu8xyW3ceT+rdP1/S62JxBeL7SaIwCH0O9sPqeh44l8OHIKVh6lmyUr1KQFOnNJ/pRF0JutY1UDEUMQ=='; 719 720 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 721 722 my $fh; 723 if (open($fh, "> $db_script")) { 724 print $fh <<EOS; 725CREATE TABLE sftpuserkeys ( 726 name TEXT NOT NULL PRIMARY KEY, 727 key BLOB NOT NULL 728); 729 730INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$dsa_data'); 731EOS 732 unless (close($fh)) { 733 die("Can't write $db_script: $!"); 734 } 735 736 } else { 737 die("Can't open $db_script: $!"); 738 } 739 740 my $cmd = "sqlite3 $db_file < $db_script"; 741 if ($ENV{TEST_VERBOSE}) { 742 print STDERR "Executing sqlite3: $cmd\n"; 743 } 744 745 my @output = `$cmd`; 746 747 unlink($db_script); 748 749 # Make sure that, if we're running as root, that the home directory has 750 # permissions/privs set for the account we create 751 if ($< == 0) { 752 unless (chmod(0755, $home_dir)) { 753 die("Can't set perms on $home_dir to 0755: $!"); 754 } 755 756 unless (chown($uid, $gid, $home_dir)) { 757 die("Can't set owner of $home_dir to $uid/$gid: $!"); 758 } 759 } 760 761 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 762 '/bin/bash'); 763 auth_group_write($auth_group_file, $group, $gid, $user); 764 765 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 766 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 767 768 my $dsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key'); 769 my $dsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key.pub'); 770 771 my $config = { 772 PidFile => $pid_file, 773 ScoreboardFile => $scoreboard_file, 774 SystemLog => $log_file, 775 TraceLog => $log_file, 776 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 777 778 AuthUserFile => $auth_user_file, 779 AuthGroupFile => $auth_group_file, 780 781 IfModules => { 782 'mod_delay.c' => { 783 DelayEngine => 'off', 784 }, 785 786 'mod_sql_sqlite.c' => { 787 SQLAuthenticate => 'off', 788 SQLConnectInfo => $db_file, 789 SQLLogFile => $log_file, 790 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 791 }, 792 793 'mod_sftp.c' => [ 794 "SFTPEngine on", 795 "SFTPLog $log_file", 796 "SFTPHostKey $rsa_host_key", 797 "SFTPHostKey $dsa_host_key", 798 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 799 ], 800 }, 801 }; 802 803 my ($port, $config_user, $config_group) = config_write($config_file, $config); 804 805 # Open pipes, for use between the parent and child processes. Specifically, 806 # the child will indicate when it's done with its test by writing a message 807 # to the parent. 808 my ($rfh, $wfh); 809 unless (pipe($rfh, $wfh)) { 810 die("Can't open pipe: $!"); 811 } 812 813 require Net::SSH2; 814 815 my $ex; 816 817 # Fork child 818 $self->handle_sigchld(); 819 defined(my $pid = fork()) or die("Can't fork: $!"); 820 if ($pid) { 821 eval { 822 my $ssh2 = Net::SSH2->new(); 823 824 sleep(1); 825 826 unless ($ssh2->connect('127.0.0.1', $port)) { 827 my ($err_code, $err_name, $err_str) = $ssh2->error(); 828 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 829 } 830 831 unless ($ssh2->auth_publickey($user, $dsa_pub_key, $dsa_priv_key)) { 832 my ($err_code, $err_name, $err_str) = $ssh2->error(); 833 die("DSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 834 } 835 836 $ssh2->disconnect(); 837 }; 838 839 if ($@) { 840 $ex = $@; 841 } 842 843 $wfh->print("done\n"); 844 $wfh->flush(); 845 846 } else { 847 eval { server_wait($config_file, $rfh) }; 848 if ($@) { 849 warn($@); 850 exit 1; 851 } 852 853 exit 0; 854 } 855 856 # Stop server 857 server_stop($pid_file); 858 859 $self->assert_child_ok($pid); 860 861 if ($ex) { 862 test_append_logfile($log_file, $ex); 863 unlink($log_file); 864 865 die($ex); 866 } 867 868 unlink($log_file, $db_file); 869} 870 871sub ssh2_auth_publickey_rsa_dsa_sql { 872 my $self = shift; 873 my $tmpdir = $self->{tmpdir}; 874 875 my $config_file = "$tmpdir/sftp.conf"; 876 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 877 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 878 879 my $log_file = test_get_logfile(); 880 881 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 882 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 883 884 my $user = 'proftpd'; 885 my $passwd = 'test'; 886 my $group = 'ftpd'; 887 my $home_dir = File::Spec->rel2abs($tmpdir); 888 my $uid = 500; 889 my $gid = 500; 890 891 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 892 893 my $rsa_data = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7jGx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00ydqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84uO6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMmef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPkByq2pv4VBo953gK7f1AQ=='; 894 my $dsa_data = 'AAAAB3NzaC1kc3MAAACBAJWsBFKoQ1HdluDnVacaPm+PDPuXAMxwpplFYafjDCye5Y2FZEjSA8GlLAsEk3XCw6JK2+ciE0I/XXn3+3cAkrdjDKQDRn8IcAANatgLSSjxS9XN4oNzKtrjSs3hOhv5ADhwKMcIhwSSf0cVRH9sGjQF3IiJBVnQjz6i//v+97otAAAAFQDqbZr3aGXlY0Q3UYS3XRNV8ZdWLwAAAIBVZ00AvPF6Kh9GUvXdUAEtNfe1JIThzC4rSc2Fyz3/mQA+GLUHtEq1ZLpO5D4PCjxHcR7N1tIarqR1f0GGjDGvaPocPNtMpaVxCsLWTCnua5fhIgZ3H24mSzd/j2TSDqIeV0DWWiWsFOTF+UzbxSDAinfDjLGV0XQ1jRhgoHS3hAAAAIAfONFEnSPWVLEl0Hv9yAozdWBmkyDijkk0zWWGh17z/Ef4ZRo5bwjsOQCx3c3XswdjDacoqUjep8EMs8MI4LpOx8SybGOGu8xyW3ceT+rdP1/S62JxBeL7SaIwCH0O9sPqeh44l8OHIKVh6lmyUr1KQFOnNJ/pRF0JutY1UDEUMQ=='; 895 896 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 897 898 my $fh; 899 if (open($fh, "> $db_script")) { 900 print $fh <<EOS; 901CREATE TABLE sftpuserkeys ( 902 name TEXT NOT NULL, 903 key BLOB NOT NULL 904); 905 906INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_data'); 907INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$dsa_data'); 908EOS 909 unless (close($fh)) { 910 die("Can't write $db_script: $!"); 911 } 912 913 } else { 914 die("Can't open $db_script: $!"); 915 } 916 917 my $cmd = "sqlite3 $db_file < $db_script"; 918 if ($ENV{TEST_VERBOSE}) { 919 print STDERR "Executing sqlite3: $cmd\n"; 920 } 921 922 my @output = `$cmd`; 923 924 unlink($db_script); 925 926 # Make sure that, if we're running as root, that the home directory has 927 # permissions/privs set for the account we create 928 if ($< == 0) { 929 unless (chmod(0755, $home_dir)) { 930 die("Can't set perms on $home_dir to 0755: $!"); 931 } 932 933 unless (chown($uid, $gid, $home_dir)) { 934 die("Can't set owner of $home_dir to $uid/$gid: $!"); 935 } 936 } 937 938 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 939 '/bin/bash'); 940 auth_group_write($auth_group_file, $group, $gid, $user); 941 942 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 943 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 944 945 my $dsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key'); 946 my $dsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key.pub'); 947 948 my $config = { 949 PidFile => $pid_file, 950 ScoreboardFile => $scoreboard_file, 951 SystemLog => $log_file, 952 TraceLog => $log_file, 953 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 954 955 AuthUserFile => $auth_user_file, 956 AuthGroupFile => $auth_group_file, 957 958 IfModules => { 959 'mod_delay.c' => { 960 DelayEngine => 'off', 961 }, 962 963 'mod_sql_sqlite.c' => { 964 SQLAuthenticate => 'off', 965 SQLConnectInfo => $db_file, 966 SQLLogFile => $log_file, 967 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 968 }, 969 970 'mod_sftp.c' => [ 971 "SFTPEngine on", 972 "SFTPLog $log_file", 973 "SFTPHostKey $rsa_host_key", 974 "SFTPHostKey $dsa_host_key", 975 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 976 ], 977 }, 978 }; 979 980 my ($port, $config_user, $config_group) = config_write($config_file, $config); 981 982 # Open pipes, for use between the parent and child processes. Specifically, 983 # the child will indicate when it's done with its test by writing a message 984 # to the parent. 985 my ($rfh, $wfh); 986 unless (pipe($rfh, $wfh)) { 987 die("Can't open pipe: $!"); 988 } 989 990 require Net::SSH2; 991 992 my $ex; 993 994 # Fork child 995 $self->handle_sigchld(); 996 defined(my $pid = fork()) or die("Can't fork: $!"); 997 if ($pid) { 998 eval { 999 my $ssh2 = Net::SSH2->new(); 1000 1001 sleep(1); 1002 1003 unless ($ssh2->connect('127.0.0.1', $port)) { 1004 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1005 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 1006 } 1007 1008 unless ($ssh2->auth_publickey($user, $dsa_pub_key, $dsa_priv_key)) { 1009 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1010 die("DSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 1011 } 1012 1013 $ssh2->disconnect(); 1014 }; 1015 1016 if ($@) { 1017 $ex = $@; 1018 } 1019 1020 $wfh->print("done\n"); 1021 $wfh->flush(); 1022 1023 } else { 1024 eval { server_wait($config_file, $rfh) }; 1025 if ($@) { 1026 warn($@); 1027 exit 1; 1028 } 1029 1030 exit 0; 1031 } 1032 1033 # Stop server 1034 server_stop($pid_file); 1035 1036 $self->assert_child_ok($pid); 1037 1038 if ($ex) { 1039 test_append_logfile($log_file, $ex); 1040 unlink($log_file); 1041 1042 die($ex); 1043 } 1044 1045 unlink($log_file, $db_file); 1046} 1047 1048sub ssh2_auth_publickey_rsa_sql_rfc4716 { 1049 my $self = shift; 1050 my $tmpdir = $self->{tmpdir}; 1051 1052 my $config_file = "$tmpdir/sftp.conf"; 1053 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 1054 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 1055 1056 my $log_file = test_get_logfile(); 1057 1058 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 1059 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 1060 1061 my $user = 'proftpd'; 1062 my $passwd = 'test'; 1063 my $group = 'ftpd'; 1064 my $home_dir = File::Spec->rel2abs($tmpdir); 1065 my $uid = 500; 1066 my $gid = 500; 1067 1068 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 1069 1070 my $rsa_rfc4716_data = '---- BEGIN SSH2 PUBLIC KEY ---- 1071Comment: "2048-bit RSA, converted from OpenSSH by tj@familiar" 1072AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7j 1073Gx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00y 1074dqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84u 1075O6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMm 1076ef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPk 1077Byq2pv4VBo953gK7f1AQ== 1078---- END SSH2 PUBLIC KEY ----'; 1079 1080 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 1081 1082 my $fh; 1083 if (open($fh, "> $db_script")) { 1084 print $fh <<EOS; 1085CREATE TABLE sftpuserkeys ( 1086 name TEXT NOT NULL PRIMARY KEY, 1087 key BLOB NOT NULL 1088); 1089 1090INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_rfc4716_data'); 1091EOS 1092 unless (close($fh)) { 1093 die("Can't write $db_script: $!"); 1094 } 1095 1096 } else { 1097 die("Can't open $db_script: $!"); 1098 } 1099 1100 my $cmd = "sqlite3 $db_file < $db_script"; 1101 if ($ENV{TEST_VERBOSE}) { 1102 print STDERR "Executing sqlite3: $cmd\n"; 1103 } 1104 1105 my @output = `$cmd`; 1106 1107 unlink($db_script); 1108 1109 # Make sure that, if we're running as root, that the home directory has 1110 # permissions/privs set for the account we create 1111 if ($< == 0) { 1112 unless (chmod(0755, $home_dir)) { 1113 die("Can't set perms on $home_dir to 0755: $!"); 1114 } 1115 1116 unless (chown($uid, $gid, $home_dir)) { 1117 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1118 } 1119 } 1120 1121 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1122 '/bin/bash'); 1123 auth_group_write($auth_group_file, $group, $gid, $user); 1124 1125 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 1126 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 1127 1128 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key'); 1129 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub'); 1130 1131 my $config = { 1132 PidFile => $pid_file, 1133 ScoreboardFile => $scoreboard_file, 1134 SystemLog => $log_file, 1135 TraceLog => $log_file, 1136 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 1137 1138 AuthUserFile => $auth_user_file, 1139 AuthGroupFile => $auth_group_file, 1140 1141 IfModules => { 1142 'mod_delay.c' => { 1143 DelayEngine => 'off', 1144 }, 1145 1146 'mod_sql_sqlite.c' => { 1147 SQLAuthenticate => 'off', 1148 SQLConnectInfo => $db_file, 1149 SQLLogFile => $log_file, 1150 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 1151 }, 1152 1153 'mod_sftp.c' => [ 1154 "SFTPEngine on", 1155 "SFTPLog $log_file", 1156 "SFTPHostKey $rsa_host_key", 1157 "SFTPHostKey $dsa_host_key", 1158 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 1159 ], 1160 }, 1161 }; 1162 1163 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1164 1165 # Open pipes, for use between the parent and child processes. Specifically, 1166 # the child will indicate when it's done with its test by writing a message 1167 # to the parent. 1168 my ($rfh, $wfh); 1169 unless (pipe($rfh, $wfh)) { 1170 die("Can't open pipe: $!"); 1171 } 1172 1173 require Net::SSH2; 1174 1175 my $ex; 1176 1177 # Fork child 1178 $self->handle_sigchld(); 1179 defined(my $pid = fork()) or die("Can't fork: $!"); 1180 if ($pid) { 1181 eval { 1182 my $ssh2 = Net::SSH2->new(); 1183 1184 sleep(1); 1185 1186 unless ($ssh2->connect('127.0.0.1', $port)) { 1187 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1188 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 1189 } 1190 1191 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 1192 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1193 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 1194 } 1195 1196 $ssh2->disconnect(); 1197 }; 1198 1199 if ($@) { 1200 $ex = $@; 1201 } 1202 1203 $wfh->print("done\n"); 1204 $wfh->flush(); 1205 1206 } else { 1207 eval { server_wait($config_file, $rfh) }; 1208 if ($@) { 1209 warn($@); 1210 exit 1; 1211 } 1212 1213 exit 0; 1214 } 1215 1216 # Stop server 1217 server_stop($pid_file); 1218 1219 $self->assert_child_ok($pid); 1220 1221 if ($ex) { 1222 test_append_logfile($log_file, $ex); 1223 unlink($log_file); 1224 1225 die($ex); 1226 } 1227 1228 unlink($log_file, $db_file); 1229} 1230 1231sub ssh2_auth_publickey_rsa_sql_rfc4716_with_continued_line { 1232 my $self = shift; 1233 my $tmpdir = $self->{tmpdir}; 1234 1235 my $config_file = "$tmpdir/sftp.conf"; 1236 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 1237 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 1238 1239 my $log_file = test_get_logfile(); 1240 1241 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 1242 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 1243 1244 my $user = 'proftpd'; 1245 my $passwd = 'test'; 1246 my $group = 'ftpd'; 1247 my $home_dir = File::Spec->rel2abs($tmpdir); 1248 my $uid = 500; 1249 my $gid = 500; 1250 1251 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 1252 1253 my $rsa_rfc4716_data = '---- BEGIN SSH2 PUBLIC KEY ---- 1254Subject: at93590 1255Comment: "2048-bit dsa, at93590@isgswapd4n2, Tue Jun 22 2010 15:00:34 \ 1256-0400" 1257AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7j 1258Gx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00y 1259dqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84u 1260O6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMm 1261ef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPk 1262Byq2pv4VBo953gK7f1AQ== 1263---- END SSH2 PUBLIC KEY ----'; 1264 1265 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 1266 1267 my $fh; 1268 if (open($fh, "> $db_script")) { 1269 print $fh <<EOS; 1270CREATE TABLE sftpuserkeys ( 1271 name TEXT NOT NULL PRIMARY KEY, 1272 key BLOB NOT NULL 1273); 1274 1275INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_rfc4716_data'); 1276EOS 1277 unless (close($fh)) { 1278 die("Can't write $db_script: $!"); 1279 } 1280 1281 } else { 1282 die("Can't open $db_script: $!"); 1283 } 1284 1285 my $cmd = "sqlite3 $db_file < $db_script"; 1286 if ($ENV{TEST_VERBOSE}) { 1287 print STDERR "Executing sqlite3: $cmd\n"; 1288 } 1289 1290 my @output = `$cmd`; 1291 1292 unlink($db_script); 1293 1294 # Make sure that, if we're running as root, that the home directory has 1295 # permissions/privs set for the account we create 1296 if ($< == 0) { 1297 unless (chmod(0755, $home_dir)) { 1298 die("Can't set perms on $home_dir to 0755: $!"); 1299 } 1300 1301 unless (chown($uid, $gid, $home_dir)) { 1302 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1303 } 1304 } 1305 1306 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1307 '/bin/bash'); 1308 auth_group_write($auth_group_file, $group, $gid, $user); 1309 1310 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 1311 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 1312 1313 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key'); 1314 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub'); 1315 1316 my $config = { 1317 PidFile => $pid_file, 1318 ScoreboardFile => $scoreboard_file, 1319 SystemLog => $log_file, 1320 TraceLog => $log_file, 1321 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 1322 1323 AuthUserFile => $auth_user_file, 1324 AuthGroupFile => $auth_group_file, 1325 1326 IfModules => { 1327 'mod_delay.c' => { 1328 DelayEngine => 'off', 1329 }, 1330 1331 'mod_sql_sqlite.c' => { 1332 SQLAuthenticate => 'off', 1333 SQLConnectInfo => $db_file, 1334 SQLLogFile => $log_file, 1335 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 1336 }, 1337 1338 'mod_sftp.c' => [ 1339 "SFTPEngine on", 1340 "SFTPLog $log_file", 1341 "SFTPHostKey $rsa_host_key", 1342 "SFTPHostKey $dsa_host_key", 1343 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 1344 ], 1345 }, 1346 }; 1347 1348 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1349 1350 # Open pipes, for use between the parent and child processes. Specifically, 1351 # the child will indicate when it's done with its test by writing a message 1352 # to the parent. 1353 my ($rfh, $wfh); 1354 unless (pipe($rfh, $wfh)) { 1355 die("Can't open pipe: $!"); 1356 } 1357 1358 require Net::SSH2; 1359 1360 my $ex; 1361 1362 # Fork child 1363 $self->handle_sigchld(); 1364 defined(my $pid = fork()) or die("Can't fork: $!"); 1365 if ($pid) { 1366 eval { 1367 my $ssh2 = Net::SSH2->new(); 1368 1369 sleep(1); 1370 1371 unless ($ssh2->connect('127.0.0.1', $port)) { 1372 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1373 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 1374 } 1375 1376 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 1377 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1378 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 1379 } 1380 1381 $ssh2->disconnect(); 1382 }; 1383 1384 if ($@) { 1385 $ex = $@; 1386 } 1387 1388 $wfh->print("done\n"); 1389 $wfh->flush(); 1390 1391 } else { 1392 eval { server_wait($config_file, $rfh) }; 1393 if ($@) { 1394 warn($@); 1395 exit 1; 1396 } 1397 1398 exit 0; 1399 } 1400 1401 # Stop server 1402 server_stop($pid_file); 1403 1404 $self->assert_child_ok($pid); 1405 1406 if ($ex) { 1407 test_append_logfile($log_file, $ex); 1408 unlink($log_file); 1409 1410 die($ex); 1411 } 1412 1413 unlink($log_file, $db_file); 1414} 1415 1416sub ssh2_auth_publickey_dsa_sql_rfc4716 { 1417 my $self = shift; 1418 my $tmpdir = $self->{tmpdir}; 1419 1420 my $config_file = "$tmpdir/sftp.conf"; 1421 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 1422 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 1423 1424 my $log_file = test_get_logfile(); 1425 1426 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 1427 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 1428 1429 my $user = 'proftpd'; 1430 my $passwd = 'test'; 1431 my $group = 'ftpd'; 1432 my $home_dir = File::Spec->rel2abs($tmpdir); 1433 my $uid = 500; 1434 my $gid = 500; 1435 1436 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 1437 1438 my $dsa_rfc4716_data = ' 1439---- BEGIN SSH2 PUBLIC KEY ---- 1440Comment: "1024-bit DSA, converted from OpenSSH by tj@familiar" 1441AAAAB3NzaC1kc3MAAACBAJWsBFKoQ1HdluDnVacaPm+PDPuXAMxwpplFYafjDCye5Y2FZE 1442jSA8GlLAsEk3XCw6JK2+ciE0I/XXn3+3cAkrdjDKQDRn8IcAANatgLSSjxS9XN4oNzKtrj 1443Ss3hOhv5ADhwKMcIhwSSf0cVRH9sGjQF3IiJBVnQjz6i//v+97otAAAAFQDqbZr3aGXlY0 1444Q3UYS3XRNV8ZdWLwAAAIBVZ00AvPF6Kh9GUvXdUAEtNfe1JIThzC4rSc2Fyz3/mQA+GLUH 1445tEq1ZLpO5D4PCjxHcR7N1tIarqR1f0GGjDGvaPocPNtMpaVxCsLWTCnua5fhIgZ3H24mSz 1446d/j2TSDqIeV0DWWiWsFOTF+UzbxSDAinfDjLGV0XQ1jRhgoHS3hAAAAIAfONFEnSPWVLEl 14470Hv9yAozdWBmkyDijkk0zWWGh17z/Ef4ZRo5bwjsOQCx3c3XswdjDacoqUjep8EMs8MI4L 1448pOx8SybGOGu8xyW3ceT+rdP1/S62JxBeL7SaIwCH0O9sPqeh44l8OHIKVh6lmyUr1KQFOn 1449NJ/pRF0JutY1UDEUMQ== 1450---- END SSH2 PUBLIC KEY ---- 1451'; 1452 1453 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 1454 1455 my $fh; 1456 if (open($fh, "> $db_script")) { 1457 print $fh <<EOS; 1458CREATE TABLE sftpuserkeys ( 1459 name TEXT NOT NULL PRIMARY KEY, 1460 key BLOB NOT NULL 1461); 1462 1463INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$dsa_rfc4716_data'); 1464EOS 1465 unless (close($fh)) { 1466 die("Can't write $db_script: $!"); 1467 } 1468 1469 } else { 1470 die("Can't open $db_script: $!"); 1471 } 1472 1473 my $cmd = "sqlite3 $db_file < $db_script"; 1474 if ($ENV{TEST_VERBOSE}) { 1475 print STDERR "Executing sqlite3: $cmd\n"; 1476 } 1477 1478 my @output = `$cmd`; 1479 1480 unlink($db_script); 1481 1482 # Make sure that, if we're running as root, that the home directory has 1483 # permissions/privs set for the account we create 1484 if ($< == 0) { 1485 unless (chmod(0755, $home_dir)) { 1486 die("Can't set perms on $home_dir to 0755: $!"); 1487 } 1488 1489 unless (chown($uid, $gid, $home_dir)) { 1490 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1491 } 1492 } 1493 1494 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1495 '/bin/bash'); 1496 auth_group_write($auth_group_file, $group, $gid, $user); 1497 1498 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 1499 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 1500 1501 my $dsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key'); 1502 my $dsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key.pub'); 1503 1504 my $config = { 1505 PidFile => $pid_file, 1506 ScoreboardFile => $scoreboard_file, 1507 SystemLog => $log_file, 1508 TraceLog => $log_file, 1509 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 1510 1511 AuthUserFile => $auth_user_file, 1512 AuthGroupFile => $auth_group_file, 1513 1514 IfModules => { 1515 'mod_delay.c' => { 1516 DelayEngine => 'off', 1517 }, 1518 1519 'mod_sql_sqlite.c' => { 1520 SQLAuthenticate => 'off', 1521 SQLConnectInfo => $db_file, 1522 SQLLogFile => $log_file, 1523 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 1524 }, 1525 1526 'mod_sftp.c' => [ 1527 "SFTPEngine on", 1528 "SFTPLog $log_file", 1529 "SFTPHostKey $rsa_host_key", 1530 "SFTPHostKey $dsa_host_key", 1531 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 1532 ], 1533 }, 1534 }; 1535 1536 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1537 1538 # Open pipes, for use between the parent and child processes. Specifically, 1539 # the child will indicate when it's done with its test by writing a message 1540 # to the parent. 1541 my ($rfh, $wfh); 1542 unless (pipe($rfh, $wfh)) { 1543 die("Can't open pipe: $!"); 1544 } 1545 1546 require Net::SSH2; 1547 1548 my $ex; 1549 1550 # Fork child 1551 $self->handle_sigchld(); 1552 defined(my $pid = fork()) or die("Can't fork: $!"); 1553 if ($pid) { 1554 eval { 1555 my $ssh2 = Net::SSH2->new(); 1556 1557 sleep(1); 1558 1559 unless ($ssh2->connect('127.0.0.1', $port)) { 1560 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1561 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 1562 } 1563 1564 unless ($ssh2->auth_publickey($user, $dsa_pub_key, $dsa_priv_key)) { 1565 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1566 die("DSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 1567 } 1568 1569 $ssh2->disconnect(); 1570 }; 1571 1572 if ($@) { 1573 $ex = $@; 1574 } 1575 1576 $wfh->print("done\n"); 1577 $wfh->flush(); 1578 1579 } else { 1580 eval { server_wait($config_file, $rfh) }; 1581 if ($@) { 1582 warn($@); 1583 exit 1; 1584 } 1585 1586 exit 0; 1587 } 1588 1589 # Stop server 1590 server_stop($pid_file); 1591 1592 $self->assert_child_ok($pid); 1593 1594 if ($ex) { 1595 test_append_logfile($log_file, $ex); 1596 unlink($log_file); 1597 1598 die($ex); 1599 } 1600 1601 unlink($log_file, $db_file); 1602} 1603 1604sub ssh2_auth_publickey_rsa_dsa_sql_rfc4716 { 1605 my $self = shift; 1606 my $tmpdir = $self->{tmpdir}; 1607 1608 my $config_file = "$tmpdir/sftp.conf"; 1609 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 1610 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 1611 1612 my $log_file = test_get_logfile(); 1613 1614 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 1615 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 1616 1617 my $user = 'proftpd'; 1618 my $passwd = 'test'; 1619 my $group = 'ftpd'; 1620 my $home_dir = File::Spec->rel2abs($tmpdir); 1621 my $uid = 500; 1622 my $gid = 500; 1623 1624 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 1625 1626 my $rsa_rfc4716_data = '---- BEGIN SSH2 PUBLIC KEY ---- 1627Comment: "2048-bit RSA, converted from OpenSSH by tj@familiar" 1628AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7j 1629Gx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00y 1630dqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84u 1631O6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMm 1632ef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPk 1633Byq2pv4VBo953gK7f1AQ== 1634---- END SSH2 PUBLIC KEY ----'; 1635 my $dsa_rfc4716_data = ' 1636---- BEGIN SSH2 PUBLIC KEY ---- 1637Comment: "1024-bit DSA, converted from OpenSSH by tj@familiar" 1638AAAAB3NzaC1kc3MAAACBAJWsBFKoQ1HdluDnVacaPm+PDPuXAMxwpplFYafjDCye5Y2FZE 1639jSA8GlLAsEk3XCw6JK2+ciE0I/XXn3+3cAkrdjDKQDRn8IcAANatgLSSjxS9XN4oNzKtrj 1640Ss3hOhv5ADhwKMcIhwSSf0cVRH9sGjQF3IiJBVnQjz6i//v+97otAAAAFQDqbZr3aGXlY0 1641Q3UYS3XRNV8ZdWLwAAAIBVZ00AvPF6Kh9GUvXdUAEtNfe1JIThzC4rSc2Fyz3/mQA+GLUH 1642tEq1ZLpO5D4PCjxHcR7N1tIarqR1f0GGjDGvaPocPNtMpaVxCsLWTCnua5fhIgZ3H24mSz 1643d/j2TSDqIeV0DWWiWsFOTF+UzbxSDAinfDjLGV0XQ1jRhgoHS3hAAAAIAfONFEnSPWVLEl 16440Hv9yAozdWBmkyDijkk0zWWGh17z/Ef4ZRo5bwjsOQCx3c3XswdjDacoqUjep8EMs8MI4L 1645pOx8SybGOGu8xyW3ceT+rdP1/S62JxBeL7SaIwCH0O9sPqeh44l8OHIKVh6lmyUr1KQFOn 1646NJ/pRF0JutY1UDEUMQ== 1647---- END SSH2 PUBLIC KEY ---- 1648'; 1649 1650 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 1651 1652 my $fh; 1653 if (open($fh, "> $db_script")) { 1654 print $fh <<EOS; 1655CREATE TABLE sftpuserkeys ( 1656 name TEXT NOT NULL, 1657 key BLOB NOT NULL 1658); 1659 1660INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_rfc4716_data'); 1661INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$dsa_rfc4716_data'); 1662EOS 1663 unless (close($fh)) { 1664 die("Can't write $db_script: $!"); 1665 } 1666 1667 } else { 1668 die("Can't open $db_script: $!"); 1669 } 1670 1671 my $cmd = "sqlite3 $db_file < $db_script"; 1672 if ($ENV{TEST_VERBOSE}) { 1673 print STDERR "Executing sqlite3: $cmd\n"; 1674 } 1675 1676 my @output = `$cmd`; 1677 1678 unlink($db_script); 1679 1680 # Make sure that, if we're running as root, that the home directory has 1681 # permissions/privs set for the account we create 1682 if ($< == 0) { 1683 unless (chmod(0755, $home_dir)) { 1684 die("Can't set perms on $home_dir to 0755: $!"); 1685 } 1686 1687 unless (chown($uid, $gid, $home_dir)) { 1688 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1689 } 1690 } 1691 1692 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1693 '/bin/bash'); 1694 auth_group_write($auth_group_file, $group, $gid, $user); 1695 1696 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 1697 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 1698 1699 my $dsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key'); 1700 my $dsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_dsa_key.pub'); 1701 1702 my $config = { 1703 PidFile => $pid_file, 1704 ScoreboardFile => $scoreboard_file, 1705 SystemLog => $log_file, 1706 TraceLog => $log_file, 1707 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 1708 1709 AuthUserFile => $auth_user_file, 1710 AuthGroupFile => $auth_group_file, 1711 1712 IfModules => { 1713 'mod_delay.c' => { 1714 DelayEngine => 'off', 1715 }, 1716 1717 'mod_sql_sqlite.c' => { 1718 SQLAuthenticate => 'off', 1719 SQLConnectInfo => $db_file, 1720 SQLLogFile => $log_file, 1721 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 1722 }, 1723 1724 'mod_sftp.c' => [ 1725 "SFTPEngine on", 1726 "SFTPLog $log_file", 1727 "SFTPHostKey $rsa_host_key", 1728 "SFTPHostKey $dsa_host_key", 1729 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 1730 ], 1731 }, 1732 }; 1733 1734 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1735 1736 # Open pipes, for use between the parent and child processes. Specifically, 1737 # the child will indicate when it's done with its test by writing a message 1738 # to the parent. 1739 my ($rfh, $wfh); 1740 unless (pipe($rfh, $wfh)) { 1741 die("Can't open pipe: $!"); 1742 } 1743 1744 require Net::SSH2; 1745 1746 my $ex; 1747 1748 # Fork child 1749 $self->handle_sigchld(); 1750 defined(my $pid = fork()) or die("Can't fork: $!"); 1751 if ($pid) { 1752 eval { 1753 my $ssh2 = Net::SSH2->new(); 1754 1755 sleep(1); 1756 1757 unless ($ssh2->connect('127.0.0.1', $port)) { 1758 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1759 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 1760 } 1761 1762 unless ($ssh2->auth_publickey($user, $dsa_pub_key, $dsa_priv_key)) { 1763 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1764 die("DSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 1765 } 1766 1767 $ssh2->disconnect(); 1768 }; 1769 1770 if ($@) { 1771 $ex = $@; 1772 } 1773 1774 $wfh->print("done\n"); 1775 $wfh->flush(); 1776 1777 } else { 1778 eval { server_wait($config_file, $rfh) }; 1779 if ($@) { 1780 warn($@); 1781 exit 1; 1782 } 1783 1784 exit 0; 1785 } 1786 1787 # Stop server 1788 server_stop($pid_file); 1789 1790 $self->assert_child_ok($pid); 1791 1792 if ($ex) { 1793 test_append_logfile($log_file, $ex); 1794 unlink($log_file); 1795 1796 die($ex); 1797 } 1798 1799 unlink($log_file, $db_file); 1800} 1801 1802sub ssh2_auth_publickey_multiple_keys_one_row_bug3942 { 1803 my $self = shift; 1804 my $tmpdir = $self->{tmpdir}; 1805 1806 my $config_file = "$tmpdir/sftp.conf"; 1807 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 1808 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 1809 1810 my $log_file = test_get_logfile(); 1811 1812 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 1813 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 1814 1815 my $user = 'proftpd'; 1816 my $passwd = 'test'; 1817 my $group = 'ftpd'; 1818 my $home_dir = File::Spec->rel2abs($tmpdir); 1819 my $uid = 500; 1820 my $gid = 500; 1821 1822 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 1823 1824 my $rsa_rfc4716_data1 = '---- BEGIN SSH2 PUBLIC KEY ---- 1825Comment: "2048-bit RSA, converted from OpenSSH by tj@familiar" 1826AAAAB3NzaC1yc2EAAAABIwAAAQEAvEm0Jex6M9GBulB6KsOAUR8uk1CCKjx1o2GV8qkOMP 1827Im3sL5642FD2ECoA73zcWs5XktcO72lrI8QxhQmz0Ob7PjobjQq209QoivUsQz9UnupDW1 1828zd9V7tH+ibmslD+LnglfML0WnGLsmvmY3VVJ1dKgXVrxDszhKIWc/QEs2QD9UzmQweBV/7 1829/tYPfVTUnW2THa66zACPdGTqtncy1MxkauSluHsLJ7eDf3g5Vx9BbxgDlavpEa9uuHjEqx 1830An+P2JFm2EKeuqg3rtLNzTt/u4XB/zSEfl/ua1zynSnOxghpE/QDGjuj9hrgGp9OXyfuOZ 1831gG0qd5fdWj6kccmG4PXw== 1832---- END SSH2 PUBLIC KEY ---- 1833'; 1834 1835 my $rsa_rfc4716_data2 = '---- BEGIN SSH2 PUBLIC KEY ---- 1836Comment: "2048-bit RSA, converted from OpenSSH by tj@familiar" 1837AAAAB3NzaC1yc2EAAAABIwAAAQEA1MDOdQ8ddQGd0hNPbO14zFAD1/c0Ontkw3egGGuVDm 183848VTnDNWGWbH5CirShUhjfLzxZkStyepdKFsYXZOeyBaHdqMfEhXhWZ+M7z9B9rUBM6R7W 1839G34v7pzd8bOYDbff25PCITNYk9m/2ZGrFgAK5EChZ9jtxmaqhYWl6xKLilXYkmhId66TTq 1840MgPUrM1sH9QeFV2axQmK1SVEkSzYTaY8WePds5D5cmZLmABAT3UYPQCcrOahISyKazJ9E+ 1841YjoMl9GoniSEiHTPK+XfyND83zIihJO16VxUVUMStR5yHBd133SVar4yKo8fv9wfgOxDcf 1842GLxgWrkgXv/3qR/8zNaQ== 1843---- END SSH2 PUBLIC KEY ---- 1844'; 1845 1846 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 1847 1848 my $fh; 1849 if (open($fh, "> $db_script")) { 1850 print $fh <<EOS; 1851CREATE TABLE sftpuserkeys ( 1852 name TEXT NOT NULL PRIMARY KEY, 1853 key BLOB NOT NULL 1854); 1855 1856INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_rfc4716_data1$rsa_rfc4716_data2'); 1857EOS 1858 unless (close($fh)) { 1859 die("Can't write $db_script: $!"); 1860 } 1861 1862 } else { 1863 die("Can't open $db_script: $!"); 1864 } 1865 1866 my $cmd = "sqlite3 $db_file < $db_script"; 1867 if ($ENV{TEST_VERBOSE}) { 1868 print STDERR "Executing sqlite3: $cmd\n"; 1869 } 1870 1871 my @output = `$cmd`; 1872 if (scalar(@output) && 1873 $ENV{TEST_VERBOSE}) { 1874 print STDERR "Output: ", join('', @output), "\n"; 1875 } 1876 1877 if ($? != 0) { 1878 die("'$cmd' failed"); 1879 } 1880 1881 unlink($db_script); 1882 1883 # Make sure that, if we're running as root, that the home directory has 1884 # permissions/privs set for the account we create 1885 if ($< == 0) { 1886 unless (chmod(0755, $home_dir)) { 1887 die("Can't set perms on $home_dir to 0755: $!"); 1888 } 1889 1890 unless (chown($uid, $gid, $home_dir)) { 1891 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1892 } 1893 } 1894 1895 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1896 '/bin/bash'); 1897 auth_group_write($auth_group_file, $group, $gid, $user); 1898 1899 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 1900 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 1901 1902 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa2048_key2'); 1903 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa2048_key2.pub'); 1904 1905 my $config = { 1906 PidFile => $pid_file, 1907 ScoreboardFile => $scoreboard_file, 1908 SystemLog => $log_file, 1909 TraceLog => $log_file, 1910 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 1911 1912 AuthUserFile => $auth_user_file, 1913 AuthGroupFile => $auth_group_file, 1914 1915 IfModules => { 1916 'mod_delay.c' => { 1917 DelayEngine => 'off', 1918 }, 1919 1920 'mod_sql_sqlite.c' => { 1921 SQLAuthenticate => 'off', 1922 SQLConnectInfo => $db_file, 1923 SQLLogFile => $log_file, 1924 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 1925 }, 1926 1927 'mod_sftp.c' => [ 1928 "SFTPEngine on", 1929 "SFTPLog $log_file", 1930 "SFTPHostKey $rsa_host_key", 1931 "SFTPHostKey $dsa_host_key", 1932 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 1933 ], 1934 }, 1935 }; 1936 1937 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1938 1939 # Open pipes, for use between the parent and child processes. Specifically, 1940 # the child will indicate when it's done with its test by writing a message 1941 # to the parent. 1942 my ($rfh, $wfh); 1943 unless (pipe($rfh, $wfh)) { 1944 die("Can't open pipe: $!"); 1945 } 1946 1947 require Net::SSH2; 1948 1949 my $ex; 1950 1951 # Fork child 1952 $self->handle_sigchld(); 1953 defined(my $pid = fork()) or die("Can't fork: $!"); 1954 if ($pid) { 1955 eval { 1956 my $ssh2 = Net::SSH2->new(); 1957 1958 sleep(3); 1959 1960 unless ($ssh2->connect('127.0.0.1', $port)) { 1961 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1962 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 1963 } 1964 1965 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 1966 my ($err_code, $err_name, $err_str) = $ssh2->error(); 1967 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 1968 } 1969 1970 $ssh2->disconnect(); 1971 }; 1972 1973 if ($@) { 1974 $ex = $@; 1975 } 1976 1977 $wfh->print("done\n"); 1978 $wfh->flush(); 1979 1980 } else { 1981 eval { server_wait($config_file, $rfh) }; 1982 if ($@) { 1983 warn($@); 1984 exit 1; 1985 } 1986 1987 exit 0; 1988 } 1989 1990 # Stop server 1991 server_stop($pid_file); 1992 1993 $self->assert_child_ok($pid); 1994 1995 if ($ex) { 1996 test_append_logfile($log_file, $ex); 1997 unlink($log_file); 1998 1999 die($ex); 2000 } 2001 2002 unlink($log_file, $db_file); 2003} 2004 2005sub get_sessions { 2006 my $db_file = shift; 2007 my $where = shift; 2008 2009 my $sql = "SELECT user, key_fingerprint, key_fingerprint_algo FROM sftpsessions"; 2010 if ($where) { 2011 $sql .= " WHERE $where"; 2012 } 2013 2014 my $cmd = "sqlite3 $db_file \"$sql\""; 2015 2016 if ($ENV{TEST_VERBOSE}) { 2017 print STDERR "Executing sqlite3: $cmd\n"; 2018 } 2019 2020 my $res = join('', `$cmd`); 2021 chomp($res); 2022 2023 # The default sqlite3 delimiter is '|' 2024 return split(/\|/, $res); 2025} 2026 2027sub ssh2_auth_publickey_rsa_sql_fp_env_vars { 2028 my $self = shift; 2029 my $tmpdir = $self->{tmpdir}; 2030 2031 my $config_file = "$tmpdir/sftp.conf"; 2032 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 2033 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 2034 2035 my $log_file = test_get_logfile(); 2036 2037 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 2038 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 2039 2040 my $user = 'proftpd'; 2041 my $passwd = 'test'; 2042 my $group = 'ftpd'; 2043 my $home_dir = File::Spec->rel2abs($tmpdir); 2044 my $uid = 500; 2045 my $gid = 500; 2046 2047 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 2048 2049 my $rsa_data = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7jGx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00ydqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84uO6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMmef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPkByq2pv4VBo953gK7f1AQ=='; 2050 2051 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 2052 2053 my $fh; 2054 if (open($fh, "> $db_script")) { 2055 print $fh <<EOS; 2056CREATE TABLE sftpuserkeys ( 2057 name TEXT NOT NULL PRIMARY KEY, 2058 key BLOB NOT NULL 2059); 2060 2061INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_data'); 2062 2063CREATE TABLE sftpsessions ( 2064 user TEXT NOT NULL PRIMARY KEY, 2065 key_fingerprint TEXT, 2066 key_fingerprint_algo TEXT 2067); 2068EOS 2069 unless (close($fh)) { 2070 die("Can't write $db_script: $!"); 2071 } 2072 2073 } else { 2074 die("Can't open $db_script: $!"); 2075 } 2076 2077 my $cmd = "sqlite3 $db_file < $db_script"; 2078 if ($ENV{TEST_VERBOSE}) { 2079 print STDERR "Executing sqlite3: $cmd\n"; 2080 } 2081 2082 my @output = `$cmd`; 2083 2084 unlink($db_script); 2085 2086 # Make sure that, if we're running as root, that the home directory has 2087 # permissions/privs set for the account we create 2088 if ($< == 0) { 2089 unless (chmod(0755, $home_dir)) { 2090 die("Can't set perms on $home_dir to 0755: $!"); 2091 } 2092 2093 unless (chown($uid, $gid, $home_dir)) { 2094 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2095 } 2096 } 2097 2098 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2099 '/bin/bash'); 2100 auth_group_write($auth_group_file, $group, $gid, $user); 2101 2102 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 2103 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 2104 2105 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key'); 2106 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub'); 2107 2108 my $config = { 2109 PidFile => $pid_file, 2110 ScoreboardFile => $scoreboard_file, 2111 SystemLog => $log_file, 2112 TraceLog => $log_file, 2113 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 2114 2115 AuthUserFile => $auth_user_file, 2116 AuthGroupFile => $auth_group_file, 2117 2118 IfModules => { 2119 'mod_delay.c' => { 2120 DelayEngine => 'off', 2121 }, 2122 2123 'mod_sql_sqlite.c' => [ 2124 'SQLAuthenticate off', 2125 "SQLConnectInfo $db_file", 2126 "SQLLogFile $log_file", 2127 'SQLNamedQuery get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 2128 'SQLNamedQuery log_user_key FREEFORM "INSERT INTO sftpsessions (user, key_fingerprint, key_fingerprint_algo) VALUES (\'%u\', \'%{env:SFTP_USER_PUBLICKEY_FINGERPRINT}\', \'%{env:SFTP_USER_PUBLICKEY_FINGERPRINT_ALGO}\')"', 2129 'SQLLog INIT log_user_key', 2130 ], 2131 2132 'mod_sftp.c' => [ 2133 "SFTPEngine on", 2134 "SFTPLog $log_file", 2135 "SFTPHostKey $rsa_host_key", 2136 "SFTPHostKey $dsa_host_key", 2137 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 2138 ], 2139 }, 2140 }; 2141 2142 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2143 2144 # Open pipes, for use between the parent and child processes. Specifically, 2145 # the child will indicate when it's done with its test by writing a message 2146 # to the parent. 2147 my ($rfh, $wfh); 2148 unless (pipe($rfh, $wfh)) { 2149 die("Can't open pipe: $!"); 2150 } 2151 2152 require Net::SSH2; 2153 2154 my $ex; 2155 2156 # Fork child 2157 $self->handle_sigchld(); 2158 defined(my $pid = fork()) or die("Can't fork: $!"); 2159 if ($pid) { 2160 eval { 2161 my $ssh2 = Net::SSH2->new(); 2162 2163 sleep(1); 2164 2165 unless ($ssh2->connect('127.0.0.1', $port)) { 2166 my ($err_code, $err_name, $err_str) = $ssh2->error(); 2167 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 2168 } 2169 2170 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 2171 my ($err_code, $err_name, $err_str) = $ssh2->error(); 2172 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 2173 } 2174 2175 my $sftp = $ssh2->sftp(); 2176 unless ($sftp) { 2177 my ($err_code, $err_name, $err_str) = $ssh2->error(); 2178 die("Can't use SFTP on SSH2 server: [$err_name] ($err_code) $err_str"); 2179 } 2180 2181 $sftp = undef; 2182 2183 $ssh2->disconnect(); 2184 }; 2185 2186 if ($@) { 2187 $ex = $@; 2188 } 2189 2190 $wfh->print("done\n"); 2191 $wfh->flush(); 2192 2193 } else { 2194 eval { server_wait($config_file, $rfh) }; 2195 if ($@) { 2196 warn($@); 2197 exit 1; 2198 } 2199 2200 exit 0; 2201 } 2202 2203 # Stop server 2204 server_stop($pid_file); 2205 2206 $self->assert_child_ok($pid); 2207 2208 if ($ex) { 2209 test_append_logfile($log_file, $ex); 2210 unlink($log_file); 2211 2212 die($ex); 2213 } 2214 2215 my ($login, $key_fp, $key_fp_algo) = get_sessions($db_file, 2216 "user = \'$user\'"); 2217 2218 my $expected; 2219 2220 $expected = $user; 2221 $self->assert($expected eq $login, 2222 test_msg("Expected user '$expected', got '$login'")); 2223 2224 # The value here depends on the version of OpenSSL we use 2225 my $expected_md5 = 'b8:ce:c2:e8:e8:9c:f7:93:11:a4:79:c2:48:64:19:45'; 2226 my $expected_sha256 = 'ad:13:cf:f3:07:f4:1f:20:95:44:e5:71:d9:e9:3c:9c:fa:4b:2a:d1:0d:90:fb:1f:a5:0e:77:ea:c1:91:f9:37'; 2227 $self->assert($expected_md5 eq $key_fp || $expected_sha256 eq $key_fp, 2228 test_msg("Expected key fingerprint '$expected_md5' or '$expected_sha256', got '$key_fp'")); 2229 2230 $expected_md5 = 'MD5'; 2231 $expected_sha256 = 'SHA256'; 2232 $self->assert($expected_md5 eq $key_fp_algo || $expected_sha256 eq $key_fp_algo, 2233 test_msg("Expected '$expected_md5' or '$expected_sha256', got '$key_fp_algo'")); 2234 2235 unlink($log_file, $db_file); 2236} 2237 2238sub ssh2_auth_publickey_rsa_sql_rfc4716_overlong_comment_bug4155 { 2239 my $self = shift; 2240 my $tmpdir = $self->{tmpdir}; 2241 2242 my $config_file = "$tmpdir/sftp.conf"; 2243 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 2244 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 2245 2246 my $log_file = test_get_logfile(); 2247 2248 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 2249 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 2250 2251 my $user = 'proftpd'; 2252 my $passwd = 'test'; 2253 my $group = 'ftpd'; 2254 my $home_dir = File::Spec->rel2abs($tmpdir); 2255 my $uid = 500; 2256 my $gid = 500; 2257 2258 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 2259 2260 my $rsa_rfc4716_data = '---- BEGIN SSH2 PUBLIC KEY ---- 2261Comment: "2048-bit RSA, converted from OpenSSH by jbaird@fc-qaftp01.corp.follett.com" 2262AAAAB3NzaC1yc2EAAAABIwAAAQEA13H33uYHCPKX+any43mlzsjxrZuFpgdACmCuPa90Kh 2263Xe6hIg6rx5nNLMOuKHfpMEshCQnj9zmtjSGyLZ9ufJv6Wg3SSHTIKQW2HtR9MLM8zzVXDE 2264pcsWQUbwAs7mBdYKlOJxFP3J4PMVAiJe+GnQ889nXkdixB4SRU6LCfrPwg5c1Ho5FOPYys 2265eAxMNjgsR1n8NUDg5COxlktnR+Tunlu/S/7TgcLi+ugvIIEB5vlhaHEZoPIpz2fl15l9FY 2266ueYvzU73ESvUgdNQE16RmKpdmr6WwN9g5mG+tQCMrhWCkk4IAo5gUlx/Go1Osgp2r0ouj1 2267MSJJkwubawXDDPj/RUjw== 2268---- END SSH2 PUBLIC KEY ----'; 2269 2270 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 2271 2272 my $fh; 2273 if (open($fh, "> $db_script")) { 2274 print $fh <<EOS; 2275CREATE TABLE sftpuserkeys ( 2276 name TEXT NOT NULL PRIMARY KEY, 2277 key BLOB NOT NULL 2278); 2279 2280INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_rfc4716_data'); 2281EOS 2282 unless (close($fh)) { 2283 die("Can't write $db_script: $!"); 2284 } 2285 2286 } else { 2287 die("Can't open $db_script: $!"); 2288 } 2289 2290 my $cmd = "sqlite3 $db_file < $db_script"; 2291 if ($ENV{TEST_VERBOSE}) { 2292 print STDERR "Executing sqlite3: $cmd\n"; 2293 } 2294 2295 my @output = `$cmd`; 2296 2297 unlink($db_script); 2298 2299 # Make sure that, if we're running as root, that the home directory has 2300 # permissions/privs set for the account we create 2301 if ($< == 0) { 2302 unless (chmod(0755, $home_dir)) { 2303 die("Can't set perms on $home_dir to 0755: $!"); 2304 } 2305 2306 unless (chown($uid, $gid, $home_dir)) { 2307 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2308 } 2309 } 2310 2311 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2312 '/bin/bash'); 2313 auth_group_write($auth_group_file, $group, $gid, $user); 2314 2315 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 2316 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 2317 2318 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key_bug4155'); 2319 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key_bug4155.pub'); 2320 2321 my $config = { 2322 PidFile => $pid_file, 2323 ScoreboardFile => $scoreboard_file, 2324 SystemLog => $log_file, 2325 TraceLog => $log_file, 2326 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 2327 2328 AuthUserFile => $auth_user_file, 2329 AuthGroupFile => $auth_group_file, 2330 2331 IfModules => { 2332 'mod_delay.c' => { 2333 DelayEngine => 'off', 2334 }, 2335 2336 'mod_sql_sqlite.c' => { 2337 SQLAuthenticate => 'off', 2338 SQLConnectInfo => $db_file, 2339 SQLLogFile => $log_file, 2340 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 2341 }, 2342 2343 'mod_sftp.c' => [ 2344 "SFTPEngine on", 2345 "SFTPLog $log_file", 2346 "SFTPHostKey $rsa_host_key", 2347 "SFTPHostKey $dsa_host_key", 2348 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 2349 ], 2350 }, 2351 }; 2352 2353 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2354 2355 # Open pipes, for use between the parent and child processes. Specifically, 2356 # the child will indicate when it's done with its test by writing a message 2357 # to the parent. 2358 my ($rfh, $wfh); 2359 unless (pipe($rfh, $wfh)) { 2360 die("Can't open pipe: $!"); 2361 } 2362 2363 require Net::SSH2; 2364 2365 my $ex; 2366 2367 # Fork child 2368 $self->handle_sigchld(); 2369 defined(my $pid = fork()) or die("Can't fork: $!"); 2370 if ($pid) { 2371 eval { 2372 my $ssh2 = Net::SSH2->new(); 2373 2374 sleep(1); 2375 2376 unless ($ssh2->connect('127.0.0.1', $port)) { 2377 my ($err_code, $err_name, $err_str) = $ssh2->error(); 2378 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 2379 } 2380 2381 unless ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 2382 my ($err_code, $err_name, $err_str) = $ssh2->error(); 2383 die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str"); 2384 } 2385 2386 $ssh2->disconnect(); 2387 }; 2388 2389 if ($@) { 2390 $ex = $@; 2391 } 2392 2393 $wfh->print("done\n"); 2394 $wfh->flush(); 2395 2396 } else { 2397 eval { server_wait($config_file, $rfh) }; 2398 if ($@) { 2399 warn($@); 2400 exit 1; 2401 } 2402 2403 exit 0; 2404 } 2405 2406 # Stop server 2407 server_stop($pid_file); 2408 2409 $self->assert_child_ok($pid); 2410 2411 if ($ex) { 2412 test_append_logfile($log_file, $ex); 2413 unlink($log_file); 2414 2415 die($ex); 2416 } 2417 2418 unlink($log_file, $db_file); 2419} 2420 2421sub ssh2_auth_publickey_rsa_sql_invalid_format_bug4350 { 2422 my $self = shift; 2423 my $tmpdir = $self->{tmpdir}; 2424 2425 my $config_file = "$tmpdir/sftp.conf"; 2426 my $pid_file = File::Spec->rel2abs("$tmpdir/sftp.pid"); 2427 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/sftp.scoreboard"); 2428 2429 my $log_file = test_get_logfile(); 2430 2431 my $auth_user_file = File::Spec->rel2abs("$tmpdir/sftp.passwd"); 2432 my $auth_group_file = File::Spec->rel2abs("$tmpdir/sftp.group"); 2433 2434 my $user = 'proftpd'; 2435 my $passwd = 'test'; 2436 my $group = 'ftpd'; 2437 my $home_dir = File::Spec->rel2abs($tmpdir); 2438 my $uid = 500; 2439 my $gid = 500; 2440 2441 my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db"); 2442 2443 my $rsa_data = 'foobar'; 2444 my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql"); 2445 2446 my $fh; 2447 if (open($fh, "> $db_script")) { 2448 print $fh <<EOS; 2449CREATE TABLE sftpuserkeys ( 2450 name TEXT NOT NULL PRIMARY KEY, 2451 key BLOB NOT NULL 2452); 2453 2454INSERT INTO sftpuserkeys (name, key) VALUES ('$user', '$rsa_data'); 2455EOS 2456 unless (close($fh)) { 2457 die("Can't write $db_script: $!"); 2458 } 2459 2460 } else { 2461 die("Can't open $db_script: $!"); 2462 } 2463 2464 my $cmd = "sqlite3 $db_file < $db_script"; 2465 if ($ENV{TEST_VERBOSE}) { 2466 print STDERR "Executing sqlite3: $cmd\n"; 2467 } 2468 2469 my @output = `$cmd`; 2470 2471 unlink($db_script); 2472 2473 # Make sure that, if we're running as root, that the home directory has 2474 # permissions/privs set for the account we create 2475 if ($< == 0) { 2476 unless (chmod(0755, $home_dir)) { 2477 die("Can't set perms on $home_dir to 0755: $!"); 2478 } 2479 2480 unless (chown($uid, $gid, $home_dir)) { 2481 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2482 } 2483 } 2484 2485 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2486 '/bin/bash'); 2487 auth_group_write($auth_group_file, $group, $gid, $user); 2488 2489 my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key'); 2490 my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key'); 2491 2492 my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key_bug4155'); 2493 my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key_bug4155.pub'); 2494 2495 my $config = { 2496 PidFile => $pid_file, 2497 ScoreboardFile => $scoreboard_file, 2498 SystemLog => $log_file, 2499 TraceLog => $log_file, 2500 Trace => 'DEFAULT:10 ssh2:20 sftp:20 scp:20', 2501 2502 AuthUserFile => $auth_user_file, 2503 AuthGroupFile => $auth_group_file, 2504 2505 IfModules => { 2506 'mod_delay.c' => { 2507 DelayEngine => 'off', 2508 }, 2509 2510 'mod_sql_sqlite.c' => { 2511 SQLAuthenticate => 'off', 2512 SQLConnectInfo => $db_file, 2513 SQLLogFile => $log_file, 2514 SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"', 2515 }, 2516 2517 'mod_sftp.c' => [ 2518 "SFTPEngine on", 2519 "SFTPLog $log_file", 2520 "SFTPHostKey $rsa_host_key", 2521 "SFTPHostKey $dsa_host_key", 2522 "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys", 2523 ], 2524 }, 2525 }; 2526 2527 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2528 2529 # Open pipes, for use between the parent and child processes. Specifically, 2530 # the child will indicate when it's done with its test by writing a message 2531 # to the parent. 2532 my ($rfh, $wfh); 2533 unless (pipe($rfh, $wfh)) { 2534 die("Can't open pipe: $!"); 2535 } 2536 2537 require Net::SSH2; 2538 2539 my $ex; 2540 2541 # Fork child 2542 $self->handle_sigchld(); 2543 defined(my $pid = fork()) or die("Can't fork: $!"); 2544 if ($pid) { 2545 eval { 2546 my $ssh2 = Net::SSH2->new(); 2547 2548 sleep(1); 2549 2550 unless ($ssh2->connect('127.0.0.1', $port)) { 2551 my ($err_code, $err_name, $err_str) = $ssh2->error(); 2552 die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str"); 2553 } 2554 2555 if ($ssh2->auth_publickey($user, $rsa_pub_key, $rsa_priv_key)) { 2556 die("RSA publickey authentication succeeded unexpectedly"); 2557 } 2558 2559 $ssh2->disconnect(); 2560 }; 2561 2562 if ($@) { 2563 $ex = $@; 2564 } 2565 2566 $wfh->print("done\n"); 2567 $wfh->flush(); 2568 2569 } else { 2570 eval { server_wait($config_file, $rfh) }; 2571 if ($@) { 2572 warn($@); 2573 exit 1; 2574 } 2575 2576 exit 0; 2577 } 2578 2579 # Stop server 2580 server_stop($pid_file); 2581 2582 $self->assert_child_ok($pid); 2583 2584 if ($ex) { 2585 test_append_logfile($log_file, $ex); 2586 unlink($log_file); 2587 2588 die($ex); 2589 } 2590 2591 unlink($log_file, $db_file); 2592} 2593 25941; 2595