chiark / gitweb /
Always use our own MAX/MIN definitions
[elogind.git] / src / libsystemd-bus / bus-socket.c
index b9ef7c03720ea6f58e5d88961d7015ecbafc7f9f..c68c7bca682791625b4adf05a50833fb75ad0f49 100644 (file)
@@ -235,7 +235,7 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) {
          * 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)
@@ -258,7 +258,9 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) {
         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;
@@ -311,13 +313,16 @@ static int bus_socket_auth_verify_server(sd_bus *b) {
 
         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;
@@ -450,7 +455,7 @@ static int bus_socket_read_auth(sd_bus *b) {
         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;
@@ -508,16 +513,23 @@ static int bus_socket_read_auth(sd_bus *b) {
                                    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;
+                                }
                         }
                 }
         }
@@ -531,6 +543,7 @@ static int bus_socket_read_auth(sd_bus *b) {
 
 static int bus_socket_setup(sd_bus *b) {
         int enable;
+        socklen_t l;
 
         assert(b);
 
@@ -544,6 +557,11 @@ static int bus_socket_setup(sd_bus *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;
 }
 
@@ -935,16 +953,22 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
                                    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;
+                                }
                         }
                 }
         }