aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/be-secure-openssl.c48
-rw-r--r--src/backend/postmaster/postmaster.c22
-rw-r--r--src/include/libpq/libpq-be.h4
-rw-r--r--src/test/modules/Makefile5
-rw-r--r--src/test/modules/ssl_passphrase_callback/.gitignore1
-rw-r--r--src/test/modules/ssl_passphrase_callback/Makefile24
-rw-r--r--src/test/modules/ssl_passphrase_callback/server.crt19
-rw-r--r--src/test/modules/ssl_passphrase_callback/server.key30
-rw-r--r--src/test/modules/ssl_passphrase_callback/ssl_passphrase_func.c88
-rw-r--r--src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl80
-rw-r--r--src/tools/msvc/Mkvcbuild.pm2
11 files changed, 292 insertions, 31 deletions
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index b53c2b813eb..a65f920343c 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -45,6 +45,9 @@
#include "tcop/tcopprot.h"
#include "utils/memutils.h"
+/* default init hook can be overridden by a shared library */
+static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart);
+openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init;
static int my_sock_read(BIO *h, char *buf, int size);
static int my_sock_write(BIO *h, const char *buf, int size);
@@ -117,27 +120,10 @@ be_tls_init(bool isServerStart)
SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
/*
- * Set password callback
+ * Call init hook (usually to set password callback)
*/
- if (isServerStart)
- {
- if (ssl_passphrase_command[0])
- SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
- }
- else
- {
- if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload)
- SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
- else
+ (* openssl_tls_init_hook)(context, isServerStart);
- /*
- * If reloading and no external command is configured, override
- * OpenSSL's default handling of passphrase-protected files,
- * because we don't want to prompt for a passphrase in an
- * already-running server.
- */
- SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
- }
/* used by the callback */
ssl_is_server_start = isServerStart;
@@ -1338,3 +1324,27 @@ ssl_protocol_version_to_openssl(int v)
return -1;
}
+
+
+static void
+default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
+{
+ if (isServerStart)
+ {
+ if (ssl_passphrase_command[0])
+ SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
+ }
+ else
+ {
+ if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload)
+ SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
+ else
+ /*
+ * If reloading and no external command is configured, override
+ * OpenSSL's default handling of passphrase-protected files,
+ * because we don't want to prompt for a passphrase in an
+ * already-running server.
+ */
+ SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
+ }
+}
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 2b9ab322931..73d278f3b2c 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -973,17 +973,6 @@ PostmasterMain(int argc, char *argv[])
LocalProcessControlFile(false);
/*
- * Initialize SSL library, if specified.
- */
-#ifdef USE_SSL
- if (EnableSSL)
- {
- (void) secure_initialize(true);
- LoadedSSL = true;
- }
-#endif
-
- /*
* Register the apply launcher. Since it registers a background worker,
* it needs to be called before InitializeMaxBackends(), and it's probably
* a good idea to call it before any modules had chance to take the
@@ -997,6 +986,17 @@ PostmasterMain(int argc, char *argv[])
process_shared_preload_libraries();
/*
+ * Initialize SSL library, if specified.
+ */
+#ifdef USE_SSL
+ if (EnableSSL)
+ {
+ (void) secure_initialize(true);
+ LoadedSSL = true;
+ }
+#endif
+
+ /*
* Now that loadable modules have had their chance to register background
* workers, calculate MaxBackends.
*/
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 82e57afc642..ee57fdc301b 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -287,6 +287,10 @@ extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len);
extern char *be_tls_get_certificate_hash(Port *port, size_t *len);
#endif
+/* init hook for SSL, the default sets the password callback if appropriate */
+typedef void(* openssl_tls_init_hook_typ)(SSL_CTX *context, bool isServerStart);
+extern openssl_tls_init_hook_typ openssl_tls_init_hook;
+
#endif /* USE_SSL */
#ifdef ENABLE_GSS
diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index b2eaef3bff5..5f975ebcbac 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -25,4 +25,9 @@ SUBDIRS = \
unsafe_tests \
worker_spi
+ifeq ($(with_openssl),yes)
+SUBDIRS += ssl_passphrase_callback
+endif
+
+
$(recurse)
diff --git a/src/test/modules/ssl_passphrase_callback/.gitignore b/src/test/modules/ssl_passphrase_callback/.gitignore
new file mode 100644
index 00000000000..1dbadf7baf9
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/.gitignore
@@ -0,0 +1 @@
+tmp_check
diff --git a/src/test/modules/ssl_passphrase_callback/Makefile b/src/test/modules/ssl_passphrase_callback/Makefile
new file mode 100644
index 00000000000..e2d19f131a6
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/Makefile
@@ -0,0 +1,24 @@
+# ssl_passphrase Makefile
+
+export with_openssl
+
+MODULE_big = ssl_passphrase_func
+OBJS = ssl_passphrase_func.o $(WIN32RES)
+PGFILEDESC = "callback function to provide a passphrase"
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/ssl_passphrase_callback
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
+
+check: prove-check
+
+prove-check: ssl_passphrase_func$(DLSUFFIX) | temp-install
+ @echo running prove ...
+ $(prove_check)
diff --git a/src/test/modules/ssl_passphrase_callback/server.crt b/src/test/modules/ssl_passphrase_callback/server.crt
new file mode 100644
index 00000000000..b3c4be4fa5c
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/server.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDCTCCAfGgAwIBAgIUfHgPLNys4V0d0cWrzRHqfs91LFMwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDMyMTE0MDM1OVoXDTQ3MDgw
+NzE0MDM1OVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEA2j0PZwmeahBC7QpG7i9/VUVJrLzy+b8oVaqZUO6nlPbY
+wuPISYTO/jqc0XDfs/Gb0kccDJ6bPfNfvSnRTG1omE6OO9YjR0u3296l4bWAmYVq
+q4SesgQmm1Wy8ODNpeGaoBUwR51OB/gFHFjUlqAjRwOmrTCbDiAsLt7e+cx+W26r
+2SrJIweiSJsqaQsMMaqlY2qpHnYgWfqRUTqwXqlno0dXuqBt+KKgqeHMY3w3XS51
+8roOI0+Q9KWsexL/aYnLwMRsHRMZcthhzTK6HD/OrLh9CxURImr4ed9TtsNiZltA
+KqLTeGbtS1D2AvFqJU8n5DvtU+26wDrHu6pEM3kSJQIDAQABo1MwUTAdBgNVHQ4E
+FgQUkkfa08hDnxYs1UjG2ydCBJs1b2AwHwYDVR0jBBgwFoAUkkfa08hDnxYs1UjG
+2ydCBJs1b2AwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAjsJh
+p4tCopCA/Pvxupv3VEwGJ+nbH7Zg/hp+o2IWuHBOK1qrkyXBv34h/69bRnWZ5UFV
+HxQwL7CjNtjZu9SbpKkaHbZXPWANC9fbPKdBz9fAEwunf33KbZe3dPv/7xbJirMz
+e+j5V0LE0Spkr/p89LipXfjGw0jLC8VRTx/vKPnmbiBsCKw5SQKh3w7CcBx84Y6q
+Nc27WQ8ReR4W4X1zHGN6kEV4H+yPN2Z9OlSixTiSNvr2mtJQsZa7gK7Wwfm79RN7
+5Kf3l8b6e2BToJwLorpK9mvu41NtwRzl4UoJ1BFJDyhMplFMd8RcwTW6yT2biOFC
+lYCajcBoms3IiyqBog==
+-----END CERTIFICATE-----
diff --git a/src/test/modules/ssl_passphrase_callback/server.key b/src/test/modules/ssl_passphrase_callback/server.key
new file mode 100644
index 00000000000..1475007c73f
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/server.key
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,DB0E7068D4DCE79FFE63C95B8D8F7CEA
+
+Y4uvnlWX/kyulqsmt8aWI55vKFdfJL4wEZItL8ZKlQFuZuxC9w0OworyjTdqO38R
+v9hwnetZBDgK8kEv6U7wR58mTfwHHCGuxYgSiPZtiW7btS4zu16ePdh8oBEzCxjW
+ALrCFt7uvRu5h2AWy/4BgV4gLNVPNB+lJFABtUoiSnUDr7+bcx7UjZ4An6HriGxC
+Kg/N1pKjT/xiKOy+yHtrp1Jih5HYDE4i99jPtMuTROf8Uyz7ibyrdd/E7QNvANQN
+Cmw4I4Xk4hZ68F0iGU0C0wLND3pWbeYPKorpo3PkI4Du+Aqlg15ae5u8CtU3fXGJ
+mq4/qLGAi1sr/45f5P5a3Q8BQpKkCmGopXMaFYOOiaf3YYgD1eVOxLhsCWqUB+O8
+ygcTNRCoKhzY+ULComXp880J3fFk5b92g4Hm1PAO42uDKzhWSnrmCBJ7ynXvnEc+
+JqhiE8Obrp6FBIHvfN26JtHcXTd/bgUMXSh7AXjsotfvPPV0URve9JJG+RnwckeT
+K3AYDOQK/lbqDGliNqHg1WiMSA2oHSqDhUMB0Sm0jh6+jxCQlsmSDvPvJfWRo5wY
+zbZZZARQnFUaHa9CZVdFxbaPGhYU6vAwxDqi42osSJEdf68Gy2KVXcelqpU/2dKk
+aHfTgAWOsajbgt9p+0369TeZb39+zLODdDJnvZYiu1pTASHP5VrJ2xHhu5zOdjXm
+GafYiPwYBM280wkIVQ0HsTX7BViU2R/7W3FqflXgQvBiraVQVwHyaX4bOU1a3rzg
+emHNLTCpRamT0i/D0tkEPgS42bWSVi9ko5Mn9yb+qToBjAOLVUOAOs9Bv3qxawhI
+XFbBDZ7DS59l2yV6eQkrG7DUCLDf4dv4WZeBnhrPe/Jg8HKcsKcJYV3cejZh8sgu
+XHeCU50+jpJDfTZVPW3TjZWmrTqStGwF1UFpj+tTsTcX+OHAY/shFs3bBZulAsMy
+5UWZWzyWHMWr/wbxW7dbhTb1gNmOgpQQz9dunSgcZ8umzSGLa0ZGmnQj9P/kZkQA
+RenuswH5O7CK/MDmf3J6svwyLt/jULmH26MZTcNu7igT6dj3VMSwkoQQaaQdtmzb
+glzN3uqf8qM+CEjV8dxlt8fv6KJV7gvoYfPAz+1pp5DVJBmRo/+b4e/d4QTV9iWS
+ScBYdonc9WXcrjmExX9+Wf/K/IKfLnKLIi2MZ3pwr1n7yY+dMeF6iREYSjFVIpZd
+MH3G9/SxTrqR7X/eHjwdv1UupYYyaDag8wpVn1RMCb0xYqh2/QP1k0pQycckL0WQ
+lieXibEuQhV/heXcqt83G6pGqLImc6YPYU46jdGpPIMyOK+ZSqJTHUWHfRMQTIMz
+varR2M3uhHvwUFzmvjLh/o6I3r0a0Rl1MztpYfjBV6MS4BKYfraWZ0kxCyV+e6tz
+O7vD0P5W2qm6b89Md3nqjUcbOM8AojcfBl3xpQrpSdgJ25YJBoJ9L2I2pIMNCK/x
+yDNEJl7yP87fdHfXZm2VoUXclDUYHyNys9Rtv9NSr+VNkIMcqrCHEgpAxwQQ5NsO
+/vOZe3wjhXXLyRO7Nh5W8jojw3xcb9c9avFUWUvM2BaS4vEYcItUoF4QuHohrCwk
+-----END RSA PRIVATE KEY-----
diff --git a/src/test/modules/ssl_passphrase_callback/ssl_passphrase_func.c b/src/test/modules/ssl_passphrase_callback/ssl_passphrase_func.c
new file mode 100644
index 00000000000..c95cb509458
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/ssl_passphrase_func.c
@@ -0,0 +1,88 @@
+/*-------------------------------------------------------------------------
+ *
+ * ssl_passphrase_func.c
+ *
+ * Loadable PostgreSQL module fetch an ssl passphrase for the server cert.
+ * instead of calling an external program. This implementation just hands
+ * back the configured password rot13'd.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include <float.h>
+#include <stdio.h>
+
+#include "libpq/libpq.h"
+#include "libpq/libpq-be.h"
+#include "utils/guc.h"
+
+PG_MODULE_MAGIC;
+
+void _PG_init(void);
+void _PG_fini(void);
+
+static char *ssl_passphrase = NULL;
+
+/* callback function */
+static int rot13_passphrase(char *buf, int size, int rwflag, void *userdata);
+/* hook function to set the callback */
+static void set_rot13(SSL_CTX *context, bool isServerStart);
+/*
+ * Module load callback
+ */
+void
+_PG_init(void)
+{
+ /* Define custom GUC variable. */
+ DefineCustomStringVariable("ssl_passphrase.passphrase",
+ "passphrase before transformation",
+ NULL,
+ &ssl_passphrase,
+ NULL,
+ PGC_SIGHUP,
+ 0, /* no flags required */
+ NULL,
+ NULL,
+ NULL);
+ if (ssl_passphrase)
+ openssl_tls_init_hook = set_rot13;
+}
+
+void
+_PG_fini(void)
+{
+ /* do nothing yet */
+}
+
+static void
+set_rot13(SSL_CTX *context, bool isServerStart)
+{
+ /* warn if the user has set ssl_passphrase_command */
+ if(ssl_passphrase_command[0])
+ ereport(WARNING,
+ (errmsg("ssl_passphrase_command setting ignored by ssl_passphrase_func module")));
+
+ SSL_CTX_set_default_passwd_cb(context, rot13_passphrase);
+}
+
+static int
+rot13_passphrase(char *buf, int size, int rwflag, void *userdata)
+{
+
+ Assert(ssl_passphrase != NULL);
+ StrNCpy(buf, ssl_passphrase, size);
+ for (char *p = buf; *p; p++)
+ {
+ char c = *p;
+
+ if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M'))
+ *p = c + 13;
+ else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
+ *p = c - 13;
+ }
+
+ return strlen(buf);
+
+}
diff --git a/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl b/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl
new file mode 100644
index 00000000000..c052d72f9cd
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl
@@ -0,0 +1,80 @@
+use strict;
+use warnings;
+
+use File::Copy;
+
+use TestLib;
+use Test::More;
+use PostgresNode;
+
+unless (($ENV{with_openssl} || 'no') eq 'yes')
+{
+ plan skip_all => 'SSL not supported by this build';
+}
+
+my $clearpass = "FooBaR1";
+my $rot13pass = "SbbOnE1";
+
+# self-signed cert was generated like this:
+# system('openssl req -new -x509 -days 10000 -nodes -out server.crt -keyout server.ckey -subj "/CN=localhost"');
+# add the cleartext passphrase to the key, remove the unprotected key
+# system("openssl rsa -aes256 -in server.ckey -out server.key -passout pass:$clearpass");
+# unlink "server.ckey";
+
+
+my $node = get_new_node('main');
+$node->init;
+$node->append_conf('postgresql.conf',
+ "ssl_passphrase.passphrase = '$rot13pass'");
+$node->append_conf('postgresql.conf',
+ "shared_preload_libraries = 'ssl_passphrase_func'");
+$node->append_conf('postgresql.conf', "listen_addresses = 'localhost'");
+$node->append_conf('postgresql.conf', "ssl = 'on'");
+
+my $ddir = $node->data_dir;
+
+# install certificate and protected key
+copy("server.crt", $ddir);
+copy("server.key", $ddir);
+chmod 0600, "$ddir/server.key";
+
+$node->start;
+
+# if the server is running we must have successfully transformed the passphrase
+ok(-e "$ddir/postmaster.pid", "postgres started");
+
+$node->stop('fast');
+
+# should get a warning if ssl_passphrase_command is set
+my $log = $node->rotate_logfile();
+
+$node->append_conf('postgresql.conf',
+ "ssl_passphrase_command = 'echo spl0tz'");
+
+$node->start;
+
+$node->stop('fast');
+
+my $log_contents = slurp_file($log);
+
+like(
+ $log_contents,
+ qr/WARNING.*ssl_passphrase_command setting ignored by ssl_passphrase_func module/,
+ "ssl_passphrase_command set warning");
+
+# set the wrong passphrase
+$node->append_conf('postgresql.conf', "ssl_passphrase.passphrase = 'blurfl'");
+
+# try to start the server again
+my $ret = TestLib::system_log('pg_ctl', '-D', $node->data_dir, '-l',
+ $node->logfile, 'start');
+
+
+# with a bad passphrase the server should not start
+ok($ret, "pg_ctl fails with bad passphrase");
+ok(!-e "$ddir/postmaster.pid", "postgres not started with bad passphrase");
+
+# just in case
+$node->stop('fast');
+
+done_testing();
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 636428b0448..39709f20e67 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -430,7 +430,7 @@ sub mkvcbuild
if (!$solution->{options}->{openssl})
{
- push @contrib_excludes, 'sslinfo';
+ push @contrib_excludes, 'sslinfo', 'ssl_passphrase_callback';
}
if (!$solution->{options}->{uuid})