[PATCH 1/2] esx: Allow specifying different CA bundle for remote connections

Martin Kletzander via Devel posted 2 patches 3 months ago
[PATCH 1/2] esx: Allow specifying different CA bundle for remote connections
Posted by Martin Kletzander via Devel 3 months ago
From: Martin Kletzander <mkletzan@redhat.com>

Add new URI parameter which allows for using non-system CA certificates
to verify remote peers.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
---
 docs/drvesx.rst    | 16 ++++++++++++++--
 src/esx/esx_util.c |  4 ++++
 src/esx/esx_util.h |  1 +
 src/esx/esx_vi.c   |  3 +++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/docs/drvesx.rst b/docs/drvesx.rst
index 13c2bc37e50b..37398a11ee09 100644
--- a/docs/drvesx.rst
+++ b/docs/drvesx.rst
@@ -91,7 +91,7 @@ Multiple parameters are separated by ``&``.
 
 ::
 
-   ?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456
+   ?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456&cainfo_path=certs/ca-bundle.pem
 
 The driver understands the extra parameters shown below.
 
@@ -146,6 +146,16 @@ The driver understands the extra parameters shown below.
 |                 |                             | ``port`` allows to override |
 |                 |                             | the default port 1080.      |
 +-----------------+-----------------------------+-----------------------------+
+| ``cainfo_path`` | Path to a file with one     | The specified file will be  |
+|                 | or more certificates        | used for verifying the      |
+|                 |                             | remote host certificate     |
+|                 |                             | instead of the default      |
+|                 |                             | system one.                 |
+|                 |                             | :since:`Since 11.5.0`.      |
+|                 |                             | Does nothing if             |
+|                 |                             | ``no_verify`` is set        |
+|                 |                             | to ``1``                    |
++-----------------+-----------------------------+-----------------------------+
 
 Authentication
 ~~~~~~~~~~~~~~
@@ -181,8 +191,10 @@ error like this one:
 
    error: internal error curl_easy_perform() returned an error: Peer certificate cannot be authenticated with known CA certificates (60)
 
-Where are two ways to solve this problem:
+Where are three ways to solve this problem:
 
+-  Use the ``cainfo_path`` `Extra parameters`_ to point to a certificate bundle
+   with the CA that signed the SSL certificate used on the ESX server.
 -  Use the ``no_verify=1`` `Extra parameters`_ to disable server
    certificate verification.
 -  Generate new SSL certificates signed by a CA known to your client computer
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index cb9638f36047..9a2d194fc94c 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -135,6 +135,9 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
                     goto cleanup;
                 }
             }
+        } else if (STRCASEEQ(queryParam->name, "cainfo_path")) {
+            g_clear_pointer(&(*parsedUri)->cainfo_path, g_free);
+            (*parsedUri)->cainfo_path = g_strdup(queryParam->value);
         } else {
             VIR_WARN("Ignoring unexpected query parameter '%s'",
                      queryParam->name);
@@ -168,6 +171,7 @@ esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri)
     g_free((*parsedUri)->vCenter);
     g_free((*parsedUri)->proxy_hostname);
     g_free((*parsedUri)->path);
+    g_free((*parsedUri)->cainfo_path);
 
     g_free(*parsedUri);
 }
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 088c943e6448..3f8d8d7cb3b4 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -44,6 +44,7 @@ struct _esxUtil_ParsedUri {
     char *proxy_hostname;
     int proxy_port;
     char *path;
+    char *cainfo_path;
 };
 
 int esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 6faf49f27b1c..9039075f2e6b 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -343,6 +343,9 @@ esxVI_CURL_Connect(esxVI_CURL *curl, esxUtil_ParsedUri *parsedUri)
                          parsedUri->proxy_port);
     }
 
+    if (parsedUri->cainfo_path)
+        curl_easy_setopt(curl->handle, CURLOPT_CAINFO, parsedUri->cainfo_path);
+
     if (virMutexInit(&curl->lock) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not initialize CURL mutex"));
-- 
2.49.0
Re: [PATCH 1/2] esx: Allow specifying different CA bundle for remote connections
Posted by Ján Tomko via Devel 2 months, 4 weeks ago
On a Monday in 2025, Martin Kletzander via Devel wrote:
>From: Martin Kletzander <mkletzan@redhat.com>
>
>Add new URI parameter which allows for using non-system CA certificates
>to verify remote peers.
>
>Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
>---
> docs/drvesx.rst    | 16 ++++++++++++++--
> src/esx/esx_util.c |  4 ++++
> src/esx/esx_util.h |  1 +
> src/esx/esx_vi.c   |  3 +++
> 4 files changed, 22 insertions(+), 2 deletions(-)
>
>diff --git a/docs/drvesx.rst b/docs/drvesx.rst
>index 13c2bc37e50b..37398a11ee09 100644
>--- a/docs/drvesx.rst
>+++ b/docs/drvesx.rst
>@@ -91,7 +91,7 @@ Multiple parameters are separated by ``&``.
>
> ::
>
>-   ?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456
>+   ?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456&cainfo_path=certs/ca-bundle.pem
>
> The driver understands the extra parameters shown below.
>
>@@ -146,6 +146,16 @@ The driver understands the extra parameters shown below.
> |                 |                             | ``port`` allows to override |
> |                 |                             | the default port 1080.      |
> +-----------------+-----------------------------+-----------------------------+
>+| ``cainfo_path`` | Path to a file with one     | The specified file will be  |
>+|                 | or more certificates        | used for verifying the      |
>+|                 |                             | remote host certificate     |
>+|                 |                             | instead of the default      |
>+|                 |                             | system one.                 |
>+|                 |                             | :since:`Since 11.5.0`.      |
>+|                 |                             | Does nothing if             |
>+|                 |                             | ``no_verify`` is set        |
>+|                 |                             | to ``1``                    |
>++-----------------+-----------------------------+-----------------------------+
>

Consider either 'cacert' (for the path to the certificate file) or
'capath' (if you go with the CURLOPT_CAPATH option and point it to a
directory). These two match curl's command line arguments.

(Or even ca_cert or ca_path, we mix underscores and nospaces in our uri
options)

IMO the 'info' part is redundant and the 'path' part might wrongly
suggest it's a $PATH-like variable instead of a path to a file.

For comparison, our tls transport, has a "pkipath" option which also
points to a directory.

> Authentication
> ~~~~~~~~~~~~~~
>@@ -181,8 +191,10 @@ error like this one:
>
>    error: internal error curl_easy_perform() returned an error: Peer certificate cannot be authenticated with known CA certificates (60)
>
>-Where are two ways to solve this problem:
>+Where are three ways to solve this problem:
>
>+-  Use the ``cainfo_path`` `Extra parameters`_ to point to a certificate bundle
>+   with the CA that signed the SSL certificate used on the ESX server.
> -  Use the ``no_verify=1`` `Extra parameters`_ to disable server
>    certificate verification.
> -  Generate new SSL certificates signed by a CA known to your client computer

Reviewed-by: Ján Tomko <jtomko@redhat.com>

Jano
Re: [PATCH 1/2] esx: Allow specifying different CA bundle for remote connections
Posted by Martin Kletzander via Devel 2 months, 4 weeks ago
On Wed, Jun 11, 2025 at 05:11:01PM +0200, Ján Tomko wrote:
>On a Monday in 2025, Martin Kletzander via Devel wrote:
>>From: Martin Kletzander <mkletzan@redhat.com>
>>
>>Add new URI parameter which allows for using non-system CA certificates
>>to verify remote peers.
>>
>>Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
>>---
>> docs/drvesx.rst    | 16 ++++++++++++++--
>> src/esx/esx_util.c |  4 ++++
>> src/esx/esx_util.h |  1 +
>> src/esx/esx_vi.c   |  3 +++
>> 4 files changed, 22 insertions(+), 2 deletions(-)
>>
>>diff --git a/docs/drvesx.rst b/docs/drvesx.rst
>>index 13c2bc37e50b..37398a11ee09 100644
>>--- a/docs/drvesx.rst
>>+++ b/docs/drvesx.rst
>>@@ -91,7 +91,7 @@ Multiple parameters are separated by ``&``.
>>
>> ::
>>
>>-   ?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456
>>+   ?no_verify=1&auto_answer=1&proxy=socks://example-proxy.com:23456&cainfo_path=certs/ca-bundle.pem
>>
>> The driver understands the extra parameters shown below.
>>
>>@@ -146,6 +146,16 @@ The driver understands the extra parameters shown below.
>> |                 |                             | ``port`` allows to override |
>> |                 |                             | the default port 1080.      |
>> +-----------------+-----------------------------+-----------------------------+
>>+| ``cainfo_path`` | Path to a file with one     | The specified file will be  |
>>+|                 | or more certificates        | used for verifying the      |
>>+|                 |                             | remote host certificate     |
>>+|                 |                             | instead of the default      |
>>+|                 |                             | system one.                 |
>>+|                 |                             | :since:`Since 11.5.0`.      |
>>+|                 |                             | Does nothing if             |
>>+|                 |                             | ``no_verify`` is set        |
>>+|                 |                             | to ``1``                    |
>>++-----------------+-----------------------------+-----------------------------+
>>
>
>Consider either 'cacert' (for the path to the certificate file) or
>'capath' (if you go with the CURLOPT_CAPATH option and point it to a
>directory). These two match curl's command line arguments.
>

I spent a significant time on this, let me explain:

CURLOPT_CAPATH:

  - takes a directory:

    - it might be confused with pkipath which uses the directory to also
      take a client certificate and client key which we definitely not
      want users to expect from this option

    - if libcurl is built against OpenSSL, the certificate directory must
      be prepared using c_rehash, which we would have to also specify in
      our docs, giving users too much info and being error-prone

  - apparently does not work on Windows (even though we probably do not
    care that much)

So that's why I wanted to use CURLOPT_CAINFO.  But using "path" in the
name could later conflict with possible request to use CURLOPT_CAPATH
specifically.

but I haven't considered cacert.  I like that.  I'll change it to
`cacert` then.  Thanks.

>(Or even ca_cert or ca_path, we mix underscores and nospaces in our uri
>options)
>
>IMO the 'info' part is redundant and the 'path' part might wrongly
>suggest it's a $PATH-like variable instead of a path to a file.
>
>For comparison, our tls transport, has a "pkipath" option which also
>points to a directory.
>
>> Authentication
>> ~~~~~~~~~~~~~~
>>@@ -181,8 +191,10 @@ error like this one:
>>
>>    error: internal error curl_easy_perform() returned an error: Peer certificate cannot be authenticated with known CA certificates (60)
>>
>>-Where are two ways to solve this problem:
>>+Where are three ways to solve this problem:
>>
>>+-  Use the ``cainfo_path`` `Extra parameters`_ to point to a certificate bundle
>>+   with the CA that signed the SSL certificate used on the ESX server.
>> -  Use the ``no_verify=1`` `Extra parameters`_ to disable server
>>    certificate verification.
>> -  Generate new SSL certificates signed by a CA known to your client computer
>
>Reviewed-by: Ján Tomko <jtomko@redhat.com>
>
>Jano