From 3e150f18d6c9c963db1e43e22ac7222a0329ab56 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Mon, 3 Feb 2014 23:36:13 +0100 Subject: [PATCH] XMPPConnection: Verify origin of IQ responses --- src/XMPPConnection.m | 59 ++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index b516880..0135872 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -563,15 +563,25 @@ { OFAutoreleasePool *pool; XMPPCallback *callback; - - if (![IQ ID]) - [IQ setID: [self generateStanzaID]]; + OFString *ID, *key; pool = [[OFAutoreleasePool alloc] init]; + + if ((ID = [IQ ID]) == nil) { + ID = [self generateStanzaID]; + [IQ setID: ID]; + } + + if ((key = [[IQ to] fullJID]) == nil) + key = [_JID bareJID]; + if (key == nil) // Only happens for resource bind + key = @"bind"; + key = [key stringByAppendingString: ID]; + callback = [XMPPCallback callbackWithTarget: target selector: selector]; [_callbacks setObject: callback - forKey: [IQ ID]]; + forKey: key]; [pool release]; [self sendStanza: IQ]; @@ -583,14 +593,24 @@ { OFAutoreleasePool *pool; XMPPCallback *callback; - - if (![IQ ID]) - [IQ setID: [self generateStanzaID]]; + OFString *ID, *key; pool = [[OFAutoreleasePool alloc] init]; + + if ((ID = [IQ ID]) == nil) { + ID = [self generateStanzaID]; + [IQ setID: ID]; + } + + if ((key = [[IQ to] fullJID]) == nil) + key = [_JID bareJID]; + if (key == nil) // Connection not yet bound, can't send stanzas + @throw [OFInvalidArgumentException exception]; + key = [key stringByAppendingString: ID]; + callback = [XMPPCallback callbackWithBlock: block]; [_callbacks setObject: callback - forKey: [IQ ID]]; + forKey: key]; [pool release]; [self sendStanza: IQ]; @@ -958,26 +978,33 @@ assert(0); } -- (void)XMPP_handleIQ: (XMPPIQ*)iq +- (void)XMPP_handleIQ: (XMPPIQ*)IQ { bool handled = false; XMPPCallback *callback; + OFString *key; - if ((callback = [_callbacks objectForKey: [iq ID]])) { - [callback runWithIQ: iq + if ((key = [[IQ from] fullJID]) == nil) + key = [_JID bareJID]; + if (key == nil) // Only happens for resource bind + key = @"bind"; + key = [key stringByAppendingString: [IQ ID]]; + + if ((callback = [_callbacks objectForKey: key])) { + [callback runWithIQ: IQ connection: self]; - [_callbacks removeObjectForKey: [iq ID]]; + [_callbacks removeObjectForKey: key]; return; } handled = [_delegates broadcastSelector: @selector( connection:didReceiveIQ:) withObject: self - withObject: iq]; + withObject: IQ]; - if (!handled && ![[iq type] isEqual: @"error"] && - ![[iq type] isEqual: @"result"]) { - [self sendStanza: [iq errorIQWithType: @"cancel" + if (!handled && ![[IQ type] isEqual: @"error"] && + ![[IQ type] isEqual: @"result"]) { + [self sendStanza: [IQ errorIQWithType: @"cancel" condition: @"service-unavailable"]]; } }