jackchen Posted March 3, 2015 Posted March 3, 2015 (edited) Hello Trancexx, Thanks for your contribution,I've learned more from your UDF. I need SSL certificate info from remote server,"https://www.autoitscript.com" for example.Codes below can get some certificate info as ExpiryTime, Subject etc.. Actually I need "Subject Alternative Name" info like "DNS Name=www.autoitscript.com DNS Name=autoitscript.com" from the certificate,It seems this info is contained in the "extention" part of certificate.Could any one point me how should I do? Thanks! expandcollapse popup#include <WinHttp.au3> Global Const $tagINTERNET_CERTIFICATE_INFO = "dword ExpiryTime[2]; dword StartTime[2]; ptr SubjectInfo; " & _ "ptr IssuerInfo; ptr ProtocolName; ptr SignatureAlgName; ptr EncryptionAlgName; dword KeySize" $hOpen = _WinHttpOpen() _WinHttpSetOption($hOpen, $WINHTTP_OPTION_SECURITY_FLAGS, 0x00003300) ; $SECURITY_FLAG_IGNORE_ALL $hConnect = _WinHttpConnect($hOpen, "www.autoitscript.com", 443) $hRequest = _WinHttpSimpleSendSSLRequest($hConnect, "GET", "/") ; I don't know why I failed to get info via _WinHttpQueryOption ;~ Global $tBuffer = _WinHttpQueryOption($hRequest, $WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT) ;~ Global $tINTERNET_CERTIFICATE_INFO = DllStructCreate($tagINTERNET_CERTIFICATE_INFO, DllStructGetPtr($tBuffer)) ;~ Global $tInfo = DllStructCreate("wchar [128]", DllStructGetData($tINTERNET_CERTIFICATE_INFO, "SubjectInfo")) ;~ Global $Info = DllStructGetData($tInfo, 1) ;~ ConsoleWrite('SSLCertificate Info: ' & @CRLF & $Info & @CRLF & @CRLF) $tBufferLength = DllStructCreate("dword") DllStructSetData($tBufferLength, 1, 2048) $tBuffer = DllStructCreate("byte[2048]") $avResult = DllCall($hWINHTTPDLL__WINHTTP, "bool", "WinHttpQueryOption", _ "handle", $hRequest, _ "dword", $WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, _ "struct*", DllStructGetPtr($tBuffer), _ "dword*", DllStructGetPtr($tBufferLength)) If Not @error And $avResult[0] Then $tINTERNET_CERTIFICATE_INFO = DllStructCreate($tagINTERNET_CERTIFICATE_INFO, DllStructGetPtr($tBuffer)) ; Get Subject $tInfo = DllStructCreate("wchar [128]", DllStructGetData($tINTERNET_CERTIFICATE_INFO, "SubjectInfo")) $Info = DllStructGetData($tInfo, 1) ConsoleWrite('SSLCertificate Info: ' & @CRLF & $Info & @CRLF & @CRLF) ;Get ExpiryTime $tInfo = DllStructCreate("int64", DllStructGetPtr($tINTERNET_CERTIFICATE_INFO, "ExpiryTime")) $Info = DllStructGetData($tInfo, 1) ConsoleWrite('SSLCertificate Info: ' & @CRLF & $Info & @CRLF & @CRLF) ; How to get SSL certificate extention info? I need "Subject Alternative Name" like "DNS Name=www.autoitscript.com DNS Name=autoitscript.com" EndIf $tBufferLength = 0 $tBuffer = 0 $tINTERNET_CERTIFICATE_INFO = 0 $tInfo = 0 _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) Edited March 3, 2015 by jackchen
trancexx Posted April 29, 2015 Author Posted April 29, 2015 (edited) To get extensions info you should query for $WINHTTP_OPTION_SERVER_CERT_CONTEXT and then use Certificate functions to read data.Something like this (no error checking here): expandcollapse popup#include "WinHttp.au3" $hOpen = _WinHttpOpen() $hConnect = _WinHttpConnect($hOpen, "https://www.facebook.com") $hRequest = _WinHttpSimpleSendSSLRequest($hConnect) ; Query for CERT_CONTEXT pointer $tBuffer = DllStructCreate("ptr") DllCall($hWINHTTPDLL__WINHTTP, "bool", "WinHttpQueryOption", _ "handle", $hRequest, _ "dword", $WINHTTP_OPTION_SERVER_CERT_CONTEXT, _ "struct*", $tBuffer, _ "dword*", DllStructGetSize($tBuffer)) ConsoleWrite("> CERT_CONTEXT pointer: " & DllStructGetData($tBuffer, 1) & @CRLF) ; Close handles _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) $pContext = DllStructGetData($tBuffer, 1) Const $CERT_NAME_DNS_TYPE = 6 Const $CERT_NAME_SEARCH_ALL_NAMES_FLAG = 0x2 ; Read size of the needed buffer $aCall = DllCall("Crypt32.dll", "dword", "CertGetNameString", _ "ptr", $pContext, _ "dword", $CERT_NAME_DNS_TYPE, _ "dword", $CERT_NAME_SEARCH_ALL_NAMES_FLAG, _ "dword*", 0, _ "struct*", 0, _ "dword", 0) $iSize = $aCall[0] ; Create buffer $tStruct = DllStructCreate("byte[" & $iSize & "]") ; Read DNS names $aCall = DllCall("Crypt32.dll", "dword", "CertGetNameString", _ "ptr", $pContext, _ "dword", $CERT_NAME_DNS_TYPE, _ "dword", $CERT_NAME_SEARCH_ALL_NAMES_FLAG, _ "dword*", 0, _ "struct*", $tStruct, _ "dword", $iSize) ; Free CERT_CONTEXT DllCall("Crypt32.dll", "dword", "CertFreeCertificateContext", "ptr", $pContext) ; Split on NULL character and convert to array $aArr = StringSplit(BinaryToString(DllStructGetData($tStruct, 1)), Chr(0), 2) ConsoleWrite("Subject Alternative Name - DNS Name=" & @CRLF) For $i = 0 To UBound($aArr) - 1 ConsoleWrite(@TAB & $aArr[$i] & @CRLF) Next ...Sorry for not replying earlier. Edited May 1, 2015 by trancexx funkey 1 ♡♡♡ . eMyvnE
bootybay Posted May 30, 2015 Posted May 30, 2015 Hi Manadar,I'd like to catch the HTTP Status Responses when pushing messages. Since the WinHttp UDF always been my nemesis I have trouble to figure out how to do that.If found some hints in the help file but I can't figure out how to add this to the SimpleFormFill: "Last (superfluous) $sAdditionalData argument can be used to pass authorization credentials in form "[CRED:username,password]", magic string to ignore cerificate errors in form "[IGNORE_CERT_ERRORS]" and/or HTTP request header data to add. "I'm still unsure if this even does what I want it to do. I just want to be able to receive the 200 OK or possible error responses (500 etc).I know it has been a long time since you posted in this topic. Maybe someone else can help me out. Hey Raizeno,try this:#include "WinHttp.au3" $sAddress = "https://api.pushover.net/1/messages.json" $sApiToken = "av26ac2nAXLyPKg2QMy4zf9YcUjz2G" ; <-yours here $sUserKey = "uMQf396GvMgrsDroaryKEvVyWkgfkw" ; <-yours here $sMessage = "hello world" ; Construct the form Const $sForm = '<form action="' & $sAddress & '" method="post">' & _ '<input name="token" value="' & $sApiToken & '"/>' & _ '<input name="user" value="' & $sUserKey & '"/>' & _ '<input name="message" value="' & $sMessage & '"/>' & _ '</form>' ; Open session $hOpen = _WinHttpOpen() ; To collect connection handle (because the form is inlined) $hConnect = $sForm ; Fill the form $sRead = _WinHttpSimpleFormFill($hConnect, $hOpen) ; Close handles _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) ; Tada mtfk! MsgBox(4096, "Simon says", $sRead)
lsakizada Posted June 2, 2015 Posted June 2, 2015 (edited) Hi, First thanks for this wonderful UDF!I am sending simple Get request to a server's API that response with json data.I noticed that the json data is truncated and partially data is received by the clientCan you please let me know what should be done to capture all data? I have this code to send the get methodexpandcollapse popupFunc BIPRequest($URL, $HTTPMethod, $HTTPSources = "", $JSON = '', $SaveHeaders = False, $SaveResponse = False, $ReadCookie = True, $SaveCookie = False, $Folder = @ScriptDir,$name="") Local $hOpen = _WinHttpOpen() Local $hConnect = _WinHttpConnect($hOpen, $URL) Local $hRequest = _WinHttpOpenRequest($hConnect, $HTTPMethod, $HTTPSources, Default, Default, Default, $WINHTTP_FLAG_SECURE) ; set options Local $CurrentOption = _WinHttpQueryOption($hRequest, $WINHTTP_OPTION_SECURITY_FLAGS) Local $Options = BitOR($CurrentOption, _ $SECURITY_FLAG_IGNORE_UNKNOWN_CA, _ $SECURITY_FLAG_IGNORE_CERT_CN_INVALID, _ $SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) _WinHttpSetOption($hRequest, $WINHTTP_OPTION_SECURITY_FLAGS, $Options) ; Send request If $ReadCookie = True Then _WinHttpAddRequestHeaders($hRequest, "Cookie: " & String(ReadCookie($Folder))) EndIf _WinHttpSendRequest($hRequest, "Content-type: application/json", $JSON) ; Wait for the response _WinHttpReceiveResponse($hRequest) ; ...get full header Local $sHeader = _WinHttpQueryHeaders($hRequest) If $SaveCookie = True Then SaveCookie($sHeader,$Folder) EndIf ; ...get full data Local $sData = _WinHttpReadData($hRequest) ; Clean/Close handles _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) ; Display retrieved header MsgBox(0, "Header", $sHeader) ; Display retrieved data MsgBox(0, "Data", $sData) If $SaveResponse = true Then SaveTestResponse($name, $sData ,$name) EndIf EndFunc ;==>BIPRequest Edited June 2, 2015 by lsakizada Be Green Now or Never (BGNN)!
lsakizada Posted June 2, 2015 Posted June 2, 2015 (edited) Please ignore my last post. I found the solution and it is very simple Needs to set the $iNumberOfBytesToRead default value of 8192 to $X bytes...Func _WinHttpReadData($hRequest, $iMode = Default, $iNumberOfBytesToRead = Default, $pBuffer = Default) Edited June 2, 2015 by lsakizada Be Green Now or Never (BGNN)!
trancexx Posted June 2, 2015 Author Posted June 2, 2015 ^^ Actually changing $iNumberOfBytesToRead isn't correct solution, because often you don't know how many bytes are there to read (chunked transfer encoding).More correct is to read in loop until all the data is read. See the help file entry for _WinHttpReadData.Also, your function can be reduced to a great degree by using set of _WinHttpSimple... functions. ♡♡♡ . eMyvnE
FaridAgl Posted June 2, 2015 Posted June 2, 2015 You may want to try something like this:Local $sResponse = '' If _WinHttpQueryHeaders($hRequest, $WINHTTP_QUERY_STATUS_CODE) == $HTTP_STATUS_OK Then If _WinHttpQueryDataAvailable($hRequest) Then While True $sResponse &= _WinHttpReadData($hRequest) If @extended Then ; --- Nothing to do Else ExitLoop EndIf WEnd If $sResponse Then ; --- Nothing to do Else Debug('Server.class | _WinHttpReadData() failed.', @ScriptLineNumber) _WinHttpCloseHandle($hRequest) Return $this.Result['InternetError'] EndIf Else Debug('Server.class | _WinHttpQueryDataAvailable() failed.', @ScriptLineNumber) _WinHttpCloseHandle($hRequest) Return $this.Result['InternetError'] EndIf Else Debug('Server.class | _WinHttpQueryHeaders() failed.', @ScriptLineNumber) _WinHttpCloseHandle($hRequest) Return $this.Result['InternetError'] EndIf _WinHttpCloseHandle($hRequest) ConsoleWrite($sResponse) http://faridaghili.ir
major4579 Posted June 2, 2015 Posted June 2, 2015 Hi,I'm trying to get and save the results of a php webpage. The URL is:"https://username:password@www.example.com/admin/report.php?startDate=2015-05-26"where the date at the end will be configured by my script. In a browser this would result in a plain text page like this:"Debbie","SMITH (Debbie)","Request Access: ","2015-05-31 17:29:47","2015-05-31 17:29:49","2015-05-31 19:10:57","301.8333333333333","""Eric,"JONES (Eric)","End Access: ","2015-05-31 18:16:00","2015-05-31 18:16:02","2015-05-31 18:44:12","46.86666666666667","" and so on.I'm trying to figure out how to do this with WinHttp. Note that going to "https://www.example.com" gets immediately redirected to a different page. Here's what I've tried:expandcollapse popup#include <WinHttp.au3> #include <WinHttpConstants.au3> $URL = "https://www.example.com/admin" $username = "username" $password = "password" $Data = "nccs.php?startDate=2015-05-31" Global $hw_open = _WinHttpOpen("WinHTTP Example4") If @error Then MsgBox(48, "Error", "Error initializing the usage of WinHTTP functions.") Exit EndIf Global $hw_connect = _WinHttpConnect($hw_open, $URL) If @error Then MsgBox(48, "Error", "Error specifying the initial target server of an HTTP request.") _WinHttpCloseHandle($hw_open) Exit EndIf Global $h_openRequest = _WinHttpOpenRequest($hw_connect, "GET", $Data) If @error Then MsgBox(48, "Error", "Error creating an HTTP request handle.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf _WinHttpSetCredentials($h_openRequest, $WINHTTP_AUTH_TARGET_SERVER, $WINHTTP_AUTH_SCHEME_BASIC, $username, $password) If @error Then MsgBox(48, "Error", "Unable to set Credentials.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf _WinHttpSendRequest($h_openRequest) If @error Then MsgBox(48, "Error", "Error sending the specified request.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf _WinHttpReceiveResponse($h_openRequest) If @error Then MsgBox(48, "Error", "Error ReceiveResponse.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf If _WinHttpQueryDataAvailable($h_openRequest) Then Global $header = _WinHttpQueryHeaders($h_openRequest) If @error Then MsgBox(48, "Error", "Error QueryHeaders.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit Endif Global $data While 1 $data &= X_WinHttpReadData($h_openRequest) If Not @extended Then ExitLoop WEnd Else MsgBox(48, "Error", "Error QueryDataAvailable.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) EndIf _WinHttpCloseHandle($h_openRequest) _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) FileWrite ("header.txt", $header) FileWrite ("data.txt", $data) Func X_WinHttpReadData($hRequest, $iNumberOfBytesToRead = 8192) Local $lpBuffer = DllStructCreate("char[" & $iNumberOfBytesToRead & "]") Local $a_iCall = DllCall("Winhttp.dll", "int", "WinHttpReadData", _ "hwnd", $hRequest, _ "ptr", DllStructGetPtr($lpBuffer), _ "ulong", $iNumberOfBytesToRead, _ "dword*", 0) If @error Or Not $a_iCall[0] Then SetError(1, 0, "") EndIf Return SetError(0, $a_iCall[4], DllStructGetData($lpBuffer, 1)) EndFuncThe Header.txt contains:HTTP/1.1 400 Bad Request Date: Tue, 02 Jun 2015 20:24:06 GMT Server: Apache/2.2.29 (Amazon) Vary: Accept-Encoding Content-Length: 449 Connection: close Content-Type: text/html; charset=iso-8859-1And the Data.txt contains:nccs.php?startDate=2015-05-31<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> Reason: You're speaking plain HTTP to an SSL-enabled server port.<br /> Instead use the HTTPS scheme to access this URL, please.<br /> </p> <hr> <address>Apache/2.2.29 (Amazon) Server at example.com Port 443</address> </body></html>Any suggestions and help would be greatly appreciated!-Marc
bPi Posted June 3, 2015 Posted June 3, 2015 I'm new to WinHTTP (have been using inetread/inetget for a while, and found that I couldn't figure out how to get around the 30 second timeout with them), and have been looking/testing/face-palming/trying again for the past day trying to figure out why I'm unable to get the following code to function as I expect. Basically, everything works when communicating with SSL sites that have valid certificates, and plain HTTP sites that don't use SSL. On internal sites with self-signed certificates (haven't been able to get the certs yet), the _WinHttpSimpleSendSSLRequest returns error code 2. I found reference somewhere that WinHTTP may require setting options, then retrying the request with self-signed certs, but adding the below logic yields a bunch more error code 2's from the _WinHttpSimpleSendSSLRequest and the directives that follow it in the code snippet below. I started off using the simple send request (as commented below), but then moved to the SSL variant as I was dealing with https sites.Is there a procedure I'm missing for sending GET-type queries using WinHTTP to a site with self-signed certificates? expandcollapse popup#include "WinHTTP.au3" #include "WinHTTPconstants.au3" $sQueryDomain = "https://Self-Signed.internal.pvt" $sQueryData = "tools/query?call=test&intVar=4&output=plain" $hHTTPopen = _WinHttpOpen() If @error Then _TrayLog("Error Opening HTTP Session", 1) Else _TrayLog("Successfully Opened HTTP Session", 1) _WinHttpSetTimeouts($hHTTPopen, 5000, Default, 99999000, 99999000) If @error Then _TrayLog("Error Setting HTTP Timeouts", 1) Else _TrayLog("Successfully Set HTTP Timeouts", 1) EndIf $hHTTPconnect = _WinHttpConnect($hHTTPopen, $sQueryDomain) If @error Then _TrayLog("Error Connecting to HTTP Domain", 1) Else _TrayLog("Successfully Connected to HTTP Domain", 1) ;~ $hHTTPrequest = _WinHttpSimpleSendRequest($hHTTPconnect, Default, $sQueryData) $hHTTPrequest = _WinHttpSimpleSendSSLRequest($hHTTPconnect, Default, $sQueryData) If @error Then _TrayLog("Error Issuing HTTP Request: " & @error, 1) _TrayLog("---Trying Again After Setting Options---", 1) $CurrentOption = _WinHttpQueryOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS) If @error Then _TrayLog("Error Querying HTTP Option", 1) Else _TrayLog("Successfully Queried HTTP Option", 1) $Options = BitOR($CurrentOption, $SECURITY_FLAG_IGNORE_UNKNOWN_CA, $SECURITY_FLAG_IGNORE_CERT_CN_INVALID, $SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) _WinHttpSetOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS, $Options) If @error Then _TrayLog("Error Setting HTTP Option: " & @error, 1) Else _TrayLog("Successfully Set HTTP Option", 1) EndIf EndIf $hHTTPrequest = _WinHttpSimpleSendSSLRequest($hHTTPconnect, Default, $sQueryData) If @error Then _TrayLog("Error Issuing HTTP Request a Second Time: " & @error, 1) Else _TrayLog("Successfully Issued HTTP Request After Option Change", 1) EndIf Else _TrayLog("Successfully Issued HTTP Request", 1) $CurrentOption = _WinHttpQueryOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS) If @error Then _TrayLog("Error Querying HTTP Option", 1) Else _TrayLog("Successfully Queried HTTP Option", 1) $Options = BitOR($CurrentOption, $SECURITY_FLAG_IGNORE_UNKNOWN_CA, $SECURITY_FLAG_IGNORE_CERT_CN_INVALID, $SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) _WinHttpSetOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS, $Options) If @error Then _TrayLog("Error Setting HTTP Option: " & @error, 1) Else _TrayLog("Successfully Set HTTP Option", 1) EndIf EndIf EndIf $bQueryData = _WinHttpSimpleReadData($hHTTPrequest, 2) If @error Then _TrayLog("Error Reading HTTP Data: " & @error, 1) Else _TrayLog("Successfully Read HTTP Data", 1) EndIf _WinHttpCloseHandle($hHTTPrequest) _WinHttpCloseHandle($hHTTPconnect) EndIf _WinHttpCloseHandle($hHTTPopen) EndIf Func _TrayLog($_s_Msg,$_b_CreateBubble=False) TraySetToolTip($_s_Msg) If $_b_CreateBubble Then TrayTip(@ScriptName,$_s_Msg,2) EndIf EndFunc Many thanks for any assistance you can provide,bPi
trancexx Posted June 3, 2015 Author Posted June 3, 2015 I'm new to WinHTTP (have been using inetread/inetget for a while, and found that I couldn't figure out how to get around the 30 second timeout with them), and have been looking/testing/face-palming/trying again for the past day trying to figure out why I'm unable to get the following code to function as I expect. Basically, everything works when communicating with SSL sites that have valid certificates, and plain HTTP sites that don't use SSL. On internal sites with self-signed certificates (haven't been able to get the certs yet), the _WinHttpSimpleSendSSLRequest returns error code 2. I found reference somewhere that WinHTTP may require setting options, then retrying the request with self-signed certs, but adding the below logic yields a bunch more error code 2's from the _WinHttpSimpleSendSSLRequest and the directives that follow it in the code snippet below. I started off using the simple send request (as commented below), but then moved to the SSL variant as I was dealing with https sites.Is there a procedure I'm missing for sending GET-type queries using WinHTTP to a site with self-signed certificates? expandcollapse popup#include "WinHTTP.au3" #include "WinHTTPconstants.au3" $sQueryDomain = "https://Self-Signed.internal.pvt" $sQueryData = "tools/query?call=test&intVar=4&output=plain" $hHTTPopen = _WinHttpOpen() If @error Then _TrayLog("Error Opening HTTP Session", 1) Else _TrayLog("Successfully Opened HTTP Session", 1) _WinHttpSetTimeouts($hHTTPopen, 5000, Default, 99999000, 99999000) If @error Then _TrayLog("Error Setting HTTP Timeouts", 1) Else _TrayLog("Successfully Set HTTP Timeouts", 1) EndIf $hHTTPconnect = _WinHttpConnect($hHTTPopen, $sQueryDomain) If @error Then _TrayLog("Error Connecting to HTTP Domain", 1) Else _TrayLog("Successfully Connected to HTTP Domain", 1) ;~ $hHTTPrequest = _WinHttpSimpleSendRequest($hHTTPconnect, Default, $sQueryData) $hHTTPrequest = _WinHttpSimpleSendSSLRequest($hHTTPconnect, Default, $sQueryData) If @error Then _TrayLog("Error Issuing HTTP Request: " & @error, 1) _TrayLog("---Trying Again After Setting Options---", 1) $CurrentOption = _WinHttpQueryOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS) If @error Then _TrayLog("Error Querying HTTP Option", 1) Else _TrayLog("Successfully Queried HTTP Option", 1) $Options = BitOR($CurrentOption, $SECURITY_FLAG_IGNORE_UNKNOWN_CA, $SECURITY_FLAG_IGNORE_CERT_CN_INVALID, $SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) _WinHttpSetOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS, $Options) If @error Then _TrayLog("Error Setting HTTP Option: " & @error, 1) Else _TrayLog("Successfully Set HTTP Option", 1) EndIf EndIf $hHTTPrequest = _WinHttpSimpleSendSSLRequest($hHTTPconnect, Default, $sQueryData) If @error Then _TrayLog("Error Issuing HTTP Request a Second Time: " & @error, 1) Else _TrayLog("Successfully Issued HTTP Request After Option Change", 1) EndIf Else _TrayLog("Successfully Issued HTTP Request", 1) $CurrentOption = _WinHttpQueryOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS) If @error Then _TrayLog("Error Querying HTTP Option", 1) Else _TrayLog("Successfully Queried HTTP Option", 1) $Options = BitOR($CurrentOption, $SECURITY_FLAG_IGNORE_UNKNOWN_CA, $SECURITY_FLAG_IGNORE_CERT_CN_INVALID, $SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) _WinHttpSetOption($hHTTPrequest, $WINHTTP_OPTION_SECURITY_FLAGS, $Options) If @error Then _TrayLog("Error Setting HTTP Option: " & @error, 1) Else _TrayLog("Successfully Set HTTP Option", 1) EndIf EndIf EndIf $bQueryData = _WinHttpSimpleReadData($hHTTPrequest, 2) If @error Then _TrayLog("Error Reading HTTP Data: " & @error, 1) Else _TrayLog("Successfully Read HTTP Data", 1) EndIf _WinHttpCloseHandle($hHTTPrequest) _WinHttpCloseHandle($hHTTPconnect) EndIf _WinHttpCloseHandle($hHTTPopen) EndIf Func _TrayLog($_s_Msg,$_b_CreateBubble=False) TraySetToolTip($_s_Msg) If $_b_CreateBubble Then TrayTip(@ScriptName,$_s_Msg,2) EndIf EndFunc Many thanks for any assistance you can provide,bPi_WinHttpSimpleSendSSLRequest will close request handle and return 0 in case of error (including cert errors). That's why you can't do anything with it. I don't know what version of WinHttp.au3 you use, but some time ago I added new parameter for _WinHttpSimpleSendSSLRequest to be able to ignore cert errors. This parameter is used internally when needed, so it's not documented. Anyway, if you want you can use it like this:$hHTTPrequest = _WinHttpSimpleSendSSLRequest($hHTTPconnect, Default, $sQueryData, Default, Default, Default, True)... to make request ignoring cert errors.Btw, why do you query security flags? Who cares what they are. If you want to ignore cert errors just set flags you want. ♡♡♡ . eMyvnE
trancexx Posted June 3, 2015 Author Posted June 3, 2015 (edited) Hi,I'm trying to get and save the results of a php webpage. The URL is:"https://username:password@www.example.com/admin/report.php?startDate=2015-05-26"where the date at the end will be configured by my script. In a browser this would result in a plain text page like this:"Debbie","SMITH (Debbie)","Request Access: ","2015-05-31 17:29:47","2015-05-31 17:29:49","2015-05-31 19:10:57","301.8333333333333","""Eric,"JONES (Eric)","End Access: ","2015-05-31 18:16:00","2015-05-31 18:16:02","2015-05-31 18:44:12","46.86666666666667","" and so on.I'm trying to figure out how to do this with WinHttp. Note that going to "https://www.example.com" gets immediately redirected to a different page. Here's what I've tried:expandcollapse popup#include <WinHttp.au3> #include <WinHttpConstants.au3> $URL = "https://www.example.com/admin" $username = "username" $password = "password" $Data = "nccs.php?startDate=2015-05-31" Global $hw_open = _WinHttpOpen("WinHTTP Example4") If @error Then MsgBox(48, "Error", "Error initializing the usage of WinHTTP functions.") Exit EndIf Global $hw_connect = _WinHttpConnect($hw_open, $URL) If @error Then MsgBox(48, "Error", "Error specifying the initial target server of an HTTP request.") _WinHttpCloseHandle($hw_open) Exit EndIf Global $h_openRequest = _WinHttpOpenRequest($hw_connect, "GET", $Data) If @error Then MsgBox(48, "Error", "Error creating an HTTP request handle.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf _WinHttpSetCredentials($h_openRequest, $WINHTTP_AUTH_TARGET_SERVER, $WINHTTP_AUTH_SCHEME_BASIC, $username, $password) If @error Then MsgBox(48, "Error", "Unable to set Credentials.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf _WinHttpSendRequest($h_openRequest) If @error Then MsgBox(48, "Error", "Error sending the specified request.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf _WinHttpReceiveResponse($h_openRequest) If @error Then MsgBox(48, "Error", "Error ReceiveResponse.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit EndIf If _WinHttpQueryDataAvailable($h_openRequest) Then Global $header = _WinHttpQueryHeaders($h_openRequest) If @error Then MsgBox(48, "Error", "Error QueryHeaders.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) Exit Endif Global $data While 1 $data &= X_WinHttpReadData($h_openRequest) If Not @extended Then ExitLoop WEnd Else MsgBox(48, "Error", "Error QueryDataAvailable.") _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) EndIf _WinHttpCloseHandle($h_openRequest) _WinHttpCloseHandle($hw_connect) _WinHttpCloseHandle($hw_open) FileWrite ("header.txt", $header) FileWrite ("data.txt", $data) Func X_WinHttpReadData($hRequest, $iNumberOfBytesToRead = 8192) Local $lpBuffer = DllStructCreate("char[" & $iNumberOfBytesToRead & "]") Local $a_iCall = DllCall("Winhttp.dll", "int", "WinHttpReadData", _ "hwnd", $hRequest, _ "ptr", DllStructGetPtr($lpBuffer), _ "ulong", $iNumberOfBytesToRead, _ "dword*", 0) If @error Or Not $a_iCall[0] Then SetError(1, 0, "") EndIf Return SetError(0, $a_iCall[4], DllStructGetData($lpBuffer, 1)) EndFuncThe Header.txt contains:HTTP/1.1 400 Bad Request Date: Tue, 02 Jun 2015 20:24:06 GMT Server: Apache/2.2.29 (Amazon) Vary: Accept-Encoding Content-Length: 449 Connection: close Content-Type: text/html; charset=iso-8859-1And the Data.txt contains:nccs.php?startDate=2015-05-31<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> Reason: You're speaking plain HTTP to an SSL-enabled server port.<br /> Instead use the HTTPS scheme to access this URL, please.<br /> </p> <hr> <address>Apache/2.2.29 (Amazon) Server at example.com Port 443</address> </body></html>Any suggestions and help would be greatly appreciated!-MarcYou could let WinHttp.au3 do all the job internally for you through _WinHttpSimpleFormFill. Like this maybe:expandcollapse popup#include "WinHttp.au3" $sAddress = "https://www.example.com/admin/report.php" ; the address of the target $sUserName = "username" $sPassword = "password" $sDate = "2015-05-31" $sForm = _ '<form action="' & $sAddress & '" method="get">' & _ ' <input name="startDate"/>' & _ ; '</form>' ; Initialize and get session handle $hOpen = _WinHttpOpen() $hConnect = $sForm ; will pass form as string so this is for coding correctness because $hConnect goes in byref ; Fill form $sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, _ Default, _ "name:startDate", $sDate, _ "[CRED:" & $sUserName & "," & $sPassword & "]") If @error Then MsgBox(4096, "Error", "Error number = " & @error) Else ConsoleWrite($sHTML & @CRLF) MsgBox(4096, "Returned", $sHTML) EndIf ; Close handles _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) Edited June 3, 2015 by trancexx eng ♡♡♡ . eMyvnE
bPi Posted June 3, 2015 Posted June 3, 2015 _WinHttpSimpleSendSSLRequest will close request handle and return 0 in case of error (including cert errors). That's why you can't do anything with it. I don't know what version of WinHttp.au3 you use, but some time ago I added new parameter for _WinHttpSimpleSendSSLRequest to be able to ignore cert errors. This parameter is used internally when needed, so it's not documented. Anyway, if you want you can use it like this:$hHTTPrequest = _WinHttpSimpleSendSSLRequest($hHTTPconnect, Default, $sQueryData, Default, Default, Default, True)... to make request ignoring cert errors.Btw, why do you query security flags? Who cares what they are. If you want to ignore cert errors just set flags you want. Thank you for your reply trancexx. I was able to get it to go using the undocumented parameter for ignoring all cert errors.The reason for querying the security flags and modifying them was as a result of reviewing some other posts and MSDN examples. Now that you mention it, I think you're absolutely right that I don't need to do the query, and could simply set the flags I want going forward.Thank you again,bPi
major4579 Posted June 5, 2015 Posted June 5, 2015 trancexx,You could let WinHttp.au3 do all the job internally for you through _WinHttpSimpleFormFill. Like this maybe:Thank you, thank you - in my ignorance I would never have thought to use the formfill function. Yet now after seeing it work and thinking about, it's beginning too make sense. I'm going to play with it some more - but it did get me exactly what I wanted!So thank you for help and for writing WinHTTP.au3 in the first place!-Marc
jackchen Posted June 23, 2015 Posted June 23, 2015 To get extensions info you should query for $WINHTTP_OPTION_SERVER_CERT_CONTEXT and then use Certificate functions to read data.Something like this (no error checking here): expandcollapse popup#include "WinHttp.au3" $hOpen = _WinHttpOpen() $hConnect = _WinHttpConnect($hOpen, "https://www.facebook.com") $hRequest = _WinHttpSimpleSendSSLRequest($hConnect) ; Query for CERT_CONTEXT pointer $tBuffer = DllStructCreate("ptr") DllCall($hWINHTTPDLL__WINHTTP, "bool", "WinHttpQueryOption", _ "handle", $hRequest, _ "dword", $WINHTTP_OPTION_SERVER_CERT_CONTEXT, _ "struct*", $tBuffer, _ "dword*", DllStructGetSize($tBuffer)) ConsoleWrite("> CERT_CONTEXT pointer: " & DllStructGetData($tBuffer, 1) & @CRLF) ; Close handles _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) $pContext = DllStructGetData($tBuffer, 1) Const $CERT_NAME_DNS_TYPE = 6 Const $CERT_NAME_SEARCH_ALL_NAMES_FLAG = 0x2 ; Read size of the needed buffer $aCall = DllCall("Crypt32.dll", "dword", "CertGetNameString", _ "ptr", $pContext, _ "dword", $CERT_NAME_DNS_TYPE, _ "dword", $CERT_NAME_SEARCH_ALL_NAMES_FLAG, _ "dword*", 0, _ "struct*", 0, _ "dword", 0) $iSize = $aCall[0] ; Create buffer $tStruct = DllStructCreate("byte[" & $iSize & "]") ; Read DNS names $aCall = DllCall("Crypt32.dll", "dword", "CertGetNameString", _ "ptr", $pContext, _ "dword", $CERT_NAME_DNS_TYPE, _ "dword", $CERT_NAME_SEARCH_ALL_NAMES_FLAG, _ "dword*", 0, _ "struct*", $tStruct, _ "dword", $iSize) ; Free CERT_CONTEXT DllCall("Crypt32.dll", "dword", "CertFreeCertificateContext", "ptr", $pContext) ; Split on NULL character and convert to array $aArr = StringSplit(BinaryToString(DllStructGetData($tStruct, 1)), Chr(0), 2) ConsoleWrite("Subject Alternative Name - DNS Name=" & @CRLF) For $i = 0 To UBound($aArr) - 1 ConsoleWrite(@TAB & $aArr[$i] & @CRLF) Next ...Sorry for not replying earlier.So many thanks for your reply!I tried your code and got DNS name from Subject Alternative Name.But it seems this code only return the first DNS name while some site's certificate contain many alternative DNS names.Currently I simply use getpeercert() in Python to get the SubjectAltName info,but how can I get the full list of all DNS names using Autoit?Thanks again.
jchd Posted June 23, 2015 Posted June 23, 2015 Please stop quoting the whole code (already posted) without reason. I can assure you that trancexx knows very well what and why she posted and BTW her post is still there for reference. Doing so only makes the discussion uselessly lengthy and increases the load on the AutoIt server with no purpose. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
trancexx Posted June 23, 2015 Author Posted June 23, 2015 So many thanks for your reply!I tried your code and got DNS name from Subject Alternative Name.But it seems this code only return the first DNS name while some site's certificate contain many alternative DNS names.Currently I simply use getpeercert() in Python to get the SubjectAltName info,but how can I get the full list of all DNS names using Autoit?Thanks again.That code snippet should give you exactly what you want. For me it prints:Subject Alternative Name - DNS Name= *.facebook.com facebook.com *.fb.com fb.com *.fbsbx.com *.fbcdn.net *.xx.fbcdn.net *.xy.fbcdn.net *.xz.fbcdn.net *.m.facebook.com *.messenger.com messenger.comCould you show me your console output for the exact code I posted? Also what system you run the code on? And with what version of both AutoIt and WinHttp.au3? ♡♡♡ . eMyvnE
trancexx Posted June 23, 2015 Author Posted June 23, 2015 Please stop quoting the whole code (already posted) without reason. I can assure you that trancexx knows very well what and why she posted and BTW her post is still there for reference. Doing so only makes the discussion uselessly lengthy and increases the load on the AutoIt server with no purpose.I couldn't disagree more with you on the subject. It's only polite to quote the post you are directly replying to, unless it's the last post in which case it's up to poster to decide what's best. That's how forums are meant to be used and how references are referenced. Forums have "Quote" button for reason. Additionally some posters tend to edit/delete their posts even after being quoted for whatever reason (usually dumb type of such), that'd be resulting in completely broken discussions if your "advice" would be followed..Excuse me for saying this but your argument about the server load is nothing more than unnecessary additional server load . ♡♡♡ . eMyvnE
jchd Posted June 23, 2015 Posted June 23, 2015 Sorry to disagree but I stand by. Over & out. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
jackchen Posted June 24, 2015 Posted June 24, 2015 That code snippet should give you exactly what you want. For me it prints:Subject Alternative Name - DNS Name= *.facebook.com facebook.com *.fb.com fb.com *.fbsbx.com *.fbcdn.net *.xx.fbcdn.net *.xy.fbcdn.net *.xz.fbcdn.net *.m.facebook.com *.messenger.com messenger.comCould you show me your console output for the exact code I posted? Also what system you run the code on? And with what version of both AutoIt and WinHttp.au3?Hi trancexx,thanks for your help.My system: Win 7 professional SP1 X64 English version with Chinese support(I'm in China)Autoit version: 3.3.12.0.WinHttp.au3: 1.6.3.7Below is the console output:>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\jxc3358\Desktop\chrome\SubjectAltName.au3" /UserParams +>09:08:57 Starting AutoIt3Wrapper v.15.503.1200.1 SciTE v.3.5.4.0 Keyboard:00000804 OS:WIN_7/Service Pack 1 CPU:X64 OS:X64 Environment(Language:0409) +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\jxc3358\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\jxc3358\AppData\Local\AutoIt v3\SciTE >Running AU3Check (3.3.12.0) from:C:\Program Files (x86)\AutoIt3 input:C:\Users\jxc3358\Desktop\chrome\SubjectAltName.au3 +>09:08:57 AU3Check ended.rc:0 >Running:(3.3.12.0):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\jxc3358\Desktop\chrome\SubjectAltName.au3" --> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop > CERT_CONTEXT pointer: 0x00ACE128 Subject Alternative Name - DNS Name= *.facebook.com +>09:09:00 AutoIt3.exe ended.rc:0 +>09:09:00 AutoIt3Wrapper Finished. >Exit code: 0 Time: 3.147
trancexx Posted June 24, 2015 Author Posted June 24, 2015 Ah yes, option to list all was added with win8. On your system it's not possible to list all entries using underlying function. Did you search around the web to see how to do it on pre-win8 systems? ♡♡♡ . eMyvnE
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now