Overview
Context
Changes
Modified src/OFTLSStream.h
from [b3a209020a]
to [d05dc14c91].
| ︙ | | |
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
-
-
-
+
+
+
-
+
-
+
-
+
|
* if available.
*
* Subclasses need to override @ref lowlevelReadIntoBuffer:length:,
* @ref lowlevelWriteBuffer:length: and
* @ref asyncPerformClientHandshakeWithHost:runLoopMode:. The method
* @ref hasDataInReadBuffer should be overridden to return `true` if the TLS
* stream has cached unprocessed data internally, while returning
* `self.wrappedStream.hasDataInReadBuffer` if it does not have any unprocessed
* data. In order to get access to the wrapped stream, @ref wrappedStream can
* be used.
* `self.underlyingStream.hasDataInReadBuffer` if it does not have any
* unprocessed data. In order to get access to the underlying stream,
* @ref underlyingStream can be used.
*/
@interface OFTLSStream: OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving>
{
OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving>
*_wrappedStream;
*_underlyingStream;
bool _verifiesCertificates;
OF_RESERVE_IVARS(OFTLSStream, 4)
}
/**
* @brief The wrapped stream.
* @brief The underlying stream.
*/
@property (readonly, nonatomic) OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *wrappedStream;
OFReadyForWritingObserving> *underlyingStream;
/**
* @brief The delegate for asynchronous operations on the stream.
*
* @note The delegate is retained for as long as asynchronous operations are
* still ongoing.
*/
|
| ︙ | | |
Modified src/OFTLSStream.m
from [659fa26933]
to [de0cb549c8].
| ︙ | | |
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
-
+
|
{
_done = true;
_exception = [exception retain];
}
@end
@implementation OFTLSStream
@synthesize wrappedStream = _wrappedStream;
@synthesize underlyingStream = _underlyingStream;
@dynamic delegate;
@synthesize verifiesCertificates = _verifiesCertificates;
+ (instancetype)alloc
{
if (self == [OFTLSStream class]) {
if (OFTLSStreamImplementation != Nil)
|
| ︙ | | |
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
|
- (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream
{
self = [super init];
@try {
_wrappedStream = [stream retain];
_underlyingStream = [stream retain];
_verifiesCertificates = true;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_wrappedStream release];
[_underlyingStream release];
[super dealloc];
}
- (void)close
{
[_wrappedStream release];
_wrappedStream = nil;
[_underlyingStream release];
_underlyingStream = nil;
[super close];
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
OF_UNRECOGNIZED_SELECTOR
}
- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
OF_UNRECOGNIZED_SELECTOR
}
- (bool)hasDataInReadBuffer
{
return (super.hasDataInReadBuffer ||
_wrappedStream.hasDataInReadBuffer);
_underlyingStream.hasDataInReadBuffer);
}
- (bool)lowlevelIsAtEndOfStream
{
return _wrappedStream.atEndOfStream;
return _underlyingStream.atEndOfStream;
}
- (int)fileDescriptorForReading
{
return _wrappedStream.fileDescriptorForReading;
return _underlyingStream.fileDescriptorForReading;
}
- (int)fileDescriptorForWriting
{
return _wrappedStream.fileDescriptorForWriting;
return _underlyingStream.fileDescriptorForWriting;
}
- (void)asyncPerformClientHandshakeWithHost: (OFString *)host
{
[self asyncPerformClientHandshakeWithHost: host
runLoopMode: OFDefaultRunLoopMode];
}
|
| ︙ | | |
Modified src/tls/OFGnuTLSTLSStream.m
from [633e4da737]
to [72367f1922].
| ︙ | | |
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
-
+
-
+
-
+
|
@implementation OFGnuTLSTLSStream
static ssize_t
readFunc(gnutls_transport_ptr_t transport, void *buffer, size_t length)
{
OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport;
@try {
length = [stream.wrappedStream readIntoBuffer: buffer
length = [stream.underlyingStream readIntoBuffer: buffer
length: length];
} @catch (OFReadFailedException *e) {
gnutls_transport_set_errno(stream->_session, e.errNo);
return -1;
}
if (length == 0 && !stream.wrappedStream.atEndOfStream) {
if (length == 0 && !stream.underlyingStream.atEndOfStream) {
gnutls_transport_set_errno(stream->_session, EWOULDBLOCK);
return -1;
}
return length;
}
static ssize_t
writeFunc(gnutls_transport_ptr_t transport, const void *buffer, size_t length)
{
OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport;
@try {
[stream.wrappedStream writeBuffer: buffer length: length];
[stream.underlyingStream writeBuffer: buffer length: length];
} @catch (OFWriteFailedException *e) {
gnutls_transport_set_errno(stream->_session, e.errNo);
if (e.errNo == EWOULDBLOCK)
return e.bytesWritten;
return -1;
|
| ︙ | | |
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
-
+
|
- (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream
{
self = [super initWithStream: stream];
@try {
_wrappedStream.delegate = self;
_underlyingStream.delegate = self;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
| ︙ | | |
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
-
+
-
+
|
if (_verifiesCertificates)
gnutls_session_set_verify_cert(_session, _host.UTF8String, 0);
status = gnutls_handshake(_session);
if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) {
if (gnutls_record_get_direction(_session) == 1)
[_wrappedStream
[_underlyingStream
asyncWriteData: [OFData dataWithItems: "" count: 0]
runLoopMode: runLoopMode];
else
[_wrappedStream asyncReadIntoBuffer: (void *)""
[_underlyingStream asyncReadIntoBuffer: (void *)""
length: 0
runLoopMode: runLoopMode];
[_delegate retain];
return;
}
|
| ︙ | | |
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
-
+
|
if (status == GNUTLS_E_INTERRUPTED ||
status == GNUTLS_E_AGAIN) {
if (gnutls_record_get_direction(_session) == 1) {
OFData *data = [OFData dataWithItems: ""
count: 0];
OFRunLoopMode runLoopMode =
[OFRunLoop currentRunLoop].currentMode;
[_wrappedStream asyncWriteData: data
[_underlyingStream asyncWriteData: data
runLoopMode: runLoopMode];
return false;
} else
return true;
}
if (status != GNUTLS_E_SUCCESS)
|
| ︙ | | |
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
-
+
|
if (status == GNUTLS_E_INTERRUPTED ||
status == GNUTLS_E_AGAIN) {
if (gnutls_record_get_direction(_session) == 1)
return data;
else {
OFRunLoopMode runLoopMode =
[OFRunLoop currentRunLoop].currentMode;
[_wrappedStream
[_underlyingStream
asyncReadIntoBuffer: (void *)""
length: 0
runLoopMode: runLoopMode];
return nil;
}
}
|
| ︙ | | |
Modified src/tls/OFSecureTransportTLSStream.m
from [e80afd9547]
to [446883c227].
| ︙ | | |
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
-
+
|
static OSStatus
readFunc(SSLConnectionRef connection, void *data, size_t *dataLength)
{
bool incomplete;
size_t length;
@try {
length = [((OFTLSStream *)connection).wrappedStream
length = [((OFTLSStream *)connection).underlyingStream
readIntoBuffer: data
length: *dataLength];
} @catch (OFReadFailedException *e) {
if (e.errNo == EWOULDBLOCK) {
*dataLength = 0;
return errSSLWouldBlock;
}
|
| ︙ | | |
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
-
+
|
return (incomplete ? errSSLWouldBlock : noErr);
}
static OSStatus
writeFunc(SSLConnectionRef connection, const void *data, size_t *dataLength)
{
@try {
[((OFTLSStream *)connection).wrappedStream
[((OFTLSStream *)connection).underlyingStream
writeBuffer: data
length: *dataLength];
} @catch (OFWriteFailedException *e) {
*dataLength = e.bytesWritten;
if (e.errNo == EWOULDBLOCK)
return errSSLWouldBlock;
|
| ︙ | | |
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
-
+
|
- (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream
{
self = [super initWithStream: stream];
@try {
_wrappedStream.delegate = self;
_underlyingStream.delegate = self;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
| ︙ | | |
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
-
+
|
* Theoretically it is possible we block because Secure
* Transport cannot write without blocking. But unfortunately,
* Secure Transport does not tell us whether it's blocked on
* reading or writing. Waiting for the stream to be either
* readable or writable doesn't work either, as the stream is
* almost always at least ready for one of the two.
*/
[_wrappedStream asyncReadIntoBuffer: (void *)""
[_underlyingStream asyncReadIntoBuffer: (void *)""
length: 0
runLoopMode: runLoopMode];
[_delegate retain];
return;
}
if (status != noErr)
|
| ︙ | | |