Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unix socket credential passing in Python

How is Unix socket credential passing accomplished in Python?

like image 941
Rakis Avatar asked Nov 02 '11 15:11

Rakis


People also ask

What is socket socket in python?

Sockets and the socket API are used to send messages across a network. They provide a form of inter-process communication (IPC). The network can be a logical, local network to the computer, or one that's physically connected to an external network, with its own connections to other networks.

What does the socket accept () method return?

If the queue has no pending connection requests, accept() blocks the caller unless socket is in nonblocking mode. If no connection requests are queued and socket is in nonblocking mode, accept() returns -1 and sets the error code to EWOULDBLOCK. The new socket descriptor cannot be used to accept new connections.


1 Answers

Internet searches on this topic came up with surprisingly few results. I figured I'd post the question and answer here for others interested in this topic.

The following client and server applications demonstrate how to accomplish this on Linux with the standard python interpreter. No extensions are required but, due to the use of embedded constants, the code is Linux-specific.

Server:

#!/usr/bin/env python

import struct
from socket import socket, AF_UNIX, SOCK_STREAM, SOL_SOCKET

SO_PEERCRED = 17 # Pulled from /usr/include/asm-generic/socket.h

s = socket(AF_UNIX, SOCK_STREAM)

s.bind('/tmp/pass_cred')
s.listen(1)

conn, addr = s.accept()

creds = conn.getsockopt(SOL_SOCKET, SO_PEERCRED, struct.calcsize('3i'))

pid, uid, gid = struct.unpack('3i',creds)

print 'pid: %d, uid: %d, gid %d' % (pid, uid, gid)

Client:

#!/usr/bin/env python

from socket import socket, AF_UNIX, SOCK_STREAM, SOL_SOCKET

SO_PASSCRED = 16 # Pulled from /usr/include/asm-generic/socket.h

s = socket(AF_UNIX, SOCK_STREAM)

s.setsockopt(SOL_SOCKET, SO_PASSCRED, 1)

s.connect('/tmp/pass_cred')

s.close()

Unfortunately, the SO_PEERCRED and SO_PASSCRED constants are not exported by python's socket module so they must be entered by hand. Although these value are unlikely to change it is possible. This should be considered by any applications using this approach.

like image 85
Rakis Avatar answered Oct 24 '22 08:10

Rakis