Overview
Comment: | Make OFTLSSocket an abstract class
This should make it easier to add TLS support using various |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
34cb121dc539a4a90083a14357549adb |
User & Date: | js on 2021-11-06 00:10:48 |
Other Links: | manifest | tags |
Context
2021-11-06
| ||
14:30 | Doxyfile: Define _Nonnull and _Nullable check-in: 033ba56f36 user: js tags: trunk | |
00:10 | Make OFTLSSocket an abstract class check-in: 34cb121dc5 user: js tags: trunk | |
2021-11-05
| ||
22:42 | Remove TLS server support check-in: a5a3047210 user: js tags: trunk | |
Changes
Modified src/Makefile from [0d79d5eef0] to [099a565a95].
︙ | ︙ | |||
135 136 137 138 139 140 141 142 143 144 145 146 147 148 | OFHTTPRequest.m \ OFHTTPResponse.m \ OFHTTPServer.m \ OFSequencedPacketSocket.m \ OFSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFUDPSocket.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \ | > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | OFHTTPRequest.m \ OFHTTPResponse.m \ OFHTTPServer.m \ OFSequencedPacketSocket.m \ OFSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFTLSSocket.m \ OFUDPSocket.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \ |
︙ | ︙ | |||
168 169 170 171 172 173 174 | OFCollection.h \ OFCryptographicHash.h \ OFJSONRepresentation.h \ OFKernelEventObserver.h \ OFKeyValueCoding.h \ OFLocking.h \ OFMessagePackRepresentation.h \ | < | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | OFCollection.h \ OFCryptographicHash.h \ OFJSONRepresentation.h \ OFKernelEventObserver.h \ OFKeyValueCoding.h \ OFLocking.h \ OFMessagePackRepresentation.h \ ObjFW.h \ macros.h \ objfw-defs.h \ platform.h \ ${USE_INCLUDES_ATOMIC} SRCS += OFAdjacentArray.m \ |
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 | ${LIBBASES_M} \ ${RUNTIME_AUTORELEASE_M} \ ${RUNTIME_INSTANCE_M} \ ${UNICODE_M} SRCS_FILES += OFFileURLHandler.m \ OFINIFileSettings.m SRCS_SOCKETS += OFDNSResolverSettings.m \ OFHTTPURLHandler.m \ OFHostAddressResolver.m \ OFIPSocketAsyncConnector.m \ OFKernelEventObserver.m \ | > < | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | ${LIBBASES_M} \ ${RUNTIME_AUTORELEASE_M} \ ${RUNTIME_INSTANCE_M} \ ${UNICODE_M} SRCS_FILES += OFFileURLHandler.m \ OFINIFileSettings.m SRCS_SOCKETS += OFDNSResolverSettings.m \ ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \ OFHTTPURLHandler.m \ OFHostAddressResolver.m \ OFIPSocketAsyncConnector.m \ OFKernelEventObserver.m \ ${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \ ${OF_POLL_KERNEL_EVENT_OBSERVER_M} \ ${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \ OFTCPSocketSOCKS5Connector.m OBJS_EXTRA = exceptions/exceptions.a \ encodings/encodings.a \ |
︙ | ︙ |
Modified src/OFHTTPClient.m from [53c6cb3f12] to [95bd8d7b45].
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #import "OFHTTPResponse.h" #import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFRunLoop.h" #import "OFSocket+Private.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" | > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #import "OFHTTPResponse.h" #import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFRunLoop.h" #import "OFSocket+Private.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFTLSSocket.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" |
︙ | ︙ | |||
695 696 697 698 699 700 701 | uint16_t port; OFNumber *URLPort; [_client close]; if ([URL.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame) { | > | > > | < < | 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | uint16_t port; OFNumber *URLPort; [_client close]; if ([URL.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame) { @try { sock = [OFTLSSocket socket]; port = 443; } @catch (OFNotImplementedException *e) { @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; } } else { sock = [OFTCPSocket socket]; port = 80; } URLPort = URL.port; if (URLPort != nil) |
︙ | ︙ |
Modified src/OFTCPSocket.h from [7942720881] to [4ad589837f].
︙ | ︙ | |||
206 207 208 209 210 211 212 | * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end | < < < < < < < < | 206 207 208 209 210 211 212 213 | * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Modified src/OFTLSSocket.h from [d519c5a780] to [38e4f875d1].
︙ | ︙ | |||
9 10 11 12 13 14 15 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ | | > > > > > > > > | | > > > > > > > > > > > > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFTCPSocket.h" OF_ASSUME_NONNULL_BEGIN /** * @protocol OFTLSSocketDelegate OFTLSSocket.h ObjFW/OFTLSSocket.h * * A delegate for OFTLSSocket. */ @protocol OFTLSSocketDelegate <OFTCPSocketDelegate> @end /** * @class OFTLSSocket OFTLSSocket.h ObjFW/OFTLSSocket.h * * @brief A class that provides Transport Layer Security on top of a TCP socket. * * This class is a class cluster and returns a suitable OFTLSSocket subclass, * if available. * * Subclasses need to override @ref accept, @ref lowlevelReadIntoBuffer:length:, * @ref lowlevelWriteBuffer:length:, @ref lowlevelIsAtEndOfStream and * @ref startTLSForHost:port:. In order to get access to the lowlevel TCP * methods (you cannot call `super`, as the class is abstract), the private * methods @ref TCPAccept, @ref lowlevelTCPReadIntoBuffer:length:, * @ref lowlevelTCPWriteBuffer:length: and @ref lowlevelTCPIsAtEndOfStream are * provided. */ @interface OFTLSSocket: OFTCPSocket { bool _verifiesCertificates; OF_RESERVE_IVARS(OFTLSSocket, 4) } /** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFTLSSocketDelegate> delegate; /** * @brief Whether certificates are verified. * * The default is enabled. */ @property (nonatomic) bool verifiesCertificates; /** * @brief Initializes the TLS socket with the specified TCP socket as its * underlying socket. * * @param socket The TCP socket to use as underlying socket */ - (instancetype)initWithSocket: (OFTCPSocket *)socket; /** * @brief Start TLS on the underlying socket with the assumption that it is * connected to the specified host and port. * * @param host The host the socket is connected to, which is also used for * verification * @param port The port the socket is connected to */ - (void)startTLSForHost: (OFString *)host port: (uint16_t)port; /** * @brief This method should never be called directly. Only subclasses of * @ref OFTLSSocket are allowed to call it. */ - (instancetype)TCPAccept; /** * @brief This method should never be called directly. Only subclasses of * @ref OFTLSSocket are allowed to call it. */ - (size_t)lowlevelTCPReadIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief This method should never be called directly. Only subclasses of * @ref OFTLSSocket are allowed to call it. */ - (size_t)lowlevelTCPWriteBuffer: (const void *)buffer length: (size_t)length; /** * @brief This method should never be called directly. Only subclasses of * @ref OFTLSSocket are allowed to call it. */ - (bool)lowlevelTCPIsAtEndOfStream; @end #ifdef __cplusplus extern "C" { #endif /** * @brief The concrete subclass of OFTLSSocket that should be used. */ extern Class _Nullable OFTLSSocketImplementation; #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Added src/OFTLSSocket.m version [d6f41e909e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | /* * Copyright (c) 2008-2021 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" Class OFTLSSocketImplementation = Nil; @interface OFTLSSocketAsyncConnector: OFObject <OFTLSSocketDelegate> { OFTLSSocket *_socket; OFString *_host; uint16_t _port; id <OFTLSSocketDelegate> _delegate; } - (instancetype)initWithSocket: (OFTLSSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (id <OFTLSSocketDelegate>)delegate; @end @implementation OFTLSSocketAsyncConnector - (instancetype)initWithSocket: (OFTLSSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (id <OFTLSSocketDelegate>)delegate { self = [super init]; @try { _socket = [sock retain]; _host = [host copy]; _port = port; _delegate = [delegate retain]; _socket.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket.delegate == self) _socket.delegate = _delegate; [_socket release]; [_delegate release]; [super dealloc]; } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { if (exception == nil) { @try { [(OFTLSSocket *)sock startTLSForHost: _host port: _port]; } @catch (id e) { [self release]; @throw e; } } _socket.delegate = _delegate; [_delegate socket: sock didConnectToHost: host port: port exception: exception]; } @end @implementation OFTLSSocket @dynamic delegate; @synthesize verifiesCertificates = _verifiesCertificates; + (instancetype)alloc { if (self == [OFTLSSocket class]) { if (OFTLSSocketImplementation == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; return [OFTLSSocketImplementation alloc]; } return [super alloc]; } - (instancetype)init { self = [super init]; _verifiesCertificates = true; return self; } - (instancetype)initWithSocket: (OFTCPSocket *)socket { self = [super init]; @try { if ([socket isKindOfClass: [OFTLSSocket class]]) @throw [OFInvalidArgumentException exception]; if ((_socket = dup(socket->_socket)) == OFInvalidSocketHandle) @throw [OFInitializationFailedException exception]; _verifiesCertificates = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)startTLSForHost: (OFString *)host port: (uint16_t)port { OF_UNRECOGNIZED_SELECTOR } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode { void *pool = objc_autoreleasePoolPush(); [[[OFTLSSocketAsyncConnector alloc] initWithSocket: self host: host port: port delegate: _delegate] autorelease]; [super asyncConnectToHost: host port: port runLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFTCPSocketAsyncConnectBlock)block { [super asyncConnectToHost: host port: port runLoopMode: runLoopMode block: ^ (id exception) { if (exception == nil) { @try { [self startTLSForHost: host port: port]; } @catch (id e) { block(e); return; } } block(exception); }]; } #endif - (instancetype)accept { OF_UNRECOGNIZED_SELECTOR } - (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)lowlevelIsAtEndOfStream { OF_UNRECOGNIZED_SELECTOR } - (instancetype)TCPAccept { return [super accept]; } - (size_t)lowlevelTCPReadIntoBuffer: (void *)buffer length: (size_t)length { return [super lowlevelReadIntoBuffer: buffer length: length]; } - (size_t)lowlevelTCPWriteBuffer: (const void *)buffer length: (size_t)length { return [super lowlevelWriteBuffer: buffer length: length]; } - (bool)lowlevelTCPIsAtEndOfStream { return [super lowlevelIsAtEndOfStream]; } @end |
Modified utils/ofhttp/OFHTTP.m from [cd70aeb710] to [2fe08b11b5].
︙ | ︙ | |||
583 584 585 586 587 588 589 | [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)sock request: (OFHTTPRequest *)request { | | < | | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 | [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)sock request: (OFHTTPRequest *)request { if (_insecure && [sock isKindOfClass: [OFTLSSocket class]]) ((OFTLSSocket *)sock).verifiesCertificates = false; } - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)body request: (OFHTTPRequest *)request { /* TODO: Do asynchronously and print status */ |
︙ | ︙ |