#include "missing.h"
#include "strv.h"
#include "utf8.h"
+#include "sd-daemon.h"
#include "sd-bus.h"
#include "bus-socket.h"
* the owner of this bus wanted authentication he should have
* checked SO_PEERCRED before even creating the bus object. */
- if (!b->ucred_valid)
+ if (!b->anonymous_auth && !b->ucred_valid)
return 0;
if (l <= 0)
if (r < 0)
return 0;
- if (u != b->ucred.uid)
+ /* We ignore the passed value if anonymous authentication is
+ * on anyway. */
+ if (!b->anonymous_auth && u != b->ucred.uid)
return 0;
return 1;
assert(b);
- if (b->rbuffer_size < 3)
+ if (b->rbuffer_size < 1)
return 0;
/* First char must be a NUL byte */
if (*(char*) b->rbuffer != 0)
return -EIO;
+ if (b->rbuffer_size < 3)
+ return 0;
+
/* Begin with the first line */
if (b->auth_rbegin <= 0)
b->auth_rbegin = 1;
if (r != 0)
return r;
- n = MAX(256, b->rbuffer_size * 2);
+ n = MAX(256u, b->rbuffer_size * 2);
if (n > BUS_AUTH_SIZE_MAX)
n = BUS_AUTH_SIZE_MAX;
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
- memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
- b->ucred_valid = true;
+ /* Ignore bogus data, which we might
+ * get on socketpair() sockets */
+ if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
+ memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
+ b->ucred_valid = true;
+ }
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_SECURITY) {
size_t l;
+
l = cmsg->cmsg_len - CMSG_LEN(0);
- memcpy(&b->label, CMSG_DATA(cmsg), l);
- b->label[l] = 0;
+ if (l > 0) {
+ memcpy(&b->label, CMSG_DATA(cmsg), l);
+ b->label[l] = 0;
+ }
}
}
}
static int bus_socket_setup(sd_bus *b) {
int enable;
+ socklen_t l;
assert(b);
fd_inc_rcvbuf(b->input_fd, 1024*1024);
fd_inc_sndbuf(b->output_fd, 1024*1024);
+ /* Get the peer for socketpair() sockets */
+ l = sizeof(b->ucred);
+ if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred))
+ b->ucred_valid = b->ucred.pid > 0;
+
return 0;
}
}
static int bus_socket_start_auth(sd_bus *b) {
- int domain = 0, r;
- socklen_t sl;
-
assert(b);
b->state = BUS_AUTHENTICATING;
b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
- sl = sizeof(domain);
- r = getsockopt(b->input_fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl);
- if (r < 0 || domain != AF_UNIX)
+ if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
b->negotiate_fds = false;
- if (b->output_fd != b->input_fd) {
- r = getsockopt(b->output_fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl);
- if (r < 0 || domain != AF_UNIX)
+ if (b->output_fd != b->input_fd)
+ if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
b->negotiate_fds = false;
- }
-
if (b->is_server)
return bus_socket_read_auth(b);
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
- memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
- bus->ucred_valid = true;
+ /* Ignore bogus data, which we might
+ * get on socketpair() sockets */
+ if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
+ memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
+ bus->ucred_valid = true;
+ }
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_SECURITY) {
size_t l;
l = cmsg->cmsg_len - CMSG_LEN(0);
- memcpy(&bus->label, CMSG_DATA(cmsg), l);
- bus->label[l] = 0;
+ if (l > 0) {
+ memcpy(&bus->label, CMSG_DATA(cmsg), l);
+ bus->label[l] = 0;
+ }
}
}
}