Differentiate between client/server for DO over TLS

This commit is contained in:
Richard Frith-Macdonald 2021-06-24 08:50:28 +01:00
parent 640198a395
commit a29248bd4d
3 changed files with 110 additions and 56 deletions

View file

@ -1,3 +1,11 @@
2021-06-19 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/Port.h:
* Source/NSSocketPort.m:
Extend the API for TLS support in Distributed Objects so that we have
separate settings for whether the port is acting as a client or
server.
2021-06-19 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTLS.m:

View file

@ -208,7 +208,8 @@ GS_EXPORT_CLASS
uint16_t portNum; /* TCP port in host byte order. */
SOCKET listener;
NSMapTable *handles; /* Handles indexed by socket. */
NSDictionary *tlsopts; /* TLS options */
NSDictionary *tlscopts; /* TLS client options */
NSDictionary *tlssopts; /* TLS server options */
#if defined(_WIN32)
WSAEVENT eventListener;
NSMapTable *events;
@ -280,14 +281,27 @@ GS_EXPORT_CLASS
* Setting nil (the default) means that TLS is not used.<br />
* Setting an empty dictionary means that TLS is used with normal options.
*/
+ (void) setOptionsForTLS: (NSDictionary*)opts;
+ (void) setClientOptionsForTLS: (NSDictionary*)opts;
/** Sets the default options for use of TLS by socket ports.<br />
* Setting nil (the default) means that TLS is not used.<br />
* Setting an empty dictionary means that TLS is used with normal options.
*/
+ (void) setServerOptionsForTLS: (NSDictionary*)opts;
/** Overrides the default options for use of TLS by the receiver.<br />
* Setting nil (the default) means that TLS is not used.<br />
* Setting an empty dictionary means that TLS is used with normal options.<br />
* This method has no effect on network sessions which are already established.
*/
- (void) setOptionsForTLS: (NSDictionary*)opts;
- (void) setClientOptionsForTLS: (NSDictionary*)opts;
/** Overrides the default options for use of TLS by the receiver.<br />
* Setting nil (the default) means that TLS is not used.<br />
* Setting an empty dictionary means that TLS is used with normal options.<br />
* This method has no effect on network sessions which are already established.
*/
- (void) setServerOptionsForTLS: (NSDictionary*)opts;
#endif
@end

View file

@ -143,7 +143,8 @@ static uint32_t maxDataLength = 32 * 1024 * 1024;
/* Options for TLS encryption of connections
*/
static NSDictionary *tlsOptions;
static NSDictionary *tlsClientOptions;
static NSDictionary *tlsServerOptions;
static NSLock *tlsLock;
#if 0
@ -225,7 +226,8 @@ typedef enum {
} GSHandleState;
@interface NSSocketPort (GSTcpHandle)
- (NSDictionary*) optionsForTLS;
- (NSDictionary*) clientOptionsForTLS;
- (NSDictionary*) serverOptionsForTLS;
@end
@interface GSTcpHandle : NSObject <RunLoopEvents>
@ -1256,7 +1258,7 @@ static Class runLoopClass;
cLength = 0;
#if defined(HAVE_GNUTLS)
NSDictionary *opts = [p optionsForTLS];
NSDictionary *opts = [p clientOptionsForTLS];
DESTROY(session);
if (opts)
{
@ -1777,6 +1779,10 @@ static Class tcpPortClass;
#endif
port->myLock = [NSRecursiveLock new];
port->_is_valid = YES;
[tlsLock lock];
[port setClientOptionsForTLS: tlsClientOptions];
[port setServerOptionsForTLS: tlsServerOptions];
[tlsLock unlock];
if (shouldListen == YES && [thisHost isEqual: aHost])
{
@ -1919,12 +1925,6 @@ static Class tcpPortClass;
NSMapInsert(thePorts, (void*)aHost, (void*)port);
NSDebugMLLog(@"NSPort", @"Created speaking port: %@", port);
}
if (tlsOptions != nil)
{
[tlsLock lock];
[port setOptionsForTLS: tlsOptions];
[tlsLock unlock];
}
}
else
{
@ -1937,12 +1937,22 @@ static Class tcpPortClass;
return port;
}
+ (void) setOptionsForTLS: (NSDictionary*)options
+ (void) setClientOptionsForTLS: (NSDictionary*)options
{
if (options != tlsOptions)
if (options != tlsClientOptions)
{
[tlsLock lock];
ASSIGNCOPY(tlsOptions, options);
ASSIGNCOPY(tlsClientOptions, options);
[tlsLock unlock];
}
}
+ (void) setServerOptionsForTLS: (NSDictionary*)options
{
if (options != tlsServerOptions)
{
[tlsLock lock];
ASSIGNCOPY(tlsServerOptions, options);
[tlsLock unlock];
}
}
@ -1974,6 +1984,42 @@ static Class tcpPortClass;
return address;
}
- (NSDictionary*) clientOptionsForTLS
{
NSDictionary *opts;
M_LOCK(myLock);
opts = RETAIN(tlscopts);
M_UNLOCK(myLock);
return AUTORELEASE(opts);
}
- (id) conversation: (NSPort*)recvPort
{
NSMapEnumerator me;
void *dummy;
GSTcpHandle *handle = nil;
M_LOCK(myLock);
/*
* Enumerate all our socket handles, and look for one with port.
*/
me = NSEnumerateMapTable(handles);
while (NSNextMapEnumeratorPair(&me, &dummy, (void**)&handle))
{
if ((NSPort*) [handle recvPort] == recvPort)
{
IF_NO_GC(RETAIN(handle);)
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return AUTORELEASE(handle);
}
}
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return nil;
}
- (id) copyWithZone: (NSZone*)zone
{
return RETAIN(self);
@ -2008,7 +2054,8 @@ static Class tcpPortClass;
NSFreeMapTable(handles);
handles = 0;
}
DESTROY(tlsopts);
DESTROY(tlscopts);
DESTROY(tlssopts);
DESTROY(host);
TEST_RELEASE(address);
DESTROY(myLock);
@ -2112,32 +2159,6 @@ static Class tcpPortClass;
}
#endif
- (id) conversation: (NSPort*)recvPort
{
NSMapEnumerator me;
void *dummy;
GSTcpHandle *handle = nil;
M_LOCK(myLock);
/*
* Enumerate all our socket handles, and look for one with port.
*/
me = NSEnumerateMapTable(handles);
while (NSNextMapEnumeratorPair(&me, &dummy, (void**)&handle))
{
if ((NSPort*) [handle recvPort] == recvPort)
{
IF_NO_GC(RETAIN(handle);)
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return AUTORELEASE(handle);
}
}
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return nil;
}
- (GSTcpHandle*) handleForPort: (NSSocketPort*)recvPort
beforeDate: (NSDate*)when
{
@ -2320,16 +2341,6 @@ static Class tcpPortClass;
return NO;
}
- (NSDictionary*) optionsForTLS
{
NSDictionary *opts;
M_LOCK(myLock);
opts = RETAIN(tlsopts);
M_UNLOCK(myLock);
return AUTORELEASE(opts);
}
- (uint16_t) portNumber
{
return portNum;
@ -2390,7 +2401,7 @@ static Class tcpPortClass;
[handle setState: GS_H_ACCEPT];
#if defined(HAVE_GNUTLS)
NSDictionary *o;
if ((o = [self optionsForTLS]) != nil)
if ((o = [self serverOptionsForTLS]) != nil)
{
handle->session = [[GSTLSSession alloc]
initWithOptions: o
@ -2695,12 +2706,33 @@ static Class tcpPortClass;
return sent;
}
/** Sets the TLS options for network connections created by this port.
- (NSDictionary*) serverOptionsForTLS
{
NSDictionary *opts;
M_LOCK(myLock);
opts = RETAIN(tlssopts);
M_UNLOCK(myLock);
return AUTORELEASE(opts);
}
/** Sets the TLS options for network connections created by this port
* acting as a network client.
*/
- (void) setOptionsForTLS: (NSDictionary*)options
- (void) setClientOptionsForTLS: (NSDictionary*)options
{
M_LOCK(myLock);
ASSIGNCOPY(tlsopts, options);
ASSIGNCOPY(tlscopts, options);
M_UNLOCK(myLock);
}
/** Sets the TLS options for network connections created by this port
* acting as a network server.
*/
- (void) setServerOptionsForTLS: (NSDictionary*)options
{
M_LOCK(myLock);
ASSIGNCOPY(tlssopts, options);
M_UNLOCK(myLock);
}