@@ -56,24 +56,51 @@ #import "namespaces.h" #import #define BUFFER_LENGTH 512 + +OF_ASSUME_NONNULL_BEGIN + +@interface XMPPConnection () +- (void)XMPP_startStream; +- (void)XMPP_handleStream: (OFXMLElement *)element; +- (void)XMPP_handleTLS: (OFXMLElement *)element; +- (void)XMPP_handleSASL: (OFXMLElement *)element; +- (void)XMPP_handleStanza: (OFXMLElement *)element; +- (void)XMPP_sendAuth: (OFString *)authName; +- (void)XMPP_sendResourceBind; +- (void)XMPP_sendStreamError: (OFString *)condition + text: (nullable OFString *)text; +- (void)XMPP_handleIQ: (XMPPIQ *)IQ; +- (void)XMPP_handleMessage: (XMPPMessage *)message; +- (void)XMPP_handlePresence: (XMPPPresence *)presence; +- (void)XMPP_handleFeatures: (OFXMLElement *)element; +- (void)XMPP_handleResourceBindForConnection: (XMPPConnection *)connection + IQ: (XMPPIQ *)IQ; +- (void)XMPP_sendSession; +- (void)XMPP_handleSessionForConnection: (XMPPConnection *)connection + IQ: (XMPPIQ *)IQ; +- (OFString *)XMPP_IDNAToASCII: (OFString *)domain; +- (XMPPMulticastDelegate *)XMPP_delegates; +@end @interface XMPPConnection_ConnectThread: OFThread { OFThread *_sourceThread; XMPPConnection *_connection; } -- initWithSourceThread: (OFThread*)sourceThread - connection: (XMPPConnection*)connection; +- initWithSourceThread: (OFThread *)sourceThread + connection: (XMPPConnection *)connection; @end + +OF_ASSUME_NONNULL_END @implementation XMPPConnection_ConnectThread -- initWithSourceThread: (OFThread*)sourceThread - connection: (XMPPConnection*)connection +- initWithSourceThread: (OFThread *)sourceThread + connection: (XMPPConnection *)connection { self = [super init]; @try { _sourceThread = [sourceThread retain]; @@ -116,11 +143,13 @@ return nil; } @end @implementation XMPPConnection -@synthesize language = _language, privateKeyFile = _privateKeyFile; +@synthesize username = _username, resource = _resource, server = _server; +@synthesize domain = _domain, password = _password, language = _language; +@synthesize privateKeyFile = _privateKeyFile; @synthesize certificateFile = _certificateFile, socket = _socket; @synthesize encryptionRequired = _encryptionRequired, encrypted = _encrypted; @synthesize supportsRosterVersioning = _supportsRosterVersioning; @synthesize supportsStreamManagement = _supportsStreamManagement; @@ -163,11 +192,11 @@ [_authModule release]; [super dealloc]; } -- (void)setUsername: (OFString*)username +- (void)setUsername: (OFString *)username { OFString *old = _username; if (username != nil) { char *node; @@ -189,16 +218,11 @@ _username = nil; [old release]; } -- (OFString*)username -{ - return [[_username copy] autorelease]; -} - -- (void)setResource: (OFString*)resource +- (void)setResource: (OFString *)resource { OFString *old = _resource; if (resource != nil) { char *res; @@ -220,16 +244,11 @@ _resource = nil; [old release]; } -- (OFString*)resource -{ - return [[_resource copy] autorelease]; -} - -- (void)setServer: (OFString*)server +- (void)setServer: (OFString *)server { OFString *old = _server; if (server != nil) _server = [self XMPP_IDNAToASCII: server]; @@ -237,16 +256,11 @@ _server = nil; [old release]; } -- (OFString*)server -{ - return [[_server copy] autorelease]; -} - -- (void)setDomain: (OFString*)domain +- (void)setDomain: (OFString *)domain { OFString *oldDomain = _domain; OFString *oldDomainToASCII = _domainToASCII; if (domain != nil) { @@ -274,16 +288,11 @@ [oldDomain release]; [oldDomainToASCII release]; } -- (OFString*)domain -{ - return [[_domain copy] autorelease]; -} - -- (void)setPassword: (OFString*)password +- (void)setPassword: (OFString *)password { OFString *old = _password; if (password != nil) { char *pass; @@ -305,15 +314,10 @@ _password = nil; [old release]; } -- (OFString*)password -{ - return [[_password copy] autorelease]; -} - - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; XMPPSRVEntry *candidate = nil; XMPPSRVLookup *SRVLookup = nil; @@ -380,11 +384,11 @@ connection: self] autorelease] start]; [pool release]; } -- (bool)XMPP_parseBuffer: (const void*)buffer +- (bool)XMPP_parseBuffer: (const void *)buffer length: (size_t)length { if ([_socket isAtEndOfStream]) { [_delegates broadcastSelector: @selector(connectionWasClosed:) withObject: self]; @@ -402,11 +406,11 @@ } return true; } -- (void)parseBuffer: (const void*)buffer +- (void)parseBuffer: (const void *)buffer length: (size_t)length { [self XMPP_parseBuffer: buffer length: length]; @@ -415,14 +419,14 @@ _oldParser = nil; _oldElementBuilder = nil; } -- (bool)stream: (OFStream*)stream - didReadIntoBuffer: (char*)buffer +- (bool)stream: (OFStream *)stream + didReadIntoBuffer: (char *)buffer length: (size_t)length - exception: (OFException*)exception + exception: (OFException *)exception { if (exception != nil) { [_delegates broadcastSelector: @selector(connection: didThrowException:) withObject: self @@ -467,11 +471,11 @@ - (bool)streamOpen { return _streamOpen; } -- (bool)checkCertificateAndGetReason: (OFString**)reason +- (bool)checkCertificateAndGetReason: (OFString **)reason { X509Certificate *cert; OFDictionary *SANs; bool serviceSpecific = false; @@ -503,20 +507,20 @@ return true; return false; } -- (void)sendStanza: (OFXMLElement*)element +- (void)sendStanza: (OFXMLElement *)element { [_delegates broadcastSelector: @selector(connection:didSendElement:) withObject: self withObject: element]; [_socket writeString: [element XMLString]]; } -- (void)sendIQ: (XMPPIQ*)IQ +- (void)sendIQ: (XMPPIQ *)IQ callbackTarget: (id)target selector: (SEL)selector { OFAutoreleasePool *pool; XMPPCallback *callback; @@ -543,11 +547,11 @@ [self sendStanza: IQ]; } #ifdef OF_HAVE_BLOCKS -- (void)sendIQ: (XMPPIQ*)IQ +- (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (xmpp_callback_block_t)block { OFAutoreleasePool *pool; XMPPCallback *callback; OFString *ID, *key; @@ -572,24 +576,21 @@ [self sendStanza: IQ]; } #endif -- (OFString*)generateStanzaID +- (OFString *)generateStanzaID { return [OFString stringWithFormat: @"objxmpp_%u", _lastID++]; } -- (void)parser: (OFXMLParser*)p - didStartElement: (OFString*)name - prefix: (OFString*)prefix - namespace: (OFString*)ns - attributes: (OFArray*)attributes -{ - OFEnumerator *enumerator; - OFXMLAttribute *attribute; - +- (void)parser: (OFXMLParser *)parser + didStartElement: (OFString *)name + prefix: (OFString *)prefix + namespace: (OFString *)NS + attributes: (OFArray *)attributes +{ if (![name isEqual: @"stream"]) { // No dedicated stream error for this, may not even be XMPP [self close]; [_socket close]; return; @@ -599,18 +600,17 @@ [self XMPP_sendStreamError: @"bad-namespace-prefix" text: nil]; return; } - if (![ns isEqual: XMPP_NS_STREAM]) { + if (![NS isEqual: XMPP_NS_STREAM]) { [self XMPP_sendStreamError: @"invalid-namespace" text: nil]; return; } - enumerator = [attributes objectEnumerator]; - while ((attribute = [enumerator nextObject]) != nil) { + for (OFXMLAttribute *attribute in attributes) { if ([[attribute name] isEqual: @"from"] && ![[attribute stringValue] isEqual: _domain]) { [self XMPP_sendStreamError: @"invalid-from" text: nil]; return; @@ -621,15 +621,15 @@ text: nil]; return; } } - [_parser setDelegate: _elementBuilder]; + [parser setDelegate: _elementBuilder]; } -- (void)elementBuilder: (OFXMLElementBuilder*)builder - didBuildElement: (OFXMLElement*)element +- (void)elementBuilder: (OFXMLElementBuilder *)builder + didBuildElement: (OFXMLElement *)element { /* Ignore whitespace elements */ if ([element name] == nil) return; @@ -652,14 +652,14 @@ if ([[element namespace] isEqual: XMPP_NS_SASL]) [self XMPP_handleSASL: element]; } -- (void)elementBuilder: (OFXMLElementBuilder*)builder - didNotExpectCloseTag: (OFString*)name - prefix: (OFString*)prefix - namespace: (OFString*)ns +- (void)elementBuilder: (OFXMLElementBuilder *)builder + didNotExpectCloseTag: (OFString *)name + prefix: (OFString *)prefix + namespace: (OFString *)ns { if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || ![ns isEqual: XMPP_NS_STREAM]) @throw [OFMalformedXMLException exception]; else { @@ -720,11 +720,11 @@ _streamOpen = _needsSession = _encrypted = false; _supportsRosterVersioning = _supportsStreamManagement = false; _lastID = 0; } -- (void)XMPP_handleStanza: (OFXMLElement*)element +- (void)XMPP_handleStanza: (OFXMLElement *)element { if ([[element name] isEqual: @"iq"]) { [self XMPP_handleIQ: [XMPPIQ stanzaWithElement: element]]; return; } @@ -744,11 +744,11 @@ [self XMPP_sendStreamError: @"unsupported-stanza-type" text: nil]; } -- (void)XMPP_handleStream: (OFXMLElement*)element +- (void)XMPP_handleStream: (OFXMLElement *)element { if ([[element name] isEqual: @"features"]) { [self XMPP_handleFeatures: element]; return; } @@ -848,11 +848,11 @@ } assert(0); } -- (void)XMPP_handleTLS: (OFXMLElement*)element +- (void)XMPP_handleTLS: (OFXMLElement *)element { if ([[element name] isEqual: @"proceed"]) { /* FIXME: Catch errors here */ SSLSocket *newSock; @@ -889,11 +889,11 @@ @throw [OFException exception]; assert(0); } -- (void)XMPP_handleSASL: (OFXMLElement*)element +- (void)XMPP_handleSASL: (OFXMLElement *)element { if ([[element name] isEqual: @"challenge"]) { OFXMLElement *responseTag; OFDataArray *challenge = [OFDataArray dataArrayWithBase64EncodedString: [element stringValue]]; @@ -937,11 +937,11 @@ } assert(0); } -- (void)XMPP_handleIQ: (XMPPIQ*)IQ +- (void)XMPP_handleIQ: (XMPPIQ *)IQ { bool handled = false; XMPPCallback *callback; OFString *key; @@ -968,25 +968,25 @@ [self sendStanza: [IQ errorIQWithType: @"cancel" condition: @"service-unavailable"]]; } } -- (void)XMPP_handleMessage: (XMPPMessage*)message +- (void)XMPP_handleMessage: (XMPPMessage *)message { [_delegates broadcastSelector: @selector(connection:didReceiveMessage:) withObject: self withObject: message]; } -- (void)XMPP_handlePresence: (XMPPPresence*)presence +- (void)XMPP_handlePresence: (XMPPPresence *)presence { [_delegates broadcastSelector: @selector(connection:didReceivePresence:) withObject: self withObject: presence]; } -- (void)XMPP_handleFeatures: (OFXMLElement*)element +- (void)XMPP_handleFeatures: (OFXMLElement *)element { OFXMLElement *startTLS = [element elementForName: @"starttls" namespace: XMPP_NS_STARTTLS]; OFXMLElement *bind = [element elementForName: @"bind" namespace: XMPP_NS_BIND]; @@ -1021,11 +1021,11 @@ enumerator = [[mechs children] objectEnumerator]; while ((mech = [enumerator nextObject]) != nil) [mechanisms addObject: [mech stringValue]]; - if (_privateKeyFile && _certificateFile && + if (_privateKeyFile != nil && _certificateFile != nil && [mechanisms containsObject: @"EXTERNAL"]) { _authModule = [[XMPPEXTERNALAuth alloc] init]; [self XMPP_sendAuth: @"EXTERNAL"]; return; } @@ -1061,12 +1061,12 @@ } assert(0); } - if (session != nil && ![session elementForName: @"optional" - namespace: XMPP_NS_SESSION]) + if (session != nil && [session elementForName: @"optional" + namespace: XMPP_NS_SESSION] == nil) _needsSession = true; if (bind != nil) { [self XMPP_sendResourceBind]; return; @@ -1073,11 +1073,11 @@ } assert(0); } -- (void)XMPP_sendAuth: (OFString*)authName +- (void)XMPP_sendAuth: (OFString *)authName { OFXMLElement *authTag; OFDataArray *initialMessage = [_authModule initialMessage]; authTag = [OFXMLElement elementWithName: @"auth" @@ -1117,12 +1117,12 @@ callbackTarget: self selector: @selector(XMPP_handleResourceBindForConnection: IQ:)]; } -- (void)XMPP_sendStreamError: (OFString*)condition - text: (OFString*)text +- (void)XMPP_sendStreamError: (OFString *)condition + text: (OFString *)text { OFXMLElement *error = [OFXMLElement elementWithName: @"error" namespace: XMPP_NS_STREAM]; [error setPrefix: @"stream" @@ -1137,26 +1137,25 @@ [_parser setDelegate: nil]; [self sendStanza: error]; [self close]; } -- (void)XMPP_handleResourceBindForConnection: (XMPPConnection*)connection - IQ: (XMPPIQ*)iq -{ - OFXMLElement *bindElement; - OFXMLElement *jidElement; - - assert([[iq type] isEqual: @"result"]); - - bindElement = [iq elementForName: @"bind" +- (void)XMPP_handleResourceBindForConnection: (XMPPConnection *)connection + IQ: (XMPPIQ *)IQ +{ + OFXMLElement *bindElement, *JIDElement; + + assert([[IQ type] isEqual: @"result"]); + + bindElement = [IQ elementForName: @"bind" namespace: XMPP_NS_BIND]; assert(bindElement != nil); - jidElement = [bindElement elementForName: @"jid" + JIDElement = [bindElement elementForName: @"jid" namespace: XMPP_NS_BIND]; - _JID = [[XMPPJID alloc] initWithString: [jidElement stringValue]]; + _JID = [[XMPPJID alloc] initWithString: [JIDElement stringValue]]; if (_needsSession) { [self XMPP_sendSession]; return; } @@ -1166,33 +1165,33 @@ withObject: _JID]; } - (void)XMPP_sendSession { - XMPPIQ *iq; + XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" + ID: [self generateStanzaID]]; - iq = [XMPPIQ IQWithType: @"set" - ID: [self generateStanzaID]]; - [iq addChild: [OFXMLElement elementWithName: @"session" + [IQ addChild: [OFXMLElement elementWithName: @"session" namespace: XMPP_NS_SESSION]]; - [self sendIQ: iq + + [self sendIQ: IQ callbackTarget: self selector: @selector(XMPP_handleSessionForConnection:IQ:)]; } -- (void)XMPP_handleSessionForConnection: (XMPPConnection*)connection - IQ: (XMPPIQ*)iq +- (void)XMPP_handleSessionForConnection: (XMPPConnection *)connection + IQ: (XMPPIQ *)IQ { - if (![[iq type] isEqual: @"result"]) - assert(0); + if (![[IQ type] isEqual: @"result"]) + OF_ENSURE(0); [_delegates broadcastSelector: @selector(connection:wasBoundToJID:) withObject: self withObject: _JID]; } -- (OFString*)XMPP_IDNAToASCII: (OFString*)domain +- (OFString *)XMPP_IDNAToASCII: (OFString *)domain { OFString *ret; char *cDomain; Idna_rc rc; @@ -1234,10 +1233,10 @@ - (void)removeDelegate: (id )delegate { [_delegates removeDelegate: delegate]; } -- (XMPPMulticastDelegate*)XMPP_delegates +- (XMPPMulticastDelegate *)XMPP_delegates { return _delegates; } @end