On Sat, Dec 17, 2011 at 3:27 AM, Ross Reedstrom <reedstrm@rice.edu> wrote:
> On Fri, Dec 16, 2011 at 02:55:09PM +0000, Richard Huxton wrote:
>> According to the docs [1], you should escape embedded colons in
>> .pgpass (fair enough). Below is PG 9.1.1
>>
>> user = "te:st", db = "te:st", password = "te:st"
>>
>> $ cat ~/.pgpass
>> *:*:te:st:te:st:te:st
>> $ psql91 -U "te:st" -d "te:st"
>> te:st=>
>>
>> $ cat ~/.pgpass
>> *:*:te\:st:te\:st:te:st
>> $ psql91 -U "te:st" -d "te:st"
>> te:st=>
>>
>> $ cat ~/.pgpass
>> *:*:te\:st:te\:st:te\:st
>> $ psql91 -U "te:st" -d "te:st"
>> psql: FATAL: password authentication failed for user "te:st"
>> password retrieved from file "/home/richardh/.pgpass"
>>
>> I'm a bit puzzled how it manages without the escaping in the first
>> case. There's a lack of consistency though that either needs
>> documenting or fixing.
>
> Hmm, seems the code in fe-connect.c that reads the password out of .pgpass does this:
>
> if ((t = pwdfMatchesString(t, hostname)) == NULL ||
> (t = pwdfMatchesString(t, port)) == NULL ||
> (t = pwdfMatchesString(t, dbname)) == NULL ||
> (t = pwdfMatchesString(t, username)) == NULL)
> [...]
>
> pwdfMatchesString 'eats' the stringbuffer until the next unmatched character or
> unescaped colon. If it falls out the bottom of that, the rest of the line is
> returned as the candidate password.
>
> Since the code that does the backslash detection is in pwdfMatchesString(), and
> the password never goes through that function, the escapes are not cleaned up.
>
> This should either be fixed by changing the documentation to say to not escape
> colons or backslashes in the password part, only, or modify this function
> (PasswordFromFile) to silently unescape the password string. It already copies
> it.
My vote is for a doc correction in the back-branches and a behavior
change in master.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company