⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w3mfc.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    //Pick the SSL protocol to use
    SSL_METHOD* pSSLMethod = NULL;
    switch (m_pSettings->m_SSLProtocol)
    {
      case CHttpServerSettings::SSL_V2:
      {
        pSSLMethod = SSLv23_server_method();
        break;
      }
      case CHttpServerSettings::SSL_V3:
      {
        pSSLMethod = SSLv3_server_method();
        break;
      }
      case CHttpServerSettings::SSL_V2_OR_V3:
      {
        pSSLMethod = SSLv23_server_method();
        break;
      }
      case CHttpServerSettings::TLS_V1:
      {
        pSSLMethod = TLSv1_server_method();
        break;
      }
      default:
      {
        ASSERT(FALSE);
        break;
      }
    }

    //Create the SSL context object
    ASSERT(pSSLMethod != NULL);
    SSL_CTX* pSSLContext = SSL_CTX_new(pSSLMethod);
    if (pSSLContext == NULL) 
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to create SSL context object"));
      OnError(sError);

      LogSSLErrors();

      m_ListenStartEvent.SetEvent();
      return;
    }
    else
      sslContext.Attach(pSSLContext);

    //Set the certificate to use
    if (SSL_CTX_use_certificate_file(sslContext, T2A((LPTSTR) (LPCTSTR) m_pSettings->m_sServerCertificateFile), SSL_FILETYPE_PEM) != 1) 
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to load up server certificate"));
      OnError(sError);

      LogSSLErrors();

      m_ListenStartEvent.SetEvent();
      return;
    }

    //Set the private key to use
    if (SSL_CTX_use_PrivateKey_file(sslContext, m_pSettings->m_sPrivateKeyFile.GetLength() ? 
                                    T2A((LPTSTR) (LPCTSTR) m_pSettings->m_sPrivateKeyFile) : 
                                    T2A((LPTSTR) (LPCTSTR) m_pSettings->m_sServerCertificateFile), SSL_FILETYPE_PEM) != 1) 
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to load up private key"));
      OnError(sError);

      LogSSLErrors();

      m_ListenStartEvent.SetEvent();
      return;
    }

    //Check that we the private key is ok
    if (SSL_CTX_check_private_key(sslContext) != 1) 
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpServer::ListenSocketFunction, Private key does not match the certificate public key"));
      OnError(sError);

      LogSSLErrors();  

      m_ListenStartEvent.SetEvent();
      return;
    }

    //Set the SSL session settings
    if (m_pSettings->m_bReuseSessions)
    {
      int nOldTimeout;
      nOldTimeout = SSL_CTX_set_timeout(sslContext, m_pSettings->m_dwSSLSessionTimeout);
    }
    else
      SSL_CTX_set_timeout(sslContext, 0);
  }
#endif

  //Use a Win32 event notification on the server socket
  int nError = WSAEventSelect(serverSocket, m_SocketEvent, FD_ACCEPT);
  if (nError == SOCKET_ERROR)
  {
    DWORD dwError = ::GetLastError();

    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::ListenSocketFunction, Failed in call to WSAEventSelect, GetLastError:%d"), dwError);
    OnError(sError);

    m_ListenStartEvent.SetEvent();
    return;
  }

  //We're now ready for accepting client connections, inform
  //the main thread that everthing is ok
  m_bListenerRunningOK = TRUE;
  m_ListenStartEvent.SetEvent();

  //Create the wait handles array (used for waiting for an event)
  HANDLE Handles[2];
  Handles[0] = m_StopEvent;
  Handles[1] = m_SocketEvent;

  //Wait for any incoming connections and the signal to exit the thread m_ListenStopEvent
  BOOL bWantStop = FALSE;
  CThreadPoolQueue* pQueue = m_ThreadPool.GetQueue();
  ASSERT(pQueue);
  while (!bWantStop)
  {
    DWORD dwWait = WaitForMultipleObjects(2, (CONST HANDLE*) &Handles, FALSE, INFINITE);
    int nSignaledHandle = dwWait - WAIT_OBJECT_0;
    if (nSignaledHandle == 0) //It was the stop request
      bWantStop = TRUE;
    else if (nSignaledHandle == 1) //It was a socket event
    {
      CHttpThreadPoolRequest* pRequest = new CHttpThreadPoolRequest;  
      try
      {
#ifdef W3MFC_SSL_SUPPORT
        pRequest->m_pSSLContext = &sslContext;
#endif

        //Accept the client connection  
        serverSocket.Accept(pRequest->m_ClientSocket, pRequest->m_ClientAddress);

        //Let a thread pool client class instance handle the work
        CThreadPoolRequest poolRequest;
        poolRequest.m_dwID = 1;
        poolRequest.m_pData = pRequest;  
        pQueue->PostRequest(poolRequest);
      }
      catch(CWSocketException* pEx)
      {
        //Report the error
        CString sError;
        sError.Format(_T("CHttpServer::ListenSocketFunction, An error occurred accepting a client connection, GetLastError:%d"), pEx->m_nError);
        OnError(sError);

        pEx->Delete();
      }
    }
  }

  //Revert back to normal security settings
  if (bUseAccount)
  {
    //Revert to the usual security settings
    if (bImpersonated)
      RevertToSelf();
  }

  //Bring down the thread pool
  m_ThreadPool.Stop();
}

UINT CHttpServer::ListenSocketFunction(LPVOID pParam)
{
  //Get back the "this" pointer from the pParam parameter
  CHttpServer* pServer = (CHttpServer*) pParam;
  ASSERT(pServer);
  ASSERT(pServer->IsKindOf(RUNTIME_CLASS(CHttpServer)));

  //Call the run method of the CHttpServer instance
  pServer->ListenSocketFunction();

#ifdef W3MFC_SSL_SUPPORT
  //cleanup SSL thread state
  ERR_remove_state(0);
#endif

  //Return the thread exit code
  return TRUE;
}

#ifdef _DEBUG
void CHttpServer::OnError(const CString& sError) //To avoid level 4 warning in release
#else
void CHttpServer::OnError(const CString& /*sError*/)
#endif
{
#ifdef _DEBUG
  //The default is to just TRACE the details
  TRACE(_T("%s\n"), sError);
#endif
}

BOOL CHttpServer::LoadHTMLResource(UINT nID, char*& pszHTML, DWORD& dwSize)
{
  BOOL bSuccess = FALSE;

  HMODULE hModule = AfxFindResourceHandle(MAKEINTRESOURCE(nID), RT_HTML);
  HRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(nID), RT_HTML);
  if (hRsrc)
  {
    //Load up the resource
    dwSize = ::SizeofResource(hModule, hRsrc); 
    HGLOBAL hGlobal = ::LoadResource(hModule, hRsrc);

    //Allocate a new char array and copy the HTML resource into it 
    if (hGlobal)
    {
      pszHTML = new char[dwSize + 1];
      char* pszResource = (char*) ::LockResource(hGlobal);
      if (pszResource)
      {
        strncpy(pszHTML, pszResource, dwSize);
        pszHTML[dwSize] = _T('\0');
        bSuccess = TRUE;
      }
      else
      {
        //Report the error
        TRACE(_T("CHttpServer::LoadHTMLResource, Failed to load HTML resource, GetLastError:%d\n"), GetLastError());
      }
    }
  }

  return bSuccess;
}

char* CHttpServer::LoadHTML(int nStatusCode, DWORD& dwSize)
{
  //What will be the return value
  char* pszHTML = NULL;

  dwSize = 0;

  switch(nStatusCode)
  {
    case 302:
    {
      pszHTML = m_psz302HTML;
      dwSize = m_dw302HTML;
      break;
    }
    case 400:
    {
      pszHTML = m_psz400HTML;
      dwSize = m_dw400HTML;
      break;
    }
    case 401:
    {
      pszHTML = m_psz401HTML;
      dwSize = m_dw401HTML;
      break;
    }
    case 404:
    {
      pszHTML = m_psz404HTML;
      dwSize = m_dw404HTML;
      break;
    }
    default:
    {
      pszHTML = m_psz500HTML;
      dwSize = m_dw500HTML;
      break;
    }
  }

  return pszHTML;
}

char* CHttpServer::GetFileDeletedHTML(DWORD& dwSize)
{
  dwSize = m_dwDeletedHTML;
  return m_pszDeletedHTML;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -