MacOS-X compatibility and security updates.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@21096 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2005-04-12 09:48:04 +00:00
parent a9da028540
commit 58692a1d62
6 changed files with 189 additions and 62 deletions

View file

@ -1,3 +1,23 @@
2005-04-12 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSDistributedNotificationCenter.h:
Added GSPublicNotificationCenterType and changed documentation for
NSLocalNotificationCenterType to say it's private to the current user.
* Source/NSDistributedNotificationCenter.m: Changed so that
NSLocalNotificationCenterType is MacOS-X compatible and the new
GSPublicNotificationCenterType works like our old implementation.
* Source/NSPortNameServer.m: Add detailed message about forthcoming
change to make the default port name server deal with message ports
rather than socket ports ... for MacOS-X compatibility and security.
* Source/externs.m: Added GSPublicNotificationCenterType
* Tools/gdnc.m: Changes for new NSDistributedNotificationCenter
behavior.
Overview ... updated distributed notifications to be private to the
owner of the processes by default. Added one-time warning message
for developers that NSConnection will be changing the same way.
These changes discussed a year or two ago (mostly with Alexander),
but nobody ever actually implemented them.
2005-04-05 Adam Fedor <fedor@gnu.org>
* gnustep-base.spec.in: Update make dependancy

View file

@ -53,11 +53,17 @@ typedef enum {
/**
* Type for [NSDistributedNotificationCenter+notificationCenterForType:] -
* localhost broadcast only. This is the only type on OS X.
* localhost current user broadcast only. This is the only type on OS X.
*/
GS_EXPORT NSString* const NSLocalNotificationCenterType;
#ifndef NO_GNUSTEP
/**
* Type of [NSDistributedNotificationCenter+notificationCenterForType:] -
* all users on the local host. This type is available only on GNUstep.
*/
GS_EXPORT NSString* const GSPublicNotificationCenterType;
/**
* Type of [NSDistributedNotificationCenter+notificationCenterForType:] -
* localhost and LAN broadcast. This type is available only on GNUstep.

View file

@ -99,6 +99,7 @@
@implementation NSDistributedNotificationCenter
static NSDistributedNotificationCenter *locCenter = nil;
static NSDistributedNotificationCenter *pubCenter = nil;
static NSDistributedNotificationCenter *netCenter = nil;
+ (id) allocWithZone: (NSZone*)z
@ -122,7 +123,11 @@ static NSDistributedNotificationCenter *netCenter = nil;
/**
* Returns a notification center of the specified type.<br />
* The <code>NSLocalNotificationCenterType</code> provides a shared access to
* a notificatiuon center used by processes on the local host.<br />
* a notification center used by processes on the local host which belong to
* the current user.<br />
* The <code>GSPublicNotificationCenterType</code> provides a shared access to
* a notificatiuon center used by processes on the local host belonging to
* any user.<br />
* The <code>GSNetworkNotificationCenterType</code> provides a shared access to
* a notificatiuon center used by processes on the local network.<br />
* MacOS-X supports only <code>NSLocalNotificationCenterType</code>.
@ -157,6 +162,34 @@ static NSDistributedNotificationCenter *netCenter = nil;
}
return locCenter;
}
else if ([type isEqual: GSPublicNotificationCenterType] == YES)
{
if (pubCenter == nil)
{
[gnustep_global_lock lock];
if (pubCenter == nil)
{
NS_DURING
{
NSDistributedNotificationCenter *tmp;
tmp = (NSDistributedNotificationCenter*)
NSAllocateObject(self, 0, NSDefaultMallocZone());
tmp->_centerLock = [NSRecursiveLock new];
tmp->_type = RETAIN(GSPublicNotificationCenterType);
pubCenter = tmp;
}
NS_HANDLER
{
[gnustep_global_lock unlock];
[localException raise];
}
NS_ENDHANDLER
}
[gnustep_global_lock unlock];
}
return pubCenter;
}
else if ([type isEqual: GSNetworkNotificationCenterType] == YES)
{
if (netCenter == nil)
@ -546,11 +579,25 @@ static NSDistributedNotificationCenter *netCenter = nil;
{
if (_remote == nil)
{
NSString *host = nil;
NSString *service = nil;
NSString *description = nil;
NSString *host = nil;
NSString *service = nil;
NSString *description = nil;
NSPortNameServer *ns = nil;
#ifdef __MINGW__
if (_type == NSLocalNotificationCenterType)
{
ASSIGN(_type, GSPublicNotificationCenterType);
}
#endif
if (_type == NSLocalNotificationCenterType)
{
host = @"";
ns = [NSMessagePortNameServer sharedInstance];
service = GDNC_SERVICE;
description = @"local host";
}
else if (_type == GSPublicNotificationCenterType)
{
/*
* Connect to the NSDistributedNotificationCenter for this host.
@ -559,7 +606,6 @@ static NSDistributedNotificationCenter *netCenter = nil;
stringForKey: @"NSHost"];
if (host == nil)
{
//host = @"localhost";
host = @"";
}
else
@ -591,6 +637,7 @@ static NSDistributedNotificationCenter *netCenter = nil;
|| [host isEqualToString: @"localhost"] == YES
|| [host isEqualToString: @"127.0.0.1"] == YES)
{
host = @"";
description = @"local host";
}
else
@ -598,6 +645,7 @@ static NSDistributedNotificationCenter *netCenter = nil;
description = host;
}
service = GDNC_SERVICE;
ns = [NSSocketPortNameServer sharedInstance];
}
else if (_type == GSNetworkNotificationCenterType)
{
@ -610,6 +658,7 @@ static NSDistributedNotificationCenter *netCenter = nil;
description = @"network host";
}
service = GDNC_NETWORK;
ns = [NSSocketPortNameServer sharedInstance];
}
else
{
@ -617,24 +666,17 @@ static NSDistributedNotificationCenter *netCenter = nil;
format: @"Unknown center type - %@", _type];
}
if ([host isEqualToString: @"*"] == YES)
{
_remote = [NSConnection rootProxyForConnectionWithRegisteredName:
service host: host
usingNameServer: [NSSocketPortNameServer sharedInstance]];
}
else
{
_remote = [NSConnection rootProxyForConnectionWithRegisteredName:
service host: host];
}
_remote = [NSConnection rootProxyForConnectionWithRegisteredName: service
host: host
usingNameServer: ns];
RETAIN(_remote);
if (_type == NSLocalNotificationCenterType
if (_type == GSPublicNotificationCenterType
&& _remote == nil && [host isEqual: @""] == NO)
{
_remote = [NSConnection rootProxyForConnectionWithRegisteredName:
[service stringByAppendingFormat: @"-%@", host] host: @"*"];
[service stringByAppendingFormat: @"-%@", host] host: @"*"
usingNameServer: ns];
RETAIN(_remote);
}
@ -690,12 +732,16 @@ static NSDistributedNotificationCenter *netCenter = nil;
args = [[NSArray alloc] initWithObjects:
@"-GSNetwork", @"YES", nil];
}
else if (_type == GSPublicNotificationCenterType)
{
args = [[NSArray alloc] initWithObjects:
@"-GSPublic", @"YES", nil];
}
else if ([host length] > 0)
{
args = [[NSArray alloc] initWithObjects:
@"-NSHost", host, nil];
}
[NSTask launchedTaskWithLaunchPath: cmd arguments: args];
[NSTimer scheduledTimerWithTimeInterval: 5.0
invocation: nil

View file

@ -66,21 +66,51 @@
*/
+ (id) systemDefaultPortNameServer
{
#ifndef __MINGW__
/* Must be kept in sync with [NSPort +initialize]. */
if (GSUserDefaultsFlag(GSMacOSXCompatible) == YES
|| [[NSUserDefaults standardUserDefaults]
boolForKey: @"NSPortIsMessagePort"])
if (GSUserDefaultsFlag(GSMacOSXCompatible) == YES)
{
#ifndef __MINGW__
return [NSMessagePortNameServer sharedInstance];
#else
return [NSSocketPortNameServer sharedInstance];
#endif
}
else
{
return [NSSocketPortNameServer sharedInstance];
}
NSString *def = [[NSUserDefaults standardUserDefaults]
stringForKey: @"NSPortIsMessagePort"];
if (def == nil)
{
GSOnceMLog(
@"\nWARNING -\n"
@"while the default nameserver used by NSConnection\n"
@"currently provides ports which can be used for inter-host\n"
@"and inter-user communications, this will be changed so that\n"
@"nsconnections will only work between processes owned by the\n"
@"same account on the same machine. This change is for\n"
@"MacOSX compatibility and for increased security.\n"
@"If your application actually needs to support inter-host\n"
@"or inter-user communications, you need to alter it to explicity\n"
@"use an instance of the NSSocketPortNameServer class to provide\n"
@"name service facilities.\n"
@"To stop this message appearing, set the NSPortIsMessagePort\n"
@"user default\n\n");
return [NSSocketPortNameServer sharedInstance];
}
else if ([def boolValue] == NO)
{
return [NSSocketPortNameServer sharedInstance];
}
else
{
#ifndef __MINGW__
return [NSMessagePortNameServer sharedInstance];
#else
return [NSSocketPortNameServer sharedInstance];
return [NSSocketPortNameServer sharedInstance];
#endif
}
}
}
- (void) dealloc

View file

@ -57,6 +57,7 @@ NSString *NSConnectionDidInitializeNotification = @"NSConnectionDidInitializeNot
*/
NSString *NSLocalNotificationCenterType = @"NSLocalNotificationCenterType";
NSString *GSNetworkNotificationCenterType = @"GSNetworkNotificationCenterType";
NSString *GSPublicNotificationCenterType = @"GSPublicNotificationCenterType";
/*
* NSThread Notifications

View file

@ -363,9 +363,14 @@ ihandler(int sig)
- (id) init
{
NSString *hostname;
NSString *service = GDNC_SERVICE;
BOOL isLocal = NO;
NSString *hostname;
NSString *service;
BOOL isNetwork = NO;
BOOL isPublic = NO;
BOOL isLocal = NO;
NSPort *port;
NSPortNameServer *ns;
NSUserDefaults *defs;
connections = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
@ -373,48 +378,68 @@ ihandler(int sig)
observersForNames = [NSMutableDictionary new];
observersForObjects = [NSMutableDictionary new];
if ([[NSUserDefaults standardUserDefaults] boolForKey: @"GSNetwork"] == YES)
defs = [NSUserDefaults standardUserDefaults];
hostname = [defs stringForKey: @"NSHost"];
if ([hostname length] > 0 || [defs boolForKey: @"GSPublic"] == YES)
{
service = GDNC_NETWORK;
if (hostname == nil || [hostname isEqualToString: @"localhost"] == YES
|| [hostname isEqualToString: @"127.0.0.1"] == YES)
{
hostname = @"";
}
isPublic = YES;
}
hostname = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSHost"];
if ([hostname length] == 0
|| [hostname isEqualToString: @"localhost"] == YES
|| [hostname isEqualToString: @"127.0.0.1"] == YES)
else if ([defs boolForKey: @"GSNetwork"] == YES)
{
isLocal = YES;
}
/*
* If this is the local server for the current host,
* use the loopback network interface. Otherwise
* create a public connection.
*/
if (0 && isLocal == YES && service != GDNC_NETWORK)
{
/* If this code is reactivated, it needs to deal correctly with the
case where NSSocketPort shouldn't be used (because it isn't the
default port). Something like
NSPort *port = [NSMessagePort port];
or just
NSPort *port = [NSPort port];
*/
NSPort *port = [NSSocketPort portWithNumber: 0
onHost: [NSHost localHost]
forceAddress: @"127.0.0.1"
listener: YES];
conn = [[NSConnection alloc] initWithReceivePort: port sendPort: nil];
isNetwork = YES;
}
else
{
conn = [NSConnection defaultConnection];
#ifdef __MINGW__
isPublic = YES;
#else
isLocal = YES;
#endif
}
if (isNetwork)
{
service = GDNC_NETWORK;
ns = [NSSocketPortNameServer sharedInstance];
port = (NSPort*)[NSSocketPort port];
}
else if (isPublic)
{
service = GDNC_SERVICE;
ns = [NSSocketPortNameServer sharedInstance];
if (isLocal == YES)
{
port = (NSPort*)[NSSocketPort portWithNumber: 0
onHost: [NSHost localHost]
forceAddress: @"127.0.0.1"
listener: YES];
}
else
{
port = (NSPort*)[NSSocketPort port];
}
}
else
{
hostname = @"";
service = GDNC_SERVICE;
ns = [NSMessagePortNameServer sharedInstance];
port = (NSPort*)[NSMessagePort port];
}
conn = [[NSConnection alloc] initWithReceivePort: port sendPort: nil];
[conn setRootObject: self];
if (isLocal == YES
if ([hostname length] == 0
|| [[NSHost hostWithName: hostname] isEqual: [NSHost currentHost]] == YES)
{
if ([conn registerName: service] == NO)
if ([conn registerName: service withNameServer: ns] == NO)
{
NSLog(@"gdnc - unable to register with name server as %@ - quiting.",
service);
@ -426,7 +451,6 @@ ihandler(int sig)
{
NSHost *host = [NSHost hostWithName: hostname];
NSPort *port = [conn receivePort];
NSPortNameServer *ns = [NSPortNameServer systemDefaultPortNameServer];
NSArray *a;
unsigned c;