/**
 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);
    }
    
}
Example #2
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;
}