mirror of https://github.com/postgres/postgres
Add tests for consistent support of connection strings in frontend programs as well as proper handling of unusual characters in database and user names. These tests were developed for the issues of CVE-2016-5424. To allow testing of names with spaces, change the pg_regress command-line options --create-role and --dbname to split their arguments by comma only, not space or comma as before. Only commas were actually used in existing uses. Noah Misch, Michael Paquier, Peter Eisentrautpull/17/head
parent
e7010ce479
commit
8b845520fb
@ -0,0 +1,142 @@ |
||||
use strict; |
||||
use warnings; |
||||
|
||||
use PostgresNode; |
||||
use TestLib; |
||||
use Test::More tests => 14; |
||||
|
||||
# In a SQL_ASCII database, pgwin32_message_to_UTF16() needs to |
||||
# interpret everything as UTF8. We're going to use byte sequences |
||||
# that aren't valid UTF-8 strings, so that would fail. Use LATIN1, |
||||
# which accepts any byte and has a conversion from each byte to UTF-8. |
||||
$ENV{LC_ALL} = 'C'; |
||||
$ENV{PGCLIENTENCODING} = 'LATIN1'; |
||||
|
||||
# Create database and user names covering the range of LATIN1 |
||||
# characters, for use in a connection string by pg_dumpall. Skip ',' |
||||
# because of pg_regress --create-role, skip [\n\r] because pg_dumpall |
||||
# does not allow them. |
||||
my $dbname1 = generate_ascii_string(1, 9) . |
||||
generate_ascii_string(11, 12) . |
||||
generate_ascii_string(14, 33) . |
||||
($TestLib::windows_os ? '' : '"x"') . # IPC::Run mishandles '"' on Windows |
||||
generate_ascii_string(35, 43) . |
||||
generate_ascii_string(45, 63); # contains '=' |
||||
my $dbname2 = generate_ascii_string(67, 129); # skip 64-66 to keep length to 62 |
||||
my $dbname3 = generate_ascii_string(130, 192); |
||||
my $dbname4 = generate_ascii_string(193, 255); |
||||
|
||||
my $node = get_new_node('main'); |
||||
$node->init(extra => ['--locale=C', '--encoding=LATIN1']); |
||||
# prep pg_hba.conf and pg_ident.conf |
||||
$node->run_log([$ENV{PG_REGRESS}, '--config-auth', $node->data_dir, |
||||
'--create-role', "$dbname1,$dbname2,$dbname3,$dbname4"]); |
||||
$node->start; |
||||
|
||||
my $backupdir = $node->backup_dir; |
||||
my $discard = "$backupdir/discard.sql"; |
||||
my $plain = "$backupdir/plain.sql"; |
||||
my $dirfmt = "$backupdir/dirfmt"; |
||||
|
||||
foreach my $dbname ($dbname1, $dbname2, $dbname3, $dbname4, 'CamelCase') |
||||
{ |
||||
$node->run_log(['createdb', $dbname]); |
||||
$node->run_log(['createuser', '-s', $dbname]); |
||||
} |
||||
|
||||
|
||||
# For these tests, pg_dumpall -r is used because it produces a short |
||||
# dump. |
||||
$node->command_ok(['pg_dumpall', '-r', '-f', $discard, '--dbname', |
||||
$node->connstr($dbname1), '-U', $dbname4], |
||||
'pg_dumpall with long ASCII name 1'); |
||||
$node->command_ok(['pg_dumpall', '-r', '-f', $discard, '--dbname', |
||||
$node->connstr($dbname2), '-U', $dbname3], |
||||
'pg_dumpall with long ASCII name 2'); |
||||
$node->command_ok(['pg_dumpall', '-r', '-f', $discard, '--dbname', |
||||
$node->connstr($dbname3), '-U', $dbname2], |
||||
'pg_dumpall with long ASCII name 3'); |
||||
$node->command_ok(['pg_dumpall', '-r', '-f', $discard, '--dbname', |
||||
$node->connstr($dbname4), '-U', $dbname1], |
||||
'pg_dumpall with long ASCII name 4'); |
||||
$node->command_ok(['pg_dumpall', '-r', '-l', 'dbname=template1'], |
||||
'pg_dumpall -l accepts connection string'); |
||||
|
||||
$node->run_log(['createdb', "foo\n\rbar"]); |
||||
# not sufficient to use -r here |
||||
$node->command_fails(['pg_dumpall', '-f', $discard], |
||||
'pg_dumpall with \n\r in database name'); |
||||
$node->run_log(['dropdb', "foo\n\rbar"]); |
||||
|
||||
|
||||
# make a table, so the parallel worker has something to dump |
||||
$node->safe_psql($dbname1, 'CREATE TABLE t0()'); |
||||
# XXX no printed message when this fails, just SIGPIPE termination |
||||
$node->command_ok(['pg_dump', '-Fd', '-j2', '-f', $dirfmt, |
||||
'-U', $dbname1, $node->connstr($dbname1)], |
||||
'parallel dump'); |
||||
|
||||
# recreate $dbname1 for restore test |
||||
$node->run_log(['dropdb', $dbname1]); |
||||
$node->run_log(['createdb', $dbname1]); |
||||
|
||||
$node->command_ok(['pg_restore', '-v', '-d', 'template1', '-j2', |
||||
'-U', $dbname1, $dirfmt], |
||||
'parallel restore'); |
||||
|
||||
$node->run_log(['dropdb', $dbname1]); |
||||
|
||||
$node->command_ok(['pg_restore', '-C', '-v', '-d', 'template1', '-j2', |
||||
'-U', $dbname1, $dirfmt], |
||||
'parallel restore with create'); |
||||
|
||||
|
||||
$node->command_ok(['pg_dumpall', '-f', $plain, '-U', $dbname1], |
||||
'take full dump'); |
||||
system_log('cat', $plain); |
||||
my($stderr, $result); |
||||
my $bootstrap_super = 'boot'; |
||||
my $restore_super = qq{a'b\\c=d\\ne"f}; |
||||
|
||||
|
||||
# Restore full dump through psql using environment variables for |
||||
# dbname/user connection parameters |
||||
|
||||
my $envar_node = get_new_node('destination_envar'); |
||||
$envar_node->init(extra => ['-U', $bootstrap_super, |
||||
'--locale=C', '--encoding=LATIN1']); |
||||
$envar_node->run_log([$ENV{PG_REGRESS}, |
||||
'--config-auth', $envar_node->data_dir, |
||||
'--create-role', "$bootstrap_super,$restore_super"]); |
||||
$envar_node->start; |
||||
|
||||
# make superuser for restore |
||||
$envar_node->run_log(['createuser', '-U', $bootstrap_super, '-s', $restore_super]); |
||||
|
||||
{ |
||||
local $ENV{PGPORT} = $envar_node->port; |
||||
local $ENV{PGUSER} = $restore_super; |
||||
$result = run_log(['psql', '-X', '-f', $plain], '2>', \$stderr); |
||||
} |
||||
ok($result, 'restore full dump using environment variables for connection parameters'); |
||||
is($stderr, '', 'no dump errors'); |
||||
|
||||
|
||||
# Restore full dump through psql using command-line options for |
||||
# dbname/user connection parameters. "\connect dbname=" forgets |
||||
# user/port from command line. |
||||
|
||||
$restore_super =~ s/"//g if $TestLib::windows_os; # IPC::Run mishandles '"' on Windows |
||||
my $cmdline_node = get_new_node('destination_cmdline'); |
||||
$cmdline_node->init(extra => ['-U', $bootstrap_super, |
||||
'--locale=C', '--encoding=LATIN1']); |
||||
$cmdline_node->run_log([$ENV{PG_REGRESS}, |
||||
'--config-auth', $cmdline_node->data_dir, |
||||
'--create-role', "$bootstrap_super,$restore_super"]); |
||||
$cmdline_node->start; |
||||
$cmdline_node->run_log(['createuser', '-U', $bootstrap_super, '-s', $restore_super]); |
||||
{ |
||||
$result = run_log(['psql', '-p', $cmdline_node->port, '-U', $restore_super, '-X', '-f', $plain], '2>', \$stderr); |
||||
} |
||||
ok($result, 'restore full dump with command-line options for connection parameters'); |
||||
is($stderr, '', 'no dump errors'); |
||||
@ -0,0 +1,38 @@ |
||||
use strict; |
||||
use warnings; |
||||
|
||||
use PostgresNode; |
||||
use TestLib; |
||||
use Test::More tests => 3; |
||||
|
||||
# Tests to check connection string handling in utilities |
||||
|
||||
# In a SQL_ASCII database, pgwin32_message_to_UTF16() needs to |
||||
# interpret everything as UTF8. We're going to use byte sequences |
||||
# that aren't valid UTF-8 strings, so that would fail. Use LATIN1, |
||||
# which accepts any byte and has a conversion from each byte to UTF-8. |
||||
$ENV{LC_ALL} = 'C'; |
||||
$ENV{PGCLIENTENCODING} = 'LATIN1'; |
||||
|
||||
# Create database names covering the range of LATIN1 characters and |
||||
# run the utilities' --all options over them. |
||||
my $dbname1 = generate_ascii_string(1, 63); # contains '=' |
||||
my $dbname2 = generate_ascii_string(67, 129); # skip 64-66 to keep length to 62 |
||||
my $dbname3 = generate_ascii_string(130, 192); |
||||
my $dbname4 = generate_ascii_string(193, 255); |
||||
|
||||
my $node = get_new_node('main'); |
||||
$node->init(extra => ['--locale=C', '--encoding=LATIN1']); |
||||
$node->start; |
||||
|
||||
foreach my $dbname ($dbname1, $dbname2, $dbname3, $dbname4, 'CamelCase') |
||||
{ |
||||
$node->run_log(['createdb', $dbname]); |
||||
} |
||||
|
||||
$node->command_ok([qw(vacuumdb --all --echo --analyze-only)], |
||||
'vacuumdb --all with unusual database names'); |
||||
$node->command_ok([qw(reindexdb --all --echo)], |
||||
'reindexdb --all with unusual database names'); |
||||
$node->command_ok([qw(clusterdb --all --echo --verbose)], |
||||
'clusterdb --all with unusual database names'); |
||||
Loading…
Reference in new issue