control: tags -1 patch

On 2016-09-21 22:59:56 [+0200], Sebastian Andrzej Siewior wrote:

> The patch attached has been sent upstream. It is untested and I kindly
> asked them to test it. I don't tag it patched until someone confirms
> that this works.

the patch attached was tested with remote-viewer + qemu.

> Kurt

Sebastian
>From 2e5a3f72b86a008758ca01bef1d2fc95c3168afd Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Fri, 30 Sep 2016 22:22:58 +0200
Subject: [PATCH] spice-gtk: get it compiled against openssl 1.1.0

and also 1.0.2h

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 spice-common/common/ssl_verify.c |  20 ++++--
 src/bio-gio.c                    | 143 ++++++++++++++++++++++++++++++---------
 src/spice-channel.c              |  24 ++++---
 3 files changed, 138 insertions(+), 49 deletions(-)

diff --git a/spice-common/common/ssl_verify.c b/spice-common/common/ssl_verify.c
index 601252e..b544aad 100644
--- a/spice-common/common/ssl_verify.c
+++ b/spice-common/common/ssl_verify.c
@@ -33,6 +33,14 @@
 #include <string.h>
 #include <gio/gio.h>
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+
+static const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+	return x->data;
+}
+#endif
+
 static int verify_pubkey(X509* cert, const char *key, size_t key_size)
 {
     EVP_PKEY* cert_pubkey = NULL;
@@ -182,10 +190,10 @@ static int verify_hostname(X509* cert, const char *hostname)
             const GENERAL_NAME* name = sk_GENERAL_NAME_value(subject_alt_names, i);
             if (name->type == GEN_DNS) {
                 found_dns_name = 1;
-                if (_gnutls_hostname_compare((char *)ASN1_STRING_data(name->d.dNSName),
+                if (_gnutls_hostname_compare((char *)ASN1_STRING_get0_data(name->d.dNSName),
                                              ASN1_STRING_length(name->d.dNSName),
                                              hostname)) {
-                    spice_debug("alt name match=%s", ASN1_STRING_data(name->d.dNSName));
+                    spice_debug("alt name match=%s", ASN1_STRING_get0_data(name->d.dNSName));
                     GENERAL_NAMES_free(subject_alt_names);
                     return 1;
                 }
@@ -208,11 +216,11 @@ static int verify_hostname(X509* cert, const char *hostname)
                 alt_ip_len = ASN1_STRING_length(name->d.iPAddress);
 
                 if ((ip_len == alt_ip_len) &&
-                   (memcmp(ASN1_STRING_data(name->d.iPAddress), ip_binary, ip_len)) == 0) {
+                   (memcmp(ASN1_STRING_get0_data(name->d.iPAddress), ip_binary, ip_len)) == 0) {
                     GInetAddress * alt_ip = NULL;
                     gchar * alt_ip_string = NULL;
 
-                    alt_ip = g_inet_address_new_from_bytes(ASN1_STRING_data(name->d.iPAddress),
+                    alt_ip = g_inet_address_new_from_bytes(ASN1_STRING_get0_data(name->d.iPAddress),
                                                            g_inet_address_get_family(ip));
                     alt_ip_string = g_inet_address_to_string(alt_ip);
                     spice_debug("alt name IP match=%s", alt_ip_string);
@@ -253,10 +261,10 @@ static int verify_hostname(X509* cert, const char *hostname)
                 continue;
             }
 
-            if (_gnutls_hostname_compare((char*)ASN1_STRING_data(cn_asn1),
+            if (_gnutls_hostname_compare((char*)ASN1_STRING_get0_data(cn_asn1),
                                          ASN1_STRING_length(cn_asn1),
                                          hostname)) {
-                spice_debug("common name match=%s", (char*)ASN1_STRING_data(cn_asn1));
+                spice_debug("common name match=%s", (char*)ASN1_STRING_get0_data(cn_asn1));
                 cn_match = 1;
                 break;
             }
diff --git a/src/bio-gio.c b/src/bio-gio.c
index b310c97..701df93 100644
--- a/src/bio-gio.c
+++ b/src/bio-gio.c
@@ -23,21 +23,95 @@
 #include "spice-util.h"
 #include "bio-gio.h"
 
-typedef struct bio_gsocket_method {
-    BIO_METHOD method;
-    GIOStream *stream;
-} bio_gsocket_method;
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static BIO_METHOD one_static_bio;
 
-#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 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;
+}
+
+static int BIO_get_new_index(void)
+{
+    return 128;
+}
+
+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(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret;
+
+    switch (cmd) {
+    case BIO_CTRL_FLUSH:
+        ret = 1;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    return ret;
+}
 
 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_get_data(bio));
+    ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(stream),
                                                      in, inl, NULL, &error);
     BIO_clear_retry_flags(bio);
 
@@ -53,10 +127,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_get_data(bio));
+    ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(stream),
                                                    out, outl, NULL, &error);
     BIO_clear_retry_flags(bio);
 
@@ -70,17 +146,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 +156,35 @@ static int bio_gio_puts(BIO *bio, const char *str)
     return ret;
 }
 
+static BIO_METHOD *bio_gio_method;
+
 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_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
-    bio_method->method = *bio->method;
-    bio_method->stream = stream;
-
-    bio->method->destroy(bio);
-    bio->method = (BIO_METHOD*)bio_method;
+    BIO *bio;
+
+    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->method->bwrite = bio_gio_write;
-    bio->method->bread = bio_gio_read;
-    bio->method->bputs = bio_gio_puts;
-    bio->method->destroy = bio_gio_destroy;
+    bio = BIO_new(bio_gio_method);
+    if (!bio)
+        return NULL;
 
+    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 0eb0e61..748cb67 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
@@ -1138,7 +1147,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);
@@ -2329,17 +2338,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;
@@ -2349,13 +2353,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);
@@ -2363,11 +2367,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

Reply via email to