#include "common.h" /* * Instantiate a remote context from a file descriptor */ Remote *remote_allocate(SOCKET fd) { Remote *remote = NULL; // Allocate the remote context if ((remote = (Remote *)malloc(sizeof(Remote)))) { memset(remote, 0, sizeof(Remote)); // Set the file descriptor remote->fd = fd; remote->lock = lock_create(); // If we failed to create the lock we must fail to create the remote // as we wont be able to synchronize communication correctly. if( remote->lock == NULL ) { remote_deallocate( remote ); return NULL; } } return remote; } /* * Deallocate a remote context */ VOID remote_deallocate( Remote * remote ) { if( remote->fd ) closesocket( remote->fd ); if( remote->lock ) lock_destroy( remote->lock ); if ( remote->uri ) free( remote->uri); // Wipe our structure from memory memset(remote, 0, sizeof(Remote)); free(remote); } /* * Override a previously set file descriptor */ VOID remote_set_fd(Remote *remote, SOCKET fd) { remote->fd = fd; } /* * Get the remote context's file descriptor */ SOCKET remote_get_fd(Remote *remote) { return remote->fd; } /* * Initializes a given cipher as instructed to by the remote endpoint */ DWORD remote_set_cipher(Remote *remote, LPCSTR cipher, Packet *initializer) { DWORD res = ERROR_SUCCESS; if (remote->crypto) free(remote->crypto); do { // Allocate storage for the crypto context if (!(remote->crypto = (CryptoContext *)malloc(sizeof(CryptoContext)))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } memset(remote->crypto, 0, sizeof(CryptoContext)); // Set the remote pointer on the crypto context remote->crypto->remote = remote; // Populate handlers according to what cipher was selected if (!strcmp(cipher, "xor")) res = xor_populate_handlers(remote->crypto); else res = ERROR_NOT_FOUND; // If we got a context and it wants to process the request, do it. if ((res == ERROR_SUCCESS) && (remote->crypto->handlers.process_negotiate_request)) res = remote->crypto->handlers.process_negotiate_request( remote->crypto, initializer); } while (0); // If we fail, destroy the crypto context should it have been allocated. if (res != ERROR_SUCCESS) { if (remote->crypto) free(remote->crypto); remote->crypto = NULL; } return res; } /* * Returns a pointer to the remote endpoint's crypto context */ CryptoContext *remote_get_cipher(Remote *remote) { return remote->crypto; }