2016-12-28 99 views
0

我有一個適用於80和443端口的VC++ HttpPOST方法。 (在熱門網站如google.com)如何在WINAPI中忽略HttpPOST請求中的證書

當我連接到一個安全的主機(172.17.9.93),具有CGI腳本現在,現在,當我連接使用小提琴手我得到一個無效證書的警告和接受警告我能夠連接。 Certificate error

相同的行爲我必須這樣做,在C++中,其是使用以下標誌SECURITY_FLAG_IGNORE_UNKNOWN_CAINTERNET_FLAG_IGNORE_CERT_CN_INVALID忽略證書和在功能HttpOpenRequest中()某些組合,但它未能和下面輸出給出。

C++控制檯輸出

172.17.9.93 : 443 data base-bin/hello.cgi 

Error 12045 has occurred while HttpSendRequest 
INVALID CA request received (12045) 

源代碼VC++

#define _WIN32_WINNT 0x600 
#include <windows.h> 
#include <stdio.h> 
#include <string> 
#include <wininet.h> 
#pragma comment(lib,"Wininet.lib") 
using namespace std; 

int doPost(std::string send, std::string &receive, LPCTSTR host, int port, LPCTSTR url) 
{ 

    char szData[1024]; 
    int winret = 0; 
    TCHAR szAccept[] = L"*/*"; 
    LPWSTR AcceptTypes[2] = { 0 }; 
    AcceptTypes[0] = szAccept; 

    HINTERNET hInternet = ::InternetOpen(TEXT("mandar"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); 
    if (hInternet != NULL) 
    { 
     printf("\n %S : %d data %S \n", host, port, url); 

     // open HTTP session 
     HINTERNET hConnect; 
     if (port == 80) 
     { 
      hConnect = ::InternetConnect(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, 0); 
     } 
     else 
     { 
      hConnect = ::InternetConnect(hInternet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, 0); 
     } 
     if (hConnect != NULL) 
     { 
      DWORD dwFlags = dwFlags |= INTERNET_FLAG_SECURE | 
       SECURITY_FLAG_IGNORE_UNKNOWN_CA | INTERNET_FLAG_IGNORE_CERT_CN_INVALID| 
       INTERNET_FLAG_IGNORE_CERT_DATE_INVALID; 
      /*SECURITY_FLAG_IGNORE_UNKNOWN_CA | 
      INTERNET_FLAG_IGNORE_CERT_CN_INVALID | 
      INTERNET_FLAG_IGNORE_CERT_DATE_INVALID 
      | SECURITY_FLAG_IGNORE_CERT_CN_INVALID 
      | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;*/ 


      // open request 
      HINTERNET hRequest; 

      if (port == 80) 
      { 
       hRequest = ::HttpOpenRequest(hConnect, TEXT("POST"), url, HTTP_VERSION, NULL, 0, NULL, 0); 
      } 
      else 
      { 
       hRequest = ::HttpOpenRequest(hConnect, TEXT("POST"), url, HTTP_VERSION, NULL, 0, dwFlags, 0); 
      } 

      if (hRequest != NULL) 
      { 
       if (::HttpSendRequest(hRequest, NULL, 0, (LPVOID)send.c_str(), send.length())) 
       { 
        for (;;) 
        { 
         // reading data 
         DWORD dwByteRead; 
         BOOL isRead = ::InternetReadFile(hRequest, szData, sizeof(szData) - 1, &dwByteRead); 

         // break cycle if error or end 
         if (isRead == FALSE || dwByteRead == 0) 
          break; 

         // saving result 
         szData[dwByteRead] = 0; 
         receive.append(szData); 
        } 
        printf(" receive data [%s]", receive.c_str()); 
       } 
       else{ 
        winret = GetLastError(); 
        printf("\nError %d has occurred while HttpSendRequest", winret); 
        switch (winret) 
        { 
        case ERROR_INTERNET_INVALID_CA: 
         printf("\nINVALID CA request received (%d)\n", winret); 
         break; 
        case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED: 
         printf("\nResubmitting for CLIENT_AUTH_CERT_NEEDED (%d)\n", winret); 
         break; 
        default: 
         printf("\nError %d has occurred while HttpSendRequest", winret); 
        } 
       } 

       // close request 
       ::InternetCloseHandle(hRequest); 
      } 
      else{ 
       winret = GetLastError(); 
       printf("\nError %d has occurred while HttpOpenRequest", winret); 
      } 
      // close session 
      ::InternetCloseHandle(hConnect); 
     } 
     else{ 
      winret = GetLastError(); 
      printf("\nError %d has occurred while InternetConnect", winret); 
     } 
     // close WinInet 
     ::InternetCloseHandle(hInternet); 
    } 
    else 
    { 
     winret = GetLastError(); 
     printf("\nError %d has occurred while InternetOpen", winret); 
    } 


    return winret; 
} 
int main() 
{ 
    std::string send; 
    std::string receive; 
    LPCTSTR host = L"172.17.9.93"; 
    int port = 443;// 80; 
    LPCTSTR url = L"base-bin/hello.cgi"; 
    doPost("<XMLhello>1</XMLhello>",receive,host,port,url); 
} 
+0

你寫的'DWORD的dwFlags =的dwFlags | = ...。通過這種方式,您可以在右側使用未初始化的var。當你聲明一個var時,它是立即可見的。我認爲'dwFlags'包含垃圾。 – alangab

回答

0

HttpOpenRequest只用旗工作形成INTERNET_FLAG_* - 通標誌SECURITY_FLAG_IGNORE_UNKNOWN_CAHttpOpenRequest這是錯誤。

找數值:

#define SECURITY_FLAG_IGNORE_UNKNOWN_CA   0x00000100 

#define INTERNET_FLAG_PRAGMA_NOCACHE 0x00000100 // asking wininet to add "pragma: no-cache" 

所以,如果你試圖通過SECURITY_FLAG_IGNORE_UNKNOWN_CAHttpOpenRequest你真傳INTERNET_FLAG_PRAGMA_NOCACHE標誌

SECURITY_FLAG_IGNORE_UNKNOWN_CA設計在InternetSetOption功能使用與INTERNET_OPTION_SECURITY_FLAGS

,所以你需要此代碼使用:

DWORD dwFlags; 
DWORD dwBuffLen = sizeof(dwFlags); 

if (InternetQueryOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, &dwBuffLen)) 
{ 
    dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; 
    InternetSetOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags)); 
} 

也看過How To Handle Invalid Certificate Authority Error with WinInet - 方法2.如果沒有一個UI:正是你的情況

+0

感謝它與InternetsetOptions一起使用,但它需要10秒鐘才能返回調用':: HttpSendRequest(hRequest,NULL,0,(LPVOID)send.c_str(),send.length())' – Mozfox

+0

@Mozfox - 但這已經是也取決於網站。有些網站可以和更多的時間打開。一些可以掛在上面 – RbMm

+0

我用捲曲檢查過,它是瞬間的。我認爲代碼是在DLL中,所以它可以影響它的工作? – Mozfox