Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit91fa7b4

Browse files
committed
Add API functions to libpq to interrogate SSL related stuff.
This makes it possible to query for things like the SSL version and cipherused, without depending on OpenSSL functions or macros. That is a goodthing if we ever get another SSL implementation.PQgetssl() still works, but it should be considered as deprecated as itonly works with OpenSSL. In particular, PQgetSslInUse() should be used tocheck if a connection uses SSL, because as soon as we have anotherimplementation, PQgetssl() will return NULL even if SSL is in use.
1 parent809d9a2 commit91fa7b4

File tree

6 files changed

+251
-37
lines changed

6 files changed

+251
-37
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 139 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,33 +1848,127 @@ int PQconnectionUsedPassword(const PGconn *conn);
18481848
</para>
18491849
</listitem>
18501850
</varlistentry>
1851+
</variablelist>
1852+
</para>
18511853

1852-
<varlistentry id="libpq-pqgetssl">
1853-
<term><function>PQgetssl</function><indexterm><primary>PQgetssl</></></term>
1854+
<para>
1855+
The following functions return information related to SSL. This information
1856+
usually doesn't change after a connection is established.
1857+
1858+
<variablelist>
1859+
<varlistentry id="libpq-pqsslinuse">
1860+
<term><function>PQsslInUse</function><indexterm><primary>PQsslInUse</></></term>
18541861
<listitem>
18551862
<para>
1856-
<indexterm><primary>SSL</><secondary sortas="libpq">in libpq</secondary></indexterm>
1857-
Returns the SSL structure used in the connection, or null
1858-
if SSL is not in use.
1863+
Returns true (1) if the connection uses SSL, false (0) if not.
18591864

18601865
<synopsis>
1861-
void *PQgetssl(const PGconn *conn);
1866+
int PQsslInUse(const PGconn *conn);
18621867
</synopsis>
18631868
</para>
18641869

1870+
</listitem>
1871+
</varlistentry>
1872+
1873+
<varlistentry id="libpq-pqsslAttribute">
1874+
<term><function>PQsslAttribute</function><indexterm><primary>PQsslAttribute</></></term>
1875+
<listitem>
18651876
<para>
1866-
This structure can be used to verify encryption levels, check server
1867-
certificates, and more. Refer to the <productname>OpenSSL</>
1868-
documentation for information about this structure.
1877+
Returns SSL-related information about the connection.
1878+
1879+
<synopsis>
1880+
const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
1881+
</synopsis>
1882+
</para>
1883+
1884+
<para>
1885+
The list of available attributes varies depending on the SSL library
1886+
being used, and the type of connection. If an attribute is not
1887+
available, returns NULL.
1888+
</para>
1889+
1890+
<para>
1891+
The following attributes are commonly available:
1892+
<variablelist>
1893+
<varlistentry>
1894+
<term><literal>library</literal></term>
1895+
<listitem>
1896+
<para>
1897+
Name of the SSL implementation in use. (Currently, only
1898+
<literal>"OpenSSL"</literal> is implemented)
1899+
</para>
1900+
</listitem>
1901+
</varlistentry>
1902+
<varlistentry>
1903+
<term><literal>protocol</literal></term>
1904+
<listitem>
1905+
<para>
1906+
SSL/TLS version in use. Common values are "SSLv2", "SSLv3",
1907+
"TLSv1", "TLSv1.1" and "TLSv1.2", but an implementation may
1908+
return other strings if some other protocol is used.
1909+
</para>
1910+
</listitem>
1911+
</varlistentry>
1912+
<varlistentry>
1913+
<term><literal>key_bits</literal></term>
1914+
<listitem>
1915+
<para>
1916+
Number of key bits used by the encryption algorithm.
1917+
</para>
1918+
</listitem>
1919+
</varlistentry>
1920+
<varlistentry>
1921+
<term><literal>cipher</literal></term>
1922+
<listitem>
1923+
<para>
1924+
A short name of the ciphersuite used, e.g.
1925+
<literal>"DHE-RSA-DES-CBC3-SHA"</literal>. The names are specific
1926+
to each SSL implementation.
1927+
</para>
1928+
</listitem>
1929+
</varlistentry>
1930+
<varlistentry>
1931+
<term><literal>compression</literal></term>
1932+
<listitem>
1933+
<para>
1934+
If SSL compression is in use, returns the name of the compression
1935+
algorithm, or "on" if compression is used but the algorithm is
1936+
not known. If compression is not in use, returns "off".
1937+
</para>
1938+
</listitem>
1939+
</varlistentry>
1940+
</variablelist>
18691941
</para>
1942+
</listitem>
1943+
</varlistentry>
18701944

1945+
<varlistentry id="libpq-pqsslattributes">
1946+
<term><function>PQsslAttributes</function><indexterm><primary>PQsslAttributes</></></term>
1947+
<listitem>
1948+
<para>
1949+
Return an array of SSL attribute names available. The array is terminated by a NULL pointer.
1950+
<synopsis>
1951+
const char **PQsslAttributes(const PGconn *conn);
1952+
</synopsis>
1953+
</para>
1954+
</listitem>
1955+
</varlistentry>
1956+
1957+
<varlistentry id="libpq-pqsslstruct">
1958+
<term><function>PQsslStruct</function><indexterm><primary>PQsslStruct</></></term>
1959+
<listitem>
1960+
<para>
1961+
Return a pointer to an SSL-implementation specific object describing
1962+
the connection.
1963+
<synopsis>
1964+
void *PQsslStruct(const PGconn *conn, const char *struct_name);
1965+
</synopsis>
1966+
</para>
18711967
<para>
1872-
The actual return value is of type <type>SSL *</type>,
1873-
where <type>SSL</type> is a type defined by
1874-
the <productname>OpenSSL</productname> library, but it is not declared
1875-
this way to avoid requiring the <productname>OpenSSL</productname>
1876-
header files. To use this function, code along the following lines
1877-
could be used:
1968+
The structs available depends on the SSL implementation in use.
1969+
For OpenSSL, there is one struct, under the name "OpenSSL",
1970+
and it returns a pointer to the OpenSSL <literal>SSL</literal> struct.
1971+
To use this function, code along the following lines could be used:
18781972
<programlisting><![CDATA[
18791973
#include <libpq-fe.h>
18801974
#include <openssl/ssl.h>
@@ -1886,13 +1980,42 @@ void *PQgetssl(const PGconn *conn);
18861980
dbconn = PQconnectdb(...);
18871981
...
18881982

1889-
ssl =PQgetssl(dbconn);
1983+
ssl =PQsslStruct(dbconn, "OpenSSL");
18901984
if (ssl)
18911985
{
18921986
/* use OpenSSL functions to access ssl */
18931987
}
18941988
]]></programlisting>
18951989
</para>
1990+
<para>
1991+
This structure can be used to verify encryption levels, check server
1992+
certificates, and more. Refer to the <productname>OpenSSL</>
1993+
documentation for information about this structure.
1994+
</para>
1995+
</listitem>
1996+
</varlistentry>
1997+
1998+
<varlistentry id="libpq-pqgetssl">
1999+
<term><function>PQgetssl</function><indexterm><primary>PQgetssl</></></term>
2000+
<listitem>
2001+
<para>
2002+
<indexterm><primary>SSL</><secondary sortas="libpq">in libpq</secondary></indexterm>
2003+
Returns the SSL structure used in the connection, or null
2004+
if SSL is not in use.
2005+
2006+
<synopsis>
2007+
void *PQgetssl(const PGconn *conn);
2008+
</synopsis>
2009+
</para>
2010+
2011+
<para>
2012+
This function is equivalent to PQsslStruct(conn, "OpenSSL"). It should
2013+
not be used in new applications, because the returned struct is
2014+
specific to OpenSSL and will not be available if another SSL
2015+
implementation is used. To check if a connection uses SSL, call
2016+
<function>PQsslInUse</> instead, and for more details about the
2017+
connection, use <function>PQsslAttribute</>.
2018+
</para>
18962019
</listitem>
18972020
</varlistentry>
18982021

‎src/bin/psql/command.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@
3030
#include<sys/types.h>/* for umask() */
3131
#include<sys/stat.h>/* for stat() */
3232
#endif
33-
#ifdefUSE_OPENSSL
34-
#include<openssl/ssl.h>
35-
#endif
3633

3734
#include"portability/instr_time.h"
3835

@@ -1815,28 +1812,24 @@ connection_warnings(bool in_startup)
18151812
staticvoid
18161813
printSSLInfo(void)
18171814
{
1818-
#ifdefUSE_OPENSSL
1819-
intsslbits=-1;
1820-
SSL*ssl;
1815+
constchar*protocol;
1816+
constchar*cipher;
1817+
constchar*bits;
1818+
constchar*compression;
18211819

1822-
ssl=PQgetssl(pset.db);
1823-
if (!ssl)
1820+
if (!PQsslInUse(pset.db))
18241821
return;/* no SSL */
18251822

1826-
SSL_get_cipher_bits(ssl,&sslbits);
1827-
printf(_("SSL connection (protocol: %s, cipher: %s, bits: %d, compression: %s)\n"),
1828-
SSL_get_version(ssl),SSL_get_cipher(ssl),sslbits,
1829-
SSL_get_current_compression(ssl) ?_("on") :_("off"));
1830-
#else
1823+
protocol=PQsslAttribute(pset.db,"protocol");
1824+
cipher=PQsslAttribute(pset.db,"cipher");
1825+
bits=PQsslAttribute(pset.db,"key_bits");
1826+
compression=PQsslAttribute(pset.db,"compression");
18311827

1832-
/*
1833-
* If psql is compiled without SSL but is using a libpq with SSL, we
1834-
* cannot figure out the specifics about the connection. But we know it's
1835-
* SSL secured.
1836-
*/
1837-
if (PQgetssl(pset.db))
1838-
printf(_("SSL connection (unknown cipher)\n"));
1839-
#endif
1828+
printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n"),
1829+
protocol ?protocol :_("unknown"),
1830+
cipher ?cipher :_("unknown"),
1831+
bits ?bits :_("unknown"),
1832+
(compression&&strcmp(compression,"off")!=0) ?_("on") :_("off"));
18401833
}
18411834

18421835

‎src/interfaces/libpq/exports.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,7 @@ lo_lseek64 162
165165
lo_tell64 163
166166
lo_truncate64 164
167167
PQconninfo 165
168+
PQsslInUse 166
169+
PQsslStruct 167
170+
PQsslAttributes 168
171+
PQsslAttribute 169

‎src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,18 @@ SSLerrfree(char *buf)
14881488
free(buf);
14891489
}
14901490

1491+
/* ------------------------------------------------------------ */
1492+
/*SSL information functions*/
1493+
/* ------------------------------------------------------------ */
1494+
1495+
int
1496+
PQsslInUse(PGconn*conn)
1497+
{
1498+
if (!conn)
1499+
return0;
1500+
returnconn->ssl_in_use;
1501+
}
1502+
14911503
/*
14921504
*Return pointer to OpenSSL object.
14931505
*/
@@ -1499,6 +1511,62 @@ PQgetssl(PGconn *conn)
14991511
returnconn->ssl;
15001512
}
15011513

1514+
void*
1515+
PQsslStruct(PGconn*conn,constchar*struct_name)
1516+
{
1517+
if (!conn)
1518+
returnNULL;
1519+
if (strcmp(struct_name,"OpenSSL")==0)
1520+
returnconn->ssl;
1521+
returnNULL;
1522+
}
1523+
1524+
constchar**
1525+
PQsslAttributes(PGconn*conn)
1526+
{
1527+
staticconstchar*result[]= {
1528+
"library",
1529+
"key_bits",
1530+
"cipher",
1531+
"compression",
1532+
"protocol",
1533+
NULL
1534+
};
1535+
returnresult;
1536+
}
1537+
1538+
constchar*
1539+
PQsslAttribute(PGconn*conn,constchar*attribute_name)
1540+
{
1541+
if (!conn)
1542+
returnNULL;
1543+
if (conn->ssl==NULL)
1544+
returnNULL;
1545+
1546+
if (strcmp(attribute_name,"library")==0)
1547+
return"OpenSSL";
1548+
1549+
if (strcmp(attribute_name,"key_bits")==0)
1550+
{
1551+
staticcharsslbits_str[10];
1552+
intsslbits;
1553+
1554+
SSL_get_cipher_bits(conn->ssl,&sslbits);
1555+
snprintf(sslbits_str,sizeof(sslbits_str),"%d",sslbits);
1556+
returnsslbits_str;
1557+
}
1558+
1559+
if (strcmp(attribute_name,"cipher")==0)
1560+
returnSSL_get_cipher(conn->ssl);
1561+
1562+
if (strcmp(attribute_name,"compression")==0)
1563+
returnSSL_get_current_compression(conn->ssl) ?"on" :"off";
1564+
1565+
if (strcmp(attribute_name,"protocol")==0)
1566+
returnSSL_get_version(conn->ssl);
1567+
1568+
returnNULL;/* unknown attribute */
1569+
}
15021570

15031571
/*
15041572
* Private substitute BIO: this does the sending and receiving using send() and

‎src/interfaces/libpq/fe-secure.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,12 +381,32 @@ pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
381381
returnn;
382382
}
383383

384+
/* Dummy versions of SSL info functions, when built without SSL support */
384385
#ifndefUSE_SSL
386+
387+
int
388+
PQsslInUse(PGconn*conn)
389+
{
390+
return0;
391+
}
392+
385393
void*
386394
PQgetssl(PGconn*conn)
387395
{
388396
returnNULL;
389397
}
398+
399+
void*
400+
PQsslStruct(PGconn*conn,constchar*struct_name)
401+
{
402+
returnNULL;
403+
}
404+
405+
constchar*
406+
PQsslAttribute(PGconn*conn,constchar*attribute_name)
407+
{
408+
returnNULL;
409+
}
390410
#endif/* USE_SSL */
391411

392412

‎src/interfaces/libpq/libpq-fe.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,12 @@ extern intPQconnectionUsedPassword(const PGconn *conn);
318318
externintPQclientEncoding(constPGconn*conn);
319319
externintPQsetClientEncoding(PGconn*conn,constchar*encoding);
320320

321+
/* SSL information functions */
322+
externintPQsslInUse(PGconn*conn);
323+
externvoid*PQsslStruct(PGconn*conn,constchar*struct_name);
324+
externconstchar*PQsslAttribute(PGconn*conn,constchar*attribute_name);
325+
externconstchar**PQsslAttributes(PGconn*conn);
326+
321327
/* Get the OpenSSL structure associated with a connection. Returns NULL for
322328
* unencrypted connections or if any other TLS library is in use. */
323329
externvoid*PQgetssl(PGconn*conn);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp