Security code enhancement

This commit is contained in:
Richard Frith-Macdonald 2021-06-18 10:32:45 +01:00
parent d0e74e3793
commit 1ed666cf0b
3 changed files with 122 additions and 23 deletions

View file

@ -1,3 +1,12 @@
2021-06-18 Richard Frith-Macdonald <rfm@gnu.org>
* EcCommand.m:
* EcProcess.m:
Pass TLS information from Command server to clients via pipe, so the
clients can use a key/certificate shared with the Command server to
encrypt communications. This avoids each client process having to
do expensive generation of a key.
2021-06-17 Richard Frith-Macdonald <rfm@gnu.org>
* EcCommand.m:

View file

@ -29,6 +29,12 @@
#import <Foundation/Foundation.h>
#import <GNUstepBase/GSConfig.h>
#if GS_USE_GNUTLS
#import <GNUstepBase/GSTLS.h>
#endif
#import "EcProcess.h"
#import "EcAlarm.h"
#import "EcClientI.h"
@ -1425,6 +1431,75 @@ valgrindLog(NSString *name)
[defs setObject: @"0" forKey: @"CoreSize"];
}
#if GS_USE_GNUTLS
/* If TLS is supported, all Distributed Object communications
* between our processes must be encrypted. Generally we can
* use shared certificate/key passed to our subprocesses on
* launch, so the subprocesses don't need to waste a lot of
* CPU (and real) time generating their own keys.
*/
if ([defs objectForKey: @"NSSocketPortOptionsForTLS"] == nil)
{
NSUserDefaults *defs = [command cmdDefaults];
NSMutableDictionary *opts;
id opt;
opts = [NSMutableDictionary dictionary];
/* If no certificate key was provided in the Command server
* configuration, we use our self-signed certificate key,
* generating it if necessary.
*/
opt = [defs objectForKey: GSTLSCertificateKeyFile];
if (nil == opt)
{
opt = [GSTLSObject dataForTLSFile: @"self-signed-key"];
if (nil == opt)
{
(void)[GSTLSCredentials selfSigned: YES];
opt = [GSTLSObject
dataForTLSFile: @"self-signed-key"];
}
}
if (opt)
{
[opts setObject: opt forKey: GSTLSCertificateKeyFile];
}
/* If no certificate was provided in the Command server
* configuration, we use our self-signed certificate,
* generating it if necessary.
*/
opt = [defs objectForKey: GSTLSCertificateFile];
if (nil == opt)
{
opt = [GSTLSObject dataForTLSFile: @"self-signed-crt"];
}
if (opt)
{
[opts setObject: opt forKey: GSTLSCertificateFile];
}
/* Pass on the TLS debug settings from the Command server
* configuration to the client.
*/
if ((opt = [defs objectForKey: GSTLSDebug]) != nil)
{
[opts setObject: opt forKey: GSTLSDebug];
}
/* Pass on the TLS priority settings from the Command server
* configuration to the client.
*/
if ((opt = [defs objectForKey: GSTLSPriority]) != nil)
{
[opts setObject: opt forKey: GSTLSPriority];
}
[defs setObject: opts forKey: @"NSSocketPortOptionsForTLS"];
}
#endif
/* Now we need to make the key/value pairs into a serialised
* form to be passed to the subprocess using a pipe.
*/

View file

@ -26,30 +26,13 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSConnection.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSDebug.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSDistantObject.h>
#import <Foundation/NSException.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSNotification.h>
#import <Foundation/NSObjCRuntime.h>
#import <Foundation/NSPort.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSRunLoop.h>
#import <Foundation/NSScanner.h>
#import <Foundation/NSSerialization.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimer.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <Foundation/Foundation.h>
#import <GNUstepBase/GSObjCRuntime.h>
#import <GNUstepBase/NSObject+GNUstepBase.h>
#if GS_USE_GNUTLS
#import <GNUstepBase/GSTLS.h>
#endif
#import "EcProcess.h"
#import "EcLogger.h"
@ -1642,6 +1625,37 @@ findMode(NSDictionary* d, NSString* s)
[cmdDefs removeVolatileDomainForName: NSArgumentDomain];
[cmdDefs setVolatileDomain: m forName: NSArgumentDomain];
}
#if GS_USE_GNUTLS
if ([NSSocketPort respondsToSelector: @selector(setOptionsForTLS:)])
{
defs = [cmdDefs dictionaryForKey: @"NSSocketPortOptionsForTLS"];
if (defs != nil)
{
NSMutableDictionary *opts = AUTORELEASE([defs mutableCopy]);
id o;
/* If we were passed data rather than filenames
* we must set it up as cached data corresponding
* to well known names.
*/
o = [opts objectForKey: GSTLSCertificateKeyFile];
if ([o isKindOfClass: [NSData class]])
{
[GSTLSObject setData: o forTLSFile: @"self-signed-key"];
[opts setObject: @"self-signed-key"
forKey: GSTLSCertificateKeyFile];
}
o = [opts objectForKey: GSTLSCertificateFile];
if ([o isKindOfClass: [NSData class]])
{
[GSTLSObject setData: o forTLSFile: @"self-signed-crt"];
[opts setObject: @"self-signed-crt"
forKey: GSTLSCertificateFile];
}
[NSSocketPort setOptionsForTLS: opts];
}
}
#endif
}
cmdUser = EC_EFFECTIVE_USER;
@ -3118,13 +3132,14 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
{
if (nil == ecLock)
{
/* Enable encrypted DO if supported bu the base library.
#if GS_USE_GNUTLS
/* Enable encrypted DO if supported by the base library.
*/
if ([NSSocketPort respondsToSelector: @selector(setOptionsForTLS:)])
{
[NSSocketPort setOptionsForTLS: [NSDictionary dictionary]];
}
#endif
ecLock = [NSRecursiveLock new];
dateClass = [NSDate class];
cDateClass = [NSCalendarDate class];