/* * Deallocates and cleans up the attributes of a socket context */ VOID free_socket_context(SocketContext *ctx) { dprintf( "[TCP] free_socket_context. ctx=0x%08X", ctx ); // Close the socket and notification handle if (ctx->fd){ closesocket(ctx->fd); ctx->fd = 0; } if (ctx->channel) { channel_close(ctx->channel, ctx->remote, NULL, 0, NULL); ctx->channel = NULL; } if (ctx->notify) { dprintf( "[TCP] free_socket_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->notify); // The scheduler calls CloseHandle on our WSACreateEvent() for us scheduler_remove_waitable(ctx->notify); ctx->notify = NULL; } // Free the context free(ctx); }
/* * Deallocate a client context */ VOID portfwd_destroy_client(PortForwardClientContext *pcctx) { // Remove the client from the list if (pcctx->prev) pcctx->prev->next = pcctx->next; else clients = pcctx->next; if (pcctx->next) pcctx->next->prev = pcctx->prev; // Close the socket/channel if (pcctx->clientFd) closesocket(pcctx->clientFd); if (pcctx->notify) { scheduler_remove_waitable(pcctx->notify); CloseHandle(pcctx->notify); } if (pcctx->channel) channel_close(pcctx->channel, pcctx->remote, NULL, 0, NULL); // Deallocate the context free(pcctx); }
/* * Destroy a local listener on a given local host and port */ DWORD portfwd_destroy_listener(LPCSTR lhost, USHORT lport) { PortForwardListenerContext *current; DWORD res = ERROR_SUCCESS; for (current = listeners; current; current = current->next) { if ((current->slhost) && (lhost) && (strcmp(current->slhost, lhost))) continue; if (current->lport != lport) continue; break; } // If an entry was found, remove it. if (current) { if (current->prev) current->prev->next = current->next; else listeners = current->next; if (current->next) current->next->prev = current->prev; if (current->slhost) free(current->slhost); if (current->rhost) free(current->rhost); if (current->listenFd) closesocket(current->listenFd); if (current->notify) { scheduler_remove_waitable(current->notify); CloseHandle(current->notify); } free(current); } else res = ERROR_NOT_FOUND; return res; }
/* * Enables or disables interactivity with the standard output handle on the channel */ DWORD process_channel_interact(Channel *channel, Packet *request, LPVOID context, BOOLEAN interact) { ProcessChannelContext *ctx = (ProcessChannelContext *)context; DWORD result = ERROR_SUCCESS; dprintf( "[PROCESS] process_channel_interact. channel=0x%08X, ctx=0x%08X, interact=%d", channel, ctx, interact ); // If the remote side wants to interact with us, schedule the stdout handle // as a waitable item if (interact) result = scheduler_insert_waitable(ctx->pStdout, channel, (WaitableNotifyRoutine)process_channel_interact_notify); else // Otherwise, remove it result = scheduler_remove_waitable(ctx->pStdout); return result; }
/* * Deallocates and cleans up the attributes of a socket context */ VOID free_socket_context(SocketContext *ctx) { // Close the socket and notification handle if (ctx->fd) closesocket(ctx->fd); if (ctx->notify) { scheduler_remove_waitable(ctx->notify); WSACloseEvent(ctx->notify); } if (ctx->channel) channel_close(ctx->channel, ctx->remote, NULL, 0, NULL); // Free the context free(ctx); }
/* * Closes the channels that were opened to the process. */ DWORD process_channel_close(Channel *channel, Packet *request, LPVOID context) { DWORD result = ERROR_SUCCESS; ProcessChannelContext *ctx = (ProcessChannelContext *)context; dprintf( "[PROCESS] process_channel_close. channel=0x%08X, ctx=0x%08X", channel, ctx ); if (channel_is_interactive(channel)) scheduler_remove_waitable(ctx->pStdout); #ifdef _WIN32 // Note: We dont close the handle ctx->pStdout as this will introduce a synchronization // problem with the channels interactive thread, specifically the call to WaitForMultipleObjects // will have undefined behaviour. The interactive thread will close the handle instead. CloseHandle(ctx->pStdin); #else close(ctx->pStdin); #endif free(ctx); return result; }