On Wed, Feb 19, 2020 at 7:10 AM Andrew Dunstan
<[email protected]> wrote:
>
> On Tue, Feb 18, 2020 at 2:01 PM Thomas Munro <[email protected]> wrote:
> >
> > On Wed, Jan 22, 2020 at 8:02 PM Andrew Dunstan
> > <[email protected]> wrote:
> > > Not sure if the placement is what you want, but maybe something like this?
> >
> > Hi Andrew, FYI this failed here:
> >
> > t/001_testfunc.pl .. Bailout called. Further testing stopped: pg_ctl
> > start failed
> > FAILED--Further testing stopped: pg_ctl start failed
> > Makefile:23: recipe for target 'prove-check' failed
> >
> > Unfortunately my robot is poorly trained and does not dump any of the
> > interesting logs for this case, but it looks like it's failing that
> > way every time.
> >
> > https://travis-ci.org/postgresql-cfbot/postgresql/builds/651756191
>
>
> Thanks for letting me know, I will investigate.
>
This should fix the issue, it happened when I switched to using a
pre-generated cert/key.
cheers
andrew
--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 18d3fff068..b0a8816cff 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);
@@ -116,27 +119,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;
@@ -1313,3 +1299,27 @@ ssl_protocol_version_to_openssl(int v, const char *guc_name, int loglevel)
GetConfigOption(guc_name, false, false))));
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 b3986bee75..53776d6198 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -972,17 +972,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
@@ -996,6 +985,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 82e57afc64..90f80bb33a 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 passwor 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 b2eaef3bff..5f975ebcba 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 0000000000..1dbadf7baf
--- /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 0000000000..e2d19f131a
--- /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 0000000000..292472a041
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/server.crt
@@ -0,0 +1,77 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 64:b5:b2:57:92:2b:e5:86:c6:c8:b1:6b:f5:79:4d:25:b2:05:91:45
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN = localhost
+ Validity
+ Not Before: Feb 18 22:02:33 2020 GMT
+ Not After : Feb 15 22:02:33 2030 GMT
+ Subject: CN = localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:fb:01:2c:02:cd:15:49:85:ea:e0:95:57:13:7a:
+ 9c:88:ed:93:f8:11:bc:d4:b2:0a:57:8e:ab:b4:5e:
+ da:a9:24:b8:43:63:35:2c:df:a1:35:8d:49:11:1a:
+ f0:9c:0a:15:63:0f:4e:53:54:35:9f:8e:2d:0f:57:
+ 13:fd:b8:61:7f:e7:ff:44:aa:23:b9:3e:e6:59:71:
+ 2a:93:84:62:f9:1d:92:37:20:a0:38:c3:a0:bf:09:
+ 28:19:7a:87:90:89:31:b0:84:4f:8f:9e:ae:f5:73:
+ 11:41:ff:ea:12:1b:ab:bb:4c:4e:ba:b1:50:ff:37:
+ b1:35:3f:0d:aa:bb:a4:93:f1:0c:1d:bd:76:73:32:
+ 2d:22:1b:77:91:e7:c6:d4:b4:5e:d3:bf:02:6f:87:
+ 16:c4:08:6b:3e:a5:17:8a:bf:82:95:42:fb:2e:69:
+ 8f:26:0a:69:7d:c1:f6:8d:a7:ca:69:1d:81:95:ac:
+ 26:d6:b9:75:25:72:ec:13:c9:cf:82:fb:f3:39:90:
+ 22:7e:64:6b:c3:2f:ad:00:0e:e5:27:87:cf:60:aa:
+ ae:64:0a:e8:04:9b:8f:25:43:cc:9e:a8:10:62:5f:
+ 4c:3a:8d:95:13:bf:18:fa:6c:be:79:be:36:84:1d:
+ 00:ba:35:c6:06:d7:5b:1b:19:b6:ec:88:60:6c:58:
+ 1e:2f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 1D:8D:CB:C5:DE:70:22:7C:1F:47:91:6C:61:03:C3:AB:78:CA:66:26
+ X509v3 Authority Key Identifier:
+ keyid:1D:8D:CB:C5:DE:70:22:7C:1F:47:91:6C:61:03:C3:AB:78:CA:66:26
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ ae:3a:22:a5:bb:95:0f:7f:de:81:58:60:6f:ce:39:f3:39:09:
+ b3:0e:ff:f9:f1:fa:ce:9c:8c:d1:8b:39:b8:ce:ac:d8:b1:63:
+ 08:fd:bd:c9:a8:b7:59:68:14:f2:17:23:0a:c8:04:34:85:5f:
+ 05:ba:70:7c:b6:56:aa:aa:7b:86:23:93:27:4c:ac:8f:4e:3a:
+ 5f:c6:54:74:d7:d4:00:a7:e7:b8:76:6c:6f:02:62:f0:55:4f:
+ 49:35:d6:f1:63:ba:e4:3b:90:cd:cc:a1:2c:ca:f6:11:22:e7:
+ 23:74:98:ee:8e:35:c0:e7:58:2b:2b:c4:99:82:81:39:17:5b:
+ a5:b5:d8:df:ca:77:9c:f0:34:1e:d5:5b:ea:76:45:b0:0a:53:
+ 6d:94:8f:7a:01:b5:83:32:0b:97:75:3a:2f:dd:cb:0c:40:6f:
+ 8c:57:17:db:21:04:6b:72:bc:e1:eb:72:8c:d4:25:53:63:bb:
+ f5:22:0b:40:dc:d0:e3:7b:fc:52:da:c4:cd:44:c1:3e:60:ae:
+ 88:c1:01:5b:52:71:33:c2:e7:43:c6:bd:92:50:46:50:ea:2e:
+ d7:ae:2f:d4:35:1e:69:e3:75:e1:bc:e7:0a:a2:e5:cb:5b:da:
+ 5e:c5:92:55:df:a2:71:44:bc:93:3a:6d:e5:cd:48:40:e2:fb:
+ 72:09:c9:e3
+-----BEGIN CERTIFICATE-----
+MIIDCTCCAfGgAwIBAgIUZLWyV5Ir5YbGyLFr9XlNJbIFkUUwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDIxODIyMDIzM1oXDTMwMDIx
+NTIyMDIzM1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEA+wEsAs0VSYXq4JVXE3qciO2T+BG81LIKV46rtF7aqSS4
+Q2M1LN+hNY1JERrwnAoVYw9OU1Q1n44tD1cT/bhhf+f/RKojuT7mWXEqk4Ri+R2S
+NyCgOMOgvwkoGXqHkIkxsIRPj56u9XMRQf/qEhuru0xOurFQ/zexNT8Nqrukk/EM
+Hb12czItIht3kefG1LRe078Cb4cWxAhrPqUXir+ClUL7LmmPJgppfcH2jafKaR2B
+lawm1rl1JXLsE8nPgvvzOZAifmRrwy+tAA7lJ4fPYKquZAroBJuPJUPMnqgQYl9M
+Oo2VE78Y+my+eb42hB0AujXGBtdbGxm27IhgbFgeLwIDAQABo1MwUTAdBgNVHQ4E
+FgQUHY3Lxd5wInwfR5FsYQPDq3jKZiYwHwYDVR0jBBgwFoAUHY3Lxd5wInwfR5Fs
+YQPDq3jKZiYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEArjoi
+pbuVD3/egVhgb8458zkJsw7/+fH6zpyM0Ys5uM6s2LFjCP29yai3WWgU8hcjCsgE
+NIVfBbpwfLZWqqp7hiOTJ0ysj046X8ZUdNfUAKfnuHZsbwJi8FVPSTXW8WO65DuQ
+zcyhLMr2ESLnI3SY7o41wOdYKyvEmYKBORdbpbXY38p3nPA0HtVb6nZFsApTbZSP
+egG1gzILl3U6L93LDEBvjFcX2yEEa3K84etyjNQlU2O79SILQNzQ43v8UtrEzUTB
+PmCuiMEBW1JxM8LnQ8a9klBGUOou164v1DUeaeN14bznCqLly1vaXsWSVd+icUS8
+kzpt5c1IQOL7cgnJ4w==
+-----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 0000000000..a8c69d237c
--- /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,6C66380BB92F2E7A0B6CE1D5AF290071
+
+7iu0jn3UasRUxYvSzozTybKZg6RBZtclJhSF/kYSrAu36rbPG4mO5lPBZq1wc+0q
+PutAjbZikucjIrU+y8/S5B0Krqmp9HD/oQ9Um5Wrcw3OXSLhLqOBp7l+9qe0Y3BB
+Efo85Ok0maaLfRWGrQ2Y2DNeNmhmVWFDxEGYTIJZQL7jQY2rfPBLA/Yin48upIUJ
+6EtsVuQELwKaerf/PN5Xjig/vx01kR2Lset2uVeiy43ZcPeN6TSwEEj6bC1PFqCR
+5MQTT+u3/HMZE6UKZ1qOuVt0Cm+QqjNWD2y9ueWvyZ2lW3U+tW1SKSbTOdujSysS
+HWF0vwMt0Aeac3SUDAggVfPzrwPYFacKSUE3RQ28+3O8g5F7G6+R9KQ1VMFPuemk
++DSLZDyLkVYnO/iauzfivONOHHRNWaYdZxS+LxLw3PfoPLjSQG7M87asZXX/lSo8
+ka/4qsnBrMb3h0KDAuD6RmbEJNk8RK8a8X7+98weBVOh+IZkp/BH4q83IjiSQhmF
+DZxuU1dH01B/3NXn7Vbk9J3V1v/GoZf5kvCnmmzC7M5ehYSXHY8NqMpM7KxI+vlw
+YZS7HRD5+PHJv4YqlD9RiKAMQfri6GfV1AcVqO8maagmgSLVmPP9tKcKHPRrFpsY
+9cd3hWDBKJ47ZUNPv1C9ibZehMJoHRDwim6KnhT1vY4ikNrlwwIOt7n5OAael3GD
+sP7Oodrgnye8mM0JtET/DVEuBZsT5uS0tfpIQvJKP7gNRLv8sMxF9t2RRgaakryD
+DPD/YbZxBY2qJnvdrLT1Co5MguOvBh+067SRtVvHFOLb4SPiO1wRLy5UvZmjCRJX
+cfCivr4beBr+mN2+1xDVpq2MaEIlT4RQkHNk1odPhof36g16Abe6QVUr/5LSsHvX
++MbgdI0FkveYrF1RdH1/B5BBagDvgA6w3m/PhzdMXJAuElR0FY/Ypow7BP4tJVUt
+wDuB8pQS9gOMxa70RHnGI9GXxpMdiwMtvZOYlw7WmezryEYSNZrBOYl8t9WTB2Dn
+q7TIdRpqE8GMkKE9gurxl0WhN2YEODNICG9luoD0TzVGwVTFOeilANBcfHFqubVs
+Z9fdKHK9Wdr96RQjRzXrCsoMTVoX3A98PGUoDPgd7NPfbH1ybc1775SryzV/C3ii
+yi3hDBBEgxW1ydmSK1PPQdFXGiSM4Tqdg0sqE5vcYhTBe4CjUZaSiW3hrwqnf8cr
+RmSlwSemzZHW3JpcH/F1H+oj2Kz+S/raD9tMVFZuiO4YcZ/1ZEkC3K7jO+G0cc8X
+EJlt1j7Vu2ULECqhHGgd2RVDX06QCwM4ZmZVEmGvtRg9r/OKZhhR4Cjgw0UcFw9Z
+POlSI7GN/Ae0WlmpdC1yj/BUvf99hcUuiPy/eVvEJQIcZPkh7AzmbGMvf6OJSQd+
+TXaDtt/A3khqkQFUBuRkh5OtJaCoh2e7Htsmb0Xf5rWpnBdDY1zs8kwjUaMP0e7r
+IWbsby39Rrwh9nis9f8JwyHg0OZAAkyJPDbkIKOsHfbEWY5zCW54/2vX0S/7rn1u
+kYmrzHRls/lfGI4l6I5zMKb7QHfsKcCRO9NGjNEQPt/q3/Cf9ZjAe2lK2/ROKf/y
+-----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 0000000000..0964ba3508
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/ssl_passphrase_func.c
@@ -0,0 +1,82 @@
+/*-------------------------------------------------------------------------
+ *
+ * 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-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)
+{
+ 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 0000000000..e146e09dd7
--- /dev/null
+++ b/src/test/modules/ssl_passphrase_callback/t/001_testfunc.pl
@@ -0,0 +1,67 @@
+
+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 3650 -nodes -text -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 had successfully transformed the passphrase
+ok(-e "$ddir/postmaster.pid","postgres started");
+
+$node->stop('fast');
+
+# 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 a43e31c60e..e1ad4f4052 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -429,7 +429,7 @@ sub mkvcbuild
if (!$solution->{options}->{openssl})
{
- push @contrib_excludes, 'sslinfo';
+ push @contrib_excludes, 'sslinfo', 'ssl_passphrase_callback';
}
if (!$solution->{options}->{uuid})