credentials from Unix-domain datagram socket?

credentials from Unix-domain datagram socket?

Post by Mikael Petterss » Fri, 27 Mar 1998 04:00:00



I'm testing Unix-domain datagram sockets for an implementation
of local RPC, and the following question arose:
Given that a server has received a call (via recvfrom()), how can it
retrieve the Unix credentials of the client?
I'd like at least the effective uid and gid, but the pid and real
uid/gid would be nice too.
My current approach is to use the st_uid/st_gid fields of the
'struct stat' of the client's sun_path[], which I got from recvfrom().
(Since the application is RPC and not message passing, I require the
client to bind() to a valid return address before calling the server.)

Is this the best way to do it?
Unfortunately, this doesn't give me the caller's pid, and I'm not
100% certain of it's accuracy -- i.e., can the client lie?

(I'm using Unix-domain sockets because I also need to be able to pass
open file descriptors around. The only viable alternatives I know of
are less widely available (SVR4 Streams, Solaris Doors, and Linux
SCM_CREDENTIALS control messages).)

/Mikael

(Compiler writer, sometimes systems hacker.)
--
Mikael Pettersson                    |

2004 Route des Lucioles, BP 93       | Phone: (+33) 4 92 38 78 59
06902 Sophia Antipolis Cedex, FRANCE | Fax:   (+33) 4 92 38 79 78

 
 
 

credentials from Unix-domain datagram socket?

Post by Andrew Giert » Fri, 27 Mar 1998 04:00:00


 Mikael> I'm testing Unix-domain datagram sockets for an
 Mikael> implementation of local RPC, and the following question
 Mikael> arose: Given that a server has received a call (via
 Mikael> recvfrom()), how can it retrieve the Unix credentials of the
 Mikael> client?

Unless I'm missing something obvious, you can only really do this on a
very few systems - those that support SCM_CREDS in sendmsg/recvmsg.

 Mikael> My current approach is to use the st_uid/st_gid fields of the
 Mikael> 'struct stat' of the client's sun_path[], which I got from
 Mikael> recvfrom().
 Mikael> Is this the best way to do it?
 Mikael> Unfortunately, this doesn't give me the caller's pid, and I'm
 Mikael> not 100% certain of it's accuracy -- i.e., can the client
 Mikael> lie?

The client can probably lie on systems that allow chown() calls by
mortal users (i.e. client can call bind(), then call chown() to give
the socket away to any uid, including root, then send the message).

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
                           or <URL: http://www.whitefang.com/unix/>

 
 
 

credentials from Unix-domain datagram socket?

Post by Mikael Petterss » Fri, 27 Mar 1998 04:00:00




Quote:>...
>The client can probably lie on systems that allow chown() calls by
>mortal users (i.e. client can call bind(), then call chown() to give
>the socket away to any uid, including root, then send the message).

Bleah. Just did some testing, and found that:
- HP-UX 9 allows users to chown() the socket to any uid/gid!
- OSF1 and Digital Unix 4 both create the socket with your uid
  but gid zero! (You can chown() the gid to your gid, though.)
- AIX, Solaris, Linux, Irix all do the Right Thing.

Guess I'll have to toss portability and resort to different
mechanisms on different systems, which probably means using
sockets on Linux, and Stream pipes elsewhere.
(And not support HP-SUX 9 at all, since it doesn't seem to have
any local IPC mechanism with the required features.)
--
Mikael Pettersson                    |

2004 Route des Lucioles, BP 93       | Phone: (+33) 4 92 38 78 59
06902 Sophia Antipolis Cedex, FRANCE | Fax:   (+33) 4 92 38 79 78

 
 
 

credentials from Unix-domain datagram socket?

Post by Roger Espel Lli » Sun, 29 Mar 1998 04:00:00




>I'm testing Unix-domain datagram sockets for an implementation
>of local RPC, and the following question arose:
>Given that a server has received a call (via recvfrom()), how can it
>retrieve the Unix credentials of the client?
>I'd like at least the effective uid and gid, but the pid and real
>uid/gid would be nice too.
>My current approach is to use the st_uid/st_gid fields of the
>'struct stat' of the client's sun_path[], which I got from recvfrom().
>(Since the application is RPC and not message passing, I require the
>client to bind() to a valid return address before calling the server.)

>Is this the best way to do it?
>Unfortunately, this doesn't give me the caller's pid, and I'm not
>100% certain of it's accuracy -- i.e., can the client lie?

If you're using RPC (as in, Sun's RPC over XDR, rfc1057), you *could*
use authentification over RPC.  It comes in various flavors: AUTH_NULL
(no auth), AUTH_UNIX (which sucks; the client can lie), and AUTH_DES
(which is fairly secure, but requires the clients to have generated keys
for themselves, and may not be available on all systems).

Quote:>(I'm using Unix-domain sockets because I also need to be able to pass
>open file descriptors around. The only viable alternatives I know of
>are less widely available (SVR4 Streams, Solaris Doors, and Linux
>SCM_CREDENTIALS control messages).)

I'd go for SCM_CREDENTIALS/SCM_CRED whenever they're available.  

Otherwise, you could come up with some scheme like:

    . have a special 1777 directory used only for auth
    . have the client create a file there, mode 600
    . pass the file's fd (through the Unix domain socket) to the server
    . fstat(), then unlink.

That loses on systems that let people give away their files, though.

--

http://www.eleves.ens.fr:8080/home/espel/index.html

 
 
 

credentials from Unix-domain datagram socket?

Post by Bill Pa » Tue, 31 Mar 1998 04:00:00


Daring to challenge the will of the almighty Leviam00se, Roger Espel Llima



: >I'm testing Unix-domain datagram sockets for an implementation
: >of local RPC, and the following question arose:
: >Given that a server has received a call (via recvfrom()), how can it
: >retrieve the Unix credentials of the client?
: >I'd like at least the effective uid and gid, but the pid and real
: >uid/gid would be nice too.
: >My current approach is to use the st_uid/st_gid fields of the
: >'struct stat' of the client's sun_path[], which I got from recvfrom().
: >(Since the application is RPC and not message passing, I require the
: >client to bind() to a valid return address before calling the server.)
: >
: >Is this the best way to do it?
: >Unfortunately, this doesn't give me the caller's pid, and I'm not
: >100% certain of it's accuracy -- i.e., can the client lie?

The st_uid/st_gid members of struct stat show you the owner and group
of the file that was opened. Unfortunately, this does not give you
absolute proof of the client process' idendity since it could have
opened a file for reading that was owned by someone else. (I agonized
over something similar to this not too long ago; I was able to find
problems with every suggestion someone gave me. Finally I had to hack
the kernel to get what I wanted.)

: If you're using RPC (as in, Sun's RPC over XDR, rfc1057), you *could*
: use authentification over RPC.  It comes in various flavors: AUTH_NULL
: (no auth), AUTH_UNIX (which sucks; the client can lie), and AUTH_DES
: (which is fairly secure, but requires the clients to have generated keys
: for themselves, and may not be available on all systems).

It also requires DES. :) Plus it too has some problems: in an RPC
message that uses AUTH_DES, you have a small block of data containing
credentials and the verifier, and then you have the actual contents
of the RPC. The problem is that the cred/verifier data is not tied
to the RPC itself in any particular way. There is an expiration window
to attempt to avoid replay (after the window expires, you have to
recompute the verifier) but the window is usually on the order of a
couple of minutes. What this means is that if I can intercept an RPC
with a valid credential/verifier block, I can strip the creds and
verifier from the message, attatch it to one of my own, then send it
out the server. The server will know that the verifier is correct, but
then it just arbitrarily trusts the rest of the message. Ideally the
verifier should contain an encrypted checksum of the RPC, but unfortunately
that's not how it works.

: >(I'm using Unix-domain sockets because I also need to be able to pass
: >open file descriptors around. The only viable alternatives I know of
: >are less widely available (SVR4 Streams, Solaris Doors, and Linux
: >SCM_CREDENTIALS control messages).)

: I'd go for SCM_CREDENTIALS/SCM_CRED whenever they're available.  

FreeBSD also supports SCM_CREDS with its sendmsg()/recvmsg() system
calls, as does BSD/OS (though in a slightly different manner).

I know of the trick with streams/TLI where you can use t_getinfo()
to learn the identify of the process on the other end of a TLI endpoint,
though offhand I don't remember the code to do it.

: Otherwise, you could come up with some scheme like:

:     . have a special 1777 directory used only for auth
:     . have the client create a file there, mode 600
:     . pass the file's fd (through the Unix domain socket) to the server
:     . fstat(), then unlink.

This is similar to some of the suggestions I got when I was looking into
this sort of thing. This is kind a of long way to go, and if you look
at it long enough you'll eventually find a problem with it. At the very
least, this is a terrible kludge and introduces more work (extra syscalls)
that you really shouldn't have to do.

: That loses on systems that let people give away their files, though.

See? I told you you'd find something wrong with it. :)

-Bill

--
=============================================================================
-Bill Paul            (212) 854-6020 | System Manager, Master of Unix-Fu


=============================================================================
  "Now, that's "Open" as used in the sentence "Open your wallet", right?"
=============================================================================

 
 
 

1. Unix Domain socket Peer Credentials?

Hello!

Does anyone know a way for a server that accepts a UNIX Domain stream
connection from a client to know exactly the UID of the client?

I'm not using STREAMS.

On Linux, I can create an unnamed socket and get the peer credentials by
using getsockopt(). Is something similar available on AIX?
        getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crlen);

I am also aware of Stevens, Advanced Programming in the UNIX Environment,
chapter 15.5.2, but this method does not work so good if the server is not
root. Also the method is not "perfect" as the book says.

Which AIX documentation covers passing credentials / access rights?

Any help is appreciated.

--
/Per Schr?der
http://developer.mimer.com

2. Problems with grep

3. Question about user credentials and unix domain sockets

4. Password aging setup?

5. Sender credentials over unix domain sockets in darwin???

6. View screen of another X-terminal

7. UNIX domain datagram sockets

8. Problem with multyplayer and direct connections with a windows network and a linux gateway

9. UNIX Domain Datagram Sockets - Receive Queue Size?

10. UNIX domain Socket Datagram question

11. UNIX Domain Datagram Socket:Receive Queue Size?

12. DATAGRAM sockets in the UNIX DOMAIN.

13. Not enough queuing of datagrams on a unix domain socket