static nsresult ReadInternetOption(uint32_t aOption, uint32_t& aFlags, nsAString& aValue) { DWORD connFlags = 0; WCHAR connName[RAS_MaxEntryName + 1]; MOZ_SEH_TRY { InternetGetConnectedStateExW(&connFlags, connName, mozilla::ArrayLength(connName), 0); } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { return NS_ERROR_FAILURE; } INTERNET_PER_CONN_OPTIONW options[2]; options[0].dwOption = INTERNET_PER_CONN_FLAGS_UI; options[1].dwOption = aOption; INTERNET_PER_CONN_OPTION_LISTW list; list.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LISTW); list.pszConnection = connFlags & INTERNET_CONNECTION_MODEM ? connName : NULL; list.dwOptionCount = mozilla::ArrayLength(options); list.dwOptionError = 0; list.pOptions = options; unsigned long size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); if (!InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size)) { if (GetLastError() != ERROR_INVALID_PARAMETER) { return NS_ERROR_FAILURE; } options[0].dwOption = INTERNET_PER_CONN_FLAGS; size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); MOZ_SEH_TRY { if (!InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size)) { return NS_ERROR_FAILURE; } } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { return NS_ERROR_FAILURE; } } aFlags = options[0].Value.dwValue; aValue.Assign(options[1].Value.pszValue); GlobalFree(options[1].Value.pszValue); return NS_OK; }
static HRESULT start_downloading(Protocol *protocol) { HRESULT hres; hres = protocol->vtbl->start_downloading(protocol); if(FAILED(hres)) { protocol_close_connection(protocol); report_result(protocol, hres); return hres; } if(protocol->bindf & BINDF_NEEDFILE) { WCHAR cache_file[MAX_PATH]; DWORD buflen = sizeof(cache_file); if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, cache_file, &buflen)) { report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file); }else { FIXME("Could not get cache file\n"); } } protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE; return S_OK; }
void InetInsertCookies(HTTP_REQUEST_HANDLE *lpReq) { if ((lpReq) && (lpReq->dwType == HTTP_REQUEST)) { EnterSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); { WCHAR *lpUrl=NULL, *lpPath=NULL, *lpHost=NULL; do { DWORD dwLen=INTERNET_MAX_URL_LENGTH*sizeof(WCHAR); lpUrl=(WCHAR*)MemQuickAlloc(dwLen); if (!lpUrl) break; if (!InternetQueryOptionW(lpReq->hReq,INTERNET_OPTION_URL,lpUrl,&dwLen)) break; lpPath=WCHAR_QuickAlloc(INTERNET_MAX_PATH_LENGTH); if (!lpPath) break; lpHost=WCHAR_QuickAlloc(INTERNET_MAX_HOST_NAME_LENGTH); if (!lpHost) break; URL_COMPONENTSW url={0}; url.dwStructSize=sizeof(url); url.lpszHostName=lpHost; url.dwHostNameLength=INTERNET_MAX_HOST_NAME_LENGTH; url.lpszUrlPath=lpPath; url.dwUrlPathLength=INTERNET_MAX_PATH_LENGTH; if (!InternetCrackUrlW(lpUrl,NULL,0,&url)) break; WCHAR *lpCookies=NULL; if (Cookie_Get(lpReq->lpUrl->lpSession,lpHost,lpPath,&lpCookies,(url.nScheme == INTERNET_SCHEME_HTTPS),url.nPort)) { HttpAddRequestHeadersW(lpReq->hReq,lpCookies,-1,HTTP_ADDREQ_FLAG_ADD); MemFree(lpCookies); } } while (false); MemFree(lpUrl); MemFree(lpPath); MemFree(lpHost); } LeaveSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); } return; }
static HRESULT WINAPI HttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption, void *pBuffer, DWORD *pcbBuffer) { FtpProtocol *This = impl_from_IWinInetHttpInfo(iface); TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer); if(!This->base.request) return E_FAIL; if(!InternetQueryOptionW(This->base.request, dwOption, pBuffer, pcbBuffer)) return S_FALSE; return S_OK; }
static BOOL CertIsValid(HINTERNET hInternet, LPWSTR lpszHostName) { HINTERNET hConnect; HINTERNET hRequest; DWORD certInfoLength; BOOL Ret = FALSE; INTERNET_CERTIFICATE_INFOW certInfo; hConnect = InternetConnectW(hInternet, lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0); if (hConnect) { hRequest = HttpOpenRequestW(hConnect, L"HEAD", NULL, NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0); if (hRequest != NULL) { Ret = HttpSendRequestW(hRequest, L"", 0, NULL, 0); if (Ret) { certInfoLength = sizeof(INTERNET_CERTIFICATE_INFOW); Ret = InternetQueryOptionW(hRequest, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, &certInfo, &certInfoLength); if (Ret) { if (certInfo.lpszEncryptionAlgName) LocalFree(certInfo.lpszEncryptionAlgName); if (certInfo.lpszIssuerInfo) { if (strcmp((LPSTR)certInfo.lpszIssuerInfo, CERT_ISSUER_INFO) != 0) Ret = FALSE; LocalFree(certInfo.lpszIssuerInfo); } if (certInfo.lpszProtocolName) LocalFree(certInfo.lpszProtocolName); if (certInfo.lpszSignatureAlgName) LocalFree(certInfo.lpszSignatureAlgName); if (certInfo.lpszSubjectInfo) { if (strcmp((LPSTR)certInfo.lpszSubjectInfo, CERT_SUBJECT_INFO) != 0) Ret = FALSE; LocalFree(certInfo.lpszSubjectInfo); } } } InternetCloseHandle(hRequest); } InternetCloseHandle(hConnect); } return Ret; }
void InetProcessCookies(HTTP_REQUEST_HANDLE *lpReq) { if ((lpReq) && (lpReq->dwType == HTTP_REQUEST)) { EnterSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); { WCHAR *lpUrl=NULL, *lpPath=NULL, *lpHost=NULL; do { DWORD dwLen=INTERNET_MAX_URL_LENGTH*sizeof(WCHAR); lpUrl=(WCHAR*)MemQuickAlloc(dwLen); if (!lpUrl) break; if (!InternetQueryOptionW(lpReq->hReq,INTERNET_OPTION_URL,lpUrl,&dwLen)) break; lpPath=WCHAR_QuickAlloc(INTERNET_MAX_PATH_LENGTH); if (!lpPath) break; lpHost=WCHAR_QuickAlloc(INTERNET_MAX_HOST_NAME_LENGTH); if (!lpHost) break; URL_COMPONENTSW url={0}; url.dwStructSize=sizeof(url); url.lpszHostName=lpHost; url.dwHostNameLength=INTERNET_MAX_HOST_NAME_LENGTH; url.lpszUrlPath=lpPath; url.dwUrlPathLength=INTERNET_MAX_PATH_LENGTH; if (!InternetCrackUrlW(lpUrl,NULL,0,&url)) break; DWORD i=0; while (true) { WCHAR *lpCookie=NULL,szTmp[1]; DWORD dwSize=0; if ((HttpQueryInfoW(lpReq->hReq,HTTP_QUERY_SET_COOKIE,szTmp,&dwSize,&i)) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) break; dwSize+=2; lpCookie=(WCHAR*)MemQuickAlloc(dwSize); if (!lpCookie) break; if (HttpQueryInfoW(lpReq->hReq,HTTP_QUERY_SET_COOKIE,lpCookie,&dwSize,&i)) { WCHAR *lpData=StrChrW(lpCookie,L'='); if (lpData) { *lpData++=0; Cookie_Parse(lpReq->lpUrl->lpSession,lpHost,lpPath,lpCookie,lpData); } } MemFree(lpCookie); } } while (false); MemFree(lpUrl); MemFree(lpPath); MemFree(lpHost); } LeaveSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); } return; }
HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data) { HRESULT hres; if (!data) { WARN("Expected pProtocolData to be non-NULL\n"); return S_OK; } if(!protocol->request) { WARN("Expected request to be non-NULL\n"); return S_OK; } if(!protocol->protocol_sink) { WARN("Expected IInternetProtocolSink pointer to be non-NULL\n"); return S_OK; } if(protocol->flags & FLAG_ERROR) { protocol->flags &= ~FLAG_ERROR; protocol->vtbl->on_error(protocol, (DWORD)data->pData); return S_OK; } if(protocol->post_stream) return write_post_stream(protocol); if(data->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA) { hres = protocol->vtbl->start_downloading(protocol); if(FAILED(hres)) { protocol_close_connection(protocol); report_result(protocol, hres); return S_OK; } if(protocol->bindf & BINDF_NEEDFILE) { WCHAR cache_file[MAX_PATH]; DWORD buflen = sizeof(cache_file); if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, cache_file, &buflen)) { report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file); }else { FIXME("Could not get cache file\n"); } } protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE; } if(data->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA) { BOOL res; /* InternetQueryDataAvailable may immediately fork and perform its asynchronous * read, so clear the flag _before_ calling so it does not incorrectly get cleared * after the status callback is called */ protocol->flags &= ~FLAG_REQUEST_COMPLETE; res = InternetQueryDataAvailable(protocol->request, &protocol->available_bytes, 0, 0); if(res) { protocol->flags |= FLAG_REQUEST_COMPLETE; report_data(protocol); }else if(GetLastError() != ERROR_IO_PENDING) { protocol->flags |= FLAG_REQUEST_COMPLETE; WARN("InternetQueryDataAvailable failed: %d\n", GetLastError()); report_result(protocol, INET_E_DATA_NOT_AVAILABLE); } } return S_OK; }
/*********************************************************************** * WININET_InvalidCertificateDialog */ static INT_PTR WINAPI WININET_InvalidCertificateDialog( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { struct WININET_ErrorDlgParams *params; HWND hitem; WCHAR buf[1024]; if( uMsg == WM_INITDIALOG ) { TRACE("WM_INITDIALOG (%08lx)\n", lParam); /* save the parameter list */ params = (struct WININET_ErrorDlgParams*) lParam; SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam ); switch( params->dwError ) { case ERROR_INTERNET_INVALID_CA: LoadStringW( WININET_hModule, IDS_CERT_CA_INVALID, buf, 1024 ); break; case ERROR_INTERNET_SEC_CERT_DATE_INVALID: LoadStringW( WININET_hModule, IDS_CERT_DATE_INVALID, buf, 1024 ); break; case ERROR_INTERNET_SEC_CERT_CN_INVALID: LoadStringW( WININET_hModule, IDS_CERT_CN_INVALID, buf, 1024 ); break; case ERROR_INTERNET_SEC_CERT_ERRORS: /* FIXME: We should fetch information about the * certificate here and show all the relevant errors. */ LoadStringW( WININET_hModule, IDS_CERT_ERRORS, buf, 1024 ); break; default: FIXME( "No message for error %d\n", params->dwError ); buf[0] = '\0'; } hitem = GetDlgItem( hdlg, IDC_CERT_ERROR ); SetWindowTextW( hitem, buf ); return TRUE; } params = (struct WININET_ErrorDlgParams*) GetWindowLongPtrW( hdlg, GWLP_USERDATA ); switch( uMsg ) { case WM_COMMAND: if( wParam == IDOK ) { BOOL res = TRUE; if( params->dwFlags & FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS ) { http_request_t *req = params->req; DWORD flags, size = sizeof(flags); InternetQueryOptionW( req->hdr.hInternet, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size ); switch( params->dwError ) { case ERROR_INTERNET_INVALID_CA: flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; break; case ERROR_INTERNET_SEC_CERT_DATE_INVALID: flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; break; case ERROR_INTERNET_SEC_CERT_CN_INVALID: flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID; break; case ERROR_INTERNET_SEC_CERT_REV_FAILED: flags |= SECURITY_FLAG_IGNORE_REVOCATION; break; case ERROR_INTERNET_SEC_CERT_ERRORS: if(flags & _SECURITY_FLAG_CERT_REV_FAILED) flags |= SECURITY_FLAG_IGNORE_REVOCATION; if(flags & _SECURITY_FLAG_CERT_INVALID_CA) flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; if(flags & _SECURITY_FLAG_CERT_INVALID_CN) flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID; if(flags & _SECURITY_FLAG_CERT_INVALID_DATE) flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; break; } /* FIXME: Use helper function */ flags |= SECURITY_FLAG_SECURE; req->security_flags |= flags; if(req->netconn) req->netconn->security_flags |= flags; } EndDialog( hdlg, res ? ERROR_SUCCESS : ERROR_NOT_SUPPORTED ); return TRUE; } if( wParam == IDCANCEL ) { TRACE("Pressed cancel.\n"); EndDialog( hdlg, ERROR_CANCELLED ); return TRUE; } break; } return FALSE; }
/*********************************************************************** * WININET_InvalidCertificateDialog */ static INT_PTR WINAPI WININET_InvalidCertificateDialog( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { struct WININET_ErrorDlgParams *params; HWND hitem; WCHAR buf[1024]; if( uMsg == WM_INITDIALOG ) { TRACE("WM_INITDIALOG (%08lx)\n", lParam); /* save the parameter list */ params = (struct WININET_ErrorDlgParams*) lParam; SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam ); switch( params->dwError ) { case ERROR_INTERNET_INVALID_CA: LoadStringW( WININET_hModule, IDS_CERT_CA_INVALID, buf, 1024 ); break; case ERROR_INTERNET_SEC_CERT_DATE_INVALID: LoadStringW( WININET_hModule, IDS_CERT_DATE_INVALID, buf, 1024 ); break; case ERROR_INTERNET_SEC_CERT_CN_INVALID: LoadStringW( WININET_hModule, IDS_CERT_CN_INVALID, buf, 1024 ); break; case ERROR_INTERNET_SEC_CERT_ERRORS: /* FIXME: We should fetch information about the * certificate here and show all the relevant errors. */ LoadStringW( WININET_hModule, IDS_CERT_ERRORS, buf, 1024 ); break; default: FIXME( "No message for error %d\n", params->dwError ); buf[0] = '\0'; } hitem = GetDlgItem( hdlg, IDC_CERT_ERROR ); SetWindowTextW( hitem, buf ); return TRUE; } params = (struct WININET_ErrorDlgParams*) GetWindowLongPtrW( hdlg, GWLP_USERDATA ); switch( uMsg ) { case WM_COMMAND: if( wParam == IDOK ) { BOOL res = TRUE; if( params->dwFlags & FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS ) { DWORD flags, size = sizeof(flags); InternetQueryOptionW( params->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size ); switch( params->dwError ) { case ERROR_INTERNET_INVALID_CA: flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; break; case ERROR_INTERNET_SEC_CERT_DATE_INVALID: flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; break; case ERROR_INTERNET_SEC_CERT_CN_INVALID: flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID; break; case ERROR_INTERNET_SEC_CERT_ERRORS: FIXME("Should only add ignore flags as needed.\n"); flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA; /* FIXME: ERROR_INTERNET_SEC_CERT_ERRORS also * seems to set the corresponding DLG_* flags. */ break; } res = InternetSetOptionW( params->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, size ); if(!res) WARN("InternetSetOption(INTERNET_OPTION_SECURITY_FLAGS) failed.\n"); } EndDialog( hdlg, res ? ERROR_SUCCESS : ERROR_NOT_SUPPORTED ); return TRUE; } if( wParam == IDCANCEL ) { TRACE("Pressed cancel.\n"); EndDialog( hdlg, ERROR_CANCELLED ); return TRUE; } break; } return FALSE; }