[Spice-commits] 3 commits - src/bio-gio.c src/spice-channel.c

Christophe Fergau teuf at kemper.freedesktop.org
Fri Jan 13 10:12:30 UTC 2017


 src/bio-gio.c       |  139 +++++++++++++++++++++++++++++++++++++++-------------
 src/spice-channel.c |   24 +++++---
 2 files changed, 120 insertions(+), 43 deletions(-)

New commits:
commit 97bd84313597d7c37c637c29e75f8862fcab1940
Author: Sebastian Andrzej Siewior <sebastian at breakpoint.cc>
Date:   Wed Nov 30 16:34:59 2016 +0100

    ssl: Use accessors rather than direct struct access
    
    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.

diff --git a/src/bio-gio.c b/src/bio-gio.c
index 0f8b415..9358fae 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,35 @@ 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) {
+        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);
commit 498f5369203d73026e9fb3929fd19a358d76a152
Author: Sebastian Andrzej Siewior <sebastian at breakpoint.cc>
Date:   Wed Oct 26 17:31:27 2016 +0200

    ssl: Rework our custom BIO type
    
    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.

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;
 }
commit 3ec02a76ea5e0bea4aa3d3cc81846a9063c26d7a
Author: Sebastian Andrzej Siewior <sebastian at breakpoint.cc>
Date:   Wed Oct 26 12:55:03 2016 +0200

    ssl: Stop creating our own X509_LOOKUP_METHOD
    
    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 <cfergeau at redhat.com>
    Acked-by: Pavel Grunt <pgrunt at redhat.com>

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++;
             }
         }


More information about the Spice-commits mailing list