cURL / Mailing Lists / curl-library / Single Mail

curl-library

curl_easy_setopt() fails to set CURLOPT_SSL_VERIFYPEER to 0L

From: cnm marketing <cnn.marketing_at_gmail.com>
Date: Sun, 10 Mar 2013 09:14:04 -0400

Hi,

I believe this may be a bug in libcurl. I'll appreciate it very much if
someone in the team can take a close look at. Here is the infor:

Platform:
"32 bit Linux Red Hat Enterprise Linux ES release 4" AND "64bit Linux SUSE
Linux Enterprise Server 11 (x86_64)"
Libcurl version:
"curl 7.12.1 (i386-redhat-linux-gnu) libcurl/7.12.1 OpenSSL/0.9.7a zlib/
1.2.1.2 libidn/0.5.6"(for 32bit RH) AND "curl 7.19.0
(x86_64-suse-linux-gnu) libcurl/7.19.0 OpenSSL/0.9.8h zlib/1.2.3
libidn/1.10" (for 64bit SUSE)

Additional Info:
1. by looking into the VERBOSE output (named "error output" below) from the
following c code (named "sample code" below), you can see
CURLOPT_SSL_VERIFYPEER is not being set to 0L (I highlighted in red).
2. You need to change the url in the code to point to your own url for your
testing.
3. I also include the VERBOSE output (named "correct output") for your
reference, I also highlighted in red.

 =========== beginning of "error output" ===============
* About to connect() to l2se0060.lss.emc.com port 8443 (#0)
* Trying 10.247.73.60... * connected
* Connected to l2se0060.lss.emc.com (10.247.73.60) port 8443 (#0)
* successfully set certificate verify locations:
* CAfile: none
  CApath: /etc/ssl/certs/
* SSL connection using DHE-RSA-AES128-SHA
* Server certificate:
* subject: /C=US/ST=MA/L=HOPKINTON/O=EMC/OU=SEM/CN=L2SE0060
* start date: 2013-02-21 02:04:05 GMT
* expire date: 2014-02-06 02:04:05 GMT
* issuer: /C=US/ST=MA/L=HOPKINTON/O=EMC/OU=SEM/CN=L2SE0060
** SSL certificate verify result: self signed certificate (18),
continuing anyway.
** Server auth using Basic with user 'smc'
> POST /univmax/restapi/performance/Array/metrics HTTP/1.1
Authorization: Basic c21jOnNtYw==
Host: l2se0060.lss.emc.com:8443
Accept: */*
Content-Type: application/json
Accept: application/xml
Content-Length: 171
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=64uy5GLfZAnTXipjAknfcFLB; Path=/univmax; Secure
< Date: Sun, 10 Mar 2013 12:54:47 GMT
< Accept-Ranges: bytes
< Server: Restlet-Framework/2.1.1
< RESTAPI-PROCESSING-TIME: 344
< RESTAPI-ACTIVE-SESSION-COUNT: 1
< Content-Type: application/xml;charset=UTF-8
< Transfer-Encoding: chunked
<
* Connection #0 to host l2se0060.lss.emc.com left intact
 =========== end of "error output" ===============

 =========== beginning of "correct output" ===============
* About to connect() to l2se0060.lss.emc.com port 8443 (#0)
* Trying 10.247.73.60... * connected
* Connected to l2se0060.lss.emc.com (10.247.73.60) port 8443 (#0)
* Initializing NSS with certpath: /etc/pki/nssdb
** skipping SSL peer certificate verification
** SSL connection using TLS_DHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate:
* subject: CN=L2SE0060,OU=SEM,O=EMC,L=HOPKINTON,ST=MA,C=US
* start date: Feb 21 02:04:05 2013 GMT
* expire date: Feb 06 02:04:05 2014 GMT
* common name: L2SE0060
* issuer: CN=L2SE0060,OU=SEM,O=EMC,L=HOPKINTON,ST=MA,C=US
* Server auth using Basic with user 'smc'
> POST /univmax/restapi/performance/Array/metrics HTTP/1.1
Authorization: Basic c21jOnNtYw==
Host: l2se0060.lss.emc.com:8443
Accept: */*
Content-Type: application/json
Accept: application/xml
Content-Length: 171
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=5P5z72UKDGlEubmys04986FI; Path=/univmax; Secure
< Date: Sun, 10 Mar 2013 12:58:31 GMT
< Accept-Ranges: bytes
< Server: Restlet-Framework/2.1.1
< RESTAPI-PROCESSING-TIME: 328
< RESTAPI-ACTIVE-SESSION-COUNT: 1
< Content-Type: application/xml;charset=UTF-8
< Transfer-Encoding: chunked
<
* Connection #0 to host l2se0060.lss.emc.com left intact
 =========== end of error "correct output" ===============

=========== beginning of make file for "sample code" ===============
cc -g -ldl -o post_d dbfetch_libcurl_post_dynamic.c
 =========== end of make file for "sample code" ===============

 =========== beginning of "sample code" ===============

/* $Id: dbfetch_libcurl_get.c -1 $

* ======================================================================

*

* Example dbfetch client in C using libcurl and HTTP POST.

*

* ======================================================================

*/

/* Include libraries */

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#define _GNU_SOURCE

#include <dlfcn.h>

#include <curl/curl.h>

struct string {

char *ptr;

size_t len;

};

void init_string(struct string *s)

{

s->len = 0;

s->ptr = malloc(s->len+1);

if (s->ptr == NULL)

{

fprintf(stderr, "malloc() failed\n");

exit(EXIT_FAILURE);

}

s->ptr[0] = '\0';

}

size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)

{

size_t new_len = s->len + size*nmemb;

s->ptr = realloc(s->ptr, new_len+1);

if (s->ptr == NULL)

{

fprintf(stderr, "realloc() failed\n");

exit(EXIT_FAILURE);

}

memcpy(s->ptr+s->len, ptr, size*nmemb);

s->ptr[new_len] = '\0';

s->len = new_len;

return size*nmemb;

}

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)

{

static int first_time=1;

char outfilename[FILENAME_MAX] = "body_post.out";

static FILE *outfile;

size_t written;

if (first_time) {

first_time = 0;

outfile = fopen(outfilename,"w");

if (outfile == NULL) {

return -1;

}

fprintf(stderr,"The body is <%s>\n",outfilename);

}

written = fwrite(ptr,size,nmemb,outfile);

return written;

}

 int httpPostData(char **xmlOut)

{

/* Exit status to return */

int exitStatus = 0;

/* Endpoint for dbfetch service to be used for POST */

const char* endpointUrl = "
https://l2se0060.lss.emc.com:8443/univmax/restapi/performance/Array/metrics"
;

char userpwd[40]="smc:smc";

const char body[800];

void* handle = dlopen("/usr/lib64/libcurl.so", RTLD_LAZY | RTLD_NOW);

if (handle == NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

return 1;

}

CURL* (*DLcurl_easy_init)();

DLcurl_easy_init = (CURL* (*)())dlsym(handle,"curl_easy_init");

if ( DLcurl_easy_init== NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

// !!!it is not thread-safe, CANNOT use it

//

/*CURLcode (*DLcurl_global_init)(long);

DLcurl_global_init = (CURLcode (*)(long))dlsym(handle, "curl_global_init");

if (DLcurl_global_init==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}*/

CURLcode (*DLcurl_easy_setopt)(CURL *, CURLoption , ...);

DLcurl_easy_setopt = (CURLcode (*)(CURL *, CURLoption , ...))dlsym(handle,
"curl_easy_setopt");

if (DLcurl_easy_setopt==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

struct curl_slist * (*DLcurl_slist_append)(struct curl_slist *, const char* );

DLcurl_slist_append = (struct curl_slist * (*)(struct curl_slist *, const
char * ))dlsym(handle, "curl_slist_append");

if (DLcurl_slist_append==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

CURLcode (*DLcurl_easy_perform)(CURL * );

DLcurl_easy_perform = (CURLcode (*)(CURL * ))dlsym(handle,
"curl_easy_perform");

if (DLcurl_easy_perform==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

const char * (*DLcurl_easy_strerror)(CURLcode );

DLcurl_easy_strerror = (const char * (*)(CURLcode ))dlsym(handle,
"curl_easy_strerror");

if (DLcurl_easy_strerror==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

void (*DLcurl_slist_free_all)(struct curl_slist * );

DLcurl_slist_free_all = (void (*)(struct curl_slist * ))dlsym(handle,
"curl_slist_free_all");

if (DLcurl_slist_free_all==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

void (*DLcurl_easy_cleanup)(CURL * );

DLcurl_easy_cleanup = (void (*)(CURL * ))dlsym(handle, "curl_easy_cleanup");

if (DLcurl_easy_cleanup==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

void (*DLcurl_easy_reset)(CURL * );

DLcurl_easy_reset = (void (*)(CURL * ))dlsym(handle, "curl_easy_reset");

if (DLcurl_easy_reset==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}

// !!!! It is not thread-safe

/*void (*DLcurl_global_cleanup)(void);

DLcurl_global_cleanup = (void (*)(void ))dlsym(handle,
"curl_global_cleanup");

if (DLcurl_global_cleanup==NULL)

{

const char * dl = dlerror();

printf("Error = %s\n", dl);

}*/

strcpy(body, "{\n\"arrayParam\": {\n\"startDate\" :
\"1361887800000\",\n\"endDate\" : \"1362495000000\",\n\"symmetrixId\" :
\"000195600138\",\n\"metrics\" : [\"IO_RATE\", \"HIT_PER_SEC\",
\"PERCENT_HIT\", \"WP\"]}}");

/* Construct resource POST data */

int postDataLen = strlen(body) + 26;

char* postData = (char*)malloc(sizeof(char) * (postDataLen));

if(postData == NULL) {

printf("Error: unable to allocate memory for POST data\n");

}

strcpy(postData, body);

printf("-------postData: %s\n\n", postData);

/* Initialise libcurl */

// !!!! It is not thread-safe, we CANNOT use it

// It works fine if we use this to init this program, however,

// We cannot use it because it is not thread-safe in our software!!!!

//

/*CURLcode globalHandle = DLcurl_global_init(CURL_GLOBAL_ALL);

if (globalHandle)

{

printf("DLcurl_global_init fails");

return 1;

}*/

char* curlErrStr = (char*)malloc(CURL_ERROR_SIZE);

/* Get a curl handle */

CURL* curlHandle = DLcurl_easy_init();

if(curlHandle)

{

struct string s;

init_string(&s);

DLcurl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, curlErrStr);

/* Set the endpoint to send the POST to */

CURLcode curlErr0 = DLcurl_easy_setopt(curlHandle, CURLOPT_URL,
endpointUrl);

if(curlErr0) {

printf("CURLOPT_URL...%s\n", DLcurl_easy_strerror(curlErr0));

}

CURLcode curlErr3 = DLcurl_easy_setopt(curlHandle, CURLOPT_SSL_VERIFYPEER,
0);

if(curlErr3) {

printf("CURLOPT_SSL_VERIFYPEER...%s\n", DLcurl_easy_strerror(curlErr3));

}

CURLcode curlErr38 = DLcurl_easy_setopt(curlHandle, CURLOPT_VERBOSE, 1);

if(curlErr38) {

printf("CURLOPT_VERBOSE...%s\n", DLcurl_easy_strerror(curlErr38));

}

CURLcode curlErr4 = DLcurl_easy_setopt(curlHandle, CURLOPT_CAINFO, 0);

if(curlErr4) {

printf("CURLOPT_CAINFO...%s\n", DLcurl_easy_strerror(curlErr4));

}

CURLcode curlErr5 = DLcurl_easy_setopt(curlHandle, CURLOPT_CAPATH, 0);

if(curlErr5) {

printf("CURLOPT_CAPATH...%s\n", DLcurl_easy_strerror(curlErr5));

}

CURLcode curlErr6 = DLcurl_easy_setopt(curlHandle, CURLOPT_SSL_VERIFYHOST,
0);

if(curlErr6) {

printf("CURLOPT_SSL_VERIFYHOST...%s\n", DLcurl_easy_strerror(curlErr6));

}

struct curl_slist *headers=NULL;

headers = DLcurl_slist_append(headers, "Content-Type:
application/json\nAccept: application/xml");

CURLcode curlErr7 = DLcurl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER,
headers);

if(curlErr7) {

printf("CURLOPT_HTTPHEADER...%s\n", DLcurl_easy_strerror(curlErr7));

}

CURLcode curlErr8 = DLcurl_easy_setopt(curlHandle, CURLOPT_USERPWD,
userpwd);

if(curlErr8) {

printf("CURLOPT_USERPWD...%s\n", DLcurl_easy_strerror(curlErr8));

}

/* Specify the POST data */

CURLcode curlErr9 = DLcurl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS,
postData);

if(curlErr9) {

printf("CURLOPT_POSTFIELDS...%s\n", DLcurl_easy_strerror(curlErr9));

}

CURLcode curlErr10 = DLcurl_easy_setopt(curlHandle,
CURLOPT_WRITEFUNCTION,&writefunc);

if(curlErr10) {

printf("CURLOPT_WRITEFUNCTION...%s\n", DLcurl_easy_strerror(curlErr10));

}

CURLcode curlErr11 = DLcurl_easy_setopt(curlHandle, CURLOPT_WRITEDATA,&s);

if(curlErr11) {

printf("CURLOPT_WRITEDATA...%s\n", DLcurl_easy_strerror(curlErr11));

}

//curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION,&write_data);

/* Execute the POST, response goes to STDOUT */

CURLcode curlErr = DLcurl_easy_perform(curlHandle);

/* Report any errors */

if(curlErr) {

printf("...%s\n", DLcurl_easy_strerror(curlErr));

}

*xmlOut = malloc(strlen(s.ptr)+1);

if (*xmlOut == NULL)

{

fprintf(stderr, "malloc() failed\n");

exit(EXIT_FAILURE);

}

*xmlOut[0] = '\0';

strncpy(*xmlOut, s.ptr, s.len);

free(s.ptr);

DLcurl_easy_reset(curlHandle);

/* free the header list */

DLcurl_slist_free_all(headers);

/* Clean-up libcurl */

DLcurl_easy_cleanup(curlHandle);

//DLcurl_global_cleanup();

}

else {

exitStatus = 1;

}

free(curlErrStr);

free(postData);

int cl = dlclose(handle);

if (cl != 0)

{

printf("Error\n");

}

/* Return the exit status */

return exitStatus;

}

int main(int argc, char* argv[])

{

int exitStatus = 0;

char * xmlOut;

int r;

for (r=0; r < 5; r++)

{

httpPostData(&xmlOut);

printf("%s...", xmlOut);

free (xmlOut);

getchar();

printf("=============");

}

return exitStatus;

}
 =========== end of "sample code" ===============

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-03-10