Attention is currently required from: Arne Schwabe, Frank Lichtenheld, Gert 
Doering, Yuriy Darnobyt, [email protected].

Hello Arne Schwabe, Selva Nair,

I'd like you to reexamine a change. Please visit

    https://gerrit.openvpn.net/c/openvpn/+/2148?usp=email

to look at the new patch set (#6).

The change is no longer submittable: checks~ChecksSubmitRule is unsatisfied now.


Change subject: Implement multiline responses for pkcs11-id commands
......................................................................

Implement multiline responses for pkcs11-id commands

Responses to the management interface commands pkcs11-id-[get|count] did
not follow the standard syntax, but instead looked like notifications.

Introduce a new management interface version so that clients announcing
versions >= 7 will receive responses in the new format while keeping
compatibility for older client versions.

If a client announces a management version >= 7 the responses conform to
the common multiline + END syntax. At the same time, it is now possible
to query all PKCS#11 ids using "all" or a range from "start" to
"end" - 1. Failures to retrieve an id will return a partial response
terminated by an "ERROR" message including the erroneous index.
The response format for pkcs11-id-get was changed to return a comma
separated list (index,id,cert_blob) which is easier to parse.

Change-Id: I09e55085cde6dbc0040e111a42128527d59832b8
Signed-off-by: Marvin Wunderlich <[email protected]>
---
M doc/management-notes.txt
M src/openvpn/manage.c
M src/openvpn/manage.h
3 files changed, 164 insertions(+), 21 deletions(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/48/2148/6

diff --git a/doc/management-notes.txt b/doc/management-notes.txt
index 6c798c0..42ea644 100644
--- a/doc/management-notes.txt
+++ b/doc/management-notes.txt
@@ -617,23 +617,109 @@
 COMMAND -- pkcs11-id-count  (OpenVPN 2.1 or higher)
 ---------------------------------------------------

-Retrieve available number of certificates.
+Retrieve available number of PKCS#11 certificates.
+
+For management client versions <7:
+
+     pkcs11-id-count
+
+The reply is ">PKCS11ID-COUNT:<count>".

 Example:

      pkcs11-id-count
      >PKCS11ID-COUNT:5

+For management client versions >= 7:
+
+     pkcs11-id-count
+
+The reply is a decimal count followed by "END" on a separate line.
+
+Example:
+
+     pkcs11-id-count
+     5
+     END
+
 COMMAND -- pkcs11-id-get  (OpenVPN 2.1 or higher)
 -------------------------------------------------

+Retrieve PKCS#11 certificates.
+
+For management client versions < 7:
+
+  pkcs11-id-get <index>
+
 Retrieve certificate by index, the ID string should be provided
 as PKCS#11 identity, the blob is a base 64 encoded certificate.

 Example:

      pkcs11-id-get 1
-     PKCS11ID-ENTRY:'1', ID:'<snip>', BLOB:'<snip>'
+     >PKCS11ID-ENTRY:'1', ID:'<id>', BLOB:'<blob>'
+
+For management client versions >= 7:
+
+  pkcs11-id-get <index>
+  pkcs11-id-get <start> <end>
+  pkcs11-id-get all
+
+Retrieve a single PKCS#11 certificate at index <index> or multiple
+PKCS#11 certificates from index <start> to <end>-1. Alternatively
+<start> = "all" retrieves all PKCS#11 certificates. A comma separated
+list including index, PKCS#11 id and the base 64 encoded certificate
+will be returned. If any id retrieval results in a failure, the returned
+list will be partial and terminated by "ERROR: .." instead of "END".
+The "ERROR" message will include the index of failure.
+
+Example 1:
+
+  Management interface client sends:
+
+    pkcs11-id-get 1
+
+  OpenVPN daemon responds with:
+
+    1,<id>,<blob>
+    END
+
+Example 2:
+
+  Management interface client sends:
+
+    pkcs11-id-get 1 3
+
+  OpenVPN daemon responds with:
+
+    1,<id_a>,<blob_a>
+    2,<id_b>,<blob_b>
+    END
+
+Example 3:
+
+  Management interface client sends:
+
+    pkcs11-id-get all
+
+  OpenVPN daemon with 3 PKCS#11 certificates responds with:
+
+    0,<id_a>,<blob_a>
+    1,<id_b>,<blob_b>
+    2,<id_c>,<blob_c>
+    END
+
+Example 4:
+
+  Management interface client sends:
+
+    pkcs11-id-get all
+
+  OpenVPN daemon with 3 PKCS#11 certificates fails to retrieve index 1
+
+    0,<id_a>,<blob_a>
+    ERROR: Failed to load PKCS#11 id at index: 1
+

 COMMAND -- client-auth  (OpenVPN 2.1 or higher)
 -----------------------------------------------
@@ -1240,7 +1326,7 @@
     "ERROR: [text]".

 (2) For commands which print multiple lines of output,
-    the last line will be "END".
+    the last line will be "END" or "ERROR: [text]".

 (3) Real-time messages will be in the form ">[source]:[text]",
     where source is "CLIENT", "ECHO", "FATAL", "HOLD", "INFO", "LOG",
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 58f63e6..f00eb30 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -74,6 +74,7 @@
     MCV_USERNAME_ONLY = 4,
     MCV_MULTILINE_PASSWORD = 5,
     MCV_PREFERRED_USERNAME = 6,
+    MCV_MULTILINE_PKCS11_RESPONSE = 7,
 };

 struct management *management; /* GLOBAL */
@@ -120,7 +121,8 @@
     msg(M_CLIENT, "pid                    : Show process ID of the current 
OpenVPN process.");
 #ifdef ENABLE_PKCS11
     msg(M_CLIENT, "pkcs11-id-count        : Get number of available PKCS#11 
identities.");
-    msg(M_CLIENT, "pkcs11-id-get index    : Get PKCS#11 identity at index.");
+    msg(M_CLIENT, "pkcs11-id-get i|all [j] : Get PKCS#11 identity at index = 
i.");
+    msg(M_CLIENT, "                          For version >= 7 also i to j-1 or 
all.");
 #endif
     msg(M_CLIENT, "client-auth CID KID    : Authenticate client-id/key-id 
CID/KID (MULTILINE)");
     msg(M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id 
CID/KID");
@@ -894,26 +896,81 @@
 static void
 man_pkcs11_id_count(const struct management *man)
 {
-    msg(M_CLIENT, ">PKCS11ID-COUNT:%d", pkcs11_management_id_count());
-}
-
-static void
-man_pkcs11_id_get(struct management *man, const int index)
-{
-    char *id = NULL;
-    char *base64 = NULL;
-
-    if (pkcs11_management_id_get(index, &id, &base64))
+    if (man->connection.client_version >= MCV_MULTILINE_PKCS11_RESPONSE)
     {
-        msg(M_CLIENT, ">PKCS11ID-ENTRY:'%d', ID:'%s', BLOB:'%s'", index, id, 
base64);
+        msg(M_CLIENT, "%d", pkcs11_management_id_count());
+        msg(M_CLIENT, "END");
     }
     else
     {
-        msg(M_CLIENT, ">PKCS11ID-ENTRY:'%d'", index);
+        msg(M_CLIENT, ">PKCS11ID-COUNT:%d", pkcs11_management_id_count());
+    }
+}
+
+static void
+man_pkcs11_id_get(struct management *man, const char *p1, const char *p2)
+{
+    ASSERT(p1);
+
+    if ((streq(p1, "all") || p2 != NULL) && man->connection.client_version < 
MCV_MULTILINE_PKCS11_RESPONSE)
+    {
+        msg(M_CLIENT, "ERROR: Listing multiple ids is only supported for 
version >= %d", MCV_MULTILINE_PKCS11_RESPONSE);
+        return;
     }

-    free(id);
-    free(base64);
+    if (man->connection.client_version >= MCV_MULTILINE_PKCS11_RESPONSE)
+    {
+        unsigned int count = pkcs11_management_id_count();
+        unsigned int from = (unsigned int)atoi(p1);
+        unsigned int to = p2 ? (unsigned int)atoi(p2) : from + 1;
+
+        if (streq(p1, "all"))
+        {
+            from = 0;
+            to = count;
+        }
+
+        bool error = false;
+        for (unsigned int i = from; i < min_uint(to, count) && !error; i++)
+        {
+            char *id = NULL;
+            char *base64 = NULL;
+
+            if (pkcs11_management_id_get(i, &id, &base64))
+            {
+                msg(M_CLIENT, "%u,%s,%s", i, id, base64);
+            }
+            else
+            {
+                error = true;
+                msg(M_CLIENT, "ERROR: Failed to load PKCS#11 id at index: %u", 
i);
+            }
+            free(id);
+            free(base64);
+        }
+        if (!error)
+        {
+            msg(M_CLIENT, "END");
+        }
+    }
+    else
+    {
+        int index = atoi(p1);
+
+        char *id = NULL;
+        char *base64 = NULL;
+
+        if (pkcs11_management_id_get(index, &id, &base64))
+        {
+            msg(M_CLIENT, ">PKCS11ID-ENTRY:'%d', ID:'%s', BLOB:'%s'", index, 
id, base64);
+        }
+        else
+        {
+            msg(M_CLIENT, ">PKCS11ID-ENTRY:'%d'", index);
+        }
+        free(id);
+        free(base64);
+    }
 }

 #endif /* ifdef ENABLE_PKCS11 */
@@ -1838,9 +1895,9 @@
     }
     else if (streq(p[0], "pkcs11-id-get"))
     {
-        if (man_need(p, 1, 0))
+        if (man_need(p, 1, MN_AT_LEAST))
         {
-            man_pkcs11_id_get(man, atoi(p[1]));
+            man_pkcs11_id_get(man, p[1], p[2]);
         }
     }
 #endif
diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index 82c0caa..1d2aff1 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -50,7 +50,7 @@
 #include "socket_util.h"
 #include "mroute.h"

-#define MANAGEMENT_VERSION                  6
+#define MANAGEMENT_VERSION                  7
 #define MANAGEMENT_N_PASSWORD_RETRIES       3
 #define MANAGEMENT_LOG_HISTORY_INITIAL_SIZE 100
 #define MANAGEMENT_ECHO_BUFFER_SIZE         100

--
To view, visit https://gerrit.openvpn.net/c/openvpn/+/2148?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.openvpn.net/settings?usp=email

Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I09e55085cde6dbc0040e111a42128527d59832b8
Gerrit-Change-Number: 2148
Gerrit-PatchSet: 6
Gerrit-Owner: [email protected]
Gerrit-Reviewer: Arne Schwabe <[email protected]>
Gerrit-Reviewer: Selva Nair <[email protected]>
Gerrit-CC: Frank Lichtenheld <[email protected]>
Gerrit-CC: Gert Doering <[email protected]>
Gerrit-CC: Yuriy Darnobyt <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: [email protected]
Gerrit-Attention: Arne Schwabe <[email protected]>
Gerrit-Attention: Gert Doering <[email protected]>
Gerrit-Attention: Frank Lichtenheld <[email protected]>
Gerrit-Attention: Yuriy Darnobyt <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to