|
21 | 21 | use warnings FATAL => 'all'; |
22 | 22 | use PostgreSQL::Test::Utils; |
23 | 23 | use PostgreSQL::Test::Cluster; |
| 24 | +use PostgreSQL::Test::Kerberos; |
24 | 25 | use Test::More; |
25 | 26 | use Time::HiRes qw(usleep); |
26 | 27 |
|
|
34 | 35 | 'Potentially unsafe test GSSAPI/Kerberos not enabled in PG_TEST_EXTRA'; |
35 | 36 | } |
36 | 37 |
|
37 | | -my ($krb5_bin_dir, $krb5_sbin_dir); |
38 | | - |
39 | | -if ($^O eq 'darwin' && -d "/opt/homebrew") |
40 | | -{ |
41 | | - # typical paths for Homebrew on ARM |
42 | | - $krb5_bin_dir = '/opt/homebrew/opt/krb5/bin'; |
43 | | - $krb5_sbin_dir = '/opt/homebrew/opt/krb5/sbin'; |
44 | | -} |
45 | | -elsif ($^O eq 'darwin') |
46 | | -{ |
47 | | - # typical paths for Homebrew on Intel |
48 | | - $krb5_bin_dir = '/usr/local/opt/krb5/bin'; |
49 | | - $krb5_sbin_dir = '/usr/local/opt/krb5/sbin'; |
50 | | -} |
51 | | -elsif ($^O eq 'freebsd') |
52 | | -{ |
53 | | - $krb5_bin_dir = '/usr/local/bin'; |
54 | | - $krb5_sbin_dir = '/usr/local/sbin'; |
55 | | -} |
56 | | -elsif ($^O eq 'linux') |
57 | | -{ |
58 | | - $krb5_sbin_dir = '/usr/sbin'; |
59 | | -} |
60 | | - |
61 | | -my $krb5_config = 'krb5-config'; |
62 | | -my $kinit = 'kinit'; |
63 | | -my $klist = 'klist'; |
64 | | -my $kdb5_util = 'kdb5_util'; |
65 | | -my $kadmin_local = 'kadmin.local'; |
66 | | -my $krb5kdc = 'krb5kdc'; |
67 | | - |
68 | | -if ($krb5_bin_dir && -d $krb5_bin_dir) |
69 | | -{ |
70 | | - $krb5_config = $krb5_bin_dir . '/' . $krb5_config; |
71 | | - $kinit = $krb5_bin_dir . '/' . $kinit; |
72 | | - $klist = $krb5_bin_dir . '/' . $klist; |
73 | | -} |
74 | | -if ($krb5_sbin_dir && -d $krb5_sbin_dir) |
75 | | -{ |
76 | | - $kdb5_util = $krb5_sbin_dir . '/' . $kdb5_util; |
77 | | - $kadmin_local = $krb5_sbin_dir . '/' . $kadmin_local; |
78 | | - $krb5kdc = $krb5_sbin_dir . '/' . $krb5kdc; |
79 | | -} |
80 | | - |
81 | | -my $host = 'auth-test-localhost.postgresql.example.com'; |
82 | | -my $hostaddr = '127.0.0.1'; |
83 | | -my $realm = 'EXAMPLE.COM'; |
84 | | - |
85 | | -my $krb5_conf = "${PostgreSQL::Test::Utils::tmp_check}/krb5.conf"; |
86 | | -my $kdc_conf = "${PostgreSQL::Test::Utils::tmp_check}/kdc.conf"; |
87 | | -my $krb5_cache = "${PostgreSQL::Test::Utils::tmp_check}/krb5cc"; |
88 | | -my $krb5_log = "${PostgreSQL::Test::Utils::log_path}/krb5libs.log"; |
89 | | -my $kdc_log = "${PostgreSQL::Test::Utils::log_path}/krb5kdc.log"; |
90 | | -my $kdc_port = PostgreSQL::Test::Cluster::get_free_port(); |
91 | | -my $kdc_datadir = "${PostgreSQL::Test::Utils::tmp_check}/krb5kdc"; |
92 | | -my $kdc_pidfile = "${PostgreSQL::Test::Utils::tmp_check}/krb5kdc.pid"; |
93 | | -my $keytab = "${PostgreSQL::Test::Utils::tmp_check}/krb5.keytab"; |
94 | | - |
95 | 38 | my $pgpass = "${PostgreSQL::Test::Utils::tmp_check}/.pgpass"; |
96 | 39 |
|
97 | 40 | my $dbname = 'postgres'; |
98 | 41 | my $username = 'test1'; |
99 | 42 | my $application = '001_auth.pl'; |
100 | 43 |
|
101 | | -note "setting up Kerberos"; |
102 | | - |
103 | | -my ($stdout, $krb5_version); |
104 | | -run_log [ $krb5_config, '--version' ], '>', \$stdout |
105 | | - or BAIL_OUT("could not execute krb5-config"); |
106 | | -BAIL_OUT("Heimdal is not supported") if $stdout =~ m/heimdal/; |
107 | | -$stdout =~ m/Kerberos 5 release ([0-9]+\.[0-9]+)/ |
108 | | - or BAIL_OUT("could not get Kerberos version"); |
109 | | -$krb5_version = $1; |
110 | | - |
111 | 44 | # Construct a pgpass file to make sure we don't use it |
112 | 45 | append_to_file($pgpass, '*:*:*:*:abc123'); |
113 | 46 |
|
114 | 47 | chmod 0600, $pgpass or die $!; |
115 | 48 |
|
116 | | -# Build the krb5.conf to use. |
117 | | -# |
118 | | -# Explicitly specify the default (test) realm and the KDC for |
119 | | -# that realm to avoid the Kerberos library trying to look up |
120 | | -# that information in DNS, and also because we're using a |
121 | | -# non-standard KDC port. |
122 | | -# |
123 | | -# Also explicitly disable DNS lookups since this isn't really |
124 | | -# our domain and we shouldn't be causing random DNS requests |
125 | | -# to be sent out (not to mention that broken DNS environments |
126 | | -# can cause the tests to take an extra long time and timeout). |
127 | | -# |
128 | | -# Reverse DNS is explicitly disabled to avoid any issue with a |
129 | | -# captive portal or other cases where the reverse DNS succeeds |
130 | | -# and the Kerberos library uses that as the canonical name of |
131 | | -# the host and then tries to acquire a cross-realm ticket. |
132 | | -append_to_file( |
133 | | - $krb5_conf, |
134 | | - qq![logging] |
135 | | -default = FILE:$krb5_log |
136 | | -kdc = FILE:$kdc_log |
137 | | -
|
138 | | -[libdefaults] |
139 | | -dns_lookup_realm = false |
140 | | -dns_lookup_kdc = false |
141 | | -default_realm = $realm |
142 | | -forwardable = false |
143 | | -rdns = false |
144 | | -
|
145 | | -[realms] |
146 | | -$realm = { |
147 | | - kdc = $hostaddr:$kdc_port |
148 | | -} |
149 | | -!); |
150 | | - |
151 | | -append_to_file( |
152 | | - $kdc_conf, |
153 | | - qq![kdcdefaults] |
154 | | -!); |
155 | | - |
156 | | -# For new-enough versions of krb5, use the _listen settings rather |
157 | | -# than the _ports settings so that we can bind to localhost only. |
158 | | -if ($krb5_version >= 1.15) |
159 | | -{ |
160 | | - append_to_file( |
161 | | - $kdc_conf, |
162 | | - qq!kdc_listen = $hostaddr:$kdc_port |
163 | | -kdc_tcp_listen = $hostaddr:$kdc_port |
164 | | -!); |
165 | | -} |
166 | | -else |
167 | | -{ |
168 | | - append_to_file( |
169 | | - $kdc_conf, |
170 | | - qq!kdc_ports = $kdc_port |
171 | | -kdc_tcp_ports = $kdc_port |
172 | | -!); |
173 | | -} |
174 | | -append_to_file( |
175 | | - $kdc_conf, |
176 | | - qq! |
177 | | -[realms] |
178 | | -$realm = { |
179 | | - database_name = $kdc_datadir/principal |
180 | | - admin_keytab = FILE:$kdc_datadir/kadm5.keytab |
181 | | - acl_file = $kdc_datadir/kadm5.acl |
182 | | - key_stash_file = $kdc_datadir/_k5.$realm |
183 | | -}!); |
184 | | - |
185 | | -mkdir $kdc_datadir or die; |
186 | | - |
187 | | -# Ensure that we use test's config and cache files, not global ones. |
188 | | -$ENV{'KRB5_CONFIG'} = $krb5_conf; |
189 | | -$ENV{'KRB5_KDC_PROFILE'} = $kdc_conf; |
190 | | -$ENV{'KRB5CCNAME'} = $krb5_cache; |
| 49 | +note "setting up Kerberos"; |
191 | 50 |
|
192 | | -my $service_principal = "$ENV{with_krb_srvnam}/$host"; |
| 51 | +my $host = 'auth-test-localhost.postgresql.example.com'; |
| 52 | +my $hostaddr = '127.0.0.1'; |
| 53 | +my $realm = 'EXAMPLE.COM'; |
193 | 54 |
|
194 | | -system_or_bail $kdb5_util, 'create', '-s', '-P', 'secret0'; |
| 55 | +my $krb = PostgreSQL::Test::Kerberos->new($host, $hostaddr, $realm); |
195 | 56 |
|
196 | 57 | my $test1_password = 'secret1'; |
197 | | -system_or_bail $kadmin_local, '-q', "addprinc -pw $test1_password test1"; |
198 | | - |
199 | | -system_or_bail $kadmin_local, '-q', "addprinc -randkey $service_principal"; |
200 | | -system_or_bail $kadmin_local, '-q', "ktadd -k $keytab $service_principal"; |
201 | | - |
202 | | -system_or_bail $krb5kdc, '-P', $kdc_pidfile; |
203 | | - |
204 | | -END |
205 | | -{ |
206 | | - # take care not to change the script's exit value |
207 | | - my $exit_code = $?; |
208 | | - |
209 | | - kill 'INT', `cat $kdc_pidfile` if defined($kdc_pidfile) && -f $kdc_pidfile; |
210 | | - |
211 | | - $? = $exit_code; |
212 | | -} |
| 58 | +$krb->create_principal('test1', $test1_password); |
213 | 59 |
|
214 | 60 | note "setting up PostgreSQL instance"; |
215 | 61 |
|
|
218 | 64 | $node->append_conf( |
219 | 65 | 'postgresql.conf', qq{ |
220 | 66 | listen_addresses = '$hostaddr' |
221 | | -krb_server_keyfile = '$keytab' |
| 67 | +krb_server_keyfile = '$krb->{keytab}' |
222 | 68 | log_connections = on |
223 | 69 | lc_messages = 'C' |
224 | 70 | }); |
@@ -332,8 +178,7 @@ sub test_query |
332 | 178 |
|
333 | 179 | test_access($node, 'test1', 'SELECT true', 2, '', 'fails without ticket'); |
334 | 180 |
|
335 | | -run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?); |
336 | | -run_log [ $klist, '-f' ] or BAIL_OUT($?); |
| 181 | +$krb->create_ticket('test1', $test1_password); |
337 | 182 |
|
338 | 183 | test_access( |
339 | 184 | $node, |
@@ -475,10 +320,8 @@ sub test_query |
475 | 320 | hostgssenc all all $hostaddr/32 gss map=mymap |
476 | 321 | }); |
477 | 322 |
|
478 | | -string_replace_file($krb5_conf, "forwardable = false", "forwardable = true"); |
479 | | - |
480 | | -run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?); |
481 | | -run_log [ $klist, '-f' ] or BAIL_OUT($?); |
| 323 | +# Re-create the ticket, with the forwardable flag set |
| 324 | +$krb->create_ticket('test1', $test1_password, forwardable => 1); |
482 | 325 |
|
483 | 326 | test_access( |
484 | 327 | $node, |
|
0 commit comments