Source: spice-gtk
Version: 0.33-3.1
Severity: important
Tags: patch

#828554 was originally filed because of missing OpenSSL 1.1.0
compatibility for spice-gtk, and was fixed with an NMU including a
proposed patch as 0.33-3.1 . this patch has been replace upstream with
a patch series (current and probably final v2, see [1]).

the original patch contained in >= 0.33-3.1 breaks a certain use case
(when compiled against libssl1.1.0) where Spice is using TLS only (see
[2,3] for details). building spice-gtk 0.33-3.2 with the old patch
replaced by the patch series fixes the issue.

attached you find the diff between the patch from #828554 and the v2, as
well as the complete patch series, according to upstream this should be
the final version.

1: https://lists.freedesktop.org/archives/spice-devel/2017-January/034919.html
2: https://lists.freedesktop.org/archives/spice-devel/2017-January/034932.html
3: https://bugzilla.proxmox.com/show_bug.cgi?id=1243
From: Christophe Fergeau <[email protected]>
To: [email protected]
Date: Wed, 11 Jan 2017 10:50:31 +0100
Message-Id: <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Subject: [Spice-devel] [spice-gtk v2 1/3] ssl: Stop creating our own
 X509_LOOKUP_METHOD
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=utf-8

From: Sebastian Andrzej Siewior <[email protected]>

OpenSSL 1.1.0 does not seem to provide API to do that anymore.

There is no need to create a custom lookup to begin with. This method
here has no callbacks implemented and is doing nothing. The way I
understand it, it is used to retrieve a `lookup' object which provides a
certificate store.  The SSL ctx provides also such a store.

Acked-by: Christophe Fergeau <[email protected]>
Acked-by: Pavel Grunt <[email protected]>
---
 src/spice-channel.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/src/spice-channel.c b/src/spice-channel.c
index 95662f3..6a911a6 100644
--- a/src/spice-channel.c
+++ b/src/spice-channel.c
@@ -2352,17 +2352,12 @@ static gboolean spice_channel_delayed_unref(gpointer data)
     return FALSE;
 }
 
-static X509_LOOKUP_METHOD spice_x509_mem_lookup = {
-    "spice_x509_mem_lookup",
-    0
-};
-
 static int spice_channel_load_ca(SpiceChannel *channel)
 {
     SpiceChannelPrivate *c = channel->priv;
     STACK_OF(X509_INFO) *inf;
     X509_INFO *itmp;
-    X509_LOOKUP *lookup;
+    X509_STORE *store;
     BIO *in;
     int i, count = 0;
     guint8 *ca;
@@ -2372,13 +2367,13 @@ static int spice_channel_load_ca(SpiceChannel *channel)
 
     g_return_val_if_fail(c->ctx != NULL, 0);
 
-    lookup = X509_STORE_add_lookup(c->ctx->cert_store, &spice_x509_mem_lookup);
     ca_file = spice_session_get_ca_file(c->session);
     spice_session_get_ca(c->session, &ca, &size);
 
     CHANNEL_DEBUG(channel, "Load CA, file: %s, data: %p", ca_file, ca);
 
     if (ca != NULL) {
+        store = SSL_CTX_get_cert_store(c->ctx);
         in = BIO_new_mem_buf(ca, size);
         inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
         BIO_free(in);
@@ -2386,11 +2381,11 @@ static int spice_channel_load_ca(SpiceChannel *channel)
         for (i = 0; i < sk_X509_INFO_num(inf); i++) {
             itmp = sk_X509_INFO_value(inf, i);
             if (itmp->x509) {
-                X509_STORE_add_cert(lookup->store_ctx, itmp->x509);
+                X509_STORE_add_cert(store, itmp->x509);
                 count++;
             }
             if (itmp->crl) {
-                X509_STORE_add_crl(lookup->store_ctx, itmp->crl);
+                X509_STORE_add_crl(store, itmp->crl);
                 count++;
             }
         }
-- 
2.9.3

_______________________________________________
Spice-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/spice-devel
From: Christophe Fergeau <[email protected]>
To: [email protected]
Date: Wed, 11 Jan 2017 10:50:32 +0100
Message-Id: <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Subject: [Spice-devel] [spice-gtk v2 2/3] ssl: Rework our custom BIO type
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=utf-8

From: Sebastian Andrzej Siewior <[email protected]>

This commit changes to an actual new BIO method rather than reusing an
existing BIO method, and overriding only the fields that we need.
The approach before this commit would be causing issues with OpenSSL
1.1.0 as some of the fields we access have become opaque.
---
 src/bio-gio.c | 57 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 29 deletions(-)

diff --git a/src/bio-gio.c b/src/bio-gio.c
index b310c97..0f8b415 100644
--- a/src/bio-gio.c
+++ b/src/bio-gio.c
@@ -23,21 +23,22 @@
 #include "spice-util.h"
 #include "bio-gio.h"
 
-typedef struct bio_gsocket_method {
-    BIO_METHOD method;
-    GIOStream *stream;
-} bio_gsocket_method;
-
-#define BIO_GET_GSOCKET(bio)  (((bio_gsocket_method*)bio->method)->gsocket)
-#define BIO_GET_ISTREAM(bio)  (g_io_stream_get_input_stream(((bio_gsocket_method*)bio->method)->stream))
-#define BIO_GET_OSTREAM(bio)  (g_io_stream_get_output_stream(((bio_gsocket_method*)bio->method)->stream))
+static long bio_gio_ctrl(G_GNUC_UNUSED BIO *b,
+                         int cmd,
+                         G_GNUC_UNUSED long num,
+                         G_GNUC_UNUSED void *ptr)
+{
+    return (cmd == BIO_CTRL_FLUSH);
+}
 
 static int bio_gio_write(BIO *bio, const char *in, int inl)
 {
+    GOutputStream *stream;
     gssize ret;
     GError *error = NULL;
 
-    ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(BIO_GET_OSTREAM(bio)),
+    stream = g_io_stream_get_output_stream(bio->ptr);
+    ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(stream),
                                                      in, inl, NULL, &error);
     BIO_clear_retry_flags(bio);
 
@@ -53,10 +54,12 @@ static int bio_gio_write(BIO *bio, const char *in, int inl)
 
 static int bio_gio_read(BIO *bio, char *out, int outl)
 {
+    GInputStream *stream;
     gssize ret;
     GError *error = NULL;
 
-    ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(BIO_GET_ISTREAM(bio)),
+    stream = g_io_stream_get_input_stream(bio->ptr);
+    ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(stream),
                                                    out, outl, NULL, &error);
     BIO_clear_retry_flags(bio);
 
@@ -70,17 +73,6 @@ static int bio_gio_read(BIO *bio, char *out, int outl)
     return ret;
 }
 
-static int bio_gio_destroy(BIO *bio)
-{
-    if (bio == NULL || bio->method == NULL)
-        return 0;
-
-    SPICE_DEBUG("bio gsocket destroy");
-    g_clear_pointer(&bio->method, g_free);
-
-    return 1;
-}
-
 static int bio_gio_puts(BIO *bio, const char *str)
 {
     int n, ret;
@@ -91,23 +83,30 @@ static int bio_gio_puts(BIO *bio, const char *str)
     return ret;
 }
 
+#define BIO_TYPE_START 128
+
 G_GNUC_INTERNAL
 BIO* bio_new_giostream(GIOStream *stream)
 {
-    // TODO: make an actual new BIO type, or just switch to GTls already...
-    BIO *bio = BIO_new_socket(-1, BIO_NOCLOSE);
+    BIO *bio;
+    static BIO_METHOD bio_gio_method;
 
-    bio_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
-    bio_method->method = *bio->method;
-    bio_method->stream = stream;
+    if (bio_gio_method.name == NULL) {
+        bio_gio_method.type = BIO_TYPE_START | BIO_TYPE_SOURCE_SINK;
+        bio_gio_method.name = "gio stream";
+    }
 
-    bio->method->destroy(bio);
-    bio->method = (BIO_METHOD*)bio_method;
+    bio = BIO_new(&bio_gio_method);
+    if (!bio)
+        return NULL;
 
     bio->method->bwrite = bio_gio_write;
     bio->method->bread = bio_gio_read;
     bio->method->bputs = bio_gio_puts;
-    bio->method->destroy = bio_gio_destroy;
+    bio->method->ctrl = bio_gio_ctrl;
+
+    bio->init = 1;
+    bio->ptr = stream;
 
     return bio;
 }
-- 
2.9.3

_______________________________________________
Spice-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/spice-devel
From: Christophe Fergeau <[email protected]>
To: [email protected]
Date: Wed, 11 Jan 2017 10:50:33 +0100
Message-Id: <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Subject: [Spice-devel] [spice-gtk v2 3/3] ssl: Use accessors rather than
 direct struct access
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=utf-8

From: Sebastian Andrzej Siewior <[email protected]>

In OpenSSL 1.1.0, the struct fields are private so we can no longer
directly access them.

The accessors are not available in previous OpenSSL releases, so we need
to add compat helpers.
---
 src/bio-gio.c       | 108 ++++++++++++++++++++++++++++++++++++++++++++--------
 src/spice-channel.c |  11 +++++-
 2 files changed, 102 insertions(+), 17 deletions(-)

diff --git a/src/bio-gio.c b/src/bio-gio.c
index 0f8b415..ef47cd3 100644
--- a/src/bio-gio.c
+++ b/src/bio-gio.c
@@ -23,6 +23,75 @@
 #include "spice-util.h"
 #include "bio-gio.h"
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static BIO_METHOD one_static_bio;
+
+static int BIO_meth_set_read(BIO_METHOD *biom,
+                             int (*bread) (BIO *, char *, int))
+{
+    biom->bread = bread;
+    return 1;
+}
+
+static int BIO_meth_set_write(BIO_METHOD *biom,
+                              int (*bwrite) (BIO *, const char *, int))
+{
+    biom->bwrite = bwrite;
+    return 1;
+}
+
+static int BIO_meth_set_puts(BIO_METHOD *biom,
+                             int (*bputs) (BIO *, const char *))
+{
+    biom->bputs = bputs;
+    return 1;
+}
+
+static int BIO_meth_set_ctrl(BIO_METHOD *biom,
+                             long (*ctrl) (BIO *, int, long, void *))
+{
+    biom->ctrl = ctrl;
+    return 1;
+}
+
+#define BIO_TYPE_START 128
+
+static int BIO_get_new_index(void)
+{
+    static int bio_index = BIO_TYPE_START;
+    return bio_index++;
+}
+
+static void BIO_set_init(BIO *a, int init)
+{
+	a->init = init;
+}
+
+static void BIO_set_data(BIO *a, void *ptr)
+{
+    a->ptr = ptr;
+}
+
+static void *BIO_get_data(BIO *a)
+{
+    return a->ptr;
+}
+
+static BIO_METHOD *BIO_meth_new(int type, const char *name)
+{
+    BIO_METHOD *biom = &one_static_bio;
+
+    biom->type = type;
+    biom->name = name;
+    return biom;
+}
+
+static void BIO_meth_free(BIO_METHOD *biom)
+{
+}
+
+#endif
+
 static long bio_gio_ctrl(G_GNUC_UNUSED BIO *b,
                          int cmd,
                          G_GNUC_UNUSED long num,
@@ -37,7 +106,7 @@ static int bio_gio_write(BIO *bio, const char *in, int inl)
     gssize ret;
     GError *error = NULL;
 
-    stream = g_io_stream_get_output_stream(bio->ptr);
+    stream = g_io_stream_get_output_stream(BIO_get_data(bio));
     ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(stream),
                                                      in, inl, NULL, &error);
     BIO_clear_retry_flags(bio);
@@ -58,7 +127,7 @@ static int bio_gio_read(BIO *bio, char *out, int outl)
     gssize ret;
     GError *error = NULL;
 
-    stream = g_io_stream_get_input_stream(bio->ptr);
+    stream = g_io_stream_get_input_stream(BIO_get_data(bio));
     ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(stream),
                                                    out, outl, NULL, &error);
     BIO_clear_retry_flags(bio);
@@ -83,30 +152,37 @@ static int bio_gio_puts(BIO *bio, const char *str)
     return ret;
 }
 
-#define BIO_TYPE_START 128
+static BIO_METHOD *bio_gio_method;
 
 G_GNUC_INTERNAL
 BIO* bio_new_giostream(GIOStream *stream)
 {
     BIO *bio;
-    static BIO_METHOD bio_gio_method;
 
-    if (bio_gio_method.name == NULL) {
-        bio_gio_method.type = BIO_TYPE_START | BIO_TYPE_SOURCE_SINK;
-        bio_gio_method.name = "gio stream";
+    if (!bio_gio_method) {
+        int index = BIO_get_new_index();
+        g_warning("index: %i", index);
+        bio_gio_method = BIO_meth_new(BIO_get_new_index() |
+                                      BIO_TYPE_SOURCE_SINK,
+                                      "gio stream");
+        if (!bio_gio_method)
+            return NULL;
+
+        if (!BIO_meth_set_write(bio_gio_method, bio_gio_write) ||
+            !BIO_meth_set_read(bio_gio_method, bio_gio_read) ||
+            !BIO_meth_set_puts(bio_gio_method, bio_gio_puts) ||
+            !BIO_meth_set_ctrl(bio_gio_method, bio_gio_ctrl)) {
+            BIO_meth_free(bio_gio_method);
+            bio_gio_method = NULL;
+            return NULL;
+        }
     }
 
-    bio = BIO_new(&bio_gio_method);
+    bio = BIO_new(bio_gio_method);
     if (!bio)
         return NULL;
 
-    bio->method->bwrite = bio_gio_write;
-    bio->method->bread = bio_gio_read;
-    bio->method->bputs = bio_gio_puts;
-    bio->method->ctrl = bio_gio_ctrl;
-
-    bio->init = 1;
-    bio->ptr = stream;
-
+    BIO_set_init(bio, 1);
+    BIO_set_data(bio, stream);
     return bio;
 }
diff --git a/src/spice-channel.c b/src/spice-channel.c
index 6a911a6..6556db3 100644
--- a/src/spice-channel.c
+++ b/src/spice-channel.c
@@ -55,6 +55,15 @@ static void spice_channel_reset_capabilities(SpiceChannel *channel);
 static void spice_channel_send_migration_handshake(SpiceChannel *channel);
 static gboolean channel_connect(SpiceChannel *channel, gboolean tls);
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+    if (pkey->type != EVP_PKEY_RSA) {
+        return NULL;
+    }
+    return pkey->pkey.rsa;
+}
+#endif
 /**
  * SECTION:spice-channel
  * @short_description: the base channel class
@@ -1161,7 +1170,7 @@ static SpiceChannelEvent spice_channel_send_spice_ticket(SpiceChannel *channel)
     pubkey = d2i_PUBKEY_bio(bioKey, NULL);
     g_return_val_if_fail(pubkey != NULL, ret);
 
-    rsa = pubkey->pkey.rsa;
+    rsa = EVP_PKEY_get0_RSA(pubkey);
     nRSASize = RSA_size(rsa);
 
     encrypted = g_alloca(nRSASize);
-- 
2.9.3

_______________________________________________
Spice-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/spice-devel
diff --git a/src/bio-gio.c b/src/bio-gio.c
index aa8ddac..ef47cd3 100644
--- a/src/bio-gio.c
+++ b/src/bio-gio.c
@@ -47,15 +47,24 @@ static int BIO_meth_set_puts(BIO_METHOD *biom,
     return 1;
 }
 
-static int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
+static int BIO_meth_set_ctrl(BIO_METHOD *biom,
+                             long (*ctrl) (BIO *, int, long, void *))
 {
-    biom->destroy = destroy;
+    biom->ctrl = ctrl;
     return 1;
 }
 
-static int BIO_get_new_index()
+#define BIO_TYPE_START 128
+
+static int BIO_get_new_index(void)
+{
+    static int bio_index = BIO_TYPE_START;
+    return bio_index++;
+}
+
+static void BIO_set_init(BIO *a, int init)
 {
-    return 128;
+       a->init = init;
 }
 
 static void BIO_set_data(BIO *a, void *ptr)
@@ -77,19 +86,27 @@ static BIO_METHOD *BIO_meth_new(int type, const char *name)
     return biom;
 }
 
-void BIO_meth_free(BIO_METHOD *biom)
+static void BIO_meth_free(BIO_METHOD *biom)
 {
 }
 
 #endif
 
+static long bio_gio_ctrl(G_GNUC_UNUSED BIO *b,
+                         int cmd,
+                         G_GNUC_UNUSED long num,
+                         G_GNUC_UNUSED void *ptr)
+{
+    return (cmd == BIO_CTRL_FLUSH);
+}
+
 static int bio_gio_write(BIO *bio, const char *in, int inl)
 {
-    GIOStream *stream;
+    GOutputStream *stream;
     gssize ret;
     GError *error = NULL;
 
-    stream = BIO_get_data(bio);
+    stream = g_io_stream_get_output_stream(BIO_get_data(bio));
     ret = 
g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(stream),
                                                      in, inl, NULL, &error);
     BIO_clear_retry_flags(bio);
@@ -106,11 +123,11 @@ static int bio_gio_write(BIO *bio, const char *in, int 
inl)
 
 static int bio_gio_read(BIO *bio, char *out, int outl)
 {
-    GIOStream *stream;
+    GInputStream *stream;
     gssize ret;
     GError *error = NULL;
 
-    stream = BIO_get_data(bio);
+    stream = g_io_stream_get_input_stream(BIO_get_data(bio));
     ret = 
g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(stream),
                                                    out, outl, NULL, &error);
     BIO_clear_retry_flags(bio);
@@ -125,19 +142,6 @@ static int bio_gio_read(BIO *bio, char *out, int outl)
     return ret;
 }
 
-static int bio_gio_destroy(BIO *bio)
-{
-    if (bio == NULL )
-        return 0;
-
-    SPICE_DEBUG("bio gsocket destroy");
-
-    /* XXX DO WE NEED to free GIOStream *stream ? */
-
-    BIO_set_data(bio, NULL);
-    return 1;
-}
-
 static int bio_gio_puts(BIO *bio, const char *str)
 {
     int n, ret;
@@ -156,13 +160,18 @@ BIO* bio_new_giostream(GIOStream *stream)
     BIO *bio;
 
     if (!bio_gio_method) {
-        bio_gio_method = BIO_meth_new(BIO_get_new_index(), "gio stream");
+        int index = BIO_get_new_index();
+        g_warning("index: %i", index);
+        bio_gio_method = BIO_meth_new(BIO_get_new_index() |
+                                      BIO_TYPE_SOURCE_SINK,
+                                      "gio stream");
         if (!bio_gio_method)
             return NULL;
-        if (!BIO_meth_set_write(bio_gio_method, bio_gio_write)
-            || !BIO_meth_set_read(bio_gio_method, bio_gio_read)
-            || !BIO_meth_set_puts(bio_gio_method, bio_gio_puts)
-            || !BIO_meth_set_destroy(bio_gio_method, bio_gio_destroy)) {
+
+        if (!BIO_meth_set_write(bio_gio_method, bio_gio_write) ||
+            !BIO_meth_set_read(bio_gio_method, bio_gio_read) ||
+            !BIO_meth_set_puts(bio_gio_method, bio_gio_puts) ||
+            !BIO_meth_set_ctrl(bio_gio_method, bio_gio_ctrl)) {
             BIO_meth_free(bio_gio_method);
             bio_gio_method = NULL;
             return NULL;
@@ -172,6 +181,8 @@ BIO* bio_new_giostream(GIOStream *stream)
     bio = BIO_new(bio_gio_method);
     if (!bio)
         return NULL;
+
+    BIO_set_init(bio, 1);
     BIO_set_data(bio, stream);
     return bio;
 }

Reply via email to