Index: src/XMPPConnection.h ================================================================== --- src/XMPPConnection.h +++ src/XMPPConnection.h @@ -214,18 +214,20 @@ - (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: (OFString*)text; - (void)XMPP_handleIQ: (XMPPIQ*)iq; - (void)XMPP_handleMessage: (XMPPMessage*)message; - (void)XMPP_handlePresence: (XMPPPresence*)presence; - (void)XMPP_handleFeatures: (OFXMLElement*)element; -- (void)XMPP_sendResourceBind; - (void)XMPP_handleResourceBind: (XMPPIQ*)iq; - (void)XMPP_sendSession; - (void)XMPP_handleSession: (XMPPIQ*)iq; - (OFString*)XMPP_IDNAToASCII: (OFString*)domain; @end @interface OFObject (XMPPConnectionDelegate) @end Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -412,22 +412,42 @@ attributes: (OFArray*)attributes { OFEnumerator *enumerator; OFXMLAttribute *attribute; - if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || - ![ns isEqual: XMPP_NS_STREAM]) { - of_log(@"Did not get expected stream start!"); - assert(0); + if (![name isEqual: @"stream"]) { + // No dedicated stream error for this, may not even be XMPP + [self close]; + [sock close]; + return; + } + + if (![prefix isEqual: @"stream"]) { + [self XMPP_sendStreamError: @"bad-namespace-prefix" + text: nil]; + return; + } + + if (![ns isEqual: XMPP_NS_STREAM]) { + [self XMPP_sendStreamError: @"invalid-namespace" + text: nil]; + return; } enumerator = [attributes objectEnumerator]; while ((attribute = [enumerator nextObject]) != nil) { if ([[attribute name] isEqual: @"from"] && ![[attribute stringValue] isEqual: domain]) { - of_log(@"Got invalid from in stream start!"); - assert(0); + [self XMPP_sendStreamError: @"invalid-from" + text: nil]; + return; + } + if ([[attribute name] isEqual: @"version"] && + ![[attribute stringValue] isEqual: @"1.0"]) { + [self XMPP_sendStreamError: @"unsupported-version" + text: nil]; + return; } } [parser setDelegate: elementBuilder]; } @@ -532,11 +552,12 @@ [self XMPP_handlePresence: [XMPPPresence stanzaWithElement: element]]; return; } - assert(0); + [self XMPP_sendStreamError: @"unsupported-stanza-type" + text: nil]; } - (void)XMPP_handleStream: (OFXMLElement*)element { @@ -882,10 +903,30 @@ [self sendIQ: iq withCallbackObject: self selector: @selector(XMPP_handleResourceBind:)]; } + +- (void)XMPP_sendStreamError: (OFString*)condition + text: (OFString*)text +{ + OFXMLElement *error = [OFXMLElement + elementWithName: @"error" + namespace: XMPP_NS_STREAM]; + [error setPrefix: @"stream" + forNamespace: XMPP_NS_STREAM]; + [error addChild: [OFXMLElement elementWithName: condition + namespace: XMPP_NS_XMPP_STREAM]]; + if (text) + [error addChild: [OFXMLElement + elementWithName: @"text" + namespace: XMPP_NS_XMPP_STREAM + stringValue: text]]; + [parser setDelegate: nil]; + [self sendStanza: error]; + [self close]; +} - (void)XMPP_handleResourceBind: (XMPPIQ*)iq { OFXMLElement *bindElement; OFXMLElement *jidElement;