cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: HTTP > HTTPS redirect with curl_global_init(CURL_GLOBAL_NOTHING) crashes

From: Richard Gray <rgray_at_plustechnologies.com>
Date: Wed, 29 Jun 2016 09:39:56 -0400

Daniel Stenberg wrote:
> On Tue, 28 Jun 2016, Ray Satiro via curl-library wrote:
>
>> In the rare circumstance where you do your own Winsock and/or SSL
>> initialization you may be able to skip using CURL_GLOBAL_WIN32 and/or
>> CURL_GLOBAL_SSL. It's not recommended or documented how to do that safely in
>> a way that meets libcurl's requirements of those libraries, which may change.
>
> Yeah. These bits and these abilities were added back in the days when we
> didn't have as many TLS backends (the sweet innocense of 2001!), so when I
> learned that both OpenSSL and the winsock stuff want to get initialized only
> once in a program I made it possible for programs that for some reason would
> do its own TLS and/or winsock initializations outside of libcurl to tell
> libcurl to skip those parts.
>
> So setting it to CURL_GLOBAL_NOTHING doesn't mean that HTTPS shouldn't work,
> it just means that the application took care of the TLS (and winsock) initing.
>
> Of course, in modern days, an application would have to know quite a bit about
> the specific libcurl instance it uses if it wants to init the TLS library
> itself and it is probably very rare and a feature almost never used
> (correctly). Then again, a vast majority of all libcurl users are using
> OpenSSL so you could make some assumptions and probably get away with them for
> a long time.
>
> But the crashes part is interesting. What exactly crashes and how? We could
> possibly try to work harder to avoid that even in a situation where this is
> wrongly used.
>

My main thrust in bringing this up was documentation about SSL initialization
and whether or not libcurl should protect against SSL use when it hasn't been
initialized. Not a big deal, because I know I was screwing up.

static const long max_redirs = 5; /* follow up to n redirects */

    rtn = curl_global_init(CURL_GLOBAL_NOTHING); /* minimal */
// rtn = curl_global_init(CURL_GLOBAL_DEFAULT);
    if (rtn)
       efunc = "curl_global_init";
    else
       {
       mh = curl_multi_init();
       if (mh == NULL)
          efunc = "curl_multi_init()";
       }
    if (*efunc)
       // LOG ERROR & FAIL

    // DEBUG OUT curl_version(), _info()

    // basic init of handle

    curl_easy_setopt(hs->eh, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(hs->eh, CURLOPT_PRIVATE, ses);
    curl_easy_setopt(hs->eh, CURLOPT_TIMEOUT, (long)HTTP_TIMEOUT);
    curl_easy_setopt(hs->eh, CURLOPT_NOSIGNAL, 1L); /* just in case */
    curl_easy_setopt(hs->eh, CURLOPT_WRITEFUNCTION, &wrt_callback);
    curl_easy_setopt(hs->eh, CURLOPT_WRITEDATA, ses);
    curl_easy_setopt(hs->eh, CURLOPT_FOLLOWLOCATION, (long)(max_redirs != 0L));
    curl_easy_setopt(hs->eh, CURLOPT_MAXREDIRS, max_redirs);
    curl_easy_setopt(hs->eh, CURLOPT_REDIR_PROTOCOLS,
                    (CURLPROTO_HTTP | CURLPROTO_HTTPS) );

    // init of individual scrape attempt

       cres = curl_easy_setopt(hs->eh, CURLOPT_URL, hs->url);
       if (cres != CURLE_OK)
          // error
       mres = curl_multi_add_handle(mh, hs->eh);
       if (mres != CURLM_OK)
         // error

curl_multi_perform is called off the main loop's select(), which is primarily
handling a boatload of SNMP (UDP) packet traffic.

Mix of my debug/logging and libcurl's:

init http scrape
  libcurl: libcurl/7.47.0 WinSSL WinIDN
  info age 3
  info ver 7.47.0
  info ver# 72f00
  info proto dict
  info proto file
  info proto ftp
  info proto ftps
  info proto gopher
  info proto http
  info proto https
  info proto imap
  info proto imaps
  info proto ldap
  info proto pop3
  info proto pop3s
  info proto rtsp
  info proto smb
  info proto smbs
  info proto smtp
  info proto smtps
  info proto telnet
  info proto tftp
  feature SSL
  entering main loop

192.168.244.206 scrape target http://192.168.244.206/ews/status/infomation.htm
  * Trying 192.168.244.206...
--- 2 2 46 1 0 192.168.244.206
  * Connected to 192.168.244.206 (192.168.244.206) port 80 (#0)
> GET /ews/status/infomation.htm HTTP/1.1
Host: 192.168.244.206
Accept: */*

* HTTP 1.0, assume close after body
< HTTP/1.0 302 Found
< Location: https://192.168.244.206/ews/status/infomation.htm
< Server: EWS-NIC4/13.11
< Connection: close
< Content-Type: text/html
<
* Closing connection 0
* Issue another request to this URL: 'https://192.168.244.206/ews/status/infomat
ion.htm'
* Trying 192.168.244.206...
* Connected to 192.168.244.206 (192.168.244.206) port 443 (#1)
* schannel: SSL/TLS connection with 192.168.244.206 port 443 (step 1/3)
* schannel: checking server certificate revocation

I was not running a debug version of libcurl (no symbols), so I pretty much
lose visibility at curl_multi_perform().

Without redirection enabled or with CURLPROTO_HTTPS out, the sequence safely
stops at the redirect.

As I said, I don't see this as a big deal and can't put a lot of time into it,
but I was curious.

Thanks Ray & Daniel!

Rich

-------------------------------------------------------------------
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2016-06-29