From 831a513b2d9eaf84c117f4549358672b03cb81b2 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Wed, 14 Oct 2015 13:47:35 -0400 Subject: [PATCH] Normalized cases --- netcon/{common.c => Common.c} | 2 +- netcon/{common.h => Common.h} | 0 netcon/Intercept.c | 936 ++++++++++++++++++++++++++++++++++ netcon/{sendfd.c => Sendfd.c} | 0 netcon/{sendfd.h => Sendfd.h} | 0 netcon/intercept.h | 233 --------- netcon/libintercept.so.1.0 | Bin 53768 -> 53568 bytes netcon/make-intercept.mk | 12 +- 8 files changed, 943 insertions(+), 240 deletions(-) rename netcon/{common.c => Common.c} (99%) rename netcon/{common.h => Common.h} (100%) create mode 100755 netcon/Intercept.c rename netcon/{sendfd.c => Sendfd.c} (100%) rename netcon/{sendfd.h => Sendfd.h} (100%) delete mode 100755 netcon/intercept.h diff --git a/netcon/common.c b/netcon/Common.c similarity index 99% rename from netcon/common.c rename to netcon/Common.c index 2e683625a..beb530c62 100755 --- a/netcon/common.c +++ b/netcon/Common.c @@ -37,7 +37,7 @@ #include #include -#include "common.h" +#include "Common.h" void dwr(const char *fmt, ...); diff --git a/netcon/common.h b/netcon/Common.h similarity index 100% rename from netcon/common.h rename to netcon/Common.h diff --git a/netcon/Intercept.c b/netcon/Intercept.c new file mode 100755 index 000000000..97af0c94a --- /dev/null +++ b/netcon/Intercept.c @@ -0,0 +1,936 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 3 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, see . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + + +#ifdef USE_GNU_SOURCE +#define _GNU_SOURCE +#endif + +/* Name used in err msgs */ +char *progname = ""; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* For NPs */ +#include +#include +#include + +/* for mmap */ +#include + +#ifdef USE_SOCKS_DNS + #include +#endif + +#include "Intercept.h" +#include "Common.h" + +#ifdef CHECKS + //#include + #include + #include /* for NPROTO */ + + #define SOCK_MAX (SOCK_PACKET + 1) + #define SOCK_TYPE_MASK 0xf +#endif + +/* Global Declarations */ +#ifdef USE_SOCKS_DNS +static int (*realresinit)(void); +#endif +static int (*realconnect)(CONNECT_SIG); +static int (*realselect)(SELECT_SIG); +static int (*realpoll)(POLL_SIG); +static int (*realbind)(BIND_SIG); +static int (*realaccept)(ACCEPT_SIG); +static int (*reallisten)(LISTEN_SIG); +static int (*realsocket)(SOCKET_SIG); +static int (*realsetsockopt)(SETSOCKOPT_SIG); +static int (*realgetsockopt)(GETSOCKOPT_SIG); +static int (*realaccept4)(ACCEPT4_SIG); + +/* Exported Function Prototypes */ +void my_init(void); +int connect(CONNECT_SIG); +int select(SELECT_SIG); +int poll(POLL_SIG); +int close(CLOSE_SIG); +int bind(BIND_SIG); +int accept(ACCEPT_SIG); +int listen(LISTEN_SIG); +int socket(SOCKET_SIG); +int setsockopt(SETSOCKOPT_SIG); +int getsockopt(GETSOCKOPT_SIG); +int accept4(ACCEPT4_SIG); + +#ifdef USE_SOCKS_DNS +int res_init(void); +#endif + +int connect_to_service(void); +int init_service_connection(); +void dwr(const char *fmt, ...); +void load_symbols(void); +void set_up_intercept(); +int checkpid(); + + +#define BUF_SZ 1024 +#define SERVICE_CONNECT_ATTEMPTS 30 + +#define ERR_OK 0 + +ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd); + +/* threading */ +pthread_mutex_t lock; +pthread_mutex_t loglock; + + +/*------------------------------------------------------------------------------ +------------------- Intercept<--->Service Comm mechanisms----------------------- +------------------------------------------------------------------------------*/ + +// TODO: Find minimum BUF_SZ for RPC +// TODO: Refactor RPC send logic + +static int is_initialized = 0; +static int fdret_sock; // used for fd-transfers +static int newfd; // used for "this_end" socket +static int thispid; +static char* af_sock_name = "/tmp/.ztnc_e5cd7a9e1c5311ab"; + +/* + * Check for forking + */ +int checkpid() { + if(thispid != getpid()) { + printf("clone/fork detected. re-initializing this instance.\n"); + set_up_intercept(); + fdret_sock = init_service_connection(); + thispid = getpid(); + } + return 0; +} + +/* + * Sends an RPC command to the service + */ +void send_command(int rpc_fd, char *cmd) +{ + int n_write = write(rpc_fd, cmd, BUF_SZ); + if(n_write < 0){ + dwr("Error writing command to service (CMD = %d)\n", cmd[0]); + errno = 0; + //return -1; + } + +} +/* + * Reads a return value from the service and sets errno (if applicable) + */ +int get_retval() +{ + if(fdret_sock >= 0) { + int retval; + int sz = sizeof(char) + sizeof(retval) + sizeof(errno); + char retbuf[BUF_SZ]; + memset(&retbuf, '\0', sz); + int n_read = read(fdret_sock, &retbuf, sz); + if(n_read > 0) { + memcpy(&retval, &retbuf[1], sizeof(retval)); + memcpy(&errno, &retbuf[1+sizeof(retval)], sizeof(errno)); + return retval; + } + } + dwr("unable to read connect: return value\n"); + return -1; +} + + +/*------------------------------------------------------------------------------ +---------- Unix-domain socket lazy initializer (for fd-transfers)-------------- +------------------------------------------------------------------------------*/ + +/* Sets up the connection pipes and sockets to the service */ +int init_service_connection() +{ + if(!is_initialized) + { + struct sockaddr_un addr; + int tfd = -1; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, af_sock_name, sizeof(addr.sun_path)-1); + + int attempts = 0; + int conn_err = -1; + + if ( (tfd = realsocket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + perror("socket error"); + exit(-1); + } + + while(conn_err < 0 && attempts < SERVICE_CONNECT_ATTEMPTS) + { + dwr("trying connection (%d): %s\n", tfd, af_sock_name); + conn_err = realconnect(tfd, (struct sockaddr*)&addr, sizeof(addr)); + + if(conn_err < 0) { + dwr("re-attempting connection in %ds\n", 1+attempts); + sleep(1); + } + else { + dwr("AF_UNIX connection established: %d\n", tfd); + is_initialized = 1; + return tfd; + } + attempts++; + } + } + return -1; +} + +/*------------------------------------------------------------------------------ +------------------------ ctors and dtors (and friends)------------------------- +------------------------------------------------------------------------------*/ + +void my_dest(void) __attribute__ ((destructor)); +void my_dest(void) { + + dwr("closing connections to service...\n"); + close(fdret_sock); + pthread_mutex_destroy(&lock); +} + + +void load_symbols(void) +{ +#ifdef USE_OLD_DLSYM + void *lib; +#endif + /* possibly add check to beginning of each method to avoid needing to cll the constructor */ + if(thispid == getpid()) { + dwr("detected duplicate call to global ctor (pid=%d).\n", thispid); + } + dwr(" -- pid = %d\n", getpid()); + dwr(" -- uid = %d\n", getuid()); + thispid = getpid(); + +#ifndef USE_OLD_DLSYM + realconnect = dlsym(RTLD_NEXT, "connect"); + realbind = dlsym(RTLD_NEXT, "bind"); + realaccept = dlsym(RTLD_NEXT, "accept"); + reallisten = dlsym(RTLD_NEXT, "listen"); + realsocket = dlsym(RTLD_NEXT, "socket"); + realbind = dlsym(RTLD_NEXT, "bind"); + realpoll = dlsym(RTLD_NEXT, "poll"); + realselect = dlsym(RTLD_NEXT, "select"); + realsetsockopt = dlsym(RTLD_NEXT, "setsockopt"); + realgetsockopt = dlsym(RTLD_NEXT, "getsockopt"); + realaccept4 = dlsym(RTLD_NEXT, "accept4"); + + #ifdef USE_SOCKS_DNS + realresinit = dlsym(RTLD_NEXT, "res_init"); + #endif + +#else + lib = dlopen(LIBCONNECT, RTLD_LAZY); + realconnect = dlsym(lib, "connect"); + realbind = dlsym(lib, "bind"); + realaccept = dlsym(lib, "accept"); + reallisten = dlsym(lib, "listen"); + realsocket = dlsym(lib, "socket"); + realpoll = dlsym(lib, "poll"); + realselect = dlsym(lib, "select"); + realsetsockopt = dlsym(lib, "setsockopt"); + realgetsockopt = dlsym(lib, "getsockopt"); + realaccept4 = dlsym(lib), "accept4"); + + #ifdef USE_SOCKS_DNS + realresinit = dlsym(lib, "res_init"); + #endif + dlclose(lib); + + lib = dlopen(LIBC, RTLD_LAZY); + dlclose(lib); +#endif +} + +/* Private Function Prototypes */ +void _init(void) __attribute__ ((constructor)); +void _init(void) { + set_up_intercept(); +} + +/* get symbols and initialize mutexes */ +void set_up_intercept() +{ + load_symbols(); + if(pthread_mutex_init(&lock, NULL) != 0) { + printf("error while initializing service call mutex\n"); + } + if(pthread_mutex_init(&loglock, NULL) != 0) { + printf("error while initializing log mutex mutex\n"); + } +} + + +/*------------------------------------------------------------------------------ +------------------------- ioctl(), fcntl(), setsockopt()------------------------ +------------------------------------------------------------------------------*/ + +char *cmd_to_str(int cmd) +{ + switch(cmd) + { + case F_DUPFD: + return "F_DUPFD"; + case F_GETFD: + return "F_GETFD"; + case F_SETFD: + return "F_SETFD"; + case F_GETFL: + return "F_GETFL"; + case F_SETFL: + return "F_SETFL"; + case F_GETLK: + return "F_GETLK"; + case F_SETLK: + return "F_SETLK"; + case F_SETLKW: + return "F_SETLKW"; + default: + return "?"; + } + return "?"; +} + +void arg_to_str(int arg) +{ + if(arg & O_RDONLY) dwr("O_RDONLY "); + if(arg & O_WRONLY) dwr("O_WRONLY "); + if(arg & O_RDWR) dwr("O_RDWR "); + if(arg & O_CREAT) dwr("O_CREAT "); + if(arg & O_EXCL) dwr("O_EXCL "); + if(arg & O_NOCTTY) dwr("O_NOCTTY "); + if(arg & O_TRUNC) dwr("O_TRUNC "); + if(arg & O_APPEND) dwr("O_APPEND "); + if(arg & O_ASYNC) dwr("O_ASYNC "); + if(arg & O_DIRECT) dwr("O_DIRECT "); + if(arg & O_NOATIME) dwr("O_NOATIME "); + if(arg & O_NONBLOCK) dwr("O_NONBLOCK "); + if(arg & O_DSYNC) dwr("O_DSYNC "); + if(arg & O_SYNC) dwr("O_SYNC "); +} + +char* level_to_str(int level) +{ + switch(level) + { + case SOL_SOCKET: + return "SOL_SOCKET"; + case IPPROTO_TCP: + return "IPPROTO_TCP"; + default: + return "?"; + } + return "?"; +} + +char* option_name_to_str(int opt) +{ + if(opt == SO_DEBUG) return "SO_DEBUG"; + if(opt == SO_BROADCAST) return "SO_BROADCAST"; + if(opt == SO_BINDTODEVICE) return "SO_BINDTODEVICE"; + if(opt == SO_REUSEADDR) return "SO_REUSEADDR"; + if(opt == SO_KEEPALIVE) return "SO_KEEPALIVE"; + if(opt == SO_LINGER) return "SO_LINGER"; + if(opt == SO_OOBINLINE) return "SO_OOBINLINE"; + if(opt == SO_SNDBUF) return "SO_SNDBUF"; + if(opt == SO_RCVBUF) return "SO_RCVBUF"; + if(opt == SO_DONTROUTE) return "SO_DONTROUTEO_ASYNC"; + if(opt == SO_RCVLOWAT) return "SO_RCVLOWAT"; + if(opt == SO_RCVTIMEO) return "SO_RCVTIMEO"; + if(opt == SO_SNDLOWAT) return "SO_SNDLOWAT"; + if(opt == SO_SNDTIMEO)return "SO_SNDTIMEO"; + return "?"; +} + +/*------------------------------------------------------------------------------ +--------------------------------- setsockopt() --------------------------------- +------------------------------------------------------------------------------*/ +/* int socket, int level, int option_name, const void *option_value, socklen_t option_len */ +int setsockopt(SETSOCKOPT_SIG) +{ +#ifdef DUMMY + dwr("setsockopt(%d)\n", socket); + return realsetsockopt(socket, level, option_name, option_value, option_len); + +#else + /* make sure we don't touch any standard outputs */ + if(socket == STDIN_FILENO || socket == STDOUT_FILENO || socket == STDERR_FILENO) + return(realsetsockopt(socket, level, option_name, option_value, option_len)); + int err = realsetsockopt(socket, level, option_name, option_value, option_len); + if(err < 0){ + //perror("setsockopt():\n"); + } + return 0; +#endif +} + + +/*------------------------------------------------------------------------------ +--------------------------------- getsockopt() --------------------------------- +------------------------------------------------------------------------------*/ +/* int sockfd, int level, int optname, void *optval, socklen_t *optlen */ + +int getsockopt(GETSOCKOPT_SIG) +{ +#ifdef DUMMY + dwr("getsockopt(%d)\n", sockfd); + return realgetsockopt(sockfd, level, optname, optval, optlen); + +#else + // make sure we don't touch any standard outputs + int err = realgetsockopt(sockfd, level, optname, optval, optlen); + + // FIXME: this condition will need a little more intelligence later on + // -- we will need to know if this fd is a local we are spoofing, or a true local + if(optname == SO_TYPE) + { + int* val = (int*)optval; + *val = 2; + optval = (void*)val; + } + if(err < 0){ + //perror("setsockopt():\n"); + } + return 0; +#endif +} + + +/*------------------------------------------------------------------------------ +---------------------------------- shutdown() ---------------------------------- +------------------------------------------------------------------------------*/ + +void shutdown_arg_to_str(int arg) +{ + if(arg & O_RDONLY) dwr("O_RDONLY "); + if(arg & O_WRONLY) dwr("O_WRONLY "); + if(arg & O_RDWR) dwr("O_RDWR "); + if(arg & O_CREAT) dwr("O_CREAT "); + if(arg & O_EXCL) dwr("O_EXCL "); + if(arg & O_NOCTTY) dwr("O_NOCTTY "); + if(arg & O_TRUNC) dwr("O_TRUNC "); + if(arg & O_APPEND) dwr("O_APPEND "); + if(arg & O_ASYNC) dwr("O_ASYNC "); + if(arg & O_DIRECT) dwr("O_DIRECT "); + if(arg & O_NOATIME) dwr("O_NOATIME "); + if(arg & O_NONBLOCK) dwr("O_NONBLOCK "); + if(arg & O_DSYNC) dwr("O_DSYNC "); + if(arg & O_SYNC) dwr("O_SYNC "); +} + +/*------------------------------------------------------------------------------ +----------------------------------- socket() ----------------------------------- +------------------------------------------------------------------------------*/ + +void sock_type_to_str(int arg) +{ + if(arg == SOCK_STREAM) printf("SOCK_STREAM "); + if(arg == SOCK_DGRAM) printf("SOCK_DGRAM "); + if(arg == SOCK_SEQPACKET) printf("SOCK_SEQPACKET "); + if(arg == SOCK_RAW) printf("SOCK_RAW "); + if(arg == SOCK_RDM) printf("SOCK_RDM "); + if(arg == SOCK_PACKET) printf("SOCK_PACKET "); + if(arg & SOCK_NONBLOCK) printf("| SOCK_NONBLOCK "); + if(arg & SOCK_CLOEXEC) printf("| SOCK_CLOEXEC "); +} + +void sock_domain_to_str(int domain) +{ + if(domain == AF_UNIX) printf("AF_UNIX "); + if(domain == AF_LOCAL) printf("AF_LOCAL "); + if(domain == AF_INET) printf("AF_INET "); + if(domain == AF_INET6) printf("AF_INET6 "); + if(domain == AF_IPX) printf("AF_IPX "); + if(domain == AF_NETLINK) printf("AF_NETLINK "); + if(domain == AF_X25) printf("AF_X25 "); + if(domain == AF_AX25) printf("AF_AX25 "); + if(domain == AF_ATMPVC) printf("AF_ATMPVC "); + if(domain == AF_APPLETALK) printf("AF_APPLETALK "); + if(domain == AF_PACKET) printf("AF_PACKET "); +} + +/* int socket_family, int socket_type, int protocol + socket() intercept function */ + +int socket(SOCKET_SIG) +{ + int err; +#ifdef CHECKS + /* Check that type makes sense */ + int flags = socket_type & ~SOCK_TYPE_MASK; + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) + return -EINVAL; + socket_type &= SOCK_TYPE_MASK; + /* Check protocol is in range */ + if (socket_family < 0 || socket_family >= NPROTO) + return -EAFNOSUPPORT; + if (socket_type < 0 || socket_type >= SOCK_MAX) + return -EINVAL; + /* Check that we haven't hit the soft-limit file descriptors allowed */ + /* FIXME: Find number of open fds + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + if(sockfd >= rl.rlim_cur){ + errno = EMFILE; + return -1; + } + */ + /* FIXME: detect ENFILE condition */ +#endif + +#ifdef DUMMY + dwr("socket(fam=%d, type=%d, prot=%d)\n", socket_family, socket_type, protocol); + return realsocket(socket_family, socket_type, protocol); + +#else + char cmd[BUF_SZ]; + fdret_sock = !is_initialized ? init_service_connection() : fdret_sock; + + if(socket_family == AF_LOCAL + || socket_family == AF_NETLINK + || socket_family == AF_UNIX) { + return realsocket(socket_family, socket_type, protocol); + } + + /* Assemble and route command */ + struct socket_st rpc_st; + rpc_st.socket_family = socket_family; + rpc_st.socket_type = socket_type; + rpc_st.protocol = protocol; + rpc_st.__tid = syscall(SYS_gettid); + + memset(cmd, '\0', BUF_SZ); + cmd[0] = RPC_SOCKET; + memcpy(&cmd[1], &rpc_st, sizeof(struct socket_st)); + pthread_mutex_lock(&lock); + write(fdret_sock,cmd, BUF_SZ); + + /* get new fd */ + char gmybuf[16]; + ssize_t size = sock_fd_read(fdret_sock, gmybuf, sizeof(gmybuf), &newfd); + if(size > 0) + { + /* send our local-fd number back to service so + it can complete its mapping table entry */ + memset(cmd, '\0', BUF_SZ); + cmd[0] = RPC_FD_MAP_COMPLETION; + memcpy(&cmd[1], &newfd, sizeof(newfd)); + if(newfd > -1) { + send_command(fdret_sock, cmd); + pthread_mutex_unlock(&lock); + errno = ERR_OK; // OK + return newfd; + } + else { // Try to read retval+errno since we RXed a bad fd + dwr("Error, service sent bad fd.\n"); + err = get_retval(); + pthread_mutex_unlock(&lock); + return err; + } + } + else { + dwr("Error while receiving new FD.\n"); + err = get_retval(); + pthread_mutex_unlock(&lock); + return err; + } +#endif +} + +/*------------------------------------------------------------------------------ +---------------------------------- connect() ----------------------------------- +------------------------------------------------------------------------------*/ + +/* int __fd, const struct sockaddr * __addr, socklen_t __len + connect() intercept function */ +int connect(CONNECT_SIG) +{ + struct sockaddr_in *connaddr; + connaddr = (struct sockaddr_in *) __addr; + +#ifdef CHECKS + /* Check that this is a valid fd */ + if(fcntl(__fd, F_GETFD) < 0) { + return -1; + errno = EBADF; + } + /* Check that it is a socket */ + int sock_type; + socklen_t sock_type_len = sizeof(sock_type); + if(getsockopt(__fd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { + errno = ENOTSOCK; + return -1; + } + /* Check family */ + if (connaddr->sin_family < 0 || connaddr->sin_family >= NPROTO){ + errno = EAFNOSUPPORT; + return -1; + } + /* FIXME: Check that address is in user space, return EFAULT ? */ +#endif + +#ifdef DUMMY + dwr("connect(%d)\n", __fd); + return realconnect(__fd, __addr, __len); + +#else + /* make sure we don't touch any standard outputs */ + if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO){ + if (realconnect == NULL) { + dwr("Unresolved symbol: connect(). Library is exiting.\n"); + exit(-1); + } + return(realconnect(__fd, __addr, __len)); + } + + if(__addr != NULL && (connaddr->sin_family == AF_LOCAL + || connaddr->sin_family == PF_NETLINK + || connaddr->sin_family == AF_NETLINK + || connaddr->sin_family == AF_UNIX)) { + int err = realconnect(__fd, __addr, __len); + return err; + } + + /* assemble and route command */ + int err; + char cmd[BUF_SZ]; + memset(cmd, '\0', BUF_SZ); + struct connect_st rpc_st; + rpc_st.__tid = syscall(SYS_gettid); + rpc_st.__fd = __fd; + memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr)); + memcpy(&rpc_st.__len, &__len, sizeof(socklen_t)); + cmd[0] = RPC_CONNECT; + memcpy(&cmd[1], &rpc_st, sizeof(struct connect_st)); + pthread_mutex_lock(&lock); + send_command(fdret_sock, cmd); + err = get_retval(); + pthread_mutex_unlock(&lock); + return err; +#endif +} + +/*------------------------------------------------------------------------------ +---------------------------------- select() ------------------------------------ +------------------------------------------------------------------------------*/ + +/* int n, fd_set *readfds, fd_set *writefds, +fd_set *exceptfds, struct timeval *timeout */ +int select(SELECT_SIG) +{ +#ifdef DUMMY + dwr("select(n=%d, , , , )\n", n); + return realselect(n, readfds, writefds, exceptfds, timeout); + +#else + return realselect(n, readfds, writefds, exceptfds, timeout); +#endif +} + +/*------------------------------------------------------------------------------ +----------------------------------- poll() ------------------------------------- +------------------------------------------------------------------------------*/ + +/* struct pollfd *__fds, nfds_t __nfds, int __timeout */ +int poll(POLL_SIG) +{ +#ifdef DUMMY + dwr("poll(, nfds=%d, timeout=%d)\n", __fds, __timeout); + return realpoll(__fds, __nfds, __timeout); + +#else + return realpoll(__fds, __nfds, __timeout); +#endif +} + +/*------------------------------------------------------------------------------ +------------------------------------ bind() ------------------------------------ +------------------------------------------------------------------------------*/ + +/* int sockfd, const struct sockaddr *addr, socklen_t addrlen + bind() intercept function */ +int bind(BIND_SIG) +{ +#ifdef CHECKS + /* Check that this is a valid fd */ + if(fcntl(sockfd, F_GETFD) < 0) { + return -1; + errno = EBADF; + } + /* Check that it is a socket */ + int sock_type = -1; + socklen_t sock_type_len = sizeof(sock_type); + if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { + errno = ENOTSOCK; + return -1; + } +#endif + + int err; +#ifdef DUMMY + dwr("bind(%d)\n", sockfd); + return realbind(sockfd, addr, addrlen); +#else + /* make sure we don't touch any standard outputs */ + if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO) + return(realbind(sockfd, addr, addrlen)); + + /* If local, just use normal syscall */ + struct sockaddr_in *connaddr; + connaddr = (struct sockaddr_in *) addr; + + if (addr != NULL && (connaddr->sin_family == AF_LOCAL + || connaddr->sin_family == PF_NETLINK + || connaddr->sin_family == AF_NETLINK + || connaddr->sin_family == AF_UNIX)) + { + if(realbind == NULL) { + dwr("Unresolved symbol: bind(). Library is exiting.\n"); + exit(-1); + } + return(realbind(sockfd, addr, addrlen)); + } + /* Assemble and route command */ + char cmd[BUF_SZ]; + struct bind_st rpc_st; + rpc_st.sockfd = sockfd; + rpc_st.__tid = syscall(SYS_gettid); + memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr)); + memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t)); + cmd[0]=RPC_BIND; + memcpy(&cmd[1], &rpc_st, sizeof(struct bind_st)); + pthread_mutex_lock(&lock); + send_command(fdret_sock, cmd); + err = get_retval(); + pthread_mutex_unlock(&lock); + errno = ERR_OK; + return err; +#endif +} + + +/*------------------------------------------------------------------------------ +----------------------------------- accept4() ---------------------------------- +------------------------------------------------------------------------------*/ + + +/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */ +int accept4(ACCEPT4_SIG) +{ +#ifdef CHECKS + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) + return -EINVAL; +#endif +#ifdef DUMMY + dwr("accept4(%d)\n", sockfd); + return accept(sockfd, addr, addrlen); +#else + return accept(sockfd, addr, addrlen); +#endif +} + + +/*------------------------------------------------------------------------------ +----------------------------------- accept() ----------------------------------- +------------------------------------------------------------------------------*/ + +/* int sockfd struct sockaddr *addr, socklen_t *addrlen + accept() intercept function */ +int accept(ACCEPT_SIG) +{ +#ifdef CHECKS + /* Check that this is a valid fd */ + if(fcntl(sockfd, F_GETFD) < 0) { + return -1; + errno = EBADF; + } + /* Check that it is a socket */ + int sock_type; + socklen_t sock_type_len = sizeof(sock_type); + if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { + errno = ENOTSOCK; + return -1; + } + /* Check that this socket supports accept() */ + if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) { + errno = EOPNOTSUPP; + return -1; + } + /* Check that we haven't hit the soft-limit file descriptors allowed */ + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + if(sockfd >= rl.rlim_cur){ + errno = EMFILE; + return -1; + } +#endif + +#ifdef DUMMY + return realaccept(sockfd, addr, addrlen); +#else + /* make sure we don't touch any standard outputs */ + if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO) + return(realaccept(sockfd, addr, addrlen)); + + addr->sa_family = AF_INET; + /* TODO: also get address info */ + + char cmd[BUF_SZ]; + if(realaccept == NULL) { + dwr( "Unresolved symbol: accept()\n"); + return -1; + } + + char gmybuf[16], c[1]; + int new_conn_socket, n = read(sockfd, c, sizeof(c)); + if(n > 0) + { + ssize_t size = sock_fd_read(fdret_sock, gmybuf, sizeof(gmybuf), &new_conn_socket); + if(size > 0) { + /* Send our local-fd number back to service so it can complete its mapping table */ + memset(cmd, '\0', BUF_SZ); + cmd[0] = RPC_FD_MAP_COMPLETION; + memcpy(&cmd[1], &new_conn_socket, sizeof(new_conn_socket)); + pthread_mutex_lock(&lock); + int n_write = write(fdret_sock, cmd, BUF_SZ); + if(n_write < 0) { + dwr("Error sending perceived FD to service.\n"); + errno = ECONNABORTED; + return -1; + } + pthread_mutex_unlock(&lock); + errno = ERR_OK; + return new_conn_socket; // OK + } + else { + dwr("Error receiving new FD from service.\n"); + errno = ECONNABORTED; + return -1; + } + } + dwr("Error reading signal byte from service.\n"); + //errno = EWOULDBLOCK; + errno = ECONNABORTED; + return -1; +#endif +} + + +/*------------------------------------------------------------------------------ +------------------------------------- listen()---------------------------------- +------------------------------------------------------------------------------*/ + +/* int sockfd, int backlog + listen() intercept function */ +int listen(LISTEN_SIG) +{ + #ifdef CHECKS + /* Check that this is a valid fd */ + if(fcntl(sockfd, F_GETFD) < 0) { + return -1; + errno = EBADF; + } + /* Check that it is a socket */ + int sock_type; + socklen_t sock_type_len = sizeof(sock_type); + if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { + errno = ENOTSOCK; + return -1; + } + /* Check that this socket supports accept() */ + if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) { + errno = EOPNOTSUPP; + return -1; + } + #endif + + int err; + +#ifdef DUMMY + dwr("listen(%d)\n", sockfd); + return reallisten(sockfd, backlog); +#else + /* make sure we don't touch any standard outputs */ + if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO) + return(reallisten(sockfd, backlog)); + + char cmd[BUF_SZ]; + dwr("listen(%d)\n", sockfd); + /* Assemble and route command */ + memset(cmd, '\0', BUF_SZ); + struct listen_st rpc_st; + rpc_st.sockfd = sockfd; + rpc_st.backlog = backlog; + rpc_st.__tid = syscall(SYS_gettid); + cmd[0] = RPC_LISTEN; + memcpy(&cmd[1], &rpc_st, sizeof(struct listen_st)); + pthread_mutex_lock(&lock); + send_command(fdret_sock, cmd); + err = get_retval(); + pthread_mutex_unlock(&lock); + errno = ERR_OK; + return err; +#endif +} diff --git a/netcon/sendfd.c b/netcon/Sendfd.c similarity index 100% rename from netcon/sendfd.c rename to netcon/Sendfd.c diff --git a/netcon/sendfd.h b/netcon/Sendfd.h similarity index 100% rename from netcon/sendfd.h rename to netcon/Sendfd.h diff --git a/netcon/intercept.h b/netcon/intercept.h deleted file mode 100755 index f190e2161..000000000 --- a/netcon/intercept.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 3 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, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - - -#ifndef _HARNESS_H -#define _HARNESS_H 1 - -#include - - -/* Userland RPC codes */ -#define RPC_UNDEFINED 0 -#define RPC_CONNECT 1 -#define RPC_CONNECT_SOCKARG 2 -#define RPC_SELECT 3 -#define RPC_POLL 4 -#define RPC_CLOSE 5 -#define RPC_READ 6 -#define RPC_WRITE 7 -#define RPC_BIND 8 -#define RPC_ACCEPT 9 -#define RPC_LISTEN 10 -#define RPC_SOCKET 11 -#define RPC_SHUTDOWN 12 - -/* Administration RPC codes */ -#define RPC_FD_MAP_COMPLETION 20 // Give the service the value we "see" for the new buffer fd -#define RPC_RETVAL 21 // not RPC per se, but something we should codify -#define RPC_KILL_INTERCEPT 22 // Tells the service we need to shut down all connections - -/* Connection statuses */ -#define UNSTARTED 0 -#define CONNECTING 1 -#define CONNECTED 2 -#define SENDING 3 -#define RECEIVING 4 -#define SENTV4REQ 5 -#define GOTV4REQ 6 -#define SENTV5METHOD 7 -#define GOTV5METHOD 8 -#define SENTV5AUTH 9 -#define GOTV5AUTH 10 -#define SENTV5CONNECT 11 -#define GOTV5CONNECT 12 -#define DONE 13 -#define FAILED 14 - -/* Flags to indicate what events a - socket was select()ed for */ -#define READ (POLLIN|POLLRDNORM) -#define WRITE (POLLOUT|POLLWRNORM|POLLWRBAND) -#define EXCEPT (POLLRDBAND|POLLPRI) -#define READWRITE (READ|WRITE) -#define READWRITEEXCEPT (READ|WRITE|EXCEPT) - - -/* for AF_UNIX sockets */ -#define MAX_PATH_NAME_SIZE 64 - -// bind -#define BIND_SIG int sockfd, const struct sockaddr *addr, socklen_t addrlen -struct bind_st -{ - int sockfd; - struct sockaddr addr; - socklen_t addrlen; - int __tid; -}; - - -// connect -#define CONNECT_SIG int __fd, const struct sockaddr * __addr, socklen_t __len -struct connect_st -{ - int __fd; - struct sockaddr __addr; - socklen_t __len; - int __tid; -}; - - -// close -#define CLOSE_SIG int fd -struct close_st -{ - int fd; -}; - - -// read -#define DEFAULT_READ_BUFFER_SIZE 1024 * 63 -// read buffer sizes (on test machine) min: 4096 default: 87380 max:6147872 -#define READ_SIG int __fd, void *__buf, size_t __nbytes -struct read_st -{ - int fd; - size_t count; - unsigned char buf[DEFAULT_READ_BUFFER_SIZE]; -}; - - - -#define DEFAULT_WRITE_BUFFER_SIZE 1024 * 63 -// write buffer sizes (on test machine) min: 4096 default: 16384 max:4194304 -#define WRITE_SIG int __fd, const void *__buf, size_t __n -struct write_st -{ - int fd; - size_t count; - char buf[DEFAULT_WRITE_BUFFER_SIZE]; -}; - - -#define LISTEN_SIG int sockfd, int backlog -struct listen_st -{ - int sockfd; - int backlog; - int __tid; -}; - - - -#define SOCKET_SIG int socket_family, int socket_type, int protocol -struct socket_st -{ - int socket_family; - int socket_type; - int protocol; - int __tid; -}; - - -#define ACCEPT4_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags - - -#define ACCEPT_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen -struct accept_st -{ - int sockfd; - struct sockaddr addr; - socklen_t addrlen; - int __tid; -}; - - -#define SHUTDOWN_SIG int socket, int how -struct shutdown_st -{ - int socket; - int how; -}; - -#define CONNECT_SOCKARG struct sockaddr * -#define SELECT_SIG int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout -#define POLL_SIG struct pollfd *__fds, nfds_t __nfds, int __timeout -#define IOCTL_SIG int __fd, unsigned long int __request, ... -#define FCNTL_SIG int __fd, int __cmd, ... -#define CLONE_SIG int (*fn) (void *arg), void *child_stack, int flags, void *arg -#define DAEMON_SIG int nochdir, int noclose - - -#define SETSOCKOPT_SIG int socket, int level, int option_name, const void *option_value, socklen_t option_len -#define GETSOCKOPT_SIG int sockfd, int level, int optname, void *optval, socklen_t *optlen - - -/* LWIP error beautification */ -const char *lwiperror(int n) -{ - switch(n) - { - case 0: - return "ERR_OK"; - case -1: - return "ERR_MEM (out of memory)"; - case -2: - return "ERR_BUF (buffer error)"; - case -3: - return "ERR_TIMEOUT (timeout)"; - case -4: - return "ERR_RTE (routing problem)"; - case -5: - return "ERR_INPROGRESS (operation in progress)"; - case -6: - return "ERR_VAL (illegal value)"; - case -7: - return "ERR_WOULDBLOCK (operation would block)"; - case -8: - return "ERR_USE (address in use)"; - case -9: - return "ERR_ISCONN (already connected)"; - case -10: - return "Fatal: ERR_ABRT (connection aborted)"; - case -11: - return "Fatal: ERR_RST (connection reset)"; - case -12: - return "Fatal: ERR_CLSD (connection closed)"; - case -13: - return "Fatal: ERR_CONN (not connected)"; - case -14: - return "Fatal: ERR_ARG (illegal argument)"; - case -15: - return "Fatal: ERR_IF (low level netif error)"; - default: - return "UNKNOWN_RET_VAL"; - } -} - -#endif diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0 index dc8ca9dc2f89693a16dddcec8d6b0f5a9d8f24cf..192e9b977e3e12af48cc567f22757054e2f75a8c 100755 GIT binary patch literal 53568 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 BDvkgE literal 53768 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