Fix multiple breakages in our support for SSL certificates.
This commit is contained in:
parent
9236c79c8e
commit
7ac258c2f3
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.163 2004/09/23 13:31:09 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.164 2004/09/26 22:51:49 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="libpq">
|
<chapter id="libpq">
|
||||||
@ -233,22 +233,13 @@ PGconn *PQconnectdb(const char *conninfo);
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
If <productname>PostgreSQL</> is compiled without SSL support,
|
If <productname>PostgreSQL</> is compiled without SSL support,
|
||||||
using option <literal>require</> will cause an error, and
|
using option <literal>require</> will cause an error, while
|
||||||
options <literal>allow</> and <literal>prefer</> will be
|
options <literal>allow</> and <literal>prefer</> will be
|
||||||
tolerated but <application>libpq</> will be unable to negotiate
|
tolerated but <application>libpq</> will be unable to negotiate
|
||||||
an <acronym>SSL</>
|
an <acronym>SSL</>
|
||||||
connection.<indexterm><primary>SSL</><secondary
|
connection.<indexterm><primary>SSL</><secondary
|
||||||
sortas="libpq">with libpq</></indexterm>
|
sortas="libpq">with libpq</></indexterm>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
Please note that <acronym>SSL</> support in libpq covers
|
|
||||||
encryption only. It will not verify the validity of the
|
|
||||||
certificate presented by the server that you are connecting to,
|
|
||||||
nor verify that the hostname matches that of the server's
|
|
||||||
certificate. Additionally, there is no support for client
|
|
||||||
certificates.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -3688,6 +3679,41 @@ If the permissions are less strict than this, the file will be ignored.
|
|||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1 id="libpq-ssl">
|
||||||
|
<title>SSL Support</title>
|
||||||
|
|
||||||
|
<indexterm zone="libpq-ssl">
|
||||||
|
<primary>SSL</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<productname>PostgreSQL</> has native support for using
|
||||||
|
<acronym>SSL</> connections to encrypt client/server communications
|
||||||
|
for increased security. See <xref linkend="ssl-tcp"> for details
|
||||||
|
about the server-side <acronym>SSL</> functionality.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If the server demands a client certificate,
|
||||||
|
<application>libpq</application>
|
||||||
|
will send the certificate stored in file
|
||||||
|
<filename>.postgresql/postgresql.crt</> within the user's home directory.
|
||||||
|
A matching private key file <filename>.postgresql/postgresql.key</>
|
||||||
|
must also be present, and must not be world-readable.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If the file <filename>.postgresql/root.crt</> is present in the user's
|
||||||
|
home directory,
|
||||||
|
<application>libpq</application> will use the certificate list stored
|
||||||
|
therein to verify the server's certificate. The SSL connection will
|
||||||
|
fail if the server does not present a certificate; therefore, to
|
||||||
|
use this feature the server must also have a <filename>root.crt</> file.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
<sect1 id="libpq-threading">
|
<sect1 id="libpq-threading">
|
||||||
<title>Behavior in Threaded Programs</title>
|
<title>Behavior in Threaded Programs</title>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.283 2004/09/23 13:15:57 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.284 2004/09/26 22:51:49 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Chapter Id="runtime">
|
<Chapter Id="runtime">
|
||||||
@ -804,7 +804,7 @@ SET ENABLE_SEQSCAN TO OFF;
|
|||||||
<para>
|
<para>
|
||||||
Enables <acronym>SSL</> connections. Please read
|
Enables <acronym>SSL</> connections. Please read
|
||||||
<xref linkend="ssl-tcp"> before using this. The default
|
<xref linkend="ssl-tcp"> before using this. The default
|
||||||
is off.
|
is off. This parameter can only be set at server start.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -4324,8 +4324,8 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
|
|||||||
The server will listen for both standard and <acronym>SSL</>
|
The server will listen for both standard and <acronym>SSL</>
|
||||||
connections on the same TCP port, and will negotiate with any
|
connections on the same TCP port, and will negotiate with any
|
||||||
connecting client on whether to use <acronym>SSL</>. See <xref
|
connecting client on whether to use <acronym>SSL</>. See <xref
|
||||||
linkend="auth-pg-hba-conf"> about how to force the server to
|
linkend="auth-pg-hba-conf"> about how to set up the server to
|
||||||
require use of <acronym>SSL</> for certain connections.
|
require use of <acronym>SSL</> for some or all connections.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -4361,20 +4361,24 @@ chmod og-rwx server.key
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
If verification of client certificates is required, place the
|
If verification of client certificates is required, place the
|
||||||
certificates of the <acronym>CA</acronym> you wish to check for in
|
certificates of the <acronym>CA</acronym>(s) you wish to check for in
|
||||||
the file <filename>root.crt</filename> in the data directory. When
|
the file <filename>root.crt</filename> in the data directory. When
|
||||||
present, a client certificate will be requested from the client
|
present, a client certificate will be requested from the client
|
||||||
making the connection and it must have been signed by one of the
|
during SSL connection startup, and it must have been signed by one of the
|
||||||
certificates present in <filename>root.crt</filename>. If no
|
certificates present in <filename>root.crt</filename>.
|
||||||
certificate is presented, the connection will be allowed to proceed
|
|
||||||
anway.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <filename>root.crt</filename> file is always checked for, and
|
When the <filename>root.crt</filename> file is not present, client
|
||||||
its absence will be noted through a message in the log. This is
|
certificates will not be requested or checked. In this mode, SSL
|
||||||
merely an informative message that client certificates will not be
|
provides communication security but not authentication.
|
||||||
requested.
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The files <filename>server.key</>, <filename>server.crt</>,
|
||||||
|
and <filename>root.crt</filename> are only examined during server
|
||||||
|
start; so you must restart the server to make changes in them take
|
||||||
|
effect.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.50 2004/09/23 20:27:50 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.51 2004/09/26 22:51:49 tgl Exp $
|
||||||
*
|
*
|
||||||
* Since the server static private key ($DataDir/server.key)
|
* Since the server static private key ($DataDir/server.key)
|
||||||
* will normally be stored unencrypted so that the database
|
* will normally be stored unencrypted so that the database
|
||||||
@ -117,7 +117,6 @@ static const char *SSLerrmessage(void);
|
|||||||
* (total in both directions) before we require renegotiation.
|
* (total in both directions) before we require renegotiation.
|
||||||
*/
|
*/
|
||||||
#define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
|
#define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
|
||||||
#define CA_PATH NULL
|
|
||||||
|
|
||||||
static SSL_CTX *SSL_context = NULL;
|
static SSL_CTX *SSL_context = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -412,12 +411,12 @@ static DH *
|
|||||||
load_dh_file(int keylength)
|
load_dh_file(int keylength)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char fnbuf[2048];
|
char fnbuf[MAXPGPATH];
|
||||||
DH *dh = NULL;
|
DH *dh = NULL;
|
||||||
int codes;
|
int codes;
|
||||||
|
|
||||||
/* attempt to open file. It's not an error if it doesn't exist. */
|
/* attempt to open file. It's not an error if it doesn't exist. */
|
||||||
snprintf(fnbuf, sizeof fnbuf, "%s/dh%d.pem", DataDir, keylength);
|
snprintf(fnbuf, sizeof(fnbuf), "%s/dh%d.pem", DataDir, keylength);
|
||||||
if ((fp = fopen(fnbuf, "r")) == NULL)
|
if ((fp = fopen(fnbuf, "r")) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -694,20 +693,26 @@ initialize_SSL(void)
|
|||||||
if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
|
if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
|
||||||
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
|
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
|
||||||
|
|
||||||
/* accept client certificates, but don't require them. */
|
/*
|
||||||
|
* Require and check client certificates only if we have a root.crt file.
|
||||||
|
*/
|
||||||
snprintf(fnbuf, sizeof(fnbuf), "%s/root.crt", DataDir);
|
snprintf(fnbuf, sizeof(fnbuf), "%s/root.crt", DataDir);
|
||||||
if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, CA_PATH))
|
if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
|
||||||
{
|
{
|
||||||
/* Not fatal - we do not require client certificates */
|
/* Not fatal - we do not require client certificates */
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("could not load root certificate file \"%s\": %s",
|
(errmsg("could not load root certificate file \"%s\": %s",
|
||||||
fnbuf, SSLerrmessage()),
|
fnbuf, SSLerrmessage()),
|
||||||
errdetail("Will not verify client certificates.")));
|
errdetail("Will not verify client certificates.")));
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
SSL_CTX_set_verify(SSL_context,
|
SSL_CTX_set_verify(SSL_context,
|
||||||
SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
|
(SSL_VERIFY_PEER |
|
||||||
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
|
||||||
|
SSL_VERIFY_CLIENT_ONCE),
|
||||||
verify_cb);
|
verify_cb);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.51 2004/09/23 20:27:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.52 2004/09/26 22:51:49 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
|
* [ Most of these notes are wrong/obsolete, but perhaps not all ]
|
||||||
|
*
|
||||||
* The client *requires* a valid server certificate. Since
|
* The client *requires* a valid server certificate. Since
|
||||||
* SSH tunnels provide anonymous confidentiality, the presumption
|
* SSH tunnels provide anonymous confidentiality, the presumption
|
||||||
* is that sites that want endpoint authentication will use the
|
* is that sites that want endpoint authentication will use the
|
||||||
@ -527,7 +529,7 @@ verify_peer(PGconn *conn)
|
|||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not get information about host (%s): %s\n"),
|
libpq_gettext("could not get information about host \"%s\": %s\n"),
|
||||||
conn->peer_cn, hstrerror(h_errno));
|
conn->peer_cn, hstrerror(h_errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -600,15 +602,15 @@ load_dh_file(int keylength)
|
|||||||
struct passwd pwdstr;
|
struct passwd pwdstr;
|
||||||
struct passwd *pwd = NULL;
|
struct passwd *pwd = NULL;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char fnbuf[2048];
|
char fnbuf[MAXPGPATH];
|
||||||
DH *dh = NULL;
|
DH *dh = NULL;
|
||||||
int codes;
|
int codes;
|
||||||
|
|
||||||
if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
|
if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* attempt to open file. It's not an error if it doesn't exist. */
|
/* attempt to open file. It's not an error if it doesn't exist. */
|
||||||
snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
|
snprintf(fnbuf, sizeof(fnbuf), "%s/.postgresql/dh%d.pem",
|
||||||
pwd->pw_dir, keylength);
|
pwd->pw_dir, keylength);
|
||||||
|
|
||||||
if ((fp = fopen(fnbuf, "r")) == NULL)
|
if ((fp = fopen(fnbuf, "r")) == NULL)
|
||||||
@ -735,7 +737,7 @@ tmp_dh_cb(SSL *s, int is_export, int keylength)
|
|||||||
* This callback is only called when the server wants a
|
* This callback is only called when the server wants a
|
||||||
* client cert.
|
* client cert.
|
||||||
*
|
*
|
||||||
* Returns 1 on success, 0 on no data, -1 on error.
|
* Must return 1 on success, 0 on no data or error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
||||||
@ -748,52 +750,52 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|||||||
struct passwd *pwd = NULL;
|
struct passwd *pwd = NULL;
|
||||||
struct stat buf,
|
struct stat buf,
|
||||||
buf2;
|
buf2;
|
||||||
char fnbuf[2048];
|
char fnbuf[MAXPGPATH];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
PGconn *conn = (PGconn *) SSL_get_app_data(ssl);
|
PGconn *conn = (PGconn *) SSL_get_app_data(ssl);
|
||||||
int (*cb) () = NULL; /* how to read user password */
|
int (*cb) () = NULL; /* how to read user password */
|
||||||
char sebuf[256];
|
char sebuf[256];
|
||||||
|
|
||||||
|
|
||||||
if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
|
if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) != 0)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not get user information\n"));
|
libpq_gettext("could not get user information\n"));
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the user certificate */
|
/* read the user certificate */
|
||||||
snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.crt",
|
snprintf(fnbuf, sizeof(fnbuf), "%s/.postgresql/postgresql.crt",
|
||||||
pwd->pw_dir);
|
pwd->pw_dir);
|
||||||
if (stat(fnbuf, &buf) == -1)
|
if (stat(fnbuf, &buf) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
if ((fp = fopen(fnbuf, "r")) == NULL)
|
if ((fp = fopen(fnbuf, "r")) == NULL)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not open certificate (%s): %s\n"),
|
libpq_gettext("could not open certificate file \"%s\": %s\n"),
|
||||||
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
|
if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
|
||||||
{
|
{
|
||||||
char *err = SSLerrmessage();
|
char *err = SSLerrmessage();
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not read certificate (%s): %s\n"),
|
libpq_gettext("could not read certificate file \"%s\": %s\n"),
|
||||||
fnbuf, err);
|
fnbuf, err);
|
||||||
SSLerrfree(err);
|
SSLerrfree(err);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* read the user key */
|
/* read the user key */
|
||||||
snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.key",
|
snprintf(fnbuf, sizeof(fnbuf), "%s/.postgresql/postgresql.key",
|
||||||
pwd->pw_dir);
|
pwd->pw_dir);
|
||||||
if (stat(fnbuf, &buf) == -1)
|
if (stat(fnbuf, &buf) == -1)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("certificate present, but not private key (%s)\n"),
|
libpq_gettext("certificate present, but not private key file \"%s\"\n"),
|
||||||
fnbuf);
|
fnbuf);
|
||||||
X509_free(*x509);
|
X509_free(*x509);
|
||||||
return 0;
|
return 0;
|
||||||
@ -802,37 +804,38 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|||||||
buf.st_uid != getuid())
|
buf.st_uid != getuid())
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("private key (%s) has wrong permissions\n"), fnbuf);
|
libpq_gettext("private key file \"%s\" has wrong permissions\n"),
|
||||||
|
fnbuf);
|
||||||
X509_free(*x509);
|
X509_free(*x509);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((fp = fopen(fnbuf, "r")) == NULL)
|
if ((fp = fopen(fnbuf, "r")) == NULL)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not open private key file (%s): %s\n"),
|
libpq_gettext("could not open private key file \"%s\": %s\n"),
|
||||||
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
||||||
X509_free(*x509);
|
X509_free(*x509);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if (fstat(fileno(fp), &buf2) == -1 ||
|
if (fstat(fileno(fp), &buf2) == -1 ||
|
||||||
buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
|
buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("private key (%s) changed during execution\n"), fnbuf);
|
libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
|
||||||
X509_free(*x509);
|
X509_free(*x509);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
|
if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
|
||||||
{
|
{
|
||||||
char *err = SSLerrmessage();
|
char *err = SSLerrmessage();
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not read private key (%s): %s\n"),
|
libpq_gettext("could not read private key file \"%s\": %s\n"),
|
||||||
fnbuf, err);
|
fnbuf, err);
|
||||||
SSLerrfree(err);
|
SSLerrfree(err);
|
||||||
X509_free(*x509);
|
X509_free(*x509);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
@ -842,12 +845,12 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|||||||
char *err = SSLerrmessage();
|
char *err = SSLerrmessage();
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("certificate/private key mismatch (%s): %s\n"),
|
libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
|
||||||
fnbuf, err);
|
fnbuf, err);
|
||||||
SSLerrfree(err);
|
SSLerrfree(err);
|
||||||
X509_free(*x509);
|
X509_free(*x509);
|
||||||
EVP_PKEY_free(*pkey);
|
EVP_PKEY_free(*pkey);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -952,45 +955,34 @@ initialize_SSL(PGconn *conn)
|
|||||||
char pwdbuf[BUFSIZ];
|
char pwdbuf[BUFSIZ];
|
||||||
struct passwd pwdstr;
|
struct passwd pwdstr;
|
||||||
struct passwd *pwd = NULL;
|
struct passwd *pwd = NULL;
|
||||||
char fnbuf[2048];
|
char fnbuf[MAXPGPATH];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (init_ssl_system(conn))
|
if (init_ssl_system(conn))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
/* Set up to verify server cert, if root.crt is present */
|
||||||
if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
|
if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
|
||||||
{
|
{
|
||||||
snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
|
snprintf(fnbuf, sizeof(fnbuf), "%s/.postgresql/root.crt",
|
||||||
pwd->pw_dir);
|
pwd->pw_dir);
|
||||||
if (stat(fnbuf, &buf) == -1)
|
if (stat(fnbuf, &buf) == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
|
||||||
#ifdef NOT_USED
|
|
||||||
char sebuf[256];
|
|
||||||
|
|
||||||
/* CLIENT CERTIFICATES NOT REQUIRED bjm 2002-09-26 */
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
|
||||||
libpq_gettext("could not read root certificate list (%s): %s\n"),
|
|
||||||
fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0))
|
|
||||||
{
|
{
|
||||||
char *err = SSLerrmessage();
|
char *err = SSLerrmessage();
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not read root certificate list (%s): %s\n"),
|
libpq_gettext("could not read root certificate file \"%s\": %s\n"),
|
||||||
fnbuf, err);
|
fnbuf, err);
|
||||||
SSLerrfree(err);
|
SSLerrfree(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
SSL_CTX_set_verify(SSL_context,
|
SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
|
||||||
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
|
}
|
||||||
SSL_CTX_set_verify_depth(SSL_context, 1);
|
}
|
||||||
|
|
||||||
/* set up empheral DH keys */
|
/* set up empheral DH keys */
|
||||||
SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
|
SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user