sd-daemon: verify socket family, too
This commit is contained in:
parent
dde770cfc6
commit
88ce42f694
2
fixme
2
fixme
|
@ -47,9 +47,9 @@
|
||||||
- uuidd DONE
|
- uuidd DONE
|
||||||
- nscd DONE
|
- nscd DONE
|
||||||
- dbus DONE
|
- dbus DONE
|
||||||
|
- rsyslog DONE
|
||||||
- rpcbind (/var/run/rpcbind.sock!)
|
- rpcbind (/var/run/rpcbind.sock!)
|
||||||
- avahi-daemon (/var/run/avahi-daemon/socket)
|
- avahi-daemon (/var/run/avahi-daemon/socket)
|
||||||
- rsyslog
|
|
||||||
- cups
|
- cups
|
||||||
- ssh CLASSIC
|
- ssh CLASSIC
|
||||||
- postfix, saslauthd
|
- postfix, saslauthd
|
||||||
|
|
|
@ -428,7 +428,7 @@ static int server_init(Server *s, unsigned n_sockets) {
|
||||||
|
|
||||||
fd = SD_LISTEN_FDS_START+i;
|
fd = SD_LISTEN_FDS_START+i;
|
||||||
|
|
||||||
if ((r = sd_is_socket(fd, SOCK_STREAM, 1)) < 0) {
|
if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1)) < 0) {
|
||||||
log_error("Failed to determine file descriptor type: %s", strerror(-r));
|
log_error("Failed to determine file descriptor type: %s", strerror(-r));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ int sd_is_fifo(int fd, const char *path) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_is_socket(int fd, int type, int listening) {
|
static int sd_is_socket_internal(int fd, int type, int listening) {
|
||||||
struct stat st_fd;
|
struct stat st_fd;
|
||||||
|
|
||||||
if (fd < 0 || type < 0)
|
if (fd < 0 || type < 0)
|
||||||
|
@ -176,18 +176,51 @@ int sd_is_socket(int fd, int type, int listening) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
|
union sockaddr_union {
|
||||||
union {
|
struct sockaddr sa;
|
||||||
struct sockaddr sa;
|
struct sockaddr_in in4;
|
||||||
struct sockaddr_in in4;
|
struct sockaddr_in6 in6;
|
||||||
struct sockaddr_in6 in6;
|
struct sockaddr_un un;
|
||||||
struct sockaddr_un un;
|
struct sockaddr_storage storage;
|
||||||
struct sockaddr_storage storage;
|
};
|
||||||
} sockaddr;
|
|
||||||
|
int sd_is_socket(int fd, int family, int type, int listening) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (family < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (family > 0) {
|
||||||
|
union sockaddr_union sockaddr;
|
||||||
|
socklen_t l;
|
||||||
|
|
||||||
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
|
l = sizeof(sockaddr);
|
||||||
|
|
||||||
|
if (getsockname(fd, &sockaddr.sa, &l) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (l < sizeof(sa_family_t))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return sockaddr.sa.sa_family == family;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
|
||||||
|
union sockaddr_union sockaddr;
|
||||||
socklen_t l;
|
socklen_t l;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if ((r = sd_is_socket(fd, type, listening)) <= 0)
|
if (family != 0 && family != AF_INET && family != AF_INET6)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
|
@ -196,13 +229,17 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
|
||||||
if (getsockname(fd, &sockaddr.sa, &l) < 0)
|
if (getsockname(fd, &sockaddr.sa, &l) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (l < sizeof(struct sockaddr))
|
if (l < sizeof(sa_family_t))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (sockaddr.sa.sa_family != AF_INET &&
|
if (sockaddr.sa.sa_family != AF_INET &&
|
||||||
sockaddr.sa.sa_family != AF_INET6)
|
sockaddr.sa.sa_family != AF_INET6)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (family > 0)
|
||||||
|
if (sockaddr.sa.sa_family != family)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (port > 0) {
|
if (port > 0) {
|
||||||
if (sockaddr.sa.sa_family == AF_INET) {
|
if (sockaddr.sa.sa_family == AF_INET) {
|
||||||
if (l < sizeof(struct sockaddr_in))
|
if (l < sizeof(struct sockaddr_in))
|
||||||
|
@ -221,17 +258,11 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
|
int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
|
||||||
union {
|
union sockaddr_union sockaddr;
|
||||||
struct sockaddr sa;
|
|
||||||
struct sockaddr_in in4;
|
|
||||||
struct sockaddr_in6 in6;
|
|
||||||
struct sockaddr_un un;
|
|
||||||
struct sockaddr_storage storage;
|
|
||||||
} sockaddr;
|
|
||||||
socklen_t l;
|
socklen_t l;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if ((r = sd_is_socket(fd, type, listening)) <= 0)
|
if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
|
|
|
@ -73,24 +73,26 @@ int sd_listen_fds(int unset_environment);
|
||||||
int sd_is_fifo(int fd, const char *path);
|
int sd_is_fifo(int fd, const char *path);
|
||||||
|
|
||||||
/* Helper call for identifying a passed file descriptor. Returns 1 if
|
/* Helper call for identifying a passed file descriptor. Returns 1 if
|
||||||
* the file descriptor is a socket of the specified type (SOCK_DGRAM,
|
* the file descriptor is a socket of the specified family (AF_INET,
|
||||||
* SOCK_STREAM, ...), 0 otherwise. If type is 0 a socket type check
|
* ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
|
||||||
* will not be done and the call only verifies if the file descriptor
|
* family is 0 a socket family check will not be done. If type is 0 a
|
||||||
* refers to a socket. If listening is > 0 it is verified that the
|
* socket type check will not be done and the call only verifies if
|
||||||
* socket is in listening mode. (i.e. listen() has been called) If
|
* the file descriptor refers to a socket. If listening is > 0 it is
|
||||||
* listening is == 0 it is verified that the socket is not in
|
* verified that the socket is in listening mode. (i.e. listen() has
|
||||||
* listening mode. If listening is < 0 no listening mode check is
|
* been called) If listening is == 0 it is verified that the socket is
|
||||||
* done. Returns a negative errno style error code on failure. */
|
* not in listening mode. If listening is < 0 no listening mode check
|
||||||
int sd_is_socket(int fd, int type, int listening);
|
* is done. Returns a negative errno style error code on failure. */
|
||||||
|
int sd_is_socket(int fd, int family, int type, int listening);
|
||||||
|
|
||||||
/* Helper call for identifying a passed file descriptor. Returns 1 if
|
/* Helper call for identifying a passed file descriptor. Returns 1 if
|
||||||
* the file descriptor is an Internet socket (either AF_INET or
|
* the file descriptor is an Internet socket, of the specified family
|
||||||
* AF_INET6) of the specified type (SOCK_DGRAM, SOCK_STREAM, ...), 0
|
* (either AF_INET or AF_INET6) of the specified type (SOCK_DGRAM,
|
||||||
* otherwise. If type is 0 a socket type check will not be done. If
|
* SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
|
||||||
* port is 0 a socket port check will not be done. The listening flag
|
* check is not done. If type is 0 a socket type check will not be
|
||||||
* is used the same way as in sd_is_socket(). Returns a negative errno
|
* done. If port is 0 a socket port check will not be done. The
|
||||||
* style error code on failure. */
|
* listening flag is used the same way as in sd_is_socket(). Returns a
|
||||||
int sd_is_socket_inet(int fd, int type, int listening, uint16_t port);
|
* negative errno style error code on failure. */
|
||||||
|
int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
|
||||||
|
|
||||||
/* Helper call for identifying a passed file descriptor. Returns 1 if
|
/* Helper call for identifying a passed file descriptor. Returns 1 if
|
||||||
* the file descriptor is an AF_UNIX socket of the specified type
|
* the file descriptor is an AF_UNIX socket of the specified type
|
||||||
|
|
Loading…
Reference in New Issue