mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-07 18:11:43 +00:00
openssl: recreate the OpenSSL 1.1 BIO interface for older versions
We want to program against the interface, so recreate it when we compile against pre-1.1 versions.
This commit is contained in:
parent
feb330d50d
commit
f15eedb3a3
@ -13,6 +13,7 @@
|
|||||||
#include "posix.h"
|
#include "posix.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "socket_stream.h"
|
#include "socket_stream.h"
|
||||||
|
#include "openssl_stream.h"
|
||||||
#include "netops.h"
|
#include "netops.h"
|
||||||
#include "git2/transport.h"
|
#include "git2/transport.h"
|
||||||
#include "git2/sys/openssl.h"
|
#include "git2/sys/openssl.h"
|
||||||
@ -71,12 +72,20 @@ static void shutdown_ssl_locking(void)
|
|||||||
|
|
||||||
#endif /* GIT_THREADS */
|
#endif /* GIT_THREADS */
|
||||||
|
|
||||||
|
static BIO_METHOD *git_stream_bio_method;
|
||||||
|
static int init_bio_method(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function aims to clean-up the SSL context which
|
* This function aims to clean-up the SSL context which
|
||||||
* we allocated.
|
* we allocated.
|
||||||
*/
|
*/
|
||||||
static void shutdown_ssl(void)
|
static void shutdown_ssl(void)
|
||||||
{
|
{
|
||||||
|
if (git_stream_bio_method) {
|
||||||
|
BIO_meth_free(git_stream_bio_method);
|
||||||
|
git_stream_bio_method = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (git__ssl_ctx) {
|
if (git__ssl_ctx) {
|
||||||
SSL_CTX_free(git__ssl_ctx);
|
SSL_CTX_free(git__ssl_ctx);
|
||||||
git__ssl_ctx = NULL;
|
git__ssl_ctx = NULL;
|
||||||
@ -121,6 +130,13 @@ int git_openssl_stream_global_init(void)
|
|||||||
git__ssl_ctx = NULL;
|
git__ssl_ctx = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (init_bio_method() < 0) {
|
||||||
|
SSL_CTX_free(git__ssl_ctx);
|
||||||
|
git__ssl_ctx = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
git__on_shutdown(shutdown_ssl);
|
git__on_shutdown(shutdown_ssl);
|
||||||
@ -156,14 +172,8 @@ int git_openssl_set_locking(void)
|
|||||||
|
|
||||||
static int bio_create(BIO *b)
|
static int bio_create(BIO *b)
|
||||||
{
|
{
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
b->init = 1;
|
|
||||||
b->num = 0;
|
|
||||||
b->ptr = NULL;
|
|
||||||
b->flags = 0;
|
|
||||||
#else
|
|
||||||
BIO_set_init(b, 1);
|
BIO_set_init(b, 1);
|
||||||
#endif
|
BIO_set_data(b, NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -173,36 +183,22 @@ static int bio_destroy(BIO *b)
|
|||||||
if (!b)
|
if (!b)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
b->init = 0;
|
|
||||||
b->num = 0;
|
|
||||||
b->ptr = NULL;
|
|
||||||
b->flags = 0;
|
|
||||||
#else
|
|
||||||
BIO_set_init(b, 0);
|
|
||||||
BIO_set_data(b, NULL);
|
BIO_set_data(b, NULL);
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bio_read(BIO *b, char *buf, int len)
|
static int bio_read(BIO *b, char *buf, int len)
|
||||||
{
|
{
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
git_stream *io = (git_stream *) b->ptr;
|
|
||||||
#else
|
|
||||||
git_stream *io = (git_stream *) BIO_get_data(b);
|
git_stream *io = (git_stream *) BIO_get_data(b);
|
||||||
#endif
|
|
||||||
return (int) git_stream_read(io, buf, len);
|
return (int) git_stream_read(io, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bio_write(BIO *b, const char *buf, int len)
|
static int bio_write(BIO *b, const char *buf, int len)
|
||||||
{
|
{
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
git_stream *io = (git_stream *) b->ptr;
|
|
||||||
#else
|
|
||||||
git_stream *io = (git_stream *) BIO_get_data(b);
|
git_stream *io = (git_stream *) BIO_get_data(b);
|
||||||
#endif
|
|
||||||
return (int) git_stream_write(io, buf, len, 0);
|
return (int) git_stream_write(io, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,21 +227,22 @@ static int bio_puts(BIO *b, const char *str)
|
|||||||
return bio_write(b, str, strlen(str));
|
return bio_write(b, str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
static int init_bio_method(void)
|
||||||
static BIO_METHOD git_stream_bio_method = {
|
{
|
||||||
BIO_TYPE_SOURCE_SINK,
|
/* Set up the BIO_METHOD we use for wrapping our own stream implementations */
|
||||||
"git_stream",
|
git_stream_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "git_stream");
|
||||||
bio_write,
|
GITERR_CHECK_ALLOC(git_stream_bio_method);
|
||||||
bio_read,
|
|
||||||
bio_puts,
|
BIO_meth_set_write(git_stream_bio_method, bio_write);
|
||||||
bio_gets,
|
BIO_meth_set_read(git_stream_bio_method, bio_read);
|
||||||
bio_ctrl,
|
BIO_meth_set_puts(git_stream_bio_method, bio_puts);
|
||||||
bio_create,
|
BIO_meth_set_gets(git_stream_bio_method, bio_gets);
|
||||||
bio_destroy
|
BIO_meth_set_ctrl(git_stream_bio_method, bio_ctrl);
|
||||||
};
|
BIO_meth_set_create(git_stream_bio_method, bio_create);
|
||||||
#else
|
BIO_meth_set_destroy(git_stream_bio_method, bio_destroy);
|
||||||
static BIO_METHOD *git_stream_bio_method = NULL;
|
|
||||||
#endif
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ssl_set_error(SSL *ssl, int error)
|
static int ssl_set_error(SSL *ssl, int error)
|
||||||
{
|
{
|
||||||
@ -466,27 +463,12 @@ int openssl_connect(git_stream *stream)
|
|||||||
|
|
||||||
st->connected = true;
|
st->connected = true;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
bio = BIO_new(&git_stream_bio_method);
|
|
||||||
#else
|
|
||||||
git_stream_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "git_stream");
|
|
||||||
BIO_meth_set_write(git_stream_bio_method, bio_write);
|
|
||||||
BIO_meth_set_read(git_stream_bio_method, bio_read);
|
|
||||||
BIO_meth_set_puts(git_stream_bio_method, bio_puts);
|
|
||||||
BIO_meth_set_gets(git_stream_bio_method, bio_gets);
|
|
||||||
BIO_meth_set_ctrl(git_stream_bio_method, bio_ctrl);
|
|
||||||
BIO_meth_set_create(git_stream_bio_method, bio_create);
|
|
||||||
BIO_meth_set_destroy(git_stream_bio_method, bio_destroy);
|
|
||||||
bio = BIO_new(git_stream_bio_method);
|
bio = BIO_new(git_stream_bio_method);
|
||||||
#endif
|
|
||||||
GITERR_CHECK_ALLOC(bio);
|
GITERR_CHECK_ALLOC(bio);
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
bio->ptr = st->io;
|
|
||||||
#else
|
|
||||||
BIO_set_data(bio, st->io);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
BIO_set_data(bio, st->io);
|
||||||
SSL_set_bio(st->ssl, bio, bio);
|
SSL_set_bio(st->ssl, bio, bio);
|
||||||
|
|
||||||
/* specify the host in case SNI is needed */
|
/* specify the host in case SNI is needed */
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
SSL_set_tlsext_host_name(st->ssl, st->host);
|
SSL_set_tlsext_host_name(st->ssl, st->host);
|
||||||
|
@ -7,10 +7,107 @@
|
|||||||
#ifndef INCLUDE_openssl_stream_h__
|
#ifndef INCLUDE_openssl_stream_h__
|
||||||
#define INCLUDE_openssl_stream_h__
|
#define INCLUDE_openssl_stream_h__
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
#include "git2/sys/stream.h"
|
#include "git2/sys/stream.h"
|
||||||
|
|
||||||
extern int git_openssl_stream_global_init(void);
|
extern int git_openssl_stream_global_init(void);
|
||||||
|
|
||||||
extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port);
|
extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
|
||||||
|
* which do not exist in previous versions. We define these inline functions so
|
||||||
|
* we can program against the interface instead of littering the implementation
|
||||||
|
* with ifdefs.
|
||||||
|
*/
|
||||||
|
# if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
|
||||||
|
GIT_INLINE(BIO_METHOD*) BIO_meth_new(int type, const char *name)
|
||||||
|
{
|
||||||
|
BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
|
||||||
|
if (!meth) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
meth->type = type;
|
||||||
|
meth->name = name;
|
||||||
|
|
||||||
|
return meth;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(void) BIO_meth_free(BIO_METHOD *biom)
|
||||||
|
{
|
||||||
|
git__free(biom);
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
|
||||||
|
{
|
||||||
|
biom->bwrite = write;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
|
||||||
|
{
|
||||||
|
biom->bread = read;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
|
||||||
|
{
|
||||||
|
biom->bputs = puts;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))
|
||||||
|
|
||||||
|
{
|
||||||
|
biom->bgets = gets;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
|
||||||
|
{
|
||||||
|
biom->ctrl = ctrl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
|
||||||
|
{
|
||||||
|
biom->create = create;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
|
||||||
|
{
|
||||||
|
biom->destroy = destroy;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(int) BIO_get_new_index(void)
|
||||||
|
{
|
||||||
|
/* This exists as of 1.1 so before we'd just have 0 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(void) BIO_set_init(BIO *b, int init)
|
||||||
|
{
|
||||||
|
b->init = init;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(void) BIO_set_data(BIO *a, void *ptr)
|
||||||
|
{
|
||||||
|
a->ptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(void*) BIO_get_data(BIO *a)
|
||||||
|
{
|
||||||
|
return a->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user