[vlc-devel] commit: Fix/split rootwrap_bind ( Rémi Denis-Courmont )
git version control
git at videolan.org
Fri Jun 6 17:53:25 CEST 2008
vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Fri Jun 6 18:14:56 2008 +0300| [536779c8d510cc6b9a29be9614be5e51961caeb8]
Fix/split rootwrap_bind
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=536779c8d510cc6b9a29be9614be5e51961caeb8
---
src/Makefile.am | 2 +-
src/network/rootbind.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 172 insertions(+), 1 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index d91a861..c5a2668 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -321,7 +321,7 @@ SOURCES_libvlc_common = \
network/tcp.c \
network/udp.c \
network/httpd.c \
- network/rootwrap.c \
+ network/rootbind.c \
network/tls.c \
network/poll.c \
text/charset.c \
diff --git a/src/network/rootbind.c b/src/network/rootbind.c
new file mode 100644
index 0000000..c6546d4
--- /dev/null
+++ b/src/network/rootbind.c
@@ -0,0 +1,171 @@
+/*****************************************************************************
+ * rootbind.c: bind to reserved ports through the root wrapper
+ *****************************************************************************
+ * Copyright © 2005-2008 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined (WIN32) && !defined (SYS_BEOS)
+# define ENABLE_ROOTWRAP 1
+#endif
+
+#include <stddef.h>
+struct sockaddr;
+int rootwrap_bind (int, int, int, const struct sockaddr *, size_t);
+
+#include <errno.h>
+
+#ifdef ENABLE_ROOTWRAP
+
+#include <string.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+
+/**
+ * Receive a file descriptor from another process
+ */
+static int recv_fd (int p)
+{
+ struct msghdr hdr;
+ struct iovec iov;
+ struct cmsghdr *cmsg;
+ int val, fd;
+ char buf[CMSG_SPACE (sizeof (fd))];
+
+ hdr.msg_name = NULL;
+ hdr.msg_namelen = 0;
+ hdr.msg_iov = &iov;
+ hdr.msg_iovlen = 1;
+ hdr.msg_control = buf;
+ hdr.msg_controllen = sizeof (buf);
+
+ iov.iov_base = &val;
+ iov.iov_len = sizeof (val);
+
+ if (recvmsg (p, &hdr, 0) != sizeof (val))
+ return -1;
+
+ for (cmsg = CMSG_FIRSTHDR (&hdr); cmsg != NULL;
+ cmsg = CMSG_NXTHDR (&hdr, cmsg))
+ {
+ if ((cmsg->cmsg_level == SOL_SOCKET)
+ && (cmsg->cmsg_type = SCM_RIGHTS)
+ && (cmsg->cmsg_len >= CMSG_LEN (sizeof (fd))))
+ {
+ memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd));
+ return fd;
+ }
+ }
+
+ errno = val;
+ return -1;
+}
+
+/**
+ * Tries to obtain a bound TCP socket from the root process
+ */
+int rootwrap_bind (int family, int socktype, int protocol,
+ const struct sockaddr *addr, size_t alen)
+{
+ /* can't use libvlc */
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ struct sockaddr_storage ss;
+ int fd, sock = -1;
+
+ const char *sockenv = getenv ("VLC_ROOTWRAP_SOCK");
+ if (sockenv != NULL)
+ sock = atoi (sock);
+ if (sock == -1)
+ {
+ errno = EACCES;
+ return -1;
+ }
+
+ switch (family)
+ {
+ case AF_INET:
+ if (alen < sizeof (struct sockaddr_in))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ break;
+
+#ifdef AF_INET6
+ case AF_INET6:
+ if (alen < sizeof (struct sockaddr_in6))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ break;
+#endif
+
+ default:
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+
+ if (family != addr->sa_family)
+ {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+
+ /* Only TCP is implemented at the moment */
+ if ((socktype != SOCK_STREAM)
+ || (protocol && (protocol != IPPROTO_TCP)))
+ {
+ errno = EACCES;
+ return -1;
+ }
+
+ memset (&ss, 0, sizeof (ss));
+ memcpy (&ss, addr, alen > sizeof (ss) ? sizeof (ss) : alen);
+
+ pthread_mutex_lock (&mutex);
+ if (send (sock, &ss, sizeof (ss), 0) != sizeof (ss))
+ return -1;
+
+ fd = recv_fd (sock);
+ pthread_mutex_unlock (&mutex);
+ return fd;
+}
+
+#else
+int rootwrap_bind (int family, int socktype, int protocol,
+ const struct sockaddr *addr, size_t alen)
+{
+ (void)family;
+ (void)socktype;
+ (void)protocol;
+ (void)addr;
+ (void)alen;
+ errno = EACCES;
+ return -1;
+}
+
+#endif /* ENABLE_ROOTWRAP */
More information about the vlc-devel
mailing list