From a6dc2a74303bad0344e8d05da2588863f8120219 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Wed, 6 Mar 2013 15:48:36 +0100 Subject: [PATCH] Retrieve pid and sid from tcp connection peer and provide them through _dbus_read_credentials_socket(). --- cmake/dbus/CMakeLists.txt | 4 +- dbus/dbus-sysdeps-win.c | 121 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 111 insertions(+), 14 deletions(-) diff --git a/cmake/dbus/CMakeLists.txt b/cmake/dbus/CMakeLists.txt index 3993d1d..1db8c26 100644 --- a/cmake/dbus/CMakeLists.txt +++ b/cmake/dbus/CMakeLists.txt @@ -266,7 +266,7 @@ if(WIN32) if(WINCE) target_link_libraries(dbus-1 ws2) else(WINCE) - target_link_libraries(dbus-1 ws2_32 advapi32 netapi32) + target_link_libraries(dbus-1 ws2_32 advapi32 netapi32 iphlpapi) endif(WINCE) else(WIN32) target_link_libraries(dbus-1 ${CMAKE_THREAD_LIBS_INIT} rt) @@ -291,7 +291,7 @@ if(WIN32) if(WINCE) target_link_libraries(dbus-internal ws2) else(WINCE) - target_link_libraries(dbus-internal ws2_32 advapi32 netapi32) + target_link_libraries(dbus-internal ws2_32 advapi32 netapi32 iphlpapi) endif(WINCE) else(WIN32) target_link_libraries(dbus-internal ${CMAKE_THREAD_LIBS_INIT} rt) diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 5a2fb20..7215e26 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -6,7 +6,7 @@ * Copyright (C) 2005 Novell, Inc. * Copyright (C) 2006 Peter Kümmel * Copyright (C) 2006 Christian Ehrlicher - * Copyright (C) 2006-2010 Ralf Habacker + * Copyright (C) 2006-2013 Ralf Habacker * * Licensed under the Academic Free License version 2.1 * @@ -52,12 +52,16 @@ #include "dbus-credentials.h" #include +#include #include #include +#include /* Declarations missing in mingw's headers */ extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid); extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid); +extern ULONG WINAPI GetTcpTable2(PMIB_TCPTABLE2 TcpTable, PULONG SizePointer, BOOL Order); +extern PCSTR WINAPI inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize); #include @@ -102,7 +106,78 @@ _dbus_win_set_errno (int err) errno = err; #endif } +/** + * @brief return peer process id from tcp handle for localhost connections + * @param handle tcp socket descriptor + * @return process id or 0 in case it could not be fetched + */ +int get_peer_pid_from_tcp_handle(int handle) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof addr; + int peer_port; + char peer_ipstr[INET6_ADDRSTRLEN]; + + DWORD result; + DWORD size; + MIB_TCPTABLE2 *tcpTable; + int i; + + getpeername(handle, (struct sockaddr*)&addr, &len); + + /* deal with both IPv4 and IPv6: */ + if (addr.ss_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + peer_port = ntohs(s->sin_port); + inet_ntop(AF_INET, &s->sin_addr, peer_ipstr, sizeof(peer_ipstr)); + } else { /* AF_INET6 */ + struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; + peer_port = ntohs(s->sin6_port); + inet_ntop(AF_INET6, &s->sin6_addr, peer_ipstr, sizeof(peer_ipstr)); + } + + /* check for localhost */ + if (strcmp(peer_ipstr,"127.0.0.1") != 0) + { + _dbus_verbose("could not fetch process id from remote process"); + return 0; + } + + if (peer_port == 0) + { + _dbus_verbose("Error not been able to fetch tcp peer port from connection"); + return 0; + } + + if ((result = GetTcpTable2(NULL, &size, TRUE)) == ERROR_INSUFFICIENT_BUFFER) + { + tcpTable = (MIB_TCPTABLE2 *) dbus_malloc(size); + if (tcpTable == NULL) + { + _dbus_verbose("Error allocating memory "); + return 0; + } + } + + if ((result = GetTcpTable2(tcpTable, &size, TRUE)) != NO_ERROR) + { + _dbus_verbose("Error fetching tcp table"); + dbus_free(tcpTable); + return 0; + } + + result = 0; + for (i = 0; i < (int) tcpTable->dwNumEntries; i++) + { + MIB_TCPROW2 *p = &tcpTable->table[i]; + int local_port = ntohs(p->dwLocalPort); + if (p->dwState == MIB_TCP_STATE_ESTAB && local_port == peer_port) + result = p->dwOwningPid; + } + dbus_free(tcpTable); + return result; +} /* Convert GetLastError() to a dbus error. */ const char* @@ -738,22 +813,23 @@ _dbus_pid_for_log (void) return _dbus_getpid (); } - #ifndef DBUS_WINCE /** Gets our SID - * @param points to sid buffer, need to be freed with LocalFree() + * @param sid points to sid buffer, need to be freed with LocalFree() + * @param process_id the process id for which the sid should be returned * @returns process sid */ static dbus_bool_t -_dbus_getsid(char **sid) +_dbus_getsid(char **sid, int process_id) { HANDLE process_token = INVALID_HANDLE_VALUE; TOKEN_USER *token_user = NULL; DWORD n; PSID psid; int retval = FALSE; - - if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token)) + HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id); + + if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token)) { _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ()); goto failed; @@ -781,6 +857,7 @@ _dbus_getsid(char **sid) retval = TRUE; failed: + CloseHandle(process_handle); if (process_token != INVALID_HANDLE_VALUE) CloseHandle (process_token); @@ -1683,7 +1760,10 @@ _dbus_read_credentials_socket (int handle, { int bytes_read = 0; DBusString buf; - + char *sid = NULL; + int pid; + int retval = TRUE; + // could fail due too OOM if (_dbus_string_init(&buf)) { @@ -1695,10 +1775,27 @@ _dbus_read_credentials_socket (int handle, _dbus_string_free(&buf); } - _dbus_credentials_add_from_current_process (credentials); - _dbus_verbose("FIXME: get faked credentials from current process"); + pid = get_peer_pid_from_tcp_handle(handle); + _dbus_verbose("client pid %d", pid); + if (pid == 0) + return FALSE; - return TRUE; + _dbus_credentials_add_unix_pid(credentials, pid); + + if (_dbus_getsid(&sid, pid)) + { + if (!_dbus_credentials_add_windows_sid(credentials,sid)) + goto failed; + } + retval = TRUE; + goto end; + +failed: + retval = FALSE; +end: + if (sid) + LocalFree(sid); + return retval; } /** @@ -1792,7 +1889,7 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials) dbus_bool_t retval = FALSE; char *sid = NULL; - if (!_dbus_getsid(&sid)) + if (!_dbus_getsid(&sid,_dbus_getpid())) goto failed; if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) @@ -1830,7 +1927,7 @@ _dbus_append_user_from_current_process (DBusString *str) dbus_bool_t retval = FALSE; char *sid = NULL; - if (!_dbus_getsid(&sid)) + if (!_dbus_getsid(&sid, _dbus_getpid())) return FALSE; retval = _dbus_string_append (str,sid); -- 1.7.4.msysgit.0