summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-05-12 20:48:28 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2023-05-13 16:42:04 +0100
commitdbe343b6e3e957b5cffbd04832c6e7364b496ae7 (patch)
tree80c6831aa9da0f686e4cd49ccb68c81df99d5b6b
parent6c0d5b11c05254d91a2d0025d556251404f8f05f (diff)
downloadlibgit2-dbe343b6e3e957b5cffbd04832c6e7364b496ae7.tar.gz
stransport: store error information
We lose some error information from the read / write callbacks to stransport. Store our own error value in the object so that we can ensure that we rely upon it.
-rw-r--r--src/libgit2/streams/stransport.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/libgit2/streams/stransport.c b/src/libgit2/streams/stransport.c
index 3f31d2541..74ee0d1ee 100644
--- a/src/libgit2/streams/stransport.c
+++ b/src/libgit2/streams/stransport.c
@@ -44,6 +44,7 @@ typedef struct {
git_stream parent;
git_stream *io;
int owned;
+ int error;
SSLContextRef ctx;
CFDataRef der_data;
git_cert_x509 cert_info;
@@ -61,7 +62,10 @@ static int stransport_connect(git_stream *stream)
return error;
ret = SSLHandshake(st->ctx);
- if (ret != errSSLServerAuthCompleted) {
+
+ if (ret != errSSLServerAuthCompleted && st->error != 0)
+ return -1;
+ else if (ret != errSSLServerAuthCompleted) {
git_error_set(GIT_ERROR_SSL, "unexpected return value from ssl handshake %d", (int)ret);
return -1;
}
@@ -147,10 +151,18 @@ static int stransport_set_proxy(
*/
static OSStatus write_cb(SSLConnectionRef conn, const void *data, size_t *len)
{
- git_stream *io = (git_stream *) conn;
+ stransport_stream *st = (stransport_stream *)conn;
+ git_stream *io = st->io;
+ OSStatus ret;
+
+ st->error = 0;
+
+ ret = git_stream__write_full(io, data, *len, 0);
- if (git_stream__write_full(io, data, *len, 0) < 0)
- return -36; /* "ioErr" from MacErrors.h which is not available on iOS */
+ if (ret < 0) {
+ st->error = ret;
+ return -36; /* ioErr */
+ }
return noErr;
}
@@ -182,18 +194,22 @@ static ssize_t stransport_write(git_stream *stream, const char *data, size_t len
*/
static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len)
{
- git_stream *io = (git_stream *) conn;
+ stransport_stream *st = (stransport_stream *)conn;
+ git_stream *io = st->io;
OSStatus error = noErr;
size_t off = 0;
ssize_t ret;
+ st->error = 0;
+
do {
ret = git_stream_read(io, data + off, *len - off);
+
if (ret < 0) {
- error = -36; /* "ioErr" from MacErrors.h which is not available on iOS */
+ st->error = ret;
+ error = -36; /* ioErr */
break;
- }
- if (ret == 0) {
+ } else if (ret == 0) {
error = errSSLClosedGraceful;
break;
}
@@ -207,12 +223,13 @@ static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len)
static ssize_t stransport_read(git_stream *stream, void *data, size_t len)
{
- stransport_stream *st = (stransport_stream *) stream;
+ stransport_stream *st = (stransport_stream *)stream;
size_t processed;
OSStatus ret;
- if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr)
+ if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr) {
return stransport_error(ret);
+ }
return processed;
}
@@ -269,7 +286,7 @@ static int stransport_wrap(
}
if ((ret = SSLSetIOFuncs(st->ctx, read_cb, write_cb)) != noErr ||
- (ret = SSLSetConnection(st->ctx, st->io)) != noErr ||
+ (ret = SSLSetConnection(st->ctx, st)) != noErr ||
(ret = SSLSetSessionOption(st->ctx, kSSLSessionOptionBreakOnServerAuth, true)) != noErr ||
(ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr ||
(ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr ||