Fix for include_url with self-signed SSL certs on Lasso 9

July 28, 2010 under Main

Lasso 9’s include_url tag has a bug in it which causes it to verify the CA of requests to all SSL hosts, regardless of the -verifypeer argument. This breaks connections to hosts with self-signed certificates. The fix is to edit the include_url tag:

< #verifypeer? < #curl->set(CURLOPT_SSL_VERIFYPEER, true)
---
> if(#verifypeer==false);
> #curl->set(CURLOPT_SSL_VERIFYPEER, false)
> /if;

Here is the full tag, renamed my_include_url, which works correctly with self-signed SSL certificates:

// [Include_URL]
// -NoData
// -Username
// -Password
// -GetParams = Array
// -PostParams = Array
// -SendMIMEHeaders
// -RetrieveMIMEHeaders = 'varname'
// -VerifyPeer
// -SSLCert = 'path'
// -SSLCertType = 'PEM' (default) or 'DER'
// -SSLKey' = 'path'
// -SSLKeyType = 'PEM' (default) or 'DER'
// -SSLKeyPasswd = 'password'
// -Timeout = #seconds
// -ConnectTimeout = #seconds

define my_include_url(url::string,
-getparams=array,
-postparams=array,
-sendmimeheaders=array,
-username='',
-password='',
-nodata=false,
-verifypeer=false,
-sslcert=void,
-sslcerttype=void,
-sslkey=void,
-sslkeytype=void,
-sslkeypasswd=void,
-timeout=void,
-connecttimeout=void,
-retrievemimeheaders='',
-options::array=array,
-string=false) => {

local(curl) = curl(#url);

// Modify URL
local(delimit) = (#url >> '?' ? '&' | '?');
iterate(#getparams, local(param));
#url += #delimit + #param->first + '=' + #param->second; // BUG URL ENCODING
local(delimit) = '&';
/iterate;

// Set CURL Options
if((#username != '') || (#password != ''));
#curl->set(CURLOPT_USERPWD, #username + ':' + #password); // BUG URL ENCODING
/if;
if(#postparams->size > 0);
if(#postparams->isa(::trait_forEach));
local(postfields) = string;
local(delimit) = '';
with param in #postparams
do {
#postfields += #delimit + #param->first + '=' + #param->second; // BUG URL ENCODING
local(delimit) = '&';
}
#curl->set(CURLOPT_POSTFIELDS, #postfields)
else(#postparams->isa(::string) || #postparams->isa(::bytes))
#curl->set(CURLOPT_POSTFIELDS, #postparams)
/if;
/if;
if(#sendmimeheaders->size > 0);
if(#sendmimeheaders->isa(::trait_forEach));
local(httpheader) = string;
local(delimit) = '';
with param in #sendmimeheaders
do {
#httpheader += #delimit + #param->first + ': ' + #param->second; // BUG URL ENCODING
local(delimit) = '\r\n';
}
#curl->set(CURLOPT_HTTPHEADER, #httpheader);
else(#postparams->isa(::string) || #postparams->isa(::bytes));
#curl->set(CURLOPT_HTTPHEADER, #sendmimeheaders);
/if;
/if;
if(#verifypeer==false);
#curl->set(CURLOPT_SSL_VERIFYPEER, false)
/if;
#sslcert?
#curl->set(CURLOPT_SSLCERT, string(#sslcert))
#sslcerttype?
#curl->set(CURLOPT_SSLCERTTYPE, string(#sslcerttype))
#sslkey?
#curl->set(CURLOPT_SSLKEY, string(#sslkey))
#sslkeytype?
#curl->set(CURLOPT_SSLKEYTYPE, string(#sslkeytype))
#sslkeypasswd?
#curl->set(CURLOPT_SSLKEYPASSWD, string(#sslkeypasswd))
#timeout?
#curl->set(CURLOPT_TIMEOUT, decimal(#timeout))
#connecttimeout?
#curl->set(CURLOPT_CONNECTTIMEOUT, decimal(#connecttimeout))

// Other CURL Options
with O in #options
where #O->isa(::pair)
do { #curl->set(#O->first, #O->second) }

// Fetch Results
if(#nodata);
local(result) = #curl->ready;
else;
local(result) = #curl->result;
#result == null ? #result = bytes;
if(#retrievemimeheaders != '');
var(#retrievemimeheaders = #curl->header);
/if;

// return as a string?
if(#string);
// user-defined charset?
#string->isa(::string) ? return #result->exportas(#string);

// auto-discover charset
local(auto_charset = string_findregexp( #curl->header, -find='(?i)charset\\s*=\\s*([\\w\\-]+)'));
if(#auto_charset->size >= 2);
#auto_charset = #auto_charset->get(2);
else; // charset not found in headers, try meta on page
local(auto_charset = string_findregexp( #result, -find='(?i)charset\\s*=\\s*([\\w\\-]+)'));
if(#auto_charset->size >= 2);
#auto_charset = #auto_charset->get(2);
else;
#auto_charset = 'utf-8'; // default is utf-8 if all else fails
/if;
/if;
#auto_charset == 'ISO-8859-1' ? #auto_charset = 'Windows-1252';
return #result->exportas(#auto_charset);
/if;

// return as bytes
return(#result);
/if;
}

comments: Closed
Subscribe