aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/libpq/be-secure.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 6b1365c6d3e..dce0eaa20e2 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -73,6 +73,7 @@
#include "libpq/libpq.h"
#include "tcop/tcopprot.h"
+#include "utils/memutils.h"
#ifdef USE_SSL
@@ -945,44 +946,54 @@ aloop:
port->count = 0;
- /* get client certificate, if available. */
+ /* Get client certificate, if available. */
port->peer = SSL_get_peer_certificate(port->ssl);
- if (port->peer == NULL)
- {
- strlcpy(port->peer_dn, "(anonymous)", sizeof(port->peer_dn));
- strlcpy(port->peer_cn, "(anonymous)", sizeof(port->peer_cn));
- }
- else
+
+ /* and extract the Common Name from it. */
+ port->peer_cn = NULL;
+ if (port->peer != NULL)
{
- X509_NAME_oneline(X509_get_subject_name(port->peer),
- port->peer_dn, sizeof(port->peer_dn));
- port->peer_dn[sizeof(port->peer_dn) - 1] = '\0';
- r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
- NID_commonName, port->peer_cn, sizeof(port->peer_cn));
- port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
- if (r == -1)
- {
- /* Unable to get the CN, set it to blank so it can't be used */
- port->peer_cn[0] = '\0';
- }
- else
+ int len;
+
+ len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
+ NID_commonName, NULL, 0);
+ if (len != -1)
{
+ char *peer_cn;
+
+ peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
+ r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
+ NID_commonName, peer_cn, len + 1);
+ peer_cn[len] = '\0';
+ if (r != len)
+ {
+ /* shouldn't happen */
+ pfree(peer_cn);
+ close_SSL(port);
+ return -1;
+ }
+
/*
* Reject embedded NULLs in certificate common name to prevent
* attacks like CVE-2009-4034.
*/
- if (r != strlen(port->peer_cn))
+ if (len != strlen(peer_cn))
{
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL certificate's common name contains embedded null")));
+ pfree(peer_cn);
close_SSL(port);
return -1;
}
+
+ port->peer_cn = peer_cn;
}
}
+
ereport(DEBUG2,
- (errmsg("SSL connection from \"%s\"", port->peer_cn)));
+ (errmsg("SSL connection from \"%s\"",
+ port->peer_cn ? port->peer_cn : "(anonymous)")));
/* set up debugging/info callback */
SSL_CTX_set_info_callback(SSL_context, info_cb);
@@ -1008,6 +1019,12 @@ close_SSL(Port *port)
X509_free(port->peer);
port->peer = NULL;
}
+
+ if (port->peer_cn)
+ {
+ pfree(port->peer_cn);
+ port->peer_cn = NULL;
+ }
}
/*