208 lines
4.6 KiB
C
208 lines
4.6 KiB
C
#include "pa.h"
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
|
|
void
|
|
msg_recv_creds(Pulse *conn, Pulse_Tag *tag)
|
|
{
|
|
#ifdef __linux__
|
|
int r;
|
|
struct msghdr mh;
|
|
struct iovec iov;
|
|
union {
|
|
struct cmsghdr hdr;
|
|
uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
|
|
} cmsg;
|
|
|
|
memset(&iov, 0, sizeof(iov));
|
|
iov.iov_base = &tag->header[tag->pos];
|
|
iov.iov_len = sizeof(tag->header) - tag->pos;
|
|
|
|
memset(&cmsg, 0, sizeof(cmsg));
|
|
memset(&mh, 0, sizeof(mh));
|
|
mh.msg_iov = &iov;
|
|
mh.msg_iovlen = 1;
|
|
mh.msg_control = &cmsg;
|
|
mh.msg_controllen = sizeof(cmsg);
|
|
|
|
r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0);
|
|
if ((!r) || (r == sizeof(tag->header))) tag->auth = EINA_TRUE;
|
|
else if (r < 0)
|
|
{
|
|
if (errno != EAGAIN)
|
|
{
|
|
ERR("%d: %s", errno, strerror(errno));
|
|
pulse_disconnect(conn);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG("%zu bytes left", sizeof(tag->header) - r);
|
|
tag->pos += r;
|
|
}
|
|
#else
|
|
conn = NULL;
|
|
tag = NULL;
|
|
#endif
|
|
}
|
|
|
|
Eina_Bool
|
|
msg_recv(Pulse *conn, Pulse_Tag *tag)
|
|
{
|
|
#ifdef __linux__
|
|
long r;
|
|
struct msghdr mh;
|
|
struct iovec iov;
|
|
union {
|
|
struct cmsghdr hdr;
|
|
uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
|
|
} cmsg;
|
|
|
|
memset(&iov, 0, sizeof(iov));
|
|
iov.iov_base = tag->data + tag->pos;
|
|
iov.iov_len = tag->dsize - tag->pos;
|
|
|
|
memset(&cmsg, 0, sizeof(cmsg));
|
|
memset(&mh, 0, sizeof(mh));
|
|
mh.msg_iov = &iov;
|
|
mh.msg_iovlen = 1;
|
|
mh.msg_control = &cmsg;
|
|
mh.msg_controllen = sizeof(cmsg);
|
|
|
|
r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0);
|
|
DBG("recv %li bytes", r);
|
|
/* things we don't really care about: credentials */
|
|
if ((!r) || ((unsigned int)r == tag->dsize))
|
|
{
|
|
conn->iq = eina_list_remove(conn->iq, tag);
|
|
return EINA_TRUE;
|
|
}
|
|
else if (r < 0)
|
|
{
|
|
if (errno != EAGAIN)
|
|
{
|
|
ERR("%d: %s", errno, strerror(errno));
|
|
pulse_disconnect(conn);
|
|
}
|
|
}
|
|
else
|
|
tag->pos += r;
|
|
#else
|
|
conn = NULL;
|
|
tag = NULL;
|
|
#endif
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
void
|
|
msg_sendmsg_creds(Pulse *conn, Pulse_Tag *tag)
|
|
{
|
|
#ifdef __linux__
|
|
int r;
|
|
struct msghdr mh;
|
|
struct iovec iov;
|
|
union {
|
|
struct cmsghdr hdr;
|
|
uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
|
|
} cmsg;
|
|
struct ucred *u;
|
|
|
|
memset(&iov, 0, sizeof(iov));
|
|
iov.iov_base = (void*) &tag->header[tag->pos];
|
|
iov.iov_len = sizeof(tag->header) - tag->pos;
|
|
|
|
memset(&cmsg, 0, sizeof(cmsg));
|
|
cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
|
cmsg.hdr.cmsg_level = SOL_SOCKET;
|
|
cmsg.hdr.cmsg_type = SCM_CREDENTIALS;
|
|
|
|
u = (struct ucred*) CMSG_DATA(&cmsg.hdr);
|
|
|
|
u->pid = getpid();
|
|
u->uid = getuid();
|
|
u->gid = getgid();
|
|
|
|
memset(&mh, 0, sizeof(mh));
|
|
mh.msg_iov = &iov;
|
|
mh.msg_iovlen = 1;
|
|
mh.msg_control = &cmsg;
|
|
mh.msg_controllen = sizeof(cmsg);
|
|
|
|
r = sendmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, MSG_NOSIGNAL);
|
|
if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE;
|
|
else if (r < 0)
|
|
{
|
|
if (errno != EAGAIN)
|
|
{
|
|
ERR("%d: %s", errno, strerror(errno));
|
|
pulse_disconnect(conn);
|
|
}
|
|
}
|
|
else
|
|
tag->pos += r;
|
|
#else
|
|
conn = NULL;
|
|
tag = NULL;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
msg_send_creds(Pulse *conn, Pulse_Tag *tag)
|
|
{
|
|
#ifdef __linux__
|
|
int r;
|
|
|
|
INF("trying to send 20 byte auth header");
|
|
r = send(ecore_main_fd_handler_fd_get(conn->fdh), &tag->header[tag->pos], sizeof(tag->header) - (tag->pos * sizeof(tag->header[0])), MSG_NOSIGNAL);
|
|
INF("%i bytes sent!", r);
|
|
if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE;
|
|
else if (r < 0)
|
|
{
|
|
if (errno != EAGAIN)
|
|
{
|
|
ERR("%d: %s", errno, strerror(errno));
|
|
pulse_disconnect(conn);
|
|
}
|
|
}
|
|
else
|
|
tag->pos += r;
|
|
#else
|
|
conn = NULL;
|
|
tag = NULL;
|
|
#endif
|
|
}
|
|
|
|
Eina_Bool
|
|
msg_send(Pulse *conn, Pulse_Tag *tag)
|
|
{
|
|
#ifdef __linux__
|
|
int r;
|
|
|
|
INF("trying to send %zu bytes", tag->dsize - tag->pos);
|
|
r = send(ecore_main_fd_handler_fd_get(conn->fdh), tag->data + tag->pos, tag->dsize - tag->pos, MSG_NOSIGNAL);
|
|
INF("%i bytes sent!", r);
|
|
if ((!r) || ((unsigned int)r == tag->dsize - tag->pos))
|
|
{
|
|
DBG("Send complete! Deleting tag...");
|
|
conn->oq = eina_list_remove(conn->oq, tag);
|
|
pulse_tag_free(tag);
|
|
return EINA_TRUE;
|
|
}
|
|
if (r < 0)
|
|
{
|
|
if (errno != EAGAIN)
|
|
{
|
|
ERR("%d: %s", errno, strerror(errno));
|
|
pulse_disconnect(conn);
|
|
}
|
|
}
|
|
else
|
|
tag->pos += r;
|
|
#else
|
|
conn = NULL;
|
|
tag = NULL;
|
|
#endif
|
|
return EINA_FALSE;
|
|
}
|