diff options
author | Tom Yu <tlyu@mit.edu> | 2011-12-14 00:07:54 +0000 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2011-12-14 00:07:54 +0000 |
commit | 93d3863162eef1ba9c27709145183ca5ce33a14a (patch) | |
tree | 9dd7b56bdf4424831f783967f8cd29c8d2547bd9 /src/ccapi | |
parent | fd8bcf5841e5affdc1622b723c2a0242ed03b7be (diff) | |
download | krb5-93d3863162eef1ba9c27709145183ca5ce33a14a.zip krb5-93d3863162eef1ba9c27709145183ca5ce33a14a.tar.gz krb5-93d3863162eef1ba9c27709145183ca5ce33a14a.tar.bz2 |
Squash commits for KfW updates
windows ccapiserver: replace Sleep with event wait
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
fix warning in test_cc_credentials_iterator_next.c
include test_ccapi_iterators.h for check_cc_credentials_iterator_next
Make ccapiserver exit if its receiveloop thread terminates for any reason.
This happens, for example, when the rpc endpoint is already registered
by another ccapiserver process. There's no reason to leave a zombie
process running that can't receive messages.
windows ccapi: launch server without console by default.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
windows ccapi: use a random challenge to authenticate ccapiserver.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
LeashView.cpp: only specify TVIF_TEXT if there is actually text.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: add runtime.wxi WIXINCLUDES in Makefile to fix dependencies.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
Windows leash64 fixes: use proper names for leash and krb5 dlls
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
Windows leash fixes: 'make install' installs leash exes.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: use MSVC 2010 merge modules
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: install leash32.exe
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: clean out unused #defines from Lglobals.h
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: use correct message id to obtain tgt from leash
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: update copyright notice in license.rtf
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fixes: install xpprof32
TODO: xpprof64!
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: purge support for old compilers
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: don't build installer into installer
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fixes: make leash ignore credentials that store config principals.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fix: make Leash_kdestroy() actually destroy k5 tickets
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fix: Add custom "Password incorrect" message to Leash_int_kinit_ex()
Overrides obscure KRB5KRB_AP_ERR_BAD_INTEGRITY message.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fixes: define USE_MESSAGE_BOX in leashdll code for user feedback.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fixes: krb5_get_init_creds_opt_init->krb5_get_init_creds_opt_alloc
Should enable leash to generate config credentials (needs verification!)
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fix: int -> size_t to fix warning in krb5routines.c
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fix: restructure low ticket warning popup code to workaround mfc bug
mfc bug causes assertions when dialog is generated from
within PreTranslateMessages() (MSG input param points to a global
variable which is corrupted in the dialog message loop). So we need
to instead PostMessage() to cause the popup later.
Also fixed logic to cause warning dialog to actually be modal as intended
when the leash window is not minimized.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fixes: fix _snprintf usage; use full error code in leash_error_message
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw fixes: ccapiserver only quits after all clients detach.
Not sure if this is really a good idea or not...
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: generate manifests
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: generate leash shortcuts (desktop and start menu)
...also install xpprof64
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: fix 'K5_ORIGINAL_NAME' for 64 bit dlls.
...still need to actually to define _WIN64 for rc.exe though
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: purge bufferoverflowu from custom.dll
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: rename leash32/64.exe to simply leash.exe
Also install leash.exe in 64 bit installer.
Split cci_thread_init into per-process and per-thread portions
Call the per-thread code on thread attach and per-process once per
process. Previously, while the function was named 'thread', it was
only actually called once per process. Currently, the per-thread
code does nothing on non-windows platforms and is not even actually
invoked.
Fixes a windows bug when multiple non-main threads try to use ccapi
at the same time.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw leash: add -console option to create console for debug output
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: use _WIN64 names where appropriate
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw leash: bracket krb.con code with #ifndef NO_KRB4
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: install krb5.ini to CommonAppDataFolder, not WindowsFolder
...but only if there isn't already a krb5.ini in the WindowsFolder.
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: "make install" also installs pdbs
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: leash32.pdb->leash.pdb
kfw installer: add site-local.wxi
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: leash htmlhelp file source
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: use html help in leash
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: "make install" installs htmlhelp (leash.chm)
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw installer: install leash help file (leash.chm)
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw: remove line breaks from html to fix table of contents generation
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw leash help: fix/add aliases for command help
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
kfw leash: fix bad data in get tickets dialog when -autoinit specified
Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>
ticket: 7050
version_fixed: 1.10
status: resolved
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-10@25585 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/ccapi')
-rw-r--r-- | src/ccapi/common/win/OldCC/autolock.hxx | 11 | ||||
-rw-r--r-- | src/ccapi/common/win/win-utils.h | 3 | ||||
-rw-r--r-- | src/ccapi/lib/ccapi_context.c | 14 | ||||
-rw-r--r-- | src/ccapi/lib/ccapi_ipc.c | 7 | ||||
-rw-r--r-- | src/ccapi/lib/ccapi_ipc.h | 2 | ||||
-rw-r--r-- | src/ccapi/lib/ccapi_os_ipc.h | 2 | ||||
-rw-r--r-- | src/ccapi/lib/win/OldCC/client.cxx | 56 | ||||
-rw-r--r-- | src/ccapi/lib/win/ccapi_os_ipc.cxx | 120 | ||||
-rw-r--r-- | src/ccapi/lib/win/debug.exports | 1 | ||||
-rw-r--r-- | src/ccapi/lib/win/dllmain.cxx | 11 | ||||
-rw-r--r-- | src/ccapi/server/ccs_server.c | 7 | ||||
-rw-r--r-- | src/ccapi/server/ccs_server.h | 2 | ||||
-rw-r--r-- | src/ccapi/server/win/WorkItem.cpp | 16 | ||||
-rw-r--r-- | src/ccapi/server/win/WorkQueue.cpp | 17 | ||||
-rw-r--r-- | src/ccapi/server/win/WorkQueue.h | 9 | ||||
-rw-r--r-- | src/ccapi/server/win/ccs_os_server.cpp | 24 | ||||
-rw-r--r-- | src/ccapi/server/win/workitem.h | 4 | ||||
-rw-r--r-- | src/ccapi/test/test_cc_credentials_iterator_next.c | 1 |
18 files changed, 216 insertions, 91 deletions
diff --git a/src/ccapi/common/win/OldCC/autolock.hxx b/src/ccapi/common/win/OldCC/autolock.hxx index bbd7734..45b881e 100644 --- a/src/ccapi/common/win/OldCC/autolock.hxx +++ b/src/ccapi/common/win/OldCC/autolock.hxx @@ -35,10 +35,8 @@ public: ~CcOsLock() {DeleteCriticalSection(&cs); valid = false;} void lock() {if (valid) EnterCriticalSection(&cs);} void unlock() {if (valid) LeaveCriticalSection(&cs);} -#if 0 bool trylock() {return valid ? (TryEnterCriticalSection(&cs) ? true : false) : false; } -#endif }; class CcAutoLock { @@ -50,4 +48,13 @@ public: ~CcAutoLock() { m_lock.unlock(); } }; +class CcAutoTryLock { + CcOsLock& m_lock; + bool m_locked; +public: + CcAutoTryLock(CcOsLock& lock):m_lock(lock) { m_locked = m_lock.trylock(); } + ~CcAutoTryLock() { if (m_locked) m_lock.unlock(); m_locked = false; } + bool IsLocked() const { return m_locked; } +}; + #endif /* __AUTOLOCK_HXX */ diff --git a/src/ccapi/common/win/win-utils.h b/src/ccapi/common/win/win-utils.h index 6469a61..41cab24 100644 --- a/src/ccapi/common/win/win-utils.h +++ b/src/ccapi/common/win/win-utils.h @@ -42,7 +42,8 @@ static enum ccapiMsgType { CCMSG_REQUEST_REPLY, CCMSG_DISCONNECT, CCMSG_LISTEN, - CCMSG_PING + CCMSG_PING, + CCMSG_QUIT }; char* clientEndpoint(const char* UUID); diff --git a/src/ccapi/lib/ccapi_context.c b/src/ccapi/lib/ccapi_context.c index a16ce0e..cf677fc 100644 --- a/src/ccapi/lib/ccapi_context.c +++ b/src/ccapi/lib/ccapi_context.c @@ -79,12 +79,12 @@ static cc_int32 cci_context_sync (cci_context_t in_context, #pragma mark - #endif -MAKE_INIT_FUNCTION(cci_thread_init); -MAKE_FINI_FUNCTION(cci_thread_fini); +MAKE_INIT_FUNCTION(cci_process_init); +MAKE_FINI_FUNCTION(cci_process_fini); /* ------------------------------------------------------------------------ */ -static int cci_thread_init (void) +static int cci_process_init (void) { cc_int32 err = ccNoError; @@ -93,7 +93,7 @@ static int cci_thread_init (void) } if (!err) { - err = cci_ipc_thread_init (); + err = cci_ipc_process_init (); } if (!err) { @@ -105,9 +105,9 @@ static int cci_thread_init (void) /* ------------------------------------------------------------------------ */ -static void cci_thread_fini (void) +static void cci_process_fini (void) { - if (!INITIALIZER_RAN (cci_thread_init) || PROGRAM_EXITING ()) { + if (!INITIALIZER_RAN (cci_process_init) || PROGRAM_EXITING ()) { return; } @@ -134,7 +134,7 @@ cc_int32 cc_initialize (cc_context_t *out_context, if (!out_context) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = CALL_INIT_FUNCTION (cci_thread_init); + err = CALL_INIT_FUNCTION (cci_process_init); } if (!err) { diff --git a/src/ccapi/lib/ccapi_ipc.c b/src/ccapi/lib/ccapi_ipc.c index 66830de..2c1fcba 100644 --- a/src/ccapi/lib/ccapi_ipc.c +++ b/src/ccapi/lib/ccapi_ipc.c @@ -28,6 +28,13 @@ /* ------------------------------------------------------------------------ */ +cc_int32 cci_ipc_process_init (void) +{ + return cci_os_ipc_process_init (); +} + +/* ------------------------------------------------------------------------ */ + cc_int32 cci_ipc_thread_init (void) { return cci_os_ipc_thread_init (); diff --git a/src/ccapi/lib/ccapi_ipc.h b/src/ccapi/lib/ccapi_ipc.h index a23791c..a23772b 100644 --- a/src/ccapi/lib/ccapi_ipc.h +++ b/src/ccapi/lib/ccapi_ipc.h @@ -28,6 +28,8 @@ #include "cci_common.h" +cc_int32 cci_ipc_process_init (void); + cc_int32 cci_ipc_thread_init (void); cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name, diff --git a/src/ccapi/lib/ccapi_os_ipc.h b/src/ccapi/lib/ccapi_os_ipc.h index e27ae63..fe7c87a 100644 --- a/src/ccapi/lib/ccapi_os_ipc.h +++ b/src/ccapi/lib/ccapi_os_ipc.h @@ -28,6 +28,8 @@ #include "cci_common.h" +cc_int32 cci_os_ipc_process_init (void); + cc_int32 cci_os_ipc_thread_init (void); cc_int32 cci_os_ipc (cc_int32 in_launch_server, diff --git a/src/ccapi/lib/win/OldCC/client.cxx b/src/ccapi/lib/win/OldCC/client.cxx index ed87123..4b2d718 100644 --- a/src/ccapi/lib/win/OldCC/client.cxx +++ b/src/ccapi/lib/win/OldCC/client.cxx @@ -195,12 +195,13 @@ DWORD find_server(Init::InitInfo& info, LPSTR endpoint) { psa, // SA FALSE, CREATE_NEW_PROCESS_GROUP | - CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS | - // CREATE_NO_WINDOW | - // DETACHED_PROCESS | /* KPK TODO: was set - restore */ - 0 - , +#ifdef CCAPI_LAUNCH_SERVER_WITH_CONSOLE + CREATE_NEW_CONSOLE | +#else + DETACHED_PROCESS | +#endif + 0, NULL, // environment szDir, // current dir &si, @@ -238,9 +239,39 @@ DWORD find_server(Init::InitInfo& info, LPSTR endpoint) { static DWORD +make_random_challenge(DWORD *challenge_out) { + HCRYPTPROV provider; + DWORD status = 0; + *challenge_out = 0; + if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + status = GetLastError(); + cci_check_error(status); + return status; + } + if (!CryptGenRandom(provider, sizeof(*challenge_out), + (BYTE *)challenge_out)) { + status = GetLastError(); + cci_check_error(status); + return status; + } + if (!CryptReleaseContext(provider, 0)) { + /* + * Note: even though CryptReleaseContext() failed, we don't really + * care since a) we've already successfully obtained our challenge + * anyway and b) at least one of the potential errors, "ERROR_BUSY" + * does not really seem to be an error at all. So GetLastError() is + * logged for informational purposes only and should not be returned. + */ + cci_check_error(GetLastError()); + } + return status; +} + +static +DWORD authenticate_server(Init::InitInfo& info) { - DWORD challenge = 17; // XXX - maybe use random number - DWORD desired_response= challenge + 1; + DWORD challenge, desired_response; HANDLE hMap = 0; LPSTR mem_name = 0; PDWORD pvalue = 0; @@ -254,6 +285,12 @@ authenticate_server(Init::InitInfo& info) { cci_check_error(status); if (!status) { + status = make_random_challenge(&challenge); + desired_response = challenge + 1; + cci_check_error(status); + } + + if (!status) { if (isNT()) { sa.nLength = sizeof(sa); status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor); @@ -358,10 +395,11 @@ Client::Connect(char* ep OPTIONAL) { } DWORD Client::Initialize(char* ep OPTIONAL) { - CcAutoLock AL(Client::sLock); + CcAutoTryLock AL(Client::sLock); + if (!AL.IsLocked() || s_init) + return 0; SecureClient s; ccs_request_IfHandle = NULL; - if (s_init) return 0; DWORD status = Client::Connect(ep); if (!status) s_init = true; return status; diff --git a/src/ccapi/lib/win/ccapi_os_ipc.cxx b/src/ccapi/lib/win/ccapi_os_ipc.cxx index 7359eb0..8cc9d03 100644 --- a/src/ccapi/lib/win/ccapi_os_ipc.cxx +++ b/src/ccapi/lib/win/ccapi_os_ipc.cxx @@ -64,7 +64,7 @@ SECURITY_ATTRIBUTES sa = { 0 }; */ cc_int32 ccapi_connect(const struct tspdata* tsp); -static DWORD handle_exception(DWORD code); +static DWORD handle_exception(DWORD code, struct tspdata* ptspdata); extern "C" { cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, @@ -75,12 +75,46 @@ cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, /* ------------------------------------------------------------------------ */ +extern "C" cc_int32 cci_os_ipc_process_init (void) { + RPC_STATUS status; + + opts.cMinCalls = 1; + opts.cMaxCalls = 20; + if (!isNT()) { + status = RpcServerRegisterIf(ccs_reply_ServerIfHandle, // interface + NULL, // MgrTypeUuid + NULL); // MgrEpv; null means use default + } + else { + status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle, // interface + NULL, // MgrTypeUuid + NULL, // MgrEpv; 0 means default + RPC_IF_ALLOW_SECURE_ONLY, + opts.cMaxCalls, + NULL); // No security callback. + } + cci_check_error(status); + + if (!status) { + status = RpcServerRegisterAuthInfo(0, // server principal + RPC_C_AUTHN_WINNT, + 0, + 0 ); + cci_check_error(status); + } + + return status; // ugh. needs translation +} + +/* ------------------------------------------------------------------------ */ + extern "C" cc_int32 cci_os_ipc_thread_init (void) { cc_int32 err = ccNoError; struct tspdata* ptspdata; - HANDLE replyEvent; + HANDLE replyEvent = NULL; UUID __RPC_FAR uuid; - unsigned char __RPC_FAR* uuidString = NULL; + RPC_CSTR __RPC_FAR uuidString = NULL; + char* endpoint = NULL; if (!GetTspData(GetTlsIndex(), &ptspdata)) return ccErrNoMem; @@ -91,10 +125,18 @@ extern "C" cc_int32 cci_os_ipc_thread_init (void) { err = cci_check_error(UuidCreate(&uuid)); // Get a UUID if (err == RPC_S_OK) { // Convert to string err = UuidToString(&uuid, &uuidString); + cci_check_error(err); } if (!err) { // Save in thread local storage tspdata_setUUID(ptspdata, uuidString); + endpoint = clientEndpoint((const char *)uuidString); + err = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc", + opts.cMaxCalls, + (RPC_CSTR)endpoint, + sa.lpSecurityDescriptor); // SD + cci_check_error(err); } + #if 0 cci_debug_printf("%s UUID:<%s>", __FUNCTION__, tspdata_getUUID(ptspdata)); #endif @@ -109,6 +151,17 @@ extern "C" cc_int32 cci_os_ipc_thread_init (void) { replyEvent = createThreadEvent((char*)uuidString, REPLY_SUFFIX); } + if (!err) { + static bool bListening = false; + if (!bListening) { + err = RpcServerListen(opts.cMinCalls, + opts.cMaxCalls, + TRUE); + cci_check_error(err); + } + bListening = err == 0; + } + if (replyEvent) tspdata_setReplyEvent(ptspdata, replyEvent); else err = cci_check_error(GetLastError()); @@ -159,6 +212,10 @@ extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, sst = tspdata_getSST (ptspdata); uuid = tspdata_getUUID(ptspdata); + // Initialize old CCAPI if necessary: + if (!err) if (!Init:: Initialized()) err = cci_check_error(Init:: Initialize( )); + if (!err) if (!Client::Initialized()) err = cci_check_error(Client::Initialize(0)); + // The lazy connection to the server has been put off as long as possible! // ccapi_connect starts listening for replies as an RPC server and then // calls ccs_rpc_connect. @@ -183,10 +240,6 @@ extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, CcAutoLock* a = 0; CcAutoLock::Start(a, Client::sLock); - // Initialize old CCAPI if necessary: - if (!err) if (!Init:: Initialized()) err = cci_check_error(Init:: Initialize( )); - if (!err) if (!Client::Initialized()) err = cci_check_error(Client::Initialize(0)); - // New code using new RPC procedures for sending the data and receiving a reply: if (!err) { RpcTryExcept { @@ -209,7 +262,7 @@ extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, (long*)(&err) ); /* Return code */ } RpcExcept(1) { - handle_exception(RpcExceptionCode()); + err = handle_exception(RpcExceptionCode(), ptspdata); } RpcEndExcept; } @@ -247,12 +300,13 @@ extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, -static DWORD handle_exception(DWORD code) { +static DWORD handle_exception(DWORD code, struct tspdata* ptspdata) { cci_debug_printf("%s code %u; ccs_request_IfHandle:0x%X", __FUNCTION__, code, ccs_request_IfHandle); if ( (code == RPC_S_SERVER_UNAVAILABLE) || (code == RPC_S_INVALID_BINDING) ) { - Client::Reconnect(0); + Client::Cleanup(); + tspdata_setConnected(ptspdata, FALSE); } - return 4; + return code; } @@ -262,7 +316,6 @@ static DWORD handle_exception(DWORD code) { */ cc_int32 ccapi_connect(const struct tspdata* tsp) { BOOL bListen = TRUE; - char* endpoint = NULL; HANDLE replyEvent = 0; RPC_STATUS status = FALSE; char* uuid = NULL; @@ -275,56 +328,13 @@ cc_int32 ccapi_connect(const struct tspdata* tsp) { /* Build complete RPC uuid using previous CCAPI implementation: */ replyEvent = tspdata_getReplyEvent(tsp); uuid = tspdata_getUUID(tsp); - endpoint = clientEndpoint(uuid); - cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint); opts.cMinCalls = 1; opts.cMaxCalls = 20; opts.fDontWait = TRUE; - if (!status) { - status = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc", - opts.cMaxCalls, - (RPC_CSTR)endpoint, - sa.lpSecurityDescriptor); // SD - cci_check_error(status); - } - - if (!status) { - status = RpcServerRegisterAuthInfo(0, // server principal - RPC_C_AUTHN_WINNT, - 0, - 0 ); - cci_check_error(status); - } - cci_debug_printf("%s is listening ...", __FUNCTION__); - if (!status) { - if (!isNT()) { - status = RpcServerRegisterIf(ccs_reply_ServerIfHandle, // interface - NULL, // MgrTypeUuid - NULL); // MgrEpv; null means use default - } - else { - status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle,// interface - NULL, // MgrTypeUuid - NULL, // MgrEpv; 0 means default - RPC_IF_ALLOW_SECURE_ONLY, - opts.cMaxCalls, - NULL); // No security callback. - } - - cci_check_error(status); - - if (!status) { - status = RpcServerListen(opts.cMinCalls, - opts.cMaxCalls, - TRUE); - cci_check_error(status); - } - } - // Clear replyEvent so we can detect when a reply to our connect request has been received: ResetEvent(replyEvent); diff --git a/src/ccapi/lib/win/debug.exports b/src/ccapi/lib/win/debug.exports index 583e9ca..6dc1fc0 100644 --- a/src/ccapi/lib/win/debug.exports +++ b/src/ccapi/lib/win/debug.exports @@ -8,3 +8,4 @@ krb5int_ipc_stream_new ccs_authenticate + cci_os_ipc_process_init diff --git a/src/ccapi/lib/win/dllmain.cxx b/src/ccapi/lib/win/dllmain.cxx index e37a9ad..3141e19 100644 --- a/src/ccapi/lib/win/dllmain.cxx +++ b/src/ccapi/lib/win/dllmain.cxx @@ -32,9 +32,10 @@ extern "C" { #include "tls.h" #include "cci_debugging.h" #include "ccapi_context.h" +#include "ccapi_ipc.h" #include "client.h" -void cci_thread_init__auxinit(); +void cci_process_init__auxinit(); } @@ -91,10 +92,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle // Allocate a TLS index: if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; - - // Initialize CCAPI once per DLL load: - firstThreadID = GetCurrentThreadId(); + cci_process_init__auxinit(); // Don't break; fallthrough: Initialize the TLS index for first thread. // The attached process creates a new thread: @@ -107,8 +106,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle memset(ptspdata, 0, sizeof(struct tspdata)); - // Initialize CCAPI once per DLL load: - if (GetCurrentThreadId() == firstThreadID) cci_thread_init__auxinit(); + // Initialize CCAPI thread data: + cci_ipc_thread_init(); break; diff --git a/src/ccapi/server/ccs_server.c b/src/ccapi/server/ccs_server.c index aeff723..1fc8d2c 100644 --- a/src/ccapi/server/ccs_server.c +++ b/src/ccapi/server/ccs_server.c @@ -399,3 +399,10 @@ cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, return cci_check_error (err); } + +/* ------------------------------------------------------------------------ */ + +cc_uint64 ccs_server_client_count () +{ + return ccs_client_array_count (g_client_array); +} diff --git a/src/ccapi/server/ccs_server.h b/src/ccapi/server/ccs_server.h index 4d17099..e920ad9 100644 --- a/src/ccapi/server/ccs_server.h +++ b/src/ccapi/server/ccs_server.h @@ -48,4 +48,6 @@ cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, cc_int32 in_reply_err, k5_ipc_stream in_reply_data); +cc_uint64 ccs_server_client_count (); + #endif /* CCS_SERVER_H */ diff --git a/src/ccapi/server/win/WorkItem.cpp b/src/ccapi/server/win/WorkItem.cpp index 22e209d..79a3487 100644 --- a/src/ccapi/server/win/WorkItem.cpp +++ b/src/ccapi/server/win/WorkItem.cpp @@ -103,10 +103,26 @@ char* WorkItem::print(char* buf) { return buf; } +int WorkList::initialize() { + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + return 0; + } + +int WorkList::cleanup() { + CloseHandle(hEvent); + hEvent = INVALID_HANDLE_VALUE; + return 0; + } + +void WorkList::wait() { + WaitForSingleObject(hEvent, INFINITE); + } + int WorkList::add(WorkItem* item) { EnterCriticalSection(&cs); wl.push_front(item); LeaveCriticalSection(&cs); + SetEvent(hEvent); return 1; } diff --git a/src/ccapi/server/win/WorkQueue.cpp b/src/ccapi/server/win/WorkQueue.cpp index cc12054..fc5fa7e 100644 --- a/src/ccapi/server/win/WorkQueue.cpp +++ b/src/ccapi/server/win/WorkQueue.cpp @@ -24,6 +24,7 @@ * or implied warranty. */ +#include "WorkQueue.h" extern "C" { #include "cci_debugging.h" } @@ -32,9 +33,21 @@ extern "C" { WorkList worklist; +EXTERN_C int worklist_initialize() { + return worklist.initialize(); + } + +EXTERN_C int worklist_cleanup() { + return worklist.cleanup(); + } + +EXTERN_C void worklist_wait() { + worklist.wait(); + } + /* C interfaces: */ -EXTERN_C bool worklist_isEmpty() { - return worklist.isEmpty(); +EXTERN_C BOOL worklist_isEmpty() { + return worklist.isEmpty() ? TRUE : FALSE; } EXTERN_C int worklist_add( const long rpcmsg, diff --git a/src/ccapi/server/win/WorkQueue.h b/src/ccapi/server/win/WorkQueue.h index 6b22651..68aa8b1 100644 --- a/src/ccapi/server/win/WorkQueue.h +++ b/src/ccapi/server/win/WorkQueue.h @@ -29,9 +29,16 @@ #include "windows.h" #include "ccs_pipe.h" +EXTERN_C int worklist_initialize(); + +EXTERN_C int worklist_cleanup(); + +/* Wait for work to be added to the list (via worklist_add) from another thread */ +EXTERN_C void worklist_wait(); + EXTERN_C BOOL worklist_isEmpty(); -EXTERN_C void worklist_add( const long rpcmsg, +EXTERN_C int worklist_add( const long rpcmsg, const ccs_pipe_t pipe, const k5_ipc_stream stream, const time_t serverStartTime); diff --git a/src/ccapi/server/win/ccs_os_server.cpp b/src/ccapi/server/win/ccs_os_server.cpp index b9c70a9..f842394 100644 --- a/src/ccapi/server/win/ccs_os_server.cpp +++ b/src/ccapi/server/win/ccs_os_server.cpp @@ -156,6 +156,10 @@ cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) { // status = startup_server(opts); // } + if (!err) { + err = worklist_initialize(); + } + if (err) { Init::Cleanup(); fprintf( stderr, "An error occured while %s the server (%u)\n", @@ -174,6 +178,8 @@ cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) { cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]); + worklist_cleanup(); + return cci_check_error (err); } @@ -190,10 +196,10 @@ cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) { cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) { cc_int32 err = 0; uintptr_t threadStatus; - unsigned int loopCounter = 0; ParseOpts::Opts opts = { 0 }; ParseOpts PO; + BOOL bQuitIfNoClients = FALSE; opts.cMinCalls = 1; opts.cMaxCalls = 20; @@ -221,15 +227,13 @@ cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) { queue. */ rpcargs.sessID = (unsigned char*)sessID; rpcargs.opts = &opts; + /// TODO: check for NULL handle, error, etc. probably move to initialize func... threadStatus = _beginthread(receiveLoop, 0, (void*)&rpcargs); /* We handle the queue entries here. Work loop: */ - while (TRUE) { - loopCounter++; - if (worklist_isEmpty() & 1) { - SleepEx(1000, TRUE); - } - else if (TRUE) { // Take next WorkItem from the queue: + while (ccs_server_client_count() > 0 || !bQuitIfNoClients) { + worklist_wait(); + while (!worklist_isEmpty()) { k5_ipc_stream buf = NULL; long rpcmsg = CCMSG_INVALID; time_t serverStartTime = 0xDEADDEAD; @@ -282,6 +286,9 @@ cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) { err = krb5int_ipc_stream_write(stream, "This is a test of the emergency broadcasting system", 52); err = ccs_os_server_send_reply(pipe, stream); break; + case CCMSG_QUIT: + bQuitIfNoClients = TRUE; + break; default: cci_debug_printf("Huh? Received invalid message type %ld from UUID:<%s>", rpcmsg, uuid); @@ -303,7 +310,6 @@ cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) { else {cci_debug_printf("Huh? Queue not empty but no item to remove.");} } } - return cci_check_error (err); } @@ -460,6 +466,8 @@ void receiveLoop(void* rpcargs) { free_alloc_p(&endpoint); } + // tell main thread to shutdown since it won't receive any more messages + worklist_add(CCMSG_QUIT, NULL, NULL, 0); _endthread(); } // End receiveLoop diff --git a/src/ccapi/server/win/workitem.h b/src/ccapi/server/win/workitem.h index 1d3df15..fff56f3 100644 --- a/src/ccapi/server/win/workitem.h +++ b/src/ccapi/server/win/workitem.h @@ -36,9 +36,13 @@ class WorkList { private: std::list <WorkItem*> wl; CRITICAL_SECTION cs; + HANDLE hEvent; public: WorkList(); ~WorkList(); + int initialize(); + int cleanup(); + void wait(); int add(WorkItem*); int remove(WorkItem**); bool isEmpty() {return wl.empty();} diff --git a/src/ccapi/test/test_cc_credentials_iterator_next.c b/src/ccapi/test/test_cc_credentials_iterator_next.c index beed791..ff5f467 100644 --- a/src/ccapi/test/test_cc_credentials_iterator_next.c +++ b/src/ccapi/test/test_cc_credentials_iterator_next.c @@ -5,6 +5,7 @@ #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" +#include "test_ccapi_iterators.h" int main (int argc, const char * argv[]) { |