diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/psql/command.c | 35 | ||||
-rw-r--r-- | src/interfaces/libpq/exports.txt | 4 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 68 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-secure.c | 20 | ||||
-rw-r--r-- | src/interfaces/libpq/libpq-fe.h | 6 |
5 files changed, 112 insertions, 21 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 4ac21f20bf4..7c9f28dee06 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -30,9 +30,6 @@ #include <sys/types.h> /* for umask() */ #include <sys/stat.h> /* for stat() */ #endif -#ifdef USE_OPENSSL -#include <openssl/ssl.h> -#endif #include "portability/instr_time.h" @@ -1815,28 +1812,24 @@ connection_warnings(bool in_startup) static void printSSLInfo(void) { -#ifdef USE_OPENSSL - int sslbits = -1; - SSL *ssl; + const char *protocol; + const char *cipher; + const char *bits; + const char *compression; - ssl = PQgetssl(pset.db); - if (!ssl) + if (!PQsslInUse(pset.db)) return; /* no SSL */ - SSL_get_cipher_bits(ssl, &sslbits); - printf(_("SSL connection (protocol: %s, cipher: %s, bits: %d, compression: %s)\n"), - SSL_get_version(ssl), SSL_get_cipher(ssl), sslbits, - SSL_get_current_compression(ssl) ? _("on") : _("off")); -#else + protocol = PQsslAttribute(pset.db, "protocol"); + cipher = PQsslAttribute(pset.db, "cipher"); + bits = PQsslAttribute(pset.db, "key_bits"); + compression = PQsslAttribute(pset.db, "compression"); - /* - * If psql is compiled without SSL but is using a libpq with SSL, we - * cannot figure out the specifics about the connection. But we know it's - * SSL secured. - */ - if (PQgetssl(pset.db)) - printf(_("SSL connection (unknown cipher)\n")); -#endif + printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n"), + protocol ? protocol : _("unknown"), + cipher ? cipher : _("unknown"), + bits ? bits : _("unknown"), + (compression && strcmp(compression, "off") != 0) ? _("on") : _("off")); } diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt index 93da50df311..4a21bf1d2cf 100644 --- a/src/interfaces/libpq/exports.txt +++ b/src/interfaces/libpq/exports.txt @@ -165,3 +165,7 @@ lo_lseek64 162 lo_tell64 163 lo_truncate64 164 PQconninfo 165 +PQsslInUse 166 +PQsslStruct 167 +PQsslAttributes 168 +PQsslAttribute 169 diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 8cdf53ec7f8..a32af343a50 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1488,6 +1488,18 @@ SSLerrfree(char *buf) free(buf); } +/* ------------------------------------------------------------ */ +/* SSL information functions */ +/* ------------------------------------------------------------ */ + +int +PQsslInUse(PGconn *conn) +{ + if (!conn) + return 0; + return conn->ssl_in_use; +} + /* * Return pointer to OpenSSL object. */ @@ -1499,6 +1511,62 @@ PQgetssl(PGconn *conn) return conn->ssl; } +void * +PQsslStruct(PGconn *conn, const char *struct_name) +{ + if (!conn) + return NULL; + if (strcmp(struct_name, "OpenSSL") == 0) + return conn->ssl; + return NULL; +} + +const char ** +PQsslAttributes(PGconn *conn) +{ + static const char *result[] = { + "library", + "key_bits", + "cipher", + "compression", + "protocol", + NULL + }; + return result; +} + +const char * +PQsslAttribute(PGconn *conn, const char *attribute_name) +{ + if (!conn) + return NULL; + if (conn->ssl == NULL) + return NULL; + + if (strcmp(attribute_name, "library") == 0) + return "OpenSSL"; + + if (strcmp(attribute_name, "key_bits") == 0) + { + static char sslbits_str[10]; + int sslbits; + + SSL_get_cipher_bits(conn->ssl, &sslbits); + snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits); + return sslbits_str; + } + + if (strcmp(attribute_name, "cipher") == 0) + return SSL_get_cipher(conn->ssl); + + if (strcmp(attribute_name, "compression") == 0) + return SSL_get_current_compression(conn->ssl) ? "on" : "off"; + + if (strcmp(attribute_name, "protocol") == 0) + return SSL_get_version(conn->ssl); + + return NULL; /* unknown attribute */ +} /* * Private substitute BIO: this does the sending and receiving using send() and diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index 3b79c6bbe7b..b43f9fe155d 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -381,12 +381,32 @@ retry_masked: return n; } +/* Dummy versions of SSL info functions, when built without SSL support */ #ifndef USE_SSL + +int +PQsslInUse(PGconn *conn) +{ + return 0; +} + void * PQgetssl(PGconn *conn) { return NULL; } + +void * +PQsslStruct(PGconn *conn, const char *struct_name) +{ + return NULL; +} + +const char * +PQsslAttribute(PGconn *conn, const char *attribute_name) +{ + return NULL; +} #endif /* USE_SSL */ diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index c402119fd46..a73eae2087a 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -318,6 +318,12 @@ extern int PQconnectionUsedPassword(const PGconn *conn); extern int PQclientEncoding(const PGconn *conn); extern int PQsetClientEncoding(PGconn *conn, const char *encoding); +/* SSL information functions */ +extern int PQsslInUse(PGconn *conn); +extern void *PQsslStruct(PGconn *conn, const char *struct_name); +extern const char *PQsslAttribute(PGconn *conn, const char *attribute_name); +extern const char **PQsslAttributes(PGconn *conn); + /* Get the OpenSSL structure associated with a connection. Returns NULL for * unencrypted connections or if any other TLS library is in use. */ extern void *PQgetssl(PGconn *conn); |