Adjust to ObjFW style

FossilOrigin-Name: 9919057cb8bb237afb11f251210a1764228c46661d5f8290708846fa70c6af83
This commit is contained in:
Jonathan Schleifer 2021-04-29 00:06:23 +00:00
parent 851e7fe676
commit 098092053c
30 changed files with 285 additions and 462 deletions

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2016, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -31,9 +31,7 @@
- (instancetype)initWithAuthcid: (OFString *)authcid - (instancetype)initWithAuthcid: (OFString *)authcid
password: (OFString *)password password: (OFString *)password
{ {
return [self initWithAuthzid: nil return [self initWithAuthzid: nil authcid: authcid password: password];
authcid: authcid
password: password];
} }
- (instancetype)initWithAuthzid: (OFString *)authzid - (instancetype)initWithAuthzid: (OFString *)authzid

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -28,8 +29,7 @@ OF_ASSUME_NONNULL_BEGIN
@class XMPPIQ; @class XMPPIQ;
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
typedef void (^xmpp_callback_block_t)(XMPPConnection *_Nonnull, typedef void (^XMPPCallbackBlock)(XMPPConnection *_Nonnull, XMPPIQ *_Nonnull);
XMPPIQ *_Nonnull);
#endif #endif
@interface XMPPCallback: OFObject @interface XMPPCallback: OFObject
@ -37,22 +37,19 @@ typedef void (^xmpp_callback_block_t)(XMPPConnection *_Nonnull,
id _target; id _target;
SEL _selector; SEL _selector;
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
xmpp_callback_block_t _block; XMPPCallbackBlock _block;
#endif #endif
} }
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
+ (instancetype)callbackWithBlock: (xmpp_callback_block_t)callback; + (instancetype)callbackWithBlock: (XMPPCallbackBlock)callback;
- (instancetype)initWithBlock: (xmpp_callback_block_t)callback; - (instancetype)initWithBlock: (XMPPCallbackBlock)callback;
#endif #endif
+ (instancetype)callbackWithTarget: (id)target + (instancetype)callbackWithTarget: (id)target selector: (SEL)selector;
selector: (SEL)selector; - (instancetype)initWithTarget: (id)target selector: (SEL)selector;
- (instancetype)initWithTarget: (id)target
selector: (SEL)selector;
- (void)runWithIQ: (XMPPIQ *)iq - (void)runWithIQ: (XMPPIQ *)iq connection: (XMPPConnection *)connection;
connection: (XMPPConnection *)connection;
@end @end
OF_ASSUME_NONNULL_END OF_ASSUME_NONNULL_END

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -26,13 +27,13 @@
@implementation XMPPCallback @implementation XMPPCallback
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
+ (instancetype)callbackWithBlock: (xmpp_callback_block_t)block + (instancetype)callbackWithBlock: (XMPPCallbackBlock)block
{ {
return [[(XMPPCallback *)[self alloc] return [[(XMPPCallback *)[self alloc]
initWithBlock: block] autorelease]; initWithBlock: block] autorelease];
} }
- (instancetype)initWithBlock: (xmpp_callback_block_t)block - (instancetype)initWithBlock: (XMPPCallbackBlock)block
{ {
self = [super init]; self = [super init];
@ -47,15 +48,13 @@
} }
#endif #endif
+ (instancetype)callbackWithTarget: (id)target + (instancetype)callbackWithTarget: (id)target selector: (SEL)selector
selector: (SEL)selector
{ {
return [[[self alloc] initWithTarget: target return [[[self alloc] initWithTarget: target
selector: selector] autorelease]; selector: selector] autorelease];
} }
- (instancetype)initWithTarget: (id)target - (instancetype)initWithTarget: (id)target selector: (SEL)selector
selector: (SEL)selector
{ {
self = [super init]; self = [super init];
@ -75,8 +74,7 @@
[super dealloc]; [super dealloc];
} }
- (void)runWithIQ: (XMPPIQ *)IQ - (void)runWithIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection
connection: (XMPPConnection *)connection
{ {
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
if (_block != NULL) if (_block != NULL)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2011, 2012, 2013, 2016, 2017, 2018 * Copyright (c) 2010, 2011, 2012, 2013, 2016, 2017, 2018, 2021
* Jonathan Schleifer <js@heap.zone> * Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
* *
@ -29,7 +29,7 @@
OF_ASSUME_NONNULL_BEGIN OF_ASSUME_NONNULL_BEGIN
#define XMPP_CONNECTION_BUFFER_LENGTH 512 #define XMPPConnectionBufferLength 512
@class XMPPConnection; @class XMPPConnection;
@class XMPPJID; @class XMPPJID;
@ -77,17 +77,15 @@ OF_ASSUME_NONNULL_BEGIN
* @param connection The connection that was bound to a JID * @param connection The connection that was bound to a JID
* @param JID The JID the conecction was bound to * @param JID The JID the conecction was bound to
*/ */
- (void)connection: (XMPPConnection *)connection - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID;
wasBoundToJID: (XMPPJID *)JID;
/*! /*!
* @brief This callback is called when the connection received an IQ stanza. * @brief This callback is called when the connection received an IQ stanza.
* *
* @param connection The connection that received the stanza * @param connection The connection that received the stanza
* @param iq The IQ stanza that was received * @param IQ The IQ stanza that was received
*/ */
- (bool)connection: (XMPPConnection *)connection - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ;
didReceiveIQ: (XMPPIQ *)iq;
/*! /*!
* @brief This callback is called when the connection received a presence * @brief This callback is called when the connection received a presence
@ -148,7 +146,7 @@ OF_ASSUME_NONNULL_BEGIN
@interface XMPPConnection: OFObject @interface XMPPConnection: OFObject
{ {
OFTCPSocket *_socket; OFTCPSocket *_socket;
char _buffer[XMPP_CONNECTION_BUFFER_LENGTH]; char _buffer[XMPPConnectionBufferLength];
OFXMLParser *_parser, *_oldParser; OFXMLParser *_parser, *_oldParser;
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
OFString *_Nullable _username, *_Nullable _password, *_Nullable _server; OFString *_Nullable _username, *_Nullable _password, *_Nullable _server;
@ -309,8 +307,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param length The length of the buffer. If length is 0, it is assumed that * @param length The length of the buffer. If length is 0, it is assumed that
* the connection was closed. * the connection was closed.
*/ */
- (void)parseBuffer: (const void *)buffer - (void)parseBuffer: (const void *)buffer length: (size_t)length;
length: (size_t)length;
/*! /*!
* @brief Sends an OFXMLElement, usually an XMPPStanza. * @brief Sends an OFXMLElement, usually an XMPPStanza.
@ -338,8 +335,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param IQ The IQ to send * @param IQ The IQ to send
* @param block The callback block * @param block The callback block
*/ */
- (void)sendIQ: (XMPPIQ *)IQ - (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (XMPPCallbackBlock)block;
callbackBlock: (xmpp_callback_block_t)block;
#endif #endif
/*! /*!

View file

@ -59,8 +59,7 @@
@interface XMPPConnection () <OFDNSResolverQueryDelegate, OFTCPSocketDelegate, @interface XMPPConnection () <OFDNSResolverQueryDelegate, OFTCPSocketDelegate,
OFXMLParserDelegate, OFXMLElementBuilderDelegate> OFXMLParserDelegate, OFXMLElementBuilderDelegate>
- (void)xmpp_tryNextSRVRecord; - (void)xmpp_tryNextSRVRecord;
- (bool)xmpp_parseBuffer: (const void *)buffer - (bool)xmpp_parseBuffer: (const void *)buffer length: (size_t)length;
length: (size_t)length;
- (void)xmpp_startStream; - (void)xmpp_startStream;
- (void)xmpp_handleStanza: (OFXMLElement *)element; - (void)xmpp_handleStanza: (OFXMLElement *)element;
- (void)xmpp_handleStream: (OFXMLElement *)element; - (void)xmpp_handleStream: (OFXMLElement *)element;
@ -72,8 +71,7 @@
- (void)xmpp_handleFeatures: (OFXMLElement *)element; - (void)xmpp_handleFeatures: (OFXMLElement *)element;
- (void)xmpp_sendAuth: (OFString *)authName; - (void)xmpp_sendAuth: (OFString *)authName;
- (void)xmpp_sendResourceBind; - (void)xmpp_sendResourceBind;
- (void)xmpp_sendStreamError: (OFString *)condition - (void)xmpp_sendStreamError: (OFString *)condition text: (OFString *)text;
text: (OFString *)text;
- (void)xmpp_handleResourceBindForConnection: (XMPPConnection *)connection - (void)xmpp_handleResourceBindForConnection: (XMPPConnection *)connection
IQ: (XMPPIQ *)IQ; IQ: (XMPPIQ *)IQ;
- (void)xmpp_sendSession; - (void)xmpp_sendSession;
@ -278,7 +276,7 @@
[self xmpp_startStream]; [self xmpp_startStream];
[_socket asyncReadIntoBuffer: _buffer [_socket asyncReadIntoBuffer: _buffer
length: XMPP_CONNECTION_BUFFER_LENGTH]; length: XMPPConnectionBufferLength];
} }
- (void)xmpp_tryNextSRVRecord - (void)xmpp_tryNextSRVRecord
@ -291,8 +289,7 @@
_nextSRVRecords = nil; _nextSRVRecords = nil;
} }
[_socket asyncConnectToHost: record.target [_socket asyncConnectToHost: record.target port: record.port];
port: record.port];
} }
- (void)resolver: (OFDNSResolver *)resolver - (void)resolver: (OFDNSResolver *)resolver
@ -315,8 +312,7 @@
if (records.count == 0) { if (records.count == 0) {
/* Fall back to A / AAAA record. */ /* Fall back to A / AAAA record. */
[_socket asyncConnectToHost: _domainToASCII [_socket asyncConnectToHost: _domainToASCII port: _port];
port: _port];
return; return;
} }
@ -337,8 +333,7 @@
[_socket setDelegate: self]; [_socket setDelegate: self];
if (_server != nil) if (_server != nil)
[_socket asyncConnectToHost: _server [_socket asyncConnectToHost: _server port: _port];
port: _port];
else { else {
OFString *SRVDomain = [_domainToASCII OFString *SRVDomain = [_domainToASCII
stringByPrependingString: @"_xmpp-client._tcp."]; stringByPrependingString: @"_xmpp-client._tcp."];
@ -365,11 +360,9 @@
} }
@try { @try {
[_parser parseBuffer: buffer [_parser parseBuffer: buffer length: length];
length: length];
} @catch (OFMalformedXMLException *e) { } @catch (OFMalformedXMLException *e) {
[self xmpp_sendStreamError: @"bad-format" [self xmpp_sendStreamError: @"bad-format" text: nil];
text: nil];
[self close]; [self close];
return false; return false;
} }
@ -377,11 +370,9 @@
return true; return true;
} }
- (void)parseBuffer: (const void *)buffer - (void)parseBuffer: (const void *)buffer length: (size_t)length
length: (size_t)length
{ {
[self xmpp_parseBuffer: buffer [self xmpp_parseBuffer: buffer length: length];
length: length];
[_oldParser release]; [_oldParser release];
[_oldElementBuilder release]; [_oldElementBuilder release];
@ -405,8 +396,7 @@
} }
@try { @try {
if (![self xmpp_parseBuffer: buffer if (![self xmpp_parseBuffer: buffer length: length])
length: length])
return false; return false;
} @catch (id e) { } @catch (id e) {
[_delegates broadcastSelector: @selector(connection: [_delegates broadcastSelector: @selector(connection:
@ -425,7 +415,7 @@
_oldElementBuilder = nil; _oldElementBuilder = nil;
[_socket asyncReadIntoBuffer: _buffer [_socket asyncReadIntoBuffer: _buffer
length: XMPP_CONNECTION_BUFFER_LENGTH]; length: XMPPConnectionBufferLength];
return false; return false;
} }
@ -502,10 +492,8 @@
key = @"bind"; key = @"bind";
key = [key stringByAppendingString: ID]; key = [key stringByAppendingString: ID];
callback = [XMPPCallback callbackWithTarget: target callback = [XMPPCallback callbackWithTarget: target selector: selector];
selector: selector]; [_callbacks setObject: callback forKey: key];
[_callbacks setObject: callback
forKey: key];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
@ -513,8 +501,7 @@
} }
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
- (void)sendIQ: (XMPPIQ *)IQ - (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (XMPPCallbackBlock)block
callbackBlock: (xmpp_callback_block_t)block
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
XMPPCallback *callback; XMPPCallback *callback;
@ -532,8 +519,7 @@
key = [key stringByAppendingString: ID]; key = [key stringByAppendingString: ID];
callback = [XMPPCallback callbackWithBlock: block]; callback = [XMPPCallback callbackWithBlock: block];
[_callbacks setObject: callback [_callbacks setObject: callback forKey: key];
forKey: key];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
@ -560,22 +546,19 @@
} }
if (![prefix isEqual: @"stream"]) { if (![prefix isEqual: @"stream"]) {
[self xmpp_sendStreamError: @"bad-namespace-prefix" [self xmpp_sendStreamError: @"bad-namespace-prefix" text: nil];
text: nil];
return; return;
} }
if (![namespace isEqual: XMPP_NS_STREAM]) { if (![namespace isEqual: XMPPStreamNS]) {
[self xmpp_sendStreamError: @"invalid-namespace" [self xmpp_sendStreamError: @"invalid-namespace" text: nil];
text: nil];
return; return;
} }
for (OFXMLAttribute *attribute in attributes) { for (OFXMLAttribute *attribute in attributes) {
if ([attribute.name isEqual: @"from"] && if ([attribute.name isEqual: @"from"] &&
![attribute.stringValue isEqual: _domain]) { ![attribute.stringValue isEqual: _domain]) {
[self xmpp_sendStreamError: @"invalid-from" [self xmpp_sendStreamError: @"invalid-from" text: nil];
text: nil];
return; return;
} }
if ([attribute.name isEqual: @"version"] && if ([attribute.name isEqual: @"version"] &&
@ -596,24 +579,23 @@
if (element.name == nil) if (element.name == nil)
return; return;
element.defaultNamespace = XMPP_NS_CLIENT; element.defaultNamespace = XMPPClientNS;
[element setPrefix: @"stream" [element setPrefix: @"stream" forNamespace: XMPPStreamNS];
forNamespace: XMPP_NS_STREAM];
[_delegates broadcastSelector: @selector(connection:didReceiveElement:) [_delegates broadcastSelector: @selector(connection:didReceiveElement:)
withObject: self withObject: self
withObject: element]; withObject: element];
if ([element.namespace isEqual: XMPP_NS_CLIENT]) if ([element.namespace isEqual: XMPPClientNS])
[self xmpp_handleStanza: element]; [self xmpp_handleStanza: element];
if ([element.namespace isEqual: XMPP_NS_STREAM]) if ([element.namespace isEqual: XMPPStreamNS])
[self xmpp_handleStream: element]; [self xmpp_handleStream: element];
if ([element.namespace isEqual: XMPP_NS_STARTTLS]) if ([element.namespace isEqual: XMPPStartTLSNS])
[self xmpp_handleTLS: element]; [self xmpp_handleTLS: element];
if ([element.namespace isEqual: XMPP_NS_SASL]) if ([element.namespace isEqual: XMPPSASLNS])
[self xmpp_handleSASL: element]; [self xmpp_handleSASL: element];
} }
@ -623,7 +605,7 @@
namespace: (OFString *)ns namespace: (OFString *)ns
{ {
if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
![ns isEqual: XMPP_NS_STREAM]) ![ns isEqual: XMPPStreamNS])
@throw [OFMalformedXMLException exception]; @throw [OFMalformedXMLException exception];
else else
[self close]; [self close];
@ -656,8 +638,8 @@
[_socket writeFormat: @"<?xml version='1.0'?>\n" [_socket writeFormat: @"<?xml version='1.0'?>\n"
@"<stream:stream to='%@' " @"<stream:stream to='%@' "
@"xmlns='" XMPP_NS_CLIENT @"' " @"xmlns='" XMPPClientNS @"' "
@"xmlns:stream='" XMPP_NS_STREAM @"' %@" @"xmlns:stream='" XMPPStreamNS @"' %@"
@"version='1.0'>", _domain, langString]; @"version='1.0'>", _domain, langString];
_streamOpen = true; _streamOpen = true;
@ -702,8 +684,7 @@
return; return;
} }
[self xmpp_sendStreamError: @"unsupported-stanza-type" [self xmpp_sendStreamError: @"unsupported-stanza-type" text: nil];
text: nil];
} }
@ -722,15 +703,14 @@
withObject: self withObject: self
withObject: element]; withObject: element];
condition = [[element elementsForNamespace: condition = [[element elementsForNamespace: XMPPXMPPStreamNS]
XMPP_NS_XMPP_STREAM].firstObject name]; .firstObject name];
if (condition == nil) if (condition == nil)
condition = @"undefined"; condition = @"undefined";
reason = [element reason = [element elementForName: @"text"
elementForName: @"text" namespace: XMPPXMPPStreamNS].stringValue;
namespace: XMPP_NS_XMPP_STREAM].stringValue;
@throw [XMPPStreamErrorException @throw [XMPPStreamErrorException
exceptionWithConnection: self exceptionWithConnection: self
@ -793,7 +773,7 @@
OFData *response = [_authModule continueWithData: challenge]; OFData *response = [_authModule continueWithData: challenge];
responseTag = [OFXMLElement elementWithName: @"response" responseTag = [OFXMLElement elementWithName: @"response"
namespace: XMPP_NS_SASL]; namespace: XMPPSASLNS];
if (response) { if (response) {
if (response.count == 0) if (response.count == 0)
responseTag.stringValue = @"="; responseTag.stringValue = @"=";
@ -843,8 +823,7 @@
key = [key stringByAppendingString: IQ.ID]; key = [key stringByAppendingString: IQ.ID];
if ((callback = [_callbacks objectForKey: key])) { if ((callback = [_callbacks objectForKey: key])) {
[callback runWithIQ: IQ [callback runWithIQ: IQ connection: self];
connection: self];
[_callbacks removeObjectForKey: key]; [_callbacks removeObjectForKey: key];
return; return;
} }
@ -878,19 +857,19 @@
- (void)xmpp_handleFeatures: (OFXMLElement *)element - (void)xmpp_handleFeatures: (OFXMLElement *)element
{ {
OFXMLElement *startTLS = [element elementForName: @"starttls" OFXMLElement *startTLS = [element elementForName: @"starttls"
namespace: XMPP_NS_STARTTLS]; namespace: XMPPStartTLSNS];
OFXMLElement *bind = [element elementForName: @"bind" OFXMLElement *bind = [element elementForName: @"bind"
namespace: XMPP_NS_BIND]; namespace: XMPPBindNS];
OFXMLElement *session = [element elementForName: @"session" OFXMLElement *session = [element elementForName: @"session"
namespace: XMPP_NS_SESSION]; namespace: XMPPSessionNS];
OFXMLElement *mechs = [element elementForName: @"mechanisms" OFXMLElement *mechs = [element elementForName: @"mechanisms"
namespace: XMPP_NS_SASL]; namespace: XMPPSASLNS];
OFMutableSet *mechanisms = [OFMutableSet set]; OFMutableSet *mechanisms = [OFMutableSet set];
if (!_encrypted && startTLS != nil) { if (!_encrypted && startTLS != nil) {
[self sendStanza: [self sendStanza:
[OFXMLElement elementWithName: @"starttls" [OFXMLElement elementWithName: @"starttls"
namespace: XMPP_NS_STARTTLS]]; namespace: XMPPStartTLSNS]];
return; return;
} }
@ -898,12 +877,10 @@
/* TODO: Find/create an exception to throw here */ /* TODO: Find/create an exception to throw here */
@throw [OFException exception]; @throw [OFException exception];
if ([element elementForName: @"ver" if ([element elementForName: @"ver" namespace: XMPPRosterVerNS] != nil)
namespace: XMPP_NS_ROSTERVER] != nil)
_supportsRosterVersioning = true; _supportsRosterVersioning = true;
if ([element elementForName: @"sm" if ([element elementForName: @"sm" namespace: XMPPSMNS] != nil)
namespace: XMPP_NS_SM] != nil)
_supportsStreamManagement = true; _supportsStreamManagement = true;
if (mechs != nil) { if (mechs != nil) {
@ -966,7 +943,7 @@
} }
if (session != nil && [session elementForName: @"optional" if (session != nil && [session elementForName: @"optional"
namespace: XMPP_NS_SESSION] == nil) namespace: XMPPSessionNS] == nil)
_needsSession = true; _needsSession = true;
if (bind != nil) { if (bind != nil) {
@ -982,10 +959,8 @@
OFXMLElement *authTag; OFXMLElement *authTag;
OFData *initialMessage = [_authModule initialMessage]; OFData *initialMessage = [_authModule initialMessage];
authTag = [OFXMLElement elementWithName: @"auth" authTag = [OFXMLElement elementWithName: @"auth" namespace: XMPPSASLNS];
namespace: XMPP_NS_SASL]; [authTag addAttributeWithName: @"mechanism" stringValue: authName];
[authTag addAttributeWithName: @"mechanism"
stringValue: authName];
if (initialMessage != nil) { if (initialMessage != nil) {
if (initialMessage.count == 0) if (initialMessage.count == 0)
authTag.stringValue = @"="; authTag.stringValue = @"=";
@ -1002,15 +977,13 @@
XMPPIQ *IQ; XMPPIQ *IQ;
OFXMLElement *bind; OFXMLElement *bind;
IQ = [XMPPIQ IQWithType: @"set" IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]];
ID: [self generateStanzaID]];
bind = [OFXMLElement elementWithName: @"bind" bind = [OFXMLElement elementWithName: @"bind" namespace: XMPPBindNS];
namespace: XMPP_NS_BIND];
if (_resource != nil) if (_resource != nil)
[bind addChild: [OFXMLElement elementWithName: @"resource" [bind addChild: [OFXMLElement elementWithName: @"resource"
namespace: XMPP_NS_BIND namespace: XMPPBindNS
stringValue: _resource]]; stringValue: _resource]];
[IQ addChild: bind]; [IQ addChild: bind];
@ -1026,15 +999,14 @@
{ {
OFXMLElement *error = [OFXMLElement OFXMLElement *error = [OFXMLElement
elementWithName: @"error" elementWithName: @"error"
namespace: XMPP_NS_STREAM]; namespace: XMPPStreamNS];
[error setPrefix: @"stream" [error setPrefix: @"stream" forNamespace: XMPPStreamNS];
forNamespace: XMPP_NS_STREAM];
[error addChild: [OFXMLElement elementWithName: condition [error addChild: [OFXMLElement elementWithName: condition
namespace: XMPP_NS_XMPP_STREAM]]; namespace: XMPPXMPPStreamNS]];
if (text) if (text)
[error addChild: [OFXMLElement [error addChild: [OFXMLElement
elementWithName: @"text" elementWithName: @"text"
namespace: XMPP_NS_XMPP_STREAM namespace: XMPPXMPPStreamNS
stringValue: text]]; stringValue: text]];
_parser.delegate = nil; _parser.delegate = nil;
[self sendStanza: error]; [self sendStanza: error];
@ -1048,13 +1020,11 @@
assert([IQ.type isEqual: @"result"]); assert([IQ.type isEqual: @"result"]);
bindElement = [IQ elementForName: @"bind" bindElement = [IQ elementForName: @"bind" namespace: XMPPBindNS];
namespace: XMPP_NS_BIND];
assert(bindElement != nil); assert(bindElement != nil);
JIDElement = [bindElement elementForName: @"jid" JIDElement = [bindElement elementForName: @"jid" namespace: XMPPBindNS];
namespace: XMPP_NS_BIND];
_JID = [[XMPPJID alloc] initWithString: JIDElement.stringValue]; _JID = [[XMPPJID alloc] initWithString: JIDElement.stringValue];
if (_needsSession) { if (_needsSession) {
@ -1069,11 +1039,10 @@
- (void)xmpp_sendSession - (void)xmpp_sendSession
{ {
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]];
ID: [self generateStanzaID]];
[IQ addChild: [OFXMLElement elementWithName: @"session" [IQ addChild: [OFXMLElement elementWithName: @"session"
namespace: XMPP_NS_SESSION]]; namespace: XMPPSessionNS]];
[self sendIQ: IQ [self sendIQ: IQ
callbackTarget: self callbackTarget: self

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -75,11 +75,9 @@
resource: (OFString *)resource resource: (OFString *)resource
{ {
if (resource != nil) if (resource != nil)
[_presences setObject: presence [_presences setObject: presence forKey: resource];
forKey: resource];
else else
[_presences setObject: presence [_presences setObject: presence forKey: @""];
forKey: @""];
self.xmpp_lockedOnJID = nil; self.xmpp_lockedOnJID = nil;
} }

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -92,8 +92,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param contact The contact that send the message * @param contact The contact that send the message
* @param message The message which was send by the contact * @param message The message which was send by the contact
*/ */
- (void)contact: (XMPPContact *)contact - (void)contact: (XMPPContact *)contact didSendMessage: (XMPPMessage *)message;
didSendMessage: (XMPPMessage *)message;
@end @end
/*! /*!

View file

@ -107,8 +107,7 @@
for (OFString *bareJID in rosterItems) { for (OFString *bareJID in rosterItems) {
XMPPContact *contact = [[[XMPPContact alloc] init] autorelease]; XMPPContact *contact = [[[XMPPContact alloc] init] autorelease];
contact.rosterItem = [rosterItems objectForKey: bareJID]; contact.rosterItem = [rosterItems objectForKey: bareJID];
[_contacts setObject: contact [_contacts setObject: contact forKey: bareJID];
forKey: bareJID];
[_delegates broadcastSelector: @selector(contactManager: [_delegates broadcastSelector: @selector(contactManager:
didAddContact:) didAddContact:)
withObject: self withObject: self
@ -137,8 +136,7 @@
if (contact == nil) { if (contact == nil) {
contact = [[[XMPPContact alloc] init] autorelease]; contact = [[[XMPPContact alloc] init] autorelease];
contact.rosterItem = rosterItem; contact.rosterItem = rosterItem;
[_contacts setObject: contact [_contacts setObject: contact forKey: bareJID];
forKey: bareJID];
[_delegates broadcastSelector: @selector(contactManager: [_delegates broadcastSelector: @selector(contactManager:
didAddContact:) didAddContact:)
withObject: self withObject: self
@ -174,8 +172,7 @@
/* Available presence */ /* Available presence */
if ([type isEqual: @"available"]) { if ([type isEqual: @"available"]) {
[contact xmpp_setPresence: presence [contact xmpp_setPresence: presence resource: JID.resource];
resource: JID.resource];
[_delegates broadcastSelector: @selector(contact: [_delegates broadcastSelector: @selector(contact:
didSendPresence:) didSendPresence:)
withObject: contact withObject: contact

View file

@ -32,8 +32,7 @@
@implementation XMPPDiscoEntity @implementation XMPPDiscoEntity
@synthesize discoNodes = _discoNodes, capsNode = _capsNode; @synthesize discoNodes = _discoNodes, capsNode = _capsNode;
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node
node: (OFString *)node
{ {
OF_UNRECOGNIZED_SELECTOR OF_UNRECOGNIZED_SELECTOR
} }
@ -57,8 +56,7 @@
capsNode: capsNode] autorelease]; capsNode: capsNode] autorelease];
} }
- (instancetype)initWithJID: (XMPPJID *)JID - (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node
node: (nullable OFString *)node
{ {
OF_INVALID_INIT_METHOD OF_INVALID_INIT_METHOD
} }
@ -79,9 +77,7 @@
- (instancetype)initWithConnection: (XMPPConnection *)connection - (instancetype)initWithConnection: (XMPPConnection *)connection
capsNode: (OFString *)capsNode capsNode: (OFString *)capsNode
{ {
self = [super initWithJID: [connection JID] self = [super initWithJID: [connection JID] node: nil name: nil];
node: nil
name: nil];
@try { @try {
_discoNodes = [[OFMutableDictionary alloc] init]; _discoNodes = [[OFMutableDictionary alloc] init];
@ -107,8 +103,7 @@
- (void)addDiscoNode: (XMPPDiscoNode *)node - (void)addDiscoNode: (XMPPDiscoNode *)node
{ {
[_discoNodes setObject: node [_discoNodes setObject: node forKey: node.node];
forKey: node.node];
} }
- (OFString *)capsHash - (OFString *)capsHash
@ -124,11 +119,9 @@
for (OFString *feature in _features) for (OFString *feature in _features)
[caps appendFormat: @"%@<", feature]; [caps appendFormat: @"%@<", feature];
[hash updateWithBuffer: caps.UTF8String [hash updateWithBuffer: caps.UTF8String length: caps.UTF8StringLength];
length: caps.UTF8StringLength];
digest = [OFData dataWithItems: hash.digest digest = [OFData dataWithItems: hash.digest count: hash.digestSize];
count: hash.digestSize];
return digest.stringByBase64Encoding; return digest.stringByBase64Encoding;
} }
@ -146,7 +139,7 @@
return false; return false;
OFXMLElement *query = [IQ elementForName: @"query" OFXMLElement *query = [IQ elementForName: @"query"
namespace: XMPP_NS_DISCO_ITEMS]; namespace: XMPPDiscoItemsNS];
if (query != nil) { if (query != nil) {
OFString *node = [query attributeForName: @"node"].stringValue; OFString *node = [query attributeForName: @"node"].stringValue;
@ -162,8 +155,7 @@
return false; return false;
} }
query = [IQ elementForName: @"query" query = [IQ elementForName: @"query" namespace: XMPPDiscoInfoNS];
namespace: XMPP_NS_DISCO_INFO];
if (query != nil) { if (query != nil) {
OFString *node = [query attributeForName: @"node"].stringValue; OFString *node = [query attributeForName: @"node"].stringValue;

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -96,8 +96,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param type The type of the identity * @param type The type of the identity
* @return An initialized XMPPDiscoIdentity * @return An initialized XMPPDiscoIdentity
*/ */
- (instancetype)initWithCategory: (OFString *)category - (instancetype)initWithCategory: (OFString *)category type: (OFString *)type;
type: (OFString *)type;
@end @end
OF_ASSUME_NONNULL_END OF_ASSUME_NONNULL_END

View file

@ -63,12 +63,9 @@
return self; return self;
} }
- (instancetype)initWithCategory: (OFString *)category - (instancetype)initWithCategory: (OFString *)category type: (OFString *)type
type: (OFString *)type
{ {
return [self initWithCategory: category return [self initWithCategory: category type: type name: nil];
type: type
name: nil];
} }
- (instancetype)init - (instancetype)init

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -103,8 +103,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param node The node's opaque name * @param node The node's opaque name
* @return An initialized XMPPDiscoNode * @return An initialized XMPPDiscoNode
*/ */
- (instancetype)initWithJID: (XMPPJID *)JID - (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node;
node: (nullable OFString *)node;
/*! /*!
* @brief Initializes an already allocated XMPPDiscoNode with the specified * @brief Initializes an already allocated XMPPDiscoNode with the specified

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -35,11 +35,9 @@
@synthesize JID = _JID, node = _node, name = _name, identities = _identities; @synthesize JID = _JID, node = _node, name = _name, identities = _identities;
@synthesize features = _features, childNodes = _childNodes; @synthesize features = _features, childNodes = _childNodes;
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node;
node: (OFString *)node;
{ {
return [[[self alloc] initWithJID: JID return [[[self alloc] initWithJID: JID node: node] autorelease];
node: node] autorelease];
} }
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID + (instancetype)discoNodeWithJID: (XMPPJID *)JID
@ -51,12 +49,9 @@
name: name] autorelease]; name: name] autorelease];
} }
- (instancetype)initWithJID: (XMPPJID *)JID - (instancetype)initWithJID: (XMPPJID *)JID node: (OFString *)node
node: (OFString *)node
{ {
return [self initWithJID: JID return [self initWithJID: JID node: node name: nil];
node: node
name: nil];
} }
- (instancetype)initWithJID: (XMPPJID *)JID - (instancetype)initWithJID: (XMPPJID *)JID
@ -77,8 +72,8 @@
_features = [[OFSortedList alloc] init]; _features = [[OFSortedList alloc] init];
_childNodes = [[OFMutableDictionary alloc] init]; _childNodes = [[OFMutableDictionary alloc] init];
[self addFeature: XMPP_NS_DISCO_ITEMS]; [self addFeature: XMPPDiscoItemsNS];
[self addFeature: XMPP_NS_DISCO_INFO]; [self addFeature: XMPPDiscoInfoNS];
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -126,7 +121,7 @@
XMPPIQ *resultIQ; XMPPIQ *resultIQ;
OFXMLElement *response; OFXMLElement *response;
OFXMLElement *query = [IQ elementForName: @"query" OFXMLElement *query = [IQ elementForName: @"query"
namespace: XMPP_NS_DISCO_ITEMS]; namespace: XMPPDiscoItemsNS];
OFString *node = [[query attributeForName: @"node"] stringValue]; OFString *node = [[query attributeForName: @"node"] stringValue];
if (!(node == _node) && ![node isEqual: _node]) if (!(node == _node) && ![node isEqual: _node])
@ -134,13 +129,13 @@
resultIQ = [IQ resultIQ]; resultIQ = [IQ resultIQ];
response = [OFXMLElement elementWithName: @"query" response = [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_DISCO_ITEMS]; namespace: XMPPDiscoItemsNS];
[resultIQ addChild: response]; [resultIQ addChild: response];
for (XMPPDiscoNode *child in _childNodes) { for (XMPPDiscoNode *child in _childNodes) {
OFXMLElement *item = OFXMLElement *item =
[OFXMLElement elementWithName: @"item" [OFXMLElement elementWithName: @"item"
namespace: XMPP_NS_DISCO_ITEMS]; namespace: XMPPDiscoItemsNS];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid"
stringValue: child.JID.fullJID]; stringValue: child.JID.fullJID];
@ -159,21 +154,20 @@
return true; return true;
} }
- (bool)xmpp_handleInfoIQ: (XMPPIQ *)IQ - (bool)xmpp_handleInfoIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection
connection: (XMPPConnection *)connection
{ {
XMPPIQ *resultIQ; XMPPIQ *resultIQ;
OFXMLElement *response; OFXMLElement *response;
resultIQ = [IQ resultIQ]; resultIQ = [IQ resultIQ];
response = [OFXMLElement elementWithName: @"query" response = [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_DISCO_INFO]; namespace: XMPPDiscoInfoNS];
[resultIQ addChild: response]; [resultIQ addChild: response];
for (XMPPDiscoIdentity *identity in _identities) { for (XMPPDiscoIdentity *identity in _identities) {
OFXMLElement *identityElement = OFXMLElement *identityElement =
[OFXMLElement elementWithName: @"identity" [OFXMLElement elementWithName: @"identity"
namespace: XMPP_NS_DISCO_INFO]; namespace: XMPPDiscoInfoNS];
[identityElement addAttributeWithName: @"category" [identityElement addAttributeWithName: @"category"
stringValue: identity.category]; stringValue: identity.category];
@ -189,7 +183,7 @@
for (OFString *feature in _features) { for (OFString *feature in _features) {
OFXMLElement *featureElement = OFXMLElement *featureElement =
[OFXMLElement elementWithName: @"feature" [OFXMLElement elementWithName: @"feature"
namespace: XMPP_NS_DISCO_INFO]; namespace: XMPPDiscoInfoNS];
[featureElement addAttributeWithName: @"var" [featureElement addAttributeWithName: @"var"
stringValue: feature]; stringValue: feature];
[response addChild: featureElement]; [response addChild: featureElement];

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2019, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -28,8 +28,7 @@
@implementation XMPPEXTERNALAuth: XMPPAuthenticator @implementation XMPPEXTERNALAuth: XMPPAuthenticator
+ (instancetype)EXTERNALAuth + (instancetype)EXTERNALAuth
{ {
return [[[self alloc] initWithAuthcid: nil return [[[self alloc] initWithAuthcid: nil password: nil] autorelease];
password: nil] autorelease];
} }
+ (instancetype)EXTERNALAuthWithAuthzid: (OFString *)authzid + (instancetype)EXTERNALAuthWithAuthzid: (OFString *)authzid

View file

@ -92,16 +92,14 @@
if (iter2 == nil) { if (iter2 == nil) {
iter2 = [OFMutableDictionary dictionary]; iter2 = [OFMutableDictionary dictionary];
[iter setObject: iter2 [iter setObject: iter2 forKey: component];
forKey: component];
} }
iter = iter2; iter = iter2;
} }
if (object != nil) if (object != nil)
[iter setObject: object [iter setObject: object forKey: [pathComponents lastObject]];
forKey: [pathComponents lastObject]];
else else
[iter removeObjectForKey: pathComponents.lastObject]; [iter removeObjectForKey: pathComponents.lastObject];
} }
@ -121,8 +119,7 @@
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
[self xmpp_setObject: string [self xmpp_setObject: string forPath: path];
forPath: path];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
} }
@ -139,13 +136,11 @@
return string; return string;
} }
- (void)setBooleanValue: (bool)boolean - (void)setBooleanValue: (bool)boolean forPath: (OFString *)path
forPath: (OFString *)path
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
[self xmpp_setObject: [OFNumber numberWithBool: boolean] [self xmpp_setObject: [OFNumber numberWithBool: boolean] forPath: path];
forPath: path];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
} }
@ -162,8 +157,7 @@
return boolean; return boolean;
} }
- (void)setIntegerValue: (long long)integer - (void)setIntegerValue: (long long)integer forPath: (OFString *)path
forPath: (OFString *)path
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
@ -185,13 +179,11 @@
return integer; return integer;
} }
- (void)setArray: (OFArray *)array - (void)setArray: (OFArray *)array forPath: (OFString *)path
forPath: (OFString *)path
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
[self xmpp_setObject: array [self xmpp_setObject: array forPath: path];
forPath: path];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
} }
@ -208,13 +200,11 @@
return array; return array;
} }
- (void)setDictionary: (OFDictionary *)dictionary - (void)setDictionary: (OFDictionary *)dictionary forPath: (OFString *)path
forPath: (OFString *)path
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
[self xmpp_setObject: dictionary [self xmpp_setObject: dictionary forPath: path];
forPath: path];
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2011, 2021, Jonathan Schleifer <js@nil.im>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -36,8 +36,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param ID The value for the stanza's id attribute * @param ID The value for the stanza's id attribute
* @return A new autoreleased XMPPIQ * @return A new autoreleased XMPPIQ
*/ */
+ (instancetype)IQWithType: (OFString *)type + (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID;
ID: (OFString *)ID;
/*! /*!
* @brief Initializes an already allocated XMPPIQ with the specified type and * @brief Initializes an already allocated XMPPIQ with the specified type and
@ -47,8 +46,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param ID The value for the stanza's id attribute * @param ID The value for the stanza's id attribute
* @return An initialized XMPPIQ * @return An initialized XMPPIQ
*/ */
- (instancetype)initWithType: (OFString *)type - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID;
ID: (OFString *)ID;
/*! /*!
* @brief Generates a result IQ for the receiving object. * @brief Generates a result IQ for the receiving object.
@ -76,8 +74,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param condition A defined conditions from RFC 6120 * @param condition A defined conditions from RFC 6120
* @return A new autoreleased XMPPIQ * @return A new autoreleased XMPPIQ
*/ */
- (XMPPIQ *)errorIQWithType: (OFString *)type - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition;
condition: (OFString *)condition;
@end @end
OF_ASSUME_NONNULL_END OF_ASSUME_NONNULL_END

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2019, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2011, 2019, 2021, Jonathan Schleifer <js@nil.im>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -27,19 +27,14 @@
#import "XMPPIQ.h" #import "XMPPIQ.h"
@implementation XMPPIQ @implementation XMPPIQ
+ (instancetype)IQWithType: (OFString *)type + (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID
ID: (OFString *)ID
{ {
return [[[self alloc] initWithType: type return [[[self alloc] initWithType: type ID: ID] autorelease];
ID: ID] autorelease];
} }
- (instancetype)initWithType: (OFString *)type - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID
ID: (OFString *)ID
{ {
self = [super initWithName: @"iq" self = [super initWithName: @"iq" type: type ID: ID];
type: type
ID: ID];
@try { @try {
if (![type isEqual: @"get"] && ![type isEqual: @"set"] && if (![type isEqual: @"get"] && ![type isEqual: @"set"] &&
@ -70,15 +65,14 @@
ID: self.ID]; ID: self.ID];
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
OFXMLElement *error = [OFXMLElement elementWithName: @"error" OFXMLElement *error = [OFXMLElement elementWithName: @"error"
namespace: XMPP_NS_CLIENT]; namespace: XMPPClientNS];
[error addAttributeWithName: @"type" [error addAttributeWithName: @"type" stringValue: type];
stringValue: type];
[error addChild: [OFXMLElement elementWithName: condition [error addChild: [OFXMLElement elementWithName: condition
namespace: XMPP_NS_STANZAS]]; namespace: XMPPStanzasNS]];
if (text) if (text)
[error addChild: [OFXMLElement elementWithName: @"text" [error addChild: [OFXMLElement elementWithName: @"text"
namespace: XMPP_NS_STANZAS namespace: XMPPStanzasNS
stringValue: text]]; stringValue: text]];
[ret addChild: error]; [ret addChild: error];
ret.to = self.from; ret.to = self.from;
@ -89,11 +83,8 @@
return ret; return ret;
} }
- (XMPPIQ *)errorIQWithType: (OFString *)type - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition
condition: (OFString *)condition
{ {
return [self errorIQWithType: type return [self errorIQWithType: type condition: condition text: nil];
condition: condition
text: nil];
} }
@end @end

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2019, 2021, Jonathan Schleifer <js@nil.im>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -42,56 +42,48 @@
return [[[self alloc] initWithType: type] autorelease]; return [[[self alloc] initWithType: type] autorelease];
} }
+ (instancetype)messageWithType: (OFString *)type + (instancetype)messageWithType: (OFString *)type ID: (OFString *)ID
ID: (OFString *)ID
{ {
return [[[self alloc] initWithType: type return [[[self alloc] initWithType: type ID: ID] autorelease];
ID: ID] autorelease];
} }
- (instancetype)init - (instancetype)init
{ {
return [self initWithType: nil return [self initWithType: nil ID: nil];
ID: nil];
} }
- (instancetype)initWithID: (OFString *)ID - (instancetype)initWithID: (OFString *)ID
{ {
return [self initWithType: nil return [self initWithType: nil ID: ID];
ID: ID];
} }
- (instancetype)initWithType: (OFString *)type - (instancetype)initWithType: (OFString *)type
{ {
return [self initWithType: type return [self initWithType: type ID: nil];
ID: nil];
} }
- (instancetype)initWithType: (OFString *)type - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID
ID: (OFString *)ID
{ {
return [super initWithName: @"message" return [super initWithName: @"message" type: type ID: ID];
type: type
ID: ID];
} }
- (void)setBody: (OFString *)body - (void)setBody: (OFString *)body
{ {
OFXMLElement *oldBody = [self elementForName: @"body" OFXMLElement *oldBody = [self elementForName: @"body"
namespace: XMPP_NS_CLIENT]; namespace: XMPPClientNS];
if (oldBody != nil) if (oldBody != nil)
[self removeChild: oldBody]; [self removeChild: oldBody];
if (body != nil) if (body != nil)
[self addChild: [OFXMLElement elementWithName: @"body" [self addChild: [OFXMLElement elementWithName: @"body"
namespace: XMPP_NS_CLIENT namespace: XMPPClientNS
stringValue: body]]; stringValue: body]];
} }
- (OFString *)body - (OFString *)body
{ {
return [self elementForName: @"body" return [self elementForName: @"body"
namespace: XMPP_NS_CLIENT].stringValue; namespace: XMPPClientNS].stringValue;
} }
@end @end

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2012, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -54,8 +54,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param selector The selector to broadcast * @param selector The selector to broadcast
* @param object The object to broadcast * @param object The object to broadcast
*/ */
- (bool)broadcastSelector: (SEL)selector - (bool)broadcastSelector: (SEL)selector withObject: (nullable id)object;
withObject: (nullable id)object;
/*! /*!
* @brief Broadcasts a selector with two objects to all registered delegates. * @brief Broadcasts a selector with two objects to all registered delegates.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2019, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2012, 2019, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -69,8 +69,7 @@
} }
} }
- (bool)broadcastSelector: (SEL)selector - (bool)broadcastSelector: (SEL)selector withObject: (id)object
withObject: (id)object
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
OFMutableData *currentDelegates = [[_delegates copy] autorelease]; OFMutableData *currentDelegates = [[_delegates copy] autorelease];

View file

@ -65,37 +65,29 @@ showToInt(OFString *show)
return [[[self alloc] initWithType: type] autorelease]; return [[[self alloc] initWithType: type] autorelease];
} }
+ (instancetype)presenceWithType: (OFString *)type + (instancetype)presenceWithType: (OFString *)type ID: (OFString *)ID
ID: (OFString *)ID
{ {
return [[[self alloc] initWithType: type return [[[self alloc] initWithType: type ID: ID] autorelease];
ID: ID] autorelease];
} }
- (instancetype)init - (instancetype)init
{ {
return [self initWithType: nil return [self initWithType: nil ID: nil];
ID: nil];
} }
- (instancetype)initWithID: (OFString *)ID - (instancetype)initWithID: (OFString *)ID
{ {
return [self initWithType: nil return [self initWithType: nil ID: ID];
ID: ID];
} }
- (instancetype)initWithType: (OFString *)type - (instancetype)initWithType: (OFString *)type
{ {
return [self initWithType: type return [self initWithType: type ID: nil];
ID: nil];
} }
- (instancetype)initWithType: (OFString *)type - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID
ID: (OFString *)ID
{ {
return [super initWithName: @"presence" return [super initWithName: @"presence" type: type ID: ID];
type: type
ID: ID];
} }
- (instancetype)initWithElement: (OFXMLElement *)element - (instancetype)initWithElement: (OFXMLElement *)element
@ -106,15 +98,15 @@ showToInt(OFString *show)
OFXMLElement *subElement; OFXMLElement *subElement;
if ((subElement = [element elementForName: @"show" if ((subElement = [element elementForName: @"show"
namespace: XMPP_NS_CLIENT])) namespace: XMPPClientNS]))
self.show = subElement.stringValue; self.show = subElement.stringValue;
if ((subElement = [element elementForName: @"status" if ((subElement = [element elementForName: @"status"
namespace: XMPP_NS_CLIENT])) namespace: XMPPClientNS]))
self.status = subElement.stringValue; self.status = subElement.stringValue;
if ((subElement = [element elementForName: @"priority" if ((subElement = [element elementForName: @"priority"
namespace: XMPP_NS_CLIENT])) namespace: XMPPClientNS]))
self.priority = [OFNumber numberWithLongLong: self.priority = [OFNumber numberWithLongLong:
[subElement longLongValueWithBase: 10]]; [subElement longLongValueWithBase: 10]];
} @catch (id e) { } @catch (id e) {
@ -137,7 +129,7 @@ showToInt(OFString *show)
- (void)setShow: (OFString *)show - (void)setShow: (OFString *)show
{ {
OFXMLElement *oldShow = [self elementForName: @"show" OFXMLElement *oldShow = [self elementForName: @"show"
namespace: XMPP_NS_CLIENT]; namespace: XMPPClientNS];
OFString *old; OFString *old;
if (oldShow != nil) if (oldShow != nil)
@ -145,7 +137,7 @@ showToInt(OFString *show)
if (show != nil) if (show != nil)
[self addChild: [OFXMLElement elementWithName: @"show" [self addChild: [OFXMLElement elementWithName: @"show"
namespace: XMPP_NS_CLIENT namespace: XMPPClientNS
stringValue: show]]; stringValue: show]];
old = _show; old = _show;
@ -156,7 +148,7 @@ showToInt(OFString *show)
- (void)setStatus: (OFString *)status - (void)setStatus: (OFString *)status
{ {
OFXMLElement *oldStatus = [self elementForName: @"status" OFXMLElement *oldStatus = [self elementForName: @"status"
namespace: XMPP_NS_CLIENT]; namespace: XMPPClientNS];
OFString *old; OFString *old;
if (oldStatus != nil) if (oldStatus != nil)
@ -164,7 +156,7 @@ showToInt(OFString *show)
if (status != nil) if (status != nil)
[self addChild: [OFXMLElement elementWithName: @"status" [self addChild: [OFXMLElement elementWithName: @"status"
namespace: XMPP_NS_CLIENT namespace: XMPPClientNS
stringValue: status]]; stringValue: status]];
old = _status; old = _status;
@ -181,7 +173,7 @@ showToInt(OFString *show)
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
OFXMLElement *oldPriority = [self elementForName: @"priority" OFXMLElement *oldPriority = [self elementForName: @"priority"
namespace: XMPP_NS_CLIENT]; namespace: XMPPClientNS];
if (oldPriority != nil) if (oldPriority != nil)
[self removeChild: oldPriority]; [self removeChild: oldPriority];
@ -189,7 +181,7 @@ showToInt(OFString *show)
OFString *priority_s = OFString *priority_s =
[OFString stringWithFormat: @"%hhd", priority.charValue]; [OFString stringWithFormat: @"%hhd", priority.charValue];
[self addChild: [OFXMLElement elementWithName: @"priority" [self addChild: [OFXMLElement elementWithName: @"priority"
namespace: XMPP_NS_CLIENT namespace: XMPPClientNS
stringValue: priority_s]]; stringValue: priority_s]];
old = _priority; old = _priority;

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2011, 2012, 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2016, 2019, 2021,
* Jonathan Schleifer <js@nil.im>
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -91,11 +92,10 @@ OF_ASSUME_NONNULL_END
_rosterRequested = true; _rosterRequested = true;
IQ = [XMPPIQ IQWithType: @"get" IQ = [XMPPIQ IQWithType: @"get" ID: [_connection generateStanzaID]];
ID: [_connection generateStanzaID]];
query = [OFXMLElement elementWithName: @"query" query = [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
if (_connection.supportsRosterVersioning) { if (_connection.supportsRosterVersioning) {
OFString *ver = OFString *ver =
@ -104,8 +104,7 @@ OF_ASSUME_NONNULL_END
if (ver == nil) if (ver == nil)
ver = @""; ver = @"";
[query addAttributeWithName: @"ver" [query addAttributeWithName: @"ver" stringValue: ver];
stringValue: ver];
} }
[IQ addChild: query]; [IQ addChild: query];
@ -116,16 +115,14 @@ OF_ASSUME_NONNULL_END
IQ:)]; IQ:)];
} }
- (bool)connection: (XMPPConnection *)connection - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ
didReceiveIQ: (XMPPIQ *)IQ
{ {
OFXMLElement *rosterElement; OFXMLElement *rosterElement;
OFXMLElement *element; OFXMLElement *element;
XMPPRosterItem *rosterItem; XMPPRosterItem *rosterItem;
OFString *origin; OFString *origin;
rosterElement = [IQ elementForName: @"query" rosterElement = [IQ elementForName: @"query" namespace: XMPPRosterNS];
namespace: XMPP_NS_ROSTER];
if (rosterElement == nil) if (rosterElement == nil)
return false; return false;
@ -139,7 +136,7 @@ OF_ASSUME_NONNULL_END
return false; return false;
element = [rosterElement elementForName: @"item" element = [rosterElement elementForName: @"item"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
if (element != nil) { if (element != nil) {
rosterItem = [self xmpp_rosterItemWithXMLElement: element]; rosterItem = [self xmpp_rosterItemWithXMLElement: element];
@ -155,8 +152,7 @@ OF_ASSUME_NONNULL_END
if (_connection.supportsRosterVersioning) { if (_connection.supportsRosterVersioning) {
OFString *ver = OFString *ver =
[rosterElement attributeForName: @"ver"].stringValue; [rosterElement attributeForName: @"ver"].stringValue;
[_dataStorage setStringValue: ver [_dataStorage setStringValue: ver forPath: @"roster.ver"];
forPath: @"roster.ver"];
[_dataStorage save]; [_dataStorage save];
} }
@ -175,19 +171,18 @@ OF_ASSUME_NONNULL_END
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
ID: [_connection generateStanzaID]]; ID: [_connection generateStanzaID]];
OFXMLElement *query = [OFXMLElement elementWithName: @"query" OFXMLElement *query = [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
OFXMLElement *item = [OFXMLElement elementWithName: @"item" OFXMLElement *item = [OFXMLElement elementWithName: @"item"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID];
stringValue: rosterItem.JID.bareJID];
if (rosterItem.name != nil) if (rosterItem.name != nil)
[item addAttributeWithName: @"name" [item addAttributeWithName: @"name"
stringValue: rosterItem.name]; stringValue: rosterItem.name];
for (OFString *group in rosterItem.groups) for (OFString *group in rosterItem.groups)
[item addChild: [OFXMLElement elementWithName: @"group" [item addChild: [OFXMLElement elementWithName: @"group"
namespace: XMPP_NS_ROSTER namespace: XMPPRosterNS
stringValue: group]]; stringValue: group]];
[query addChild: item]; [query addChild: item];
@ -201,14 +196,12 @@ OF_ASSUME_NONNULL_END
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
ID: [_connection generateStanzaID]]; ID: [_connection generateStanzaID]];
OFXMLElement *query = [OFXMLElement elementWithName: @"query" OFXMLElement *query = [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
OFXMLElement *item = [OFXMLElement elementWithName: @"item" OFXMLElement *item = [OFXMLElement elementWithName: @"item"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID];
stringValue: rosterItem.JID.bareJID]; [item addAttributeWithName: @"subscription" stringValue: @"remove"];
[item addAttributeWithName: @"subscription"
stringValue: @"remove"];
[query addChild: item]; [query addChild: item];
[IQ addChild: query]; [IQ addChild: query];
@ -259,13 +252,11 @@ OF_ASSUME_NONNULL_END
[item setObject: rosterItem.groups [item setObject: rosterItem.groups
forKey: @"groups"]; forKey: @"groups"];
[items setObject: item [items setObject: item forKey: rosterItem.JID.bareJID];
forKey: rosterItem.JID.bareJID];
} else } else
[items removeObjectForKey: rosterItem.JID.bareJID]; [items removeObjectForKey: rosterItem.JID.bareJID];
[_dataStorage setDictionary: items [_dataStorage setDictionary: items forPath: @"roster.items"];
forPath: @"roster.items"];
} }
if (![rosterItem.subscription isEqual: @"remove"]) if (![rosterItem.subscription isEqual: @"remove"])
@ -296,8 +287,7 @@ OF_ASSUME_NONNULL_END
rosterItem.subscription = subscription; rosterItem.subscription = subscription;
for (OFXMLElement *groupElement in for (OFXMLElement *groupElement in
[element elementsForName: @"group" [element elementsForName: @"group" namespace: XMPPRosterNS])
namespace: XMPP_NS_ROSTER])
[groups addObject: groupElement.stringValue]; [groups addObject: groupElement.stringValue];
if (groups.count > 0) if (groups.count > 0)
@ -310,7 +300,7 @@ OF_ASSUME_NONNULL_END
IQ: (XMPPIQ *)IQ IQ: (XMPPIQ *)IQ
{ {
OFXMLElement *rosterElement = [IQ elementForName: @"query" OFXMLElement *rosterElement = [IQ elementForName: @"query"
namespace: XMPP_NS_ROSTER]; namespace: XMPPRosterNS];
if (connection.supportsRosterVersioning) { if (connection.supportsRosterVersioning) {
if (rosterElement == nil) { if (rosterElement == nil) {
@ -342,7 +332,7 @@ OF_ASSUME_NONNULL_END
XMPPRosterItem *rosterItem; XMPPRosterItem *rosterItem;
if (![element.name isEqual: @"item"] || if (![element.name isEqual: @"item"] ||
![element.namespace isEqual: XMPP_NS_ROSTER]) ![element.namespace isEqual: XMPPRosterNS])
continue; continue;
rosterItem = [self xmpp_rosterItemWithXMLElement: element]; rosterItem = [self xmpp_rosterItemWithXMLElement: element];
@ -355,8 +345,7 @@ OF_ASSUME_NONNULL_END
if (connection.supportsRosterVersioning && rosterElement != nil) { if (connection.supportsRosterVersioning && rosterElement != nil) {
OFString *ver = OFString *ver =
[rosterElement attributeForName: @"ver"].stringValue; [rosterElement attributeForName: @"ver"].stringValue;
[_dataStorage setStringValue: ver [_dataStorage setStringValue: ver forPath: @"roster.ver"];
forPath: @"roster.ver"];
[_dataStorage save]; [_dataStorage save];
} }

View file

@ -37,8 +37,7 @@
@interface XMPPSCRAMAuth () @interface XMPPSCRAMAuth ()
- (OFString *)xmpp_genNonce; - (OFString *)xmpp_genNonce;
- (const uint8_t *)xmpp_HMACWithKey: (OFData *)key - (const uint8_t *)xmpp_HMACWithKey: (OFData *)key data: (OFData *)data;
data: (OFData *)data;
- (OFData *)xmpp_hiWithData: (OFData *)str - (OFData *)xmpp_hiWithData: (OFData *)str
salt: (OFData *)salt salt: (OFData *)salt
iterationCount: (intmax_t)i; iterationCount: (intmax_t)i;
@ -137,10 +136,8 @@
if (authzid) { if (authzid) {
OFMutableString *new = [[authzid mutableCopy] autorelease]; OFMutableString *new = [[authzid mutableCopy] autorelease];
[new replaceOccurrencesOfString: @"=" [new replaceOccurrencesOfString: @"=" withString: @"=3D"];
withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"];
[new replaceOccurrencesOfString: @","
withString: @"=2C"];
[new makeImmutable]; [new makeImmutable];
_authzid = [new copy]; _authzid = [new copy];
} else } else
@ -155,10 +152,8 @@
if (authcid) { if (authcid) {
OFMutableString *new = [[authcid mutableCopy] autorelease]; OFMutableString *new = [[authcid mutableCopy] autorelease];
[new replaceOccurrencesOfString: @"=" [new replaceOccurrencesOfString: @"=" withString: @"=3D"];
withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"];
[new replaceOccurrencesOfString: @","
withString: @"=2C"];
[new makeImmutable]; [new makeImmutable];
_authcid = [new copy]; _authcid = [new copy];
} else } else
@ -281,17 +276,13 @@
count: channelBinding.count]; count: channelBinding.count];
} }
tmpString = tmpArray.stringByBase64Encoding; tmpString = tmpArray.stringByBase64Encoding;
[ret addItems: "c=" [ret addItems: "c=" count: 2];
count: 2]; [ret addItems: tmpString.UTF8String count: tmpString.UTF8StringLength];
[ret addItems: tmpString.UTF8String
count: tmpString.UTF8StringLength];
// Add r=<nonce> // Add r=<nonce>
[ret addItem: ","]; [ret addItem: ","];
[ret addItems: "r=" [ret addItems: "r=" count: 2];
count: 2]; [ret addItems: sNonce.UTF8String count: sNonce.UTF8StringLength];
[ret addItems: sNonce.UTF8String
count: sNonce.UTF8StringLength];
/* /*
* IETF RFC 5802: * IETF RFC 5802:
@ -312,19 +303,17 @@
[authMessage addItems: _clientFirstMessageBare.UTF8String [authMessage addItems: _clientFirstMessageBare.UTF8String
count: _clientFirstMessageBare.UTF8StringLength]; count: _clientFirstMessageBare.UTF8StringLength];
[authMessage addItem: ","]; [authMessage addItem: ","];
[authMessage addItems: data.items [authMessage addItems: data.items count: data.count * data.itemSize];
count: data.count * data.itemSize];
[authMessage addItem: ","]; [authMessage addItem: ","];
[authMessage addItems: ret.items [authMessage addItems: ret.items count: ret.count];
count: ret.count];
/* /*
* IETF RFC 5802: * IETF RFC 5802:
* ClientKey := HMAC(SaltedPassword, "Client Key") * ClientKey := HMAC(SaltedPassword, "Client Key")
*/ */
clientKey = [self xmpp_HMACWithKey: saltedPassword clientKey = [self
data: [OFData dataWithItems: "Client Key" xmpp_HMACWithKey: saltedPassword
count: 10]]; data: [OFData dataWithItems: "Client Key" count: 10]];
/* /*
* IETF RFC 5802: * IETF RFC 5802:
@ -346,9 +335,9 @@
* IETF RFC 5802: * IETF RFC 5802:
* ServerKey := HMAC(SaltedPassword, "Server Key") * ServerKey := HMAC(SaltedPassword, "Server Key")
*/ */
serverKey = [self xmpp_HMACWithKey: saltedPassword serverKey = [self
data: [OFData dataWithItems: "Server Key" xmpp_HMACWithKey: saltedPassword
count: 10]]; data: [OFData dataWithItems: "Server Key" count: 10]];
/* /*
* IETF RFC 5802: * IETF RFC 5802:
@ -359,8 +348,7 @@
[_serverSignature release]; [_serverSignature release];
_serverSignature = [[OFData alloc] _serverSignature = [[OFData alloc]
initWithItems: [self xmpp_HMACWithKey: tmpArray initWithItems: [self xmpp_HMACWithKey: tmpArray data: authMessage]
data: authMessage]
count: [_hashType digestSize]]; count: [_hashType digestSize]];
/* /*
@ -375,11 +363,9 @@
// Add p=<base64(ClientProof)> // Add p=<base64(ClientProof)>
[ret addItem: ","]; [ret addItem: ","];
[ret addItems: "p=" [ret addItems: "p=" count: 2];
count: 2];
tmpString = tmpArray.stringByBase64Encoding; tmpString = tmpArray.stringByBase64Encoding;
[ret addItems: tmpString.UTF8String [ret addItems: tmpString.UTF8String count: tmpString.UTF8StringLength];
count: tmpString.UTF8StringLength];
return ret; return ret;
} }
@ -447,11 +433,9 @@
hashI = [[[_hashType alloc] init] autorelease]; hashI = [[[_hashType alloc] init] autorelease];
[hashI updateWithBuffer: key.items [hashI updateWithBuffer: key.items
length: key.itemSize * key.count]; length: key.itemSize * key.count];
[k addItems: hashI.digest [k addItems: hashI.digest count: hashI.digestSize];
count: hashI.digestSize];
} else } else
[k addItems: key.items [k addItems: key.items count: key.itemSize * key.count];
count: key.itemSize * key.count];
@try { @try {
kI = OFAllocMemory(1, blockSize); kI = OFAllocMemory(1, blockSize);
@ -508,24 +492,21 @@
[salty addItems: "\0\0\0\1" [salty addItems: "\0\0\0\1"
count: 4]; count: 4];
uOld = [self xmpp_HMACWithKey: str uOld = [self xmpp_HMACWithKey: str data: salty];
data: salty];
for (j = 0; j < digestSize; j++) for (j = 0; j < digestSize; j++)
result[j] ^= uOld[j]; result[j] ^= uOld[j];
for (j = 0; j < i - 1; j++) { for (j = 0; j < i - 1; j++) {
tmp = [[OFMutableData alloc] init]; tmp = [[OFMutableData alloc] init];
[tmp addItems: uOld [tmp addItems: uOld count: digestSize];
count: digestSize];
/* releases uOld and previous tmp */ /* releases uOld and previous tmp */
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
pool = objc_autoreleasePoolPush(); pool = objc_autoreleasePoolPush();
[tmp autorelease]; [tmp autorelease];
u = [self xmpp_HMACWithKey: str u = [self xmpp_HMACWithKey: str data: tmp];
data: tmp];
for (k = 0; k < digestSize; k++) for (k = 0; k < digestSize; k++)
result[k] ^= u[k]; result[k] ^= u[k];
@ -533,8 +514,7 @@
uOld = u; uOld = u;
} }
ret = [OFData dataWithItems: result ret = [OFData dataWithItems: result count: digestSize];
count: digestSize];
} @finally { } @finally {
OFFreeMemory(result); OFFreeMemory(result);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2016, 2021, Jonathan Schleifer <js@nil.im>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -87,8 +87,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param ID The value for the stanza's id attribute * @param ID The value for the stanza's id attribute
* @return A new autoreleased XMPPStanza * @return A new autoreleased XMPPStanza
*/ */
+ (instancetype)stanzaWithName: (OFString *)name + (instancetype)stanzaWithName: (OFString *)name ID: (nullable OFString *)ID;
ID: (nullable OFString *)ID;
/*! /*!
* @brief Creates a new autoreleased XMPPStanza with the specified name, type * @brief Creates a new autoreleased XMPPStanza with the specified name, type
@ -137,8 +136,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param type The value for the stanza's type attribute * @param type The value for the stanza's type attribute
* @return A initialized XMPPStanza * @return A initialized XMPPStanza
*/ */
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name type: (nullable OFString *)type;
type: (nullable OFString *)type;
/*! /*!
* @brief Initializes an already allocated XMPPStanza with the specified name * @brief Initializes an already allocated XMPPStanza with the specified name
@ -148,8 +146,7 @@ OF_ASSUME_NONNULL_BEGIN
* @param ID The value for the stanza's id attribute * @param ID The value for the stanza's id attribute
* @return A initialized XMPPStanza * @return A initialized XMPPStanza
*/ */
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name ID: (nullable OFString *)ID;
ID: (nullable OFString *)ID;
/*! /*!
* @brief Initializes an already allocated XMPPStanza with the specified name, * @brief Initializes an already allocated XMPPStanza with the specified name,

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2019, 2021, Jonathan Schleifer <js@nil.im>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -36,18 +36,14 @@
return [[[self alloc] initWithName: name] autorelease]; return [[[self alloc] initWithName: name] autorelease];
} }
+ (instancetype)stanzaWithName: (OFString *)name + (instancetype)stanzaWithName: (OFString *)name type: (OFString *)type
type: (OFString *)type
{ {
return [[[self alloc] initWithName: name return [[[self alloc] initWithName: name type: type] autorelease];
type: type] autorelease];
} }
+ (instancetype)stanzaWithName: (OFString *)name + (instancetype)stanzaWithName: (OFString *)name ID: (OFString *)ID
ID: (OFString *)ID
{ {
return [[[self alloc] initWithName: name return [[[self alloc] initWithName: name ID: ID] autorelease];
ID: ID] autorelease];
} }
+ (instancetype)stanzaWithName: (OFString *)name + (instancetype)stanzaWithName: (OFString *)name
@ -70,8 +66,7 @@
OF_INVALID_INIT_METHOD OF_INVALID_INIT_METHOD
} }
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name namespace: (OFString *)namespace
namespace: (OFString *)namespace
{ {
OF_INVALID_INIT_METHOD OF_INVALID_INIT_METHOD
} }
@ -95,25 +90,18 @@
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name
{ {
return [self initWithName: name return [self initWithName: name type: nil ID: nil];
type: nil
ID: nil];
} }
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name type: (OFString *)type
type: (OFString *)type
{ {
return [self initWithName: name return [self initWithName: name type: type ID: nil];
type: type
ID: nil];
} }
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name
ID: (OFString *)ID ID: (OFString *)ID
{ {
return [self initWithName: name return [self initWithName: name type: nil ID: ID];
type: nil
ID: ID];
} }
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name
@ -121,7 +109,7 @@
ID: (OFString *)ID ID: (OFString *)ID
{ {
self = [super initWithName: name self = [super initWithName: name
namespace: XMPP_NS_CLIENT namespace: XMPPClientNS
stringValue: nil]; stringValue: nil];
@try { @try {
@ -129,9 +117,8 @@
![name isEqual: @"presence"]) ![name isEqual: @"presence"])
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
self.defaultNamespace = XMPP_NS_CLIENT; self.defaultNamespace = XMPPClientNS;
[self setPrefix: @"stream" [self setPrefix: @"stream" forNamespace: XMPPStreamNS];
forNamespace: XMPP_NS_STREAM];
if (type != nil) if (type != nil)
self.type = type; self.type = type;
@ -193,8 +180,7 @@
[self removeAttributeForName: @"from"]; [self removeAttributeForName: @"from"];
if (from != nil) if (from != nil)
[self addAttributeWithName: @"from" [self addAttributeWithName: @"from" stringValue: from.fullJID];
stringValue: from.fullJID];
} }
- (void)setTo: (XMPPJID *)to - (void)setTo: (XMPPJID *)to
@ -206,8 +192,7 @@
[self removeAttributeForName: @"to"]; [self removeAttributeForName: @"to"];
if (to != nil) if (to != nil)
[self addAttributeWithName: @"to" [self addAttributeWithName: @"to" stringValue: to.fullJID];
stringValue: to.fullJID];
} }
- (void)setType: (OFString *)type - (void)setType: (OFString *)type
@ -219,8 +204,7 @@
[self removeAttributeForName: @"type"]; [self removeAttributeForName: @"type"];
if (type != nil) if (type != nil)
[self addAttributeWithName: @"type" [self addAttributeWithName: @"type" stringValue: type];
stringValue: type];
} }
- (void)setID: (OFString *)ID - (void)setID: (OFString *)ID
@ -232,8 +216,7 @@
[self removeAttributeForName: @"id"]; [self removeAttributeForName: @"id"];
if (ID != nil) if (ID != nil)
[self addAttributeWithName: @"id" [self addAttributeWithName: @"id" stringValue: ID];
stringValue: ID];
} }
- (void)setLanguage: (OFString *)language - (void)setLanguage: (OFString *)language

View file

@ -30,17 +30,13 @@ OF_ASSUME_NONNULL_BEGIN
@protocol XMPPStorage <OFObject> @protocol XMPPStorage <OFObject>
- (void)save; - (void)save;
- (void)setStringValue: (nullable OFString *)string - (void)setStringValue: (nullable OFString *)string forPath: (OFString *)path;
forPath: (OFString *)path;
- (nullable OFString *)stringValueForPath: (OFString *)path; - (nullable OFString *)stringValueForPath: (OFString *)path;
- (void)setBooleanValue: (bool)boolean - (void)setBooleanValue: (bool)boolean forPath: (OFString *)path;
forPath: (OFString *)path;
- (bool)booleanValueForPath: (OFString *)path; - (bool)booleanValueForPath: (OFString *)path;
- (void)setIntegerValue: (long long)integer - (void)setIntegerValue: (long long)integer forPath: (OFString *)path;
forPath: (OFString *)path;
- (long long)integerValueForPath: (OFString *)path; - (long long)integerValueForPath: (OFString *)path;
- (void)setArray: (nullable OFArray *)array - (void)setArray: (nullable OFArray *)array forPath: (OFString *)path;
forPath: (OFString *)path;
- (nullable OFArray *)arrayForPath: (OFString *)path; - (nullable OFArray *)arrayForPath: (OFString *)path;
- (void)setDictionary: (nullable OFDictionary *)dictionary - (void)setDictionary: (nullable OFDictionary *)dictionary
forPath: (OFString *)path; forPath: (OFString *)path;

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2019, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2019, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -60,7 +60,7 @@
OFString *elementName = element.name; OFString *elementName = element.name;
OFString *elementNS = element.namespace; OFString *elementNS = element.namespace;
if ([elementNS isEqual: XMPP_NS_SM]) { if ([elementNS isEqual: XMPPSMNS]) {
if ([elementName isEqual: @"enabled"]) { if ([elementName isEqual: @"enabled"]) {
_receivedCount = 0; _receivedCount = 0;
return; return;
@ -74,7 +74,7 @@
if ([elementName isEqual: @"r"]) { if ([elementName isEqual: @"r"]) {
OFXMLElement *ack = OFXMLElement *ack =
[OFXMLElement elementWithName: @"a" [OFXMLElement elementWithName: @"a"
namespace: XMPP_NS_SM]; namespace: XMPPSMNS];
OFString *stringValue = [OFString OFString *stringValue = [OFString
stringWithFormat: @"%" PRIu32, _receivedCount]; stringWithFormat: @"%" PRIu32, _receivedCount];
[ack addAttributeWithName: @"h" [ack addAttributeWithName: @"h"
@ -83,7 +83,7 @@
} }
} }
if ([elementNS isEqual: XMPP_NS_CLIENT] && if ([elementNS isEqual: XMPPClientNS] &&
([elementName isEqual: @"iq"] || ([elementName isEqual: @"iq"] ||
[elementName isEqual: @"presence"] || [elementName isEqual: @"presence"] ||
[elementName isEqual: @"message"])) [elementName isEqual: @"message"]))
@ -97,12 +97,11 @@
} }
*/ */
- (void)connection: (XMPPConnection *)connection - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID
wasBoundToJID: (XMPPJID *)JID
{ {
if (connection.supportsStreamManagement) if (connection.supportsStreamManagement)
[connection sendStanza: [connection sendStanza:
[OFXMLElement elementWithName: @"enable" [OFXMLElement elementWithName: @"enable"
namespace: XMPP_NS_SM]]; namespace: XMPPSMNS]];
} }
@end @end

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2012, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -33,8 +33,7 @@
@throw [OFMalformedXMLException exception]; @throw [OFMalformedXMLException exception];
} }
- (void)parser: (OFXMLParser *)parser - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment
foundComment: (OFString *)comment
{ {
@throw [OFMalformedXMLException exception]; @throw [OFMalformedXMLException exception];
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2011, 2021, Jonathan Schleifer <js@nil.im>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -20,18 +20,18 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#define XMPP_NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind" #define XMPPBindNS @"urn:ietf:params:xml:ns:xmpp-bind"
#define XMPP_NS_CAPS @"http://jabber.org/protocol/caps" #define XMPPCapsNS @"http://jabber.org/protocol/caps"
#define XMPP_NS_CLIENT @"jabber:client" #define XMPPClientNS @"jabber:client"
#define XMPP_NS_DISCO_INFO @"http://jabber.org/protocol/disco#info" #define XMPPDiscoInfoNS @"http://jabber.org/protocol/disco#info"
#define XMPP_NS_DISCO_ITEMS @"http://jabber.org/protocol/disco#items" #define XMPPDiscoItemsNS @"http://jabber.org/protocol/disco#items"
#define XMPP_NS_MUC @"http://jabber.org/protocol/muc" #define XMPPMUCNS @"http://jabber.org/protocol/muc"
#define XMPP_NS_ROSTER @"jabber:iq:roster" #define XMPPRosterNS @"jabber:iq:roster"
#define XMPP_NS_ROSTERVER @"urn:xmpp:features:rosterver" #define XMPPRosterVerNS @"urn:xmpp:features:rosterver"
#define XMPP_NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl" #define XMPPSASLNS @"urn:ietf:params:xml:ns:xmpp-sasl"
#define XMPP_NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session" #define XMPPSessionNS @"urn:ietf:params:xml:ns:xmpp-session"
#define XMPP_NS_SM @"urn:xmpp:sm:3" #define XMPPSMNS @"urn:xmpp:sm:3"
#define XMPP_NS_STANZAS @"urn:ietf:params:xml:ns:xmpp-stanzas" #define XMPPStanzasNS @"urn:ietf:params:xml:ns:xmpp-stanzas"
#define XMPP_NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls" #define XMPPStartTLSNS @"urn:ietf:params:xml:ns:xmpp-tls"
#define XMPP_NS_STREAM @"http://etherx.jabber.org/streams" #define XMPPStreamNS @"http://etherx.jabber.org/streams"
#define XMPP_NS_XMPP_STREAM @"urn:ietf:params:xml:ns:xmpp-streams" #define XMPPXMPPStreamNS @"urn:ietf:params:xml:ns:xmpp-streams"

View file

@ -81,8 +81,7 @@ OF_APPLICATION_DELEGATE(AppDelegate)
@"from='alice@example.com'><body>Hello everyone</body>" @"from='alice@example.com'><body>Hello everyone</body>"
@"</message>"]); @"</message>"]);
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: @"128"];
ID: @"128"];
IQ.to = [XMPPJID JIDWithString: @"juliet@capulet.lit"]; IQ.to = [XMPPJID JIDWithString: @"juliet@capulet.lit"];
IQ.from = [XMPPJID JIDWithString: @"romeo@montague.lit"]; IQ.from = [XMPPJID JIDWithString: @"romeo@montague.lit"];
assert([IQ.XMLString isEqual: @"<iq type='set' id='128' " assert([IQ.XMLString isEqual: @"<iq type='set' id='128' "
@ -90,14 +89,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
@"from='romeo@montague.lit'/>"]); @"from='romeo@montague.lit'/>"]);
OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"]; OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"];
[elem addAttributeWithName: @"from" [elem addAttributeWithName: @"from" stringValue: @"bob@localhost"];
stringValue: @"bob@localhost"]; [elem addAttributeWithName: @"to" stringValue: @"alice@localhost"];
[elem addAttributeWithName: @"to" [elem addAttributeWithName: @"type" stringValue: @"get"];
stringValue: @"alice@localhost"]; [elem addAttributeWithName: @"id" stringValue: @"42"];
[elem addAttributeWithName: @"type"
stringValue: @"get"];
[elem addAttributeWithName: @"id"
stringValue: @"42"];
XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem]; XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
assert([elem.XMLString isEqual: [stanza XMLString]]); assert([elem.XMLString isEqual: [stanza XMLString]]);
assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", assert(([[OFString stringWithFormat: @"%@, %@, %@, %@",
@ -147,8 +142,7 @@ OF_APPLICATION_DELEGATE(AppDelegate)
OFLog(@"Auth successful"); OFLog(@"Auth successful");
} }
- (void)connection: (XMPPConnection *)conn_ - (void)connection: (XMPPConnection *)conn_ wasBoundToJID: (XMPPJID *)JID
wasBoundToJID: (XMPPJID *)JID
{ {
OFLog(@"Bound to JID: %@", JID.fullJID); OFLog(@"Bound to JID: %@", JID.fullJID);
OFLog(@"Supports SM: %@", OFLog(@"Supports SM: %@",
@ -212,12 +206,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
[conn sendStanza: pres]; [conn sendStanza: pres];
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
XMPPIQ *IQ = [XMPPIQ IQWithType: @"get" XMPPIQ *IQ = [XMPPIQ IQWithType: @"get" ID: [conn generateStanzaID]];
ID: [conn generateStanzaID]];
[IQ addChild: [OFXMLElement elementWithName: @"ping" [IQ addChild: [OFXMLElement elementWithName: @"ping"
namespace: @"urn:xmpp:ping"]]; namespace: @"urn:xmpp:ping"]];
[conn sendIQ: IQ [conn sendIQ: IQ callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) {
callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) {
OFLog(@"Ping response: %@", resp); OFLog(@"Ping response: %@", resp);
}]; }];
#endif #endif
@ -243,16 +235,14 @@ OF_APPLICATION_DELEGATE(AppDelegate)
OFLog(@"Got roster push: %@", rosterItem); OFLog(@"Got roster push: %@", rosterItem);
} }
- (bool)connection: (XMPPConnection *)conn - (bool)connection: (XMPPConnection *)conn didReceiveIQ: (XMPPIQ *)iq
didReceiveIQ: (XMPPIQ *)iq
{ {
OFLog(@"IQ: %@", iq); OFLog(@"IQ: %@", iq);
return NO; return NO;
} }
- (void)connection: (XMPPConnection *)conn - (void)connection: (XMPPConnection *)conn didReceiveMessage: (XMPPMessage *)msg
didReceiveMessage: (XMPPMessage *)msg
{ {
OFLog(@"Message: %@", msg); OFLog(@"Message: %@", msg);
} }
@ -263,14 +253,12 @@ OF_APPLICATION_DELEGATE(AppDelegate)
OFLog(@"Presence: %@", pres); OFLog(@"Presence: %@", pres);
} }
- (void)connection: (XMPPConnection *)conn - (void)connection: (XMPPConnection *)conn didThrowException: (id)e
didThrowException: (id)e
{ {
@throw e; @throw e;
} }
- (void)connectionWasClosed: (XMPPConnection *)conn - (void)connectionWasClosed: (XMPPConnection *)conn error: (OFXMLElement *)error
error: (OFXMLElement *)error
{ {
OFLog(@"Connection was closed: %@", error); OFLog(@"Connection was closed: %@", error);
} }