[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r17083: {torvm} Initial import of code cleanup and various bug fixes includi (in torvm/trunk/build/win32: . src/torvm-w32)
Author: coderman
Date: 2008-10-13 23:54:28 -0400 (Mon, 13 Oct 2008)
New Revision: 17083
Added:
torvm/trunk/build/win32/src/torvm-w32/apicommon.c
torvm/trunk/build/win32/src/torvm-w32/apicommon.h
torvm/trunk/build/win32/src/torvm-w32/creds.c
torvm/trunk/build/win32/src/torvm-w32/creds.h
torvm/trunk/build/win32/src/torvm-w32/registry.c
torvm/trunk/build/win32/src/torvm-w32/registry.h
torvm/trunk/build/win32/src/torvm-w32/thrpool.c
torvm/trunk/build/win32/src/torvm-w32/thrpool.h
torvm/trunk/build/win32/src/torvm-w32/torvm.h
torvm/trunk/build/win32/src/torvm-w32/vmconfig.h.in
Modified:
torvm/trunk/build/win32/Makefile
torvm/trunk/build/win32/src/torvm-w32/Makefile
torvm/trunk/build/win32/src/torvm-w32/torvm.c
Log:
Initial import of code cleanup and various bug fixes including bridged DHCP connections
Modified: torvm/trunk/build/win32/Makefile
===================================================================
--- torvm/trunk/build/win32/Makefile 2008-10-14 02:14:28 UTC (rev 17082)
+++ torvm/trunk/build/win32/Makefile 2008-10-14 03:54:28 UTC (rev 17083)
@@ -238,7 +238,7 @@
ifeq (,$(W32AUTO_BUILD_CMD))
W32BLD=echo "Win32 build ISO image ready. Please load the ISO into a Windows systems to start the build."
else
- W32BLD=$(W32AUTO_BUILD_CMD);true
+ W32BLD=now=`date`;echo "Starting win32 automated build at $$now";$(W32AUTO_BUILD_CMD);now=`date`;echo "Build done at $$now";true
endif
runinstall: buildiso
Modified: torvm/trunk/build/win32/src/torvm-w32/Makefile
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/Makefile 2008-10-14 02:14:28 UTC (rev 17082)
+++ torvm/trunk/build/win32/src/torvm-w32/Makefile 2008-10-14 03:54:28 UTC (rev 17083)
@@ -10,17 +10,32 @@
all: torvm$(EXESUF)
-OBJS+=torvm.o torvmrc.o
+OBJS+=torvm.o torvmrc.o apicommon.o creds.o extension.o thrpool.o
-torvm$(EXESUF): $(OBJS)
+torvm$(EXESUF): $(OBJS) vmconfig.h
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
-torvm.o: torvm.c
+torvm.o: torvm.c vmconfig.h
$(CC) $(CPPFLAGS) -c -o $@ $<
torvmrc.o: torvm.rc
windres torvm.rc torvmrc.o
+apicommon.o: apicommon.c
+ $(CC) $(CPPFLAGS) -c -o $@ $<
+
+creds.o: creds.c
+ $(CC) $(CPPFLAGS) -c -o $@ $<
+
+extension.o: extension.c
+ $(CC) $(CPPFLAGS) -c -o $@ $<
+
+thrpool.o: thrpool.c
+ $(CC) $(CPPFLAGS) -c -o $@ $<
+
+vmconfig.h: vmconfig.h.in
+ @if [ ! -f $@ ]; then cp $< $@; else touch $@; fi
+
clean:
rm -f *.o *.d torvm$(EXESUF)
Added: torvm/trunk/build/win32/src/torvm-w32/apicommon.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/apicommon.c (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/apicommon.c 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,285 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+
+#include "apicommon.h"
+
+/* jump hoops to read ethernet adapter MAC address.
+ */
+#define _NDIS_CONTROL_CODE(request,method) \
+ CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS)
+#define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE( 0, METHOD_OUT_DIRECT )
+
+/* these are not yet used, but we may need them to interact with network devices
+ * directly to enable/disable, change MAC, etc.
+ */
+#define IOCTL_NDIS_QUERY_ALL_STATS _NDIS_CONTROL_CODE( 1, METHOD_OUT_DIRECT )
+#define IOCTL_NDIS_ADD_DEVICE _NDIS_CONTROL_CODE( 2, METHOD_BUFFERED )
+#define IOCTL_NDIS_DELETE_DEVICE _NDIS_CONTROL_CODE( 3, METHOD_BUFFERED )
+#define IOCTL_NDIS_TRANSLATE_NAME _NDIS_CONTROL_CODE( 4, METHOD_BUFFERED )
+#define IOCTL_NDIS_ADD_TDI_DEVICE _NDIS_CONTROL_CODE( 5, METHOD_BUFFERED )
+#define IOCTL_NDIS_NOTIFY_PROTOCOL _NDIS_CONTROL_CODE( 6, METHOD_BUFFERED )
+#define IOCTL_NDIS_GET_LOG_DATA _NDIS_CONTROL_CODE( 7, METHOD_OUT_DIRECT )
+
+/* OID's we need to query */
+#define OID_802_3_PERMANENT_ADDRESS 0x01010101
+#define OID_802_3_CURRENT_ADDRESS 0x01010102
+#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
+/* probably will never need these, but just in case ... */
+#define OID_GEN_MEDIA_IN_USE 0x00010104
+#define OID_WAN_PERMANENT_ADDRESS 0x04010101
+#define OID_WAN_CURRENT_ADDRESS 0x04010102
+#define OID_WW_GEN_PERMANENT_ADDRESS 0x0901010B
+#define OID_WW_GEN_CURRENT_ADDRESS 0x0901010C
+
+BOOL getmypath (TCHAR **path)
+{
+ TCHAR mypath[MAX_PATH];
+ if (! GetModuleFileName(NULL,
+ &mypath,
+ sizeof(mypath))) {
+ lerror ("Unable to obtain current program path.");
+ return FALSE;
+ }
+ *path = strdup(mypath);
+}
+
+void bgstartupinfo (STARTUPINFO *si)
+{
+ si->dwXCountChars = 48;
+ si->dwYCountChars = 5;
+ si->lpTitle = "Tor VM Win32";
+ si->dwFillAttribute = BACKGROUND_BLUE | BACKGROUND_INTENSITY;
+ si->wShowWindow = SW_HIDE;
+ si->dwFlags |= STARTF_USECOUNTCHARS | STARTF_USEFILLATTRIBUTE | STARTF_USESHOWWINDOW;
+ return;
+}
+
+BOOL localhnd (HANDLE *hnd)
+{
+ HANDLE orighnd = *hnd;
+ /* dupe handle for no inherit */
+ if (! DuplicateHandle(GetCurrentProcess(),
+ orighnd,
+ GetCurrentProcess(),
+ hnd,
+ 0,
+ FALSE, /* no inherit */
+ DUPLICATE_SAME_ACCESS)) {
+ lerror ("Unable to duplicate handle. Error code: %d", GetLastError());
+ *hnd = orighnd;
+ return FALSE;
+ }
+ /* now that we know the dupe was successful, close the original handle. */
+ CloseHandle (orighnd);
+ return TRUE;
+}
+
+BOOL proclocalhnd (HANDLE srcproc,
+ HANDLE dstproc,
+ HANDLE *hnd)
+{
+ HANDLE orighnd = *hnd;
+ if (! DuplicateHandle(srcproc,
+ orighnd,
+ dstproc,
+ hnd,
+ 0,
+ FALSE, /* no inherit */
+ DUPLICATE_SAME_ACCESS)) {
+ lerror ("Unable to duplicate handle. Error code: %d", GetLastError());
+ *hnd = orighnd;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL getcompguid (TCHAR **guid)
+{
+/* MRP_TEMP this needs dynamic linkage */
+ return FALSE;
+ static const int alen = 64 * sizeof(TCHAR);
+ *guid = (TCHAR *)malloc(alen);
+ if (! *guid)
+ fatal ("Allocation failure in: %s line no: %s with sz: %d", __FILE__ , __LINE__ , alen);
+#if 0
+ if (! GetComputerObjectName(NameUniqueId,
+ *guid,
+ alen)) {
+ lerror ("Unable to obtain computer unique id name. Error code: %d", GetLastError());
+ free (*guid);
+ *guid = NULL;
+ return FALSE;
+ }
+#endif
+ return TRUE;
+}
+
+int getosversion (void) {
+ static int osver = -1;
+
+ /* used cached version info if version has been checked already */
+ if (osver >= 0)
+ return osver;
+
+ osver = OS_UNKNOWN;
+ OSVERSIONINFO info;
+ ZeroMemory(&info, sizeof(OSVERSIONINFO));
+ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&info);
+ if (info.dwMajorVersion == 5) {
+ if (info.dwMinorVersion == 0) {
+ ldebug ("Operating system version is Windows 2000");
+ osver = OS_2000;
+ }
+ else if (info.dwMinorVersion == 1) {
+ ldebug ("Operating system version is Windows XP");
+ osver = OS_XP;
+ }
+ else if (info.dwMinorVersion == 2) {
+ ldebug ("Operating system version is Windows Server 2003");
+ osver = OS_SERVER2003;
+ }
+ }
+ else if (info.dwMajorVersion == 6) {
+ OSVERSIONINFOEX exinfo;
+ ZeroMemory(&exinfo, sizeof(OSVERSIONINFOEX));
+ exinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ GetVersionEx(&exinfo);
+ if (exinfo.wProductType != VER_NT_WORKSTATION) {
+ ldebug ("Operating system version is Windows Vista");
+ osver = OS_VISTA;
+ }
+ else {
+ ldebug ("Operating system version is Windows Server 2008");
+ osver = OS_SERVER2008;
+ }
+ }
+ return osver;
+}
+
+int getosbits (void) {
+ static int osbits = -1;
+
+ if (osbits >= 0)
+ return osbits;
+
+ osbits = 0;
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+ ldebug ("Operating system is running on 64bit architecture.");
+ osbits = 64;
+ }
+ else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
+ ldebug ("Operating system is running on 32bit architecture.");
+ osbits = 32;
+ }
+ else {
+ ldebug ("Operating system is running on UNKNOWN architecture.");
+ }
+ return osbits;
+}
+
+BOOL getmacaddr(const char * devguid,
+ char ** mac)
+{
+ char * devfstr = NULL;
+ unsigned char macbuf[6];
+ BOOL status;
+ HANDLE devfd;
+ DWORD retsz, oidcode;
+ BOOL retval = FALSE;
+
+ *mac = NULL;
+ devfstr = malloc(1024);
+ snprintf (devfstr, 1023, "\\\\.\\%s", devguid);
+ devfd = CreateFile(devfstr,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (devfd == INVALID_HANDLE_VALUE)
+ {
+ lerror ("Unable to open net device handle for path: %s", devfstr);
+ goto cleanup;
+ }
+
+#define MAXMAC 24
+ oidcode = OID_802_3_CURRENT_ADDRESS;
+ status = DeviceIoControl(devfd,
+ IOCTL_NDIS_QUERY_GLOBAL_STATS,
+ &oidcode, sizeof(oidcode),
+ macbuf, sizeof(macbuf),
+ &retsz,
+ (LPOVERLAPPED) NULL);
+ if (retsz == sizeof(macbuf)) {
+ *mac = malloc(MAXMAC);
+ memset(*mac, 0, MAXMAC);
+ snprintf(*mac, MAXMAC-1,
+ "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+ macbuf[0], macbuf[1], macbuf[2], macbuf[3], macbuf[4], macbuf[5]);
+ retval = TRUE;
+ }
+ else {
+ retval = FALSE;
+ }
+
+ cleanup:
+ if (devfd != INVALID_HANDLE_VALUE)
+ CloseHandle(devfd);
+ free(devfstr);
+
+ return retval;
+}
+
+BOOL isconnected(const char * devguid)
+{
+ char * devfstr = NULL;
+ BOOL status;
+ HANDLE devfd;
+ DWORD retsz, oidcode, intfStatus;
+ BOOL retval = FALSE;
+
+ devfstr = malloc(1024);
+ snprintf (devfstr, 1023, "\\\\.\\%s", devguid);
+ devfd = CreateFile(devfstr,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (devfd == INVALID_HANDLE_VALUE)
+ {
+ lerror ("Unable to open net device handle for path: %s", devfstr);
+ goto cleanup;
+ }
+
+ oidcode = OID_GEN_MEDIA_CONNECT_STATUS;
+ status = DeviceIoControl(devfd,
+ IOCTL_NDIS_QUERY_GLOBAL_STATS,
+ &oidcode, sizeof(oidcode),
+ &intfStatus, sizeof(intfStatus),
+ &retsz,
+ (LPOVERLAPPED) NULL);
+ if (status) {
+ ldebug ("Received media connect status %d for device %s.", intfStatus, devguid);
+ retval = (intfStatus == 0) ? TRUE : FALSE;
+ }
+ else {
+ retval = FALSE;
+ }
+
+ cleanup:
+ if (devfd != INVALID_HANDLE_VALUE)
+ CloseHandle(devfd);
+ free(devfstr);
+
+ return retval;
+}
+
+
+
Added: torvm/trunk/build/win32/src/torvm-w32/apicommon.h
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/apicommon.h (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/apicommon.h 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,91 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#ifndef __apicommon_h__
+#define __apicommon_h__
+
+/* enable certain parts of the win32 API for process / system functions
+ * default to win2k.
+ * other versions:
+ * 0x0501 = XP / Server2003
+ * 0x0502 = XP SP2 / Server2003 SP1
+ * 0x0600 = Vista / Server2008
+ */
+#define _WIN32_WINNT 0x0500
+
+#include <windows.h>
+#include <security.h>
+#include <tchar.h>
+#include <winreg.h>
+#include <winioctl.h>
+#include <winerror.h>
+#include <wincrypt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* misc win32 api utility functions
+ */
+BOOL getmypath (TCHAR **path);
+BOOL getprocwd (TCHAR **cwd);
+BOOL setprocwd (const TCHAR *cwd);
+
+/* localize a handle resource to the current process (no inherit)
+ * types of handles supported:
+ * Access token
+ * Change notification
+ * Communications device
+ * Console input
+ * Console screen buffer
+ * Desktop
+ * Event
+ * File
+ * File mapping
+ * Job
+ * Mailslot
+ * Mutex
+ * Pipe
+ * Process
+ * Registry key
+ * Semaphore
+ * Thread
+ * Time
+ * Window station
+ */
+BOOL localhnd (HANDLE *hnd);
+
+/* duplicating files in other processes does not close original */
+BOOL proclocalhnd (HANDLE srcproc,
+ HANDLE dstproc,
+ HANDLE *hnd);
+
+/* get the current Windows OS version. this is needed for things like the network
+ * configuration export and some API calls.
+ */
+#define OS_UNKNOWN 0
+#define OS_SERVER2008 5
+#define OS_VISTA 4
+#define OS_SERVER2003 3
+#define OS_XP 2
+#define OS_2000 1
+
+int getosversion (void);
+int getosbits (void);
+
+BOOL getcompguid (TCHAR **guid);
+void bgstartupinfo (STARTUPINFO *si);
+
+BOOL getmacaddr(const char * devguid,
+ char ** mac);
+BOOL isconnected(const char * devguid);
+
+#endif /* apicommon_h */
Added: torvm/trunk/build/win32/src/torvm-w32/creds.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/creds.c (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/creds.c 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,284 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#include "creds.h"
+
+BOOL setdriversigning (BOOL sigcheck)
+{
+ /* thanks to Stefan 'Sec' Zehl and Blaine Fleming for this snippet.
+ * see http://support.microsoft.com/?kbid=298503 for details on this subversion.
+ * the ideal alternative is to pay the thousands of dollars for a driver signature.
+ */
+#define HP_HASHVALUE HP_HASHVAL
+ HCRYPTPROV cryptoprovider;
+ HCRYPTHASH digest;
+ BYTE data[16];
+ DWORD len;
+ DWORD seed;
+ HKEY rkey;
+ BYTE onoff;
+ char regval[4];
+ int x;
+
+ onoff = sigcheck ? 1 : 0;
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ "System\\WPA\\PnP",
+ 0,
+ KEY_READ,
+ &rkey) != ERROR_SUCCESS){
+ return FALSE;
+ }
+ len = sizeof(seed);
+ if(RegQueryValueEx(rkey,
+ "seed",
+ NULL,
+ NULL,
+ (BYTE*)&seed,
+ &len) != ERROR_SUCCESS){
+ return FALSE;
+ }
+ RegCloseKey(rkey);
+ if (!CryptAcquireContext(&cryptoprovider,
+ NULL,
+ NULL,
+ PROV_RSA_FULL,
+ 0)) {
+ if (!CryptAcquireContext(&cryptoprovider,
+ NULL,
+ NULL,
+ PROV_RSA_FULL,
+ CRYPT_NEWKEYSET)) {
+ return FALSE;
+ }
+ }
+ if (!CryptCreateHash(cryptoprovider,
+ CALG_MD5,
+ 0,
+ 0,
+ &digest)) {
+ return FALSE;
+ }
+ ZeroMemory( regval, sizeof(regval) );
+ regval[1] = onoff;
+ if (!CryptHashData(digest,
+ regval,
+ sizeof(regval),
+ 0)) {
+ return FALSE;
+ }
+ if (!CryptHashData(digest,
+ (BYTE*)&seed,
+ sizeof(seed),
+ 0)) {
+ return FALSE;
+ }
+ len = sizeof(data);
+ if (!CryptGetHashParam(digest,
+ HP_HASHVALUE,
+ data,
+ &len,
+ 0)) {
+ return FALSE;
+ }
+ CryptDestroyHash(digest);
+ CryptReleaseContext(cryptoprovider, 0);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
+ 0,
+ KEY_WRITE,
+ &rkey) != ERROR_SUCCESS) {
+ return FALSE;
+ }
+ if (RegSetValueEx(rkey,
+ "PrivateHash",
+ 0,
+ REG_BINARY,
+ data,
+ sizeof(data)) != ERROR_SUCCESS) {
+ return FALSE;
+ }
+ RegCloseKey(rkey);
+
+ /* the user preference may or may not be set. if not, go to machine pref. */
+ if (RegOpenKeyEx(HKEY_CURRENT_USER,
+ "Software\\Microsoft\\Driver Signing",
+ 0,
+ KEY_WRITE,
+ &rkey) == ERROR_SUCCESS) {
+ if(RegSetValueEx(rkey,
+ "Policy",
+ 0,
+ REG_BINARY,
+ &onoff,
+ 1) != ERROR_SUCCESS) {
+ /* return FALSE; */
+ }
+ RegCloseKey(rkey);
+ }
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Driver Signing",
+ 0,
+ KEY_WRITE,
+ &rkey) != ERROR_SUCCESS) {
+ return FALSE;
+ }
+ if(RegSetValueEx(rkey,
+ "Policy",
+ 0,
+ REG_BINARY,
+ &onoff,
+ 1) != ERROR_SUCCESS) {
+ return FALSE;
+ }
+ RegCloseKey(rkey);
+
+ return TRUE;
+}
+
+/* keep linkage to these dynamic, in case the requisite Dll's don't exist. */
+#define NTSTATUS ULONG
+
+typedef struct _LSA_TRANSLATED_SID2 {
+ SID_NAME_USE Use;
+ PSID Sid;
+ LONG DomainIndex;
+ ULONG Flags;
+} LSA_TRANSLATED_SID2, *PLSA_TRANSLATED_SID2;
+
+typedef BOOL (__stdcall *PFnIsUserAnAdmin)(void);
+typedef BOOL (__stdcall *PFnAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY pIdAuth,
+ BYTE nSubAuthCount,
+ DWORD dwSubAuth0,
+ DWORD dwSubAuth1,
+ DWORD dwSubAuth2,
+ DWORD dwSubAuth3,
+ DWORD dwSubAuth4,
+ DWORD dwSubAuth5,
+ DWORD dwSubAuth6,
+ DWORD dwSubAuth7,
+ PSID pSid);
+typedef BOOL (WINAPI *PFnCheckTokenMembership)(HANDLE TokenHandle,
+ PSID SidToCheck,
+ PBOOL IsMember);
+typedef PVOID (__stdcall *PFnFreeSid)(PSID pSid);
+typedef NTSTATUS (__stdcall *PFnLsaOpenPolicy)(PLSA_UNICODE_STRING SystemName,
+ PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
+ ACCESS_MASK DesiredAccess,
+ PLSA_HANDLE PolicyHandle);
+typedef NTSTATUS (__stdcall *PFnLsaLookupNames2)(LSA_HANDLE PolicyHandle,
+ ULONG Flags,
+ ULONG Count,
+ PLSA_UNICODE_STRING Names,
+ PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
+ PLSA_TRANSLATED_SID2 *Sids);
+typedef NTSTATUS (__stdcall *PFnLsaAddAccountRights)(LSA_HANDLE PolicyHandle,
+ PSID AccountSid,
+ PLSA_UNICODE_STRING UserRights,
+ ULONG CountOfRights);
+typedef NTSTATUS (__stdcall *PFnLsaRemoveAccountRights)(LSA_HANDLE PolicyHandle,
+ PSID AccountSid,
+ BOOLEAN AllRights,
+ PLSA_UNICODE_STRING UserRights,
+ ULONG CountOfRights);
+typedef NTSTATUS (__stdcall *PFnLsaEnumerateAccountRights)(LSA_HANDLE PolicyHandle,
+ PSID AccountSid,
+ PLSA_UNICODE_STRING *UserRights,
+ PULONG CountOfRights);
+typedef BOOL (__stdcall *PFnAdjustTokenPrivileges)(HANDLE TokenHandle,
+ BOOL DisableAllPrivileges,
+ PTOKEN_PRIVILEGES NewState,
+ DWORD BufferLength,
+ PTOKEN_PRIVILEGES PreviousState,
+ PDWORD ReturnLength);
+typedef ULONG (__stdcall *PFnLsaNtStatusToWinError)(NTSTATUS Status);
+
+struct ft_advapi {
+ PFnAllocateAndInitializeSid AllocateAndInitializeSid;
+ PFnFreeSid FreeSid;
+ PFnCheckTokenMembership CheckTokenMembership;
+ PFnLsaOpenPolicy LsaOpenPolicy;
+ PFnLsaLookupNames2 LsaLookupNames2;
+ PFnLsaAddAccountRights LsaAddAccountRights;
+ PFnLsaRemoveAccountRights LsaRemoveAccountRights;
+ PFnLsaEnumerateAccountRights LsaEnumerateAccountRights;
+ PFnAdjustTokenPrivileges AdjustTokenPrivileges;
+ PFnLsaNtStatusToWinError LsaNtStatusToWinError;
+};
+
+static struct ft_advapi *s_advapi = NULL;
+static HMODULE s_advapi_hnd = INVALID_HANDLE_VALUE;
+
+static void loadadvapifuncs (void)
+{
+ if (s_advapi != NULL)
+ return;
+
+ s_advapi = (struct ft_advapi *)malloc(sizeof(struct ft_advapi));
+ memset(s_advapi, 0, sizeof(struct ft_advapi));
+ s_advapi_hnd = LoadLibrary("advapi32.dll");
+ if (s_advapi_hnd) {
+ ldebug ("Loading advapi functions from library.");
+ s_advapi->AllocateAndInitializeSid = (PFnAllocateAndInitializeSid) GetProcAddress(s_advapi_hnd, "AllocateAndInitializeSid");
+ s_advapi->FreeSid = (PFnFreeSid) GetProcAddress(s_advapi_hnd, "FreeSid");
+ s_advapi->CheckTokenMembership = (PFnCheckTokenMembership) GetProcAddress(s_advapi_hnd, "CheckTokenMembership");
+ s_advapi->LsaOpenPolicy = (PFnLsaOpenPolicy) GetProcAddress(s_advapi_hnd, "LsaOpenPolicy");
+ s_advapi->LsaLookupNames2 = (PFnLsaLookupNames2) GetProcAddress(s_advapi_hnd, "LsaLookupNames2");
+ s_advapi->LsaAddAccountRights = (PFnLsaAddAccountRights) GetProcAddress(s_advapi_hnd, "LsaAddAccountRights");
+ s_advapi->LsaRemoveAccountRights = (PFnLsaRemoveAccountRights) GetProcAddress(s_advapi_hnd, "LsaRemoveAccountRights");
+ s_advapi->LsaEnumerateAccountRights = (PFnLsaEnumerateAccountRights) GetProcAddress(s_advapi_hnd, "LsaEnumerateAccountRights");
+ s_advapi->AdjustTokenPrivileges = (PFnAdjustTokenPrivileges) GetProcAddress(s_advapi_hnd, "AdjustTokenPrivileges");
+ s_advapi->LsaNtStatusToWinError = (PFnLsaNtStatusToWinError) GetProcAddress(s_advapi_hnd, "LsaNtStatusToWinError");
+ }
+ else {
+ ldebug ("No advapi library located; unable to map API functions.");
+ }
+ return;
+}
+
+BOOL haveadminrights (void)
+{
+ SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
+ PSID admgroup;
+ BOOL isadmin = FALSE;
+ HMODULE module;
+ PFnIsUserAnAdmin pfnIsUserAnAdmin;
+
+ /* use IsUserAnAdmin when possible (Vista or greater). otherwise we fall back to checking
+ * token membership manually. For Vista and greater we want to know if we are currently running
+ * with Administrator rights, not only that user is a member of Administrator group.
+ */
+ module = LoadLibrary("shell32.dll");
+ if (module) {
+ pfnIsUserAnAdmin = (PFnIsUserAnAdmin) GetProcAddress(module, "IsUserAnAdmin");
+ if (pfnIsUserAnAdmin) {
+ isadmin = pfnIsUserAnAdmin();
+ FreeLibrary(module);
+ return isadmin;
+ }
+ FreeLibrary(module);
+ }
+
+ if (s_advapi == NULL)
+ loadadvapifuncs();
+
+ if (s_advapi->AllocateAndInitializeSid &&
+ s_advapi->CheckTokenMembership &&
+ s_advapi->FreeSid) {
+ if(s_advapi->AllocateAndInitializeSid(&ntauth,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &admgroup)) {
+ if( !s_advapi->CheckTokenMembership(NULL,
+ admgroup,
+ &isadmin) ) {
+ /* error occurred? default to false */
+ isadmin = FALSE;
+ }
+ s_advapi->FreeSid(admgroup);
+ }
+ }
+ return isadmin;
+}
+
Added: torvm/trunk/build/win32/src/torvm-w32/creds.h
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/creds.h (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/creds.h 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,14 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#ifndef __creds_h__
+#define __creds_h__
+
+#include "torvm.h"
+#include <ntsecpkg.h>
+#include <ntsecapi.h>
+
+BOOL setdriversigning (BOOL sigcheck);
+BOOL haveadminrights (void);
+
+#endif /* creds_h */
Added: torvm/trunk/build/win32/src/torvm-w32/registry.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/registry.c (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/registry.c 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1 @@
+#include "registry.h"
Added: torvm/trunk/build/win32/src/torvm-w32/registry.h
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/registry.h (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/registry.h 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,22 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#ifndef __registry_h__
+#define __registry_h__
+
+#include "torvm.h"
+
+/* win32 registry fun */
+#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+#define NETWORK_CLIENTS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E973-E325-11CE-BFC1-08002BE10318}"
+#define NETWORK_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E974-E325-11CE-BFC1-08002BE10318}"
+#define NETWORK_PROTOCOLS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E975-E325-11CE-BFC1-08002BE10318}"
+#define TCPIP_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"
+#define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
+
+#define REG_NAME_MAX 256
+
+BOOL pruneregtree (const TCHAR *entry);
+
+#endif /* registry_h */
Added: torvm/trunk/build/win32/src/torvm-w32/thrpool.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/thrpool.c (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/thrpool.c 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1 @@
+#include "thrpool.h"
Added: torvm/trunk/build/win32/src/torvm-w32/thrpool.h
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/thrpool.h (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/thrpool.h 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,9 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#ifndef __thrpool_h__
+#define __thrpool_h__
+
+#include "torvm.h"
+
+#endif /* thrpool_h */
Modified: torvm/trunk/build/win32/src/torvm-w32/torvm.c
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/torvm.c 2008-10-14 02:14:28 UTC (rev 17082)
+++ torvm/trunk/build/win32/src/torvm-w32/torvm.c 2008-10-14 03:54:28 UTC (rev 17083)
@@ -1,97 +1,44 @@
/* Copyright (C) 2008 The Tor Project, Inc.
* See LICENSE file for rights and terms.
*/
+#include "torvm.h"
-/* enable certain parts of the win32 API for process / system functions */
-#define _WIN32_WINNT 0x0500
-
-#include <windows.h>
-#include <tchar.h>
-#include <winreg.h>
-#include <winioctl.h>
-#include <winerror.h>
-#include <wincrypt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-/* things that should go into configure / headers / runtime dynamic */
-#define REG_NAME_MAX 256
-#define TOR_VM_ROOT "C:\\Tor_VM"
-#define W_TOR_VM_ROOT L"C:\\Tor_VM"
-#define TOR_VM_BIN TOR_VM_ROOT "\\bin"
-#define TOR_VM_LIB TOR_VM_ROOT "\\lib"
-#define TOR_VM_STATE TOR_VM_ROOT "\\state"
+#define TOR_VM_BASE "C:\\Tor_VM"
+#define W_TOR_VM_BASE L"C:\\Tor_VM"
+#define TOR_VM_BIN TOR_VM_BASE "\\bin"
+#define TOR_VM_LIB TOR_VM_BASE "\\lib"
+#define TOR_VM_STATE TOR_VM_BASE "\\state"
#define WIN_DRV_DIR "C:\\WINDOWS\\system32\\drivers"
#define TOR_TAP_NAME "Tor VM Tap32"
#define TOR_TAP_SVC "tortap91"
+BOOL buildpath (const TCHAR *dirname,
+ TCHAR **fullpath);
+BOOL buildwsyspath (TCHAR **fullpath);
+
+
struct s_rconnelem {
BOOL isactive;
BOOL isdefgw;
BOOL isdhcp;
+ BOOL istortap;
LPTSTR name;
LPTSTR guid;
LPTSTR macaddr;
LPTSTR ipaddr;
LPTSTR netmask;
LPTSTR gateway;
+ LPTSTR dhcpsvr;
+ LPTSTR driver;
struct s_rconnelem * next;
};
-
-/* jump hoops to read ethernet adapter MAC address.
+/* logging:
+ * lerror to stderr and log file(s) if set
+ * linfo to log and debug file
+ * ldebug to debug file
+ * fatal logs error and then exits process
*/
-#define _NDIS_CONTROL_CODE(request,method) \
- CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS)
-#define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE( 0, METHOD_OUT_DIRECT )
-
-/* these are not yet used, but we may need them to interact with network devices
- * directly to enable/disable, change MAC, etc.
- */
-#define IOCTL_NDIS_QUERY_ALL_STATS _NDIS_CONTROL_CODE( 1, METHOD_OUT_DIRECT )
-#define IOCTL_NDIS_ADD_DEVICE _NDIS_CONTROL_CODE( 2, METHOD_BUFFERED )
-#define IOCTL_NDIS_DELETE_DEVICE _NDIS_CONTROL_CODE( 3, METHOD_BUFFERED )
-#define IOCTL_NDIS_TRANSLATE_NAME _NDIS_CONTROL_CODE( 4, METHOD_BUFFERED )
-#define IOCTL_NDIS_ADD_TDI_DEVICE _NDIS_CONTROL_CODE( 5, METHOD_BUFFERED )
-#define IOCTL_NDIS_NOTIFY_PROTOCOL _NDIS_CONTROL_CODE( 6, METHOD_BUFFERED )
-#define IOCTL_NDIS_GET_LOG_DATA _NDIS_CONTROL_CODE( 7, METHOD_OUT_DIRECT )
-
-/* OID's we need to query */
-#define OID_802_3_PERMANENT_ADDRESS 0x01010101
-#define OID_802_3_CURRENT_ADDRESS 0x01010102
-#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
-/* probably will never need these, but just in case ... */
-#define OID_GEN_MEDIA_IN_USE 0x00010104
-#define OID_WAN_PERMANENT_ADDRESS 0x04010101
-#define OID_WAN_CURRENT_ADDRESS 0x04010102
-#define OID_WW_GEN_PERMANENT_ADDRESS 0x0901010B
-#define OID_WW_GEN_CURRENT_ADDRESS 0x0901010C
-
-/* win32 registry fun */
-#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-#define NETWORK_CLIENTS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E973-E325-11CE-BFC1-08002BE10318}"
-#define NETWORK_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E974-E325-11CE-BFC1-08002BE10318}"
-#define NETWORK_PROTOCOLS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E975-E325-11CE-BFC1-08002BE10318}"
-#define TCPIP_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"
-
-
-/* debug, info and error logging
- * lerror to stderr and log file (if set)
- * linfo to log file
- * ldebug to debug log file
- * fatal logs error and then exits process
- */
static HANDLE s_logh = INVALID_HANDLE_VALUE;
static HANDLE s_dbgh = INVALID_HANDLE_VALUE;
@@ -111,7 +58,9 @@
}
-static void _flog (HANDLE fd,
+static void _flog (HANDLE fda,
+ HANDLE fdb,
+ HANDLE fdc,
const char * msgtype,
const char * format,
va_list argptr)
@@ -125,7 +74,9 @@
SYSTEMTIME now;
va_list ap;
- if (fd == INVALID_HANDLE_VALUE)
+ if ( (fda == INVALID_HANDLE_VALUE) &&
+ (fdb == INVALID_HANDLE_VALUE) &&
+ (fdc == INVALID_HANDLE_VALUE) )
return;
if (msgbuf == NULL) {
@@ -164,9 +115,21 @@
/* full msg buffer */
len = msgmax -1;
}
- WriteFile (fd, msgbuf, len, &written, NULL);
- WriteFile (fd, newline, strlen(newline), &written, NULL);
- FlushFileBuffers (fd);
+ if (fda != INVALID_HANDLE_VALUE) {
+ WriteFile (fda, msgbuf, len, &written, NULL);
+ WriteFile (fda, newline, strlen(newline), &written, NULL);
+ FlushFileBuffers (fda);
+ }
+ if (fdb != INVALID_HANDLE_VALUE) {
+ WriteFile (fdb, msgbuf, len, &written, NULL);
+ WriteFile (fdb, newline, strlen(newline), &written, NULL);
+ FlushFileBuffers (fdb);
+ }
+ if (fdc != INVALID_HANDLE_VALUE) {
+ WriteFile (fdc, msgbuf, len, &written, NULL);
+ WriteFile (fdc, newline, strlen(newline), &written, NULL);
+ FlushFileBuffers (fdc);
+ }
return;
}
@@ -181,7 +144,7 @@
fd = GetStdHandle (STD_OUTPUT_HANDLE);
va_start (argptr, format);
- _flog (fd, "ERROR", format, argptr);
+ _flog (fd, s_logh, s_dbgh, "FATAL", format, argptr);
va_end (argptr);
_exit (9);
return;
@@ -201,7 +164,7 @@
}
va_start (argptr, format);
- _flog (fd, "ERROR", format, argptr);
+ _flog (fd, s_logh, s_dbgh, "ERROR", format, argptr);
va_end (argptr);
return;
}
@@ -209,11 +172,8 @@
void linfo (const char* format, ...)
{
va_list argptr;
- if (s_logh == INVALID_HANDLE_VALUE)
- return;
-
va_start (argptr, format);
- _flog (s_logh, "info", format, argptr);
+ _flog (s_logh, s_dbgh, INVALID_HANDLE_VALUE, "info", format, argptr);
va_end (argptr);
return;
}
@@ -236,153 +196,13 @@
void ldebug (const char* format, ...)
{
va_list argptr;
- if (s_dbgh == INVALID_HANDLE_VALUE)
- return;
-
va_start (argptr, format);
- _flog (s_dbgh, "debug", format, argptr);
+ _flog (s_dbgh, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, "debug", format, argptr);
va_end (argptr);
return;
}
-BOOL setdriversigning (BOOL sigcheck)
-{
- /* thanks to Stefan 'Sec' Zehl and Blaine Fleming for this snippet.
- * see http://support.microsoft.com/?kbid=298503 for details on this subversion.
- * the ideal alternative is to pay the thousands of dollars for a driver signature.
- */
-#define HP_HASHVALUE HP_HASHVAL
- HCRYPTPROV cryptoprovider;
- HCRYPTHASH digest;
- BYTE data[16];
- DWORD len;
- DWORD seed;
- HKEY rkey;
- BYTE onoff;
- char regval[4];
- int x;
-
- onoff = sigcheck ? 1 : 0;
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- "System\\WPA\\PnP",
- 0,
- KEY_READ,
- &rkey) != ERROR_SUCCESS){
- return FALSE;
- }
- len = sizeof(seed);
- if(RegQueryValueEx(rkey,
- "seed",
- NULL,
- NULL,
- (BYTE*)&seed,
- &len) != ERROR_SUCCESS){
- return FALSE;
- }
- RegCloseKey(rkey);
- if (!CryptAcquireContext(&cryptoprovider,
- NULL,
- NULL,
- PROV_RSA_FULL,
- 0)) {
- if (!CryptAcquireContext(&cryptoprovider,
- NULL,
- NULL,
- PROV_RSA_FULL,
- CRYPT_NEWKEYSET)) {
- return FALSE;
- }
- }
- if (!CryptCreateHash(cryptoprovider,
- CALG_MD5,
- 0,
- 0,
- &digest)) {
- return FALSE;
- }
- ZeroMemory( regval, sizeof(regval) );
- regval[1] = onoff;
- if (!CryptHashData(digest,
- regval,
- sizeof(regval),
- 0)) {
- return FALSE;
- }
- if (!CryptHashData(digest,
- (BYTE*)&seed,
- sizeof(seed),
- 0)) {
- return FALSE;
- }
- len = sizeof(data);
- if (!CryptGetHashParam(digest,
- HP_HASHVALUE,
- data,
- &len,
- 0)) {
- return FALSE;
- }
- CryptDestroyHash(digest);
- CryptReleaseContext(cryptoprovider, 0);
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
- 0,
- KEY_WRITE,
- &rkey) != ERROR_SUCCESS) {
- return FALSE;
- }
- if (RegSetValueEx(rkey,
- "PrivateHash",
- 0,
- REG_BINARY,
- data,
- sizeof(data)) != ERROR_SUCCESS) {
- return FALSE;
- }
- RegCloseKey(rkey);
-
- /* the user preference may or may not be set. if not, go to machine pref. */
- if (RegOpenKeyEx(HKEY_CURRENT_USER,
- "Software\\Microsoft\\Driver Signing",
- 0,
- KEY_WRITE,
- &rkey) == ERROR_SUCCESS) {
- if(RegSetValueEx(rkey,
- "Policy",
- 0,
- REG_BINARY,
- &onoff,
- 1) != ERROR_SUCCESS) {
- /* return FALSE; */
- }
- RegCloseKey(rkey);
- }
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- "Software\\Microsoft\\Driver Signing",
- 0,
- KEY_WRITE,
- &rkey) != ERROR_SUCCESS) {
- return FALSE;
- }
- if(RegSetValueEx(rkey,
- "Policy",
- 0,
- REG_BINARY,
- &onoff,
- 1) != ERROR_SUCCESS) {
- return FALSE;
- }
- RegCloseKey(rkey);
-
- return TRUE;
-}
-
-BOOL istapinstalled(struct s_rconnelem * connlist)
-{
- return FALSE;
-}
-
BOOL installtap(void)
{
STARTUPINFO si;
@@ -399,6 +219,7 @@
si.cb = sizeof(si);
dir = TOR_VM_LIB;
cmd = "\"" TOR_VM_BIN "\\devcon.exe\" install tortap91.inf TORTAP91";
+ ldebug ("Tap install cmd: %s", cmd);
if( !CreateProcess(NULL,
cmd,
@@ -439,6 +260,7 @@
int stop = 0;
int numconn = 0;
const char name_string[] = "Name";
+ char svc_string[REG_NAME_MAX];
opts = CREATE_NEW_PROCESS_GROUP;
@@ -447,6 +269,7 @@
si.cb = sizeof(si);
dir = TOR_VM_LIB;
cmd = "\"" TOR_VM_BIN "\\devcon.exe\" remove TORTAP91";
+ ldebug ("Tap un-install cmd: %s", cmd);
ldebug ("Removing TORTAP91 device via devcon.");
if( !CreateProcess(NULL,
@@ -547,13 +370,13 @@
KEY_SET_VALUE,
&dkey);
if (status != ERROR_SUCCESS) {
- lerror ("Failed to open network connection key for write: %d", status);
+ lerror ("Failed to open network connection key for write: %d", GetLastError());
continue;
}
/* now we can delete the connection key itself */
status = RegDeleteKey(dkey, "Connection");
if (status != ERROR_SUCCESS) {
- lerror ("Failed to remove tap connection subkey from registry: %d", status);
+ lerror ("Failed to remove tap connection subkey from registry: %d", GetLastError());
}
RegCloseKey (dkey);
/* finally, remove the top level connection key from the list of connections ids */
@@ -564,11 +387,11 @@
KEY_SET_VALUE,
&dkey);
if (status != ERROR_SUCCESS) {
- lerror ("Failed to open top level network connection key for write: %d", status);
+ lerror ("Failed to open top level network connection key for write: %d", GetLastError());
}
status = RegDeleteKey(dkey, enum_name);
if (status != ERROR_SUCCESS) {
- lerror ("Failed to remove top level tap key from registry: %d", status);
+ lerror ("Failed to remove top level tap key from registry: %d", GetLastError());
}
RegCloseKey (dkey);
}
@@ -578,6 +401,51 @@
RegCloseKey (key);
+ /* now for any service entries for the Tor tap service */
+ snprintf(svc_string,
+ sizeof(svc_string),
+ "%s\\%s",
+ SERVICES_KEY, TOR_TAP_SVC);
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ svc_string,
+ 0,
+ KEY_READ,
+ &key);
+ if (status == ERROR_SUCCESS) {
+ RegCloseKey (key);
+ ldebug ("Found a Tor tap service entry. Attempting removal...");
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ svc_string,
+ 0,
+ KEY_SET_VALUE,
+ &key);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Cannot open Tor tap services key for write access. Error code: %d", GetLastError());
+ }
+ else {
+ RegDeleteKey(key, "Enum");
+ RegDeleteKey(key, "Security");
+ RegCloseKey (key);
+ }
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ SERVICES_KEY,
+ 0,
+ KEY_SET_VALUE,
+ &key);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Cannot open service parent key for write access to remove tap subkey. Error code: %d", GetLastError());
+ }
+ else {
+ status = RegDeleteKey(key, TOR_TAP_SVC);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to remove tap service key from registry: %d", GetLastError());
+ }
+ else {
+ ldebug ("Removal complete.");
+ }
+ RegCloseKey (key);
+ }
+ }
return TRUE;
}
@@ -628,7 +496,11 @@
BOOL uninstalltornpf (void)
{
LPTSTR fname = WIN_DRV_DIR "\\tornpf.sys";
+ LPTSTR cmd = "\"net.exe\" stop tornpf";
DeleteFile (fname);
+ if (! runcommand(cmd)) {
+ return FALSE;
+ }
return TRUE;
}
@@ -646,13 +518,32 @@
LPTSTR cmd = NULL;
LPTSTR dir = NULL;
DWORD exitcode;
- DWORD opts = 0;
+ DWORD opts = CREATE_NEW_PROCESS_GROUP;
DWORD numread;
DWORD numwritten;
- CHAR * buff;
+ CHAR * buff = NULL;
- opts = CREATE_NEW_PROCESS_GROUP;
+ /* for vista or above also save the firewall context
+ * do this before the IP context so that restore doesn't leave us vulnerable (even briefly)
+ */
+ if (getosversion() >= OS_VISTA) {
+ cmd = "\"netsh.exe\" advfirewall export \"" TOR_VM_STATE "\\firewall.wfw\"";
+ runcommand(cmd);
+ linfo ("Saved current firewall configuration state.");
+ }
+ fh = CreateFile (TOR_VM_STATE "\\netcfg.save",
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (fh == INVALID_HANDLE_VALUE) {
+ lerror ("Unable to open network save file for writing. Error code: %d", GetLastError());
+ return FALSE;
+ }
+
ZeroMemory( &pi, sizeof(pi) );
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
@@ -661,7 +552,6 @@
sattr.lpSecurityDescriptor = NULL;
dir = TOR_VM_STATE;
cmd = "\"netsh.exe\" interface ip dump";
- /* cmd = "\"netsh.exe\" dump"; <- this is noisy and slow. avoid if possible. */
CreatePipe(&stdout_rd, &stdout_wr, &sattr, 0);
SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0);
@@ -678,13 +568,16 @@
cmd,
NULL, // process handle no inherit
NULL, // thread handle no inherit
- TRUE, // handles are inherited
+ FALSE, // default handle inheritance false
opts,
NULL, // environment block
dir,
&si,
&pi) ) {
- lerror ("Failed to launch process. Error code: %d", GetLastError());
+ lerror ("Failed to launch netsh process. Error code: %d", GetLastError());
+ if (buff)
+ free(buff);
+ CloseHandle(fh);
return FALSE;
}
@@ -692,25 +585,19 @@
CloseHandle(stdin_rd);
CloseHandle(stdin_wr);
- fh = CreateFile (TOR_VM_STATE "\\netcfg.save",
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
buff = (CHAR *)malloc(READSIZE);
while (ReadFile(stdout_rd, buff, READSIZE, &numread, NULL) && (numread > 0)) {
WriteFile(fh, buff, numread, &numwritten, NULL);
}
- CloseHandle (fh);
- linfo ("Saved current network configuration state.");
+ linfo ("Saved current IP network configuration state.");
+ free(buff);
CloseHandle(stdout_rd);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
+ CloseHandle (fh);
+
return TRUE;
}
@@ -721,9 +608,13 @@
LPTSTR cmd = NULL;
LPTSTR dir = NULL;
DWORD exitcode;
- DWORD opts = 0;
+ DWORD opts = CREATE_NEW_PROCESS_GROUP;
- opts = CREATE_NEW_PROCESS_GROUP;
+ if (getosversion() >= OS_VISTA) {
+ cmd = "\"netsh.exe\" advfirewall import \"" TOR_VM_STATE "\\firewall.wfw\"";
+ runcommand(cmd);
+ linfo ("Imported saved firewall configuration.");
+ }
ZeroMemory( &pi, sizeof(pi) );
ZeroMemory( &si, sizeof(si) );
@@ -807,18 +698,30 @@
BOOL disablefirewall(void)
{
- LPSTR cmd;
- cmd = "\"netsh.exe\" firewall set opmode disable";
+ LPTSTR cmd = "\"netsh.exe\" firewall set opmode disable";
+ ldebug ("Disable firewall cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
return TRUE;
}
+BOOL enablefirewall(void)
+{
+ /* TODO: we need to check if exceptions are disabled, and set opmode enable disable accordingly. */
+ LPTSTR cmd = "\"netsh.exe\" firewall set opmode enable";
+ ldebug ("Re-enable firewall cmd: %s", cmd);
+ if (! runcommand(cmd)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
BOOL cleararpcache(void)
{
LPSTR cmd;
cmd = "\"netsh.exe\" interface ip delete arpcache";
+ ldebug ("Clear ARP cache cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
@@ -829,6 +732,7 @@
{
LPSTR cmd;
cmd = "\"ipconfig.exe\" /flushdns";
+ ldebug ("Flush DNS cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
@@ -839,17 +743,21 @@
{
LPSTR cmd;
cmd = "\"netsh.exe\" interface ip set address \"" TOR_TAP_NAME "\" static 10.10.10.2 255.255.255.252 10.10.10.1 1";
+ ldebug ("Tap config cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
cmd = "\"netsh.exe\" interface ip set dns \"" TOR_TAP_NAME "\" static 4.2.2.2";
+ ldebug ("Tap config cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
cmd = "\"netsh.exe\" interface ip add dns \"" TOR_TAP_NAME "\" 4.2.2.4";
+ ldebug ("Tap config cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
+ ldebug ("Tap config complete.");
return TRUE;
}
@@ -857,6 +765,7 @@
{
LPSTR cmd;
cmd = "\"netsh.exe\" interface ip set address \"Local Area Connection\" static 10.231.254.1 255.255.255.254";
+ ldebug ("Bridge interface null route cmd: %s", cmd);
if (! runcommand(cmd)) {
return FALSE;
}
@@ -924,106 +833,6 @@
return TRUE;
}
-BOOL getmacaddr(const char * devguid,
- char ** mac)
-{
- char * devfstr = NULL;
- unsigned char macbuf[6];
- BOOL status;
- HANDLE devfd;
- DWORD retsz, oidcode;
- BOOL retval = FALSE;
-
- *mac = NULL;
- devfstr = malloc(1024);
- snprintf (devfstr, 1023, "\\\\.\\%s", devguid);
- devfd = CreateFile(devfstr,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (devfd == INVALID_HANDLE_VALUE)
- {
- lerror ("Unable to open net device handle for path: %s", devfstr);
- goto cleanup;
- }
-
-#define MAXMAC 24
- oidcode = OID_802_3_CURRENT_ADDRESS;
- status = DeviceIoControl(devfd,
- IOCTL_NDIS_QUERY_GLOBAL_STATS,
- &oidcode, sizeof(oidcode),
- macbuf, sizeof(macbuf),
- &retsz,
- (LPOVERLAPPED) NULL);
- if (retsz == sizeof(macbuf)) {
- *mac = malloc(MAXMAC);
- memset(*mac, 0, MAXMAC);
- snprintf(*mac, MAXMAC-1,
- "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- macbuf[0], macbuf[1], macbuf[2], macbuf[3], macbuf[4], macbuf[5]);
- retval = TRUE;
- }
- else {
- retval = FALSE;
- }
-
- cleanup:
- if (devfd != INVALID_HANDLE_VALUE)
- CloseHandle(devfd);
- free(devfstr);
-
- return retval;
-}
-
-BOOL isconnected(const char * devguid)
-{
- char * devfstr = NULL;
- BOOL status;
- HANDLE devfd;
- DWORD retsz, oidcode, intfStatus;
- BOOL retval = FALSE;
-
- devfstr = malloc(1024);
- snprintf (devfstr, 1023, "\\\\.\\%s", devguid);
- devfd = CreateFile(devfstr,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (devfd == INVALID_HANDLE_VALUE)
- {
- lerror ("Unable to open net device handle for path: %s", devfstr);
- goto cleanup;
- }
-
- oidcode = OID_GEN_MEDIA_CONNECT_STATUS;
- status = DeviceIoControl(devfd,
- IOCTL_NDIS_QUERY_GLOBAL_STATS,
- &oidcode, sizeof(oidcode),
- &intfStatus, sizeof(intfStatus),
- &retsz,
- (LPOVERLAPPED) NULL);
- if (status) {
- ldebug ("Received media connect status %d for device %s.", intfStatus, devguid);
- retval = (intfStatus == 0) ? TRUE : FALSE;
- }
- else {
- retval = FALSE;
- }
-
- cleanup:
- if (devfd != INVALID_HANDLE_VALUE)
- CloseHandle(devfd);
- free(devfstr);
-
- return retval;
-}
-
int loadnetinfo(struct s_rconnelem **connlist)
{
LONG status;
@@ -1067,7 +876,7 @@
if (status == ERROR_NO_MORE_ITEMS)
break;
else if (status != ERROR_SUCCESS) {
- return -1;
+ break;
}
snprintf(connection_string,
@@ -1093,10 +902,10 @@
&len);
if (status != ERROR_SUCCESS || name_type != REG_SZ) {
- return -1;
+ break;
}
else {
- /* add this connection info the list */
+ /* add this connection info to the list */
numconn++;
if (ce == NULL) {
*connlist = ce = malloc(sizeof(struct s_rconnelem));
@@ -1131,15 +940,14 @@
"EnableDHCP",
NULL,
NULL,
- &(ce->isdhcp),
+ (LPBYTE)&(ce->isdhcp),
&len);
if (status == ERROR_SUCCESS) {
- ce->gateway = strdup(name_data);
ldebug ("Connection %s %s using DHCP.", ce->name, ce->isdhcp ? "is" : "is NOT");
}
len = sizeof (name_data);
status = RegQueryValueEx(tkey,
- "DefaultGateway",
+ ce->isdhcp ? "DhcpDefaultGateway" : "DefaultGateway",
NULL,
&name_type,
name_data,
@@ -1147,7 +955,7 @@
if (status == ERROR_SUCCESS) {
ce->gateway = strdup(name_data);
ldebug ("Connection %s default gateway: %s.", ce->name, ce->gateway);
- if (strcmp(ce->gateway, "0.0.0.0") != 0) {
+ if ( (strlen(ce->gateway) > 6) && (strcmp(ce->gateway, "0.0.0.0") != 0) ) {
ce->isdefgw = TRUE;
ldebug ("Connection %s has the default route.", ce->name);
}
@@ -1184,29 +992,29 @@
RegCloseKey (key);
- i = 0;
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- ADAPTER_KEY,
- 0,
- KEY_READ,
- &key);
+ if (numconn <= 0)
+ return numconn;
- if (status != ERROR_SUCCESS) {
- lerror ("Failed to open key for read: %d", status);
- return -1;
- }
-
+ i = 0;
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ ADAPTER_KEY,
+ 0,
+ KEY_READ,
+ &key);
+ if (status != ERROR_SUCCESS) {
+ lerror ("Failed to open key for read: %d", status);
+ }
+ else {
while (1) {
- char enum_name[REG_NAME_MAX];
- char connection_string[REG_NAME_MAX];
- HKEY ckey;
- char name_data[REG_NAME_MAX];
- char cguid[REG_NAME_MAX];
- DWORD name_type;
+ char enum_name[REG_NAME_MAX];
+ char connection_string[REG_NAME_MAX];
+ HKEY ckey;
+ char name_data[REG_NAME_MAX];
+ char cguid[REG_NAME_MAX];
+ DWORD name_type;
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
+ len = sizeof (enum_name);
+ status = RegEnumKeyEx(
key,
i++,
enum_name,
@@ -1216,25 +1024,24 @@
NULL,
NULL);
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS) {
- return -1;
- }
+ if (status == ERROR_NO_MORE_ITEMS)
+ break;
+ else if (status != ERROR_SUCCESS)
+ break;
- snprintf(connection_string,
+ snprintf(connection_string,
sizeof(connection_string),
"%s\\%s",
ADAPTER_KEY, enum_name);
- status = RegOpenKeyEx(
+ status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
connection_string,
0,
KEY_READ,
&ckey);
- if (status == ERROR_SUCCESS) {
+ if (status == ERROR_SUCCESS) {
len = sizeof (name_data);
status = RegQueryValueEx(
ckey,
@@ -1251,24 +1058,24 @@
}
RegCloseKey (ckey);
- }
- else {
+ }
+ else {
/* printf ("Failed read key %s , errorno: %d", connection_string, status); */
- }
+ }
- snprintf(connection_string,
+ snprintf(connection_string,
sizeof(connection_string),
"%s\\%s",
ADAPTER_KEY, enum_name);
- status = RegOpenKeyEx(
+ status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
connection_string,
0,
KEY_READ,
&ckey);
- if (status == ERROR_SUCCESS) {
+ if (status == ERROR_SUCCESS) {
len = sizeof (name_data);
status = RegQueryValueEx(
ckey,
@@ -1278,33 +1085,32 @@
name_data,
&len);
- if (status != ERROR_SUCCESS || name_type != REG_SZ) {
+ if (status != ERROR_SUCCESS || name_type != REG_SZ)
ldebug ("Failed parse of key %s\\NetCfgInstanceId , errorno: %d", connection_string, status);
- }
else {
ldebug ("GUID: %s", name_data);
strcpy (cguid, name_data);
}
RegCloseKey (ckey);
- }
- else {
- ldebug ("Failed read key %s , errorno: %d", connection_string, status);
- }
+ }
+ else {
+ ldebug ("Failed read key %s , errorno: %d", connection_string, status);
+ }
- snprintf(connection_string,
+ snprintf(connection_string,
sizeof(connection_string),
"%s\\%s\\Ndi",
ADAPTER_KEY, enum_name);
- status = RegOpenKeyEx(
+ status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
connection_string,
0,
KEY_READ,
&ckey);
- if (status == ERROR_SUCCESS) {
+ if (status == ERROR_SUCCESS) {
len = sizeof (name_data);
status = RegQueryValueEx(
ckey,
@@ -1314,12 +1120,20 @@
name_data,
&len);
- if (status != ERROR_SUCCESS || name_type != REG_SZ) {
+ if (status != ERROR_SUCCESS || name_type != REG_SZ)
ldebug ("Failed parse of key %s\\Service , errorno: %d", connection_string, status);
- }
- else {
+ else {
ldebug ("Service: %s", name_data);
+ ce = *connlist;
+ while (ce && strcmp(ce->guid , cguid) != 0) {
+ ce = ce->next;
+ }
+ if (ce) {
+ ce->driver = strdup(name_data);
+ }
if (strcmp(name_data, TOR_TAP_SVC) == 0) {
+ if (ce)
+ ce->istortap = TRUE;
snprintf(connection_string,
sizeof(connection_string),
"%s\\%s\\Connection",
@@ -1343,100 +1157,97 @@
RegCloseKey (wkey);
}
}
- }
+ }
- RegCloseKey (ckey);
+ RegCloseKey (ckey);
}
- else {
+ else
ldebug ("Failed read key %s , errorno: %d", connection_string, status);
- }
}
RegCloseKey (key);
-
- return numconn;
-}
-
-/* keep linkage to these dynamic, in case the requisite Dll's don't exist. */
-typedef BOOL (__stdcall *PFnIsUserAnAdmin)(void);
-typedef BOOL (__stdcall *PFnAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY pIdAuth, BYTE nSubAuthCount, DWORD dwSubAuth0, DWORD dwSubAuth1, DWORD dwSubAuth2, DWORD dwSubAuth3, DWORD dwSubAuth4, DWORD dwSubAuth5, DWORD dwSubAuth6, DWORD dwSubAuth7, PSID pSid);
-typedef BOOL (WINAPI *PFnCheckTokenMembership)(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember);
-typedef PVOID (__stdcall *PFnFreeSid)(PSID pSid);
-
-BOOL haveadminrights (void)
-{
- SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
- PSID admgroup;
- BOOL isadmin = FALSE;
- HMODULE module;
- PFnIsUserAnAdmin pfnIsUserAnAdmin = NULL;
- PFnAllocateAndInitializeSid pfnAllocateAndInitializeSid = NULL;
- PFnCheckTokenMembership pfnCheckTokenMembership = NULL;
- PFnFreeSid pfnFreeSid = NULL;
-
- /* use IsUserAnAdmin when possible (Vista or greater). otherwise we fall back to checking
- * token membership manually. For Vista and greater we want to know if we are currently running
- * with Administrator rights, not only that user is a member of Administrator group.
- */
- module = LoadLibrary("shell32.dll");
- if (module) {
- pfnIsUserAnAdmin = (PFnIsUserAnAdmin) GetProcAddress(module, "IsUserAnAdmin");
- if (pfnIsUserAnAdmin) {
- isadmin = pfnIsUserAnAdmin();
- FreeLibrary(module);
- return isadmin;
- }
- FreeLibrary(module);
}
- module = LoadLibrary("advapi32.dll");
- if (module) {
- pfnAllocateAndInitializeSid = (PFnAllocateAndInitializeSid) GetProcAddress(module, "AllocateAndInitializeSid");
- pfnCheckTokenMembership = (PFnCheckTokenMembership) GetProcAddress(module, "CheckTokenMembership");
- pfnFreeSid = (PFnFreeSid) GetProcAddress(module, "FreeSid");
- if (pfnAllocateAndInitializeSid && pfnCheckTokenMembership && pfnFreeSid) {
- if(pfnAllocateAndInitializeSid(&ntauth,
- 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &admgroup))
- {
- if( !pfnCheckTokenMembership(NULL,
- admgroup,
- &isadmin) )
- {
- /* error occurred? default to false */
- isadmin = FALSE;
- }
- pfnFreeSid(admgroup);
- }
- }
- FreeLibrary(module);
- }
- return isadmin;
+ return numconn;
}
BOOL buildcmdline (struct s_rconnelem * brif,
BOOL usedebug,
+ BOOL noinit,
char ** cmdline)
{
+/* DHCPSVR DHCPNAME LEASE ISDHCP CTLSOCK HASHPW */
*cmdline = (char *)malloc(4096);
const char * basecmds = "quiet loglevel=0 clocksource=hpet";
const char * dbgcmds = "loglevel=9 clocksource=hpet DEBUGINIT";
- snprintf (*cmdline, 4095,
- "%s IP=%s MASK=%s GW=%s MAC=%s MTU=1480 PRIVIP=10.10.10.1",
- usedebug ? dbgcmds : basecmds,
- brif->ipaddr,
- brif->netmask,
- brif->gateway,
- brif->macaddr);
+ if (noinit) {
+ snprintf (*cmdline, 4095,
+ "%s NOINIT",
+ basecmds);
+ }
+ else {
+ if (brif->isdhcp == FALSE) {
+ snprintf (*cmdline, 4095,
+ "%s IP=%s MASK=%s GW=%s MAC=%s MTU=1480 PRIVIP=10.10.10.1",
+ usedebug ? dbgcmds : basecmds,
+ brif->ipaddr,
+ brif->netmask,
+ brif->gateway,
+ brif->macaddr);
+ }
+ else {
+ snprintf (*cmdline, 4095,
+ "%s IP=%s MASK=%s GW=%s MAC=%s MTU=1480 PRIVIP=10.10.10.1 ISDHCP DHCPSVR=%s LEASE=%d CTLSOCK=10.10.10.1:9051 HASHPW=%s",
+ usedebug ? dbgcmds : basecmds,
+ brif->ipaddr,
+ brif->netmask,
+ brif->gateway,
+ brif->macaddr,
+ brif->dhcpsvr,
+ 0,
+ /* control port password is "password"
+ * TODO: use Crypto API to collect entropy for ephemeral password generation
+ */
+ "16:6407E39581A121B26051A360CA8BB1535C73877C894E7B6EC554422789");
+ }
+ }
return TRUE;
}
+BOOL spawnprocess (PROCESS_INFORMATION * pi,
+ const TCHAR *cmdline)
+{
+ STARTUPINFO si;
+ SECURITY_ATTRIBUTES sattr;
+ DWORD opts = 0;
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory( pi, sizeof(PROCESS_INFORMATION) );
+
+ TCHAR *cmd = (TCHAR*)malloc(4096);
+ snprintf (cmd, 4095,
+ "\"C:\\Tor_VM\\bin\\qemu.exe\" -L . -kernel ../lib/vmlinuz -hda ../state/hdd.img -m %d -std-vga");
+ ldebug ("Launching Qemu with cmd: %s", cmd);
+ if( !CreateProcess(NULL,
+ cmd,
+ NULL, // process handle no inherit
+ NULL, // thread handle no inherit
+ TRUE,
+ opts,
+ NULL, // environment block
+ TOR_VM_BIN,
+ &si,
+ pi) ) {
+ lerror ("Failed to launch process. Error code: %d", GetLastError());
+ return FALSE;
+ }
+ return TRUE;
+}
+
BOOL launchtorvm (PROCESS_INFORMATION * pi,
char * bridgeintf,
char * macaddr,
+ char * tapname,
char * cmdline)
{
STARTUPINFO si;
@@ -1446,30 +1257,51 @@
SECURITY_ATTRIBUTES sattr;
LPTSTR cmd = NULL;
LPTSTR dir = NULL;
- DWORD opts = CREATE_NEW_PROCESS_GROUP | BELOW_NORMAL_PRIORITY_CLASS;
+ /* DWORD opts = BELOW_NORMAL_PRIORITY_CLASS; */
+ DWORD opts = CREATE_NEW_PROCESS_GROUP;
DWORD numwritten;
+ DWORD pipesz;
ZeroMemory( &si, sizeof(si) );
+ ZeroMemory( &sattr, sizeof(sattr) );
ZeroMemory( pi, sizeof(PROCESS_INFORMATION) );
si.cb = sizeof(si);
- sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+/* sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
sattr.bInheritHandle = TRUE;
- sattr.lpSecurityDescriptor = NULL;
+ sattr.lpSecurityDescriptor = NULL; */
dir = TOR_VM_BIN;
- cmd = (LPTSTR)malloc(1024);
- snprintf (cmd, 1023,
- "\"" TOR_VM_BIN "\\qemu.exe\" -name \"Tor VM \" -L . -kernel ../lib/vmlinuz -append \"%s\" -hda ../state/hdd.img -m %d -std-vga -net nic,model=pcnet,macaddr=%s -net pcap,devicename=\"%s\" -net nic,vlan=1,model=pcnet -net tap,vlan=1,ifname=\"%s\" -net user,vlan=2 -net nic,vlan=2,model=pcnet",
+ cmd = (LPTSTR)malloc(4096);
+ if (tapname) {
+ snprintf (cmd, 4095,
+ "\"" TOR_VM_BIN "\\qemu.exe\" -name \"Tor VM \" -L . -kernel ../lib/vmlinuz -append \"%s\" -hda ../state/hdd.img -m %d -std-vga -net nic,model=pcnet,macaddr=%s -net pcap,devicename=\"%s\" -net nic,vlan=1,model=pcnet -net tap,vlan=1,ifname=\"%s\"",
cmdline,
32,
macaddr,
bridgeintf,
- TOR_TAP_NAME);
+ tapname);
+ }
+ else {
+ snprintf (cmd, 4095,
+ "\"" TOR_VM_BIN "\\qemu.exe\" -name \"Tor VM \" -L . -kernel ../lib/vmlinuz -append \"%s\" -hda ../state/hdd.img -m %d -std-vga -net nic,model=pcnet,macaddr=%s -net pcap,devicename=\"%s\"",
+ cmdline,
+ 32,
+ macaddr,
+ bridgeintf);
+ }
ldebug ("Launching Qemu with cmd: %s", cmd);
-/* don't use this stdin pipe until the read 0 issue is resolved.
- CreatePipe(&stdin_rd, &stdin_wr, &sattr, 0);
+/*
+ pipesz = strlen(cmdline);
+ CreatePipe(&stdin_rd, &stdin_wr, &sattr, pipesz);
SetHandleInformation(stdin_wr, HANDLE_FLAG_INHERIT, 0);
+ if (! WriteFile(stdin_wr, cmdline, strlen(cmdline), &numwritten, NULL)) {
+ lerror ("Failed to write kernel command line to stdin handle. Error code: %d", GetLastError());
+ }
+ else {
+ ldebug ("Wrote %d bytes of cmdline len %d to qemu stdin pipe.", numwritten, strlen(cmdline));
+ }
+
stdout_h = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = stdout_h;
@@ -1477,35 +1309,24 @@
si.hStdInput = stdin_rd;
si.dwFlags |= STARTF_USESTDHANDLES;
*/
-
- if( !CreateProcess(NULL,
+ if( !CreateProcess(NULL,
cmd,
- NULL, // process handle no inherit
- NULL, // thread handle no inherit
-/* TRUE, // handle inheritance needed for std handles */
- FALSE,
+ NULL,
+ NULL,
+ TRUE,
opts,
- NULL, // environment block
+ NULL,
dir,
&si,
pi) ) {
lerror ("Failed to launch Qemu Tor VM process. Error code: %d", GetLastError());
return FALSE;
}
-
/*
- CloseHandle(stdin_rd);
-
- if (! WriteFile(stdin_wr, cmdline, strlen(cmdline), &numwritten, NULL)) {
- lerror ("Failed to write kernel command line to stdin handle. Error code: %d", GetLastError());
- }
- else {
- ldebug ("Wrote %d bytes of cmdline len %d to qemu stdin.", numwritten, strlen(cmdline));
- }
FlushFileBuffers (stdin_wr);
+ CloseHandle(stdin_rd);
CloseHandle(stdin_wr);
*/
-
return TRUE;
}
@@ -1554,12 +1375,11 @@
DWORD authopts = 0;
DWORD propts = 0;
- //authopts = LOGON_WITH_PROFILE;
propts = CREATE_NEW_PROCESS_GROUP | HIGH_PRIORITY_CLASS;
si.cb = sizeof(si);
- wcmd = W_TOR_VM_ROOT L"\\torvm.exe";
- cmd = TOR_VM_ROOT "\\torvm.exe";
+ wcmd = W_TOR_VM_BASE L"\\torvm.exe";
+ cmd = TOR_VM_BASE "\\torvm.exe";
/* first, let's see if Administrator has no password set. */
if( !CreateProcessWithLogonW(username,
@@ -1587,6 +1407,42 @@
return TRUE;
}
+BOOL runningdetached (void)
+{
+ return TRUE;
+}
+
+BOOL detachself (void)
+{
+ STARTUPINFOW si = {0};
+ PROCESS_INFORMATION pi = {0};
+ LPTSTR cmd = NULL;
+ LPTSTR mypath = NULL;
+ LPTSTR args = "";
+ bgstartupinfo (&si);
+ getmypath(&mypath);
+ cmd = (TCHAR *)malloc (4096);
+ snprintf (cmd, 4095,
+ "\"%s\" %s",
+ mypath, args);
+ if( !CreateProcess(NULL,
+ cmd,
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_NEW_PROCESS_GROUP | HIGH_PRIORITY_CLASS,
+ NULL,
+ NULL,
+ &si,
+ &pi) ) {
+ lerror ("Failed to launch detached torvm.exe process. Error code: %d", GetLastError());
+ free (cmd);
+ return FALSE;
+ }
+ free (cmd);
+ return TRUE;
+}
+
BOOL setupenv (void)
{
#define EBUFSZ 4096
@@ -1665,13 +1521,37 @@
int numintf;
struct s_rconnelem *connlist = NULL;
struct s_rconnelem *ce = NULL;
- BOOL vmdebug = FALSE;
+ BOOL indebug = FALSE;
+ BOOL vmnop = FALSE;
+ BOOL noinit = FALSE;
BOOL foundit = FALSE;
char * cmdline = NULL;
+ if (getosbits() > 32) {
+ lerror ("Error: only 32bit operating systems are currently supported.");
+ MessageBox(NULL,
+ "Sorry, only 32bit operating systems are currently supported.",
+ "Unsupported Operating System Architecture",
+ MB_OK);
+ exit (1);
+ }
+
+ if (!setupenv()) {
+ fatal ("Unable to prepare process environment.");
+ }
+
+ /* ensure we are running detached or as service */
+ if (! runningdetached()) {
+ if(detachself()) {
+ _exit(0);
+ }
+ }
+
/* invocation options:
* clean - restore network setup (if saved config exists), clean up tap, etc.
* debug - launch vm in debug mode, shell at console in vm, etc.
+ * vmnop - launch vm without any network devices.
+ * repair - replace virtual disk with original empty disk image.
* TODO: implement "real" command line options
*/
if (argc > 1) {
@@ -1680,9 +1560,24 @@
restorenetconfig();
exit (0);
}
- if (strcmp(argv[1], "debug") == 0) {
- vmdebug = TRUE;
+ else if (strcmp(argv[1], "debug") == 0) {
+ indebug = TRUE;
}
+ else if (strcmp(argv[1], "vmnop") == 0) {
+ indebug = TRUE;
+ vmnop = TRUE;
+ }
+ else if (strcmp(argv[1], "noinit") == 0) {
+ noinit = TRUE;
+ }
+ else if (strcmp(argv[1], "detach") == 0) {
+ if(detachself()) { _exit(0); }
+ }
+ else if (strcmp(argv[1], "repair") == 0) {
+ LPTSTR fname = TOR_VM_STATE "\\hdd.img";
+ DeleteFile (fname);
+ linfo ("Restored virtual disk image back to original state.");
+ }
}
if (!haveadminrights()) {
@@ -1694,100 +1589,138 @@
return 1;
}
- logto (TOR_VM_STATE "\\torvm.log");
- debugto (TOR_VM_STATE "\\debug.log");
+ logto (TOR_VM_STATE "\\vmlog.txt");
+ debugto (TOR_VM_STATE "\\debug.txt");
- if (!setupenv()) {
- fatal ("Unable to prepare process environment.");
- }
+ if (!vmnop) {
+ if (!savenetconfig()) {
+ fatal ("Unable to save current network configuration.");
+ }
- if (!savenetconfig()) {
- fatal ("Unable to save current network configuration.");
- }
+ ce = NULL;
+ numintf = loadnetinfo(&connlist);
+ if (numintf > 0) {
+ ce = connlist;
+ while (ce && ce->istortap != TRUE) {
+ ce = ce->next;
+ }
+ }
+ /* disable removing the tap automatically until reload issues resolved.
+ * uninstalltap(); */
+ if (ce == NULL) {
+ if (!setdriversigning (FALSE)) {
+ lerror ("Unable to disable driver signing checks. Installing tap anyway...");
+ }
+ if (!installtap()) {
+ lerror ("Unable to load TAP-Win32 network driver.");
+ goto shutdown;
+ }
+ if (!setdriversigning (TRUE)) {
+ lerror ("Unable to restore driver signing checks.");
+ }
+ /* TODO: util method to free structure of list elem */
+ numintf = loadnetinfo(&connlist);
+ }
- uninstalltap();
+ if (!installtornpf()) {
+ lerror ("Unable to install Tor NPF service driver.");
+ goto shutdown;
+ }
- if (!setdriversigning (FALSE)) {
- lerror ("Unable to disable driver signing checks. Installing tap anyway...");
+ if (! configbridge()) {
+ lerror ("Unable to configure blackhole route for bridged interface.");
+ }
+ if (! disableservices()) {
+ lerror ("Unable to disable dangerous windows network services.");
+ }
+ if (getosversion() > OS_2000) {
+ if (! disablefirewall()) {
+ lerror ("Unable to disable windows firewall.");
+ }
+ }
+ if (! cleararpcache()) {
+ lerror ("Unable to clear arp cache.");
+ }
+ if (! flushdns()) {
+ lerror ("Unable to flush cached DNS entries.");
+ }
}
- if (!installtap()) {
- lerror ("Unable to load TAP-Win32 network driver.");
- goto shutdown;
- }
- if (!setdriversigning (TRUE)) {
- lerror ("Unable to restore driver signing checks.");
- }
- if (!installtornpf()) {
- lerror ("Unable to install Tor NPF service driver.");
- goto shutdown;
- }
-
- numintf = loadnetinfo(&connlist);
-
- if (! configbridge()) {
- lerror ("Unable to configure blackhole route for bridged interface.");
- }
- if (! disableservices()) {
- lerror ("Unable to disable dangerous windows network services.");
- }
- if (! disablefirewall()) {
- lerror ("Unable to disable windows firewall.");
- }
- if (! cleararpcache()) {
- lerror ("Unable to clear arp cache.");
- }
- if (! flushdns()) {
- lerror ("Unable to flush cached DNS entries.");
- }
+ /* all invocations past this point need a virtual disk at minimum */
if (! checkvirtdisk()) {
lerror ("Unable to confirm usable virtual disk is present.");
}
- if (numintf <= 0) {
- lerror ("Unable to find any usable network interfaces.");
- goto shutdown;
- }
+ if (!vmnop) {
+ if (numintf <= 0) {
+ lerror ("Unable to find any usable network interfaces.");
+ goto shutdown;
+ }
- ce = connlist;
- while (!foundit && ce) {
- if (ce->isdefgw) {
- foundit = TRUE;
+ ce = connlist;
+ while (!foundit && ce) {
+ if (ce->isdefgw) {
+ foundit = TRUE;
+ }
+ else {
+ ce = ce->next;
+ }
}
- else {
- ce = ce->next;
+ if (ce == NULL) {
+ lerror ("Unable to find network interface with a default route.");
+ goto shutdown;
}
}
- if (ce == NULL) {
- lerror ("Unable to find network interface with a default route.");
- goto shutdown;
+
+ if (!vmnop) {
+ if (! buildcmdline(ce, indebug, noinit, &cmdline)) {
+ lerror ("Unable to generate command line for kernel.");
+ goto shutdown;
+ }
}
- if (! buildcmdline(ce, vmdebug, &cmdline)) {
- lerror ("Unable to generate command line for kernel.");
- goto shutdown;
- }
+
ldebug ("Generated kernel command line: %s", cmdline);
PROCESS_INFORMATION pi;
- if (! launchtorvm(&pi,
- ce->name,
- ce->macaddr,
- cmdline)) {
- lerror ("Unable to launch Qemu TorVM instance.");
- goto shutdown;
+ if (!vmnop) {
+ if (! launchtorvm(&pi,
+ ce->name,
+ ce->macaddr,
+ TOR_TAP_NAME,
+ cmdline)) {
+ lerror ("Unable to launch Qemu TorVM instance.");
+ goto shutdown;
+ }
}
+ else {
+ if (! spawnprocess(&pi, "qemu.exe")) {
+ lerror ("Unable to launch default Qemu instance.");
+ goto shutdown;
+ }
+ }
/* need to delay long enough to allow qemu to start and open tap device */
- Sleep (4000);
+ Sleep (2000);
if (! isrunning(&pi)) {
- lerror ("Tor VM failed to start properly.");
- goto shutdown;
+ buildcmdline(ce, FALSE, TRUE, &cmdline);
+ launchtorvm(&pi,
+ ce->name,
+ ce->macaddr,
+ NULL,
+ cmdline);
+ /* need to delay long enough to allow qemu to start and open tap device */
+ Sleep (2000);
+ if (! isrunning(&pi)) {
+ lerror ("Tor VM no tap fallback failed to start properly.");
+ goto shutdown;
+ }
}
-
- if (! configtap()) {
- lerror ("Unable to configure tap device. Exiting.");
- goto shutdown;
+ else {
+ if (! configtap()) {
+ lerror ("Unable to configure tap device. Exiting.");
+ goto shutdown;
+ }
}
waitforit(&pi);
@@ -1795,9 +1728,16 @@
linfo ("Tor VM closed, restoring host network and services.");
shutdown:
+ if (getosversion() > OS_2000) {
+ if (! enablefirewall()) {
+ lerror ("Unable to re-enable windows firewall.");
+ }
+ }
+ /* TEMP: leave for now ....
if (! uninstalltap()) {
lerror ("Unable to remove TAP-Win32 device.");
}
+ */
if (! uninstalltornpf()) {
lerror ("Unable to remove Tor NPF service driver.");
}
Added: torvm/trunk/build/win32/src/torvm-w32/torvm.h
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/torvm.h (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/torvm.h 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,13 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#ifndef __torvm_h__
+#define __torvm_h__
+
+#include "vmconfig.h"
+#include "apicommon.h"
+#include "creds.h"
+#include "registry.h"
+#include "thrpool.h"
+
+#endif /* torvm_h */
Added: torvm/trunk/build/win32/src/torvm-w32/vmconfig.h.in
===================================================================
--- torvm/trunk/build/win32/src/torvm-w32/vmconfig.h.in (rev 0)
+++ torvm/trunk/build/win32/src/torvm-w32/vmconfig.h.in 2008-10-14 03:54:28 UTC (rev 17083)
@@ -0,0 +1,23 @@
+/* Copyright (C) 2008 The Tor Project, Inc.
+ * See LICENSE file for rights and terms.
+ */
+#ifndef __vmconfig_h__
+#define __vmconfig_h__
+
+/* by default temporarily disable driver signature checking to install tap
+ * adapter without the pointless unsigned driver prompt.
+ */
+#ifndef _DISABLE_DRIVER_SIGCHECK
+#define _DISABLE_DRIVER_SIGCHECK
+#endif
+
+/* set default network configuration parameters for host and vm
+ */
+#ifndef _DEFAULT_TAP_ADDR
+#define _DEFAULT_TAP_ADDR "10.10.10.1/29"
+#endif
+#ifndef _DEFAULT_NULLRT_ADDR
+#define _DEFAULT_NULLRT_ADDR "10.231.254.1/31"
+#endif
+
+#endif /* vmconfig_h */