Commit dbe343b6 by Edward Thomson

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.
parent 6c0d5b11
...@@ -44,6 +44,7 @@ typedef struct { ...@@ -44,6 +44,7 @@ typedef struct {
git_stream parent; git_stream parent;
git_stream *io; git_stream *io;
int owned; int owned;
int error;
SSLContextRef ctx; SSLContextRef ctx;
CFDataRef der_data; CFDataRef der_data;
git_cert_x509 cert_info; git_cert_x509 cert_info;
...@@ -61,7 +62,10 @@ static int stransport_connect(git_stream *stream) ...@@ -61,7 +62,10 @@ static int stransport_connect(git_stream *stream)
return error; return error;
ret = SSLHandshake(st->ctx); 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); git_error_set(GIT_ERROR_SSL, "unexpected return value from ssl handshake %d", (int)ret);
return -1; return -1;
} }
...@@ -147,10 +151,18 @@ static int stransport_set_proxy( ...@@ -147,10 +151,18 @@ static int stransport_set_proxy(
*/ */
static OSStatus write_cb(SSLConnectionRef conn, const void *data, size_t *len) 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) if (ret < 0) {
return -36; /* "ioErr" from MacErrors.h which is not available on iOS */ st->error = ret;
return -36; /* ioErr */
}
return noErr; return noErr;
} }
...@@ -182,18 +194,22 @@ static ssize_t stransport_write(git_stream *stream, const char *data, size_t len ...@@ -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) 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; OSStatus error = noErr;
size_t off = 0; size_t off = 0;
ssize_t ret; ssize_t ret;
st->error = 0;
do { do {
ret = git_stream_read(io, data + off, *len - off); ret = git_stream_read(io, data + off, *len - off);
if (ret < 0) { if (ret < 0) {
error = -36; /* "ioErr" from MacErrors.h which is not available on iOS */ st->error = ret;
error = -36; /* ioErr */
break; break;
} } else if (ret == 0) {
if (ret == 0) {
error = errSSLClosedGraceful; error = errSSLClosedGraceful;
break; break;
} }
...@@ -207,12 +223,13 @@ static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len) ...@@ -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) 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; size_t processed;
OSStatus ret; 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 stransport_error(ret);
}
return processed; return processed;
} }
...@@ -269,7 +286,7 @@ static int stransport_wrap( ...@@ -269,7 +286,7 @@ static int stransport_wrap(
} }
if ((ret = SSLSetIOFuncs(st->ctx, read_cb, write_cb)) != noErr || 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 = SSLSetSessionOption(st->ctx, kSSLSessionOptionBreakOnServerAuth, true)) != noErr ||
(ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr || (ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr ||
(ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr || (ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr ||
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment