/* Thread launcher function responsible for registering * cleanup handlers and calling pthread_exit, if not done * in thread function. */ static void* thread_launcher(void* arg) { DWORD res = 1; void* rc = NULL; WINPR_THREAD* thread = (WINPR_THREAD*) arg; typedef void* (*fkt_t)(void*); fkt_t fkt; if (!thread) { WLog_ERR(TAG, "Called with invalid argument %p", arg); goto exit; } if (!(fkt = (fkt_t)thread->lpStartAddress)) { WLog_ERR(TAG, "Thread function argument is %p", fkt); goto exit; } if (pthread_mutex_lock(&thread->threadIsReadyMutex)) goto exit; if (!ListDictionary_Contains(thread_list, &thread->thread)) { if (pthread_cond_wait(&thread->threadIsReady, &thread->threadIsReadyMutex) != 0) { WLog_ERR(TAG, "The thread could not be made ready"); pthread_mutex_unlock(&thread->threadIsReadyMutex); goto exit; } } if (pthread_mutex_unlock(&thread->threadIsReadyMutex)) goto exit; assert(ListDictionary_Contains(thread_list, &thread->thread)); rc = fkt(thread->lpParameter); exit: if (thread) { if (!thread->exited) thread->dwExitCode = (DWORD)(size_t)rc; set_event(thread); res = thread->dwExitCode; if (thread->detached || !thread->started) cleanup_handle(thread); } return rc; }
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc) { char* token64; int ntlm_token_length = 0; BYTE* ntlm_token_data = NULL; HttpResponse* http_response; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; http_response = http_response_recv(rpc->TlsIn); if (!http_response) return -1; if (ListDictionary_Contains(http_response->Authenticates, "NTLM")) { token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM"); if (!token64) goto out; crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length); } out: ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; http_response_free(http_response); return 0; }
void remove_callback_by_name(const char *name, void *context) { if (!cb_dict) { DEBUG_WARN("trying to remove '%s', but function list does not exist.", name); return; } if (!ListDictionary_Contains(cb_dict, (void *)name)) { DEBUG_WARN("trying to remove '%s', which is not in function list.", name); return; } DEBUG_DVC("Removing '%s' from function list.", name); ListDictionary_Remove(cb_dict, (void *)name); if (ListDictionary_Count(cb_dict) < 1) { DEBUG_DVC("Function list is empty, freeing resources."); ListDictionary_Free(cb_dict); cb_dict = NULL; } dump_callbacks(); }
void *get_callback_by_name(const char *name, void **context) { struct cb_value *rc; if (!cb_dict) { DEBUG_WARN("'%s' not found, function list does not exist.", name); return NULL; } if (!ListDictionary_Contains(cb_dict, (void *)name)) { DEBUG_WARN("'%s' not found", name); return NULL; } rc = ListDictionary_GetItemValue(cb_dict, (void *)name); DEBUG_DVC("'%s'=%p found", name, rc); if (context) *context = rc->context; return rc->fkt; }
HANDLE _GetCurrentThread(VOID) { HANDLE hdl = NULL; pthread_t tid = pthread_self(); if (!thread_list) { WLog_ERR(TAG, "function called without existing thread list!"); #if defined(WITH_DEBUG_THREADS) DumpThreadHandles(); #endif } else if (!ListDictionary_Contains(thread_list, &tid)) { WLog_ERR(TAG, "function called, but no matching entry in thread list!"); #if defined(WITH_DEBUG_THREADS) DumpThreadHandles(); #endif } else { hdl = ListDictionary_GetItemValue(thread_list, &tid); } return hdl; }
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc, HttpResponse* response) { char* token64 = NULL; int ntlmTokenLength = 0; BYTE* ntlmTokenData = NULL; rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; if (ListDictionary_Contains(response->Authenticates, "NTLM")) { token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM"); if (!token64) return -1; crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); } if (ntlmTokenData && ntlmTokenLength) { ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; } return 1; }
void cleanup_handle(void *obj) { WINPR_THREAD* thread = (WINPR_THREAD*) obj; int rc = pthread_mutex_destroy(&thread->mutex); if (rc) WLog_ERR(TAG, "failed to destroy mutex [%d] %s (%d)", rc, strerror(errno), errno); if (thread->pipe_fd[0]) close(thread->pipe_fd[0]); if (thread->pipe_fd[1]) close(thread->pipe_fd[1]); if (thread_list && ListDictionary_Contains(thread_list, &thread->thread)) ListDictionary_Remove(thread_list, &thread->thread); #if defined(WITH_DEBUG_THREADS) if (thread->create_stack) winpr_backtrace_free(thread->create_stack); if (thread->exit_stack) winpr_backtrace_free(thread->exit_stack); #endif free(thread); }
BOOL rdg_process_out_channel_response(rdpRdg* rdg, HttpResponse* response) { int status; wStream* s; char* token64 = NULL; int ntlmTokenLength = 0; BYTE* ntlmTokenData = NULL; rdpNtlm* ntlm = rdg->ntlm; if (response->StatusCode != HTTP_STATUS_DENIED) { WLog_DBG(TAG, "RDG not supported"); rdg->state = RDG_CLIENT_STATE_NOT_FOUND; return FALSE; } WLog_DBG(TAG, "Out Channel authorization required"); if (ListDictionary_Contains(response->Authenticates, "NTLM")) { token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM"); if (!token64) { return FALSE; } crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); } if (ntlmTokenData && ntlmTokenLength) { ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; } ntlm_authenticate(ntlm); s = rdg_build_http_request(rdg, "RDG_OUT_DATA"); if (!s) return FALSE; status = tls_write_all(rdg->tlsOut, Stream_Buffer(s), Stream_Length(s)); Stream_Free(s, TRUE); ntlm_free(rdg->ntlm); rdg->ntlm = NULL; if (status < 0) { return FALSE; } rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE; return TRUE; }
const char* http_response_get_auth_token(HttpResponse* respone, const char* method) { if (!respone || !method) return NULL; if (!ListDictionary_Contains(respone->Authenticates, method)) return NULL; return ListDictionary_GetItemValue(respone->Authenticates, method); }
VOID ExitThread(DWORD dwExitCode) { DWORD rc; pthread_t tid = pthread_self(); if (!thread_list) { WLog_ERR(TAG, "function called without existing thread list!"); #if defined(WITH_DEBUG_THREADS) DumpThreadHandles(); #endif pthread_exit(0); } else if (!ListDictionary_Contains(thread_list, &tid)) { WLog_ERR(TAG, "function called, but no matching entry in thread list!"); #if defined(WITH_DEBUG_THREADS) DumpThreadHandles(); #endif pthread_exit(0); } else { WINPR_THREAD* thread; ListDictionary_Lock(thread_list); thread = ListDictionary_GetItemValue(thread_list, &tid); assert(thread); thread->exited = TRUE; thread->dwExitCode = dwExitCode; #if defined(WITH_DEBUG_THREADS) thread->exit_stack = winpr_backtrace(20); #endif ListDictionary_Unlock(thread_list); set_event(thread); rc = thread->dwExitCode; if (thread->detached || !thread->started) cleanup_handle(thread); pthread_exit((void*) (size_t) rc); } }
BOOL ThreadCloseHandle(HANDLE handle) { WINPR_THREAD* thread = (WINPR_THREAD*) handle; if (!thread_list) { WLog_ERR(TAG, "Thread list does not exist, check call!"); dump_thread(thread); } else if (!ListDictionary_Contains(thread_list, &thread->thread)) { WLog_ERR(TAG, "Thread list does not contain this thread! check call!"); dump_thread(thread); } else { ListDictionary_Lock(thread_list); dump_thread(thread); if ((thread->started) && (WaitForSingleObject(thread, 0) != WAIT_OBJECT_0)) { WLog_ERR(TAG, "Thread running, setting to detached state!"); thread->detached = TRUE; pthread_detach(thread->thread); } else { cleanup_handle(thread); } ListDictionary_Unlock(thread_list); if (ListDictionary_Count(thread_list) < 1) { ListDictionary_Free(thread_list); thread_list = NULL; } } return TRUE; }
int TestListDictionary(int argc, char* argv[]) { int count; char* value; wListDictionary* list; list = ListDictionary_New(FALSE); ListDictionary_Add(list, key1, val1); ListDictionary_Add(list, key2, val2); ListDictionary_Add(list, key3, val3); count = ListDictionary_Count(list); if (count != 3) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count); return -1; } ListDictionary_Remove(list, key2); count = ListDictionary_Count(list); if (count != 2) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 2, count); return -1; } ListDictionary_Remove(list, key3); count = ListDictionary_Count(list); if (count != 1) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 1, count); return -1; } ListDictionary_Remove(list, key1); count = ListDictionary_Count(list); if (count != 0) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count); return -1; } ListDictionary_Add(list, key1, val1); ListDictionary_Add(list, key2, val2); ListDictionary_Add(list, key3, val3); count = ListDictionary_Count(list); if (count != 3) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count); return -1; } value = (char*) ListDictionary_GetItemValue(list, key1); if (strcmp(value, val1) != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val1, value); return -1; } value = (char*) ListDictionary_GetItemValue(list, key2); if (strcmp(value, val2) != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val2, value); return -1; } value = (char*) ListDictionary_GetItemValue(list, key3); if (strcmp(value, val3) != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val3, value); return -1; } ListDictionary_SetItemValue(list, key2, "apple"); value = (char*) ListDictionary_GetItemValue(list, key2); if (strcmp(value, "apple") != 0) { printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", "apple", value); return -1; } if (!ListDictionary_Contains(list, key2)) { printf("ListDictionary_Contains: Expected : %d, Actual: %d\n", TRUE, FALSE); return -1; } ListDictionary_Clear(list); count = ListDictionary_Count(list); if (count != 0) { printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count); return -1; } ListDictionary_Free(list); return 0; }