From: KaiGai Kohei on
(2010/06/11 21:11), Stephen Frost wrote:
> * Magnus Hagander (magnus(a)hagander.net) wrote:
>> On Fri, Jun 11, 2010 at 14:07, Stephen Frost<sfrost(a)snowman.net> wrote:
>>> I definitely like the idea but I dislike requiring the user to do
>>> something to implement it. Thinking about how packagers might want to
>>> use it, could we make it possible to build it defaulted to a specific
>>> value (eg: 'postgres' on Debian) and allow users a way to override
>>> and/or unset it?
>>
>> Well, even if we don't put that in, the packager could export a global
>> PGREQUIREPEER environment variable.
>
> Yeahhhh, no, that's a crappy solution, sorry. :) I've been down that
> road with people trying to monkey with /etc/bashrc; oh wait, not
> everyone uses bash, and having every package screw with that stuff is
> equally horrible. Admittedly, in this specific case, Debian could
> implement what you're talking about in it's wrapper system, maybe, but I
> still don't like it and if people don't use the wrapper (I can imagine
> cases why that might happen, tho I havn't ever had to myself), they
> wouldn't get the benefit..
>
Are you suggesting the packager enforces a certain unix user on the
installation time, although 'postgres' shall be used in most cases?

Let's back to the purpose of the feature.
In my understanding, it provides the client process the way to verity
user identifier of the server process before sending password.
Indeed, if we provide a default value of the "requirepeer" using
environment variable, the client process can override its own setting.
But is there any problem?

This option allows the client process to specify an expected user
identifier of the server process, then libpq closes the connection
if not matched.
Even if the default shall be given from the system default, the
client can provide an explicit alternative in the connection string.
Is there any fundamental differences to the environment variable?

Thanks,
--
KaiGai Kohei <kaigai(a)ak.jp.nec.com>

--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: Peter Eisentraut on
On fre, 2010-06-11 at 08:07 -0400, Stephen Frost wrote:
> Having the option wouldn't do much unless users know of it and use it
> and it strikes that will very often not be the case.

That situation is the same as with SSL over TCP/IP with certificate
validation. I don't think we can make either of these the default
without risking breaking a lot of things.


--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: KaiGai Kohei on
I've checked on this patch.

As you described at the source code comments as follows,
it is not portable except for Linux due to the getsockopt() API.

+ // TODO: currently Linux-only code, needs to be made
+ // portable; see backend/libpq/auth.c

I expect it shall be fixed (using the code come from ident_unix()?)
before committing.


I'd like to point out one other point.
It uses getpwuid() to translate a user identifier into a user name,
but it returns a pointer of the static variable within glibc.
So, it is not thread-safe. I recommend to use getpwnam_r() instead.

Except for the issue, it looks to me fine.

* The patch can be applied on the head of the git repository.
* We can build the code without any warnings/errors.
* It works as described in the documentation.

[kaigai(a)saba ~]$ php -r 'pg_connect("dbname=postgres requirepeer=xxxx");'
PHP Warning: pg_connect(): Unable to connect to PostgreSQL server: invalid connection option "requirepeer" in Command line code on line 1
=> Existing library, so not supported.

[kaigai(a)saba ~]$ env LD_LIBRARY_PATH=/usr/local/pgsql/lib/ \
php -r 'pg_connect("dbname=postgres requirepeer=xxxx");'
PHP Warning: pg_connect(): Unable to connect to PostgreSQL server: requirepeer failed (actual: kaigai != required: xxxx) in Command line code on line 1
LOG: incomplete startup packet
=> Patched library, so it prevent unexpected user-id of server process

[kaigai(a)saba ~]$ env LD_LIBRARY_PATH=/usr/local/pgsql/lib/ \
php -r 'pg_connect("dbname=postgres requirepeer=kaigai");'
=> Patched library, so it does not prevent anything for the expected user-id.

[kaigai(a)saba ~]$ env LD_LIBRARY_PATH=/usr/local/pgsql/lib/ \
php -r 'pg_connect("dbname=postgres");'
=> No "requirepeer", so it does not prevent anything.

[kaigai(a)saba ~]$ env LD_LIBRARY_PATH=/usr/local/pgsql/lib/ \
env PGREQUIREPEER=xyz php -r 'pg_connect("dbname=postgres");'
PHP Warning: pg_connect(): Unable to connect to PostgreSQL server: requirepeer failed (actual: kaigai != required: xyz) in Command line code on line 1
LOG: incomplete startup packet
=> PGREQUIREPEER environment variable, instead of "requirepeer" option. Same result.

[kaigai(a)saba ~]$ env LD_LIBRARY_PATH=/usr/local/pgsql/lib/ \
env PGREQUIREPEER=kaigai php -r 'pg_connect("dbname=postgres");'
=> PGREQUIREPEER environment variable, instead of "requirepeer" option. Same result.

Thanks,

(2010/05/30 20:00), Peter Eisentraut wrote:
> It has been discussed several times in the past that there is no way for
> a client to authenticate a server over Unix-domain sockets. So
> depending on circumstances, a local user could easily insert his own
> server and collect passwords and data. Suggestions for possible
> remedies included:
>
> You can put the socket file in a sufficiently write-protected directory.
> But that would strongly deviate from the default setup, and anyway the
> client still cannot readily verify that the server is the right one.
>
> You can also run SSL over Unix-domain sockets. This is currently
> disabled in the code, but it would work just fine. But it's obviously
> kind of awkward, and the connection overhead was noticeable in tests.
>
> Then it was suggested to use the local "ident" mechanism in reverse, so
> the client could verify what user the server runs under. I have
> implemented a prototype of this. You can put, e.g.,
>
> requirepeer=postgres
>
> into the connection parameters, and the connection will be rejected
> unless the process at the other end of the socket is running as
> postgres.
>
> The patch needs some portability work and possible refactoring because
> of that, but before I embark on that, comments on the concept?
>
>
>
>
>


--
KaiGai Kohei <kaigai(a)ak.jp.nec.com>

--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

From: Peter Eisentraut on
On tis, 2010-06-22 at 09:37 +0900, KaiGai Kohei wrote:
> As you described at the source code comments as follows,
> it is not portable except for Linux due to the getsockopt() API.
>
> + // TODO: currently Linux-only code, needs to be made
> + // portable; see backend/libpq/auth.c
>
> I expect it shall be fixed (using the code come from ident_unix()?)
> before committing.

Updated patch attached.

Note that the code that gets the user ID from the other end of a socket
appears to have two different modes of operation. On some platforms
(Linux, OpenBSD, Solaris), you call a function and get the answer. On
some other platforms (other BSDs?), you need to send a packet and read
the answer. I don't have any possibility to test the latter approach,
and it seemed a bit complicated to code "blindly". So I have omitted
support for that, but if someone else wants to do the porting, that is
of course possible.

> I'd like to point out one other point.
> It uses getpwuid() to translate a user identifier into a user name,
> but it returns a pointer of the static variable within glibc.
> So, it is not thread-safe. I recommend to use getpwnam_r() instead.

Good catch. pqGetpwuid() was actually the right function to use.
From: KaiGai Kohei on
(2010/07/01 11:30), Peter Eisentraut wrote:
> On tis, 2010-06-22 at 09:37 +0900, KaiGai Kohei wrote:
>> As you described at the source code comments as follows,
>> it is not portable except for Linux due to the getsockopt() API.
>>
>> + // TODO: currently Linux-only code, needs to be made
>> + // portable; see backend/libpq/auth.c
>>
>> I expect it shall be fixed (using the code come from ident_unix()?)
>> before committing.
>
> Updated patch attached.
>
> Note that the code that gets the user ID from the other end of a socket
> appears to have two different modes of operation. On some platforms
> (Linux, OpenBSD, Solaris), you call a function and get the answer. On
> some other platforms (other BSDs?), you need to send a packet and read
> the answer. I don't have any possibility to test the latter approach,
> and it seemed a bit complicated to code "blindly". So I have omitted
> support for that, but if someone else wants to do the porting, that is
> of course possible.
>
I checked the revised patch.
The part to obtain user id of the peer is identical with ident_unix()
on the backend, so I believe it will work well, although I don't have
test environment except for Linux.

>> I'd like to point out one other point.
>> It uses getpwuid() to translate a user identifier into a user name,
>> but it returns a pointer of the static variable within glibc.
>> So, it is not thread-safe. I recommend to use getpwnam_r() instead.
>
> Good catch. pqGetpwuid() was actually the right function to use.
>
I have a question.

The pqGetpwuid() is enclosed by #ifndef WIN32 ... #endif, although
this patch encloses the section to obtain user id of the peer by
#ifdef HAVE_UNIX_SOCKETS ... #endif.

Is there any possibilities that both WIN32 and HAVE_UNIX_SOCKETS are
set concurrently? If possible, the libpq may try to call undefined
function, then build will be failed.

I'd like someone to try to build with this patch on win32 platform,
and report it.

Thanks,
--
KaiGai Kohei <kaigai(a)ak.jp.nec.com>

--
Sent via pgsql-hackers mailing list (pgsql-hackers(a)postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers