On Thu, Oct 29, 2020 at 7:26 PM Stephen Frost <[email protected]> wrote:
>
> Greetings,
>
> * vignesh C ([email protected]) wrote:
> > I have made a v2 patch based on the changes you have suggested. The
> > patch for the same is attached.
>
> > From b067cf823750f200102be0a0cad9a26a08e29a92 Mon Sep 17 00:00:00 2001
> > From: Vignesh C <[email protected]>
> > Date: Wed, 28 Oct 2020 08:19:06 +0530
> > Subject: [PATCH v2] Log message for GSS connection is missing once
> > connection
> > authorization is successful.
> >
> > Log message for GSS connection is missing once connection authorization is
> > successful. We have similar log message for SSL connections once the
> > connection
> > authorization is successful. This message will help the user to identify the
> > connection that was selected from the logfile.
>
> Just to be clear- it's not that the message is 'missing', it's just not
> providing the (certainly useful) information about how the connection
> was authorized. The commit message should make it clear that what we're
> doing here is improving the connection authorization message for GSS
> authenticated or encrypted connections.
>
I have updated the commit message accordingly.
> > diff --git a/src/backend/utils/init/postinit.c
> > b/src/backend/utils/init/postinit.c
> > index d4ab4c7..7980e92 100644
> > --- a/src/backend/utils/init/postinit.c
> > +++ b/src/backend/utils/init/postinit.c
> > @@ -267,6 +267,21 @@ PerformAuthentication(Port *port)
> >
> > be_tls_get_compression(port) ? _("on") : _("off"))));
> > else
> > #endif
> > +#ifdef ENABLE_GSS
> > + if (be_gssapi_get_auth(port) ||
> > be_gssapi_get_princ(port))
> > + ereport(LOG,
> > + (port->application_name !=
> > NULL
> > + ? errmsg("replication
> > connection authorized: user=%s application_name=%s GSS %s (principal=%s)",
> > +
> > port->user_name,
> > +
> > port->application_name,
> > +
> > be_gssapi_get_auth(port) || be_gssapi_get_enc(port) ? _("on") : _("off"),
> > +
> > be_gssapi_get_princ(port))
> > + : errmsg("replication
> > connection authorized: user=%s GSS %s (principal=%s)",
> > +
> > port->user_name,
> > +
> > be_gssapi_get_auth(port) || be_gssapi_get_enc(port) ? _("on") : _("off"),
> > +
> > be_gssapi_get_princ(port))));
> > + else
> > +#endif
>
> No, this isn't what I was suggesting. "on" and "off" really isn't
> communicating the details about the GSS-using connection. What I
> suggested before was something like:
>
> errmsg("replication connection authorized: user=%s application_name=%s GSS %s
> (principal=%s)",
> port->user_name,
> port->application_name,
> (be_gssapi_get_auth(port) && be_gssapi_get_enc(port)) ?
> "authenticated and encrypted" : be_gssapi_get_auth(port) ? "authenticated" :
> "encrypted",
> be_gssapi_get_princ(port))
>
> Though I'll admit that perhaps there's something better which could be
> done here- but just 'on/off' certainly isn't that. Another option might
> be:
>
> errmsg("replication connection authorized: user=%s application_name=%s GSS
> authenticated: %s, encrypted: %s, principal: %s",
> port->user_name,
> port->application_name,
> be_gssapi_get_auth(port) ? "yes" : "no",
> be_gssapi_get_enc(port) ? "yes" : "no",
> be_gssapi_get_princ(port))
>
I like the above method that you suggested, I have changed it based on
the above.
> Also, it would be good to see if there's a way to add to the tests we
> have for GSSAPI authentication/encryption to show that we hit each of
> the possible cases and check that we get the correct messages in the log
> as a result.
>
I have added the log validation to the existing tests that are present
for authentication.
Attached v3 patch has the change for the same.
Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com
From 039a626513cab357070d33ddc872f22e0f4f3e88 Mon Sep 17 00:00:00 2001
From: Vignesh C <[email protected]>
Date: Fri, 30 Oct 2020 17:58:45 +0530
Subject: [PATCH v3] Improving the connection authorization message for GSS
authenticated/encrypted connections.
Added log message to include GSS authentication, encryption & principal
information. This message will help the user to know if GSS authentication or
encryption was used and which GSS principal was used.
---
src/backend/utils/init/postinit.c | 80 ++++++++++++++-------------------------
src/test/kerberos/t/001_auth.pl | 73 ++++++++++++++++++++++++++++-------
2 files changed, 87 insertions(+), 66 deletions(-)
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index d4ab4c7..34d3045 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -246,62 +246,38 @@ PerformAuthentication(Port *port)
if (Log_connections)
{
+ StringInfoData logmsg;
+ initStringInfo(&logmsg);
if (am_walsender)
- {
+ appendStringInfo(&logmsg, "replication ");
+
+ appendStringInfo(&logmsg, "connection authorized: user=%s",
+ port->user_name);
+ if (!am_walsender)
+ appendStringInfo(&logmsg, " database=%s", port->database_name);
+
+ if (port->application_name != NULL)
+ appendStringInfo(&logmsg, " application_name=%s",
+ port->application_name);
+
#ifdef USE_SSL
- if (port->ssl_in_use)
- ereport(LOG,
- (port->application_name != NULL
- ? errmsg("replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)",
- port->user_name,
- port->application_name,
- be_tls_get_version(port),
- be_tls_get_cipher(port),
- be_tls_get_cipher_bits(port),
- be_tls_get_compression(port) ? _("on") : _("off"))
- : errmsg("replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)",
- port->user_name,
- be_tls_get_version(port),
- be_tls_get_cipher(port),
- be_tls_get_cipher_bits(port),
- be_tls_get_compression(port) ? _("on") : _("off"))));
- else
+ if (port->ssl_in_use)
+ appendStringInfo(&logmsg, " SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)",
+ be_tls_get_version(port),
+ be_tls_get_cipher(port),
+ be_tls_get_cipher_bits(port),
+ be_tls_get_compression(port) ? _("on") : _("off"));
#endif
- ereport(LOG,
- (port->application_name != NULL
- ? errmsg("replication connection authorized: user=%s application_name=%s",
- port->user_name,
- port->application_name)
- : errmsg("replication connection authorized: user=%s",
- port->user_name)));
- }
- else
- {
-#ifdef USE_SSL
- if (port->ssl_in_use)
- ereport(LOG,
- (port->application_name != NULL
- ? errmsg("connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)",
- port->user_name, port->database_name, port->application_name,
- be_tls_get_version(port),
- be_tls_get_cipher(port),
- be_tls_get_cipher_bits(port),
- be_tls_get_compression(port) ? _("on") : _("off"))
- : errmsg("connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)",
- port->user_name, port->database_name,
- be_tls_get_version(port),
- be_tls_get_cipher(port),
- be_tls_get_cipher_bits(port),
- be_tls_get_compression(port) ? _("on") : _("off"))));
- else
+#ifdef ENABLE_GSS
+ if (be_gssapi_get_princ(port))
+ appendStringInfo(&logmsg, " GSS (authenticated=%s, encrypted=%s, principal=%s)",
+ be_gssapi_get_auth(port) ? _("yes") : _("no"),
+ be_gssapi_get_enc(port) ? _("yes") : _("no"),
+ be_gssapi_get_princ(port));
#endif
- ereport(LOG,
- (port->application_name != NULL
- ? errmsg("connection authorized: user=%s database=%s application_name=%s",
- port->user_name, port->database_name, port->application_name)
- : errmsg("connection authorized: user=%s database=%s",
- port->user_name, port->database_name)));
- }
+
+ ereport(LOG, errmsg("%s", logmsg.data));
+ pfree(logmsg.data);
}
set_ps_display("startup");
diff --git a/src/test/kerberos/t/001_auth.pl b/src/test/kerberos/t/001_auth.pl
index b3aeea9..701e6ad 100644
--- a/src/test/kerberos/t/001_auth.pl
+++ b/src/test/kerberos/t/001_auth.pl
@@ -16,10 +16,11 @@ use warnings;
use TestLib;
use PostgresNode;
use Test::More;
+use Time::HiRes qw(usleep);
if ($ENV{with_gssapi} eq 'yes')
{
- plan tests => 18;
+ plan tests => 32;
}
else
{
@@ -160,6 +161,8 @@ my $node = get_new_node('node');
$node->init;
$node->append_conf('postgresql.conf', "listen_addresses = '$hostaddr'");
$node->append_conf('postgresql.conf', "krb_server_keyfile = '$keytab'");
+$node->append_conf('postgresql.conf', "logging_collector= 'on'");
+$node->append_conf('postgresql.conf', "log_connections= 'on'");
$node->start;
$node->safe_psql('postgres', 'CREATE USER test1;');
@@ -169,7 +172,7 @@ note "running tests";
# Test connection success or failure, and if success, that query returns true.
sub test_access
{
- my ($node, $role, $query, $expected_res, $gssencmode, $test_name) = @_;
+ my ($node, $role, $query, $expected_res, $gssencmode, $test_name, $expect_log_msg) = @_;
# need to connect over TCP/IP for Kerberos
my ($res, $stdoutres, $stderrres) = $node->psql(
@@ -192,6 +195,33 @@ sub test_access
{
is($res, $expected_res, $test_name);
}
+
+ # Verify specified log message is logged in the log file.
+ if ($expect_log_msg ne '')
+ {
+ my $current_logfiles = slurp_file($node->data_dir . '/current_logfiles');
+ note "current_logfiles = $current_logfiles";
+ like($current_logfiles, qr|^stderr log/postgresql-.*log$|,
+ 'current_logfiles is sane');
+
+ my $lfname = $current_logfiles;
+ $lfname =~ s/^stderr //;
+ chomp $lfname;
+
+ # might need to retry if logging collector process is slow...
+ my $max_attempts = 10 * 10;
+ my $first_logfile;
+ for (my $attempts = 0; $attempts < $max_attempts; $attempts++)
+ {
+ $first_logfile = slurp_file($node->data_dir . '/' . $lfname);
+ last if $first_logfile =~ m/$expect_log_msg /;
+ usleep(100_000);
+ }
+
+ like($first_logfile, qr/$expect_log_msg/,
+ 'found expected log file content');
+ }
+
return;
}
@@ -223,11 +253,11 @@ $node->append_conf('pg_hba.conf',
qq{host all all $hostaddr/32 gss map=mymap});
$node->restart;
-test_access($node, 'test1', 'SELECT true', 2, '', 'fails without ticket');
+test_access($node, 'test1', 'SELECT true', 2, '', 'fails without ticket', '');
run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?);
-test_access($node, 'test1', 'SELECT true', 2, '', 'fails without mapping');
+test_access($node, 'test1', 'SELECT true', 2, '', 'fails without mapping', '');
$node->append_conf('pg_ident.conf', qq{mymap /^(.*)\@$realm\$ \\1});
$node->restart;
@@ -238,21 +268,28 @@ test_access(
'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
'',
- 'succeeds with mapping with default gssencmode and host hba');
+ 'succeeds with mapping with default gssencmode and host hba',
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=yes, principal=test1\@EXAMPLE.COM\)'
+);
+
test_access(
$node,
"test1",
'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
"gssencmode=prefer",
- "succeeds with GSS-encrypted access preferred with host hba");
+ "succeeds with GSS-encrypted access preferred with host hba",
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=yes, principal=test1\@EXAMPLE.COM\)'
+);
test_access(
$node,
"test1",
'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
"gssencmode=require",
- "succeeds with GSS-encrypted access required with host hba");
+ "succeeds with GSS-encrypted access required with host hba",
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=yes, principal=test1\@EXAMPLE.COM\)'
+);
# Test that we can transport a reasonable amount of data.
test_query(
@@ -286,16 +323,20 @@ test_access(
'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
"gssencmode=prefer",
- "succeeds with GSS-encrypted access preferred and hostgssenc hba");
+ "succeeds with GSS-encrypted access preferred and hostgssenc hba",
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=yes, principal=test1\@EXAMPLE.COM\)'
+);
test_access(
$node,
"test1",
'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
"gssencmode=require",
- "succeeds with GSS-encrypted access required and hostgssenc hba");
+ "succeeds with GSS-encrypted access required and hostgssenc hba",
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=yes, principal=test1\@EXAMPLE.COM\)'
+);
test_access($node, "test1", 'SELECT true', 2, "gssencmode=disable",
- "fails with GSS encryption disabled and hostgssenc hba");
+ "fails with GSS encryption disabled and hostgssenc hba", '');
unlink($node->data_dir . '/pg_hba.conf');
$node->append_conf('pg_hba.conf',
@@ -308,17 +349,20 @@ test_access(
'SELECT gss_authenticated and not encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
"gssencmode=prefer",
- "succeeds with GSS-encrypted access preferred and hostnogssenc hba, but no encryption"
+ "succeeds with GSS-encrypted access preferred and hostnogssenc hba, but no encryption",
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=no, principal=test1\@EXAMPLE.COM\)'
);
test_access($node, "test1", 'SELECT true', 2, "gssencmode=require",
- "fails with GSS-encrypted access required and hostnogssenc hba");
+ "fails with GSS-encrypted access required and hostnogssenc hba", '');
test_access(
$node,
"test1",
'SELECT gss_authenticated and not encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
"gssencmode=disable",
- "succeeds with GSS encryption disabled and hostnogssenc hba");
+ "succeeds with GSS encryption disabled and hostnogssenc hba",
+ 'connection authorized: user=test1 database=postgres application_name=001_auth.pl GSS \(authenticated=yes, encrypted=no, principal=test1\@EXAMPLE.COM\)'
+);
truncate($node->data_dir . '/pg_ident.conf', 0);
unlink($node->data_dir . '/pg_hba.conf');
@@ -332,4 +376,5 @@ test_access(
'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();',
0,
'',
- 'succeeds with include_realm=0 and defaults');
+ 'succeeds with include_realm=0 and defaults',
+ '');
--
1.8.3.1