--- /dev/null
+/*\r
+\r
+ Copyright (C) 1998 Danilo Almeida. All rights reserved.\r
+\r
+ automatic stack-based locking object\r
+\r
+ This file is part of FIFS (Framework for Implementing File Systems). \r
+\r
+ This software is distributed with NO WARRANTY OF ANY KIND. No\r
+ author or distributor accepts any responsibility for the\r
+ consequences of using it, or for whether it serves any particular\r
+ purpose or works at all, unless he or she says so in writing.\r
+ Refer to the included modified Alladin Free Public License (the\r
+ "License") for full details.\r
+\r
+ Every copy of this software must include a copy of the License, in\r
+ a plain ASCII text file named COPYING. The License grants you the\r
+ right to copy, modify and redistribute this software, but only\r
+ under certain conditions described in the License. Among other\r
+ things, the License requires that the copyright notice and this\r
+ notice be preserved on all copies.\r
+\r
+*/\r
+\r
+#ifndef __AUTOLOCK_HXX__\r
+#define __AUTOLOCK_HXX__\r
+\r
+#include <windows.h>\r
+\r
+class CcOsLock {\r
+ CRITICAL_SECTION cs;\r
+ bool valid;\r
+public:\r
+ CcOsLock() {InitializeCriticalSection(&cs); valid = true; }\r
+ ~CcOsLock() {DeleteCriticalSection(&cs); valid = false;}\r
+ void lock() {if (valid) EnterCriticalSection(&cs);}\r
+ void unlock() {if (valid) LeaveCriticalSection(&cs);}\r
+#if 0\r
+ bool trylock() {return valid ? (TryEnterCriticalSection(&cs) ? true : false)\r
+ : false; }\r
+#endif\r
+};\r
+\r
+class CcAutoLock {\r
+ CcOsLock& m_lock;\r
+public:\r
+ static void Start(CcAutoLock*& a, CcOsLock& lock) { a = new CcAutoLock(lock); };\r
+ static void Stop (CcAutoLock*& a) { delete a; a = 0; };\r
+ CcAutoLock(CcOsLock& lock):m_lock(lock) { m_lock.lock(); }\r
+ ~CcAutoLock() { m_lock.unlock(); }\r
+};\r
+\r
+#endif /* __AUTOLOCK_HXX */\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include "init.hxx"\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+ }\r
+\r
+\r
+CcOsLock Init::s_lock;\r
+DWORD Init::s_refcount = 0;\r
+DWORD Init::s_error = ERROR_INVALID_HANDLE;\r
+bool Init::s_init = false;\r
+Init::InitInfo Init::s_info = { 0 };\r
+HINSTANCE Init::s_hRpcDll = 0;\r
+\r
+#define INIT "INIT: "\r
+\r
+static\r
+void\r
+ShowInfo(\r
+ Init::InitInfo& info\r
+ );\r
+\r
+DWORD\r
+Init::Info(\r
+ InitInfo& info\r
+ )\r
+{\r
+ // This funciton will not do automatic initialization.\r
+ CcAutoLock AL(s_lock);\r
+ if (!s_init) {\r
+ memset(&info, 0, sizeof(info));\r
+ return s_error ? s_error : ERROR_INVALID_HANDLE;\r
+ } else {\r
+ info = s_info;\r
+ return 0;\r
+ }\r
+}\r
+\r
+DWORD\r
+Init::Initialize() {\r
+ CcAutoLock AL(s_lock);\r
+ cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init);\r
+ if (s_init) {\r
+ s_refcount++;\r
+ return 0;\r
+ }\r
+ SecureClient s;\r
+ DWORD status = 0;\r
+ OSVERSIONINFO osvi;\r
+ BOOL isSupportedVersion = FALSE;\r
+ memset(&s_info, 0, sizeof(s_info));\r
+ memset(&osvi, 0, sizeof(osvi));\r
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+ status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK.\r
+\r
+ if (!status) {\r
+ switch(osvi.dwPlatformId) {\r
+ case VER_PLATFORM_WIN32_WINDOWS:\r
+ s_info.isNT = FALSE;\r
+ isSupportedVersion = TRUE;\r
+ break;\r
+ case VER_PLATFORM_WIN32_NT:\r
+ s_info.isNT = TRUE;\r
+ isSupportedVersion = TRUE;\r
+ break;\r
+ case VER_PLATFORM_WIN32s:\r
+ default:\r
+ s_info.isNT = FALSE;\r
+ break;\r
+ }\r
+ \r
+ if (!isSupportedVersion) {\r
+ cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__);\r
+ status = 1;\r
+ }\r
+ }\r
+\r
+ if (!status) {status = !s_info.isNT;}\r
+\r
+ if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));}\r
+\r
+ if (!status) {\r
+ s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx)\r
+ GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx));\r
+ if (!s_info.fRpcBindingSetAuthInfoEx) {\r
+ cci_debug_printf(" Running on NT but could not find RpcBindinSetAuthInfoEx");\r
+ status = 1;\r
+ }\r
+ }\r
+ \r
+ if (!status) {\r
+ s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx)\r
+ GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx));\r
+ if (!s_info.fRpcServerRegisterIfEx) {\r
+ cci_debug_printf(" Running on NT but could not find RpcServerRegisterIfEx");\r
+ status = 1;\r
+ }\r
+ }\r
+\r
+ if (!status) {\r
+ status = SecureClient::Attach();\r
+ if (status) {\r
+ cci_debug_printf(" SecureClient::Attach() failed (%u)", status);\r
+ }\r
+ }\r
+\r
+ if (status) {\r
+ memset(&s_info, 0, sizeof(s_info));\r
+ if (s_hRpcDll) {\r
+ FreeLibrary(s_hRpcDll);\r
+ s_hRpcDll = 0;\r
+ }\r
+ cci_debug_printf(" Init::Attach() failed (%u)", status);\r
+ } else {\r
+ s_refcount++;\r
+ s_init = true;\r
+ ShowInfo(s_info);\r
+ }\r
+ s_error = status;\r
+ return status;\r
+}\r
+\r
+DWORD\r
+Init::Cleanup(\r
+ )\r
+{\r
+ CcAutoLock AL(s_lock);\r
+ s_refcount--;\r
+ if (s_refcount) return 0;\r
+ if (!s_init) return 0;\r
+ DWORD error = 0;\r
+ if (s_hRpcDll) {\r
+ FreeLibrary(s_hRpcDll);\r
+ s_hRpcDll = 0;\r
+ }\r
+ error = SecureClient::Detach();\r
+ memset(&s_info, 0, sizeof(s_info));\r
+ s_init = false;\r
+ s_error = 0;\r
+ if (error) {\r
+ cci_debug_printf(" Init::Detach() had an error (%u)", error);\r
+ }\r
+ return error;\r
+}\r
+\r
+static\r
+void\r
+ShowInfo(\r
+ Init::InitInfo& info\r
+ )\r
+{\r
+ if (info.isNT) {\r
+ cci_debug_printf(" Running on Windows NT using secure mode");\r
+ } else {\r
+ cci_debug_printf(" Running insecurely on non-NT Windows");\r
+ }\r
+ return;\r
+}\r
--- /dev/null
+;LIBRARY COMERR32\r
+HEAPSIZE 8192\r
+\r
+EXPORTS\r
+
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+\r
+#include "cci_debugging.h"\r
+#include "util.h"\r
+\r
+BOOL isNT() {\r
+ OSVERSIONINFO osvi;\r
+ DWORD status = 0;\r
+ BOOL bSupportedVersion = FALSE;\r
+ BOOL bIsNT = FALSE;\r
+\r
+ memset(&osvi, 0, sizeof(osvi));\r
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+ status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK.\r
+\r
+ if (!status) {\r
+ switch(osvi.dwPlatformId) {\r
+ case VER_PLATFORM_WIN32_WINDOWS:\r
+ bIsNT = FALSE;\r
+ bSupportedVersion = TRUE;\r
+ break;\r
+ case VER_PLATFORM_WIN32_NT:\r
+ bIsNT = TRUE;\r
+ bSupportedVersion = TRUE;\r
+ break;\r
+ case VER_PLATFORM_WIN32s:\r
+ default:\r
+ bIsNT = FALSE;\r
+ break;\r
+ }\r
+ \r
+ if (!bSupportedVersion) {\r
+ cci_debug_printf("%s Running on an unsupported version of Windows", __FUNCTION__);\r
+ status = 1;\r
+ }\r
+ }\r
+\r
+ return (!status && bIsNT && bSupportedVersion);\r
+ }\r
+\r
+char* allocEventName(char* uuid_string, char* suffix) {\r
+ LPSTR event_name = NULL;\r
+ cc_int32 err = ccNoError;\r
+\r
+ event_name = malloc(strlen(uuid_string) + strlen(suffix) + 3);\r
+ if (!event_name) err = cci_check_error(ccErrNoMem);\r
+\r
+ if (!err) {\r
+ strcpy(event_name, uuid_string);\r
+ strcat(event_name, "_");\r
+ strcat(event_name, suffix);\r
+ }\r
+\r
+ return event_name;\r
+ }\r
+\r
+HANDLE createThreadEvent(char* uuid, char* suffix) {\r
+ LPSTR event_name = NULL;\r
+ HANDLE hEvent = NULL;\r
+ PSECURITY_ATTRIBUTES psa = 0; // Everything having to do with\r
+ SECURITY_ATTRIBUTES sa = { 0 }; // sa, psa, security is copied\r
+ DWORD status = 0; // from the previous implementation.\r
+\r
+ psa = isNT() ? &sa : 0;\r
+\r
+ if (isNT()) {\r
+ sa.nLength = sizeof(sa);\r
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);\r
+ cci_check_error(status);\r
+ }\r
+\r
+ if (!status) {\r
+ event_name = allocEventName(uuid, suffix);\r
+ if (!event_name) status = cci_check_error(ccErrNoMem);\r
+ }\r
+ cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name);\r
+ \r
+ if (!status) {\r
+ hEvent = CreateEvent(psa, FALSE, FALSE, event_name);\r
+ if (!hEvent) status = cci_check_error(GetLastError());\r
+ }\r
+\r
+ if (!status) ResetEvent(hEvent);\r
+\r
+ \r
+ if (event_name) free(event_name);\r
+ if (isNT()) free(sa.lpSecurityDescriptor);\r
+\r
+ return hEvent;\r
+ }\r
+\r
+HANDLE openThreadEvent(char* uuid, char* suffix) {\r
+ LPSTR event_name = NULL;\r
+ HANDLE hEvent = NULL;\r
+ DWORD status = 0;\r
+\r
+ event_name = allocEventName(uuid, suffix);\r
+ if (!event_name) status = cci_check_error(ccErrNoMem);\r
+ cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name);\r
+\r
+ if (!status) {\r
+ hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);\r
+ if (!hEvent) status = cci_check_error(GetLastError());\r
+ }\r
+\r
+ if (event_name) free(event_name);\r
+\r
+ return hEvent;\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef __CCUTILS_H__\r
+#define __CCUTILS_H__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+#if 0\r
+}\r
+#endif\r
+\r
+#define REPLY_SUFFIX (char*)"reply"\r
+#define LISTEN_SUFFIX (char*)"listen"\r
+\r
+BOOL isNT();\r
+char* allocEventName (char* uuid, char* suffix);\r
+HANDLE createThreadEvent(char* uuid, char* suffix);\r
+HANDLE openThreadEvent (char* uuid, char* suffix);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __CCUTILS_H__ */\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include "init.hxx"\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+ }\r
+\r
+\r
+CcOsLock Init::s_lock;\r
+DWORD Init::s_refcount = 0;\r
+DWORD Init::s_error = ERROR_INVALID_HANDLE;\r
+bool Init::s_init = false;\r
+Init::InitInfo Init::s_info = { 0 };\r
+HINSTANCE Init::s_hRpcDll = 0;\r
+\r
+#define INIT "INIT: "\r
+\r
+static\r
+void\r
+ShowInfo(\r
+ Init::InitInfo& info\r
+ );\r
+\r
+DWORD\r
+Init::Info(\r
+ InitInfo& info\r
+ )\r
+{\r
+ // This funciton will not do automatic initialization.\r
+ CcAutoLock AL(s_lock);\r
+ if (!s_init) {\r
+ memset(&info, 0, sizeof(info));\r
+ return s_error ? s_error : ERROR_INVALID_HANDLE;\r
+ } else {\r
+ info = s_info;\r
+ return 0;\r
+ }\r
+}\r
+\r
+DWORD\r
+Init::Initialize() {\r
+ CcAutoLock AL(s_lock);\r
+// cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init);\r
+ if (s_init) {\r
+ s_refcount++;\r
+ return 0;\r
+ }\r
+ SecureClient s;\r
+ DWORD status = 0;\r
+ OSVERSIONINFO osvi;\r
+ BOOL isSupportedVersion = FALSE;\r
+ memset(&s_info, 0, sizeof(s_info));\r
+ memset(&osvi, 0, sizeof(osvi));\r
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+ status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK.\r
+\r
+ if (!status) {\r
+ switch(osvi.dwPlatformId) {\r
+ case VER_PLATFORM_WIN32_WINDOWS:\r
+ s_info.isNT = FALSE;\r
+ isSupportedVersion = TRUE;\r
+ break;\r
+ case VER_PLATFORM_WIN32_NT:\r
+ s_info.isNT = TRUE;\r
+ isSupportedVersion = TRUE;\r
+ break;\r
+ case VER_PLATFORM_WIN32s:\r
+ default:\r
+ s_info.isNT = FALSE;\r
+ break;\r
+ }\r
+ \r
+ if (!isSupportedVersion) {\r
+ cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__);\r
+ status = 1;\r
+ }\r
+ }\r
+\r
+ if (!status) {status = !s_info.isNT;}\r
+\r
+ if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));}\r
+\r
+ if (!status) {\r
+ s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx)\r
+ GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx));\r
+ if (!s_info.fRpcBindingSetAuthInfoEx) {\r
+ cci_debug_printf(" Running on NT but could not find RpcBindinSetAuthInfoEx");\r
+ status = 1;\r
+ }\r
+ }\r
+ \r
+ if (!status) {\r
+ s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx)\r
+ GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx));\r
+ if (!s_info.fRpcServerRegisterIfEx) {\r
+ cci_debug_printf(" Running on NT but could not find RpcServerRegisterIfEx");\r
+ status = 1;\r
+ }\r
+ }\r
+\r
+ if (!status) {\r
+ status = SecureClient::Attach();\r
+ if (status) {\r
+ cci_debug_printf(" SecureClient::Attach() failed (%u)", status);\r
+ }\r
+ }\r
+\r
+ if (status) {\r
+ memset(&s_info, 0, sizeof(s_info));\r
+ if (s_hRpcDll) {\r
+ FreeLibrary(s_hRpcDll);\r
+ s_hRpcDll = 0;\r
+ }\r
+ cci_debug_printf(" Init::Attach() failed (%u)", status);\r
+ } else {\r
+ s_refcount++;\r
+ s_init = true;\r
+ ShowInfo(s_info);\r
+ }\r
+ s_error = status;\r
+ return status;\r
+}\r
+\r
+DWORD\r
+Init::Cleanup(\r
+ )\r
+{\r
+ CcAutoLock AL(s_lock);\r
+ s_refcount--;\r
+ if (s_refcount) return 0;\r
+ if (!s_init) return 0;\r
+ DWORD error = 0;\r
+ if (s_hRpcDll) {\r
+ FreeLibrary(s_hRpcDll);\r
+ s_hRpcDll = 0;\r
+ }\r
+ error = SecureClient::Detach();\r
+ memset(&s_info, 0, sizeof(s_info));\r
+ s_init = false;\r
+ s_error = 0;\r
+ if (error) {\r
+ cci_debug_printf(" Init::Detach() had an error (%u)", error);\r
+ }\r
+ return error;\r
+}\r
+\r
+static\r
+void\r
+ShowInfo(\r
+ Init::InitInfo& info\r
+ )\r
+{\r
+ if (info.isNT) {\r
+ cci_debug_printf(" Running on Windows NT using secure mode");\r
+ } else {\r
+ cci_debug_printf(" Running insecurely on non-NT Windows");\r
+ }\r
+ return;\r
+}\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+#include "autolock.hxx"\r
+#include <rpc.h>\r
+\r
+typedef RPC_STATUS (RPC_ENTRY *FP_RpcBindingSetAuthInfoExA)(\r
+ IN RPC_BINDING_HANDLE Binding,\r
+ IN unsigned char __RPC_FAR * ServerPrincName,\r
+ IN unsigned long AuthnLevel,\r
+ IN unsigned long AuthnSvc,\r
+ IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL\r
+ IN unsigned long AuthzSvc,\r
+ IN RPC_SECURITY_QOS *SecurityQos OPTIONAL\r
+ );\r
+\r
+typedef RPC_STATUS (RPC_ENTRY *FP_RpcBindingSetAuthInfoExW)(\r
+ IN RPC_BINDING_HANDLE Binding,\r
+ IN unsigned short __RPC_FAR * ServerPrincName,\r
+ IN unsigned long AuthnLevel,\r
+ IN unsigned long AuthnSvc,\r
+ IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL\r
+ IN unsigned long AuthzSvc, OPTIONAL\r
+ IN RPC_SECURITY_QOS *SecurityQOS\r
+ );\r
+\r
+typedef RPC_STATUS (RPC_ENTRY *FP_RpcServerRegisterIfEx)(\r
+ IN RPC_IF_HANDLE IfSpec,\r
+ IN UUID __RPC_FAR * MgrTypeUuid,\r
+ IN RPC_MGR_EPV __RPC_FAR * MgrEpv,\r
+ IN unsigned int Flags,\r
+ IN unsigned int MaxCalls,\r
+ IN RPC_IF_CALLBACK_FN __RPC_FAR *IfCallback\r
+ );\r
+\r
+#ifdef UNICODE\r
+#define FP_RpcBindingSetAuthInfoEx FP_RpcBindingSetAuthInfoExW\r
+#define FN_RpcBindingSetAuthInfoEx "RpcBindingSetAuthInfoExW"\r
+#else\r
+#define FP_RpcBindingSetAuthInfoEx FP_RpcBindingSetAuthInfoExA\r
+#define FN_RpcBindingSetAuthInfoEx "RpcBindingSetAuthInfoExA"\r
+#endif\r
+\r
+#define FN_RpcServerRegisterIfEx "RpcServerRegisterIfEx"\r
+\r
+class Init\r
+{\r
+public:\r
+ struct InitInfo {\r
+ BOOL isNT;\r
+ FP_RpcBindingSetAuthInfoEx fRpcBindingSetAuthInfoEx;\r
+ FP_RpcServerRegisterIfEx fRpcServerRegisterIfEx;\r
+ };\r
+\r
+ static DWORD Initialize();\r
+ static DWORD Cleanup();\r
+ static DWORD Info(InitInfo& info);\r
+\r
+ static bool Initialized() { return s_init; }\r
+\r
+private:\r
+ static CcOsLock s_lock;\r
+ static DWORD s_refcount;\r
+ static DWORD s_error;\r
+ static bool s_init;\r
+ static InitInfo s_info;\r
+ static HINSTANCE s_hRpcDll;\r
+};\r
+\r
+#define INIT_INIT_EX(trap, error) \\r
+do \\r
+{ \\r
+ if (!Init::Initialized()) \\r
+ { \\r
+ DWORD rc = Init::Initialize(); \\r
+ if (rc) return (trap) ? (error) : rc; \\r
+ } \\r
+} while(0)\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+\r
+#ifdef _WIN64\r
+#define CCAPI_MODULE "krbcc64"\r
+#else\r
+#define CCAPI_MODULE "krbcc32"\r
+#endif\r
+#define CCAPI_DLL CCAPI_MODULE ".dll"\r
+#define CCAPI_EXE CCAPI_MODULE "s.exe"\r
+\r
+#define CCAPI_DLL "ccapi.dll"\r
+#define CCAPI_EXE "ccapiserver.exe"
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <opts.hxx>\r
+\r
+#if 0\r
+const struct Opts*\r
+GetOpts(\r
+ )\r
+{\r
+ bool done = false;\r
+ struct Opts* o;\r
+ if (!(o = new Opts))\r
+ goto cleanup;\r
+ if (!(o->pszString = new char[lstrlenA(opts.pszString) + 1]))\r
+ goto cleanup;\r
+ if (!(o->pszEndpoint = new char[lstrlenA(opts.pszEndpoint) + 1]))\r
+ goto cleanup;\r
+ strcpy(o->pszString, opts.pszString);\r
+ strcpy(o->pszEndpoint, opts.pszEndpoint);\r
+ done = true;\r
+ cleanup:\r
+ if (!done) {\r
+ FreeOpts(o);\r
+ o = 0;\r
+ }\r
+ return o;\r
+}\r
+\r
+void\r
+FreeOpts(\r
+ struct Opts* o\r
+ )\r
+{\r
+ if (o) {\r
+ if (o->pszString)\r
+ delete [] o->pszString;\r
+ if (o->pszEndpoint)\r
+ delete [] o->pszEndpoint;\r
+ delete o;\r
+ }\r
+}\r
+#endif\r
+\r
+bool\r
+ParseOpts::IsValidOpt(\r
+ char ch\r
+ )\r
+{\r
+ return (m_ValidOpts[ch % 256] != 0);\r
+}\r
+\r
+void\r
+ParseOpts::PrintOpt(\r
+ char ch,\r
+ char* text\r
+ )\r
+{\r
+ if (IsValidOpt(ch))\r
+ fprintf(stderr, " -%c %s\n", ch, text);\r
+}\r
+\r
+void\r
+ParseOpts::UsageOpts(\r
+ char * program,\r
+ int code\r
+ )\r
+{\r
+ fprintf(stderr, "Usage: %s [options]\n", program);\r
+ PrintOpt('k', "stop server");\r
+#ifdef CCAPI_TEST_OPTIONS\r
+ PrintOpt('s', "string");\r
+ PrintOpt('e', "endpoint");\r
+ PrintOpt('m', "maxcalls");\r
+ PrintOpt('n', "mincalls");\r
+ PrintOpt('f', "flag_wait_op");\r
+ PrintOpt('u', "unprotected");\r
+ PrintOpt('b', "use security callback");\r
+#endif\r
+ PrintOpt('c', "output debug info to console");\r
+ exit(code);\r
+}\r
+\r
+void\r
+ParseOpts::SetValidOpts(\r
+ char* valid_opts\r
+ )\r
+{\r
+ memset(m_ValidOpts, 0, sizeof(m_ValidOpts));\r
+ char *p = valid_opts;\r
+ for (p = valid_opts; *p; p++) {\r
+ m_ValidOpts[*p % sizeof(m_ValidOpts)] = 1;\r
+ }\r
+}\r
+\r
+void\r
+ParseOpts::Parse(\r
+ Opts& opts,\r
+ int argc,\r
+ char **argv\r
+ )\r
+{\r
+ int i;\r
+ for (i = 1; i < argc; i++) {\r
+ if ((*argv[i] == '-') || (*argv[i] == '/')) {\r
+ char ch = tolower(*(argv[i]+1));\r
+ if (!IsValidOpt(ch))\r
+ UsageOpts(argv[0]);\r
+ switch (ch) {\r
+ case 'k':\r
+ opts.bShutdown = TRUE;\r
+ break;\r
+#ifdef CCAPI_TEST_OPTIONS\r
+ case 's':\r
+ opts.pszString = argv[++i];\r
+ break;\r
+ case 'e':\r
+ opts.pszEndpoint = argv[++i];\r
+ break;\r
+ case 'm':\r
+ opts.cMaxCalls = (unsigned int) atoi(argv[++i]);\r
+ break;\r
+ case 'n':\r
+ opts.cMinCalls = (unsigned int) atoi(argv[++i]);\r
+ break;\r
+ case 'f':\r
+ opts.fDontWait = (unsigned int) atoi(argv[++i]);\r
+ break;\r
+ case 'u':\r
+ opts.bDontProtect = TRUE;\r
+ break;\r
+ case 'b':\r
+ opts.bSecCallback = TRUE;\r
+ break;\r
+#endif\r
+ case 'c':\r
+ opts.bConsole = TRUE;\r
+ break;\r
+ case 'h':\r
+ case '?':\r
+ default:\r
+ UsageOpts(argv[0]);\r
+ }\r
+ }\r
+ else\r
+ UsageOpts(argv[0]);\r
+ }\r
+\r
+}\r
+\r
+ParseOpts::ParseOpts(char* valid_opts)\r
+{\r
+ SetValidOpts(valid_opts);\r
+}\r
+\r
+ParseOpts::ParseOpts()\r
+{\r
+}\r
+\r
+ParseOpts::~ParseOpts()\r
+{\r
+}\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+\r
+class ParseOpts\r
+{\r
+public:\r
+ struct Opts {\r
+ char* pszString;\r
+ char* pszEndpoint;\r
+ unsigned int cMinCalls;\r
+ unsigned int cMaxCalls;\r
+ unsigned int fDontWait;\r
+ bool bDontProtect;\r
+ bool bShutdown;\r
+ bool bSecCallback;\r
+ bool bConsole;\r
+ };\r
+\r
+ ParseOpts(char* valid_opts);\r
+ ParseOpts();\r
+ ~ParseOpts();\r
+ void SetValidOpts(char* valid_opts);\r
+ void Parse(Opts& opts, int argc, char **argv);\r
+\r
+private:\r
+ bool IsValidOpt(char ch);\r
+ void PrintOpt(char ch, char* text);\r
+ void UsageOpts(char* program, int code = 0);\r
+\r
+ char m_ValidOpts[256];\r
+};\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+ }\r
+\r
+CcOsLock SecureClient::s_lock;\r
+DWORD SecureClient::s_refcount = 0;\r
+DWORD SecureClient::s_error = 0;\r
+HANDLE SecureClient::s_hToken = 0;\r
+\r
+#include "util.h"\r
+\r
+#define SC "SecureClient::"\r
+\r
+DWORD\r
+SecureClient::Attach(\r
+ )\r
+{\r
+ CcAutoLock AL(s_lock);\r
+ if (s_hToken) {\r
+ s_refcount++;\r
+ return 0;\r
+ }\r
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, \r
+ &s_hToken)) {\r
+ s_refcount++;\r
+ s_error = 0;\r
+ } else {\r
+ s_hToken = 0;\r
+ s_error = GetLastError();\r
+ }\r
+ return s_error;\r
+}\r
+\r
+DWORD\r
+SecureClient::Detach(\r
+ )\r
+{\r
+ CcAutoLock AL(s_lock);\r
+ s_refcount--;\r
+ if (s_refcount) return 0;\r
+ if (!s_hToken) return 0;\r
+ DWORD error = 0;\r
+ if (!CloseHandle(s_hToken))\r
+ error = GetLastError();\r
+ s_hToken = 0;\r
+ s_error = 0;\r
+ return error;\r
+}\r
+\r
+DWORD SecureClient::Token(HANDLE& hToken) {\r
+ // This function will not do automatic initialization.\r
+ CcAutoLock AL(s_lock);\r
+ hToken = 0;\r
+ if (!s_hToken) {\r
+ cci_debug_printf("%s no process token initialized (%u)", __FUNCTION__, s_error);\r
+ return s_error ? s_error : ERROR_INVALID_HANDLE;\r
+ } \r
+ else {\r
+ DWORD status = 0;\r
+ if (!DuplicateHandle(GetCurrentProcess(), s_hToken, \r
+ GetCurrentProcess(), &hToken, 0, FALSE, \r
+ DUPLICATE_SAME_ACCESS)) {\r
+ status = GetLastError();\r
+ cci_debug_printf(" Could not duplicate handle (%u)", status);\r
+ }\r
+ return status;\r
+ }\r
+ }\r
+\r
+void\r
+SecureClient::Start(SecureClient*& s) {\r
+ s = new SecureClient;\r
+}\r
+\r
+void\r
+SecureClient::Stop(SecureClient*& s) {\r
+ delete s;\r
+ s = 0;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+/* This constructor turns off impersonation.\r
+ * It is OK for OpenThreadToken to return an error -- that just means impersonation\r
+ * is off.\r
+ */\r
+SecureClient::SecureClient():\r
+ m_Error(0),\r
+ m_hToken(0),\r
+ m_NeedRestore(false) {\r
+\r
+ HANDLE hThread = GetCurrentThread();\r
+ HANDLE hThDuplicate;\r
+ \r
+ int status = DuplicateHandle( GetCurrentProcess(),\r
+ hThread,\r
+ GetCurrentProcess(),\r
+ &hThDuplicate,\r
+ TOKEN_ALL_ACCESS,\r
+ FALSE,\r
+ 0);\r
+ if (!status) return;\r
+\r
+ if (!OpenThreadToken(hThDuplicate, TOKEN_ALL_ACCESS, FALSE, &m_hToken)) {\r
+ m_Error = GetLastError();\r
+ return;\r
+ }\r
+ if (SetThreadToken(&hThDuplicate, NULL)) {\r
+ m_NeedRestore = true;\r
+ } else {\r
+ m_Error = GetLastError();\r
+ }\r
+ CloseHandle(hThDuplicate);\r
+ }\r
+\r
+SecureClient::~SecureClient() {\r
+ if (m_NeedRestore) {\r
+ HANDLE hThread = GetCurrentThread();\r
+ if (!SetThreadToken(&hThread, m_hToken)) {\r
+ m_Error = cci_check_error(GetLastError());\r
+ }\r
+ }\r
+ if (m_hToken) {\r
+ if (!CloseHandle(m_hToken)) {\r
+ m_Error = cci_check_error(GetLastError());\r
+ }\r
+ }\r
+ }\r
+\r
+DWORD SecureClient::Error() {\r
+ return m_Error;\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+\r
+#include <windows.h>\r
+#include "autolock.hxx"\r
+\r
+class SecureClient\r
+{\r
+public:\r
+ static DWORD Attach();\r
+ static DWORD Detach();\r
+ static DWORD Token(HANDLE& hToken);\r
+ static void Start(SecureClient*& s);\r
+ static void Stop(SecureClient*& s);\r
+\r
+#if 0\r
+ static DWORD CheckImpersonation();\r
+ static bool IsImp();\r
+ static DWORD DuplicateImpAsPrimary(HANDLE& hPrimary);\r
+#endif\r
+\r
+ SecureClient();\r
+ ~SecureClient();\r
+ DWORD Error();\r
+\r
+private:\r
+ static CcOsLock s_lock;\r
+ static DWORD s_refcount;\r
+ static DWORD s_error;\r
+ static HANDLE s_hToken;\r
+\r
+ DWORD m_Error;\r
+ HANDLE m_hToken;\r
+ bool m_NeedRestore;\r
+};\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <stdio.h> // for _snprintf\r
+\r
+#include "util.h"\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+#include "ccutils.h"\r
+ }\r
+\r
+\r
+\r
+void* malloc_alloc_p(size_t size) {\r
+ return malloc(size);\r
+ }\r
+\r
+void free_alloc_p(void *pptr) {\r
+ void **real_pptr = (void**)pptr;\r
+ if (*real_pptr) {\r
+ free(*real_pptr);\r
+ *real_pptr = 0;\r
+ }\r
+ }\r
+\r
+extern "C" DWORD alloc_textual_sid(\r
+ PSID pSid, // binary Sid\r
+ LPSTR *pTextualSid // buffer for Textual representaion of Sid\r
+ ) {\r
+ PSID_IDENTIFIER_AUTHORITY psia;\r
+ DWORD dwSubAuthorities;\r
+ DWORD dwSidRev = SID_REVISION;\r
+ DWORD dwCounter;\r
+ DWORD dwSidSize;\r
+\r
+ *pTextualSid = 0;\r
+\r
+ //\r
+ // test if Sid passed in is valid\r
+ //\r
+ if(!IsValidSid(pSid)) return ERROR_INVALID_PARAMETER;\r
+\r
+ // obtain SidIdentifierAuthority\r
+ psia = GetSidIdentifierAuthority(pSid);\r
+ \r
+ // obtain sidsubauthority count\r
+ dwSubAuthorities =* GetSidSubAuthorityCount(pSid);\r
+ \r
+ //\r
+ // compute buffer length\r
+ // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL\r
+ //\r
+ dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);\r
+ *pTextualSid = (LPSTR)malloc_alloc_p(dwSidSize);\r
+ if (!*pTextualSid)\r
+ return GetLastError();\r
+\r
+ LPSTR TextualSid = *pTextualSid;\r
+\r
+ //\r
+ // prepare S-SID_REVISION-\r
+ //\r
+ wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );\r
+ \r
+ //\r
+ // prepare SidIdentifierAuthority\r
+ //\r
+ if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )\r
+ {\r
+ wsprintf(TextualSid + lstrlen(TextualSid),\r
+ TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),\r
+ (USHORT)psia->Value[0],\r
+ (USHORT)psia->Value[1],\r
+ (USHORT)psia->Value[2],\r
+ (USHORT)psia->Value[3],\r
+ (USHORT)psia->Value[4],\r
+ (USHORT)psia->Value[5]);\r
+ }\r
+ else\r
+ {\r
+ wsprintf(TextualSid + lstrlen(TextualSid), TEXT("%lu"),\r
+ (ULONG)(psia->Value[5] ) +\r
+ (ULONG)(psia->Value[4] << 8) +\r
+ (ULONG)(psia->Value[3] << 16) +\r
+ (ULONG)(psia->Value[2] << 24) );\r
+ }\r
+ \r
+ //\r
+ // loop through SidSubAuthorities\r
+ //\r
+ for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)\r
+ {\r
+ wsprintf(TextualSid + lstrlen(TextualSid), TEXT("-%lu"),\r
+ *GetSidSubAuthority(pSid, dwCounter) );\r
+ }\r
+ return 0;\r
+}\r
+\r
+DWORD alloc_token_user(HANDLE hToken, PTOKEN_USER *pptu) {\r
+ DWORD status = 0;\r
+ DWORD size = 0;\r
+ *pptu = 0;\r
+\r
+ GetTokenInformation(hToken, TokenUser, *pptu, 0, &size);\r
+ if (size == 0) status = GetLastError();\r
+\r
+ if (!status) {\r
+ if (!(*pptu = (PTOKEN_USER)malloc_alloc_p(size)))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!GetTokenInformation(hToken, TokenUser, *pptu, size, &size))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (status && *pptu) {\r
+ free_alloc_p(pptu);\r
+ }\r
+ return status;\r
+ }\r
+\r
+DWORD\r
+alloc_username(\r
+ PSID Sid,\r
+ LPSTR* pname,\r
+ LPSTR* pdomain = 0\r
+ )\r
+{\r
+ DWORD status = 0;\r
+ DWORD name_len = 0;\r
+ DWORD domain_len = 0;\r
+ SID_NAME_USE snu;\r
+ LPSTR name = 0;\r
+ LPSTR domain = 0;\r
+\r
+ *pname = 0;\r
+ if (pdomain) *pdomain = 0;\r
+\r
+ LookupAccountSidA(NULL, Sid, 0, &name_len, 0, &domain_len, &snu);\r
+ if ((name_len == 0) || (domain_len == 0)) status = GetLastError();\r
+\r
+ if (!status) {\r
+ if (!(name = (LPSTR)malloc_alloc_p(name_len))) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!(domain = (LPSTR)malloc_alloc_p(domain_len))) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!LookupAccountSidA(NULL, Sid, name, &name_len, domain, &domain_len, &snu)) status = GetLastError();\r
+ }\r
+\r
+ if (status) {\r
+ if (name) free_alloc_p(&name);\r
+ if (domain) free_alloc_p(&domain);\r
+ } \r
+ else {\r
+ if (pdomain) {\r
+ *pname = name;\r
+ *pdomain = domain;\r
+ } \r
+ else {\r
+ DWORD size = name_len + domain_len + 1;\r
+ *pname = (LPSTR)malloc_alloc_p(size);\r
+ if (!*pname) status = GetLastError();\r
+ else _snprintf(*pname, size, "%s\\%s", name, domain);\r
+ }\r
+ }\r
+ return status;\r
+ }\r
+\r
+DWORD get_authentication_id(HANDLE hToken, LUID* pAuthId) {\r
+ TOKEN_STATISTICS ts;\r
+ DWORD len;\r
+\r
+ if (!GetTokenInformation(hToken, TokenStatistics, &ts, sizeof(ts), &len))\r
+ return GetLastError();\r
+ *pAuthId = ts.AuthenticationId;\r
+ return 0;\r
+ }\r
+\r
+DWORD\r
+alloc_name_9x(\r
+ LPSTR* pname,\r
+ LPSTR postfix\r
+ )\r
+{\r
+ char prefix[] = "krbcc";\r
+ DWORD len = (sizeof(prefix) - 1) + 1 + strlen(postfix) + 1;\r
+\r
+ *pname = (LPSTR)malloc_alloc_p(len);\r
+ if (!*pname) return GetLastError();\r
+ _snprintf(*pname, len, "%s.%s", prefix, postfix);\r
+ return 0;\r
+}\r
+\r
+DWORD alloc_name_NT(LPSTR* pname, LPSTR postfix) {\r
+ DWORD status = 0;\r
+ HANDLE hToken = 0;\r
+ LUID auth_id;\r
+#ifdef _DEBUG\r
+ PTOKEN_USER ptu = 0;\r
+ LPSTR name = 0;\r
+ LPSTR domain = 0;\r
+ LPSTR sid = 0;\r
+#endif\r
+ char prefix[] = "krbcc";\r
+ // Play it safe and say 3 characters are needed per 8 bits (byte).\r
+ // Note that 20 characters are needed for a 64-bit number in\r
+ // decimal (plus one for the string termination.\r
+ // and include room for sessionId.\r
+ char lid[3*sizeof(LUID)+1+5];\r
+ DWORD sessionId;\r
+ DWORD len = 0;\r
+\r
+ *pname = 0;\r
+\r
+ status = SecureClient::Token(hToken);\r
+\r
+ if (!status) {\r
+ status = get_authentication_id(hToken, &auth_id);\r
+ }\r
+\r
+ if (!status) {\r
+ if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId))\r
+ sessionId = 0;\r
+ }\r
+\r
+#ifdef _DEBUG\r
+ if (!status) {status = alloc_token_user(hToken, &ptu);}\r
+ if (!status) {status = alloc_username(ptu->User.Sid, &name, &domain);}\r
+ if (!status) {status = alloc_textual_sid(ptu->User.Sid, &sid);}\r
+#endif\r
+\r
+ if (!status) {\r
+ _snprintf(lid, sizeof(lid), "%I64u.%u", auth_id, sessionId);\r
+ lid[sizeof(lid)-1] = 0; // be safe\r
+\r
+ len = (sizeof(prefix) - 1) + 1 + strlen(lid) + 1 + strlen(postfix) + 1;\r
+ *pname = (LPSTR)malloc_alloc_p(len);\r
+ if (!*pname) status = GetLastError();\r
+ }\r
+\r
+ //\r
+ // We used to allocate a name of the form:\r
+ // "prefix.domain.name.sid.lid.postfix" (usually under 80\r
+ // characters, depending on username). However, XP thought this\r
+ // was "invalid" (too long?) for some reason.\r
+ //\r
+ // Therefore, we now use "prefix.lid.postfix"\r
+ // and for Terminal server we use "prefix.lid.sessionId.postfix"\r
+ //\r
+\r
+ if (!status) {\r
+ _snprintf(*pname, len, "%s.%s.%s", prefix, lid, postfix);\r
+ }\r
+\r
+#ifdef _DEBUG\r
+ if (sid)\r
+ free_alloc_p(&sid);\r
+ if (name)\r
+ free_alloc_p(&name);\r
+ if (domain)\r
+ free_alloc_p(&domain);\r
+ if (ptu)\r
+ free_alloc_p(&ptu);\r
+#endif\r
+ if (hToken && hToken != INVALID_HANDLE_VALUE)\r
+ CloseHandle(hToken);\r
+ if (status && *pname)\r
+ free_alloc_p(pname);\r
+ return status;\r
+}\r
+\r
+extern "C" DWORD alloc_name(LPSTR* pname, LPSTR postfix, BOOL isNT) {\r
+ return isNT ? alloc_name_NT(pname, postfix) : \r
+ alloc_name_9x(pname, postfix);\r
+ }\r
+\r
+extern "C" DWORD alloc_own_security_descriptor_NT(PSECURITY_DESCRIPTOR* ppsd) {\r
+ DWORD status = 0;\r
+ HANDLE hToken = 0;\r
+ PTOKEN_USER ptu = 0;\r
+ PSID pSid = 0;\r
+ PACL pAcl = 0;\r
+ DWORD size = 0;\r
+ SECURITY_DESCRIPTOR sd;\r
+\r
+ *ppsd = 0;\r
+\r
+ if (!status) {status = SecureClient::Token(hToken);}\r
+\r
+ // Get SID:\r
+ if (!status) {status = alloc_token_user(hToken, &ptu);}\r
+\r
+ if (!status) {\r
+ size = GetLengthSid(ptu->User.Sid);\r
+ pSid = (PSID) malloc_alloc_p(size);\r
+ if (!pSid) status = GetLastError();\r
+ }\r
+ if (!status) {\r
+ if (!CopySid(size, pSid, ptu->User.Sid)) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ // Prepare ACL:\r
+ size = sizeof(ACL);\r
+ // Add an ACE:\r
+ size += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid);\r
+ pAcl = (PACL) malloc_alloc_p(size);\r
+ if (!pAcl) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!InitializeAcl(pAcl, size, ACL_REVISION)) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSid)) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ // Prepare SD itself:\r
+ if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!SetSecurityDescriptorOwner(&sd, pSid, FALSE)) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!IsValidSecurityDescriptor(&sd)) status = ERROR_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!status) {\r
+ // We now have a SD. Let's copy it.\r
+ {\r
+ // This should not succeed. Instead it should give us the size.\r
+ BOOL ok = MakeSelfRelativeSD(&sd, 0, &size);\r
+ }\r
+ if (size == 0) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ *ppsd = (PSECURITY_DESCRIPTOR) malloc_alloc_p(size);\r
+ if (!*ppsd) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!MakeSelfRelativeSD(&sd, *ppsd, &size)) status = GetLastError();\r
+ }\r
+\r
+ if (ptu) free_alloc_p(&ptu);\r
+ if (pSid) free_alloc_p(&pSid);\r
+ if (pAcl) free_alloc_p(&pAcl);\r
+ if (hToken && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);\r
+ if (status && *ppsd) free_alloc_p(ppsd);\r
+ return status;\r
+}\r
+\r
+DWORD\r
+alloc_module_file_name(\r
+ char* module,\r
+ char** pname\r
+ )\r
+{\r
+ const DWORD max = 8192;\r
+ DWORD status = 0;\r
+ DWORD got = 0;\r
+ DWORD size = 512; // use low number to test...\r
+ HMODULE h = 0;\r
+ BOOL ok = FALSE;\r
+ char* name = 0;\r
+\r
+ if (!pname)\r
+ return ERROR_INVALID_PARAMETER;\r
+ *pname = 0;\r
+\r
+ h = GetModuleHandle(module);\r
+\r
+ if (!h) return GetLastError();\r
+\r
+ // We assume size < max and size > 0\r
+ while (!status && !ok) {\r
+ if (size > max) {\r
+ // XXX - Assert?\r
+ status = ERROR_INVALID_DATA;\r
+ continue;\r
+ }\r
+ if (name) free_alloc_p(&name);\r
+ name = (char*)malloc_alloc_p(size + 1);\r
+ if (!name) {\r
+ status = ERROR_NOT_ENOUGH_MEMORY;\r
+ continue;\r
+ }\r
+ name[size] = 0;\r
+ got = GetModuleFileName(h, name, size);\r
+ if (!got) {\r
+ status = GetLastError();\r
+ // sanity check:\r
+ if (!status) {\r
+ // XXX - print nasty message...assert?\r
+ status = ERROR_INVALID_DATA;\r
+ }\r
+ continue;\r
+ }\r
+ // To know we're ok, we need to verify that what we got\r
+ // was bigger than GetModuleSize thought it got.\r
+ ok = got && (got < size) && !name[got];\r
+ size *= 2;\r
+ }\r
+ if (status && name)\r
+ free_alloc_p(&name);\r
+ else\r
+ *pname = name;\r
+ return status;\r
+}\r
+\r
+DWORD\r
+alloc_module_dir_name(\r
+ char* module,\r
+ char** pname\r
+ )\r
+{\r
+ DWORD status = alloc_module_file_name(module, pname);\r
+ if (!status) {\r
+ char* name = *pname;\r
+ char* p = name + strlen(name);\r
+ while ((p >= name) && (*p != '\\') && (*p != '/')) p--;\r
+ if (p < name) {\r
+ free_alloc_p(pname);\r
+ status = ERROR_INVALID_DATA;\r
+ } else {\r
+ *p = 0;\r
+ }\r
+ }\r
+ return status;\r
+}\r
+\r
+DWORD\r
+alloc_module_dir_name_with_file(\r
+ char* module,\r
+ char* file,\r
+ char** pname\r
+ )\r
+{\r
+ DWORD status = alloc_module_dir_name(module, pname);\r
+ if (!status) {\r
+ char* name = *pname;\r
+ size_t name_size = strlen(name);\r
+ size_t size = name_size + 1 + strlen(file) + 1;\r
+ char* result = (char*)malloc_alloc_p(size);\r
+ if (!result) {\r
+ status = ERROR_NOT_ENOUGH_MEMORY;\r
+ free_alloc_p(pname);\r
+ } else {\r
+ strcpy(result, name);\r
+ result[name_size] = '\\';\r
+ strcpy(result + name_size + 1, file);\r
+ free_alloc_p(pname);\r
+ *pname = result;\r
+ }\r
+ }\r
+ return status;\r
+}\r
+\r
+DWORD alloc_cmdline_2_args(char* prog,\r
+ char* arg1,\r
+ char* arg2,\r
+ char** pname) {\r
+ DWORD status = 0;\r
+ size_t size = strlen(prog) + strlen(arg1) + strlen(arg2) + 4;\r
+ char* result = (char*)malloc_alloc_p(size);\r
+ if (!result) {\r
+ status = ERROR_NOT_ENOUGH_MEMORY;\r
+ } \r
+ else {\r
+ strcpy(result, prog);\r
+ strcat(result, " ");\r
+ strcat(result, arg1);\r
+ strcat(result, " ");\r
+ strcat(result, arg2);\r
+ *pname = result;\r
+ }\r
+ cci_debug_printf("%s made <%s>", __FUNCTION__, result);\r
+ return status;\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef __UTIL_H__\r
+#define __UTIL_H__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+#if 0\r
+}\r
+#endif\r
+\r
+BOOL isNT();\r
+\r
+void*\r
+user_allocate(\r
+ size_t size\r
+ );\r
+\r
+void\r
+user_free(\r
+ void* ptr\r
+ );\r
+\r
+void\r
+free_alloc_p(\r
+ void* pptr\r
+ );\r
+\r
+DWORD\r
+alloc_name(\r
+ LPSTR* pname,\r
+ LPSTR postfix,\r
+ BOOL isNT\r
+ );\r
+\r
+DWORD\r
+alloc_own_security_descriptor_NT(\r
+ PSECURITY_DESCRIPTOR* ppsd\r
+ );\r
+\r
+DWORD\r
+alloc_module_dir_name(\r
+ char* module,\r
+ char** pname\r
+ );\r
+\r
+DWORD\r
+alloc_module_dir_name_with_file(\r
+ char* module,\r
+ char* file,\r
+ char** pname\r
+ );\r
+\r
+DWORD alloc_cmdline_2_args(\r
+ char* prog,\r
+ char* arg1,\r
+ char* arg2,\r
+ char** pname);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __UTIL_H__ */\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdio.h> \r
+#include <stdarg.h>\r
+\r
+#include "cci_os_debugging.h"\r
+#include "win-utils.h"\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+void cci_os_debug_vprintf (const char *in_format, va_list in_args) {\r
+ printf ( "%s %ld ", timestamp(), GetCurrentThreadId() );\r
+ vprintf ( in_format, in_args );\r
+ printf ( "\n" );\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "cci_common.h"\r
+#include "cci_os_identifier.h"\r
+\r
+#include <rpc.h>\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) {\r
+ cc_int32 err = ccNoError;\r
+ UUID uuid;\r
+ char* uuidStringTemp;\r
+\r
+ err = UuidCreate(&uuid);\r
+\r
+ if (!err) {\r
+ err = UuidToString(&uuid, &uuidStringTemp);\r
+ }\r
+\r
+ if (!err) {\r
+ *out_uuid_string = malloc(1+strlen(uuidStringTemp));\r
+\r
+ if (*out_uuid_string) {\r
+ strcpy(*out_uuid_string, uuidStringTemp);\r
+ }\r
+\r
+ RpcStringFree(&uuidStringTemp);\r
+ }\r
+\r
+ cci_debug_printf("cci_os_identifier_new_uuid returning %s", *out_uuid_string);\r
+\r
+ return cci_check_error (err);\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[implicit_handle(handle_t ccs_reply_IfHandle)]\r
+\r
+interface ccs_reply {\r
+ [async] ccapi_listen();\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[ uuid (6E3B5060-CA46-1067-B31A-00DD010662DA),\r
+ version(1.0),\r
+ pointer_default(unique)\r
+]\r
+\r
+/* This interface sends a cci_stream via rpc.\r
+ */\r
+\r
+interface ccs_reply {\r
+ const long HSIZE = sizeof(void*);\r
+\r
+/* The reply from the server to a request from the client: */\r
+void ccs_rpc_request_reply(\r
+ [in] const long rpcmsg, /* Message type */\r
+ [in, size_is(HSIZE)] const char tsphandle[],\r
+ [in, string] const char* uuid,\r
+ [in] const long srvStartTime, /* Server Start Time */\r
+ [in] const long cbIn, /* Length of buffer */\r
+ [in, size_is(cbIn)] const unsigned char chIn[], /* Data buffer */\r
+ [out] long* status ); /* Return code */\r
+\r
+void ccs_rpc_connect_reply(\r
+ [in] const long rpcmsg, /* Message type */\r
+ [in, size_is(HSIZE)] const char tsphandle[],\r
+ [in, string] const char* uuid,\r
+ [in] const long srvStartTime, /* Server Start Time */\r
+ [out] long* status ); /* Return code */\r
+\r
+void ccapi_listen(\r
+ handle_t hBinding, \r
+ [in] const long rpcmsg, /* Message type */\r
+ [out] long* status ); /* Return code */\r
+\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[implicit_handle(handle_t ccs_request_IfHandle)]\r
+interface ccs_request\r
+{\r
+\r
+}\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[ uuid (906B0CE0-C70B-1067-B317-00DD010662DA),\r
+ version(1.0),\r
+ pointer_default(unique)\r
+]\r
+\r
+interface ccs_request {\r
+\r
+typedef char CC_CHAR;\r
+typedef unsigned char CC_UCHAR;\r
+typedef int CC_INT32;\r
+typedef unsigned int CC_UINT32;\r
+\r
+const long HSIZE = sizeof(void*);\r
+\r
+void ccs_rpc_request(\r
+ [in] const long rpcmsg, /* Message type */\r
+ [in, size_is(HSIZE)] const char tsphandle[],\r
+ [in, string] const char* pszUUID, /* Requestor's UUID */\r
+ [in] const long lenRequest, /* Length of buffer */\r
+ [in, size_is(lenRequest)] const char* pszRequest, /* Data buffer */\r
+ [in] const long serverStartTime,/* Which server session we're talking to */\r
+ [out] long* status ); /* Return code */\r
+\r
+void ccs_rpc_connect(\r
+ [in] const long rpcmsg, /* Message type */\r
+ [in, size_is(HSIZE)] const char tsphandle[],\r
+ [in, string] const char* pszUUID, /* Requestor's UUID */\r
+ [out] long* status ); /* Return code */\r
+\r
+CC_UINT32 ccs_authenticate(\r
+ [in, string] const CC_CHAR* name );\r
+}\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "string.h"\r
+\r
+#include "tls.h"\r
+\r
+struct tspdata* new_tspdata(char* uuid, time_t sst) {\r
+ struct tspdata* p = (struct tspdata*)malloc(sizeof(struct tspdata));\r
+ if (p) {\r
+ memset(p, 0, sizeof(struct tspdata));\r
+ p->_sst = sst;\r
+ if (uuid) {strncpy(p->_uuid, uuid, UUID_SIZE-1);}\r
+ }\r
+ return p;\r
+ }\r
+\r
+void delete_tspdata(struct tspdata* p) {\r
+ if (p) free(p);\r
+ }\r
+\r
+void tspdata_setUUID(struct tspdata* p, unsigned char __RPC_FAR* uuidString) {\r
+ strncpy(p->_uuid, uuidString, UUID_SIZE-1);\r
+ };\r
+\r
+void tspdata_setConnected (struct tspdata* p, BOOL b) {p->_CCAPI_Connected = b;}\r
+\r
+void tspdata_setReplyEvent(struct tspdata* p, HANDLE h) {p->_replyEvent = h;}\r
+\r
+void tspdata_setRpcAState (struct tspdata* p, RPC_ASYNC_STATE* rpcState) {\r
+ p->_rpcState = rpcState;}\r
+\r
+void tspdata_setSST (struct tspdata* p, time_t t) {p->_sst = t;}\r
+\r
+void tspdata_setStream (struct tspdata* p, cci_stream_t s) {p->_stream = s;}\r
+\r
+\r
+BOOL tspdata_getConnected (struct tspdata* p) {return p->_CCAPI_Connected;}\r
+\r
+HANDLE tspdata_getReplyEvent(struct tspdata* p) {return p->_replyEvent;}\r
+\r
+time_t tspdata_getSST (const struct tspdata* p) {return p->_sst;}\r
+\r
+cci_stream_t tspdata_getStream (const struct tspdata* p) {return p->_stream;}\r
+\r
+char* tspdata_getUUID (const struct tspdata* p) {return p->_uuid;}\r
+\r
+RPC_ASYNC_STATE* tspdata_getRpcAState (const struct tspdata* p) {return p->_rpcState;}\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+/* Thread local storage for client threads. */\r
+\r
+#ifndef _tls_h\r
+#define _tls_h\r
+\r
+#include "windows.h"\r
+#include "time.h"\r
+\r
+#include "cci_stream.h"\r
+\r
+#define UUID_SIZE 128\r
+\r
+/* The client code can be run in any client thread. The thread-specific data\r
+ is defined here.\r
+ */\r
+\r
+struct tspdata {\r
+ BOOL _CCAPI_Connected;\r
+ RPC_ASYNC_STATE* _rpcState;\r
+ HANDLE _replyEvent;\r
+ time_t _sst;\r
+ cci_stream_t _stream;\r
+ char _uuid[UUID_SIZE];\r
+ };\r
+\r
+struct tspdata* new_tspdata (char* uuid, time_t sst);\r
+void delete_tspdata (struct tspdata* p);\r
+\r
+void tspdata_setConnected (struct tspdata* p, BOOL b);\r
+void tspdata_setReplyEvent(struct tspdata* p, HANDLE h);\r
+void tspdata_setRpcAState (struct tspdata* p, RPC_ASYNC_STATE* rpcState);\r
+void tspdata_setSST (struct tspdata* p, time_t t);\r
+void tspdata_setStream (struct tspdata* p, cci_stream_t s);\r
+void tspdata_setUUID (struct tspdata* p, unsigned char __RPC_FAR* uuidString);\r
+HANDLE tspdata_getReplyEvent(const struct tspdata* p);\r
+\r
+BOOL tspdata_getConnected(const struct tspdata* p);\r
+RPC_ASYNC_STATE* tspdata_getRpcAState(const struct tspdata* p);\r
+time_t tspdata_getSST (const struct tspdata* p);\r
+cci_stream_t tspdata_getStream (const struct tspdata* p);\r
+char* tspdata_getUUID (const struct tspdata* p);\r
+\r
+\r
+#endif _tls_h\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <time.h>\r
+#include "windows.h"\r
+\r
+#include "win-utils.h"\r
+#include "cci_debugging.h"\r
+\r
+#pragma warning (disable : 4996)\r
+\r
+#define UUID_SIZE 128\r
+\r
+char* clientPrefix = "CCAPI_CLIENT_";\r
+char* serverPrefix = "CCS_LISTEN_";\r
+unsigned char* pszProtocolSequence = "ncalrpc";\r
+\r
+#define MAX_TIMESTAMP 40\r
+char _ts[MAX_TIMESTAMP];\r
+\r
+char* clientEndpoint(const char* UUID) {\r
+ char* _clientEndpoint = (char*)malloc(strlen(UUID) + strlen(clientPrefix) + 2);\r
+ strcpy(_clientEndpoint, clientPrefix);\r
+ strncat(_clientEndpoint, UUID, UUID_SIZE);\r
+// cci_debug_printf("%s returning %s", __FUNCTION__, _clientEndpoint);\r
+ return _clientEndpoint;\r
+ } \r
+\r
+char* serverEndpoint(const char* user) {\r
+ char* _serverEndpoint = (char*)malloc(strlen(user) + strlen(serverPrefix) + 2);\r
+ strcpy(_serverEndpoint, serverPrefix);\r
+ strncat(_serverEndpoint, user, UUID_SIZE);\r
+ return _serverEndpoint;\r
+ } \r
+\r
+char* timestamp() {\r
+ SYSTEMTIME _stime;\r
+ GetSystemTime(&_stime);\r
+ GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &_stime, "HH:mm:ss", _ts, sizeof(_ts)-1);\r
+ return _ts;\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _win_utils_h\r
+#define _win_utils_h\r
+\r
+#ifndef TRUE\r
+#define TRUE (1==1)\r
+#endif\r
+\r
+#ifndef FALSE\r
+#define FALSE (1==0)\r
+#endif\r
+\r
+static enum ccapiMsgType {\r
+ CCMSG_INVALID = 0,\r
+ CCMSG_CONNECT,\r
+ CCMSG_REQUEST,\r
+ CCMSG_CONNECT_REPLY,\r
+ CCMSG_REQUEST_REPLY,\r
+ CCMSG_DISCONNECT,\r
+ CCMSG_LISTEN,\r
+ CCMSG_PING\r
+ };\r
+\r
+char* clientEndpoint(const char* UUID);\r
+char* serverEndpoint(const char* UUID);\r
+extern unsigned char* pszProtocolSequence;\r
+\r
+char* timestamp();\r
+\r
+#endif // _win_utils_h
\ No newline at end of file
--- /dev/null
+!include <Win32.Mak>\r
+\r
+# . is ...\pismere\athena\auth\krb5\src\ccapi\lib\win\r
+CCAPI = ..\..\r
+CO = $(CCAPI)\common\r
+COWIN = $(CCAPI)\common\win\r
+CCUTIL = $(CCAPI)\common\win\OldCC \r
+LIBDIR = $(CCAPI)\lib\r
+LIBWIN = $(LIBDIR)\win\r
+K5SRC = $(CCAPI)\..\r
+POSIX = $(K5SRC)\lib\krb5\posix\r
+OLDCC = $(LIBWIN)\OldCC\r
+\r
+INC = -I.. -I$(CO) -I$(COWIN) -I$(K5SRC)\include -I..\..\..\util\et -I$(OLDCC) \\r
+ -I$(LIBWIN) -I$(CCUTIL)\r
+MIDLI = /I $(K5SRC)\include /I. /I$(COWIN) /I$(CO) \r
+\r
+!if "$(CPU)" == "i386"\r
+cflags = $(cflags) /EHsc /MDd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \\r
+$(INC) -D_CRT_SECURE_NO_WARNINGS\r
+!else\r
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)\r
+!endif\r
+\r
+!if "$(PREPROCESS)" == "P"\r
+cflags = $(cflags) -P\r
+!endif\r
+\r
+all : ccapi.dll\r
+\r
+common = cci_array_internal.obj cci_cred_union.obj cci_debugging.obj cci_identifier.obj \\r
+ cci_message.obj cci_stream.obj \r
+ \r
+commonwin = cci_os_debugging.obj \\r
+ cci_os_identifier.obj \\r
+ tls.obj \\r
+ win-utils.obj\r
+\r
+dll = ccapi_ccache.obj \\r
+ ccapi_ccache_iterator.obj \\r
+ ccapi_context.obj \\r
+ ccapi_context_change_time.obj \\r
+ ccapi_credentials.obj \\r
+ ccapi_credentials_iterator.obj \\r
+ ccapi_ipc.obj \\r
+ ccapi_string.obj \r
+\r
+dllwin = ccs_reply_s.obj \\r
+ ccs_reply_proc.obj \\r
+ ccs_request_c.obj \r
+ \r
+dllwincxx = ccapi_os_ipc.obj \\r
+ dllmain.obj\r
+ \r
+oldcc = client.obj \\r
+ rpc.obj \r
+ \r
+utils = ccutils.obj\r
+\r
+utilscxx = init.obj \\r
+ secure.obj \\r
+ util.obj\r
+\r
+\r
+linkobjs = $(common) $(commonwin) $(dll) $(dllwin) $(dllwincxx) $(oldcc) $(utils) $(utilscxx)\r
+\r
+#includes = \r
+\r
+# Main program:\r
+ccapi.dll : $(linkobjs) ccapi.def\r
+ $(link) $(linkdebug) $(conflags) -out:ccapi.dll /DEF:ccapi.def /implib:ccapi.lib $(dlllflags) \\r
+ $(linkobjs) rpcrt4.lib kernel32.lib user32.lib $(conlibsdll) \r
+\r
+\r
+ccs_request.h ccs_request_c.c ccs_request_s.c : $(COWIN)\ccs_request.idl $(COWIN)\ccs_request.acf\r
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" \\r
+ $(COWIN)\ccs_request.idl\r
+\r
+ccs_reply.h ccs_reply_c.c ccs_reply_s.c : $(COWIN)\ccs_reply.idl $(COWIN)\ccs_reply.acf\r
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) \\r
+ $(COWIN)\ccs_reply.idl\r
+\r
+$(common) : $(CO)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CO)\$*.c\r
+\r
+$(commonwin) : $(COWIN)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(COWIN)\$*.c\r
+\r
+$(dll) : $(LIBDIR)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBDIR)\$*.c\r
+\r
+$(dllwin) : $*.c ccs_reply.h ccs_request.h\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBWIN)\$*.c\r
+\r
+$(dllwincxx) : $*.cxx ccs_reply.h ccs_request.h\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBWIN)\$*.cxx\r
+\r
+$(oldcc) : $(OLDCC)\$*.cxx\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(OLDCC)\$*.cxx\r
+\r
+$(utils) : $(CCUTIL)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CCUTIL)\$*.c\r
+\r
+$(utilscxx) : $(CCUTIL)\$*.cxx\r
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CCUTIL)\$*.cxx\r
+\r
+\r
+\r
+# Clean up everything\r
+cleanall : clean\r
+ -del *.dll\r
+\r
+# Clean up everything but the .EXEs\r
+clean :\r
+ -del *.obj\r
+ -del *.map\r
--- /dev/null
+\r
+\r
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */\r
+\r
+\r
+ /* File created by MIDL compiler version 6.00.0366 */\r
+/* at Fri Nov 30 10:06:16 2007\r
+ */\r
+/* Compiler settings for ccapi.idl:\r
+ Oic, W1, Zp8, env=Win32 (32b run)\r
+ protocol : dce , ms_ext, c_ext, oldnames\r
+ error checks: allocation ref bounds_check enum stub_data \r
+ VC __declspec() decoration level: \r
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+ DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+//@@MIDL_FILE_HEADING( )\r
+\r
+#pragma warning( disable: 4049 ) /* more than 64k source lines */\r
+\r
+\r
+/* verify that the <rpcndr.h> version is high enough to compile this file*/\r
+#ifndef __REQUIRED_RPCNDR_H_VERSION__\r
+#define __REQUIRED_RPCNDR_H_VERSION__ 440\r
+#endif\r
+\r
+#include "rpc.h"\r
+#include "rpcndr.h"\r
+\r
+#ifndef __ccapi_h__\r
+#define __ccapi_h__\r
+\r
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
+#pragma once\r
+#endif\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+void * __RPC_USER MIDL_user_allocate(size_t);\r
+void __RPC_USER MIDL_user_free( void * ); \r
+\r
+#ifndef __ccapi_INTERFACE_DEFINED__\r
+#define __ccapi_INTERFACE_DEFINED__\r
+\r
+/* interface ccapi */\r
+/* [implicit_handle][unique][version][uuid] */ \r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CTX *HCTX;\r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CACHE *HCACHE;\r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CACHE_ITER *HCACHE_ITER;\r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CRED_ITER *HCRED_ITER;\r
+\r
+typedef unsigned char CC_CHAR;\r
+\r
+typedef unsigned char CC_UCHAR;\r
+\r
+typedef int CC_INT32;\r
+\r
+typedef unsigned int CC_UINT32;\r
+\r
+typedef CC_INT32 CC_TIME_T;\r
+\r
+\r
+enum __MIDL_ccapi_0001\r
+ { STK_AFS = 0,\r
+ STK_DES = 1\r
+ } ;\r
+\r
+enum __MIDL_ccapi_0002\r
+ { CC_API_VER_1 = 1,\r
+ CC_API_VER_2 = 2\r
+ } ;\r
+\r
+enum __MIDL_ccapi_0003\r
+ { KRB_NAME_SZ = 40,\r
+ KRB_INSTANCE_SZ = 40,\r
+ KRB_REALM_SZ = 40,\r
+ MAX_V4_CRED_LEN = 1250\r
+ } ;\r
+typedef struct _NC_INFO\r
+ {\r
+ /* [string] */ CC_CHAR *name;\r
+ /* [string] */ CC_CHAR *principal;\r
+ CC_INT32 vers;\r
+ } NC_INFO;\r
+\r
+typedef struct _NC_INFO_LIST\r
+ {\r
+ CC_UINT32 length;\r
+ /* [size_is] */ NC_INFO *info;\r
+ } NC_INFO_LIST;\r
+\r
+typedef struct _V4_CRED\r
+ {\r
+ CC_UCHAR kversion;\r
+ CC_CHAR principal[ 41 ];\r
+ CC_CHAR principal_instance[ 41 ];\r
+ CC_CHAR service[ 41 ];\r
+ CC_CHAR service_instance[ 41 ];\r
+ CC_CHAR realm[ 41 ];\r
+ CC_UCHAR session_key[ 8 ];\r
+ CC_INT32 kvno;\r
+ CC_INT32 str_to_key;\r
+ CC_INT32 issue_date;\r
+ CC_INT32 lifetime;\r
+ CC_UINT32 address;\r
+ CC_INT32 ticket_sz;\r
+ CC_UCHAR ticket[ 1250 ];\r
+ } V4_CRED;\r
+\r
+typedef struct _CC_DATA\r
+ {\r
+ CC_UINT32 type;\r
+ CC_UINT32 length;\r
+ /* [size_is] */ CC_UCHAR *data;\r
+ } CC_DATA;\r
+\r
+typedef struct _CC_DATA_LIST\r
+ {\r
+ CC_UINT32 count;\r
+ /* [size_is] */ CC_DATA *data;\r
+ } CC_DATA_LIST;\r
+\r
+typedef struct _V5_CRED\r
+ {\r
+ /* [string] */ CC_CHAR *client;\r
+ /* [string] */ CC_CHAR *server;\r
+ CC_DATA keyblock;\r
+ CC_TIME_T authtime;\r
+ CC_TIME_T starttime;\r
+ CC_TIME_T endtime;\r
+ CC_TIME_T renew_till;\r
+ CC_UINT32 is_skey;\r
+ CC_UINT32 ticket_flags;\r
+ CC_DATA_LIST addresses;\r
+ CC_DATA ticket;\r
+ CC_DATA second_ticket;\r
+ CC_DATA_LIST authdata;\r
+ } V5_CRED;\r
+\r
+typedef /* [switch_type] */ union _CRED_PTR_UNION\r
+ {\r
+ /* [case()] */ V4_CRED *pV4Cred;\r
+ /* [case()] */ V5_CRED *pV5Cred;\r
+ } CRED_PTR_UNION;\r
+\r
+typedef struct _CRED_UNION\r
+ {\r
+ CC_INT32 cred_type;\r
+ /* [switch_is] */ CRED_PTR_UNION cred;\r
+ } CRED_UNION;\r
+\r
+CC_INT32 rcc_initialize( \r
+ /* [out] */ HCTX *pctx);\r
+\r
+CC_INT32 rcc_shutdown( \r
+ /* [out][in] */ HCTX *pctx);\r
+\r
+CC_INT32 rcc_get_change_time( \r
+ /* [in] */ HCTX ctx,\r
+ /* [out] */ CC_TIME_T *time);\r
+\r
+CC_INT32 rcc_create( \r
+ /* [in] */ HCTX ctx,\r
+ /* [string][in] */ const CC_CHAR *name,\r
+ /* [string][in] */ const CC_CHAR *principal,\r
+ /* [in] */ CC_INT32 vers,\r
+ /* [in] */ CC_UINT32 flags,\r
+ /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_open( \r
+ /* [in] */ HCTX ctx,\r
+ /* [string][in] */ const CC_CHAR *name,\r
+ /* [in] */ CC_INT32 vers,\r
+ /* [in] */ CC_UINT32 flags,\r
+ /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_close( \r
+ /* [out][in] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_destroy( \r
+ /* [out][in] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs_begin( \r
+ /* [in] */ HCTX ctx,\r
+ /* [out] */ HCACHE_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs_end( \r
+ /* [out][in] */ HCACHE_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs_next( \r
+ /* [in] */ HCACHE_ITER iter,\r
+ /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs( \r
+ /* [in] */ HCTX ctx,\r
+ /* [out][in] */ HCACHE_ITER *piter,\r
+ /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_get_NC_info( \r
+ /* [in] */ HCTX ctx,\r
+ /* [out] */ NC_INFO_LIST **info_list);\r
+\r
+CC_INT32 rcc_get_name( \r
+ /* [in] */ HCACHE cache,\r
+ /* [string][out] */ CC_CHAR **name);\r
+\r
+CC_INT32 rcc_set_principal( \r
+ /* [in] */ HCACHE cache,\r
+ /* [in] */ CC_INT32 vers,\r
+ /* [string][in] */ const CC_CHAR *principal);\r
+\r
+CC_INT32 rcc_get_principal( \r
+ /* [in] */ HCACHE cache,\r
+ /* [string][out] */ CC_CHAR **principal);\r
+\r
+CC_INT32 rcc_get_cred_version( \r
+ /* [in] */ HCACHE cache,\r
+ /* [out] */ CC_INT32 *vers);\r
+\r
+CC_INT32 rcc_lock_request( \r
+ /* [in] */ HCACHE cache,\r
+ /* [in] */ CC_INT32 lock_type);\r
+\r
+CC_INT32 rcc_store( \r
+ /* [in] */ HCACHE cache,\r
+ /* [in] */ CRED_UNION cred);\r
+\r
+CC_INT32 rcc_remove_cred( \r
+ /* [in] */ HCACHE cache,\r
+ /* [in] */ CRED_UNION cred);\r
+\r
+CC_INT32 rcc_seq_fetch_creds( \r
+ /* [in] */ HCACHE cache,\r
+ /* [out][in] */ HCRED_ITER *piter,\r
+ /* [out] */ CRED_UNION **cred);\r
+\r
+CC_INT32 rcc_seq_fetch_creds_begin( \r
+ /* [in] */ HCACHE cache,\r
+ /* [out] */ HCRED_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_creds_end( \r
+ /* [out][in] */ HCRED_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_creds_next( \r
+ /* [in] */ HCRED_ITER iter,\r
+ /* [out] */ CRED_UNION **cred);\r
+\r
+CC_UINT32 Connect( \r
+ /* [string][in] */ CC_CHAR *name);\r
+\r
+void Shutdown( void);\r
+\r
+\r
+extern handle_t ccapi_IfHandle;\r
+\r
+\r
+extern RPC_IF_HANDLE ccapi_ClientIfHandle;\r
+extern RPC_IF_HANDLE ccapi_ServerIfHandle;\r
+#endif /* __ccapi_INTERFACE_DEFINED__ */\r
+\r
+/* Additional Prototypes for ALL interfaces */\r
+\r
+void __RPC_USER HCTX_rundown( HCTX );\r
+void __RPC_USER HCACHE_rundown( HCACHE );\r
+void __RPC_USER HCACHE_ITER_rundown( HCACHE_ITER );\r
+void __RPC_USER HCRED_ITER_rundown( HCRED_ITER );\r
+\r
+/* end of Additional Prototypes */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "stdio.h" // KPKDBG\r
+\r
+#include "ccs_request.h"\r
+\r
+#include "ccapi.h"\r
+#include "util.h"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+#include "tls.h" // KPKDBG\r
+ }\r
+\r
+#include "client.h"\r
+#include "init.hxx"\r
+#include "name.h"\r
+#include "secure.hxx"\r
+\r
+#define SECONDS_TO_WAIT 10\r
+\r
+#define STARTUP "CLIENT STARTUP: "\r
+#define DISCONNECT "CLIENT DISCONNECT: "\r
+\r
+bool Client::s_init = false;\r
+CcOsLock Client::sLock;\r
+\r
+static DWORD bind_client(char* ep OPTIONAL, Init::InitInfo& info, LPSTR* endpoint) {\r
+ DWORD status = 0;\r
+ unsigned char * pszStringBinding = NULL;\r
+\r
+ if (!ep) {\r
+ status = alloc_name(endpoint, "ep", isNT());\r
+ } \r
+ else {\r
+ *endpoint = ep;\r
+ }\r
+\r
+ if (!status) {\r
+ /* Use a convenience function to concatenate the elements of */\r
+ /* the string binding into the proper sequence. */\r
+ status = RpcStringBindingCompose(0, // uuid\r
+ (unsigned char*)"ncalrpc", // protseq\r
+ 0, // address\r
+ (unsigned char*)(*endpoint), // endpoint\r
+ 0, // options\r
+ &pszStringBinding);\r
+ cci_check_error(status);\r
+ }\r
+ \r
+ if (!status) {\r
+ /* Set the binding handle that will be used to bind to the server. */\r
+ status = RpcBindingFromStringBinding(pszStringBinding, &ccs_request_IfHandle);\r
+ cci_check_error(status);\r
+ }\r
+\r
+ if (!status) {\r
+ // Win9x might call RpcBindingSetAuthInfo (not Ex), but it does not\r
+ // quite work on Win9x...\r
+ if (isNT()) {\r
+ RPC_SECURITY_QOS qos;\r
+ qos.Version = RPC_C_SECURITY_QOS_VERSION;\r
+ qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;\r
+ qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;\r
+ qos.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;\r
+\r
+ status = info.fRpcBindingSetAuthInfoEx(ccs_request_IfHandle,\r
+ 0, // principal\r
+ RPC_C_AUTHN_LEVEL_CONNECT,\r
+ RPC_C_AUTHN_WINNT,\r
+ 0, // current address space\r
+ RPC_C_AUTHZ_NAME,\r
+ &qos);\r
+ cci_check_error(status);\r
+ }\r
+ }\r
+\r
+ if (pszStringBinding) {\r
+ DWORD status = RpcStringFree(&pszStringBinding); \r
+ cci_check_error(status);\r
+ }\r
+ return cci_check_error(status);\r
+ }\r
+\r
+DWORD find_server(Init::InitInfo& info, LPSTR endpoint) {\r
+ DWORD status = 0;\r
+ LPSTR event_name = 0;\r
+ HANDLE hEvent = 0;\r
+ SECURITY_ATTRIBUTES sa = { 0 };\r
+ PSECURITY_ATTRIBUTES psa = 0;\r
+ STARTUPINFO si = { 0 };\r
+ PROCESS_INFORMATION pi = { 0 };\r
+ char* szExe = 0;\r
+ char* szDir = 0;\r
+ BOOL bRes = FALSE;\r
+ char* cmdline = NULL;\r
+#if 0\r
+ HANDLE hToken = 0;\r
+#endif\r
+\r
+ psa = isNT() ? &sa : 0;\r
+\r
+// cci_debug_printf("%s Looking for server; ccs_request_IfHandle:0x%X", __FUNCTION__, ccs_request_IfHandle);\r
+ status = cci_check_error(RpcMgmtIsServerListening(ccs_request_IfHandle));\r
+ if (status == RPC_S_NOT_LISTENING) {\r
+// cci_debug_printf(" Server *NOT* found!");\r
+ si.cb = sizeof(si);\r
+\r
+ status = alloc_module_dir_name(CCAPI_DLL, &szDir);\r
+\r
+ if (!status) {\r
+ status = alloc_module_dir_name_with_file(CCAPI_DLL, CCAPI_EXE, &szExe);\r
+ }\r
+\r
+ if (!status) {\r
+ status = alloc_name(&event_name, "startup", isNT());\r
+ cci_check_error(status);\r
+ }\r
+\r
+ if (!status) {\r
+ if (isNT()) {\r
+ sa.nLength = sizeof(sa);\r
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);\r
+ cci_check_error(status);\r
+ }\r
+ }\r
+\r
+ if (!status) {\r
+ hEvent = CreateEvent(psa, FALSE, FALSE, event_name);\r
+ cci_debug_printf(" CreateEvent(... %s) returned hEvent 0x%X", event_name, hEvent);\r
+ if (!hEvent) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+\r
+#if 0\r
+ if (SecureClient::IsImp()) {\r
+ cci_debug_printf(STARTUP "Token is impersonation token"));\r
+ SecureClient::DuplicateImpAsPrimary(hToken);\r
+ } \r
+ else {\r
+ cci_debug_printf(STARTUP "Token is NOT impersonation token"));\r
+ }\r
+#endif\r
+\r
+#if 0\r
+ if (hToken)\r
+ bRes = CreateProcessAsUser(hToken,\r
+ szExe, // app name\r
+ NULL, // cmd line\r
+ psa, // SA\r
+ psa, // SA\r
+ FALSE, \r
+ CREATE_NEW_PROCESS_GROUP | \r
+ //CREATE_NEW_CONSOLE |\r
+ NORMAL_PRIORITY_CLASS |\r
+ // CREATE_NO_WINDOW |\r
+ DETACHED_PROCESS |\r
+ 0\r
+ ,\r
+ NULL, // environment\r
+ szDir, // current dir\r
+ &si,\r
+ &pi);\r
+ else\r
+#endif\r
+ alloc_cmdline_2_args(szExe, endpoint, "-D", &cmdline);\r
+ bRes = CreateProcess( szExe, // app name\r
+ NULL, //cmdline, // cmd line is <server endpoint -[DC]>\r
+ psa, // SA\r
+ psa, // SA\r
+ FALSE, \r
+ CREATE_NEW_PROCESS_GROUP | \r
+ CREATE_NEW_CONSOLE |\r
+ NORMAL_PRIORITY_CLASS |\r
+ // CREATE_NO_WINDOW |\r
+ // DETACHED_PROCESS | /* KPK TODO: was set - restore */\r
+ 0\r
+ ,\r
+ NULL, // environment\r
+ szDir, // current dir\r
+ &si,\r
+ &pi);\r
+ if (!bRes) {\r
+ status = GetLastError();\r
+ cci_debug_printf(" CreateProcess returned %d; LastError: %d", bRes, status);\r
+ }\r
+ cci_debug_printf(" Waiting...");\r
+ }\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ status = WaitForSingleObject(hEvent, (SECONDS_TO_WAIT)*1000);\r
+ status = RpcMgmtIsServerListening(ccs_request_IfHandle);\r
+ }\r
+ } \r
+ else if (status) {\r
+ cci_debug_printf(" unexpected error while looking for server: 0D%d / 0U%u / 0X%X", status, status, status);\r
+ } \r
+\r
+#if 0\r
+ if (hToken)\r
+ CloseHandle(hToken);\r
+#endif\r
+ if (szDir) free_alloc_p(&szDir);\r
+ if (szExe) free_alloc_p(&szExe);\r
+ if (hEvent) CloseHandle(hEvent);\r
+ if (pi.hThread) CloseHandle(pi.hThread);\r
+ if (pi.hProcess) CloseHandle(pi.hProcess);\r
+ if (sa.lpSecurityDescriptor) free_alloc_p(&sa.lpSecurityDescriptor);\r
+ return cci_check_error(status);\r
+\r
+}\r
+\r
+static\r
+DWORD\r
+authenticate_server(Init::InitInfo& info) {\r
+ DWORD challenge = 17; // XXX - maybe use random number\r
+ DWORD desired_response= challenge + 1;\r
+ HANDLE hMap = 0;\r
+ LPSTR mem_name = 0;\r
+ PDWORD pvalue = 0;\r
+ CC_UINT32 response = 0;\r
+ SECURITY_ATTRIBUTES sa = { 0 };\r
+ DWORD status = 0;\r
+\r
+ cci_debug_printf("%s entry", __FUNCTION__);\r
+\r
+ status = alloc_name(&mem_name, "auth", isNT());\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ if (isNT()) {\r
+ sa.nLength = sizeof(sa);\r
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);\r
+ }\r
+ }\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, isNT() ? &sa : 0, \r
+ PAGE_READWRITE, 0, sizeof(DWORD), mem_name);\r
+ if (!hMap)\r
+ status = GetLastError();\r
+ }\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);\r
+ if (!pvalue) status = GetLastError();\r
+ }\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ *pvalue = challenge;\r
+\r
+ RpcTryExcept {\r
+ response = ccs_authenticate( (CC_CHAR*)mem_name );\r
+ }\r
+ RpcExcept(1) {\r
+ status = RpcExceptionCode();\r
+ cci_check_error(status);\r
+ }\r
+ RpcEndExcept;\r
+ }\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ // Check response\r
+ if ((response != desired_response) && (*pvalue != desired_response)) {\r
+ cci_debug_printf(" Could not authenticate server.");\r
+ status = ERROR_ACCESS_DENIED; // XXX - CO_E_NOMATCHINGSIDFOUND?\r
+ } \r
+ else {\r
+ cci_debug_printf(" Server authenticated!");\r
+ }\r
+ cci_check_error(status);\r
+ }\r
+\r
+ free_alloc_p(&mem_name);\r
+ free_alloc_p(&sa.lpSecurityDescriptor);\r
+ if (pvalue) {\r
+ BOOL ok = UnmapViewOfFile(pvalue);\r
+// DEBUG_ASSERT(ok);\r
+ }\r
+ if (hMap) CloseHandle(hMap);\r
+ return status;\r
+}\r
+\r
+DWORD\r
+Client::Disconnect() {\r
+ DWORD status = 0;\r
+ if (ccs_request_IfHandle) {\r
+ /* The calls to the remote procedures are complete. */\r
+ /* Free the binding handle */\r
+ status = RpcBindingFree(&ccs_request_IfHandle);\r
+ }\r
+ s_init = false;\r
+ return status;\r
+ }\r
+\r
+DWORD\r
+Client::Connect(char* ep OPTIONAL) {\r
+ LPSTR endpoint = 0;\r
+ DWORD status = 0;\r
+\r
+ if (!ccs_request_IfHandle) {\r
+ Init::InitInfo info;\r
+\r
+ status = Init::Info(info);\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ status = bind_client(ep, info, &endpoint);\r
+ cci_check_error(status);\r
+ }\r
+\r
+ if (!status) {\r
+ status = find_server(info, endpoint);\r
+ cci_check_error(status);\r
+ }\r
+\r
+ if (!status) {\r
+ status = authenticate_server(info);\r
+ cci_check_error(status);\r
+ }\r
+ }\r
+\r
+\r
+ if (endpoint && (endpoint != ep)) free_alloc_p(&endpoint);\r
+ \r
+ if (status) Client::Disconnect();\r
+ return status;\r
+ }\r
+\r
+DWORD Client::Initialize(char* ep OPTIONAL) {\r
+ CcAutoLock AL(Client::sLock);\r
+ SecureClient s;\r
+ ccs_request_IfHandle = NULL;\r
+ if (s_init) return 0;\r
+ DWORD status = Client::Connect(ep);\r
+ if (!status) s_init = true;\r
+ return status;\r
+ }\r
+\r
+DWORD Client::Cleanup() {\r
+ CcAutoLock AL(Client::sLock);\r
+ SecureClient s;\r
+ return Client::Disconnect();\r
+ }\r
+\r
+DWORD Client::Reconnect(char* ep OPTIONAL) {\r
+ CcAutoLock AL(Client::sLock);\r
+ SecureClient s;\r
+ DWORD status = 0;\r
+\r
+ if (Initialized()) {\r
+ DWORD status = Client::Cleanup();\r
+ }\r
+ if ( (!status) ) {\r
+ status = Client::Initialize(ep);\r
+ }\r
+\r
+ return status;\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef __DLL_CLIENT_H__\r
+#define __DLL_CLIENT_H__\r
+\r
+#include "autolock.hxx"\r
+#include "init.hxx"\r
+\r
+class Client {\r
+public:\r
+ static DWORD Initialize(char* ep OPTIONAL);\r
+ static DWORD Cleanup();\r
+ static DWORD Reconnect(char* ep OPTIONAL);\r
+\r
+ static bool Initialized() { return s_init; }\r
+\r
+ static CcOsLock sLock;\r
+\r
+private:\r
+ static bool s_init;\r
+\r
+ static DWORD Disconnect();\r
+ static DWORD Connect(char* ep OPTIONAL);\r
+ };\r
+\r
+#define CLIENT_INIT_EX(trap, error) \\r
+do \\r
+{ \\r
+ INIT_INIT_EX(trap, error); \\r
+ if (!Client::Initialized()) \\r
+ { \\r
+ DWORD status = Client::Initialize(0); \\r
+ if (status) return (trap) ? (error) : status; \\r
+ } \\r
+} while(0)\r
+\r
+#endif\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+\r
+extern "C" {\r
+#include "CredentialsCache.h"\r
+#include "secure.hxx"\r
+#include "client.h"\r
+#include "autolock.hxx"\r
+#include "cci_debugging.h"\r
+ }\r
+\r
+extern HANDLE hCCAPIv2Mutex;\r
+\r
+#define MAKE_RPC_CALL(rc, x) \\r
+do { \\r
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE ); \\r
+ SecureClient* s = 0; \\r
+ SecureClient::Start(s); \\r
+ CcAutoLock* a = 0; \\r
+ CcAutoLock::Start(a, Client::sLock); \\r
+ RpcTryExcept { \\r
+ cci_debug_printf("RpcTry: #x"); \\r
+ x; \\r
+ } \\r
+ RpcExcept(1) { \\r
+ rc = handle_exception(RpcExceptionCode()); \\r
+ } \\r
+ RpcEndExcept; \\r
+ CcAutoLock::Stop(a); \\r
+ SecureClient::Stop(s); \\r
+ ReleaseMutex( hCCAPIv2Mutex ); \\r
+} while (0)\r
+\r
+static\r
+DWORD\r
+handle_exception(DWORD code) {\r
+ cci_debug_printf("Runtime reported exception %u", code);\r
+ if (code == RPC_S_SERVER_UNAVAILABLE) {\r
+ Client::Reconnect(0);\r
+ }\r
+ return 4;\r
+ }\r
+\r
+//////////////////////////////////////////////////////////////////////////////\r
+\r
+cc_int32 cc_initialize() {\r
+\r
+ CLIENT_INIT_EX(true, 4);\r
+ cc_int32 rc = ccNoError;\r
+\r
+ MAKE_RPC_CALL(rc, rc = 5);\r
+ return rc;\r
+ }
\ No newline at end of file
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINCCAPI", "WINCCAPI.vcproj", "{1137FC16-E53E-48C1-8293-085B4BE68C32}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Release|Win32 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.Build.0 = Debug|Win32\r
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.ActiveCfg = Release|Win32\r
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="8.00"\r
+ Name="WINCCAPI"\r
+ ProjectGUID="{1137FC16-E53E-48C1-8293-085B4BE68C32}"\r
+ RootNamespace="WINCCAPI"\r
+ Keyword="MakeFileProj"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="Debug"\r
+ IntermediateDirectory="Debug"\r
+ ConfigurationType="0"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake"\r
+ ReBuildCommandLine="nmake"\r
+ CleanCommandLine="nmake clean"\r
+ Output="output.log"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;"\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="Release"\r
+ IntermediateDirectory="Release"\r
+ ConfigurationType="0"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake"\r
+ ReBuildCommandLine="nmake"\r
+ CleanCommandLine="nmake clean"\r
+ Output="output.log"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;"\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\common\win\win-utils.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ </Filter>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_reply.Idl"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_request.idl"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\win-utils.c"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_reply.Acf"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_request.Acf"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\Makefile"\r
+ >\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+;LIBRARY COMERR32\r
+HEAPSIZE 8192\r
+\r
+EXPORTS\r
+ cci_debug_printf\r
+ \r
+ cc_initialize\r
+\r
+ cci_string_new\r
+ cci_string_d_initializer\r
+ ccapi_string_release\r
+\r
+ cci_credentials_iterator_new \r
+ cci_credentials_iterator_write \r
+\r
+ cci_ccache_iterator_new \r
+ cci_ccache_iterator_write \r
+\r
+ ccapi_ccache_iterator_release \r
+ ccapi_ccache_iterator_next \r
+ ccapi_ccache_iterator_clone \r
+\r
+ ccapi_credentials_iterator_release \r
+ ccapi_credentials_iterator_next \r
+ ccapi_credentials_iterator_clone\r
+ \r
+;debugging:\r
+ _cci_check_error\r
+ cci_os_ipc\r
+ cci_os_ipc_msg\r
+ cci_os_ipc_thread_init\r
+ cci_stream_data\r
+ cci_stream_write\r
+ cci_stream_new\r
+ \r
+ ccs_authenticate\r
+ \r
+ \r
+
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+extern "C" {\r
+#include "k5-thread.h"\r
+#include "ccapi_os_ipc.h"\r
+#include "tls.h"\r
+#include "dllmain.h"\r
+#include "ccs_reply.h"\r
+#include "ccs_request.h"\r
+#include "win-utils.h"\r
+#include "ccutils.h"\r
+#include "util.h"\r
+ }\r
+\r
+#include "CredentialsCache.h"\r
+#include "secure.hxx"\r
+#include "opts.hxx"\r
+#include "client.h"\r
+#include "autolock.hxx"\r
+#include "cci_debugging.h"\r
+\r
+#define SECONDS_TO_WAIT 10\r
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle\r
+\r
+extern HANDLE hCCAPIv2Mutex;\r
+ParseOpts::Opts opts = { 0 };\r
+PSECURITY_ATTRIBUTES psa = 0;\r
+SECURITY_ATTRIBUTES sa = { 0 };\r
+\r
+/* The layout of the rest of this module: \r
+\r
+ The entrypoints defined in ccs_os_ipc.h:\r
+ cci_os_ipc_thread_init\r
+ cci_os_ipc\r
+\r
+ Other routines needed by those four.\r
+ cci_os_connect\r
+ handle_exception\r
+ */\r
+\r
+cc_int32 ccapi_connect(const struct tspdata* tsp);\r
+static DWORD handle_exception(DWORD code);\r
+\r
+extern "C" {\r
+cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,\r
+ cci_stream_t in_request_stream,\r
+ cc_int32 in_msg,\r
+ cci_stream_t* out_reply_stream);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+extern "C" cc_int32 cci_os_ipc_thread_init (void) {\r
+ cc_int32 err = ccNoError;\r
+ struct tspdata* ptspdata;\r
+ HANDLE replyEvent;\r
+ UUID __RPC_FAR uuid;\r
+ unsigned char __RPC_FAR* uuidString = NULL;\r
+\r
+ if (!GetTspData(&ptspdata)) return ccErrNoMem;\r
+\r
+ opts.cMinCalls = 1;\r
+ opts.cMaxCalls = 20;\r
+ opts.fDontWait = TRUE;\r
+\r
+ err = cci_check_error(UuidCreate(&uuid)); // Get a UUID\r
+ if (err == RPC_S_OK) { // Convert to string\r
+ err = UuidToString(&uuid, &uuidString);\r
+ }\r
+ if (!err) { // Save in thread local storage\r
+ tspdata_setUUID(ptspdata, uuidString);\r
+ }\r
+ cci_debug_printf("%s UUID:<%s>", __FUNCTION__, tspdata_getUUID(ptspdata));\r
+\r
+ // Initialize old CCAPI if necessary:\r
+ if (!err) if (!Init:: Initialized()) err = Init:: Initialize( );\r
+ if (!err) if (!Client::Initialized()) err = Client::Initialize(0);\r
+\r
+ if (!err) {\r
+ /* Whenever a reply to an RPC request is received, the RPC caller needs to\r
+ know when the reply has been received. It does that by waiting for a \r
+ client-specific event to be set. Define the event name to be <UUID>_reply: */\r
+ replyEvent = createThreadEvent((char*)uuidString, REPLY_SUFFIX);\r
+ }\r
+\r
+ if (replyEvent) tspdata_setReplyEvent(ptspdata, replyEvent);\r
+ else err = cci_check_error(GetLastError());\r
+\r
+ if (uuidString) RpcStringFree(&uuidString);\r
+\r
+ return cci_check_error(err);\r
+ }\r
+\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,\r
+ cci_stream_t in_request_stream,\r
+ cci_stream_t* out_reply_stream) {\r
+ return cci_os_ipc_msg( in_launch_server, \r
+ in_request_stream, \r
+ CCMSG_REQUEST, \r
+ out_reply_stream);\r
+ }\r
+\r
+extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,\r
+ cci_stream_t in_request_stream,\r
+ cc_int32 in_msg,\r
+ cci_stream_t* out_reply_stream) {\r
+\r
+ cc_int32 err = ccNoError;\r
+ cc_int32 done = FALSE;\r
+ cc_int32 try_count = 0;\r
+ cc_int32 server_died = FALSE;\r
+ TCHAR* pszStringBinding= NULL;\r
+ struct tspdata* ptspdata = NULL;\r
+ char* uuid = NULL;\r
+ int lenUUID = 0;\r
+ unsigned int trycount = 0;\r
+ time_t sst = 0;\r
+ STARTUPINFO si = { 0 };\r
+ PROCESS_INFORMATION pi = { 0 };\r
+ HANDLE replyEvent = 0;\r
+ BOOL bCCAPI_Connected= FALSE;\r
+\r
+ if (!in_request_stream) { err = cci_check_error (ccErrBadParam); }\r
+ if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); }\r
+ \r
+ if (!GetTspData(&ptspdata)) {return ccErrBadParam;}\r
+ bCCAPI_Connected = tspdata_getConnected (ptspdata);\r
+ replyEvent = tspdata_getReplyEvent (ptspdata);\r
+ sst = tspdata_getSST (ptspdata);\r
+ uuid = tspdata_getUUID(ptspdata);\r
+\r
+ // The lazy connection to the server has been put off as long as possible!\r
+ // ccapi_connect starts listening for replies as an RPC server and then\r
+ // calls ccs_rpc_connect.\r
+ if (!bCCAPI_Connected) {\r
+ err = cci_check_error(ccapi_connect(ptspdata));\r
+ bCCAPI_Connected = !err;\r
+ tspdata_setConnected(ptspdata, bCCAPI_Connected);\r
+ }\r
+\r
+ // Clear replyEvent so we can detect when a reply to our request has been received:\r
+ ResetEvent(replyEvent);\r
+ \r
+ //++ Use the old CCAPI implementation to try to talk to the server:\r
+ // It has all the code to use the RPC in a thread-safe way, make the endpoint, \r
+ // (re)connect and (re)start the server.\r
+ // Note: the old implementation wrapped the thread-safety stuff in a macro.\r
+ // Here it is expanded and thus duplicated for each RPC call. The new code has\r
+ // a very limited number of RPC calls, unlike the older code.\r
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );\r
+ SecureClient* s = 0;\r
+ SecureClient::Start(s);\r
+ CcAutoLock* a = 0;\r
+ CcAutoLock::Start(a, Client::sLock);\r
+\r
+ // Initialize old CCAPI if necessary:\r
+ if (!err) if (!Init:: Initialized()) err = cci_check_error(Init:: Initialize( ));\r
+ if (!err) if (!Client::Initialized()) err = cci_check_error(Client::Initialize(0));\r
+\r
+ // New code using new RPC procedures for sending the data and receiving a reply:\r
+ if (!err) {\r
+ RpcTryExcept {\r
+ if (!GetTspData(&ptspdata)) {return ccErrBadParam;}\r
+ uuid = tspdata_getUUID(ptspdata);\r
+ lenUUID = 1 + strlen(uuid); /* 1+ includes terminating \0. */\r
+ cci_debug_printf("%s calling remote ccs_rpc_request tsp*:0x%X", __FUNCTION__, ptspdata);\r
+ cci_debug_printf(" rpcmsg:%d; UUID[%d]:<%s> SST:%ld", in_msg, lenUUID, uuid, sst);\r
+\r
+ ccs_rpc_request( /* make call with user message: */\r
+ in_msg, /* Message type */\r
+ (unsigned char*)&ptspdata, /* Our tspdata* will be sent back to the reply proc. */\r
+ (unsigned char*)uuid,\r
+ cci_stream_size(in_request_stream),\r
+ (unsigned char*)cci_stream_data(in_request_stream), /* Data buffer */\r
+ sst, /* session start time */\r
+ (long*)(&err) ); /* Return code */\r
+ }\r
+ RpcExcept(1) {\r
+ handle_exception(RpcExceptionCode());\r
+ }\r
+ RpcEndExcept;\r
+ }\r
+\r
+ cci_check_error(err);\r
+ CcAutoLock::Stop(a);\r
+ SecureClient::Stop(s);\r
+ ReleaseMutex(hCCAPIv2Mutex); \r
+ //-- Use the old CCAPI implementation to try to talk to the server.\r
+\r
+ // Wait for reply handler to set event:\r
+ if (!err) {\r
+ cci_debug_printf(" Waiting for request reply.");\r
+ err = cci_check_error(WaitForSingleObject(replyEvent, INFINITE));//(SECONDS_TO_WAIT)*1000));\r
+ cci_debug_printf(" Request reply received!");\r
+ }\r
+\r
+ if (!err) {\r
+ err = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));\r
+ }\r
+\r
+ if (!err && server_died) {\r
+ err = cci_check_error (ccErrServerUnavailable);\r
+ }\r
+#if 0 \r
+ if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {\r
+ err = ccNoError; /* If the server is not running just return an empty stream. */\r
+ }\r
+#endif\r
+\r
+ if (!err) {\r
+ *out_reply_stream = tspdata_getStream(ptspdata);\r
+ }\r
+ \r
+ cci_debug_printf(" payload:<%s>", cci_stream_data(*out_reply_stream));\r
+\r
+ return cci_check_error (err); \r
+ }\r
+\r
+\r
+\r
+static DWORD handle_exception(DWORD code) {\r
+ cci_debug_printf("%s code %u; ccs_request_IfHandle:0x%X", __FUNCTION__, code, ccs_request_IfHandle);\r
+ if ( (code == RPC_S_SERVER_UNAVAILABLE) || (code == RPC_S_INVALID_BINDING) ) {\r
+ Client::Reconnect(0);\r
+ }\r
+ return 4;\r
+ }\r
+\r
+\r
+/* Establish a CCAPI connection with the server.\r
+ * The connect logic here is identical to the logic in the send request code.\r
+ * TODO: merge this connect code with that request code.\r
+ */\r
+cc_int32 ccapi_connect(const struct tspdata* tsp) {\r
+ BOOL bListen = TRUE;\r
+ char* endpoint = NULL;\r
+ HANDLE replyEvent = 0;\r
+ RPC_STATUS status = FALSE;\r
+ char* uuid = NULL;\r
+\r
+ /* Start listening to our uuid before establishing the connection,\r
+ * so that when the server tries to call ccapi_listen, we will be ready.\r
+ */\r
+\r
+ /* Build complete RPC uuid using previous CCAPI implementation: */\r
+ replyEvent = tspdata_getReplyEvent(tsp);\r
+ uuid = tspdata_getUUID(tsp);\r
+ endpoint = clientEndpoint(uuid);\r
+ cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);\r
+\r
+ opts.cMinCalls = 1;\r
+ opts.cMaxCalls = 20;\r
+ opts.fDontWait = TRUE;\r
+\r
+ if (!status) {\r
+ status = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc",\r
+ opts.cMaxCalls,\r
+ (RPC_CSTR)endpoint,\r
+ sa.lpSecurityDescriptor); // SD\r
+ cci_check_error(status);\r
+ }\r
+\r
+ if (!status) {\r
+ status = RpcServerRegisterAuthInfo(0, // server principal\r
+ RPC_C_AUTHN_WINNT,\r
+ 0,\r
+ 0 );\r
+ cci_check_error(status);\r
+ }\r
+\r
+ cci_debug_printf("%s is listening ...", __FUNCTION__);\r
+\r
+ if (!status) {\r
+ if (!isNT()) {\r
+ status = RpcServerRegisterIf(ccs_reply_ServerIfHandle, // interface \r
+ NULL, // MgrTypeUuid\r
+ NULL); // MgrEpv; null means use default\r
+ } \r
+ else {\r
+ status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle,// interface\r
+ NULL, // MgrTypeUuid\r
+ NULL, // MgrEpv; 0 means default\r
+ RPC_IF_ALLOW_SECURE_ONLY,\r
+ opts.cMaxCalls,\r
+ NULL); // No security callback.\r
+ }\r
+\r
+ cci_check_error(status);\r
+\r
+ if (!status) {\r
+ status = RpcServerListen(opts.cMinCalls,\r
+ opts.cMaxCalls,\r
+ TRUE);\r
+ cci_check_error(status);\r
+ }\r
+ }\r
+\r
+ // Clear replyEvent so we can detect when a reply to our connect request has been received:\r
+ ResetEvent(replyEvent);\r
+\r
+ // We use the old CCAPI implementation to try to talk to the server. \r
+ // It has all the code to make the uuid, (re)connect and (re)start the server.\r
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );\r
+ SecureClient* s = 0;\r
+ SecureClient::Start(s);\r
+ CcAutoLock* a = 0;\r
+ CcAutoLock::Start(a, Client::sLock);\r
+\r
+ // Initialize old CCAPI if necessary:\r
+ if (!status) if (!Init:: Initialized()) status = Init:: Initialize( );\r
+ if (!status) if (!Client::Initialized()) status = Client::Initialize(0);\r
+\r
+ // New code using new RPC procedures for sending the data and receiving a reply:\r
+ if (!status) {\r
+ RpcTryExcept {\r
+ ccs_rpc_connect( /* make call with user message: */\r
+ CCMSG_CONNECT, /* Message type */\r
+ (unsigned char*)&tsp, /* Our tspdata* will be sent back to the reply proc. */\r
+ (unsigned char*)uuid,\r
+ (long*)(&status) ); /* Return code */\r
+ }\r
+ RpcExcept(1) {\r
+ cci_check_error(RpcExceptionCode());\r
+ status = ccErrBadInternalMessage;\r
+ }\r
+ RpcEndExcept;\r
+ }\r
+\r
+ CcAutoLock::Stop(a);\r
+ SecureClient::Stop(s);\r
+ ReleaseMutex(hCCAPIv2Mutex); \r
+\r
+ if (!status) {\r
+ cci_debug_printf("%s Waiting for replyEvent.", __FUNCTION__);\r
+ status = WaitForSingleObject(replyEvent, INFINITE);//(SECONDS_TO_WAIT)*1000);\r
+ status = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));\r
+ cci_debug_printf(" Server %sFOUND!", (status) ? "NOT " : "");\r
+ }\r
+ if (status) {\r
+ cci_debug_printf(" unexpected error while looking for server... (%u)", status);\r
+ } \r
+ \r
+ cci_debug_printf("%s TODO: check connect reply result.", __FUNCTION__);\r
+ cci_debug_printf("%s TODO: merge this connect code with that request code.", __FUNCTION__);\r
+ return status;\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <windows.h>\r
+\r
+#include "cci_debugging.h"\r
+#include "ccs_reply.h" /* generated by MIDL compiler */\r
+#include "ccutils.h"\r
+#include "tls.h"\r
+#include "win-utils.h"\r
+\r
+\r
+void ccs_rpc_request_reply(\r
+ const long rpcmsg, /* Message type */\r
+ const char tspHandle[], /* Client's tspdata* */\r
+ const char* uuid, /* uuid for making thread-specific event name */\r
+ const long srvStartTime, /* Server Start Time */\r
+ const long cbIn, /* Length of buffer */\r
+ const char* chIn, /* Data buffer */\r
+ long* ret_status ) { /* Return code */\r
+\r
+ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX);\r
+ DWORD* p = (DWORD*)(tspHandle);\r
+ struct tspdata* tsp = (struct tspdata*)*p;\r
+ cci_stream_t stream;\r
+ long status = 0;\r
+\r
+ cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);\r
+ cci_debug_printf(" payload:<%s>", chIn);\r
+ cci_debug_printf(" uuid from handle:<%s>", tspdata_getUUID(tsp));\r
+\r
+ if (!status) { \r
+ status = cci_stream_new (&stream); /* Create a stream for the request data */\r
+ }\r
+\r
+ if (!status) { /* Put the data into the stream */\r
+ status = cci_stream_write (stream, chIn, cbIn);\r
+ }\r
+\r
+ if (!status) { /* Put the data into the stream */\r
+ tspdata_setStream(tsp, stream);\r
+ }\r
+\r
+ SetEvent(hEvent);\r
+ CloseHandle(hEvent);\r
+ *ret_status = status;\r
+ }\r
+\r
+void ccs_rpc_connect_reply(\r
+ const long rpcmsg, /* Message type */\r
+ const char tspHandle[], /* Client's tspdata* */\r
+ const char* uuid, /* uuid for making thread-specific event name */\r
+ const long srvStartTime, /* Server Start Time */\r
+ long* status ) { /* Return code */\r
+\r
+ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX);\r
+ DWORD* p = (DWORD*)(tspHandle);\r
+\r
+ cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);\r
+\r
+ SetEvent(hEvent);\r
+ CloseHandle(hEvent);\r
+ }\r
+\r
+void ccapi_listen(\r
+ RPC_ASYNC_STATE* rpcState,\r
+ handle_t hBinding,\r
+ const long rpcmsg, /* Message type */\r
+ long* status ) { /* Return code */\r
+\r
+ cci_debug_printf("%s %s!", __FUNCTION__, rpcState->UserInfo);\r
+ *status = 0;\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <LMCons.h>\r
+\r
+extern "C" {\r
+#include "dllmain.h"\r
+#include "tls.h"\r
+#include "cci_debugging.h"\r
+#include "ccapi_context.h"\r
+#include "client.h"\r
+\r
+//void cci_thread_init__auxinit();\r
+ }\r
+\r
+#define CCAPI_V2_MUTEX_NAME TEXT("MIT_CCAPI_V4_MUTEX")\r
+\r
+// Process-specific data:\r
+static DWORD dwTlsIndex;\r
+static char _user[UNLEN+1]; // Username is used as part of the server and client endpoints.\r
+static HANDLE sessionToken;\r
+static char* ep_prefices[] = {"CCS", "CCAPI"};\r
+HANDLE hCCAPIv2Mutex = NULL;\r
+DWORD firstThreadID = 0;\r
+\r
+// These data structures are used by the old CCAPI implementation \r
+// to keep track of the state of the RPC connection. All data is static.\r
+static Init init;\r
+static Client client;\r
+\r
+// DllMain() is the entry-point function for this DLL. \r
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle\r
+ DWORD fdwReason, // reason called\r
+ LPVOID lpvReserved) { // reserved \r
+\r
+ struct tspdata* ptspdata;\r
+ BOOL fIgnore;\r
+ BOOL bStatus;\r
+ DWORD status = 0; // 0 is success.\r
+ DWORD maxUN = sizeof(_user);\r
+ unsigned int i = 0;\r
+ unsigned int j = 0;\r
+ \r
+ switch (fdwReason) { \r
+ // The DLL is loading due to process initialization or a call to LoadLibrary:\r
+ case DLL_PROCESS_ATTACH: \r
+ cci_debug_printf("%s DLL_PROCESS_ATTACH", __FUNCTION__);\r
+ // Process-wide mutex used to allow only one thread at a time into the RPC code:\r
+ hCCAPIv2Mutex = CreateMutex(NULL, FALSE, CCAPI_V2_MUTEX_NAME);\r
+\r
+ // Figure out our username; it's process-wide:\r
+ bStatus = GetUserName(_user, &maxUN);\r
+ if (!bStatus) return bStatus;\r
+\r
+ // Remove any characters that aren't valid endpoint characters:\r
+ while (_user[j] != 0) {\r
+ if (isalnum(_user[j])) _user[i++] = _user[j];\r
+ j++;\r
+ }\r
+ _user[i] = '\0';\r
+\r
+ // Our logon session is determined in client.cxx, old CCAPI code carried\r
+ // over to this implementation.\r
+\r
+ // Allocate a TLS index:\r
+ if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; \r
+ \r
+ // Initialize CCAPI once per DLL load:\r
+ firstThreadID = GetCurrentThreadId();\r
+\r
+ // Don't break; fallthrough: Initialize the TLS index for first thread.\r
+ \r
+ // The attached process creates a new thread:\r
+ case DLL_THREAD_ATTACH:\r
+ // Initialize the TLS index for this thread:\r
+ ptspdata = (struct tspdata*) LocalAlloc(LPTR, sizeof(struct tspdata)); \r
+ cci_debug_printf("%s DLL_THREAD_ATTACH; tsp*:0x%X", __FUNCTION__, ptspdata);\r
+ if (ptspdata == NULL) return FALSE;\r
+ fIgnore = TlsSetValue(dwTlsIndex, ptspdata); \r
+\r
+ memset(ptspdata, 0, sizeof(struct tspdata));\r
+\r
+ // Initialize CCAPI once per DLL load:\r
+ if (GetCurrentThreadId() == firstThreadID) cci_thread_init__auxinit();\r
+\r
+ break; \r
+ \r
+ // The thread of the attached process terminates:\r
+ case DLL_THREAD_DETACH: \r
+ cci_debug_printf("%s DLL_THREAD_DETACH", __FUNCTION__);\r
+ // Release the allocated memory for this thread:\r
+ ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex); \r
+ if (ptspdata != NULL) {\r
+ LocalFree((HLOCAL) ptspdata); \r
+ TlsSetValue(dwTlsIndex, NULL); \r
+ }\r
+ break; \r
+ \r
+ // DLL unload due to process termination or FreeLibrary:\r
+ case DLL_PROCESS_DETACH: \r
+ cci_debug_printf("%s DLL_PROCESS_DETACH", __FUNCTION__);\r
+ //++ Copied from previous implementation:\r
+ // Process Teardown "Problem"\r
+ //\r
+ // There are two problems that occur during process teardown:\r
+ //\r
+ // 1) Windows (NT/9x/2000) does not keep track of load/unload\r
+ // ordering dependencies for use in process teardown.\r
+ //\r
+ // 2) The RPC exception handling in the RPC calls do not work\r
+ // during process shutdown in Win9x.\r
+ //\r
+ // When a process is being torn down in Windows, the krbcc DLL\r
+ // may get a DLL_PROCESS_DETACH before other DLLs are done\r
+ // with it. Thus, it may disconnect from the RPC server\r
+ // before the last shutdown RPC call.\r
+ //\r
+ // On NT/2000, this is ok because the RPC call will fail and just\r
+ // return an error.\r
+ //\r
+ // On Win9x/Me, the RPC exception will not be caught.\r
+ // However, Win9x ignores exceptions during process shutdown,\r
+ // so the exception will never be seen unless a debugger is\r
+ // attached to the proccess.\r
+ //\r
+ // A good potential woraround would be to have a global\r
+ // variable that denotes whether the DLL is attached to the\r
+ // process. If it is not, all entrypoints into the DLL should\r
+ // return failure.\r
+ //\r
+ // A not as good workaround is below but ifdefed out.\r
+ //\r
+ // However, we can safely ignore this problem since it can\r
+ // only affects people running debuggers under 9x/Me who are\r
+ // using multiple DLLs that use this DLL.\r
+ //\r
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );\r
+#if 0\r
+ bool process_teardown_workaround = false;\r
+ if (lpvReserved) {\r
+ Init::InitInfo info;\r
+ status = Init::Info(info);\r
+ if (status) break;\r
+ if (!info.isNT) process_teardown_workaround = true;\r
+ }\r
+ if (process_teardown_workaround)\r
+ break;\r
+#endif\r
+ // return value is ignored, so we set status for debugging purposes\r
+ status = Client::Cleanup();\r
+ status = Init::Cleanup();\r
+ ReleaseMutex( hCCAPIv2Mutex );\r
+ CloseHandle( hCCAPIv2Mutex );\r
+ //-- Copied from previous implementation.\r
+\r
+ // Release the allocated memory for this thread:\r
+ ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex); \r
+ if (ptspdata != NULL) LocalFree((HLOCAL) ptspdata);\r
+ TlsFree(dwTlsIndex); // Release the TLS index.\r
+ break; \r
+ \r
+ default: break; \r
+ } \r
+ \r
+ UNREFERENCED_PARAMETER(hinstDLL); // no whining!\r
+ UNREFERENCED_PARAMETER(lpvReserved); \r
+ return status ? FALSE : TRUE;\r
+}\r
+\r
+\r
+#ifdef __cplusplus // If used by C++ code, \r
+extern "C" { // we need to export the C interface\r
+#endif\r
+\r
+__declspec(dllexport)\r
+BOOL WINAPI PutTspData(struct tspdata* dw) {\r
+ LPVOID lpvData; \r
+ struct tspdata** pData; // The stored memory pointer \r
+\r
+ // Retrieve a data pointer for the current thread:\r
+ lpvData = TlsGetValue(dwTlsIndex); \r
+\r
+ // If NULL, allocate memory for the TLS slot for this thread:\r
+ if (lpvData == NULL) {\r
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct tspdata)); \r
+ if (lpvData == NULL) return FALSE;\r
+ if (!TlsSetValue(dwTlsIndex, lpvData)) return FALSE;\r
+ }\r
+\r
+ pData = (struct tspdata**) lpvData; // Cast to my data type.\r
+ // In this example, it is only a pointer to a DWORD\r
+ // but it can be a structure pointer to contain more complicated data.\r
+\r
+ (*pData) = dw;\r
+ return TRUE;\r
+ }\r
+\r
+__declspec(dllexport)\r
+BOOL WINAPI GetTspData(struct tspdata** pdw) {\r
+ struct tspdata* pData; // The stored memory pointer \r
+\r
+ pData = (struct tspdata*)TlsGetValue(dwTlsIndex); \r
+ if (pData == NULL) return FALSE;\r
+ (*pdw) = pData;\r
+ return TRUE;\r
+ }\r
+\r
+#if 0 // replaced by clientEndpoint / serverEndpoint.\r
+__declspec(dllexport)\r
+char* WINAPI getEndpoint(enum EndpointType ep) {\r
+ // The server endpoint is of the form CCS_<LSID>\r
+ // The client endpoint is of the form CCAPI_<uuid>\r
+ // Each client thread can have its own connection.\r
+ //\r
+ // NB: Caller must free the data the returned char* points to.\r
+ struct tspdata* pData;\r
+ char* s;\r
+ char* uuid;\r
+ unsigned int len;\r
+\r
+ switch (ep) {\r
+ case EPT_SERVER:\r
+ s = (char*)malloc(32); // Length of CCS_<DWORD>\r
+ sprintf(s, "%s_%ld", ep_prefices[EPT_SERVER], sessionToken);\r
+ break;\r
+ case EPT_CLIENT:\r
+ GetTspData(&pData);\r
+ uuid = tspdata_getUUID(pData);\r
+ len = 4 + strlen(ep_prefices[ep]) + strlen(_user) + strlen(uuid);\r
+ s = (char*)malloc(len);\r
+ sprintf(s, "%s_%s_%s", ep_prefices[EPT_CLIENT], _user, uuid);\r
+ break;\r
+ default:;\r
+ }\r
+ cci_debug_printf("%s(%d) returning %s", __FUNCTION__, ep, s);\r
+\r
+ return s;\r
+ }\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+/*********************************************************************/\r
+/* MIDL allocate and free */\r
+/*********************************************************************/\r
+\r
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {\r
+ return(malloc(len));\r
+ }\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {\r
+ free(ptr);\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _dll_h\r
+#define _dll_h\r
+\r
+#include "windows.h"\r
+\r
+enum EndpointType {EPT_SERVER=0, EPT_CLIENT};\r
+\r
+#ifdef __cplusplus // If used by C++ code, \r
+extern "C" { // we need to export the C interface\r
+#endif\r
+__declspec(dllexport) BOOL WINAPI PutTspData(struct tspdata* p);\r
+__declspec(dllexport) BOOL WINAPI GetTspData(struct tspdata** p);\r
+\r
+//__declspec(dllexport) char* WINAPI getEndpoint(enum EndpointType);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif _dll_h
\ No newline at end of file
--- /dev/null
+!include <Win32.Mak>\r
+\r
+# . is ...\pismere\athena\auth\krb5\src\ccapi\server\win\r
+CCAPI = ..\..\r
+CO = $(CCAPI)\common\r
+COWIN = $(CCAPI)\common\win\r
+CCUTIL = $(CCAPI)\common\win\OldCC\r
+LIBDIR = $(CCAPI)\lib\r
+LIBWIN = $(CCAPI)\lib\win\r
+K5SRC = $(CCAPI)\..\r
+POSIX = $(K5SRC)\lib\krb5\posix\r
+\r
+INC = -I. -I.. -I$(CO) -I$(COWIN) -I$(K5SRC)\include -I..\..\..\util\et -I$(CCUTIL)\r
+\r
+!if "$(CPU)" == "i386"\r
+cflags = $(cflags) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \\r
+$(INC) -MTd\r
+!else\r
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)\r
+!endif\r
+\r
+all : server\r
+\r
+server : server.exe\r
+\r
+common = cci_array_internal.obj cci_cred_union.obj cci_debugging.obj cci_identifier.obj \\r
+ cci_message.obj cci_stream.obj \r
+ \r
+commonwin = cci_os_debugging.obj \\r
+ cci_os_identifier.obj \\r
+ tls.obj \\r
+ win-utils.obj\r
+\r
+ccutils = ccutils.obj \r
+\r
+ccutilscxx = opts.obj util.obj secure.obj init.obj\r
+\r
+dll = ccapi_string.obj\r
+\r
+srv = ccs_array.obj ccs_cache_collection.obj ccs_callback.obj ccs_ccache.obj \\r
+ ccs_ccache_iterator.obj ccs_client.obj \\r
+ ccs_credentials.obj ccs_credentials_iterator.obj ccs_list.obj ccs_list_internal.obj \\r
+ ccs_lock.obj ccs_lock_state.obj ccs_pipe.obj ccs_server.obj \r
+\r
+srvwin = ccs_os_pipe.obj ccs_reply_c.obj \\r
+ ccs_request_proc.obj ccs_win_pipe.obj\r
+\r
+srvwincpp = ccs_os_server.obj ccs_request_s.obj WorkItem.obj WorkQueue.obj\r
+ \r
+linkobjs = $(common) $(commonwin) $(ccutils) $(ccutilscxx) \\r
+ $(srv) $(srvwin) $(srvwincpp)\r
+\r
+includes = ccs_reply.h ccs_request.h\r
+\r
+# Main program:\r
+server.exe : $(linkobjs) \r
+# $(link) $(linkdebug) $(conflags) -MTd -out:ccapiserver.exe $(linkobjs) \\r
+ $(link) $(linkdebug) $(conflags) -out:ccapiserver.exe $(linkobjs) \\r
+ rpcrt4.lib advapi32.lib ws2_32.lib user32.lib\r
+\r
+\r
+ccs_request.h ccs_request_s.cpp : $(COWIN)\ccs_request.idl $(COWIN)\ccs_request.acf\r
+ midl $(MIDL_OPTIMIZATION) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) -sstub \\r
+ ccs_request_s.cpp $(COWIN)\ccs_request.idl\r
+\r
+ccs_reply.h ccs_reply_c.c : $(COWIN)\ccs_reply.idl $(COWIN)\ccs_reply.acf\r
+ midl $(MIDL_OPTIMIZATION) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) \\r
+ $(COWIN)\ccs_reply.idl\r
+\r
+$(common) : $(CO)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(CO)\$*.c\r
+\r
+$(commonwin) : $(COWIN)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(COWIN)\$*.c\r
+\r
+$(ccutils) : $(CCUTIL)\$*.c\r
+ $(cc) $(cdebug) $(cflags) $(CCUTIL)\$*.c\r
+\r
+$(ccutilscxx) : $(CCUTIL)\$*.cxx\r
+ $(cc) $(cdebug) $(cflags) $(CCUTIL)\$*.cxx\r
+\r
+$(srv) : ..\$*.c\r
+ $(cc) $(cdebug) $(cflags) ..\$*.c\r
+\r
+$(srvwin) : $*.c $(includes) \r
+ $(cc) $(cdebug) $(cflags) $*.c\r
+\r
+$(srvwincpp) : $*.cpp\r
+ $(cc) $(cdebug) $(cflags) $*.cpp\r
+\r
+\r
+# Clean up everything\r
+cleanall : clean\r
+ -del *.exe\r
+\r
+# Clean up everything but the .EXEs\r
+clean :\r
+ -del *.obj\r
+ -del *.map\r
+ -del ccs_request_s.c\r
+ -del ccs_request_c.c\r
+ -del ccs_request.h\r
+ -del ccs_reply_s.c\r
+ -del ccs_reply_c.c\r
+ -del ccs_reply.h\r
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server.vcproj", "{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Release|Win32 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.Build.0 = Debug|Win32\r
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.ActiveCfg = Release|Win32\r
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="8.00"\r
+ Name="Server"\r
+ ProjectGUID="{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"\r
+ RootNamespace="Server"\r
+ Keyword="MakeFileProj"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="Debug"\r
+ IntermediateDirectory="Debug"\r
+ ConfigurationType="0"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake"\r
+ ReBuildCommandLine="nmake"\r
+ CleanCommandLine="nmake clean"\r
+ Output=""\r
+ PreprocessorDefinitions="WIN32;_DEBUG;"\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="Release"\r
+ IntermediateDirectory="Release"\r
+ ConfigurationType="0"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake"\r
+ ReBuildCommandLine="nmake"\r
+ CleanCommandLine="nmake clean"\r
+ Output=""\r
+ PreprocessorDefinitions="WIN32;NDEBUG;"\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\common\cci_debugging.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\cci_os_debugging.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\cci_stream.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_reply.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_request.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\ccs_server.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\ccutils.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\init.hxx"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\..\include\k5-platform.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\secure.hxx"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\util.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\win-utils.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\workitem.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\WorkQueue.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ </Filter>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\common\cci_debugging.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\cci_os_debugging.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\cci_stream.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\ccs_lock.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_os_pipe.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_os_server.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_reply.Idl"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_reply_c.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_reply_s.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_request.idl"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_request_c.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_request_proc.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\ccs_request_s.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\ccs_server.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\ccutils.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\init.cxx"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\secure.cxx"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\ccutil\util.cxx"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\common\win\win-utils.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\WorkItem.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\WorkQueue.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <File\r
+ RelativePath="..\..\common\win\ccs_reply.Acf"\r
+ >\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <string.h>\r
+#include "assert.h"\r
+\r
+#pragma warning (disable : 4996)\r
+\r
+#include "win-utils.h"\r
+#include "WorkItem.h"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+ }\r
+\r
+// CountedBuffer makes a copy of the data. Each CountedBuffer must be deleted.\r
+\r
+void deleteBuffer(char** buf) {\r
+ if (*buf) {\r
+ delete [](*buf);\r
+ *buf = NULL;\r
+ }\r
+ }\r
+\r
+// WorkItem contains a CountedBuffer which must be deleted, \r
+// so each WorkItem must be deleted.\r
+WorkItem::WorkItem(cci_stream_t buf, WIN_PIPE* pipe, const long type, const long sst) \r
+: _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { }\r
+\r
+WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) {\r
+\r
+ cci_stream_t _buf = NULL;\r
+ cci_stream_new(&_buf);\r
+ cci_stream_write(_buf, \r
+ cci_stream_data(item.payload()),\r
+ cci_stream_size(item.payload()) );\r
+ WorkItem(_buf, item._pipe, item._rpcmsg, item._sst);\r
+ }\r
+\r
+WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { }\r
+\r
+WorkItem::~WorkItem() {\r
+ if (_buf) cci_stream_release(_buf);\r
+ if (_pipe) ccs_win_pipe_release(_pipe);\r
+ }\r
+\r
+const cci_stream_t WorkItem::take_payload() {\r
+ cci_stream_t temp = payload();\r
+ _buf = NULL;\r
+ return temp;\r
+ }\r
+\r
+WIN_PIPE* WorkItem::take_pipe() {\r
+ WIN_PIPE* temp = pipe();\r
+ _pipe = NULL;\r
+ return temp;\r
+ }\r
+\r
+WorkList::WorkList() {\r
+ assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400));\r
+ }\r
+\r
+WorkList::~WorkList() {\r
+ // Delete any WorkItems in the queue:\r
+ WorkItem* item;\r
+ cci_debug_printf("%s", __FUNCTION__);\r
+ char buf[2048];\r
+ char* pbuf = (char*)buf;\r
+ while (remove(&item)) {\r
+ cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));\r
+ delete item;\r
+ }\r
+\r
+ DeleteCriticalSection(&cs);\r
+ }\r
+\r
+char* WorkItem::print(char* buf) {\r
+ sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst, \r
+ ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe));\r
+ return buf;\r
+ }\r
+\r
+int WorkList::add(WorkItem* item) {\r
+ EnterCriticalSection(&cs);\r
+ wl.push_front(item);\r
+ LeaveCriticalSection(&cs);\r
+ return 1;\r
+ }\r
+\r
+int WorkList::remove(WorkItem** item) {\r
+ bool bEmpty;\r
+\r
+ bEmpty = wl.empty() & 1;\r
+\r
+ if (!bEmpty) {\r
+ EnterCriticalSection(&cs);\r
+ *item = wl.back();\r
+ wl.pop_back();\r
+ LeaveCriticalSection(&cs);\r
+ }\r
+\r
+ return !bEmpty;\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+extern "C" {\r
+ #include "cci_debugging.h"\r
+ }\r
+\r
+#include "WorkItem.h"\r
+\r
+WorkList worklist;\r
+\r
+/* C interfaces: */\r
+EXTERN_C bool worklist_isEmpty() {\r
+ return worklist.isEmpty();\r
+ }\r
+\r
+EXTERN_C int worklist_add( const long rpcmsg, \r
+ const ccs_pipe_t pipe, \r
+ const cci_stream_t stream, \r
+ const time_t serverStartTime) {\r
+ return worklist.add(new WorkItem(stream, pipe, rpcmsg, serverStartTime) );\r
+ }\r
+\r
+EXTERN_C int worklist_remove(long* rpcmsg,\r
+ ccs_pipe_t* pipe,\r
+ cci_stream_t* stream,\r
+ time_t* sst) {\r
+ WorkItem* item = NULL;\r
+ cc_int32 err = worklist.remove(&item);\r
+\r
+ *rpcmsg = item->type();\r
+ *pipe = item->take_pipe();\r
+ *stream = item->take_payload();\r
+ *sst = item->sst();\r
+ delete item;\r
+ return err;\r
+ }\r
+\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2007 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _work_queue_h\r
+#define _work_queue_h\r
+\r
+#include "windows.h"\r
+#include "cci_stream.h"\r
+#include "ccs_pipe.h"\r
+\r
+EXTERN_C BOOL worklist_isEmpty();\r
+\r
+EXTERN_C void worklist_add( const long rpcmsg,\r
+ const ccs_pipe_t pipe,\r
+ const cci_stream_t stream,\r
+ const time_t serverStartTime);\r
+\r
+EXTERN_C int worklist_remove(long* rpcmsg,\r
+ ccs_pipe_t* pipe,\r
+ cci_stream_t* stream,\r
+ time_t* serverStartTime);\r
+\r
+#endif // _work_queue_h
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "ccs_common.h"\r
+#include "ccs_os_pipe.h"\r
+#include "ccs_win_pipe.h"\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+/* On Windows, a pipe is a struct. See ccs_win_pipe.h for details. */\r
+ \r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) {\r
+ return ccs_win_pipe_valid(in_pipe);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_copy (ccs_pipe_t* out_pipe, ccs_pipe_t in_pipe) {\r
+ return ccs_win_pipe_copy(\r
+ out_pipe, \r
+ in_pipe);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe) {\r
+ return ccs_win_pipe_release(io_pipe);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_compare (ccs_pipe_t pipe_1,\r
+ ccs_pipe_t pipe_2,\r
+ cc_uint32 *out_equal) {\r
+\r
+ return ccs_win_pipe_compare(pipe_1, pipe_2, out_equal);\r
+ }\r
+\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "process.h"\r
+#include "windows.h" \r
+\r
+extern "C" {\r
+#include "ccs_common.h"\r
+#include "ccs_os_server.h"\r
+#include <syslog.h>\r
+#include "ccs_reply.h"\r
+#include "ccs_request.h"\r
+#include "win-utils.h"\r
+#include "ccutils.h"\r
+#include "cci_stream.h"\r
+ }\r
+\r
+#include "WorkQueue.h"\r
+#include "util.h"\r
+#include "opts.hxx"\r
+#include "init.hxx"\r
+\r
+#pragma warning (disable : 4996)\r
+\r
+BOOL bListen = TRUE; /* Why aren't bool and true defined? */\r
+const char* sessID = NULL; /* The logon session we are running on behalf of. */\r
+time_t _sst = 0;\r
+unsigned char* pszNetworkAddress = NULL;\r
+unsigned char* pszStringBinding = NULL;\r
+BOOL bRpcHandleInited = FALSE; \r
+_RPC_ASYNC_STATE* rpcState = NULL;\r
+\r
+/* Thread procedures can take only one void* argument. We put all the args we want \r
+ to pass into this struct and then pass a pointer to the struct: */\r
+struct RpcRcvArgs {\r
+ char* networkAddress;\r
+ unsigned char* protocolSequence;\r
+ unsigned char* sessID; /* Used for this server's endpoint */\r
+ unsigned char* uuid; /* Used for client's UUID */\r
+ ParseOpts::Opts* opts;\r
+ RPC_STATUS status;\r
+ } rpcargs = { NULL, /* pszNetworkAddress */\r
+ (unsigned char*)"ncalrpc", /* pszProtocolSequence */\r
+ NULL, /* sessID placeholder */\r
+ NULL, /* uuid placeholder */\r
+ NULL }; /* Opts placeholder */\r
+\r
+/* Command line format:\r
+ argv[0] Program name\r
+ argv[1] session ID to use\r
+ argv[2] "D" Debug: go into infinite loop in ccs_os_server_initialize so process \r
+ can be attached in debugger.\r
+ Any other value: continue \r
+ */\r
+#define N_FIXED_ARGS 3\r
+#define SERVER_REPLY_RPC_HANDLE ccs_reply_IfHandle\r
+\r
+/* Forward declarations: */\r
+void receiveLoop(void* rpcargs);\r
+void connectionListener(void* rpcargs);\r
+void Usage(const char* argv0);\r
+void printError(TCHAR* msg);\r
+void setMySST() {_sst = time(&_sst);}\r
+time_t getMySST() {return _sst;}\r
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe);\r
+void RPC_ENTRY clientListener( _RPC_ASYNC_STATE*, \r
+ void* Context,\r
+ RPC_ASYNC_EVENT Event);\r
+RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,\r
+ IN void *Context);\r
+RPC_STATUS send_init(char* clientUUID);\r
+//DWORD alloc_name(LPSTR* pname, LPSTR postfix);\r
+\r
+\r
+/* The layout of the rest of this module: \r
+\r
+ The four entrypoints defined in ccs_os_server.h:\r
+ ccs_os_server_initialize\r
+ cc_int32 ccs_os_server_cleanup \r
+ cc_int32 ccs_os_server_listen_loop \r
+ cc_int32 ccs_os_server_send_reply \r
+\r
+ Other routines needed by those four.\r
+ */\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) {\r
+ cc_int32 err = 0;\r
+ ParseOpts::Opts opts = { 0 };\r
+ ParseOpts PO;\r
+ BOOL bAdjustedShutdown = FALSE;\r
+ HMODULE hKernel32 = GetModuleHandle("kernel32");\r
+\r
+ if (!err) {\r
+ sessID = argv[1];\r
+ setMySST();\r
+\r
+ opts.cMinCalls = 1;\r
+ opts.cMaxCalls = 20;\r
+ opts.fDontWait = TRUE;\r
+\r
+#ifdef CCAPI_TEST_OPTIONS\r
+ PO.SetValidOpts("kemnfubc");\r
+#else\r
+ PO.SetValidOpts("kc");\r
+#endif\r
+\r
+ PO.Parse(opts, argc, (char**)argv);\r
+ \r
+// while(*argv[2] == 'D') {} /* Hang here to attach process with debugger. */\r
+\r
+ if (hKernel32) {\r
+ typedef BOOL (WINAPI *FP_SetProcessShutdownParameters)(DWORD, DWORD);\r
+ FP_SetProcessShutdownParameters pSetProcessShutdownParameters =\r
+ (FP_SetProcessShutdownParameters)\r
+ GetProcAddress(hKernel32, "SetProcessShutdownParameters");\r
+ if (pSetProcessShutdownParameters) {\r
+ bAdjustedShutdown = pSetProcessShutdownParameters(100, 0);\r
+ }\r
+ }\r
+ cci_debug_printf("%s Shutdown Parameters", \r
+ bAdjustedShutdown ? "Adjusted" : "Did not adjust");\r
+\r
+ err = Init::Initialize();\r
+ }\r
+\r
+// if (!err) {\r
+// if (opts.bShutdown) {\r
+// status = shutdown_server(opts.pszEndpoint);\r
+// }\r
+// } \r
+// else {\r
+// status = startup_server(opts);\r
+// }\r
+\r
+ if (err) {\r
+ Init::Cleanup();\r
+ fprintf( stderr, "An error occured while %s the server (%u)\n", \r
+ opts.bShutdown ? "shutting down" : "starting/running",\r
+ err);\r
+ exit(cci_check_error (err));\r
+ }\r
+\r
+ return cci_check_error (err);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) {\r
+ cc_int32 err = 0;\r
+ \r
+ cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]);\r
+ \r
+ return cci_check_error (err);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+/* This function takes work items off the work queue and executes them.\r
+ * This is the one and only place where the multi-threaded Windows code\r
+ * calls into the single-threaded common code.\r
+ *\r
+ * The actual 'listening' for requests from clients happens after receiveloop\r
+ * establishes the RPC endpoint the clients will connect to and the RPC procedures\r
+ * put the work items into the work queue.\r
+ */\r
+cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) {\r
+ cc_int32 err = 0;\r
+ uintptr_t threadStatus;\r
+ unsigned int loopCounter = 0;\r
+\r
+ ParseOpts::Opts opts = { 0 };\r
+ ParseOpts PO;\r
+ \r
+ opts.cMinCalls = 1;\r
+ opts.cMaxCalls = 20;\r
+ opts.fDontWait = TRUE;\r
+\r
+#ifdef CCAPI_TEST_OPTIONS\r
+ PO.SetValidOpts("kemnfubc");\r
+#else\r
+ PO.SetValidOpts("kc");\r
+#endif\r
+ PO.Parse(opts, argc, (char**)argv);\r
+\r
+ \r
+ //++ debug stuff\r
+ #define INFO_BUFFER_SIZE 32767\r
+ TCHAR infoBuf[INFO_BUFFER_SIZE];\r
+ DWORD bufCharCount = INFO_BUFFER_SIZE;\r
+ // Get and display the user name. \r
+ bufCharCount = INFO_BUFFER_SIZE;\r
+ if( !GetUserName( infoBuf, &bufCharCount ) ) printError( TEXT("GetUserName") ); \r
+ //--\r
+\r
+ /* Sending the reply from within the request RPC handler doesn't seem to work.\r
+ So we listen for requests in a separate thread and put the requests in a\r
+ queue. */\r
+ rpcargs.sessID = (unsigned char*)sessID;\r
+ rpcargs.opts = &opts;\r
+ threadStatus = _beginthread(receiveLoop, 0, (void*)&rpcargs);\r
+\r
+ /* We handle the queue entries here. Work loop: */\r
+ while (TRUE) {\r
+ loopCounter++;\r
+ if (worklist_isEmpty() & 1) {\r
+ SleepEx(1000, TRUE);\r
+ }\r
+ else if (TRUE) { // Take next WorkItem from the queue:\r
+ cci_stream_t buf = NULL;\r
+ long rpcmsg = CCMSG_INVALID;\r
+ time_t serverStartTime = 0xDEADDEAD;\r
+ RPC_STATUS status = 0;\r
+ char* uuid = NULL;\r
+ cci_stream_t stream = NULL;\r
+ ccs_pipe_t pipe = NULL;\r
+ ccs_pipe_t pipe2 = NULL;\r
+\r
+ if (worklist_remove(&rpcmsg, &pipe, &buf, &serverStartTime)) {\r
+ uuid = ccs_win_pipe_getUuid(pipe);\r
+ cci_debug_printf("%s: processing WorkItem msg:%ld pipeUUID:<%s> pipeHandle:0x%X SST:%ld", \r
+ __FUNCTION__, rpcmsg, uuid, ccs_win_pipe_getHandle(pipe), serverStartTime);\r
+\r
+ if (serverStartTime <= getMySST()) {\r
+ switch (rpcmsg) {\r
+ case CCMSG_CONNECT: {\r
+ cci_debug_printf(" Processing CONNECT");\r
+ rpcargs.uuid = (unsigned char*)uuid;\r
+\r
+ // Even if a disconnect message is received before this code finishes,\r
+ // it won't be dequeued and processed until after this code finishes.\r
+ // So we can add the client after starting the connection listener.\r
+ connectionListener((void*)&rpcargs);\r
+ status = rpcargs.status;\r
+\r
+ if (!status) {\r
+ status = ccs_server_add_client(pipe);\r
+ }\r
+ if (!status) {status = send_connection_reply(pipe);}\r
+ break;\r
+ }\r
+ case CCMSG_DISCONNECT: {\r
+ cci_debug_printf(" Processing DISCONNECT");\r
+ if (!status) {\r
+ status = ccs_server_remove_client(pipe);\r
+ }\r
+ break;\r
+ }\r
+ case CCMSG_REQUEST:\r
+ cci_debug_printf(" Processing REQUEST");\r
+ ccs_pipe_copy(&pipe2, pipe);\r
+ // Dispatch message here, setting both pipes to the client UUID:\r
+ err = ccs_server_handle_request (pipe, pipe2, buf);\r
+ break;\r
+ case CCMSG_PING:\r
+ cci_debug_printf(" Processing PING");\r
+ err = cci_stream_new (&stream);\r
+ err = cci_stream_write(stream, "This is a test of the emergency broadcasting system", 52);\r
+ err = ccs_os_server_send_reply(pipe, stream);\r
+ break;\r
+ default:\r
+ cci_debug_printf("Huh? Received invalid message type %ld from UUID:<%s>", \r
+ rpcmsg, uuid);\r
+ break;\r
+ }\r
+ if (buf) cci_stream_release(buf);\r
+ /* Don't free uuid, which was allocated here. A pointer to it is in the \r
+ rpcargs struct which was passed to connectionListener which will be\r
+ received by ccapi_listen when the client exits. ccapi_listen needs \r
+ the uuid to know which client to disconnect.\r
+ */\r
+ }\r
+ // Server's start time is different from what the client thinks. \r
+ // That means the server has rebooted since the client connected.\r
+ else { \r
+ cci_debug_printf("Whoops! Server has rebooted since client established connection.");\r
+ }\r
+ }\r
+ else {cci_debug_printf("Huh? Queue not empty but no item to remove.");}\r
+ }\r
+ }\r
+\r
+ return cci_check_error (err);\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_pipe,\r
+ cci_stream_t in_reply_stream) {\r
+\r
+ /* ccs_pipe_t in_reply_pipe is a char* reply endpoint.\r
+ cci_stream_t in_reply_stream is the data to be sent.\r
+ */\r
+\r
+ cc_int32 err = 0;\r
+ char* uuid = ccs_win_pipe_getUuid(in_pipe);\r
+ HANDLE h = ccs_win_pipe_getHandle(in_pipe);\r
+\r
+ if (!err) {\r
+ err = send_init(uuid); // Sets RPC handle to be used.\r
+ }\r
+\r
+ if (!err) {\r
+ RpcTryExcept {\r
+ long status;\r
+ ccs_rpc_request_reply( // make call with user message\r
+ CCMSG_REQUEST_REPLY, /* Message type */\r
+ (unsigned char*)&h, /* client's tspdata* */\r
+ (unsigned char*)uuid,\r
+ getMySST(),\r
+ cci_stream_size(in_reply_stream), /* Length of buffer */\r
+ (const unsigned char*)cci_stream_data(in_reply_stream), /* Data buffer */\r
+ &status ); /* Return code */\r
+ }\r
+ RpcExcept(1) {\r
+ cci_check_error(RpcExceptionCode());\r
+ }\r
+ RpcEndExcept\r
+ }\r
+\r
+ /* The calls to the remote procedures are complete. */\r
+ /* Free whatever we allocated: */\r
+ err = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);\r
+\r
+ return cci_check_error (err);\r
+ }\r
+\r
+\r
+/* Windows-specific routines: */\r
+\r
+void Usage(const char* argv0) {\r
+ printf("Usage:\n");\r
+ printf("%s [m maxcalls] [n mincalls] [f dontwait] [h|?]]\n", argv0);\r
+ printf(" CCAPI server process.\n");\r
+ printf(" h|? whow usage message. <\n");\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+/* The receive thread repeatedly issues RpcServerListen.\r
+ When a message arrives, it is handled in the RPC procedure. \r
+ */\r
+void receiveLoop(void* rpcargs) {\r
+\r
+ struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;\r
+ RPC_STATUS status = FALSE;\r
+ unsigned char* pszSecurity = NULL;\r
+ LPSTR endpoint = NULL;\r
+ LPSTR event_name = NULL;\r
+ PSECURITY_DESCRIPTOR psd = NULL;\r
+ HANDLE hEvent = 0;\r
+ Init::InitInfo info;\r
+\r
+ cci_debug_printf("THREAD BEGIN: %s", __FUNCTION__);\r
+\r
+ status = Init::Info(info);\r
+\r
+ /* Build complete RPC endpoint using previous CCAPI implementation: */\r
+ if (!status) {\r
+ if (!rcvargs->opts->pszEndpoint) {\r
+ if (!status) {\r
+ status = alloc_name(&endpoint, "ep", isNT());\r
+ }\r
+\r
+ if (!status) {\r
+ status = alloc_name(&event_name, "startup", isNT());\r
+ }\r
+\r
+ if (!status) {\r
+ hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);\r
+ // We ignore any error opening the event because we do not know who started us.\r
+ // [Comment paraphrased from previous implementation, whence it was copied.]\r
+ }\r
+ }\r
+ else {\r
+ endpoint = rcvargs->opts->pszEndpoint;\r
+ }\r
+ }\r
+\r
+ cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);\r
+\r
+ if (!status && isNT()) {\r
+ status = alloc_own_security_descriptor_NT(&psd);\r
+ }\r
+\r
+ if (!status) {\r
+ status = RpcServerUseProtseqEp(rcvargs->protocolSequence,\r
+ rcvargs->opts->cMaxCalls,\r
+ (RPC_CSTR)endpoint,\r
+ rcvargs->opts->bDontProtect ? 0 : psd); // SD\r
+ }\r
+\r
+ if (!status) {\r
+ status = RpcServerRegisterAuthInfo(0, // server principal\r
+ RPC_C_AUTHN_WINNT,\r
+ 0,\r
+ 0);\r
+ }\r
+\r
+ while (bListen && !status) {\r
+ cci_debug_printf("%s is listening ...", __FUNCTION__);\r
+\r
+ if (!info.isNT) {\r
+ status = RpcServerRegisterIf(ccs_request_ServerIfHandle, // interface \r
+ NULL, // MgrTypeUuid\r
+ NULL); // MgrEpv; null means use default\r
+ } \r
+ else {\r
+ status = info.fRpcServerRegisterIfEx(ccs_request_ServerIfHandle, // interface\r
+ NULL, // MgrTypeUuid\r
+ NULL, // MgrEpv; 0 means default\r
+ RPC_IF_ALLOW_SECURE_ONLY,\r
+ rcvargs->opts->cMaxCalls,\r
+ rcvargs->opts->bSecCallback ? \r
+ (RPC_IF_CALLBACK_FN*)sec_callback : 0 );\r
+ }\r
+\r
+ if (!status) {\r
+ status = RpcServerListen(rcvargs->opts->cMinCalls,\r
+ rcvargs->opts->cMaxCalls,\r
+ rcvargs->opts->fDontWait);\r
+ }\r
+\r
+ if (!status) {\r
+ if (rcvargs->opts->fDontWait) {\r
+ if (hEvent) SetEvent(hEvent); // Ignore any error -- SetEvent is an optimization.\r
+ status = RpcMgmtWaitServerListen(); \r
+ }\r
+ }\r
+ }\r
+\r
+ if (status) { // Cleanup in case of errors:\r
+ if (hEvent) CloseHandle(hEvent);\r
+ free_alloc_p(&event_name);\r
+ free_alloc_p(&psd);\r
+ if (endpoint && (endpoint != rcvargs->opts->pszEndpoint)) \r
+ free_alloc_p(&endpoint);\r
+ }\r
+\r
+ _endthread();\r
+ } // End receiveLoop\r
+\r
+\r
+#if 0\r
+\r
+ return status;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/* ------------------------------------------------------------------------ */\r
+/* The connection listener thread waits forever for a call to the CCAPI_CLIENT_<UUID>\r
+ endpoint, ccapi_listen function to complete. If the call completes or gets an \r
+ RPC exception, it means the client has disappeared.\r
+\r
+ A separate connectionListener is started for each client that has connected to the server.\r
+ */\r
+\r
+void connectionListener(void* rpcargs) {\r
+\r
+ struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;\r
+ RPC_STATUS status = FALSE;\r
+ char* endpoint;\r
+ unsigned char* pszOptions = NULL;\r
+ unsigned char * pszUuid = NULL;\r
+\r
+ endpoint = clientEndpoint((char*)rcvargs->uuid);\r
+ rpcState = (RPC_ASYNC_STATE*)malloc(sizeof(RPC_ASYNC_STATE));\r
+ status = RpcAsyncInitializeHandle(rpcState, sizeof(RPC_ASYNC_STATE));\r
+ cci_debug_printf("");\r
+ cci_debug_printf("%s About to LISTEN to <%s>", __FUNCTION__, endpoint);\r
+\r
+ rpcState->UserInfo = rcvargs->uuid;\r
+ rpcState->NotificationType = RpcNotificationTypeApc;\r
+ rpcState->u.APC.NotificationRoutine = clientListener;\r
+ rpcState->u.APC.hThread = 0;\r
+\r
+ /* [If in use] Free previous binding: */\r
+ if (bRpcHandleInited) { \r
+ // Free previous binding (could have been used to call ccapi_listen \r
+ // in a different client thread).\r
+ // Don't check result or update status.\r
+ RpcStringFree(&pszStringBinding);\r
+ RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);\r
+ bRpcHandleInited = FALSE;\r
+ }\r
+\r
+ /* Set up binding to the client's endpoint: */\r
+ if (!status) {\r
+ status = RpcStringBindingCompose(\r
+ pszUuid,\r
+ pszProtocolSequence,\r
+ pszNetworkAddress,\r
+ (RPC_CSTR)endpoint,\r
+ pszOptions,\r
+ &pszStringBinding);\r
+ }\r
+\r
+ /* Set the binding handle that will be used to bind to the server. */\r
+ if (!status) {\r
+ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE); \r
+ }\r
+ if (!status) {bRpcHandleInited = TRUE;}\r
+\r
+ RpcTryExcept {\r
+ cci_debug_printf(" Calling remote procedure ccapi_listen");\r
+ ccapi_listen(rpcState, SERVER_REPLY_RPC_HANDLE, CCMSG_LISTEN, &status);\r
+ /* Asynchronous call will return immediately. */\r
+ }\r
+ RpcExcept(1) {\r
+ status = cci_check_error(RpcExceptionCode());\r
+ }\r
+ RpcEndExcept\r
+ \r
+ rcvargs->status = status;\r
+ } // End connectionListener\r
+\r
+\r
+void RPC_ENTRY clientListener(\r
+ _RPC_ASYNC_STATE* pAsync,\r
+ void* Context,\r
+ RPC_ASYNC_EVENT Event\r
+ ) {\r
+\r
+ ccs_pipe_t pipe = ccs_win_pipe_new((char*)pAsync->UserInfo, NULL);\r
+\r
+ cci_debug_printf("%s(0x%X, ...) async routine for <0x%X:%s>!", \r
+ __FUNCTION__, pAsync, pAsync->UserInfo, pAsync->UserInfo);\r
+\r
+ worklist_add( CCMSG_DISCONNECT, \r
+ pipe,\r
+ NULL, /* No payload with connect request */\r
+ (const time_t)0 ); /* No server session number with connect request */\r
+ }\r
+\r
+\r
+void printError( TCHAR* msg ) {\r
+ DWORD eNum;\r
+ TCHAR sysMsg[256];\r
+ TCHAR* p;\r
+\r
+ eNum = GetLastError( );\r
+ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | \r
+ FORMAT_MESSAGE_IGNORE_INSERTS,\r
+ NULL, eNum,\r
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
+ sysMsg, 256, NULL );\r
+\r
+ // Trim the end of the line and terminate it with a null\r
+ p = sysMsg;\r
+ while( ( *p > 31 ) || ( *p == 9 ) )\r
+ ++p;\r
+ do { *p-- = 0; } while( ( p >= sysMsg ) &&\r
+ ( ( *p == '.' ) || ( *p < 33 ) ) );\r
+\r
+ // Display the message\r
+ cci_debug_printf("%s failed with error %d (%s)", msg, eNum, sysMsg);\r
+ }\r
+\r
+\r
+RPC_STATUS send_init(char* clientUUID) {\r
+ RPC_STATUS status;\r
+ unsigned char * pszUuid = NULL;\r
+ unsigned char * pszOptions = NULL;\r
+ \r
+ /* Use a convenience function to concatenate the elements of */\r
+ /* the string binding into the proper sequence. */\r
+ status = RpcStringBindingCompose(pszUuid,\r
+ pszProtocolSequence,\r
+ pszNetworkAddress,\r
+ (unsigned char*)clientEndpoint(clientUUID),\r
+ pszOptions,\r
+ &pszStringBinding);\r
+ if (status) {return (status);}\r
+\r
+ /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */\r
+ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);\r
+ return (status);\r
+ }\r
+\r
+RPC_STATUS send_finish() {\r
+ RPC_STATUS status;\r
+ /* Can't shut down client -- it runs listen function which */\r
+ /* server uses to detect the client going away. */ \r
+\r
+ /* The calls to the remote procedures are complete. */\r
+ /* Free the string and the binding handle */\r
+ status = RpcStringFree(&pszStringBinding); // remote calls done; unbind\r
+ if (status) {return (status);}\r
+\r
+ status = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); // remote calls done; unbind\r
+ \r
+ return (status);\r
+ }\r
+\r
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe) {\r
+ char* uuid = ccs_win_pipe_getUuid (in_pipe);\r
+ HANDLE h = ccs_win_pipe_getHandle(in_pipe);\r
+ RPC_STATUS status = send_init(uuid);\r
+\r
+ RpcTryExcept {\r
+ ccs_rpc_connect_reply( // make call with user message\r
+ CCMSG_CONNECT_REPLY, /* Message type */\r
+ (unsigned char*)&h, /* client's tspdata* */\r
+ (unsigned char*)uuid,\r
+ getMySST(), /* Server's session number = it's start time */\r
+ &status ); /* Return code */\r
+ }\r
+ RpcExcept(1) {\r
+ cci_check_error(RpcExceptionCode());\r
+ }\r
+ RpcEndExcept\r
+\r
+ status = send_finish();\r
+ return (status);\r
+ }\r
+\r
+#if 0\r
+DWORD alloc_name(LPSTR* pname, LPSTR postfix) {\r
+ DWORD len = strlen(sessID) + 1 + strlen(postfix) + 1;\r
+\r
+ *pname = (LPSTR)malloc(len);\r
+ if (!*pname) return GetLastError();\r
+ _snprintf(*pname, len, "%s.%s", sessID, postfix);\r
+ return 0;\r
+ }\r
+#endif\r
+\r
+RPC_STATUS GetPeerName( RPC_BINDING_HANDLE hClient,\r
+ LPTSTR pszClientName,\r
+ int iMaxLen) {\r
+ RPC_STATUS Status = RPC_S_OK;\r
+ RPC_BINDING_HANDLE hServer = NULL;\r
+ PTBYTE pszStringBinding = NULL;\r
+ PTBYTE pszClientNetAddr = NULL;\r
+ PTBYTE pszProtSequence = NULL;\r
+\r
+ memset(pszClientName, 0, iMaxLen * sizeof(TCHAR));\r
+\r
+ __try {\r
+ // Create a partially bound server handle from the client handle.\r
+ Status = RpcBindingServerFromClient (hClient, &hServer);\r
+ if (Status != RPC_S_OK) __leave;\r
+\r
+ // Get the partially bound server string binding and parse it.\r
+ Status = RpcBindingToStringBinding (hServer,\r
+ &pszStringBinding);\r
+ if (Status != RPC_S_OK) __leave;\r
+\r
+ // String binding only contains protocol sequence and client\r
+ // address, and is not currently implemented for named pipes.\r
+ Status = RpcStringBindingParse (pszStringBinding, NULL,\r
+ &pszProtSequence, &pszClientNetAddr, \r
+ NULL, NULL);\r
+ if (Status != RPC_S_OK)\r
+ __leave;\r
+ int iLen = lstrlen(pszClientName) + 1;\r
+ if (iMaxLen < iLen)\r
+ Status = RPC_S_BUFFER_TOO_SMALL;\r
+ lstrcpyn(pszClientName, (LPCTSTR)pszClientNetAddr, iMaxLen);\r
+ }\r
+ __finally {\r
+ if (pszProtSequence)\r
+ RpcStringFree (&pszProtSequence);\r
+ \r
+ if (pszClientNetAddr)\r
+ RpcStringFree (&pszClientNetAddr);\r
+ \r
+ if (pszStringBinding)\r
+ RpcStringFree (&pszStringBinding);\r
+ \r
+ if (hServer)\r
+ RpcBindingFree (&hServer);\r
+ }\r
+ return Status;\r
+}\r
+\r
+struct client_auth_info {\r
+ RPC_AUTHZ_HANDLE authz_handle;\r
+ unsigned char* server_principal; // need to RpcFreeString this\r
+ ULONG authn_level;\r
+ ULONG authn_svc;\r
+ ULONG authz_svc;\r
+};\r
+\r
+RPC_STATUS\r
+GetClientId(\r
+ RPC_BINDING_HANDLE hClient,\r
+ char* client_id,\r
+ int max_len,\r
+ client_auth_info* info\r
+ )\r
+{\r
+ RPC_AUTHZ_HANDLE authz_handle = 0;\r
+ unsigned char* server_principal = 0;\r
+ ULONG authn_level = 0;\r
+ ULONG authn_svc = 0;\r
+ ULONG authz_svc = 0;\r
+ RPC_STATUS status = 0;\r
+\r
+ memset(client_id, 0, max_len);\r
+\r
+ if (info) {\r
+ memset(info, 0, sizeof(client_auth_info));\r
+ }\r
+\r
+ status = RpcBindingInqAuthClient(hClient, &authz_handle, \r
+ info ? &server_principal : 0, \r
+ &authn_level, &authn_svc, &authz_svc);\r
+ if (status == RPC_S_OK)\r
+ {\r
+ if (info) {\r
+ info->server_principal = server_principal;\r
+ info->authz_handle = authz_handle;\r
+ info->authn_level = authn_level;\r
+ info->authn_svc = authn_svc;\r
+ info->authz_svc = authz_svc;\r
+ }\r
+\r
+ if (authn_svc == RPC_C_AUTHN_WINNT) {\r
+ WCHAR* username = (WCHAR*)authz_handle;\r
+ int len = lstrlenW(username) + 1;\r
+ if (max_len < len)\r
+ status = RPC_S_BUFFER_TOO_SMALL;\r
+ _snprintf(client_id, max_len, "%S", username);\r
+ } else {\r
+ status = RPC_S_UNKNOWN_AUTHN_SERVICE;\r
+ }\r
+ }\r
+ return status;\r
+}\r
+\r
+char*\r
+rpc_error_to_string(\r
+ RPC_STATUS status\r
+ )\r
+{\r
+ switch(status) {\r
+ case RPC_S_OK:\r
+ return "OK";\r
+ case RPC_S_INVALID_BINDING:\r
+ return "Invalid binding";\r
+ case RPC_S_WRONG_KIND_OF_BINDING:\r
+ return "Wrong binding";\r
+ case RPC_S_BINDING_HAS_NO_AUTH:\r
+ RpcRaiseException(RPC_S_BINDING_HAS_NO_AUTH);\r
+ return "Binding has no auth";\r
+ default:\r
+ return "BUG: I am confused";\r
+ }\r
+}\r
+\r
+void\r
+print_client_info(\r
+ RPC_STATUS peer_status,\r
+ const char* peer_name,\r
+ RPC_STATUS client_status,\r
+ const char* client_id,\r
+ client_auth_info* info\r
+ )\r
+{\r
+ if (peer_status == RPC_S_OK || peer_status == RPC_S_BUFFER_TOO_SMALL) {\r
+ cci_debug_printf("%s Peer Name is \"%s\"", __FUNCTION__, peer_name);\r
+ } else {\r
+ cci_debug_printf("%s Error %u getting Peer Name (%s)",\r
+ __FUNCTION__, peer_status, rpc_error_to_string(peer_status));\r
+ }\r
+\r
+ if (client_status == RPC_S_OK || client_status == RPC_S_BUFFER_TOO_SMALL) {\r
+ if (info) {\r
+ cci_debug_printf("%s Client Auth Info"\r
+ "\tServer Principal: %s\n"\r
+ "\tAuthentication Level: %d\n"\r
+ "\tAuthentication Service: %d\n"\r
+ "\tAuthorization Service: %d\n",\r
+ __FUNCTION__, \r
+ info->server_principal,\r
+ info->authn_level,\r
+ info->authn_svc,\r
+ info->authz_svc);\r
+ }\r
+ cci_debug_printf("%s Client ID is \"%s\"", __FUNCTION__, client_id);\r
+ } else {\r
+ cci_debug_printf("%s Error getting Client Info (%u = %s)", \r
+ __FUNCTION__, client_status, rpc_error_to_string(client_status));\r
+ }\r
+}\r
+\r
+DWORD sid_check() {\r
+ DWORD status = 0;\r
+ HANDLE hToken_c = 0;\r
+ HANDLE hToken_s = 0;\r
+ PTOKEN_USER ptu_c = 0;\r
+ PTOKEN_USER ptu_s = 0;\r
+ DWORD len = 0;\r
+ BOOL bImpersonate = FALSE;\r
+\r
+ // Note GetUserName will fail while impersonating at identify\r
+ // level. The workaround is to impersonate, OpenThreadToken,\r
+ // revert, call GetTokenInformation, and finally, call\r
+ // LookupAccountSid.\r
+\r
+ // XXX - Note: This workaround does not appear to work.\r
+ // OpenThreadToken fails with error 1346: "Either a requid\r
+ // impersonation level was not provided or the provided\r
+ // impersonation level is invalid".\r
+\r
+ status = RpcImpersonateClient(0);\r
+\r
+ if (!status) {\r
+ bImpersonate = TRUE;\r
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken_c))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ status = RpcRevertToSelf();\r
+ }\r
+\r
+ if (!status) {\r
+ bImpersonate = FALSE;\r
+\r
+ len = 0;\r
+ GetTokenInformation(hToken_c, TokenUser, ptu_c, 0, &len);\r
+ if (len == 0) status = 1;\r
+ }\r
+\r
+ if (!status) {\r
+ if (!(ptu_c = (PTOKEN_USER)LocalAlloc(0, len)))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!GetTokenInformation(hToken_c, TokenUser, ptu_c, len, &len))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken_s))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ len = 0;\r
+ GetTokenInformation(hToken_s, TokenUser, ptu_s, 0, &len);\r
+ if (len == 0) status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!(ptu_s = (PTOKEN_USER)LocalAlloc(0, len)))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!status) {\r
+ if (!GetTokenInformation(hToken_s, TokenUser, ptu_s, len, &len))\r
+ status = GetLastError();\r
+ }\r
+\r
+ if (!EqualSid(ptu_s->User.Sid, ptu_c->User.Sid))\r
+ status = RPC_S_ACCESS_DENIED;\r
+\r
+/* Cleanup: */\r
+ if (!hToken_c && !bImpersonate)\r
+ cci_debug_printf("%s Cannot impersonate (%u)", __FUNCTION__, status);\r
+ else if (!hToken_c)\r
+ cci_debug_printf("%s Failed to open client token (%u)", __FUNCTION__, status);\r
+ else if (bImpersonate)\r
+ cci_debug_printf("%s Failed to revert (%u)", __FUNCTION__, status);\r
+ else if (!ptu_c)\r
+ cci_debug_printf("%s Failed to get client token user info (%u)",\r
+ __FUNCTION__, status);\r
+ else if (!hToken_s)\r
+ cci_debug_printf("%s Failed to open server token (%u)", __FUNCTION__, status);\r
+ else if (!ptu_s)\r
+ cci_debug_printf("%s Failed to get server token user info (%u)",\r
+ __FUNCTION__, status);\r
+ else if (status == RPC_S_ACCESS_DENIED)\r
+ cci_debug_printf("%s SID **does not** match!", __FUNCTION__);\r
+ else if (status == RPC_S_OK)\r
+ cci_debug_printf("%s SID matches!", __FUNCTION__);\r
+ else \r
+ if (status) {\r
+ cci_debug_printf("%s unrecognized error %u", __FUNCTION__, status);\r
+ abort();\r
+ }\r
+\r
+ if (bImpersonate) RpcRevertToSelf();\r
+ if (hToken_c && hToken_c != INVALID_HANDLE_VALUE)\r
+ CloseHandle(hToken_c);\r
+ if (ptu_c) LocalFree(ptu_c);\r
+ if (hToken_s && hToken_s != INVALID_HANDLE_VALUE)\r
+ CloseHandle(hToken_s);\r
+ if (ptu_s) LocalFree(ptu_s);\r
+ if (status) cci_debug_printf("%s returning %u", __FUNCTION__, status);\r
+ return status;\r
+ }\r
+\r
+RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,\r
+ IN void *Context) {\r
+ char peer_name[1024];\r
+ char client_name[1024];\r
+ RPC_STATUS peer_status;\r
+ RPC_STATUS client_status;\r
+\r
+ cci_debug_printf("%s", __FUNCTION__);\r
+ peer_status = GetPeerName(Context, peer_name, sizeof(peer_name));\r
+ client_status = GetClientId(Context, client_name, sizeof(client_name), 0);\r
+ print_client_info(peer_status, peer_name, client_status, client_name, 0);\r
+ DWORD sid_status = sid_check();\r
+ cci_debug_printf("%s returning (%u)", __FUNCTION__, sid_status);\r
+ return sid_status;\r
+ }\r
+\r
+\r
+\r
+/*********************************************************************/\r
+/* MIDL allocate and free */\r
+/*********************************************************************/\r
+\r
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {\r
+ return(malloc(len));\r
+ }\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {\r
+ free(ptr);\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+\r
+#include "ccs_request.h" // header file generated by MIDL compiler\r
+#include "cci_debugging.h"\r
+#include "WorkQueue.h"\r
+#include "win-utils.h"\r
+#include "ccs_win_pipe.h"\r
+\r
+void ccs_rpc_request(\r
+ const long rpcmsg, /* Message type */\r
+ const char tspHandle[], /* Client's tspdata* */\r
+ const char* pszUUID, /* Where client will listen for the reply */\r
+ const long lenRequest, /* Length of buffer */\r
+ const char pbRequest[], /* Data buffer */\r
+ const long serverStartTime, /* Which server session we're talking to */\r
+ long* return_status ) { /* Return code */\r
+\r
+ cc_int32 status = 0;\r
+ cci_stream_t stream;\r
+ DWORD* p = (DWORD*)(tspHandle);\r
+ WIN_PIPE* pipe = NULL;\r
+\r
+ cci_debug_printf("%s rpcmsg:%d; UUID:<%s> SST:<%s>", \r
+ __FUNCTION__, rpcmsg, pszUUID, serverStartTime);\r
+\r
+ status = (rpcmsg != CCMSG_REQUEST) && (rpcmsg != CCMSG_PING);\r
+ \r
+ if (!status) { \r
+ status = cci_stream_new (&stream); /* Create a stream for the request data */\r
+ }\r
+\r
+ if (!status) { /* Put the data into the stream */\r
+ status = cci_stream_write (stream, pbRequest, lenRequest);\r
+ }\r
+\r
+ pipe = ccs_win_pipe_new(pszUUID, *p); \r
+ worklist_add(rpcmsg, pipe, stream, serverStartTime);\r
+ *return_status = status;\r
+ }\r
+\r
+\r
+void ccs_rpc_connect(\r
+ const long rpcmsg, /* Message type */\r
+ const char tspHandle[], /* Client's tspdata* */\r
+ const char* pszUUID, /* Data buffer */\r
+ long* return_status ) { /* Return code */\r
+\r
+ DWORD* p = (DWORD*)(tspHandle);\r
+ WIN_PIPE* pipe = ccs_win_pipe_new(pszUUID, *p);\r
+\r
+ cci_debug_printf("%s; rpcmsg:%d; UUID: <%s>", __FUNCTION__, rpcmsg, pszUUID);\r
+\r
+ worklist_add( rpcmsg, \r
+ pipe,\r
+ NULL, /* No payload with connect request */\r
+ (const time_t)0 ); /* No server session number with connect request */\r
+ }\r
+\r
+\r
+// 'Authentication' is client setting a value in a file and the server\r
+// returning that value plus one.\r
+CC_UINT32 ccs_authenticate(const CC_CHAR* name) {\r
+ HANDLE hMap = 0;\r
+ PDWORD pvalue = 0;\r
+ CC_UINT32 result = 0;\r
+ DWORD status = 0;\r
+\r
+ cci_debug_printf("%s ( %s )", __FUNCTION__, name);\r
+\r
+ hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, (LPSTR)name);\r
+ status = !hMap;\r
+\r
+ if (!status) {\r
+ pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);\r
+ status = !pvalue;\r
+ }\r
+\r
+ if (!status) {\r
+ *pvalue += 1;\r
+ result = *pvalue;\r
+ }\r
+\r
+ if (pvalue) {\r
+ UnmapViewOfFile(pvalue);\r
+ }\r
+\r
+ if (hMap) CloseHandle(hMap);\r
+ return result;\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "assert.h"\r
+\r
+#include "ccs_win_pipe.h"\r
+#include "cci_debugging.h"\r
+\r
+/* Ref:\r
+struct ccs_win_pipe_t {\r
+ char* uuid;\r
+ HANDLE clientHandle;\r
+ }\r
+ */\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+struct ccs_win_pipe_t* ccs_win_pipe_new (const char* uuid, const HANDLE h) {\r
+\r
+ cc_int32 err = ccNoError;\r
+ struct ccs_win_pipe_t* out_pipe = NULL;\r
+ char* uuidCopy = NULL;\r
+\r
+ if (!err) {\r
+ if (!uuid) {err = cci_check_error(ccErrBadParam);}\r
+ }\r
+\r
+ if (!err) {\r
+ uuidCopy = (char*)malloc(1+strlen(uuid));\r
+ if (!uuidCopy) {err = cci_check_error(ccErrBadParam);}\r
+ strcpy(uuidCopy, uuid);\r
+ }\r
+ \r
+ if (!err) {\r
+ out_pipe = (struct ccs_win_pipe_t*)malloc(sizeof(struct ccs_win_pipe_t));\r
+ if (!out_pipe) {err = cci_check_error(ccErrBadParam);}\r
+ out_pipe->uuid = uuidCopy;\r
+ out_pipe->clientHandle = h;\r
+ }\r
+\r
+ cci_debug_printf("0x%X = %s(%s, 0x%X)", out_pipe, __FUNCTION__, uuid, h);\r
+\r
+ return out_pipe;\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe, \r
+ const WIN_PIPE* in_pipe) {\r
+\r
+ *out_pipe = \r
+ ccs_win_pipe_new(\r
+ ccs_win_pipe_getUuid (in_pipe),\r
+ ccs_win_pipe_getHandle(in_pipe) );\r
+\r
+ return (*out_pipe) ? ccNoError : ccErrBadParam;\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_release(const WIN_PIPE* in_pipe) {\r
+\r
+ cc_int32 err = ccNoError;\r
+\r
+ if (!ccs_win_pipe_valid(in_pipe)) {err = cci_check_error(ccErrBadParam);}\r
+\r
+ if (!err) {\r
+ if (!in_pipe->uuid) free(in_pipe->uuid);\r
+ if (!in_pipe) free(in_pipe);\r
+ }\r
+\r
+ return err;\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe) {\r
+\r
+ if (!in_pipe) {\r
+ cci_check_error(ccErrBadParam);\r
+ return FALSE;\r
+ }\r
+\r
+ if (!in_pipe->uuid) {\r
+ cci_check_error(ccErrBadParam);\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_compare (const WIN_PIPE* in_pipe_1,\r
+ const WIN_PIPE* in_pipe_2,\r
+ cc_uint32 *out_equal) {\r
+\r
+ cc_int32 err = ccNoError;\r
+ int seq = 0;\r
+ *out_equal = FALSE;\r
+\r
+ if (!ccs_win_pipe_valid(in_pipe_1)) {err = cci_check_error(ccErrBadParam);}\r
+ if (!ccs_win_pipe_valid(in_pipe_2)) {err = cci_check_error(ccErrBadParam);}\r
+ if (!out_equal) {err = cci_check_error(ccErrBadParam);}\r
+\r
+ /* A disconnect doesn't have a tls* with it -- only the uuid. SO only\r
+ compare the uuids.\r
+ */\r
+ if (!err) {\r
+ seq = strcmp( ccs_win_pipe_getUuid(in_pipe_1),\r
+ ccs_win_pipe_getUuid(in_pipe_2) );\r
+ *out_equal = (seq == 0);\r
+ }\r
+\r
+ return err;\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+char* ccs_win_pipe_getUuid (const WIN_PIPE* in_pipe) {\r
+\r
+ char* result = NULL;\r
+\r
+ if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);}\r
+ else {result = in_pipe->uuid;}\r
+\r
+ return result;\r
+ }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+HANDLE ccs_win_pipe_getHandle (const WIN_PIPE* in_pipe) {\r
+\r
+ HANDLE result = NULL;\r
+\r
+ if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);}\r
+ else {result = in_pipe->clientHandle;}\r
+\r
+ return result;\r
+ }\r
--- /dev/null
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission. Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose. It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _ccs_win_pipe_h_\r
+#define _ccs_win_pipe_h_\r
+\r
+#include "windows.h"\r
+\r
+#include "CredentialsCache.h"\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+/* On Windows, a pipe is a struct containing a UUID and a handle. Both the \r
+ UUID and handle are supplied by the client. \r
+ \r
+ The UUID is used to build the client's reply endpoint. \r
+ \r
+ The handle is to the requesting client thread's thread local storage struct,\r
+ so that the client's one and only reply handler can put reply data where\r
+ the requesting thread will be able to see it.\r
+ */\r
+ \r
+struct ccs_win_pipe_t {\r
+ char* uuid;\r
+ HANDLE clientHandle;\r
+ };\r
+\r
+typedef struct ccs_win_pipe_t WIN_PIPE;\r
+\r
+struct ccs_win_pipe_t* ccs_win_pipe_new(const char* uuid, const HANDLE h);\r
+\r
+cc_int32 ccs_win_pipe_release (const WIN_PIPE* io_pipe);\r
+\r
+cc_int32 ccs_win_pipe_compare (const WIN_PIPE* win_pipe_1,\r
+ const WIN_PIPE* win_pipe_2,\r
+ cc_uint32 *out_equal);\r
+\r
+cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe, \r
+ const WIN_PIPE* in_pipe);\r
+\r
+cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe);\r
+\r
+char* ccs_win_pipe_getUuid (const WIN_PIPE* in_pipe);\r
+HANDLE ccs_win_pipe_getHandle (const WIN_PIPE* in_pipe);\r
+\r
+#endif // _ccs_win_pipe_h_
\ No newline at end of file
--- /dev/null
+#ifndef __WorkItem\r
+#define __WorkItem\r
+\r
+#include <list>\r
+#include "windows.h"\r
+\r
+extern "C" {\r
+ #include "cci_stream.h"\r
+ #include "ccs_pipe.h"\r
+ }\r
+\r
+class WorkItem {\r
+private:\r
+ cci_stream_t _buf;\r
+ WIN_PIPE* _pipe;\r
+ const long _rpcmsg;\r
+ const long _sst;\r
+public:\r
+ WorkItem( cci_stream_t buf, \r
+ WIN_PIPE* pipe, \r
+ const long type, \r
+ const long serverStartTime);\r
+ WorkItem( const WorkItem&);\r
+ WorkItem();\r
+ ~WorkItem();\r
+\r
+ const cci_stream_t payload() const {return _buf;}\r
+ const cci_stream_t take_payload();\r
+ WIN_PIPE* take_pipe();\r
+ WIN_PIPE* pipe() const {return _pipe;}\r
+ const long type() const {return _rpcmsg;}\r
+ const long sst() const {return _sst;}\r
+ char* print(char* buf);\r
+ };\r
+\r
+class WorkList {\r
+private:\r
+ std::list <WorkItem*> wl;\r
+ CRITICAL_SECTION cs;\r
+public:\r
+ WorkList();\r
+ ~WorkList();\r
+ int add(WorkItem*);\r
+ int remove(WorkItem**);\r
+ bool isEmpty() {return wl.empty();}\r
+ };\r
+\r
+#endif // __WorkItem
\ No newline at end of file
--- /dev/null
+# . is ccapi/test.\r
+CO = ..\common\r
+COWIN = $(CO)\win\r
+LIBDIR = ..\lib\r
+LIBWIN = $(LIBDIR)\win\r
+\r
+!include <Win32.Mak>\r
+\r
+INC = -I..\..\include -I..\..\util\et -I$(CO) -I$(COWIN) -I$(LIBDIR) -I$(LIBWIN)\r
+\r
+!if "$(CPU)" == "i386"\r
+cflags = $(cflags) /EHsc /MTd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \\r
+$(INC)\r
+!else\r
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)\r
+!endif\r
+LIBS = $(LIBWIN)\ccapi.lib\r
+\r
+DSTROOT = .\r
+SRC = $(DSTROOT)\r
+#OBJDIR = $(DSTROOT)\obj\r
+OBJDIR = .\r
+OBJEXT = obj\r
+TESTDIR = $(DSTROOT)\tests\r
+TESTEXT = exe\r
+DSTDIR = $(DSTROOT)\ccapi_tests\r
+PINGOBJS = pingtest.obj ccs_request_c.obj \r
+SIMPLEOBJS = simple_lock_test.obj\r
+\r
+OBJS = cci_debugging.$(OBJEXT) \\r
+ ccs_request_c.obj \\r
+ cci_os_debugging.$(OBJEXT) \\r
+ win-utils.obj \\r
+ ccapi_os_ipc.obj \\r
+ cci_stream.obj\r
+ \r
+#all: build-base simple_lock_test pingtest \r
+all: build-base pingtest \r
+\r
+# compile base files used by all tests\r
+build-base: $(OBJS)\r
+ @echo "Base objects built."\r
+\r
+# rule to compile src files\r
+.c.obj:\r
+ $(cc) $(cdebug) $(cflags) /Fo$(OBJDIR)\$(*B).$(OBJEXT) $(SRC)\$(*B).c\r
+\r
+simple_lock_test: simple_lock_test.obj $(OBJS)\r
+ @echo R3+ Build $(*B) in $(TESTDIR)\r
+ $(cc) $(cdebug) $(cflags) $(*B).c\r
+ $(link) $(linkdebug) $(conflags) -out:$(TESTDIR)\$(*B).exe $(*B).obj \\r
+ $(LIBS) rpcrt4.lib\r
+ @echo R3- Built $(*B) in $(TESTDIR)\r
+\r
+pingtest: pingtest.obj\r
+ @echo R4+ Build $(*B) in $(TESTDIR)\r
+ $(cc) $(cdebug) $(cflags) $(*B).c\r
+# $(link) $(linkdebug) $(conflags) -out:$(*B).exe $(*B).obj \\r
+ $(link) $(linkdebug) $(conflags) -out:$(*B).exe $(PINGOBJS) \\r
+ $(LIBS) rpcrt4.lib\r
+ @echo R4- Built $(*B) in $(TESTDIR)\r
+\r
+clean:\r
+ DEL *.$(OBJEXT)
\ No newline at end of file
--- /dev/null
+// pingtest.c\r
+//\r
+// Test RPC to server, with PING message, which exists for no other purpose than this test.\r
+\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include "cci_debugging.h"\r
+#include "CredentialsCache.h"\r
+#include "cci_stream.h"\r
+#include "win-utils.h"\r
+\r
+#include "ccs_request.h"\r
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle\r
+\r
+\r
+extern cc_int32 cci_os_ipc_thread_init (void);\r
+extern cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,\r
+ cci_stream_t in_request_stream,\r
+ cc_int32 in_msg,\r
+ cci_stream_t* out_reply_stream);\r
+\r
+RPC_STATUS send_test(char* endpoint) {\r
+ unsigned char* pszNetworkAddress = NULL;\r
+ unsigned char* pszOptions = NULL;\r
+ unsigned char* pszStringBinding = NULL;\r
+ unsigned char* pszUuid = NULL;\r
+ RPC_STATUS status;\r
+ \r
+ status = RpcStringBindingCompose(pszUuid,\r
+ (RPC_CSTR)"ncalrpc",\r
+ pszNetworkAddress,\r
+ (unsigned char*)endpoint,\r
+ pszOptions,\r
+ &pszStringBinding);\r
+ cci_debug_printf("%s pszStringBinding = %s", __FUNCTION__, pszStringBinding);\r
+ if (status) {return cci_check_error(status);}\r
+\r
+ /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */\r
+ status = RpcBindingFromStringBinding(pszStringBinding, &CLIENT_REQUEST_RPC_HANDLE);\r
+ if (status) {return cci_check_error(status);}\r
+\r
+ status = RpcStringFree(&pszStringBinding); // Temp var no longer needed.\r
+\r
+ if (!status) {\r
+ RpcTryExcept {\r
+ cci_debug_printf("%s calling remote procedure 'ccs_authenticate'", __FUNCTION__);\r
+ status = ccs_authenticate((CC_CHAR*)"DLLMAIN TEST!");\r
+ cci_debug_printf(" ccs_authenticate returned %d", status);\r
+ }\r
+ RpcExcept(1) {\r
+ status = cci_check_error(RpcExceptionCode());\r
+ }\r
+ RpcEndExcept\r
+ }\r
+\r
+ cci_check_error(RpcBindingFree(&CLIENT_REQUEST_RPC_HANDLE));\r
+\r
+ return (status);\r
+ }\r
+\r
+int main( int argc, char *argv[]) {\r
+ cc_int32 err = 0;\r
+ cc_context_t context = NULL;\r
+ cci_stream_t send_stream = NULL;\r
+ cci_stream_t reply_stream = NULL;\r
+ char* message = "Hello, RPC!";\r
+\r
+\r
+// send_test("krbcc.229026.0.ep");\r
+\r
+#if 0\r
+ err = cc_initialize(&context, ccapi_version_7, NULL, NULL);\r
+#endif\r
+\r
+ if (!err) {\r
+ err = cci_os_ipc_thread_init();\r
+ }\r
+ if (!err) {\r
+ err = cci_stream_new (&send_stream);\r
+ err = cci_stream_write(send_stream, message, 1+strlen(message));\r
+ }\r
+\r
+ if (!err) {\r
+ err = cci_os_ipc_msg(TRUE, send_stream, CCMSG_PING, &reply_stream); \r
+ }\r
+ Sleep(10*1000);\r
+ cci_debug_printf("Try finishing async call.");\r
+\r
+ Sleep(INFINITE);\r
+ cci_debug_printf("main: return. err == %d", err);\r
+ \r
+ return 0;\r
+ }\r
+\r
+\r
+\r
+/*********************************************************************/\r
+/* MIDL allocate and free */\r
+/*********************************************************************/\r
+\r
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {\r
+ return(malloc(len));\r
+ }\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {\r
+ free(ptr);\r
+ }\r
-/*
- simple_lock_test.c
-
- Initializes two contexts in two different threads and tries to get read locks on both at the same time.
- Hangs at line 24.
-*/
-#include <pthread.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <Kerberos/CredentialsCache.h>
-
-void * other_thread ()
-{
- cc_int32 err;
- cc_context_t context = NULL;
-
- err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
-
- fprintf(stderr, "thread: attempting lock. may hang. err == %d\n", err);
-
- if (!err) {
- // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately
- err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
- }
-
- if (context) {
- cc_context_unlock(context);
- cc_context_release(context);
- context = NULL;
- }
- fprintf(stderr, "thread: return. err == %d\n", err);
-}
-
-
-int main (int argc, char *argv[])
-{
- cc_int32 err;
- int status;
- pthread_t thread_id;
- cc_context_t context = NULL;
-
- err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
- if (!err) {
- err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
- }
-
- fprintf(stderr, "main: initialized and read locked context. err == %d\n", err);
-
- status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL);
- if (status != 0) {
- fprintf(stderr,"Create error!\n");
- exit(-1);
- }
-
- pthread_join(thread_id, NULL);
-
- fprintf(stderr, "main: unlocking and releasing context. err == %d\n", err);
-
- if (context) {
- cc_context_unlock(context);
- cc_context_release(context);
- context = NULL;
- }
-
- fprintf(stderr, "main: return. err == %d\n", err);
-
- return 0;
-}
\ No newline at end of file
+/*\r
+ simple_lock_test.c\r
+ \r
+ Initializes two contexts in two different threads and tries to get read locks on both at the same time.\r
+ Hangs at line 24.\r
+*/\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include "cci_debugging.h"\r
+\r
+#ifdef TARGET_OS_MAC\r
+#include <stdlib.h>\r
+#include <Kerberos/CredentialsCache.h>\r
+#else\r
+#include "CredentialsCache.h"\r
+#endif\r
+\r
+\r
+void * other_thread () {\r
+ cc_int32 err;\r
+ cc_context_t context = NULL;\r
+ \r
+ err = cc_initialize(&context, ccapi_version_7, NULL, NULL);\r
+\r
+ cci_debug_printf("thread: attempting lock. may hang. err == %d", err);\r
+\r
+ if (!err) {\r
+ // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately\r
+ err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);\r
+ }\r
+\r
+ if (context) {\r
+ cc_context_unlock(context);\r
+ cc_context_release(context);\r
+ context = NULL;\r
+ }\r
+ cci_debug_printf("thread: return. err == %d", err);\r
+ }\r
+\r
+\r
+int main (int argc, char *argv[]) {\r
+ cc_int32 err;\r
+ int status;\r
+ cc_context_t context = NULL;\r
+\r
+#ifdef TARGET_OS_MAC\r
+ pthread_t thread_id;\r
+#endif\r
+\r
+ err = cc_initialize(&context, ccapi_version_7, NULL, NULL);\r
+ if (!err) {\r
+ err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);\r
+ }\r
+ \r
+ cci_debug_printf("main: initialized and read locked context. err == %d", err);\r
+\r
+#ifdef TARGET_OS_MAC\r
+ status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL);\r
+ if (status != 0) {\r
+ cci_debug_printf("Create error!");\r
+ exit(-1);\r
+ }\r
+\r
+ pthread_join(thread_id, NULL);\r
+#else\r
+\r
+#endif\r
+ \r
+ cci_debug_printf("main: unlocking and releasing context. err == %d", err);\r
+ \r
+ if (context) {\r
+ cci_debug_printf("main: calling cc_context_unlock");\r
+ cc_context_unlock(context);\r
+ cci_debug_printf("main: calling cc_context_release");\r
+ cc_context_release(context);\r
+ context = NULL;\r
+ }\r
+\r
+ cci_debug_printf("main: return. err == %d", err);\r
+ \r
+ UNREFERENCED_PARAMETER(status); // no whining!\r
+ return 0;\r
+ }
\ No newline at end of file