/** Handles each clients request whether it is a server request or a client request **/ void request_handler(int clientSock) { char buf[1024]; char command[50] = ""; char *request = command; while( (recv(clientSock, request, 1, 0) != 0) && (*request != '\n')) { request++; } *request = '\0'; //check if it is SERVER/HELLO command if(strcmp(command, "SERVER/HELLO") == 0) { processServerHello(clientSock, 1); } //check if it is a client request command else if(strcmp(command, "CLIENT/REQUEST") == 0) { processClientRequest(clientSock); } else { strcpy(buf, "SERVER/ERROR\n"); send(clientSock, buf, strlen(buf), 0); } }
int_t main(void) { error_t error; int_t ret; int_t clientAddrLen; SOCKADDR_IN serverAddr; SOCKADDR_IN clientAddr; WSADATA wsaData; HCRYPTPROV hProvider; uint8_t seed[32]; //Server socket descriptor SOCKET serverSocket = SOCKET_ERROR; //Client socket descriptor SOCKET clientSocket = SOCKET_ERROR; //Start-up message TRACE_INFO("******************************\r\n"); TRACE_INFO("*** CycloneSSL Server Demo ***\r\n"); TRACE_INFO("******************************\r\n"); TRACE_INFO("\r\n"); //Acquire cryptographic context ret = CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); //Any error to report? if(!ret) { //Debug message TRACE_ERROR("Error: Cannot acquire cryptographic context (%d)\r\n", GetLastError()); //Exit immediately return ERROR_FAILURE; } //Generate a random seed ret = CryptGenRandom(hProvider, sizeof(seed), seed); //Any error to report? if(!ret) { //Debug message TRACE_ERROR("Error: Failed to generate random data (%d)\r\n", GetLastError()); //Exit immediately return ERROR_FAILURE; } //Release cryptographic context CryptReleaseContext(hProvider, 0); //PRNG initialization error = yarrowInit(&yarrowContext); //Any error to report? if(error) { //Debug message TRACE_ERROR("Error: PRNG initialization failed (%d)\r\n", error); //Exit immediately return ERROR_FAILURE; } //Properly seed the PRNG error = yarrowSeed(&yarrowContext, seed, sizeof(seed)); //Any error to report? if(error) { //Debug message TRACE_ERROR("Error: Failed to seed PRNG (%d)\r\n", error); //Exit immediately return error; } //Winsock initialization ret = WSAStartup(MAKEWORD(2, 2), &wsaData); //Any error to report? if(ret) { //Debug message TRACE_ERROR("Error: Winsock initialization failed (%d)\r\n", ret); //Exit immediately return ERROR_FAILURE; } //Start of exception handling block do { //Debug message TRACE_INFO("Loading credentials...\r\n"); //Load Diffie-Hellman parameters error = readPemFile(APP_SERVER_DH_PARAMS, &dhParams, &dhParamsLength); //Any error to report? if(error) break; //Load server's RSA certificate error = readPemFile(APP_SERVER_RSA_CERT, &serverRsaCert, &serverRsaCertLength); //Any error to report? if(error) break; //Load server's RSA private key error = readPemFile(APP_SERVER_RSA_PRIVATE_KEY, &serverRsaPrivateKey, &serverRsaPrivateKeyLength); //Any error to report? if(error) break; //Load server's DSA certificate error = readPemFile(APP_SERVER_DSA_CERT, &serverDsaCert, &serverDsaCertLength); //Any error to report? if(error) break; //Load server's DSA private key error = readPemFile(APP_SERVER_DSA_PRIVATE_KEY, &serverDsaPrivateKey, &serverDsaPrivateKeyLength); //Any error to report? if(error) break; //Load server's ECDSA certificate error = readPemFile(APP_SERVER_ECDSA_CERT, &serverEcdsaCert, &serverEcdsaCertLength); //Any error to report? if(error) break; //Load server's ECDSA private key error = readPemFile(APP_SERVER_ECDSA_PRIVATE_KEY, &serverEcdsaPrivateKey, &serverEcdsaPrivateKeyLength); //Any error to report? if(error) break; //Load trusted CA certificates error = readPemFile(APP_CA_CERT_BUNDLE, &trustedCaList, &trustedCaListLength); //Any error to report? if(error) break; //TLS session cache initialization tlsCache = tlsInitCache(16); //Any error to report? if(!tlsCache) { //Debug message TRACE_ERROR("Error: TLS cache initialization failed\r\n"); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Open a socket serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Failed to open socket? if(serverSocket < 0) { //Debug message TRACE_ERROR("Error: Cannot open socket (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Server port serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = INADDR_ANY; serverAddr.sin_port = htons(APP_SERVER_PORT); //Bind the socket to the relevant port number ret = bind(serverSocket, (PSOCKADDR) &serverAddr, sizeof(serverAddr)); //Any error to report? if(ret < 0) { //Debug message TRACE_ERROR("Error: Failed to bind socket (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Place the socket in the listening state ret = listen(serverSocket, 10); //Any error to report? if(ret < 0) { //Debug message TRACE_ERROR("Error: Failed to enter listening state (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Main loop while(1) { //Debug message TRACE_INFO("\r\n\r\n"); TRACE_INFO("Waiting for an incoming connection...\r\n\r\n"); //Initialize address length clientAddrLen = sizeof(clientAddr); //Accept a new connection request clientSocket = accept(serverSocket, (PSOCKADDR) &clientAddr, &clientAddrLen); //Any error to report? if(clientSocket < 0) { //Debug message TRACE_ERROR("Error: Cannot accept new connection request (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Increment hit counter hitCounter++; //Debug message TRACE_INFO("Connection #%u established with client %s port %u...\r\n", hitCounter, inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port)); //Process incoming request error = processClientRequest(clientSocket); //Failed to service client request? if(error) { //Debug message TRACE_ERROR("Error: Failed to process client request (%d)\r\n", error); } //Debug message TRACE_INFO("Closing connection...\r\n"); //Close socket closesocket(clientSocket); } //End of exception handling block } while(0); //Close server socket if necessary if(serverSocket >= 0) closesocket(serverSocket); //Release session cache tlsFreeCache(tlsCache); //Free previously allocated resources free(dhParams); free(serverRsaCert); free(serverRsaPrivateKey); free(serverDsaCert); free(serverDsaPrivateKey); free(trustedCaList); //Release PRNG context yarrowRelease(&yarrowContext); //Winsock related cleanup WSACleanup(); //Dumps all the memory blocks in the heap when a memory leak has occurred _CrtDumpMemoryLeaks(); //Wait for the user to press a key system("pause"); //Return status code return error; }