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