Jump to content

Recommended Posts

Posted

With the _DllCallBack function comes the handy libcurl.au3 to handle dll calls to the cURL libcurl.dll.

Running the function on sites with an invalid certificate produces an error: "error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed".

Using curl.exe from the commandline and specifying to turn off certificate validation allows for successful downloading, eg 'curl.exe -k https://o.aolcdn.com -o output.txt'.

The documentation says that the same is possible also with libcurl.dll, ie with a call like curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE). My question is, how might we go about this with with the AutoIt function and is it possible?

#include "DllCallBack.au3"

; From libcurl headers
Global Const $CURLOPT_URL = 0x2712
Global Const $CURLOPT_WRITEDATA = 0x2711
Global Const $CURLOPT_WRITEFUNCTION = 0x4E2B
Global Const $CURLOPT_PROGRESSFUNCTION = 0x4E58
Global Const $CURLOPT_NOPROGRESS = 0x2B
Global Const $CURLOPT_ERRORBUFFER = 0x271A
Global Const $CURLOPT_TRANSFERTEXT = 0x35
Global Const $CURL_ERROR_SIZE = 0x100

; Load and initialize curl
$hDll_LibCurl = DllOpen("libcurl.dll")
$hCurlHandle = DllCall($hDll_LibCurl, "ptr:cdecl", "curl_easy_init")
$hCurlHandle = $hCurlHandle[0]

; Register Callback function's
; typedef int (*curl_progress_callback)(void *clientp,double dltotal,double dlnow,double ultotal,double ulnow);
$pProgress = _DllCallBack ("_Progress", "ptr;double;double;double;double",$_DllCallBack_Cdecl)
; size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
$pWriteFunc = _DllCallBack ("_WriteFunc", "ptr;uint;uint;ptr",$_DllCallBack_Cdecl)

; Create a buffer for error messages and Url
$CURL_ERROR = DllStructCreate("char[" & $CURL_ERROR_SIZE + 1 & "]")
$URL = DllStructCreate("char[256]")
DllStructSetData($URL, 1, "https://o.aolcdn.com")

; Setup Task
;DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_TRANSFERTEXT, "int", 1)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_URL, "ptr", DllStructGetPtr($URL))
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_NOPROGRESS, "int", 0)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_PROGRESSFUNCTION, "ptr", $pProgress)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_WRITEFUNCTION, "ptr", $pWriteFunc)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_ERRORBUFFER, "ptr", DllStructGetPtr($CURL_ERROR))

; Perform task
Global $g_nTimer = TimerInit(), $g_hFileOut = FileOpen("libcurl_dummy",2+16)
ProgressOn("Downloading", "")
$nPerform = DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_perform", "ptr", $hCurlHandle)
$nPerform = $nPerform[0]
If $nPerform <> 0 Then
    ; libcurl reported an error
    ConsoleWrite("! " & DllStructGetData($CURL_ERROR, 1) & @CRLF)
EndIf

; The progress function which gets called
Func _Progress($clientp, $dltotal, $dlnow, $ultotal, $ulnow)
    If TimerDiff($g_nTimer) > 250 Then
        ProgressSet($dlnow / $dltotal * 100, StringFormat("%.2fKb (%.1f%%)", $dlnow / 1024, $dlnow / $dltotal * 100))
        $g_nTimer = TimerInit()
    EndIf
    Return 0 ; Continue
EndFunc   ;==>_Progress

; This Callback function recieves the data downloaded
Func _WriteFunc ($ptr,$nSize,$nMemb,$pStream)
   Local $vData = DllStructCreate ("byte[" & $nSize*$nMemb & "]",$ptr)
   FileWrite($g_hFileOut,DllStructGetData($vData,1))
   Return $nSize*$nMemb
EndFunc

; Cleanup
ProgressOff()
FileClose($g_hFileOut)
DllCall($hDll_LibCurl, "none:cdecl", "curl_easy_cleanup", "ptr", $hCurlHandle)
$URL = 0
$CURL_ERROR = 0
_DllCallBack_Free ($pProgress)
_DllCallBack_Free ($pWriteFunc)

Thanks,

Galapo.

Posted

All you should need to know is the value for CURLOPT_SSL_VERIFYPEER. I did a quick search and I think 64 is the proper value. So something like this should work.

Global Const $CURLOPT_SSL_VERIFYPEER = 0x40

DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_SSL_VERIFYPEER, "int", 0)
Posted

Hi zorphnog,

Thanks indeed for that! I just tested and the function is now working for the server I was having troubles with.

So the idea is to convert the value to hex for use within the AutoIt function. Finally I get the idea of how these dll calls work.

Thanks again,

Galapo.

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...