From eac843e29e1846b46c390920c2ae4a55dd51d3ee Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Tue, 4 Jul 2000 14:37:18 +0000 Subject: [PATCH] Updates for message authentication stuff git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6871 72102866-910b-0410-8b05-ffd578937521 --- Headers/gnustep/base/NSConnection.h | 10 +++++++--- Headers/gnustep/base/NSPortCoder.h | 3 --- Source/GSTcpPort.m | 12 ++++++----- Source/NSConnection.m | 12 +++++++---- Source/NSPortCoder.m | 30 ++++++++++++++++------------ Source/NSPortMessage.m | 4 ++-- Testing/client.m | 31 +++++++++++++++++++++++++++++ Testing/server.m | 24 ++++++++++++++++++++++ 8 files changed, 96 insertions(+), 30 deletions(-) diff --git a/Headers/gnustep/base/NSConnection.h b/Headers/gnustep/base/NSConnection.h index ae082989d..f7656a251 100644 --- a/Headers/gnustep/base/NSConnection.h +++ b/Headers/gnustep/base/NSConnection.h @@ -187,10 +187,14 @@ GS_EXPORT NSString *ConnectionBecameInvalidNotification; - (NSConnection*) connection: (NSConnection*)ancestorConn didConnect: (NSConnection*)newConn; - -- (BOOL) authenticateComponents: (NSArray*)components +/* + * These are like the MacOS-X delegate methods, except that we provide the + * components in mutable arrays, so that the delegate can alter the data + * items in the array. Of course, you must do that WITH CARE. + */ +- (BOOL) authenticateComponents: (NSMutableArray*)components withData: (NSData*)authenticationData; -- (NSData*) authenticationDataForComponents: (NSArray*)components; +- (NSData*) authenticationDataForComponents: (NSMutableArray*)components; @end diff --git a/Headers/gnustep/base/NSPortCoder.h b/Headers/gnustep/base/NSPortCoder.h index 0a5c2f853..e2947c2f2 100644 --- a/Headers/gnustep/base/NSPortCoder.h +++ b/Headers/gnustep/base/NSPortCoder.h @@ -43,9 +43,6 @@ BOOL _encodingRoot; BOOL _initialPass; id _dst; /* Serialization destination. */ - IMP _eSerImp; /* Method to serialize with. */ - IMP _eTagImp; /* Serialize a type tag. */ - IMP _xRefImp; /* Serialize a crossref. */ IMP _eObjImp; /* Method to encode an id. */ IMP _eValImp; /* Method to encode others. */ #ifndef _IN_PORT_CODER_M diff --git a/Source/GSTcpPort.m b/Source/GSTcpPort.m index fc03b9576..8ea861c00 100644 --- a/Source/GSTcpPort.m +++ b/Source/GSTcpPort.m @@ -517,6 +517,7 @@ static Class runLoopClass; [pm setMsgid: rId]; rId = 0; DESTROY(rItems); + NSDebugMLLog(@"GSTcpHandle", @"got message %@", pm); [rp handlePortMessage: pm]; RELEASE(pm); } @@ -664,6 +665,7 @@ static Class runLoopClass; * For a zero-length data chunk, we create an empty * data object and add it to the current message. */ + rType = GSP_NONE; /* ready for a new item */ rLength -= rWant; if (rLength > 0) { @@ -699,7 +701,7 @@ static Class runLoopClass; { GSPortMsgHeader *h; - rType = GSP_NONE; + rType = GSP_NONE; /* ready for a new item */ /* * We have read a message header - set up to read the * remainder of the message. @@ -756,7 +758,7 @@ static Class runLoopClass; { NSData *d; - rType = GSP_NONE; + rType = GSP_NONE; /* ready for a new item */ d = [mutableDataClass allocWithZone: NSDefaultMallocZone()]; d = [d initWithBytes: bytes length: rWant]; [rItems addObject: d]; @@ -777,7 +779,7 @@ static Class runLoopClass; { GSTcpPort *p; - rType = GSP_NONE; + rType = GSP_NONE; /* ready for a new item */ p = decodePort(rData); /* * Set up to read another item header. @@ -931,8 +933,8 @@ static Class runLoopClass; BOOL sent = NO; NSAssert([components count] > 0, NSInternalInconsistencyException); - NSDebugMLLog(@"GSTcpHandle", @"Sending message 0x%x on 0x%x(%d) before %@", - components, self, desc, when); + NSDebugMLLog(@"GSTcpHandle", @"Sending message 0x%x %@ on 0x%x(%d) before %@", + components, components, self, desc, when); [wMsgs addObject: components]; l = [runLoopClass currentRunLoop]; diff --git a/Source/NSConnection.m b/Source/NSConnection.m index c9e2f854b..b61a11403 100644 --- a/Source/NSConnection.m +++ b/Source/NSConnection.m @@ -1458,19 +1458,22 @@ static NSLock *global_proxies_gate; return; } - if (_authenticateIn == YES) + if (conn->_authenticateIn == YES + && (type == METHOD_REQUEST || type == METHOD_REPLY)) { NSData *d; unsigned count = [components count]; - d = AUTORELEASE(RETAIN([components objectAtIndex: --count])); + d = RETAIN([components objectAtIndex: --count]); [components removeObjectAtIndex: count]; - if ([[self delegate] authenticateComponents: components + if ([[conn delegate] authenticateComponents: components withData: d] == NO) { + RELEASE(d); [NSException raise: NSFailedAuthenticationException format: @"message not authenticated by delegate"]; } + RELEASE(d); } rmc = [conn _makeInRmc: components]; @@ -1995,7 +1998,8 @@ static NSLock *global_proxies_gate; BOOL needsReply = NO; NSMutableArray *components = [c _components]; - if (_authenticateOut == YES) + if (_authenticateOut == YES + && (msgid == METHOD_REQUEST || msgid == METHOD_REPLY)) { NSData *d; diff --git a/Source/NSPortCoder.m b/Source/NSPortCoder.m index 56681cb93..0de61f458 100644 --- a/Source/NSPortCoder.m +++ b/Source/NSPortCoder.m @@ -295,18 +295,27 @@ typeCheck(char t1, char t2) @implementation NSPortCoder +@class NSMutableDataMalloc; + static Class connectionClass; static Class mutableArrayClass; static Class mutableDataClass; static Class mutableDictionaryClass; +static IMP _eSerImp; /* Method to serialize with. */ +static IMP _eTagImp; /* Serialize a type tag. */ +static IMP _xRefImp; /* Serialize a crossref. */ + + (void) initialize { if (self == [NSPortCoder class]) { connectionClass = [NSConnection class]; mutableArrayClass = [NSMutableArray class]; - mutableDataClass = [NSMutableData class]; + mutableDataClass = [NSMutableDataMalloc class]; + _eSerImp = [mutableDataClass instanceMethodForSelector: eSerSel]; + _eTagImp = [mutableDataClass instanceMethodForSelector: eTagSel]; + _xRefImp = [mutableDataClass instanceMethodForSelector: xRefSel]; mutableDictionaryClass = [NSMutableDictionary class]; } } @@ -330,6 +339,7 @@ static Class mutableDictionaryClass; - (void) dealloc { + RELEASE(_dst); /* Decoders retain their output data object. */ RELEASE(_comp); RELEASE(_conn); RELEASE(_cInfo); @@ -1683,14 +1693,10 @@ static Class mutableDictionaryClass; _dst = [mutableDataClass allocWithZone: _zone]; _dst = [_dst initWithLength: _cursor]; [_comp addObject: _dst]; - RELEASE(_dst); /* * Cache method implementations for writing into data object etc */ - _eSerImp = [_dst methodForSelector: eSerSel]; - _eTagImp = [_dst methodForSelector: eTagSel]; - _xRefImp = [_dst methodForSelector: xRefSel]; _eObjImp = [self methodForSelector: eObjSel]; _eValImp = [self methodForSelector: eValSel]; @@ -1709,16 +1715,14 @@ static Class mutableDictionaryClass; } else { - unsigned count; - /* - * If re-initialising, we just need to empty the old stuff. + * If re-initialising, we need to empty the old stuff. + * NB. Our _dst object may have been removed from the _comp + * array elsewhere, so we empty the _comp array and then re-add + * _dst */ - count = [_comp count]; - while (count-- > 1) - { - [_comp removeObjectAtIndex: count]; - } + [_comp removeAllObjects]; + [_comp addObject: _dst]; [_dst setLength: _cursor]; GSIMapCleanMap(_clsMap); GSIMapCleanMap(_cIdMap); diff --git a/Source/NSPortMessage.m b/Source/NSPortMessage.m index 7309d2f46..b49df9be0 100644 --- a/Source/NSPortMessage.m +++ b/Source/NSPortMessage.m @@ -41,8 +41,8 @@ - (NSString*) description { return [NSString stringWithFormat: - @"NSPortMessage (Id %u)\n Send: %@\n Recv: %@\n Components -\n%@", - _msgid, _send, _recv, _components]; + @"NSPortMessage 0x%x (Id %u)\n Send: %@\n Recv: %@\n Components -\n%@", + self, _msgid, _send, _recv, _components]; } /* PortMessages MUST be initialised with ports and data. */ diff --git a/Testing/client.m b/Testing/client.m index 8551f5e5a..aa613017f 100644 --- a/Testing/client.m +++ b/Testing/client.m @@ -5,12 +5,41 @@ #include #include #include +#include #include #include #include #include #include "server.h" +@interface Auth : NSObject +@end + +@implementation Auth +- (BOOL) authenticateComponents: (NSMutableArray*)components + withData: (NSData*)authData +{ + unsigned count = [components count]; + + while (count-- > 0) + { + id obj = [components objectAtIndex: count]; + + if ([obj isKindOfClass: [NSData class]] == YES) + { + NSMutableData *d = [obj mutableCopy]; + unsigned l = [d length]; + char *p = (char*)[d mutableBytes]; + + while (l-- > 0) + p[l] ^= 42; + [components replaceObjectAtIndex: count withObject: d]; + RELEASE(d); + } + } + return YES; +} +@end int main (int argc, char *argv[]) { @@ -36,6 +65,7 @@ int main (int argc, char *argv[]) BOOL b; const char *type; NSAutoreleasePool *arp = [NSAutoreleasePool new]; + Auth *auth = [Auth new]; GSDebugAllocationActive(YES); [NSConnection setDebug: 10]; @@ -59,6 +89,7 @@ printf("oneway %d\n", _F_ONEWAY); p = [NSConnection rootProxyForConnectionWithRegisteredName:@"test2server" host:nil]; c = [p connectionForProxy]; + [c setDelegate:auth]; [c setRequestTimeout:180.0]; [c setReplyTimeout:180.0]; localObj = [[NSObject alloc] init]; diff --git a/Testing/server.m b/Testing/server.m index 512c2d585..4b559caf1 100644 --- a/Testing/server.m +++ b/Testing/server.m @@ -5,12 +5,36 @@ #include #include #include +#include #include #include #include #include "server.h" @implementation Server +- (NSData*) authenticationDataForComponents: (NSMutableArray*)components +{ + unsigned count = [components count]; + + while (count-- > 0) + { + id obj = [components objectAtIndex: count]; + + if ([obj isKindOfClass: [NSData class]] == YES) + { + NSMutableData *d = [obj mutableCopy]; + unsigned l = [d length]; + char *p = (char*)[d mutableBytes]; + + while (l-- > 0) + p[l] ^= 42; + [components replaceObjectAtIndex: count withObject: d]; + RELEASE(d); + } + } + return [NSData data]; +} + - init { the_array = [[NSMutableArray alloc] init];