mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-05 13:29:57 -05:00
add support for authentication using SCM_CREDENTIALS
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@596 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
a1f5573313
commit
3f264b2c4a
12 changed files with 343 additions and 92 deletions
|
|
@ -27,12 +27,14 @@
|
|||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "winsock.h"
|
||||
|
||||
#include <polypcore/util.h>
|
||||
#include <polypcore/socket-util.h>
|
||||
#include <polypcore/xmalloc.h>
|
||||
#include <polypcore/log.h>
|
||||
|
||||
#include "iochannel.h"
|
||||
|
||||
|
|
@ -242,6 +244,134 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
|
|||
return r;
|
||||
}
|
||||
|
||||
#ifdef SCM_CREDENTIALS
|
||||
|
||||
int pa_iochannel_creds_supported(pa_iochannel *io) {
|
||||
struct sockaddr_un sa;
|
||||
socklen_t l;
|
||||
|
||||
assert(io);
|
||||
assert(io->ifd >= 0);
|
||||
assert(io->ofd == io->ifd);
|
||||
|
||||
l = sizeof(sa);
|
||||
|
||||
if (getsockname(io->ifd, (struct sockaddr*) &sa, &l) < 0)
|
||||
return 0;
|
||||
|
||||
return sa.sun_family == AF_UNIX;
|
||||
}
|
||||
|
||||
int pa_iochannel_creds_enable(pa_iochannel *io) {
|
||||
int t = 1;
|
||||
|
||||
assert(io);
|
||||
assert(io->ifd >= 0);
|
||||
|
||||
if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) {
|
||||
pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l) {
|
||||
ssize_t r;
|
||||
struct msghdr mh;
|
||||
struct iovec iov;
|
||||
uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))];
|
||||
struct ucred *ucred;
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
assert(io);
|
||||
assert(data);
|
||||
assert(l);
|
||||
assert(io->ofd >= 0);
|
||||
|
||||
memset(&iov, 0, sizeof(iov));
|
||||
iov.iov_base = (void*) data;
|
||||
iov.iov_len = l;
|
||||
|
||||
memset(cmsg_data, 0, sizeof(cmsg_data));
|
||||
cmsg = (struct cmsghdr*) cmsg_data;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_CREDENTIALS;
|
||||
|
||||
ucred = (struct ucred*) CMSG_DATA(cmsg);
|
||||
ucred->pid = getpid();
|
||||
ucred->uid = getuid();
|
||||
ucred->gid = getgid();
|
||||
|
||||
memset(&mh, 0, sizeof(mh));
|
||||
mh.msg_name = NULL;
|
||||
mh.msg_namelen = 0;
|
||||
mh.msg_iov = &iov;
|
||||
mh.msg_iovlen = 1;
|
||||
mh.msg_control = cmsg_data;
|
||||
mh.msg_controllen = sizeof(cmsg_data);
|
||||
mh.msg_flags = 0;
|
||||
|
||||
if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) {
|
||||
io->writable = 0;
|
||||
enable_mainloop_sources(io);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid) {
|
||||
ssize_t r;
|
||||
struct msghdr mh;
|
||||
struct iovec iov;
|
||||
uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))];
|
||||
|
||||
assert(io);
|
||||
assert(data);
|
||||
assert(l);
|
||||
assert(io->ifd >= 0);
|
||||
assert(ucred);
|
||||
assert(creds_valid);
|
||||
|
||||
memset(&iov, 0, sizeof(iov));
|
||||
iov.iov_base = data;
|
||||
iov.iov_len = l;
|
||||
|
||||
memset(cmsg_data, 0, sizeof(cmsg_data));
|
||||
|
||||
memset(&mh, 0, sizeof(mh));
|
||||
mh.msg_name = NULL;
|
||||
mh.msg_namelen = 0;
|
||||
mh.msg_iov = &iov;
|
||||
mh.msg_iovlen = 1;
|
||||
mh.msg_control = cmsg_data;
|
||||
mh.msg_controllen = sizeof(cmsg_data);
|
||||
mh.msg_flags = 0;
|
||||
|
||||
if ((r = recvmsg(io->ifd, &mh, MSG_NOSIGNAL)) >= 0) {
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
*creds_valid = 0;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
|
||||
|
||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
|
||||
assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)));
|
||||
memcpy(ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
|
||||
*creds_valid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
io->readable = 0;
|
||||
enable_mainloop_sources(io);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) {
|
||||
assert(io);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue