aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
Commit message (Collapse)AuthorAge
* In libpq for Windows, call WSAStartup once and WSACleanup not at all.Tom Lane2020-10-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Windows documentation insists that every WSAStartup call should have a matching WSACleanup call. However, if that ever had actual relevance, it wasn't in this century. Every remotely-modern Windows kernel is capable of cleaning up when a process exits without doing that, and must be so to avoid resource leaks in case of a process crash. Moreover, Postgres backends have done WSAStartup without WSACleanup since commit 4cdf51e64 in 2004, and we've never seen any indication of a problem with that. libpq's habit of doing WSAStartup during connection start and WSACleanup during shutdown is also rather inefficient, since a series of non-overlapping connection requests leads to repeated, quite expensive DLL unload/reload cycles. We document a workaround for that (having the application call WSAStartup for itself), but that's just a kluge. It's also worth noting that it's far from uncommon for applications to exit without doing PQfinish, and we've not heard reports of trouble from that either. However, the real reason for acting on this is that recent experiments by Alexander Lakhin show that calling WSACleanup during PQfinish is triggering the symptom we occasionally see that a process using libpq fails to emit expected stdio output. Therefore, let's change libpq so that it calls WSAStartup only once per process, during the first connection attempt, and never calls WSACleanup at all. While at it, get rid of the only other WSACleanup call in our code tree, in pg_dump/parallel.c; that presumably is equally useless. Back-patch of HEAD commit 7d00a6b2d. Discussion: https://postgr.es/m/ac976d8c-03df-d6b8-025c-15a2de8d9af1@postgrespro.ru
* Teach libpq to handle arbitrary-length lines in .pgpass files.Tom Lane2020-09-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Historically there's been a hard-wired assumption here that no line of a .pgpass file could be as long as NAMEDATALEN*5 bytes. That's a bit shaky to start off with, because (a) there's no reason to suppose that host names fit in NAMEDATALEN, and (b) this figure fails to allow for backslash escape characters. However, it fails completely if someone wants to use a very long password, and we're now hearing reports of people wanting to use "security tokens" that can run up to several hundred bytes. Another angle is that the file is specified to allow comment lines, but there's no reason to assume that long comment lines aren't possible. Rather than guessing at what might be a more suitable limit, let's replace the fixed-size buffer with an expansible PQExpBuffer. That adds one malloc/free cycle to the typical use-case, but that's surely pretty cheap relative to the I/O this code has to do. Also, add TAP test cases to exercise this code, because there was no test coverage before. This reverts most of commit 2eb3bc588, as there's no longer a need for a warning message about overlength .pgpass lines. (I kept the explicit check for comment lines, though.) In HEAD and v13, this also fixes an oversight in 74a308cf5: there's not much point in explicit_bzero'ing the line buffer if we only do so in two of the three exit paths. Back-patch to all supported branches, except that the test case only goes back to v10 where src/test/authentication/ was added. Discussion: https://postgr.es/m/4187382.1598909041@sss.pgh.pa.us
* Fix bugs in libpq's management of GSS encryption state.Tom Lane2020-07-13
| | | | | | | | | | | | | | | | | | | | | GSS-related resources should be cleaned up in pqDropConnection, not freePGconn, else the wrong things happen when resetting a connection or trying to switch to a different server. It's also critical to reset conn->gssenc there. During connection setup, initialize conn->try_gss at the correct place, else switching to a different server won't work right. Remove now-redundant cleanup of GSS resources around one (and, for some reason, only one) pqDropConnection call in connectDBStart. Per report from Kyotaro Horiguchi that psql would freeze up, rather than successfully resetting a GSS-encrypted connection after a server restart. This is YA oversight in commit b0b39f72b, so back-patch to v12. Discussion: https://postgr.es/m/20200710.173803.435804731896516388.horikyota.ntt@gmail.com
* Fix dispsize for libpq connection parameters channel_binding and gssencmodeMichael Paquier2020-01-29
| | | | | | | | | | | | | channel_binding's longest allowed value is not "7", it is actually "8". gssencmode also got that wrong. A similar mistake has been fixed as of f4051e3. Backpatch down to v12, where gssencmode has been introduced. Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/20200128053633.GD1552@paquier.xyz Backpatch-through: 12
* Extensive code review for GSSAPI encryption mechanism.Tom Lane2020-01-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix assorted bugs in handling of non-blocking I/O when using GSSAPI encryption. The encryption layer could return the wrong status information to its caller, resulting in effectively dropping some data (or possibly in aborting a not-broken connection), or in a "livelock" situation where data remains to be sent but the upper layers think transmission is done and just go to sleep. There were multiple small thinkos contributing to that, as well as one big one (failure to think through what to do when a send fails after having already transmitted data). Note that these errors could cause failures whether the client application asked for non-blocking I/O or not, since both libpq and the backend always run things in non-block mode at this level. Also get rid of use of static variables for GSSAPI inside libpq; that's entirely not okay given that multiple connections could be open at once inside a single client process. Also adjust a bunch of random small discrepancies between the frontend and backend versions of the send/receive functions -- except for error handling, they should be identical, and now they are. Also extend the Kerberos TAP tests to exercise cases where nontrivial amounts of data need to be pushed through encryption. Before, those tests didn't provide any useful coverage at all for the cases of interest here. (They still might not, depending on timing, but at least there's a chance.) Per complaint from pmc@citylink and subsequent investigation. Back-patch to v12 where this code was introduced. Discussion: https://postgr.es/m/20200109181822.GA74698@gate.oper.dinoex.org
* libpq should expose GSS-related parameters even when not implemented.Tom Lane2019-12-20
| | | | | | | | | | | | | | | | | | | | | | We realized years ago that it's better for libpq to accept all connection parameters syntactically, even if some are ignored or restricted due to lack of the feature in a particular build. However, that lesson from the SSL support was for some reason never applied to the GSSAPI support. This is causing various buildfarm members to have problems with a test case added by commit 6136e94dc, and it's just a bad idea from a user-experience standpoint anyway, so fix it. While at it, fix some places where parameter-related infrastructure was added with the aid of a dartboard, or perhaps with the aid of the anti-pattern "add new stuff at the end". It should be safe to rearrange the contents of struct pg_conn even in released branches, since that's private to libpq (and we'd have to move some fields in some builds to fix this, anyway). Back-patch to all supported branches. Discussion: https://postgr.es/m/11297.1576868677@sss.pgh.pa.us
* Fix thinkos from 4f4061b for libpq integer parsingMichael Paquier2019-10-23
| | | | | | | | | | | A check was redundant. While on it, add an assertion to make sure that the parsing routine is never called with a NULL input. All the code paths currently calling the parsing routine are careful with NULL inputs already, but future callers may forget that. Reported-by: Peter Eisentraut, Lars Kanis Discussion: https://postgr.es/m/ec64956b-4597-56b6-c3db-457d15250fe4@2ndquadrant.com Backpatch-through: 12
* Fix error reporting of connect_timeout in libpq for value parsingMichael Paquier2019-10-21
| | | | | | | | | | | The logic was correctly detecting a parsing failure, but the parsing error did not get reported back to the client properly. Reported-by: Ed Morley Author: Lars Kanis Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/a9b4cbd7-4ecb-06b2-ebd7-1739bbff3217@greiz-reinsdorf.de Backpatch-through: 12
* Fix parsing of integer values for connection parameters in libpqMichael Paquier2019-10-21
| | | | | | | | | | | | | | | | Commit e7a2217 has introduced stricter checks for integer values in connection parameters for libpq. However this failed to correctly check after trailing whitespaces, while leading whitespaces were discarded per the use of strtol(3). This fixes and refactors the parsing logic to handle both cases consistently. Note that trying to restrict the use of trailing whitespaces can easily break connection strings like in ECPG regression tests (these have allowed me to catch the parsing bug with connect_timeout). Author: Michael Paquier Reviewed-by: Lars Kanis Discussion: https://postgr.es/m/a9b4cbd7-4ecb-06b2-ebd7-1739bbff3217@greiz-reinsdorf.de Backpatch-through: 12
* Message style fixesPeter Eisentraut2019-09-06
|
* libpq: ccache -> credential cachePeter Eisentraut2019-09-06
| | | | | The term "ccache" is overloaded. Let's be more clear, in case someone other than a Kerberos wizard has to read this code.
* Fix failures to ignore \r when reading Windows-style newlines.Tom Lane2019-07-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | libpq failed to ignore Windows-style newlines in connection service files. This normally wasn't a problem on Windows itself, because fgets() would convert \r\n to just \n. But if libpq were running inside a program that changes the default fopen mode to binary, it would see the \r's and think they were data. In any case, it's project policy to ignore \r in text files unconditionally, because people sometimes try to use files with DOS-style newlines on Unix machines, where the C library won't hide that from us. Hence, adjust parseServiceFile() to ignore \r as well as \n at the end of the line. In HEAD, go a little further and make it ignore all trailing whitespace, to match what it's always done with leading whitespace. In HEAD, also run around and fix up everyplace where we have newline-chomping code to make all those places look consistent and uniformly drop \r. It is not clear whether any of those changes are fixing live bugs. Most of the non-cosmetic changes are in places that are reading popen output, and the jury is still out as to whether popen on Windows can return \r\n. (The Windows-specific code in pipe_read_line seems to think so, but our lack of support for this elsewhere suggests maybe it's not a problem in practice.) Hence, I desisted from applying those changes to back branches, except in run_ssl_passphrase_command() which is new enough and little-tested enough that we'd probably not have heard about any problems there. Tom Lane and Michael Paquier, per bug #15827 from Jorge Gustavo Rocha. Back-patch the parseServiceFile() change to all supported branches, and the run_ssl_passphrase_command() change to v11 where that was added. Discussion: https://postgr.es/m/15827-e6ba53a3a7ed543c@postgresql.org
* Tweak libpq's PQhost, PQhostaddr, and psql's \connectAlvaro Herrera2019-06-14
| | | | | | | | | | | | | | | | | | | | | | | | Fixes some problems introduced by 6e5f8d489acc: * When reusing conninfo data from the previous connection in \connect, the host address should only be reused if it was specified as hostaddr; if it wasn't, then 'host' is resolved afresh. We were reusing the same IP address, which ignores a possible DNS change as well as any other addresses that the name resolves to than the one that was used in the original connection. * PQhost, PQhostaddr: Don't present user-specified hostaddr when we have an inet_net_ntop-produced equivalent address. The latter has been put in canonical format, which is cleaner (so it produces "127.0.0.1" when given "host=2130706433", for example). * Document the hostaddr-reusing aspect of \connect. * Fix some code comments Author: Fabien Coelho Reported-by: Noah Misch Discussion: https://postgr.es/m/20190527203713.GA58392@gust.leadboat.com
* Phase 2 pgindent run for v12.Tom Lane2019-05-22
| | | | | | | | | Switch to 2.1 version of pg_bsd_indent. This formats multiline function declarations "correctly", that is with additional lines of parameter declarations indented to match where the first line's left parenthesis is. Discussion: https://postgr.es/m/CAEepm=0P3FeTXRcU5B2W3jv3PgRVZ-kGUXLGfd42FFhUROO3ug@mail.gmail.com
* Initial pgindent run for v12.Tom Lane2019-05-22
| | | | | | | | This is still using the 2.0 version of pg_bsd_indent. I thought it would be good to commit this separately, so as to document the differences between 2.0 and 2.1 behavior. Discussion: https://postgr.es/m/16296.1558103386@sss.pgh.pa.us
* GSSAPI: Improve documentation and testsStephen Frost2019-04-19
| | | | | | | | | | | | | | | | | | | | | | | | | | The GSSAPI encryption patch neglected to update the protocol documentation to describe how to set up a GSSAPI encrypted connection from a client to the server, so fix that by adding the appropriate documentation to protocol.sgml. The tests added for encryption support were overly long and couldn't be run in parallel due to race conditions; this was largely because each test was setting up its own KDC to perform the tests. Instead, merge the authentication tests and the encryption tests into the original test, where we only create one KDC to run the tests with. Also, have the tests check what the server's opinion is of the connection and if it was GSS authenticated or encrypted using the pg_stat_gssapi view. In passing, fix the libpq label for GSSENC-Mode to be consistent with the "PGGSSENCMODE" environment variable. Missing protocol documentation pointed out by Michael Paquier. Issues with the tests pointed out by Tom Lane and Peter Eisentraut. Refactored tests and added documentation by me. Reviewed by Robbie Harwood (protocol documentation) and Michael Paquier (rework of the tests).
* Add support TCP user timeout in libpq and the backend serverMichael Paquier2019-04-06
| | | | | | | | | | | | | | | | | Similarly to the set of parameters for keepalive, a connection parameter for libpq is added as well as a backend GUC, called tcp_user_timeout. Increasing the TCP user timeout is useful to allow a connection to survive extended periods without end-to-end connection, and decreasing it allows application to fail faster. By default, the parameter is 0, which makes the connection use the system default, and follows a logic close to the keepalive parameters in its handling. When connecting through a Unix-socket domain, the parameters have no effect. Author: Ryohei Nagaura Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
* Handle errors during GSSAPI startup betterStephen Frost2019-04-04
| | | | | | | | | | | | | | | | | | | | | There was some confusion over the format of the error message returned from the server during GSSAPI startup; specifically, it was expected that a length would be returned when, in reality, at this early stage in the startup sequence, no length is returned from the server as part of an error message. Correct the client-side code for dealing with error messages sent by the server during startup by simply reading what's available into our buffer, after we've discovered it's an error message, and then reporting back what was returned. In passing, also add in documentation of the environment variable PGGSSENCMODE which was missed previously, and adjust the code to look for the PGGSSENCMODE variable (the environment variable change was missed in the prior GSSMODE -> GSSENCMODE commit). Error-handling issue discovered by Peter Eisentraut, the rest were items discovered during testing of the error handling.
* GSSAPI encryption supportStephen Frost2019-04-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On both the frontend and backend, prepare for GSSAPI encryption support by moving common code for error handling into a separate file. Fix a TODO for handling multiple status messages in the process. Eliminate the OIDs, which have not been needed for some time. Add frontend and backend encryption support functions. Keep the context initiation for authentication-only separate on both the frontend and backend in order to avoid concerns about changing the requested flags to include encryption support. In postmaster, pull GSSAPI authorization checking into a shared function. Also share the initiator name between the encryption and non-encryption codepaths. For HBA, add "hostgssenc" and "hostnogssenc" entries that behave similarly to their SSL counterparts. "hostgssenc" requires either "gss", "trust", or "reject" for its authentication. Similarly, add a "gssencmode" parameter to libpq. Supported values are "disable", "require", and "prefer". Notably, negotiation will only be attempted if credentials can be acquired. Move credential acquisition into its own function to support this behavior. Add a simple pg_stat_gssapi view similar to pg_stat_ssl, for monitoring if GSSAPI authentication was used, what principal was used, and if encryption is being used on the connection. Finally, add documentation for everything new, and update existing documentation on connection security. Thanks to Michael Paquier for the Windows fixes. Author: Robbie Harwood, with changes to the read/write functions by me. Reviewed in various forms and at different times by: Michael Paquier, Andres Freund, David Steele. Discussion: https://www.postgresql.org/message-id/flat/jlg1tgq1ktm.fsf@thriss.redhat.com
* Restructure libpq's handling of send failures.Tom Lane2019-03-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Originally, if libpq got a failure (e.g., ECONNRESET) while trying to send data to the server, it would just report that and wash its hands of the matter. It was soon found that that wasn't a very pleasant way of coping with server-initiated disconnections, so we introduced a hack (pqHandleSendFailure) in the code that sends queries to make it peek ahead for server error reports before reporting the send failure. It now emerges that related cases can occur during connection setup; in particular, as of TLS 1.3 it's unsafe to assume that SSL connection failures will be reported by SSL_connect rather than during our first send attempt. We could have fixed that in a hacky way by applying pqHandleSendFailure after a startup packet send failure, but (a) pqHandleSendFailure explicitly disclaims suitability for use in any state except query startup, and (b) the problem still potentially exists for other send attempts in libpq. Instead, let's fix this in a more general fashion by eliminating pqHandleSendFailure altogether, and instead arranging to postpone all reports of send failures in libpq until after we've made an attempt to read and process server messages. The send failure won't be reported at all if we find a server message or detect input EOF. (Note: this removes one of the reasons why libpq typically overwrites, rather than appending to, conn->errorMessage: pqHandleSendFailure needed that behavior so that the send failure report would be replaced if we got a server message or read failure report. Eventually I'd like to get rid of that overwrite behavior altogether, but today is not that day. For the moment, pqSendSome is assuming that its callees will overwrite not append to conn->errorMessage.) Possibly this change should get back-patched someday; but it needs testing first, so let's not consider that till after v12 beta. Discussion: https://postgr.es/m/CAEepm=2n6Nv+5tFfe8YnkUm1fXgvxR0Mm1FoD+QKG-vLNGLyKg@mail.gmail.com
* Remove duplicate variable declaration in fe-connect.cMichael Paquier2019-02-22
| | | | | | | | The same variables are declared twice when checking if a connection is writable, which is useless. Author: Haribabu Kommi Discussion: https://postgr.es/m/CAJrrPGf=rcALB54w_Tg1_hx3y+cgSWaERY-uYSQzGc3Zt5XN4g@mail.gmail.com
* Update copyright for 2019Bruce Momjian2019-01-02
| | | | Backpatch-through: certain files through 9.4
* psql: Show IP address in \conninfoAlvaro Herrera2018-11-19
| | | | | | | | | | | | | | | When hostaddr is given, the actual IP address that psql is connected to can be totally unexpected for the given host. The more verbose output we now generate makes things clearer. Since the "host" and "hostaddr" parts of the conninfo could come from different sources (say, one of them is in the service specification or a URI-style conninfo and the other is not), this is not as silly as it may first appear. This is also definitely useful if the hostname resolves to multiple addresses. Author: Fabien Coelho Reviewed-by: Pavel Stehule, Arthur Zakirov Discussion: https://postgr.es/m/alpine.DEB.2.21.1810261532380.27686@lancre https://postgr.es/m/alpine.DEB.2.21.1808201323020.13832@lancre
* Incorporate strerror_r() into src/port/snprintf.c, too.Tom Lane2018-09-26
| | | | | | | | | | | | This provides the features that used to exist in useful_strerror() for users of strerror_r(), too. Also, standardize on the GNU convention that strerror_r returns a char pointer that may not be NULL. I notice that libpq's win32.c contains a variant version of strerror_r that probably ought to be folded into strerror.c. But lacking a Windows environment, I should leave that to somebody else. Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
* Parse more strictly integer parameters from connection strings in libpqMichael Paquier2018-09-12
| | | | | | | | | | | | | | | | | | | | The following parameters have been parsed in lossy ways when specified in a connection string processed by libpq: - connect_timeout - keepalives - keepalives_count - keepalives_idle - keepalives_interval - port Overflowing values or the presence of incorrect characters were not properly checked, leading to libpq trying to use such values and fail with unhelpful error messages. This commit hardens the parsing of those parameters so as it is possible to find easily incorrect values. Author: Fabien Coelho Reviewed-by: Peter Eisentraut, Michael Paquier Discussion: https://postgr.es/m/alpine.DEB.2.21.1808171206180.20841@lancre
* Install a check for mis-linking of src/port and src/common functions.Tom Lane2018-09-09
| | | | | | | | | | | | | | | | | | | | | | | | | On ELF-based platforms (and maybe others?) it's possible for a shared library, when dynamically loaded into the backend, to call the backend versions of src/port and src/common functions rather than the frontend versions that are actually linked into the shlib. This is definitely not what we want, because the frontend versions often behave slightly differently. Up to now it's been "slight" enough that nobody noticed; but with the addition of SCRAM support functions in src/common, we're observing crashes due to the difference between palloc and malloc memory allocation rules, as reported in bug #15367 from Jeremy Evans. The purpose of this patch is to create a direct test for this type of mis-linking, so that we know whether any given platform requires extra measures to prevent using the wrong functions. If the test fails, it will lead to connection failures in the contrib/postgres_fdw regression test. At the moment, *BSD platforms using ELF format are known to have the problem and can be expected to fail; but we need to know whether anything else does, and we need a reliable ongoing check for future platforms. Actually fixing the problem will be the subject of later commit(s). Discussion: https://postgr.es/m/153626613985.23143.4743626885618266803@wrigleys.postgresql.org
* libpq: Change "options" dispchar to normalPeter Eisentraut2018-09-07
| | | | | | | | | | | | | | | | | | libpq connection options as returned by PQconndefaults() have a "dispchar" field that determines (among other things) whether an option is a "debug" option, which shouldn't be shown by default to clients. postgres_fdw makes use of that to control which connection options to accept from a foreign server configuration. Curiously, the "options" option, which allows passing configuration settings to the backend server, was listed as a debug option, which prevented it from being used by postgres_fdw. Maybe it was once meant for debugging, but it's clearly in general use nowadays. So change the dispchar for it to be the normal non-debug case. Also remove the "debug" reference from its label field. Reported-by: Shinoda, Noriyoshi <noriyoshi.shinoda@hpe.com>
* In libpq, don't look up all the hostnames at once.Tom Lane2018-08-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Historically, we looked up the target hostname in connectDBStart, so that PQconnectPoll did not need to do DNS name resolution. The patches that added multiple-target-host support to libpq preserved this division of labor; but it's really nonsensical now, because it means that if any one of the target hosts fails to resolve in DNS, the connection fails. That negates the no-single-point-of-failure goal of the feature. Additionally, DNS lookups aren't exactly cheap, but the code did them all even if the first connection attempt succeeds. Hence, rearrange so that PQconnectPoll does the lookups, and only looks up a hostname when it's time to try that host. This does mean that PQconnectPoll could block on a DNS lookup --- but if you wanted to avoid that, you should be using hostaddr, as the documentation has always specified. It seems fairly unlikely that any applications would really care whether the lookup occurs inside PQconnectStart or PQconnectPoll. In addition to calling out that fact explicitly, do some other minor wordsmithing in the docs around the multiple-target-host feature. Since this seems like a bug in the multiple-target-host feature, backpatch to v10 where that was introduced. In the back branches, avoid moving any existing fields of struct pg_conn, just in case any third-party code is looking into that struct. Tom Lane, reviewed by Fabien Coelho Discussion: https://postgr.es/m/4913.1533827102@sss.pgh.pa.us
* Fix libpq's implementation of per-host connection timeouts.Tom Lane2018-08-13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 5f374fe7a attempted to turn the connect_timeout from an overall maximum time limit into a per-host limit, but it didn't do a great job of that. The timer would only get restarted if we actually detected timeout within connectDBComplete(), not if we changed our attention to a new host for some other reason. In that case the old timeout continued to run, possibly causing a premature timeout failure for the new host. Fix that, and also tweak the logic so that if we do get a timeout, we advance to the next available IP address, not to the next host name. There doesn't seem to be a good reason to assume that all the IP addresses supplied for a given host name will necessarily fail the same way as the current one. Moreover, this conforms better to the admittedly-vague documentation statement that the timeout is "per connection attempt". I changed that to "per host name or IP address" to be clearer. (Note that reconnections to the same server, such as for switching protocol version or SSL status, don't get their own separate timeout; that was true before and remains so.) Also clarify documentation about the interpretation of connect_timeout values less than 2. This seems like a bug, so back-patch to v10 where this logic came in. Tom Lane, reviewed by Fabien Coelho Discussion: https://postgr.es/m/5735.1533828184@sss.pgh.pa.us
* Fix failure to reset libpq's state fully between connection attempts.Tom Lane2018-08-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The logic in PQconnectPoll() did not take care to ensure that all of a PGconn's internal state variables were reset before trying a new connection attempt. If we got far enough in the connection sequence to have changed any of these variables, and then decided to try a new server address or server name, the new connection might be completed with some state that really only applied to the failed connection. While this has assorted bad consequences, the only one that is clearly a security issue is that password_needed didn't get reset, so that if the first server asked for a password and the second didn't, PQconnectionUsedPassword() would return an incorrect result. This could be leveraged by unprivileged users of dblink or postgres_fdw to allow them to use server-side login credentials that they should not be able to use. Other notable problems include the possibility of forcing a v2-protocol connection to a server capable of supporting v3, or overriding "sslmode=prefer" to cause a non-encrypted connection to a server that would have accepted an encrypted one. Those are certainly bugs but it's harder to paint them as security problems in themselves. However, forcing a v2-protocol connection could result in libpq having a wrong idea of the server's standard_conforming_strings setting, which opens the door to SQL-injection attacks. The extent to which that's actually a problem, given the prerequisite that the attacker needs control of the client's connection parameters, is unclear. These problems have existed for a long time, but became more easily exploitable in v10, both because it introduced easy ways to force libpq to abandon a connection attempt at a late stage and then try another one (rather than just giving up), and because it provided an easy way to specify multiple target hosts. Fix by rearranging PQconnectPoll's state machine to provide centralized places to reset state properly when moving to a new target host or when dropping and retrying a connection to the same host. Tom Lane, reviewed by Noah Misch. Our thanks to Andrew Krasichkov for finding and reporting the problem. Security: CVE-2018-10915
* Remove support for tls-unique channel binding.Heikki Linnakangas2018-08-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are some problems with the tls-unique channel binding type. It's not supported by all SSL libraries, and strictly speaking it's not defined for TLS 1.3 at all, even though at least in OpenSSL, the functions used for it still seem to work with TLS 1.3 connections. And since we had no mechanism to negotiate what channel binding type to use, there would be awkward interoperability issues if a server only supported some channel binding types. tls-server-end-point seems feasible to support with any SSL library, so let's just stick to that. This removes the scram_channel_binding libpq option altogether, since there is now only one supported channel binding type. This also removes all the channel binding tests from the SSL test suite. They were really just testing the scram_channel_binding option, which is now gone. Channel binding is used if both client and server support it, so it is used in the existing tests. It would be good to have some tests specifically for channel binding, to make sure it really is used, and the different combinations of a client and a server that support or doesn't support it. The current set of settings we have make it hard to write such tests, but I did test those things manually, by disabling HAVE_BE_TLS_GET_CERTIFICATE_HASH and/or HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH. I also removed the SCRAM_CHANNEL_BINDING_TLS_END_POINT constant. This is a matter of taste, but IMO it's more readable to just use the "tls-server-end-point" string. Refactor the checks on whether the SSL library supports the functions needed for tls-server-end-point channel binding. Now the server won't advertise, and the client won't choose, the SCRAM-SHA-256-PLUS variant, if compiled with an OpenSSL version too old to support it. In the passing, add some sanity checks to check that the chosen SASL mechanism, SCRAM-SHA-256 or SCRAM-SHA-256-PLUS, matches whether the SCRAM exchange used channel binding or not. For example, if the client selects the non-channel-binding variant SCRAM-SHA-256, but in the SCRAM message uses channel binding anyway. It's harmless from a security point of view, I believe, and I'm not sure if there are some other conditions that would cause the connection to fail, but it seems better to be strict about these things and check explicitly. Discussion: https://www.postgresql.org/message-id/ec787074-2305-c6f4-86aa-6902f98485a4%40iki.fi
* Fix libpq's code for searching .pgpass; rationalize empty-list-item cases.Tom Lane2018-08-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before v10, we always searched ~/.pgpass using the host parameter, and nothing else, to match to the "hostname" field of ~/.pgpass. (However, null host or host matching DEFAULT_PGSOCKET_DIR was replaced by "localhost".) In v10, this got broken by commit 274bb2b38, repaired by commit bdac9836d, and broken again by commit 7b02ba62e; in the code actually shipped, we'd search with hostaddr if both that and host were specified --- though oddly, *not* if only hostaddr were specified. Since this is directly contrary to the documentation, and not backwards-compatible, it's clearly a bug. However, the change wasn't totally without justification, even though it wasn't done quite right, because the pre-v10 behavior has arguably been buggy since we added hostaddr. If hostaddr is specified and host isn't, the pre-v10 code will search ~/.pgpass for "localhost", and ship that password off to a server that most likely isn't local at all. That's unhelpful at best, and could be a security breach at worst. Therefore, rather than just revert to that old behavior, let's define the behavior as "search with host if provided, else with hostaddr if provided, else search for localhost". (As before, a host name matching DEFAULT_PGSOCKET_DIR is replaced by localhost.) This matches the behavior of the actual connection code, so that we don't pick up an inappropriate password; and it allows useful searches to happen when only hostaddr is given. While we're messing around here, ensure that empty elements within a host or hostaddr list select the same behavior as a totally-empty field would; for instance "host=a,,b" is equivalent to "host=a,/tmp,b" if DEFAULT_PGSOCKET_DIR is /tmp. Things worked that way in some cases already, but not consistently so, which contributed to the confusion about what key ~/.pgpass would get searched with. Update documentation accordingly, and also clarify some nearby text. Back-patch to v10 where the host/hostaddr list functionality was introduced. Discussion: https://postgr.es/m/30805.1532749137@sss.pgh.pa.us
* Fix error message when a hostaddr cannot be parsed.Heikki Linnakangas2018-07-19
| | | | | | | | | | | | | | We were incorrectly passing hostname, not hostaddr, in the error message, and because of that, you got: $ psql 'hostaddr=foo' psql: could not parse network address "(null)": Name or service not known Backpatch to v10, where this was broken (by commit 7b02ba62e9). Report and fix by Robert Haas. Discussion: https://www.postgresql.org/message-id/CA+TgmoapFQA30NomGKEaZCu3iN7mF7fux8fbbk9SouVOT2JP7w@mail.gmail.com
* Post-feature-freeze pgindent run.Tom Lane2018-04-26
| | | | Discussion: https://postgr.es/m/15719.1523984266@sss.pgh.pa.us
* libpq: PQhost to return active connected host or hostaddrPeter Eisentraut2018-03-27
| | | | | | | | | | | | | | | | | | | | | | Previously, PQhost didn't return the connected host details when the connection type was CHT_HOST_ADDRESS (i.e., via hostaddr). Instead, it returned the complete host connection parameter (which could contain multiple hosts) or the default host details, which was confusing and arguably incorrect. Change this to return the actually connected host or hostaddr irrespective of the connection type. When hostaddr but no host was specified, hostaddr is now returned. Never return the original host connection parameter, and document that PQhost cannot be relied on before the connection is established. PQport is similarly changed to always return the active connection port and never the original connection parameter. Author: Hari Babu <kommi.haribabu@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> Reviewed-by: David G. Johnston <david.g.johnston@gmail.com>
* Set libpq sslcompression to off by defaultPeter Eisentraut2018-03-17
| | | | | | | | | | | | | | Since SSL compression is no longer recommended, turn the default in libpq from on to off. OpenSSL 1.1.0 and many distribution packages already turn compression off by default, so such a server won't accept compression anyway. So this will mainly affect users of older OpenSSL installations. Also update the documentation to make clear that this setting is no longer recommended. Discussion: https://www.postgresql.org/message-id/flat/595cf3b1-4ffe-7f05-6f72-f72b7afa7993%402ndquadrant.com
* Fix wording of "hostaddrs"Magnus Hagander2018-01-21
| | | | | | | The field is still called "hostaddr", so make sure references use "hostaddr values" instead. Author: Michael Paquier <michael.paquier@gmail.com>
* Update copyright for 2018Bruce Momjian2018-01-02
| | | | Backpatch-through: certain files through 9.3
* Add libpq connection parameter "scram_channel_binding"Peter Eisentraut2017-12-19
| | | | | | | | | | | | | | | | | This parameter can be used to enforce the channel binding type used during a SCRAM authentication. This can be useful to check code paths where an invalid channel binding type is used by a client and will be even more useful to allow testing other channel binding types when they are added. The default value is tls-unique, which is what RFC 5802 specifies. Clients can optionally specify an empty value, which has as effect to not use channel binding and use SCRAM-SHA-256 as chosen SASL mechanism. More tests for SCRAM and channel binding are added to the SSL test suite. Author: Author: Michael Paquier <michael.paquier@gmail.com>
* Add some const decorations to prototypesPeter Eisentraut2017-11-10
| | | | Reviewed-by: Fabien COELHO <coelho@cri.ensmp.fr>
* Change TRUE/FALSE to true/falsePeter Eisentraut2017-11-08
| | | | | | | | | | | | | | The lower case spellings are C and C++ standard and are used in most parts of the PostgreSQL sources. The upper case spellings are only used in some files/modules. So standardize on the standard spellings. The APIs for ICU, Perl, and Windows define their own TRUE and FALSE, so those are left as is when using those APIs. In code comments, we use the lower-case spelling for the C concepts and keep the upper-case spelling for the SQL concepts. Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
* Fix libpq to not require user's home directory to exist.Tom Lane2017-10-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Some people like to run libpq-using applications in environments where there's no home directory. We've broken that scenario before (cf commits 5b4067798 and bd58d9d88), and commit ba005f193 broke it again, by making it a hard error if we fail to get the home directory name while looking for ~/.pgpass. The previous precedent is that if we can't get the home directory name, we should just silently act as though the file we hoped to find there doesn't exist. Rearrange the new code to honor that. Looking around, the service-file code added by commit 41a4e4595 had the same disease. Apparently, that escaped notice because it only runs when a service name has been specified, which I guess the people who use this scenario don't do. Nonetheless, it's wrong too, so fix that case as well. Add a comment about this policy to pqGetHomeDirectory, in the probably vain hope of forestalling the same error in future. And upgrade the rather miserable commenting in parseServiceInfo, too. In passing, also back off parseServiceInfo's assumption that only ENOENT is an ignorable error from stat() when checking a service file. We would need to ignore at least ENOTDIR as well (cf 5b4067798), and seeing that the far-better-tested code for ~/.pgpass treats all stat() failures alike, I think this code ought to as well. Per bug #14872 from Dan Watson. Back-patch the .pgpass change to v10 where ba005f193 came in. The service-file bugs are far older, so back-patch the other changes to all supported branches. Discussion: https://postgr.es/m/20171025200457.1471.34504@wrigleys.postgresql.org
* Replace most usages of ntoh[ls] and hton[sl] with pg_bswap.h.Andres Freund2017-10-01
| | | | | | | | | | | | | | | | | All postgres internal usages are replaced, it's just libpq example usages that haven't been converted. External users of libpq can't generally rely on including postgres internal headers. Note that this includes replacing open-coded byte swapping of 64bit integers (using two 32 bit swaps) with a single 64bit swap. Where it looked applicable, I have removed netinet/in.h and arpa/inet.h usage, which previously provided the relevant functionality. It's perfectly possible that I missed other reasons for including those, the buildfarm will tell. Author: Andres Freund Discussion: https://postgr.es/m/20170927172019.gheidqy6xvlxb325@alap3.anarazel.de
* Reduce excessive dereferencing of function pointersPeter Eisentraut2017-09-07
| | | | | | | | | | | | It is equivalent in ANSI C to write (*funcptr) () and funcptr(). These two styles have been applied inconsistently. After discussion, we'll use the more verbose style for plain function pointer variables, to make it clear that it's a variable, and the shorter style when the function pointer is in a struct (s.func() or s->func()), because then it's clear that it's not a plain function name, and otherwise the excessive punctuation makes some of those invocations hard to read. Discussion: https://www.postgresql.org/message-id/f52c16db-14ed-757d-4b48-7ef360b1631d@2ndquadrant.com
* Fix up some misusage of appendStringInfo() and friendsPeter Eisentraut2017-08-15
| | | | | | | | Change to appendStringInfoChar() or appendStringInfoString() where those can be used. Author: David Rowley <david.rowley@2ndquadrant.com> Reviewed-by: Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>
* Fix check for empty hostname.Heikki Linnakangas2017-07-10
| | | | | | | As reported by Arthur Zakirov, Gcc 7.1 complained about this with -Wpointer-compare. Discussion: https://www.postgresql.org/message-id/CAKNkYnybV_NFVacGbW=VspzAo3TwRJFNi+9iBob66YqQMZopwg@mail.gmail.com
* Allow multiple hostaddrs to go with multiple hostnames.Heikki Linnakangas2017-07-10
| | | | | | | | | | | | | | | Also fix two other issues, while we're at it: * In error message on connection failure, if multiple network addresses were given as the host option, as in "host=127.0.0.1,127.0.0.2", the error message printed the address twice. * If there were many more ports than hostnames, the error message would always claim that there was one port too many, even if there was more than one. For example, if you gave 2 hostnames and 5 ports, the error message claimed that you gave 2 hostnames and 3 ports. Discussion: https://www.postgresql.org/message-id/10badbc6-4d5a-a769-623a-f7ada43e14dd@iki.fi
* Second try at fixing tcp_keepalives_idle option on Solaris.Tom Lane2017-06-28
| | | | | | | | | | | | | | | | | | | | | | | Buildfarm evidence shows that TCP_KEEPALIVE_THRESHOLD doesn't exist after all on Solaris < 11. This means we need to take positive action to prevent the TCP_KEEPALIVE code path from being taken on that platform. I've chosen to limit it with "&& defined(__darwin__)", since it's unclear that anyone else would follow Apple's precedent of spelling the symbol that way. Also, follow a suggestion from Michael Paquier of eliminating code duplication by defining a couple of intermediate symbols for the socket option. In passing, make some effort to reduce the number of translatable messages by replacing "setsockopt(foo) failed" with "setsockopt(%s) failed", etc, throughout the affected files. And update relevant documentation so that it doesn't claim to provide an exhaustive list of the possible socket option names. Like the previous commit (f0256c774), back-patch to all supported branches. Discussion: https://postgr.es/m/20170627163757.25161.528@wrigleys.postgresql.org
* Support tcp_keepalives_idle option on Solaris.Tom Lane2017-06-27
| | | | | | | | | | | | | | | | Turns out that the socket option for this is named TCP_KEEPALIVE_THRESHOLD, at least according to the tcp(7P) man page for Solaris 11. (But since that text refers to "SunOS", it's likely pretty ancient.) It appears that the symbol TCP_KEEPALIVE does get defined on that platform, but it doesn't seem to represent a valid protocol-level socket option. This leads to bleats in the postmaster log, and no tcp_keepalives_idle functionality. Per bug #14720 from Andrey Lizenko, as well as an earlier report from Dhiraj Chawla that nobody had followed up on. The issue's been there since we added the TCP_KEEPALIVE code path in commit 5acd417c8, so back-patch to all supported branches. Discussion: https://postgr.es/m/20170627163757.25161.528@wrigleys.postgresql.org
* Phase 3 of pgindent updates.Tom Lane2017-06-21
| | | | | | | | | | | | | | | | | | | | | | | | | Don't move parenthesized lines to the left, even if that means they flow past the right margin. By default, BSD indent lines up statement continuation lines that are within parentheses so that they start just to the right of the preceding left parenthesis. However, traditionally, if that resulted in the continuation line extending to the right of the desired right margin, then indent would push it left just far enough to not overrun the margin, if it could do so without making the continuation line start to the left of the current statement indent. That makes for a weird mix of indentations unless one has been completely rigid about never violating the 80-column limit. This behavior has been pretty universally panned by Postgres developers. Hence, disable it with indent's new -lpl switch, so that parenthesized lines are always lined up with the preceding left paren. This patch is much less interesting than the first round of indent changes, but also bulkier, so I thought it best to separate the effects. Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us