Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Fix pg_rewind to handle relation data files in tablespaces properly.

  1. [PATCH v2] Tests for Kerberos/GSSAPI authentication

    Peter Eisentraut <peter_e@gmx.net> — 2018-03-05T19:42:11Z

    ---
     configure                       |   4 +
     configure.in                    |   2 +
     doc/src/sgml/regress.sgml       |  12 ++-
     src/Makefile.global.in          |   2 +
     src/test/Makefile               |   7 +-
     src/test/kerberos/.gitignore    |   2 +
     src/test/kerberos/Makefile      |  25 ++++++
     src/test/kerberos/README        |  35 ++++++++
     src/test/kerberos/t/001_auth.pl | 177 ++++++++++++++++++++++++++++++++++++++++
     9 files changed, 264 insertions(+), 2 deletions(-)
     create mode 100644 src/test/kerberos/.gitignore
     create mode 100644 src/test/kerberos/Makefile
     create mode 100644 src/test/kerberos/README
     create mode 100644 src/test/kerberos/t/001_auth.pl
    
    diff --git a/configure b/configure
    index 1242e310b4..3943711283 100755
    --- a/configure
    +++ b/configure
    @@ -709,7 +709,9 @@ with_systemd
     with_selinux
     with_openssl
     with_ldap
    +with_krb_srvnam
     krb_srvtab
    +with_gssapi
     with_python
     with_perl
     with_tcl
    @@ -5788,6 +5790,7 @@ $as_echo "$with_gssapi" >&6; }
     
     
     
    +
     #
     # Kerberos configuration parameters
     #
    @@ -5815,6 +5818,7 @@ fi
     
     
     
    +
     cat >>confdefs.h <<_ACEOF
     #define PG_KRB_SRVNAM "$with_krb_srvnam"
     _ACEOF
    diff --git a/configure.in b/configure.in
    index aee3ab0867..1babdbb755 100644
    --- a/configure.in
    +++ b/configure.in
    @@ -638,6 +638,7 @@ PGAC_ARG_BOOL(with, gssapi, no, [build with GSSAPI support],
       krb_srvtab="FILE:\$(sysconfdir)/krb5.keytab"
     ])
     AC_MSG_RESULT([$with_gssapi])
    +AC_SUBST(with_gssapi)
     
     
     AC_SUBST(krb_srvtab)
    @@ -650,6 +651,7 @@ PGAC_ARG_REQ(with, krb-srvnam,
                  [NAME], [default service principal name in Kerberos (GSSAPI) [postgres]],
                  [],
                  [with_krb_srvnam="postgres"])
    +AC_SUBST(with_krb_srvnam)
     AC_DEFINE_UNQUOTED([PG_KRB_SRVNAM], ["$with_krb_srvnam"],
                        [Define to the name of the default PostgreSQL service principal in Kerberos (GSSAPI). (--with-krb-srvnam=NAME)])
     
    diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
    index 3c448dc5bc..673a8c2164 100644
    --- a/doc/src/sgml/regress.sgml
    +++ b/doc/src/sgml/regress.sgml
    @@ -220,10 +220,20 @@ <title>Additional Test Suites</title>
        <varname>PG_TEST_EXTRA</varname> to a whitespace-separated list, for
        example:
     <programlisting>
    -make check-world PG_TEST_EXTRA='ldap ssl'
    +make check-world PG_TEST_EXTRA='kerberos ldap ssl'
     </programlisting>
        The following values are currently supported:
        <variablelist>
    +    <varlistentry>
    +     <term><literal>kerberos</literal></term>
    +     <listitem>
    +      <para>
    +       Runs the test suite under <filename>src/test/kerberos</filename>.  This
    +       requires an MIT Kerberos installation and opens TCP/IP listen sockets.
    +      </para>
    +     </listitem>
    +    </varlistentry>
    +
         <varlistentry>
          <term><literal>ldap</literal></term>
          <listitem>
    diff --git a/src/Makefile.global.in b/src/Makefile.global.in
    index dcb8dc5d90..15c14951e8 100644
    --- a/src/Makefile.global.in
    +++ b/src/Makefile.global.in
    @@ -186,6 +186,8 @@ with_tcl	= @with_tcl@
     with_openssl	= @with_openssl@
     with_selinux	= @with_selinux@
     with_systemd	= @with_systemd@
    +with_gssapi	= @with_gssapi@
    +with_krb_srvnam	= @with_krb_srvnam@
     with_ldap	= @with_ldap@
     with_libxml	= @with_libxml@
     with_libxslt	= @with_libxslt@
    diff --git a/src/test/Makefile b/src/test/Makefile
    index 3de9428299..efb206aa75 100644
    --- a/src/test/Makefile
    +++ b/src/test/Makefile
    @@ -17,6 +17,11 @@ SUBDIRS = perl regress isolation modules authentication recovery subscription
     # Test suites that are not safe by default but can be run if selected
     # by the user via the whitespace-separated list in variable
     # PG_TEST_EXTRA:
    +ifeq ($(with_gssapi),yes)
    +ifneq (,$(filter kerberos,$(PG_TEST_EXTRA)))
    +SUBDIRS += kerberos
    +endif
    +endif
     ifeq ($(with_ldap),yes)
     ifneq (,$(filter ldap,$(PG_TEST_EXTRA)))
     SUBDIRS += ldap
    @@ -32,7 +37,7 @@ endif
     # clean" etc to recurse into them.  (We must filter out those that we
     # have conditionally included into SUBDIRS above, else there will be
     # make confusion.)
    -ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples ldap locale thread ssl)
    +ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos ldap locale thread ssl)
     
     # We want to recurse to all subdirs for all standard targets, except that
     # installcheck and install should not recurse into the subdirectory "modules".
    diff --git a/src/test/kerberos/.gitignore b/src/test/kerberos/.gitignore
    new file mode 100644
    index 0000000000..871e943d50
    --- /dev/null
    +++ b/src/test/kerberos/.gitignore
    @@ -0,0 +1,2 @@
    +# Generated by test suite
    +/tmp_check/
    diff --git a/src/test/kerberos/Makefile b/src/test/kerberos/Makefile
    new file mode 100644
    index 0000000000..4df4989470
    --- /dev/null
    +++ b/src/test/kerberos/Makefile
    @@ -0,0 +1,25 @@
    +#-------------------------------------------------------------------------
    +#
    +# Makefile for src/test/kerberos
    +#
    +# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
    +# Portions Copyright (c) 1994, Regents of the University of California
    +#
    +# src/test/kerberos/Makefile
    +#
    +#-------------------------------------------------------------------------
    +
    +subdir = src/test/kerberos
    +top_builddir = ../../..
    +include $(top_builddir)/src/Makefile.global
    +
    +export with_gssapi with_krb_srvnam
    +
    +check:
    +	$(prove_check)
    +
    +installcheck:
    +	$(prove_installcheck)
    +
    +clean distclean maintainer-clean:
    +	rm -rf tmp_check
    diff --git a/src/test/kerberos/README b/src/test/kerberos/README
    new file mode 100644
    index 0000000000..cdfaeb89d3
    --- /dev/null
    +++ b/src/test/kerberos/README
    @@ -0,0 +1,35 @@
    +src/test/kerberos/README
    +
    +Tests for Kerberos/GSSAPI functionality
    +=======================================
    +
    +This directory contains a test suite for Kerberos/GSSAPI
    +functionality.  This requires a full MIT Kerberos installation,
    +including server and client tools, and is therefore kept separate and
    +not run by default.
    +
    +Also, this test suite creates a KDC server that listens for TCP/IP
    +connections on localhost without any real access control, so it is not
    +safe to run this on a system where there might be untrusted local
    +users.
    +
    +Running the tests
    +=================
    +
    +    make check
    +
    +or
    +
    +    make installcheck
    +
    +Requirements
    +============
    +
    +MIT Kerberos server and client tools are required.  Heimdal is not
    +supported.
    +
    +Debian/Ubuntu packages: krb5-admin-server krb5-kdc krb5-user
    +
    +RHEL/CentOS packages: krb5-server krb5-workstation
    +
    +FreeBSD port: krb5 (base system has Heimdal)
    diff --git a/src/test/kerberos/t/001_auth.pl b/src/test/kerberos/t/001_auth.pl
    new file mode 100644
    index 0000000000..f26460e627
    --- /dev/null
    +++ b/src/test/kerberos/t/001_auth.pl
    @@ -0,0 +1,177 @@
    +use strict;
    +use warnings;
    +use TestLib;
    +use PostgresNode;
    +use Test::More;
    +
    +if ($ENV{with_gssapi} eq 'yes')
    +{
    +	plan tests => 4;
    +}
    +else
    +{
    +	plan skip_all => 'GSSAPI/Kerberos not supported by this build';
    +}
    +
    +my ($krb5_bin_dir, $krb5_sbin_dir);
    +
    +if ($^O eq 'darwin')
    +{
    +	$krb5_bin_dir = '/usr/local/opt/krb5/bin';
    +	$krb5_sbin_dir = '/usr/local/opt/krb5/sbin';
    +}
    +elsif ($^O eq 'freebsd')
    +{
    +	$krb5_bin_dir = '/usr/local/bin';
    +	$krb5_sbin_dir = '/usr/local/sbin';
    +}
    +elsif ($^O eq 'linux')
    +{
    +	$krb5_sbin_dir = '/usr/sbin';
    +}
    +
    +my $krb5_config = 'krb5-config';
    +my $kinit = 'kinit';
    +my $kdb5_util = 'kdb5_util';
    +my $kadmin_local = 'kadmin.local';
    +my $krb5kdc = 'krb5kdc';
    +
    +if ($krb5_bin_dir && -d $krb5_bin_dir)
    +{
    +	$krb5_config = $krb5_bin_dir . '/' . $krb5_config;
    +	$kinit = $krb5_bin_dir . '/' . $kinit;
    +}
    +if ($krb5_sbin_dir && -d $krb5_sbin_dir)
    +{
    +	$kdb5_util = $krb5_sbin_dir . '/' . $kdb5_util;
    +	$kadmin_local = $krb5_sbin_dir . '/' . $kadmin_local;
    +	$krb5kdc = $krb5_sbin_dir . '/' . $krb5kdc;
    +}
    +
    +my $realm = 'EXAMPLE.COM';
    +
    +my $krb5_conf = "${TestLib::tmp_check}/krb5.conf";
    +my $kdc_conf = "${TestLib::tmp_check}/kdc.conf";
    +my $krb5_log = "${TestLib::tmp_check}/krb5libs.log";
    +my $kdc_log = "${TestLib::tmp_check}/krb5kdc.log";
    +my $kdc_port = int(rand() * 16384) + 49152;
    +my $kdc_datadir = "${TestLib::tmp_check}/krb5kdc";
    +my $kdc_pidfile = "${TestLib::tmp_check}/krb5kdc.pid";
    +my $keytab = "${TestLib::tmp_check}/krb5.keytab";
    +
    +note "setting up Kerberos";
    +
    +my ($stdout, $krb5_version);
    +run_log [ $krb5_config, '--version' ], '>', \$stdout or BAIL_OUT("could not execute krb5-config");
    +BAIL_OUT("Heimdal is not supported") if $stdout =~ m/heimdal/;
    +$stdout =~ m/Kerberos 5 release ([0-9]+\.[0-9]+)/ or BAIL_OUT("could not get Kerberos version");
    +$krb5_version = $1;
    +
    +append_to_file($krb5_conf,
    +qq![logging]
    +default = FILE:$krb5_log
    +kdc = FILE:$kdc_log
    +
    +[libdefaults]
    +default_realm = $realm
    +
    +[realms]
    +$realm = {
    +    kdc = localhost:$kdc_port
    +}!);
    +
    +append_to_file($kdc_conf,
    +qq![kdcdefaults]
    +!);
    +# For new-enough versions of krb5, use the _listen settings rather
    +# than the _ports settings so that we can bind to localhost only.
    +if ($krb5_version >= 1.15)
    +{
    +	append_to_file($kdc_conf,
    +qq!kdc_listen = localhost:$kdc_port
    +kdc_tcp_listen = localhost:$kdc_port
    +!);
    +}
    +else
    +{
    +	append_to_file($kdc_conf,
    +qq!kdc_ports = $kdc_port
    +kdc_tcp_ports = $kdc_port
    +!);
    +}
    +append_to_file($kdc_conf,
    +qq!
    +[realms]
    +$realm = {
    +    database_name = $kdc_datadir/principal
    +    admin_keytab = FILE:$kdc_datadir/kadm5.keytab
    +    acl_file = $kdc_datadir/kadm5.acl
    +    key_stash_file = $kdc_datadir/_k5.$realm
    +}!);
    +
    +mkdir $kdc_datadir or die;
    +
    +$ENV{'KRB5_CONFIG'} = $krb5_conf;
    +$ENV{'KRB5_KDC_PROFILE'} = $kdc_conf;
    +
    +my $service_principal = "$ENV{with_krb_srvnam}/localhost";
    +
    +system_or_bail $kdb5_util, 'create', '-s', '-P', 'secret0';
    +
    +my $test1_password = 'secret1';
    +system_or_bail $kadmin_local, '-q', "addprinc -pw $test1_password test1";
    +
    +system_or_bail $kadmin_local, '-q', "addprinc -randkey $service_principal";
    +system_or_bail $kadmin_local, '-q', "ktadd -k $keytab $service_principal";
    +
    +system_or_bail $krb5kdc, '-P', $kdc_pidfile;
    +
    +END
    +{
    +    kill 'INT', `cat $kdc_pidfile` if -f $kdc_pidfile;
    +}
    +
    +note "setting up PostgreSQL instance";
    +
    +my $node = get_new_node('node');
    +$node->init;
    +$node->append_conf('postgresql.conf', "listen_addresses = 'localhost'");
    +$node->append_conf('postgresql.conf', "krb_server_keyfile = '$keytab'");
    +$node->start;
    +
    +$node->safe_psql('postgres', 'CREATE USER test1;');
    +
    +note "running tests";
    +
    +sub test_access
    +{
    +	my ($node, $role, $expected_res, $test_name) = @_;
    +
    +	# need to connect over TCP/IP for Kerberos
    +	my $res = $node->psql('postgres', 'SELECT 1',
    +						  extra_params => [ '-d', $node->connstr('postgres').' host=localhost',
    +											'-U', $role ]);
    +	is($res, $expected_res, $test_name);
    +}
    +
    +unlink($node->data_dir . '/pg_hba.conf');
    +$node->append_conf('pg_hba.conf', qq{host all all localhost gss map=mymap});
    +$node->restart;
    +
    +test_access($node, 'test1', 2, 'fails without ticket');
    +
    +run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?);
    +
    +test_access($node, 'test1', 2, 'fails without mapping');
    +
    +$node->append_conf('pg_ident.conf', qq{mymap  /^(.*)\@$realm\$  \\1});
    +$node->restart;
    +
    +test_access($node, 'test1', 0, 'succeeds with mapping');
    +
    +truncate($node->data_dir . '/pg_ident.conf', 0);
    +unlink($node->data_dir . '/pg_hba.conf');
    +$node->append_conf('pg_hba.conf', qq{host all all localhost gss include_realm=0});
    +$node->restart;
    +
    +test_access($node, 'test1', 0, 'succeeds with include_realm=0');
    
    base-commit: 2f3e2340cd1b67e91cefdf45e4c915297d1034e2
    -- 
    2.16.2
    
    
    --------------02153BB8ABF1722CA33C672A--