Re: Multi-threading, NSS, client certificates and Linux problem

2017-01-20 Thread Pawel Veselov
On Fri, Jan 20, 2017 at 3:35 AM, Kamil Dudka  wrote:
> On Thursday, January 19, 2017 13:39:44 Pawel Veselov wrote:
>> Things work perfectly fine if I use the database, i.e. no MT problems.
>> Unfortunately, this is not a workaround to what I'm trying to achieve,
>> but it is pointing to nss-pem as a culprit, isn't it?
> Exactly.

I tried using PKCS#12 format for authenticating, but I can't make it work
either. I set the certificate type to P12, but simply get "NSS error -8018
(SEC_ERROR_UNKNOWN_PKCS11_ERROR)". Curl application simply rejects P12
certificate type, so don't know what's up with that.

>> Anywhere in particular you'd like me to dig in there?
> The nss-pem module maintains a global array of objects named pem_objs.  I
> guess it could be a problem if accesses to the array were not synchronized.
> But they should be thanks to the patch I referenced in my previous reply.

Well, I'm not familiar with curl or nss code so it's not easy for me to
understand this.

I'm looking at the code in nss_create_object, and is already a bit confused.
On the face of it it looks like the method creates some sort of "slots" with
NSS library, and there are ever only two potential names for these slots -
"PEM Token #0" or "PEM Token #1", depending on whether the certificate being
loaded is CA or not.

The function uses this slot during its execution, only locking it out when
the slot is being "found" (in nss_find_slot_by_name). I see that
PK11_CreateGenericObject() function uses a full lock when working with the
slot (EnterSlotMonitor/ExitSlotMonitor). The private key is loaded separately.
I haven't figured out all the logic, but the following sequence
strikes me as odd, I don't understand how things would work in this
case.

Consider nss_load_key (it doesn't matter what's going here, I just see that
the slot object is freely used by multiple threads that seem to store some
information into it, which can be easily overwritten by other threads).

thread#1 calls nss_create_object on key#1
thread#2 calls nss_create_object on key#2
thread#1 calls PK11_Authenticate (password)

At that last point, the only input is slot ID and password, I don't
see how it can possible know to operate on key#1, and not key#2...

If you could please help me understand how the MT is realized on these
slots, and where does it happen that certificate/keys are actually
written out to the TCP socket, it would be very helpful. The
documentation for PK11 is scarce to
come about (if you have a pointer to that, it'd be very helpful as well :) )

> Are your private keys encrypted?

They are not encrypted.

>> P.S. I also discovered that if database is used (even if it just
>> exists, may be it needs to have a CA, may be it doesn't), then
>> CURLOPT_CAINFO is ignored, or at least the cert that is provided by it
>> is no longer trusted. May be because the same cert is in the DB, and
>> without the C flag. If it is the latter, it is probably still a
>> problem, because if I say I need to trust cert X, there is no other
>> way for me to do it (if it is a system database, for example).
> You can try it with your own (e.g. empty) NSS database.  You can set the
> $SSL_DIR environment variable to make libcurl use a different database.

It's a stretch, sure, but the problem is:
* server's cert is signed with caXX
* client's cert is signed with caXX (same CA)
* you import client's chain into the cert database (CA gets imported, but
  left in there without trust)
* You don't want to enable trust for this CA for all connections
* You only want to enable trusting the CA explicitly when you need to.
* NSS always picks caXX from the database, even if it is specified as
  "trusted" separately, and because it's not marked as trusted in the DB,
  doesn't accept server's certificate.

P.P.S.

I also noticed this other thing in the code, may be I'm wrong.
The documentation says that to avoid conflicts between using file names and
certificate aliases for NSS, the use should prepend './' to the relative
file names. However, the code (nss_load_cert) checks if the file exists
first. So if there is a file at CWD/nick, it's not possible to use the
nickname, no?
---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

Re: [PATCH 0/5] Add some curl*va() API functions

2017-01-20 Thread Dan Fandrich
On Fri, Jan 20, 2017 at 05:42:39PM +0200, Ioan-Adrian Ratiu wrote:
> These API functions with a va_list parameter are in addition to the
> existing functions using "..." and are useful in case the library-caller is
> also a function getting "..." variable arguments, so the caller can pass its
> args to the library using the va-list. Doing this is impossible with the
> existing libcurl "..." functions because the caller has no way of passing
> its "..." args except by using a va_args list.
>
> Ioan-Adrian Ratiu (5):
>   curl_easy_getinfo: Add va() API function
>   curl_easy_setopt: Add va() API function
>   curl_formadd: Add va() API function
>   curl_multi_setopt: Add va() API function
>   curl_share_setopt: Add va() API function

What would be the real-life use case for these? The "variable" argument list
in all but one of these functions isn't actually variable; there is exactly one
argument in each case. And there was a recent proposal to revamp the curl form
functions entirely: https://github.com/curl/curl/wiki/formpost-API-redesigned

>>> Dan
---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

[PATCH 5/5] curl_share_setopt: Add va() API function

2017-01-20 Thread Ioan-Adrian Ratiu
Signed-off-by: Ioan-Adrian Ratiu 
---
 docs/libcurl/curl_share_setopt.3 |  6 +-
 include/curl/curl.h  |  1 +
 lib/share.c  | 18 +-
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/docs/libcurl/curl_share_setopt.3 b/docs/libcurl/curl_share_setopt.3
index 55e06f129..893a19997 100644
--- a/docs/libcurl/curl_share_setopt.3
+++ b/docs/libcurl/curl_share_setopt.3
@@ -21,14 +21,18 @@
 .\" **
 .TH curl_share_setopt 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual"
 .SH NAME
-curl_share_setopt - Set options for a shared object
+curl_share_setopt, curl_share_setopt_va - Set options for a shared object
 .SH SYNOPSIS
 .B #include 
 .sp
 CURLSHcode curl_share_setopt(CURLSH *share, CURLSHoption option, parameter);
+
+CURLSHcode curl_share_setopt_va(CURLSH *share, CURLSHoption option, va_list 
params);
 .ad
 .SH DESCRIPTION
 Set the \fIoption\fP to \fIparameter\fP for the given \fIshare\fP.
+
+For curl_share_setopt_va the first element of the va_list should contain 
\fIparameter\fP.
 .SH OPTIONS
 .IP CURLSHOPT_LOCKFUNC
 The \fIparameter\fP must be a pointer to a function matching the following
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 36ecf53cd..f1cb35c93 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -2382,6 +2382,7 @@ typedef enum {
 
 CURL_EXTERN CURLSH *curl_share_init(void);
 CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_setopt_va(CURLSH *, CURLSHoption option, 
va_list params);
 CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
 
 /
diff --git a/lib/share.c b/lib/share.c
index 5b3957fcf..da8331536 100644
--- a/lib/share.c
+++ b/lib/share.c
@@ -47,11 +47,9 @@ curl_share_init(void)
   return share;
 }
 
-#undef curl_share_setopt
 CURLSHcode
-curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
+curl_share_setopt_va(struct Curl_share *share, CURLSHoption option, va_list 
param)
 {
-  va_list param;
   int type;
   curl_lock_function lockfunc;
   curl_unlock_function unlockfunc;
@@ -63,8 +61,6 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption 
option, ...)
using this share */
 return CURLSHE_IN_USE;
 
-  va_start(param, option);
-
   switch(option) {
   case CURLSHOPT_SHARE:
 /* this is a type this share will share */
@@ -165,6 +161,18 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption 
option, ...)
 break;
   }
 
+  return res;
+}
+
+#undef curl_share_setopt
+CURLSHcode
+curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
+{
+  va_list param;
+  CURLSHcode res;
+
+  va_start(param, option);
+  res = curl_share_setopt_va(share, option, param);
   va_end(param);
 
   return res;
-- 
2.11.0

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

[PATCH 3/5] curl_formadd: Add va() API function

2017-01-20 Thread Ioan-Adrian Ratiu
Signed-off-by: Ioan-Adrian Ratiu 
---
 docs/libcurl/curl_formadd.3 |  5 -
 include/curl/curl.h |  6 +-
 lib/formdata.c  | 12 ++--
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/docs/libcurl/curl_formadd.3 b/docs/libcurl/curl_formadd.3
index 5d1faa532..36fcf6b6b 100644
--- a/docs/libcurl/curl_formadd.3
+++ b/docs/libcurl/curl_formadd.3
@@ -21,12 +21,15 @@
 .\" **
 .TH curl_formadd 3 "24 June 2002" "libcurl 7.9.8" "libcurl Manual"
 .SH NAME
-curl_formadd - add a section to a multipart/formdata HTTP POST
+curl_formadd, curl_formadd_va - add a section to a multipart/formdata HTTP POST
 .SH SYNOPSIS
 .B #include 
 .sp
 .BI "CURLFORMcode curl_formadd(struct curl_httppost ** " firstitem,
 .BI "struct curl_httppost ** " lastitem, " ...);"
+
+.BI "CURLFORMcode curl_formadd_va(struct curl_httppost ** " firstitem,
+.BI "struct curl_httppost ** " lastitem, " va_list arg);"
 .ad
 .SH DESCRIPTION
 curl_formadd() is used to append sections when building a multipart/formdata
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 467bb0240..36ecf53cd 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -2003,7 +2003,7 @@ typedef enum {
 } CURLFORMcode;
 
 /*
- * NAME curl_formadd()
+ * NAME curl_formadd()/curl_formadd_va()
  *
  * DESCRIPTION
  *
@@ -2015,6 +2015,10 @@ CURL_EXTERN CURLFORMcode curl_formadd(struct 
curl_httppost **httppost,
   struct curl_httppost **last_post,
   ...);
 
+CURL_EXTERN CURLFORMcode curl_formadd_va(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ va_list arg);
+
 /*
  * callback function for curl_formget()
  * The void *arg pointer will be the one passed as second argument to
diff --git a/lib/formdata.c b/lib/formdata.c
index c12227623..61eca92c1 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -733,11 +733,19 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
 }
 
 /*
- * curl_formadd() is a public API to add a section to the multipart formpost.
+ * curl_formadd()/curl_formadd_va() are public APIs to add a section to
+ * the multipart formpost.
  *
  * @unittest: 1308
  */
 
+CURLFORMcode curl_formadd_va(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ va_list arg)
+{
+  return FormAdd(httppost, last_post, arg);
+}
+
 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
   struct curl_httppost **last_post,
   ...)
@@ -745,7 +753,7 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
   va_list arg;
   CURLFORMcode result;
   va_start(arg, last_post);
-  result = FormAdd(httppost, last_post, arg);
+  result = curl_formadd_va(httppost, last_post, arg);
   va_end(arg);
   return result;
 }
-- 
2.11.0

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

[PATCH 1/5] curl_easy_getinfo: Add va() API function

2017-01-20 Thread Ioan-Adrian Ratiu
Signed-off-by: Ioan-Adrian Ratiu 
---
 docs/libcurl/curl_easy_getinfo.3 |  7 ++-
 include/curl/easy.h  |  7 ++-
 lib/easy.c   | 22 +++---
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3
index fabc7e92f..6edf41d8d 100644
--- a/docs/libcurl/curl_easy_getinfo.3
+++ b/docs/libcurl/curl_easy_getinfo.3
@@ -22,12 +22,14 @@
 .\"
 .TH curl_easy_getinfo 3 "11 Feb 2009" "libcurl 7.19.4" "libcurl Manual"
 .SH NAME
-curl_easy_getinfo - extract information from a curl handle
+curl_easy_getinfo,curl_easy_getinfo_va - extract information from a curl handle
 .SH SYNOPSIS
 .B #include 
 
 .B "CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );"
 
+.B "CURLcode curl_easy_getinfo_va(CURL *curl, CURLINFO info, va_list params);"
+
 .SH DESCRIPTION
 Request internal information from the curl session with this function.  The
 third argument \fBMUST\fP be a pointer to a long, a pointer to a char *, a
@@ -37,6 +39,9 @@ accordingly and can be relied upon only if the function 
returns CURLE_OK.  Use
 this function AFTER a performed transfer if you want to get transfer related
 data.
 
+For curl_share_setopt_va the first element of the va_list \fBMUST\fP conform to
+the specification for the third argument of curl_share_setopt above.
+
 You should not free the memory returned by this function unless it is
 explicitly mentioned below.
 .SH AVAILABLE INFORMATION
diff --git a/include/curl/easy.h b/include/curl/easy.h
index 752c5049f..2db58d03e 100644
--- a/include/curl/easy.h
+++ b/include/curl/easy.h
@@ -31,7 +31,7 @@ CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
 CURL_EXTERN void curl_easy_cleanup(CURL *curl);
 
 /*
- * NAME curl_easy_getinfo()
+ * NAME curl_easy_getinfo()/curl_easy_getinfo_va()
  *
  * DESCRIPTION
  *
@@ -42,9 +42,14 @@ CURL_EXTERN void curl_easy_cleanup(CURL *curl);
  * function returns CURLE_OK.  This function is intended to get used *AFTER* a
  * performed transfer, all results from this function are undefined until the
  * transfer is completed.
+ *
+ * The first element of the va_list arg of curl_easy_getinfo_va MUST conform to
+ * the specification of the third arg of curl_easy_getinfo above.
+ *
  */
 CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
 
+CURL_EXTERN CURLcode curl_easy_getinfo_va(CURL *curl, CURLINFO info, va_list 
params);
 
 /*
  * NAME curl_easy_duphandle()
diff --git a/lib/easy.c b/lib/easy.c
index bed94a444..0fbc9cb41 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -835,22 +835,30 @@ void curl_easy_cleanup(struct Curl_easy *data)
 }
 
 /*
- * curl_easy_getinfo() is an external interface that allows an app to retrieve
- * information from a performed transfer and similar.
+ * curl_easy_getinfo()/curl_easy_getinfo_va() are external interfaces that
+ * allow an app to retrieve information from a performed transfer and similar.
  */
-#undef curl_easy_getinfo
-CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
+CURLcode curl_easy_getinfo_va(struct Curl_easy *data, CURLINFO info, va_list 
arg)
 {
-  va_list arg;
   void *paramp;
   CURLcode result;
 
-  va_start(arg, info);
   paramp = va_arg(arg, void *);
-
   result = Curl_getinfo(data, info, paramp);
 
+  return result;
+}
+
+#undef curl_easy_getinfo
+CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
+{
+  va_list arg;
+  CURLcode result;
+
+  va_start(arg, info);
+  result = curl_easy_getinfo_va(data, info, arg);
   va_end(arg);
+
   return result;
 }
 
-- 
2.11.0

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

[PATCH 2/5] curl_easy_setopt: Add va() API function

2017-01-20 Thread Ioan-Adrian Ratiu
Signed-off-by: Ioan-Adrian Ratiu 
---
 docs/libcurl/curl_easy_setopt.3 |  6 +-
 include/curl/easy.h |  1 +
 lib/easy.c  | 22 +++---
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 422cb8569..b8eb8977b 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -22,11 +22,13 @@
 .\"
 .TH curl_easy_setopt 3 "25 Jun 2014" "libcurl 7.38.0" "libcurl Manual"
 .SH NAME
-curl_easy_setopt \- set options for a curl easy handle
+curl_easy_setopt,curl_easy_setopt_va \- set options for a curl easy handle
 .SH SYNOPSIS
 #include 
 
 CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
+
+CURLcode curl_easy_setopt_va(CURL *handle, CURLoption option, va_list params);
 .SH DESCRIPTION
 \fIcurl_easy_setopt(3)\fP is used to tell libcurl how to behave. By setting
 the appropriate options, the application can change libcurl's behavior.  All
@@ -37,6 +39,8 @@ expects. Read this manual carefully as bad input values may 
cause libcurl to
 behave badly!  You can only set one option in each function call. A typical
 application uses many \fIcurl_easy_setopt(3)\fP calls in the setup phase.
 
+For curl_easy_setopt_va the first element of the va_list should contain 
\fIparam\fP.
+
 Options set with this function call are valid for all forthcoming transfers
 performed using this \fIhandle\fP.  The options are not in any way reset
 between transfers, so if you want subsequent transfers with different options,
diff --git a/include/curl/easy.h b/include/curl/easy.h
index 2db58d03e..6ec663102 100644
--- a/include/curl/easy.h
+++ b/include/curl/easy.h
@@ -27,6 +27,7 @@ extern "C" {
 
 CURL_EXTERN CURL *curl_easy_init(void);
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_setopt_va(CURL *curl, CURLoption option, 
va_list params);
 CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
 CURL_EXTERN void curl_easy_cleanup(CURL *curl);
 
diff --git a/lib/easy.c b/lib/easy.c
index 0fbc9cb41..59a4ab1eb 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -366,24 +366,32 @@ struct Curl_easy *curl_easy_init(void)
 }
 
 /*
- * curl_easy_setopt() is the external interface for setting options on an
- * easy handle.
+ * curl_easy_setopt()/curl_easy_setopt_va() are external interfaces for
+ * setting options on an easy handle.
  */
 
-#undef curl_easy_setopt
-CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
+CURLcode curl_easy_setopt_va(struct Curl_easy *data, CURLoption tag, va_list 
arg)
 {
-  va_list arg;
   CURLcode result;
 
   if(!data)
 return CURLE_BAD_FUNCTION_ARGUMENT;
 
-  va_start(arg, tag);
-
   result = Curl_setopt(data, tag, arg);
 
+  return result;
+}
+
+#undef curl_easy_setopt
+CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
+{
+  va_list arg;
+  CURLcode result;
+
+  va_start(arg, tag);
+  result = curl_easy_setopt_va(data, tag, arg);
   va_end(arg);
+
   return result;
 }
 
-- 
2.11.0

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

[PATCH 4/5] curl_multi_setopt: Add va() API function

2017-01-20 Thread Ioan-Adrian Ratiu
Signed-off-by: Ioan-Adrian Ratiu 
---
 docs/libcurl/curl_multi_setopt.3 |  6 +-
 include/curl/multi.h |  5 -
 lib/multi.c  | 22 --
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/docs/libcurl/curl_multi_setopt.3 b/docs/libcurl/curl_multi_setopt.3
index d27c52441..56f68fb03 100644
--- a/docs/libcurl/curl_multi_setopt.3
+++ b/docs/libcurl/curl_multi_setopt.3
@@ -21,11 +21,13 @@
 .\" **
 .TH curl_multi_setopt 3 "4 Nov 2014" "libcurl 7.39.0" "libcurl Manual"
 .SH NAME
-curl_multi_setopt \- set options for a curl multi handle
+curl_multi_setopt,curl_multi_setopt_va \- set options for a curl multi handle
 .SH SYNOPSIS
 #include 
 
 CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param);
+
+CURLMcode curl_multi_setopt_va(CURLM * multi_handle, CURLMoption option, 
va_list params);
 .SH DESCRIPTION
 \fIcurl_multi_setopt(3)\fP is used to tell a libcurl multi handle how to
 behave. By using the appropriate options to \fIcurl_multi_setopt(3)\fP, you
@@ -36,6 +38,8 @@ pointer\fP or a \fBcurl_off_t\fP type, depending on what the 
specific option
 expects. Read this manual carefully as bad input values may cause libcurl to
 behave badly!  You can only set one option in each function call.
 
+For curl_multi_setopt_va the first element of the va_list should contain 
\fIparam\fP.
+
 .SH OPTIONS
 .IP CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE
 See \fICURLMOPT_CHUNK_LENGTH_PENALTY_SIZE(3)\fP
diff --git a/include/curl/multi.h b/include/curl/multi.h
index d1e00cc5d..fcc3c0e67 100644
--- a/include/curl/multi.h
+++ b/include/curl/multi.h
@@ -385,7 +385,7 @@ typedef enum {
 
 
 /*
- * Name:curl_multi_setopt()
+ * Name:curl_multi_setopt()/curl_multi_setopt_va()
  *
  * Desc:Sets options for the multi handle.
  *
@@ -394,6 +394,9 @@ typedef enum {
 CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
 CURLMoption option, ...);
 
+CURL_EXTERN CURLMcode curl_multi_setopt_va(CURLM *multi_handle,
+   CURLMoption option,
+   va_list params);
 
 /*
  * Name:curl_multi_assign()
diff --git a/lib/multi.c b/lib/multi.c
index 950b600cb..d8d483da3 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -2666,18 +2666,14 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
   return result;
 }
 
-#undef curl_multi_setopt
-CURLMcode curl_multi_setopt(struct Curl_multi *multi,
-CURLMoption option, ...)
+CURLMcode curl_multi_setopt_va(struct Curl_multi *multi,
+   CURLMoption option, va_list param)
 {
   CURLMcode res = CURLM_OK;
-  va_list param;
 
   if(!GOOD_MULTI_HANDLE(multi))
 return CURLM_BAD_HANDLE;
 
-  va_start(param, option);
-
   switch(option) {
   case CURLMOPT_SOCKETFUNCTION:
 multi->socket_cb = va_arg(param, curl_socket_callback);
@@ -2730,7 +2726,21 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
 res = CURLM_UNKNOWN_OPTION;
 break;
   }
+
+  return res;
+}
+
+#undef curl_multi_setopt
+CURLMcode curl_multi_setopt(struct Curl_multi *multi,
+CURLMoption option, ...)
+{
+  CURLMcode res;
+  va_list param;
+
+  va_start(param, option);
+  res = curl_multi_setopt_va(multi, option, param);
   va_end(param);
+
   return res;
 }
 
-- 
2.11.0

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

[PATCH 0/5] Add some curl*va() API functions

2017-01-20 Thread Ioan-Adrian Ratiu
These API functions with a va_list parameter are in addition to the
existing functions using "..." and are useful in case the library-caller is
also a function getting "..." variable arguments, so the caller can pass its
args to the library using the va-list. Doing this is impossible with the
existing libcurl "..." functions because the caller has no way of passing
its "..." args except by using a va_args list.

Ioan-Adrian Ratiu (5):
  curl_easy_getinfo: Add va() API function
  curl_easy_setopt: Add va() API function
  curl_formadd: Add va() API function
  curl_multi_setopt: Add va() API function
  curl_share_setopt: Add va() API function

 docs/libcurl/curl_easy_getinfo.3 |  7 ++-
 docs/libcurl/curl_easy_setopt.3  |  6 +-
 docs/libcurl/curl_formadd.3  |  5 -
 docs/libcurl/curl_multi_setopt.3 |  6 +-
 docs/libcurl/curl_share_setopt.3 |  6 +-
 include/curl/curl.h  |  7 ++-
 include/curl/easy.h  |  8 +++-
 include/curl/multi.h |  5 -
 lib/easy.c   | 44 +++-
 lib/formdata.c   | 12 +--
 lib/multi.c  | 22 ++--
 lib/share.c  | 18 +++-
 12 files changed, 111 insertions(+), 35 deletions(-)

-- 
2.11.0

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

Re: broken cURL on semicolon (of Windows drive letter) in file://

2017-01-20 Thread Daniel Stenberg

On Fri, 20 Jan 2017, Kees Dekker wrote:

I discovered that cURL 7.50.1 did accepts, but cURL 7.52.1 did not accept a 
colon in an URL. Example: the following URL did not work: 
file://c://temp/test.xml


Okay, your subject says semicolon and your mail body says colon. But the 
problem is actually neither. It is about the number of slashes.


Back in commit 346340808c we made the URL parser for file:// stricter. The 
file:// URLs are constructed like this (according to RFC 1738 as well as in 
the pending updated spec, draft-ietf-appsawg-file-scheme[1]):


  file://hostname/path

... where we used to ignore the host name since it doesn't serve any purpose. 
We learned that it confused and miselad users when used like 
file://etc/passwd, as it would appear to be another path than we'd actually 
use. So we made the hostname required to be localhost, 127.0.0.1 or blank.


This shipped in 7.52.0 and 7.52.1.

Subsequently, Anatol Belski filed issue #1187 [2] in which he revealed that 
PHP and a lot of other infrastructure is using the malformatted version of the 
file:// URL to a vast extent and that this change is causing them a lot of 
problems. Apparently they are doing something like "file://$path" for all 
platforms, which on non-windows thus adds a third slash and everything is 
fine, but for windows it'll add a drive letter there instead (ie one slash too 
few).


Based on that discussion, Jay Satiro landed commit 1d4202ade602d which brings 
back the support for that particular malformed version of the file:// URL. 
Since that version, and thus in the coming 7.53.0 release, we will again 
accept file://[letter]:/path on Windows.


I also discovered that back slashes are not allowed anymore (may be related 
to https://github.com/curl/curl/issues/1007). That is also an 
incompatibility breach (but if standards define to do so, it is acceptable).


Backslashes in the URL you mean, instead of regular forward slashes? I'm not 
aware of us changing treatment of that recently. Can you elaborate? But yes, 
backslashes are not legal characters in URLs and should rather be percent 
escaped.


If the standard does not forbid colons, cURL should also not forbid them, 
isn't it?


I'm pretty sure curl doesn't forbid colons at all.

If a simple C reproduction is needed, please let me know, I will then make 
one.


If you still believe there's a problem after this mail, then sure please 
provide one!


[1] = https://tools.ietf.org/html/draft-ietf-appsawg-file-scheme-16
[2] = https://github.com/curl/curl/issues/1187

--

 / daniel.haxx.se
---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

broken cURL on semicolon (of Windows drive letter) in file://

2017-01-20 Thread Kees Dekker
Hi,

I discovered that cURL 7.50.1 did accepts, but cURL 7.52.1 did not accept a 
colon in an URL. Example: the following URL did not work: 
file://c://temp/test.xml.

I also discovered that back slashes are not allowed anymore (may be related to 
https://github.com/curl/curl/issues/1007). That is also an incompatibility 
breach (but if standards define to do so, it is acceptable).

As there is no other method in Windows to tell an absolute path by adding a 
drive letter (or UNC path). So if the running process has a different working 
directory and calls the curl_easy_perform() function with provided URL, then 
the URL cannot be opened. This looks to me as a bug... If the standard does not 
forbid colons, cURL should also not forbid them, isn't it?

If a simple C reproduction is needed, please let me know, I will then make one.

Kees
---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

Re: Multi-threading, NSS, client certificates and Linux problem

2017-01-20 Thread Kamil Dudka
On Thursday, January 19, 2017 13:39:44 Pawel Veselov wrote:
> Things work perfectly fine if I use the database, i.e. no MT problems.
> Unfortunately, this is not a workaround to what I'm trying to achieve,
> but it is pointing to nss-pem as a culprit, isn't it?

Exactly.

> Anywhere in particular you'd like me to dig in there?

The nss-pem module maintains a global array of objects named pem_objs.  I 
guess it could be a problem if accesses to the array were not synchronized.  
But they should be thanks to the patch I referenced in my previous reply.

Are your private keys encrypted?

If so, I would also focus on the decryption code in pem_mdSession_Login(),
or better try reproducing the bug with unencrypted keys first.

> P.S. I also discovered that if database is used (even if it just
> exists, may be it needs to have a CA, may be it doesn't), then
> CURLOPT_CAINFO is ignored, or at least the cert that is provided by it
> is no longer trusted. May be because the same cert is in the DB, and
> without the C flag. If it is the latter, it is probably still a
> problem, because if I say I need to trust cert X, there is no other
> way for me to do it (if it is a system database, for example).

You can try it with your own (e.g. empty) NSS database.  You can set the 
$SSL_DIR environment variable to make libcurl use a different database.

Kamil
---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

RE: proposed changes for winbuild makefile

2017-01-20 Thread Kees Dekker
I will try to do so. But it will take time (set this on my todo list). If you 
have any wishes or suggestions, please let me know. I can't promise a date 
whenever I've something ready (I'm still busy to get all working of our own 
product, that uses cuRL (and OpenSSL + for Windows also zlib and libssh2). It 
is a pity that it is not very loud here, may be sending something on the 
generic (non-devel) list is an idea? My experience is that (like I do too) 
mailing lists are not checked unless someone run into problems, and start 
searching for a solution :-).

-Original Message-
From: curl-library [mailto:curl-library-boun...@cool.haxx.se] On Behalf Of Rod 
Widdowson
Sent: Thursday, January 19, 2017 17:01
To: 'libcurl development' 
Subject: RE: proposed changes for winbuild makefile 

> Is this a question to me to provide information to the help text? 

It’s a suggestion to you to do so.  With the hope that if someone out there 
thinks it a bad idea they'll chime in.

> (Note that this is the first time I was involved in this mailing list, I don't
> know the procedure how a fix/patch get applied.

I'm not very loud on this list either, but Daniel asked someone to jump in, so 
I did.  I'm hoping that all the lurking Windows users out there and/or Daniel 
will eventually chime in.   I can't provide more of a steer, but it seems like 
"a compelling case" is a good way to get a patch committed.

But as Daniel said elsewhere recently, the silence is deafening.  If we add the 
BASE_NAME stuff, the changes you propose would work well for me and I cannot 
see that it would break any existing user - if you believe my line that "what's 
in the help text will be backwards compatible, nothing else is guaranteed.

/Rod


---
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:  https://curl.haxx.se/mail/etiquette.html

---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

Re: Multiple READFUNCTION callbacks not happening

2017-01-20 Thread Pushkar Kulkarni
Hi Daniel,

Thanks for the prompt response.

>> Hm. Which version of libcurl is this? Can you try to set
CURLOPT_POSTFIELDSIZE instead of CURLOPT_INFILESIZE >> for the POST size?
That's what post-callback.c does... (I would expect them to work the same
in 7.43.0 or later but who >> knows for sure!)
Yes, I did try setting CURLOPT_POSTFIELDSIZE. I see the same behaviour :-(
I am using libcurl 7.47.0 on Ubuntu 16.04.

>> It'll be much more helpful if you posted a stand-alone example that
reproduces the problem. Possibily by changing the >> post-callback.c
example to work more like your code.
I'll try to work on this.

Thanks again,
Pushkar

On Fri, Jan 20, 2017 at 12:37 PM, Daniel Stenberg  wrote:

> On Fri, 20 Jan 2017, Pushkar Kulkarni wrote:
>
> If for a payload of 23K, we set the CURLOPT_INFILESIZE to 23K, we get only
>> one callback with size*nmemb = 16K. There are no subsequent callbacks and
>> hence the server keeps waiting before timing out.
>>
>
> Hm. Which version of libcurl is this? Can you try to set
> CURLOPT_POSTFIELDSIZE instead of CURLOPT_INFILESIZE for the POST size?
> That's what post-callback.c does... (I would expect them to work the same
> in 7.43.0 or later but who knows for sure!)
>
> Do let me know if you need more clarity on the code.
>>
>
> It'll be much more helpful if you posted a stand-alone example that
> reproduces the problem. Possibily by changing the post-callback.c example
> to work more like your code.
>
> Is there a way to dump all the options set on an easy handle? Though the
>> programmer must know what option he/she's setting, I am wondering if
>> there's a way to have it as a debug output.
>>
>
> No there isn't. But I'll agree that such a function would be really handy
> at times...
>
> --
>
>  / daniel.haxx.se
> ---
> Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
> Etiquette:   https://curl.haxx.se/mail/etiquette.html
---
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html