diff --git a/src/shims/windows/msg.cc b/src/shims/windows/msg.cc index 06caebb01..43d6937bb 100644 --- a/src/shims/windows/msg.cc +++ b/src/shims/windows/msg.cc @@ -1,14 +1,5 @@ -#include -#include #include -#include // include before other socket headers on Windows - -#include -#include - -#pragma comment(lib, "IPHlpAPI.lib") - int socketpair(int domain, int type, int protocol, SOCKET sv[2]) { if ((domain != AF_UNIX && domain != AF_INET) || type != SOCK_STREAM) { return -1; @@ -19,141 +10,3 @@ int socketpair(int domain, int type, int protocol, SOCKET sv[2]) { sv[1] = sockets[1]; return r; } - -static DWORD getsockpid(SOCKET client) { - /* http://stackoverflow.com/a/25431340 */ - DWORD pid = 0; - - struct sockaddr_in Server = {0}; - int ServerSize = sizeof(Server); - - struct sockaddr_in Client = {0}; - int ClientSize = sizeof(Client); - - if ((getsockname(client, (struct sockaddr *)&Server, &ServerSize) == 0) && - (getpeername(client, (struct sockaddr *)&Client, &ClientSize) == 0)) { - struct _MIB_TCPTABLE2 *TcpTable = NULL; - ULONG TcpTableSize = 0; - ULONG result; - do { - result = GetTcpTable2(TcpTable, &TcpTableSize, TRUE); - if (result != ERROR_INSUFFICIENT_BUFFER) { - break; - } - free(TcpTable); - TcpTable = (struct _MIB_TCPTABLE2 *)malloc(TcpTableSize); - } while (TcpTable != NULL); - - if (result == NO_ERROR) { - for (DWORD dw = 0; dw < TcpTable->dwNumEntries; ++dw) { - struct _MIB_TCPROW2 *row = &(TcpTable->table[dw]); - if ((row->dwState == 5 /* MIB_TCP_STATE_ESTAB */) && - (row->dwLocalAddr == Client.sin_addr.s_addr) && - ((row->dwLocalPort & 0xFFFF) == Client.sin_port) && - (row->dwRemoteAddr == Server.sin_addr.s_addr) && - ((row->dwRemotePort & 0xFFFF) == Server.sin_port)) { - pid = row->dwOwningPid; - break; - } - } - } - - free(TcpTable); - } - - return pid; -} - -ssize_t sendmsg(SOCKET sock, struct msghdr *msg, int flags) { - ssize_t result = -1; - struct cmsghdr *header = CMSG_FIRSTHDR(msg); - if (header->cmsg_level == SOL_SOCKET && header->cmsg_type == SCM_RIGHTS) { - /* We're trying to send over a handle of some kind. - * We have to look up which process we're communicating with, - * open a handle to it, and then duplicate our handle into it. - * However, the first two steps cannot be done atomically. - * Therefore, this code HAS A RACE CONDITIONS and is therefore NOT SECURE. - * In the absense of a malicious actor, though, it is exceedingly unlikely - * that the child process closes AND that its process ID is reassigned - * to another existing process. - */ - SOCKET *const pfd = (SOCKET *)CMSG_DATA(header); - WSAPROTOCOL_INFO protocol_info = {0}; - /* assume socket if it's a pipe, until proven otherwise */ - BOOL is_socket = GetFileType((HANDLE)(SOCKET)(*pfd)) == FILE_TYPE_PIPE; - DWORD const target_pid = getsockpid(sock); - HANDLE target_process = NULL; - if (target_pid) { - if (is_socket) { - result = WSADuplicateSocket(*pfd, target_pid, &protocol_info); - if (result == -1 && WSAGetLastError() == WSAENOTSOCK) { - is_socket = FALSE; - } - } - if (!is_socket) { - /* This is a regular handle... fit it into the same struct */ - target_process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, target_pid); - if (target_process) { - if (DuplicateHandle(GetCurrentProcess(), (HANDLE)(intptr_t)*pfd, target_process, - (HANDLE *)&protocol_info, 0, TRUE, DUPLICATE_SAME_ACCESS)) { - result = 0; - } - } - } - } - if (result == 0) { - DWORD const nbufs = msg->dwBufferCount + 1; - WSABUF *const bufs = (WSABUF *)_alloca(sizeof(*msg->lpBuffers) * nbufs); - bufs[0].buf = (char *)&protocol_info; - bufs[0].len = sizeof(protocol_info); - memcpy(&bufs[1], msg->lpBuffers, msg->dwBufferCount * sizeof(*msg->lpBuffers)); - DWORD nb; - result = WSASend(sock, bufs, nbufs, &nb, flags, NULL, NULL) == 0 - ? (ssize_t)(nb - sizeof(protocol_info)) - : -1; - } - if (result == -1 && target_process && !is_socket) { - /* we failed to send the handle, and it needs cleaning up! */ - HANDLE duplicated_back = NULL; - if (DuplicateHandle(target_process, *(HANDLE *)&protocol_info, GetCurrentProcess(), - &duplicated_back, 0, FALSE, DUPLICATE_CLOSE_SOURCE)) { - CloseHandle(duplicated_back); - } - } - if (target_process) { - CloseHandle(target_process); - } - } - return result; -} - -ssize_t recvmsg(SOCKET sock, struct msghdr *msg, int flags) { - int result = -1; - struct cmsghdr *header = CMSG_FIRSTHDR(msg); - if (msg->msg_controllen && flags == 0 /* We can't send flags on Windows... */) { - WSAPROTOCOL_INFO protocol_info = {0}; - DWORD const nbufs = msg->dwBufferCount + 1; - WSABUF *const bufs = (WSABUF *)_alloca(sizeof(*msg->lpBuffers) * nbufs); - bufs[0].buf = (char *)&protocol_info; - bufs[0].len = sizeof(protocol_info); - memcpy(&bufs[1], msg->lpBuffers, msg->dwBufferCount * sizeof(*msg->lpBuffers)); - DWORD nb; - DWORD dwFlags = flags; - result = WSARecv(sock, bufs, nbufs, &nb, &dwFlags, NULL, NULL) == 0 - ? (ssize_t)(nb - sizeof(protocol_info)) - : -1; - if (result != -1) { - SOCKET *const pfd = (SOCKET *)CMSG_DATA(header); - if (protocol_info.iSocketType == 0 && protocol_info.iProtocol == 0) { - *pfd = *(SOCKET *)&protocol_info; - } else { - *pfd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, - &protocol_info, 0, WSA_FLAG_OVERLAPPED); - } - header->cmsg_len = CMSG_LEN(sizeof(*pfd)); - header->cmsg_level = SOL_SOCKET; - header->cmsg_type = SCM_RIGHTS; - } - } - return result; -} diff --git a/src/shims/windows/sys/socket.h b/src/shims/windows/sys/socket.h index d6a44722d..1d500f49d 100644 --- a/src/shims/windows/sys/socket.h +++ b/src/shims/windows/sys/socket.h @@ -1,36 +1,10 @@ #ifndef SOCKET_H #define SOCKET_H -typedef unsigned short sa_family_t; - #include #include // ssize_t -#define cmsghdr _WSACMSGHDR -#undef CMSG_DATA -#define CMSG_DATA WSA_CMSG_DATA -#define CMSG_SPACE WSA_CMSG_SPACE -#define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR -#define CMSG_LEN WSA_CMSG_LEN -#define CMSG_NXTHDR WSA_CMSG_NXTHDR - -#define SCM_RIGHTS 1 - -#define iovec _WSABUF -#define iov_base buf -#define iov_len len -#define msghdr _WSAMSG -#define msg_name name -#define msg_namelen namelen -#define msg_iov lpBuffers -#define msg_iovlen dwBufferCount -#define msg_control Control.buf -#define msg_controllen Control.len -#define msg_flags dwFlags - int dumb_socketpair(SOCKET socks[2]); -ssize_t sendmsg(SOCKET sockfd, struct msghdr *msg, int flags); -ssize_t recvmsg(SOCKET sockfd, struct msghdr *msg, int flags); int socketpair(int domain, int type, int protocol, SOCKET sv[2]); #endif /* SOCKET_H */ diff --git a/src/shims/windows/sys/time.cc b/src/shims/windows/sys/time.cc deleted file mode 100644 index 2c6bfdd0e..000000000 --- a/src/shims/windows/sys/time.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -#ifdef timezone -#pragma push_macro("timezone") // Work around https://bugs.python.org/issue34657 -#undef timezone -#define timezone timezone -#endif - -int gettimeofday(struct timeval *tv, struct timezone *tz) { - // Free implementation from: https://stackoverflow.com/a/26085827 - SYSTEMTIME systime; - GetSystemTime(&systime); - FILETIME filetime; - SystemTimeToFileTime(&systime, &filetime); - unsigned long long const epoch_time_offset = 11644473600ULL * 60 * 60 * 24, - time_high = filetime.dwHighDateTime, - time = - filetime.dwLowDateTime + - (time_high << (CHAR_BIT * sizeof(filetime.dwLowDateTime))); - tv->tv_sec = static_cast((time - epoch_time_offset) / 10000000); - tv->tv_usec = static_cast(systime.wMilliseconds * 1000); - return 0; -} - -#ifdef timezone -#pragma pop_macro("timezone") -#endif diff --git a/src/shims/windows/sys/time.h b/src/shims/windows/sys/time.h deleted file mode 100644 index 2b8eb9619..000000000 --- a/src/shims/windows/sys/time.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TIME_H -#define TIME_H - -#ifdef timezone -#pragma push_macro("timezone") // Work around https://bugs.python.org/issue34657 -#undef timezone -#define timezone timezone -#endif - -#include // clients require timeval definition - -struct timeval; -struct timezone; - -#ifdef __cplusplus -extern "C" -#endif - int - gettimeofday(struct timeval *tv, struct timezone *tz); - -#ifdef timezone -#pragma pop_macro("timezone") -#endif - -#endif /* TIME_H */