Adjust to ObjFW style
FossilOrigin-Name: 9919057cb8bb237afb11f251210a1764228c46661d5f8290708846fa70c6af83
This commit is contained in:
parent
851e7fe676
commit
098092053c
30 changed files with 285 additions and 462 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -31,9 +31,7 @@
|
|||
- (instancetype)initWithAuthcid: (OFString *)authcid
|
||||
password: (OFString *)password
|
||||
{
|
||||
return [self initWithAuthzid: nil
|
||||
authcid: authcid
|
||||
password: password];
|
||||
return [self initWithAuthzid: nil authcid: authcid password: password];
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthzid: (OFString *)authzid
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
|
||||
* Copyright (c) 2021, Jonathan Schleifer <js@nil.im>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
*
|
||||
|
@ -28,8 +29,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
@class XMPPIQ;
|
||||
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
typedef void (^xmpp_callback_block_t)(XMPPConnection *_Nonnull,
|
||||
XMPPIQ *_Nonnull);
|
||||
typedef void (^XMPPCallbackBlock)(XMPPConnection *_Nonnull, XMPPIQ *_Nonnull);
|
||||
#endif
|
||||
|
||||
@interface XMPPCallback: OFObject
|
||||
|
@ -37,22 +37,19 @@ typedef void (^xmpp_callback_block_t)(XMPPConnection *_Nonnull,
|
|||
id _target;
|
||||
SEL _selector;
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
xmpp_callback_block_t _block;
|
||||
XMPPCallbackBlock _block;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
+ (instancetype)callbackWithBlock: (xmpp_callback_block_t)callback;
|
||||
- (instancetype)initWithBlock: (xmpp_callback_block_t)callback;
|
||||
+ (instancetype)callbackWithBlock: (XMPPCallbackBlock)callback;
|
||||
- (instancetype)initWithBlock: (XMPPCallbackBlock)callback;
|
||||
#endif
|
||||
|
||||
+ (instancetype)callbackWithTarget: (id)target
|
||||
selector: (SEL)selector;
|
||||
- (instancetype)initWithTarget: (id)target
|
||||
selector: (SEL)selector;
|
||||
+ (instancetype)callbackWithTarget: (id)target selector: (SEL)selector;
|
||||
- (instancetype)initWithTarget: (id)target selector: (SEL)selector;
|
||||
|
||||
- (void)runWithIQ: (XMPPIQ *)iq
|
||||
connection: (XMPPConnection *)connection;
|
||||
- (void)runWithIQ: (XMPPIQ *)iq connection: (XMPPConnection *)connection;
|
||||
@end
|
||||
|
||||
OF_ASSUME_NONNULL_END
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
|
||||
* Copyright (c) 2021, Jonathan Schleifer <js@nil.im>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
*
|
||||
|
@ -26,13 +27,13 @@
|
|||
|
||||
@implementation XMPPCallback
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
+ (instancetype)callbackWithBlock: (xmpp_callback_block_t)block
|
||||
+ (instancetype)callbackWithBlock: (XMPPCallbackBlock)block
|
||||
{
|
||||
return [[(XMPPCallback *)[self alloc]
|
||||
initWithBlock: block] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)initWithBlock: (xmpp_callback_block_t)block
|
||||
- (instancetype)initWithBlock: (XMPPCallbackBlock)block
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
@ -47,15 +48,13 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
+ (instancetype)callbackWithTarget: (id)target
|
||||
selector: (SEL)selector
|
||||
+ (instancetype)callbackWithTarget: (id)target selector: (SEL)selector
|
||||
{
|
||||
return [[[self alloc] initWithTarget: target
|
||||
selector: selector] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTarget: (id)target
|
||||
selector: (SEL)selector
|
||||
- (instancetype)initWithTarget: (id)target selector: (SEL)selector
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
@ -75,8 +74,7 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)runWithIQ: (XMPPIQ *)IQ
|
||||
connection: (XMPPConnection *)connection
|
||||
- (void)runWithIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection
|
||||
{
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
if (_block != NULL)
|
||||
|
|
|
@ -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>
|
||||
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
|
||||
*
|
||||
|
@ -29,7 +29,7 @@
|
|||
|
||||
OF_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#define XMPP_CONNECTION_BUFFER_LENGTH 512
|
||||
#define XMPPConnectionBufferLength 512
|
||||
|
||||
@class XMPPConnection;
|
||||
@class XMPPJID;
|
||||
|
@ -77,17 +77,15 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param connection The connection that was bound to a JID
|
||||
* @param JID The JID the conecction was bound to
|
||||
*/
|
||||
- (void)connection: (XMPPConnection *)connection
|
||||
wasBoundToJID: (XMPPJID *)JID;
|
||||
- (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID;
|
||||
|
||||
/*!
|
||||
* @brief This callback is called when the connection received an IQ 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
|
||||
didReceiveIQ: (XMPPIQ *)iq;
|
||||
- (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ;
|
||||
|
||||
/*!
|
||||
* @brief This callback is called when the connection received a presence
|
||||
|
@ -148,7 +146,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
@interface XMPPConnection: OFObject
|
||||
{
|
||||
OFTCPSocket *_socket;
|
||||
char _buffer[XMPP_CONNECTION_BUFFER_LENGTH];
|
||||
char _buffer[XMPPConnectionBufferLength];
|
||||
OFXMLParser *_parser, *_oldParser;
|
||||
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
|
||||
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
|
||||
* the connection was closed.
|
||||
*/
|
||||
- (void)parseBuffer: (const void *)buffer
|
||||
length: (size_t)length;
|
||||
- (void)parseBuffer: (const void *)buffer length: (size_t)length;
|
||||
|
||||
/*!
|
||||
* @brief Sends an OFXMLElement, usually an XMPPStanza.
|
||||
|
@ -338,8 +335,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param IQ The IQ to send
|
||||
* @param block The callback block
|
||||
*/
|
||||
- (void)sendIQ: (XMPPIQ *)IQ
|
||||
callbackBlock: (xmpp_callback_block_t)block;
|
||||
- (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (XMPPCallbackBlock)block;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
|
|
@ -59,8 +59,7 @@
|
|||
@interface XMPPConnection () <OFDNSResolverQueryDelegate, OFTCPSocketDelegate,
|
||||
OFXMLParserDelegate, OFXMLElementBuilderDelegate>
|
||||
- (void)xmpp_tryNextSRVRecord;
|
||||
- (bool)xmpp_parseBuffer: (const void *)buffer
|
||||
length: (size_t)length;
|
||||
- (bool)xmpp_parseBuffer: (const void *)buffer length: (size_t)length;
|
||||
- (void)xmpp_startStream;
|
||||
- (void)xmpp_handleStanza: (OFXMLElement *)element;
|
||||
- (void)xmpp_handleStream: (OFXMLElement *)element;
|
||||
|
@ -72,8 +71,7 @@
|
|||
- (void)xmpp_handleFeatures: (OFXMLElement *)element;
|
||||
- (void)xmpp_sendAuth: (OFString *)authName;
|
||||
- (void)xmpp_sendResourceBind;
|
||||
- (void)xmpp_sendStreamError: (OFString *)condition
|
||||
text: (OFString *)text;
|
||||
- (void)xmpp_sendStreamError: (OFString *)condition text: (OFString *)text;
|
||||
- (void)xmpp_handleResourceBindForConnection: (XMPPConnection *)connection
|
||||
IQ: (XMPPIQ *)IQ;
|
||||
- (void)xmpp_sendSession;
|
||||
|
@ -278,7 +276,7 @@
|
|||
[self xmpp_startStream];
|
||||
|
||||
[_socket asyncReadIntoBuffer: _buffer
|
||||
length: XMPP_CONNECTION_BUFFER_LENGTH];
|
||||
length: XMPPConnectionBufferLength];
|
||||
}
|
||||
|
||||
- (void)xmpp_tryNextSRVRecord
|
||||
|
@ -291,8 +289,7 @@
|
|||
_nextSRVRecords = nil;
|
||||
}
|
||||
|
||||
[_socket asyncConnectToHost: record.target
|
||||
port: record.port];
|
||||
[_socket asyncConnectToHost: record.target port: record.port];
|
||||
}
|
||||
|
||||
- (void)resolver: (OFDNSResolver *)resolver
|
||||
|
@ -315,8 +312,7 @@
|
|||
|
||||
if (records.count == 0) {
|
||||
/* Fall back to A / AAAA record. */
|
||||
[_socket asyncConnectToHost: _domainToASCII
|
||||
port: _port];
|
||||
[_socket asyncConnectToHost: _domainToASCII port: _port];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -337,8 +333,7 @@
|
|||
[_socket setDelegate: self];
|
||||
|
||||
if (_server != nil)
|
||||
[_socket asyncConnectToHost: _server
|
||||
port: _port];
|
||||
[_socket asyncConnectToHost: _server port: _port];
|
||||
else {
|
||||
OFString *SRVDomain = [_domainToASCII
|
||||
stringByPrependingString: @"_xmpp-client._tcp."];
|
||||
|
@ -365,11 +360,9 @@
|
|||
}
|
||||
|
||||
@try {
|
||||
[_parser parseBuffer: buffer
|
||||
length: length];
|
||||
[_parser parseBuffer: buffer length: length];
|
||||
} @catch (OFMalformedXMLException *e) {
|
||||
[self xmpp_sendStreamError: @"bad-format"
|
||||
text: nil];
|
||||
[self xmpp_sendStreamError: @"bad-format" text: nil];
|
||||
[self close];
|
||||
return false;
|
||||
}
|
||||
|
@ -377,11 +370,9 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
- (void)parseBuffer: (const void *)buffer
|
||||
length: (size_t)length
|
||||
- (void)parseBuffer: (const void *)buffer length: (size_t)length
|
||||
{
|
||||
[self xmpp_parseBuffer: buffer
|
||||
length: length];
|
||||
[self xmpp_parseBuffer: buffer length: length];
|
||||
|
||||
[_oldParser release];
|
||||
[_oldElementBuilder release];
|
||||
|
@ -405,8 +396,7 @@
|
|||
}
|
||||
|
||||
@try {
|
||||
if (![self xmpp_parseBuffer: buffer
|
||||
length: length])
|
||||
if (![self xmpp_parseBuffer: buffer length: length])
|
||||
return false;
|
||||
} @catch (id e) {
|
||||
[_delegates broadcastSelector: @selector(connection:
|
||||
|
@ -425,7 +415,7 @@
|
|||
_oldElementBuilder = nil;
|
||||
|
||||
[_socket asyncReadIntoBuffer: _buffer
|
||||
length: XMPP_CONNECTION_BUFFER_LENGTH];
|
||||
length: XMPPConnectionBufferLength];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -502,10 +492,8 @@
|
|||
key = @"bind";
|
||||
key = [key stringByAppendingString: ID];
|
||||
|
||||
callback = [XMPPCallback callbackWithTarget: target
|
||||
selector: selector];
|
||||
[_callbacks setObject: callback
|
||||
forKey: key];
|
||||
callback = [XMPPCallback callbackWithTarget: target selector: selector];
|
||||
[_callbacks setObject: callback forKey: key];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
|
||||
|
@ -513,8 +501,7 @@
|
|||
}
|
||||
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
- (void)sendIQ: (XMPPIQ *)IQ
|
||||
callbackBlock: (xmpp_callback_block_t)block
|
||||
- (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (XMPPCallbackBlock)block
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
XMPPCallback *callback;
|
||||
|
@ -532,8 +519,7 @@
|
|||
key = [key stringByAppendingString: ID];
|
||||
|
||||
callback = [XMPPCallback callbackWithBlock: block];
|
||||
[_callbacks setObject: callback
|
||||
forKey: key];
|
||||
[_callbacks setObject: callback forKey: key];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
|
||||
|
@ -560,22 +546,19 @@
|
|||
}
|
||||
|
||||
if (![prefix isEqual: @"stream"]) {
|
||||
[self xmpp_sendStreamError: @"bad-namespace-prefix"
|
||||
text: nil];
|
||||
[self xmpp_sendStreamError: @"bad-namespace-prefix" text: nil];
|
||||
return;
|
||||
}
|
||||
|
||||
if (![namespace isEqual: XMPP_NS_STREAM]) {
|
||||
[self xmpp_sendStreamError: @"invalid-namespace"
|
||||
text: nil];
|
||||
if (![namespace isEqual: XMPPStreamNS]) {
|
||||
[self xmpp_sendStreamError: @"invalid-namespace" text: nil];
|
||||
return;
|
||||
}
|
||||
|
||||
for (OFXMLAttribute *attribute in attributes) {
|
||||
if ([attribute.name isEqual: @"from"] &&
|
||||
![attribute.stringValue isEqual: _domain]) {
|
||||
[self xmpp_sendStreamError: @"invalid-from"
|
||||
text: nil];
|
||||
[self xmpp_sendStreamError: @"invalid-from" text: nil];
|
||||
return;
|
||||
}
|
||||
if ([attribute.name isEqual: @"version"] &&
|
||||
|
@ -596,24 +579,23 @@
|
|||
if (element.name == nil)
|
||||
return;
|
||||
|
||||
element.defaultNamespace = XMPP_NS_CLIENT;
|
||||
[element setPrefix: @"stream"
|
||||
forNamespace: XMPP_NS_STREAM];
|
||||
element.defaultNamespace = XMPPClientNS;
|
||||
[element setPrefix: @"stream" forNamespace: XMPPStreamNS];
|
||||
|
||||
[_delegates broadcastSelector: @selector(connection:didReceiveElement:)
|
||||
withObject: self
|
||||
withObject: element];
|
||||
|
||||
if ([element.namespace isEqual: XMPP_NS_CLIENT])
|
||||
if ([element.namespace isEqual: XMPPClientNS])
|
||||
[self xmpp_handleStanza: element];
|
||||
|
||||
if ([element.namespace isEqual: XMPP_NS_STREAM])
|
||||
if ([element.namespace isEqual: XMPPStreamNS])
|
||||
[self xmpp_handleStream: element];
|
||||
|
||||
if ([element.namespace isEqual: XMPP_NS_STARTTLS])
|
||||
if ([element.namespace isEqual: XMPPStartTLSNS])
|
||||
[self xmpp_handleTLS: element];
|
||||
|
||||
if ([element.namespace isEqual: XMPP_NS_SASL])
|
||||
if ([element.namespace isEqual: XMPPSASLNS])
|
||||
[self xmpp_handleSASL: element];
|
||||
}
|
||||
|
||||
|
@ -623,7 +605,7 @@
|
|||
namespace: (OFString *)ns
|
||||
{
|
||||
if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
|
||||
![ns isEqual: XMPP_NS_STREAM])
|
||||
![ns isEqual: XMPPStreamNS])
|
||||
@throw [OFMalformedXMLException exception];
|
||||
else
|
||||
[self close];
|
||||
|
@ -656,8 +638,8 @@
|
|||
|
||||
[_socket writeFormat: @"<?xml version='1.0'?>\n"
|
||||
@"<stream:stream to='%@' "
|
||||
@"xmlns='" XMPP_NS_CLIENT @"' "
|
||||
@"xmlns:stream='" XMPP_NS_STREAM @"' %@"
|
||||
@"xmlns='" XMPPClientNS @"' "
|
||||
@"xmlns:stream='" XMPPStreamNS @"' %@"
|
||||
@"version='1.0'>", _domain, langString];
|
||||
|
||||
_streamOpen = true;
|
||||
|
@ -702,8 +684,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
[self xmpp_sendStreamError: @"unsupported-stanza-type"
|
||||
text: nil];
|
||||
[self xmpp_sendStreamError: @"unsupported-stanza-type" text: nil];
|
||||
}
|
||||
|
||||
|
||||
|
@ -722,15 +703,14 @@
|
|||
withObject: self
|
||||
withObject: element];
|
||||
|
||||
condition = [[element elementsForNamespace:
|
||||
XMPP_NS_XMPP_STREAM].firstObject name];
|
||||
condition = [[element elementsForNamespace: XMPPXMPPStreamNS]
|
||||
.firstObject name];
|
||||
|
||||
if (condition == nil)
|
||||
condition = @"undefined";
|
||||
|
||||
reason = [element
|
||||
elementForName: @"text"
|
||||
namespace: XMPP_NS_XMPP_STREAM].stringValue;
|
||||
reason = [element elementForName: @"text"
|
||||
namespace: XMPPXMPPStreamNS].stringValue;
|
||||
|
||||
@throw [XMPPStreamErrorException
|
||||
exceptionWithConnection: self
|
||||
|
@ -793,7 +773,7 @@
|
|||
OFData *response = [_authModule continueWithData: challenge];
|
||||
|
||||
responseTag = [OFXMLElement elementWithName: @"response"
|
||||
namespace: XMPP_NS_SASL];
|
||||
namespace: XMPPSASLNS];
|
||||
if (response) {
|
||||
if (response.count == 0)
|
||||
responseTag.stringValue = @"=";
|
||||
|
@ -843,8 +823,7 @@
|
|||
key = [key stringByAppendingString: IQ.ID];
|
||||
|
||||
if ((callback = [_callbacks objectForKey: key])) {
|
||||
[callback runWithIQ: IQ
|
||||
connection: self];
|
||||
[callback runWithIQ: IQ connection: self];
|
||||
[_callbacks removeObjectForKey: key];
|
||||
return;
|
||||
}
|
||||
|
@ -878,19 +857,19 @@
|
|||
- (void)xmpp_handleFeatures: (OFXMLElement *)element
|
||||
{
|
||||
OFXMLElement *startTLS = [element elementForName: @"starttls"
|
||||
namespace: XMPP_NS_STARTTLS];
|
||||
namespace: XMPPStartTLSNS];
|
||||
OFXMLElement *bind = [element elementForName: @"bind"
|
||||
namespace: XMPP_NS_BIND];
|
||||
namespace: XMPPBindNS];
|
||||
OFXMLElement *session = [element elementForName: @"session"
|
||||
namespace: XMPP_NS_SESSION];
|
||||
namespace: XMPPSessionNS];
|
||||
OFXMLElement *mechs = [element elementForName: @"mechanisms"
|
||||
namespace: XMPP_NS_SASL];
|
||||
namespace: XMPPSASLNS];
|
||||
OFMutableSet *mechanisms = [OFMutableSet set];
|
||||
|
||||
if (!_encrypted && startTLS != nil) {
|
||||
[self sendStanza:
|
||||
[OFXMLElement elementWithName: @"starttls"
|
||||
namespace: XMPP_NS_STARTTLS]];
|
||||
namespace: XMPPStartTLSNS]];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -898,12 +877,10 @@
|
|||
/* TODO: Find/create an exception to throw here */
|
||||
@throw [OFException exception];
|
||||
|
||||
if ([element elementForName: @"ver"
|
||||
namespace: XMPP_NS_ROSTERVER] != nil)
|
||||
if ([element elementForName: @"ver" namespace: XMPPRosterVerNS] != nil)
|
||||
_supportsRosterVersioning = true;
|
||||
|
||||
if ([element elementForName: @"sm"
|
||||
namespace: XMPP_NS_SM] != nil)
|
||||
if ([element elementForName: @"sm" namespace: XMPPSMNS] != nil)
|
||||
_supportsStreamManagement = true;
|
||||
|
||||
if (mechs != nil) {
|
||||
|
@ -966,7 +943,7 @@
|
|||
}
|
||||
|
||||
if (session != nil && [session elementForName: @"optional"
|
||||
namespace: XMPP_NS_SESSION] == nil)
|
||||
namespace: XMPPSessionNS] == nil)
|
||||
_needsSession = true;
|
||||
|
||||
if (bind != nil) {
|
||||
|
@ -982,10 +959,8 @@
|
|||
OFXMLElement *authTag;
|
||||
OFData *initialMessage = [_authModule initialMessage];
|
||||
|
||||
authTag = [OFXMLElement elementWithName: @"auth"
|
||||
namespace: XMPP_NS_SASL];
|
||||
[authTag addAttributeWithName: @"mechanism"
|
||||
stringValue: authName];
|
||||
authTag = [OFXMLElement elementWithName: @"auth" namespace: XMPPSASLNS];
|
||||
[authTag addAttributeWithName: @"mechanism" stringValue: authName];
|
||||
if (initialMessage != nil) {
|
||||
if (initialMessage.count == 0)
|
||||
authTag.stringValue = @"=";
|
||||
|
@ -1002,15 +977,13 @@
|
|||
XMPPIQ *IQ;
|
||||
OFXMLElement *bind;
|
||||
|
||||
IQ = [XMPPIQ IQWithType: @"set"
|
||||
ID: [self generateStanzaID]];
|
||||
IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]];
|
||||
|
||||
bind = [OFXMLElement elementWithName: @"bind"
|
||||
namespace: XMPP_NS_BIND];
|
||||
bind = [OFXMLElement elementWithName: @"bind" namespace: XMPPBindNS];
|
||||
|
||||
if (_resource != nil)
|
||||
[bind addChild: [OFXMLElement elementWithName: @"resource"
|
||||
namespace: XMPP_NS_BIND
|
||||
namespace: XMPPBindNS
|
||||
stringValue: _resource]];
|
||||
|
||||
[IQ addChild: bind];
|
||||
|
@ -1026,15 +999,14 @@
|
|||
{
|
||||
OFXMLElement *error = [OFXMLElement
|
||||
elementWithName: @"error"
|
||||
namespace: XMPP_NS_STREAM];
|
||||
[error setPrefix: @"stream"
|
||||
forNamespace: XMPP_NS_STREAM];
|
||||
namespace: XMPPStreamNS];
|
||||
[error setPrefix: @"stream" forNamespace: XMPPStreamNS];
|
||||
[error addChild: [OFXMLElement elementWithName: condition
|
||||
namespace: XMPP_NS_XMPP_STREAM]];
|
||||
namespace: XMPPXMPPStreamNS]];
|
||||
if (text)
|
||||
[error addChild: [OFXMLElement
|
||||
elementWithName: @"text"
|
||||
namespace: XMPP_NS_XMPP_STREAM
|
||||
namespace: XMPPXMPPStreamNS
|
||||
stringValue: text]];
|
||||
_parser.delegate = nil;
|
||||
[self sendStanza: error];
|
||||
|
@ -1048,13 +1020,11 @@
|
|||
|
||||
assert([IQ.type isEqual: @"result"]);
|
||||
|
||||
bindElement = [IQ elementForName: @"bind"
|
||||
namespace: XMPP_NS_BIND];
|
||||
bindElement = [IQ elementForName: @"bind" namespace: XMPPBindNS];
|
||||
|
||||
assert(bindElement != nil);
|
||||
|
||||
JIDElement = [bindElement elementForName: @"jid"
|
||||
namespace: XMPP_NS_BIND];
|
||||
JIDElement = [bindElement elementForName: @"jid" namespace: XMPPBindNS];
|
||||
_JID = [[XMPPJID alloc] initWithString: JIDElement.stringValue];
|
||||
|
||||
if (_needsSession) {
|
||||
|
@ -1069,11 +1039,10 @@
|
|||
|
||||
- (void)xmpp_sendSession
|
||||
{
|
||||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
|
||||
ID: [self generateStanzaID]];
|
||||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]];
|
||||
|
||||
[IQ addChild: [OFXMLElement elementWithName: @"session"
|
||||
namespace: XMPP_NS_SESSION]];
|
||||
namespace: XMPPSessionNS]];
|
||||
|
||||
[self sendIQ: IQ
|
||||
callbackTarget: self
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -75,11 +75,9 @@
|
|||
resource: (OFString *)resource
|
||||
{
|
||||
if (resource != nil)
|
||||
[_presences setObject: presence
|
||||
forKey: resource];
|
||||
[_presences setObject: presence forKey: resource];
|
||||
else
|
||||
[_presences setObject: presence
|
||||
forKey: @""];
|
||||
[_presences setObject: presence forKey: @""];
|
||||
|
||||
self.xmpp_lockedOnJID = nil;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -92,8 +92,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param contact The contact that send the message
|
||||
* @param message The message which was send by the contact
|
||||
*/
|
||||
- (void)contact: (XMPPContact *)contact
|
||||
didSendMessage: (XMPPMessage *)message;
|
||||
- (void)contact: (XMPPContact *)contact didSendMessage: (XMPPMessage *)message;
|
||||
@end
|
||||
|
||||
/*!
|
||||
|
|
|
@ -107,8 +107,7 @@
|
|||
for (OFString *bareJID in rosterItems) {
|
||||
XMPPContact *contact = [[[XMPPContact alloc] init] autorelease];
|
||||
contact.rosterItem = [rosterItems objectForKey: bareJID];
|
||||
[_contacts setObject: contact
|
||||
forKey: bareJID];
|
||||
[_contacts setObject: contact forKey: bareJID];
|
||||
[_delegates broadcastSelector: @selector(contactManager:
|
||||
didAddContact:)
|
||||
withObject: self
|
||||
|
@ -137,8 +136,7 @@
|
|||
if (contact == nil) {
|
||||
contact = [[[XMPPContact alloc] init] autorelease];
|
||||
contact.rosterItem = rosterItem;
|
||||
[_contacts setObject: contact
|
||||
forKey: bareJID];
|
||||
[_contacts setObject: contact forKey: bareJID];
|
||||
[_delegates broadcastSelector: @selector(contactManager:
|
||||
didAddContact:)
|
||||
withObject: self
|
||||
|
@ -174,8 +172,7 @@
|
|||
|
||||
/* Available presence */
|
||||
if ([type isEqual: @"available"]) {
|
||||
[contact xmpp_setPresence: presence
|
||||
resource: JID.resource];
|
||||
[contact xmpp_setPresence: presence resource: JID.resource];
|
||||
[_delegates broadcastSelector: @selector(contact:
|
||||
didSendPresence:)
|
||||
withObject: contact
|
||||
|
|
|
@ -32,8 +32,7 @@
|
|||
@implementation XMPPDiscoEntity
|
||||
@synthesize discoNodes = _discoNodes, capsNode = _capsNode;
|
||||
|
||||
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID
|
||||
node: (OFString *)node
|
||||
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node
|
||||
{
|
||||
OF_UNRECOGNIZED_SELECTOR
|
||||
}
|
||||
|
@ -57,8 +56,7 @@
|
|||
capsNode: capsNode] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID
|
||||
node: (nullable OFString *)node
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node
|
||||
{
|
||||
OF_INVALID_INIT_METHOD
|
||||
}
|
||||
|
@ -79,9 +77,7 @@
|
|||
- (instancetype)initWithConnection: (XMPPConnection *)connection
|
||||
capsNode: (OFString *)capsNode
|
||||
{
|
||||
self = [super initWithJID: [connection JID]
|
||||
node: nil
|
||||
name: nil];
|
||||
self = [super initWithJID: [connection JID] node: nil name: nil];
|
||||
|
||||
@try {
|
||||
_discoNodes = [[OFMutableDictionary alloc] init];
|
||||
|
@ -107,8 +103,7 @@
|
|||
|
||||
- (void)addDiscoNode: (XMPPDiscoNode *)node
|
||||
{
|
||||
[_discoNodes setObject: node
|
||||
forKey: node.node];
|
||||
[_discoNodes setObject: node forKey: node.node];
|
||||
}
|
||||
|
||||
- (OFString *)capsHash
|
||||
|
@ -124,11 +119,9 @@
|
|||
for (OFString *feature in _features)
|
||||
[caps appendFormat: @"%@<", feature];
|
||||
|
||||
[hash updateWithBuffer: caps.UTF8String
|
||||
length: caps.UTF8StringLength];
|
||||
[hash updateWithBuffer: caps.UTF8String length: caps.UTF8StringLength];
|
||||
|
||||
digest = [OFData dataWithItems: hash.digest
|
||||
count: hash.digestSize];
|
||||
digest = [OFData dataWithItems: hash.digest count: hash.digestSize];
|
||||
|
||||
return digest.stringByBase64Encoding;
|
||||
}
|
||||
|
@ -146,7 +139,7 @@
|
|||
return false;
|
||||
|
||||
OFXMLElement *query = [IQ elementForName: @"query"
|
||||
namespace: XMPP_NS_DISCO_ITEMS];
|
||||
namespace: XMPPDiscoItemsNS];
|
||||
|
||||
if (query != nil) {
|
||||
OFString *node = [query attributeForName: @"node"].stringValue;
|
||||
|
@ -162,8 +155,7 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
query = [IQ elementForName: @"query"
|
||||
namespace: XMPP_NS_DISCO_INFO];
|
||||
query = [IQ elementForName: @"query" namespace: XMPPDiscoInfoNS];
|
||||
|
||||
if (query != nil) {
|
||||
OFString *node = [query attributeForName: @"node"].stringValue;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -96,8 +96,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param type The type of the identity
|
||||
* @return An initialized XMPPDiscoIdentity
|
||||
*/
|
||||
- (instancetype)initWithCategory: (OFString *)category
|
||||
type: (OFString *)type;
|
||||
- (instancetype)initWithCategory: (OFString *)category type: (OFString *)type;
|
||||
@end
|
||||
|
||||
OF_ASSUME_NONNULL_END
|
||||
|
|
|
@ -63,12 +63,9 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCategory: (OFString *)category
|
||||
type: (OFString *)type
|
||||
- (instancetype)initWithCategory: (OFString *)category type: (OFString *)type
|
||||
{
|
||||
return [self initWithCategory: category
|
||||
type: type
|
||||
name: nil];
|
||||
return [self initWithCategory: category type: type name: nil];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -103,8 +103,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param node The node's opaque name
|
||||
* @return An initialized XMPPDiscoNode
|
||||
*/
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID
|
||||
node: (nullable OFString *)node;
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node;
|
||||
|
||||
/*!
|
||||
* @brief Initializes an already allocated XMPPDiscoNode with the specified
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -35,11 +35,9 @@
|
|||
@synthesize JID = _JID, node = _node, name = _name, identities = _identities;
|
||||
@synthesize features = _features, childNodes = _childNodes;
|
||||
|
||||
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID
|
||||
node: (OFString *)node;
|
||||
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node;
|
||||
{
|
||||
return [[[self alloc] initWithJID: JID
|
||||
node: node] autorelease];
|
||||
return [[[self alloc] initWithJID: JID node: node] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)discoNodeWithJID: (XMPPJID *)JID
|
||||
|
@ -51,12 +49,9 @@
|
|||
name: name] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID
|
||||
node: (OFString *)node
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID node: (OFString *)node
|
||||
{
|
||||
return [self initWithJID: JID
|
||||
node: node
|
||||
name: nil];
|
||||
return [self initWithJID: JID node: node name: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithJID: (XMPPJID *)JID
|
||||
|
@ -77,8 +72,8 @@
|
|||
_features = [[OFSortedList alloc] init];
|
||||
_childNodes = [[OFMutableDictionary alloc] init];
|
||||
|
||||
[self addFeature: XMPP_NS_DISCO_ITEMS];
|
||||
[self addFeature: XMPP_NS_DISCO_INFO];
|
||||
[self addFeature: XMPPDiscoItemsNS];
|
||||
[self addFeature: XMPPDiscoInfoNS];
|
||||
} @catch (id e) {
|
||||
[self release];
|
||||
@throw e;
|
||||
|
@ -126,7 +121,7 @@
|
|||
XMPPIQ *resultIQ;
|
||||
OFXMLElement *response;
|
||||
OFXMLElement *query = [IQ elementForName: @"query"
|
||||
namespace: XMPP_NS_DISCO_ITEMS];
|
||||
namespace: XMPPDiscoItemsNS];
|
||||
OFString *node = [[query attributeForName: @"node"] stringValue];
|
||||
|
||||
if (!(node == _node) && ![node isEqual: _node])
|
||||
|
@ -134,13 +129,13 @@
|
|||
|
||||
resultIQ = [IQ resultIQ];
|
||||
response = [OFXMLElement elementWithName: @"query"
|
||||
namespace: XMPP_NS_DISCO_ITEMS];
|
||||
namespace: XMPPDiscoItemsNS];
|
||||
[resultIQ addChild: response];
|
||||
|
||||
for (XMPPDiscoNode *child in _childNodes) {
|
||||
OFXMLElement *item =
|
||||
[OFXMLElement elementWithName: @"item"
|
||||
namespace: XMPP_NS_DISCO_ITEMS];
|
||||
namespace: XMPPDiscoItemsNS];
|
||||
|
||||
[item addAttributeWithName: @"jid"
|
||||
stringValue: child.JID.fullJID];
|
||||
|
@ -159,21 +154,20 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
- (bool)xmpp_handleInfoIQ: (XMPPIQ *)IQ
|
||||
connection: (XMPPConnection *)connection
|
||||
- (bool)xmpp_handleInfoIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection
|
||||
{
|
||||
XMPPIQ *resultIQ;
|
||||
OFXMLElement *response;
|
||||
|
||||
resultIQ = [IQ resultIQ];
|
||||
response = [OFXMLElement elementWithName: @"query"
|
||||
namespace: XMPP_NS_DISCO_INFO];
|
||||
namespace: XMPPDiscoInfoNS];
|
||||
[resultIQ addChild: response];
|
||||
|
||||
for (XMPPDiscoIdentity *identity in _identities) {
|
||||
OFXMLElement *identityElement =
|
||||
[OFXMLElement elementWithName: @"identity"
|
||||
namespace: XMPP_NS_DISCO_INFO];
|
||||
namespace: XMPPDiscoInfoNS];
|
||||
|
||||
[identityElement addAttributeWithName: @"category"
|
||||
stringValue: identity.category];
|
||||
|
@ -189,7 +183,7 @@
|
|||
for (OFString *feature in _features) {
|
||||
OFXMLElement *featureElement =
|
||||
[OFXMLElement elementWithName: @"feature"
|
||||
namespace: XMPP_NS_DISCO_INFO];
|
||||
namespace: XMPPDiscoInfoNS];
|
||||
[featureElement addAttributeWithName: @"var"
|
||||
stringValue: feature];
|
||||
[response addChild: featureElement];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -28,8 +28,7 @@
|
|||
@implementation XMPPEXTERNALAuth: XMPPAuthenticator
|
||||
+ (instancetype)EXTERNALAuth
|
||||
{
|
||||
return [[[self alloc] initWithAuthcid: nil
|
||||
password: nil] autorelease];
|
||||
return [[[self alloc] initWithAuthcid: nil password: nil] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)EXTERNALAuthWithAuthzid: (OFString *)authzid
|
||||
|
|
|
@ -92,16 +92,14 @@
|
|||
|
||||
if (iter2 == nil) {
|
||||
iter2 = [OFMutableDictionary dictionary];
|
||||
[iter setObject: iter2
|
||||
forKey: component];
|
||||
[iter setObject: iter2 forKey: component];
|
||||
}
|
||||
|
||||
iter = iter2;
|
||||
}
|
||||
|
||||
if (object != nil)
|
||||
[iter setObject: object
|
||||
forKey: [pathComponents lastObject]];
|
||||
[iter setObject: object forKey: [pathComponents lastObject]];
|
||||
else
|
||||
[iter removeObjectForKey: pathComponents.lastObject];
|
||||
}
|
||||
|
@ -121,8 +119,7 @@
|
|||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
|
||||
[self xmpp_setObject: string
|
||||
forPath: path];
|
||||
[self xmpp_setObject: string forPath: path];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
}
|
||||
|
@ -139,13 +136,11 @@
|
|||
return string;
|
||||
}
|
||||
|
||||
- (void)setBooleanValue: (bool)boolean
|
||||
forPath: (OFString *)path
|
||||
- (void)setBooleanValue: (bool)boolean forPath: (OFString *)path
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
|
||||
[self xmpp_setObject: [OFNumber numberWithBool: boolean]
|
||||
forPath: path];
|
||||
[self xmpp_setObject: [OFNumber numberWithBool: boolean] forPath: path];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
}
|
||||
|
@ -162,8 +157,7 @@
|
|||
return boolean;
|
||||
}
|
||||
|
||||
- (void)setIntegerValue: (long long)integer
|
||||
forPath: (OFString *)path
|
||||
- (void)setIntegerValue: (long long)integer forPath: (OFString *)path
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
|
||||
|
@ -185,13 +179,11 @@
|
|||
return integer;
|
||||
}
|
||||
|
||||
- (void)setArray: (OFArray *)array
|
||||
forPath: (OFString *)path
|
||||
- (void)setArray: (OFArray *)array forPath: (OFString *)path
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
|
||||
[self xmpp_setObject: array
|
||||
forPath: path];
|
||||
[self xmpp_setObject: array forPath: path];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
}
|
||||
|
@ -208,13 +200,11 @@
|
|||
return array;
|
||||
}
|
||||
|
||||
- (void)setDictionary: (OFDictionary *)dictionary
|
||||
forPath: (OFString *)path
|
||||
- (void)setDictionary: (OFDictionary *)dictionary forPath: (OFString *)path
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
|
||||
[self xmpp_setObject: dictionary
|
||||
forPath: path];
|
||||
[self xmpp_setObject: dictionary forPath: path];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
}
|
||||
|
|
11
src/XMPPIQ.h
11
src/XMPPIQ.h
|
@ -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>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
|
@ -36,8 +36,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param ID The value for the stanza's id attribute
|
||||
* @return A new autoreleased XMPPIQ
|
||||
*/
|
||||
+ (instancetype)IQWithType: (OFString *)type
|
||||
ID: (OFString *)ID;
|
||||
+ (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID;
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* @return An initialized XMPPIQ
|
||||
*/
|
||||
- (instancetype)initWithType: (OFString *)type
|
||||
ID: (OFString *)ID;
|
||||
- (instancetype)initWithType: (OFString *)type ID: (OFString *)ID;
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* @return A new autoreleased XMPPIQ
|
||||
*/
|
||||
- (XMPPIQ *)errorIQWithType: (OFString *)type
|
||||
condition: (OFString *)condition;
|
||||
- (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition;
|
||||
@end
|
||||
|
||||
OF_ASSUME_NONNULL_END
|
||||
|
|
31
src/XMPPIQ.m
31
src/XMPPIQ.m
|
@ -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>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
|
@ -27,19 +27,14 @@
|
|||
#import "XMPPIQ.h"
|
||||
|
||||
@implementation XMPPIQ
|
||||
+ (instancetype)IQWithType: (OFString *)type
|
||||
ID: (OFString *)ID
|
||||
+ (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID
|
||||
{
|
||||
return [[[self alloc] initWithType: type
|
||||
ID: ID] autorelease];
|
||||
return [[[self alloc] initWithType: type ID: ID] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType: (OFString *)type
|
||||
ID: (OFString *)ID
|
||||
- (instancetype)initWithType: (OFString *)type ID: (OFString *)ID
|
||||
{
|
||||
self = [super initWithName: @"iq"
|
||||
type: type
|
||||
ID: ID];
|
||||
self = [super initWithName: @"iq" type: type ID: ID];
|
||||
|
||||
@try {
|
||||
if (![type isEqual: @"get"] && ![type isEqual: @"set"] &&
|
||||
|
@ -70,15 +65,14 @@
|
|||
ID: self.ID];
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
OFXMLElement *error = [OFXMLElement elementWithName: @"error"
|
||||
namespace: XMPP_NS_CLIENT];
|
||||
namespace: XMPPClientNS];
|
||||
|
||||
[error addAttributeWithName: @"type"
|
||||
stringValue: type];
|
||||
[error addAttributeWithName: @"type" stringValue: type];
|
||||
[error addChild: [OFXMLElement elementWithName: condition
|
||||
namespace: XMPP_NS_STANZAS]];
|
||||
namespace: XMPPStanzasNS]];
|
||||
if (text)
|
||||
[error addChild: [OFXMLElement elementWithName: @"text"
|
||||
namespace: XMPP_NS_STANZAS
|
||||
namespace: XMPPStanzasNS
|
||||
stringValue: text]];
|
||||
[ret addChild: error];
|
||||
ret.to = self.from;
|
||||
|
@ -89,11 +83,8 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
- (XMPPIQ *)errorIQWithType: (OFString *)type
|
||||
condition: (OFString *)condition
|
||||
- (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition
|
||||
{
|
||||
return [self errorIQWithType: type
|
||||
condition: condition
|
||||
text: nil];
|
||||
return [self errorIQWithType: type condition: condition text: nil];
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -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>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
|
@ -42,56 +42,48 @@
|
|||
return [[[self alloc] initWithType: type] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)messageWithType: (OFString *)type
|
||||
ID: (OFString *)ID
|
||||
+ (instancetype)messageWithType: (OFString *)type ID: (OFString *)ID
|
||||
{
|
||||
return [[[self alloc] initWithType: type
|
||||
ID: ID] autorelease];
|
||||
return [[[self alloc] initWithType: type ID: ID] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self initWithType: nil
|
||||
ID: nil];
|
||||
return [self initWithType: nil ID: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithID: (OFString *)ID
|
||||
{
|
||||
return [self initWithType: nil
|
||||
ID: ID];
|
||||
return [self initWithType: nil ID: ID];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType: (OFString *)type
|
||||
{
|
||||
return [self initWithType: type
|
||||
ID: nil];
|
||||
return [self initWithType: type ID: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType: (OFString *)type
|
||||
ID: (OFString *)ID
|
||||
- (instancetype)initWithType: (OFString *)type ID: (OFString *)ID
|
||||
{
|
||||
return [super initWithName: @"message"
|
||||
type: type
|
||||
ID: ID];
|
||||
return [super initWithName: @"message" type: type ID: ID];
|
||||
}
|
||||
|
||||
- (void)setBody: (OFString *)body
|
||||
{
|
||||
OFXMLElement *oldBody = [self elementForName: @"body"
|
||||
namespace: XMPP_NS_CLIENT];
|
||||
namespace: XMPPClientNS];
|
||||
|
||||
if (oldBody != nil)
|
||||
[self removeChild: oldBody];
|
||||
|
||||
if (body != nil)
|
||||
[self addChild: [OFXMLElement elementWithName: @"body"
|
||||
namespace: XMPP_NS_CLIENT
|
||||
namespace: XMPPClientNS
|
||||
stringValue: body]];
|
||||
}
|
||||
|
||||
- (OFString *)body
|
||||
{
|
||||
return [self elementForName: @"body"
|
||||
namespace: XMPP_NS_CLIENT].stringValue;
|
||||
namespace: XMPPClientNS].stringValue;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -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/
|
||||
*
|
||||
|
@ -54,8 +54,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param selector The selector to broadcast
|
||||
* @param object The object to broadcast
|
||||
*/
|
||||
- (bool)broadcastSelector: (SEL)selector
|
||||
withObject: (nullable id)object;
|
||||
- (bool)broadcastSelector: (SEL)selector withObject: (nullable id)object;
|
||||
|
||||
/*!
|
||||
* @brief Broadcasts a selector with two objects to all registered delegates.
|
||||
|
|
|
@ -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/
|
||||
*
|
||||
|
@ -69,8 +69,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (bool)broadcastSelector: (SEL)selector
|
||||
withObject: (id)object
|
||||
- (bool)broadcastSelector: (SEL)selector withObject: (id)object
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
OFMutableData *currentDelegates = [[_delegates copy] autorelease];
|
||||
|
|
|
@ -65,37 +65,29 @@ showToInt(OFString *show)
|
|||
return [[[self alloc] initWithType: type] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)presenceWithType: (OFString *)type
|
||||
ID: (OFString *)ID
|
||||
+ (instancetype)presenceWithType: (OFString *)type ID: (OFString *)ID
|
||||
{
|
||||
return [[[self alloc] initWithType: type
|
||||
ID: ID] autorelease];
|
||||
return [[[self alloc] initWithType: type ID: ID] autorelease];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self initWithType: nil
|
||||
ID: nil];
|
||||
return [self initWithType: nil ID: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithID: (OFString *)ID
|
||||
{
|
||||
return [self initWithType: nil
|
||||
ID: ID];
|
||||
return [self initWithType: nil ID: ID];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType: (OFString *)type
|
||||
{
|
||||
return [self initWithType: type
|
||||
ID: nil];
|
||||
return [self initWithType: type ID: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithType: (OFString *)type
|
||||
ID: (OFString *)ID
|
||||
- (instancetype)initWithType: (OFString *)type ID: (OFString *)ID
|
||||
{
|
||||
return [super initWithName: @"presence"
|
||||
type: type
|
||||
ID: ID];
|
||||
return [super initWithName: @"presence" type: type ID: ID];
|
||||
}
|
||||
|
||||
- (instancetype)initWithElement: (OFXMLElement *)element
|
||||
|
@ -106,15 +98,15 @@ showToInt(OFString *show)
|
|||
OFXMLElement *subElement;
|
||||
|
||||
if ((subElement = [element elementForName: @"show"
|
||||
namespace: XMPP_NS_CLIENT]))
|
||||
namespace: XMPPClientNS]))
|
||||
self.show = subElement.stringValue;
|
||||
|
||||
if ((subElement = [element elementForName: @"status"
|
||||
namespace: XMPP_NS_CLIENT]))
|
||||
namespace: XMPPClientNS]))
|
||||
self.status = subElement.stringValue;
|
||||
|
||||
if ((subElement = [element elementForName: @"priority"
|
||||
namespace: XMPP_NS_CLIENT]))
|
||||
namespace: XMPPClientNS]))
|
||||
self.priority = [OFNumber numberWithLongLong:
|
||||
[subElement longLongValueWithBase: 10]];
|
||||
} @catch (id e) {
|
||||
|
@ -137,7 +129,7 @@ showToInt(OFString *show)
|
|||
- (void)setShow: (OFString *)show
|
||||
{
|
||||
OFXMLElement *oldShow = [self elementForName: @"show"
|
||||
namespace: XMPP_NS_CLIENT];
|
||||
namespace: XMPPClientNS];
|
||||
OFString *old;
|
||||
|
||||
if (oldShow != nil)
|
||||
|
@ -145,7 +137,7 @@ showToInt(OFString *show)
|
|||
|
||||
if (show != nil)
|
||||
[self addChild: [OFXMLElement elementWithName: @"show"
|
||||
namespace: XMPP_NS_CLIENT
|
||||
namespace: XMPPClientNS
|
||||
stringValue: show]];
|
||||
|
||||
old = _show;
|
||||
|
@ -156,7 +148,7 @@ showToInt(OFString *show)
|
|||
- (void)setStatus: (OFString *)status
|
||||
{
|
||||
OFXMLElement *oldStatus = [self elementForName: @"status"
|
||||
namespace: XMPP_NS_CLIENT];
|
||||
namespace: XMPPClientNS];
|
||||
OFString *old;
|
||||
|
||||
if (oldStatus != nil)
|
||||
|
@ -164,7 +156,7 @@ showToInt(OFString *show)
|
|||
|
||||
if (status != nil)
|
||||
[self addChild: [OFXMLElement elementWithName: @"status"
|
||||
namespace: XMPP_NS_CLIENT
|
||||
namespace: XMPPClientNS
|
||||
stringValue: status]];
|
||||
|
||||
old = _status;
|
||||
|
@ -181,7 +173,7 @@ showToInt(OFString *show)
|
|||
@throw [OFInvalidArgumentException exception];
|
||||
|
||||
OFXMLElement *oldPriority = [self elementForName: @"priority"
|
||||
namespace: XMPP_NS_CLIENT];
|
||||
namespace: XMPPClientNS];
|
||||
|
||||
if (oldPriority != nil)
|
||||
[self removeChild: oldPriority];
|
||||
|
@ -189,7 +181,7 @@ showToInt(OFString *show)
|
|||
OFString *priority_s =
|
||||
[OFString stringWithFormat: @"%hhd", priority.charValue];
|
||||
[self addChild: [OFXMLElement elementWithName: @"priority"
|
||||
namespace: XMPP_NS_CLIENT
|
||||
namespace: XMPPClientNS
|
||||
stringValue: priority_s]];
|
||||
|
||||
old = _priority;
|
||||
|
|
|
@ -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>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
|
@ -91,11 +92,10 @@ OF_ASSUME_NONNULL_END
|
|||
|
||||
_rosterRequested = true;
|
||||
|
||||
IQ = [XMPPIQ IQWithType: @"get"
|
||||
ID: [_connection generateStanzaID]];
|
||||
IQ = [XMPPIQ IQWithType: @"get" ID: [_connection generateStanzaID]];
|
||||
|
||||
query = [OFXMLElement elementWithName: @"query"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
|
||||
if (_connection.supportsRosterVersioning) {
|
||||
OFString *ver =
|
||||
|
@ -104,8 +104,7 @@ OF_ASSUME_NONNULL_END
|
|||
if (ver == nil)
|
||||
ver = @"";
|
||||
|
||||
[query addAttributeWithName: @"ver"
|
||||
stringValue: ver];
|
||||
[query addAttributeWithName: @"ver" stringValue: ver];
|
||||
}
|
||||
|
||||
[IQ addChild: query];
|
||||
|
@ -116,16 +115,14 @@ OF_ASSUME_NONNULL_END
|
|||
IQ:)];
|
||||
}
|
||||
|
||||
- (bool)connection: (XMPPConnection *)connection
|
||||
didReceiveIQ: (XMPPIQ *)IQ
|
||||
- (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ
|
||||
{
|
||||
OFXMLElement *rosterElement;
|
||||
OFXMLElement *element;
|
||||
XMPPRosterItem *rosterItem;
|
||||
OFString *origin;
|
||||
|
||||
rosterElement = [IQ elementForName: @"query"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
rosterElement = [IQ elementForName: @"query" namespace: XMPPRosterNS];
|
||||
|
||||
if (rosterElement == nil)
|
||||
return false;
|
||||
|
@ -139,7 +136,7 @@ OF_ASSUME_NONNULL_END
|
|||
return false;
|
||||
|
||||
element = [rosterElement elementForName: @"item"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
|
||||
if (element != nil) {
|
||||
rosterItem = [self xmpp_rosterItemWithXMLElement: element];
|
||||
|
@ -155,8 +152,7 @@ OF_ASSUME_NONNULL_END
|
|||
if (_connection.supportsRosterVersioning) {
|
||||
OFString *ver =
|
||||
[rosterElement attributeForName: @"ver"].stringValue;
|
||||
[_dataStorage setStringValue: ver
|
||||
forPath: @"roster.ver"];
|
||||
[_dataStorage setStringValue: ver forPath: @"roster.ver"];
|
||||
[_dataStorage save];
|
||||
}
|
||||
|
||||
|
@ -175,19 +171,18 @@ OF_ASSUME_NONNULL_END
|
|||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
|
||||
ID: [_connection generateStanzaID]];
|
||||
OFXMLElement *query = [OFXMLElement elementWithName: @"query"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
OFXMLElement *item = [OFXMLElement elementWithName: @"item"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
|
||||
[item addAttributeWithName: @"jid"
|
||||
stringValue: rosterItem.JID.bareJID];
|
||||
[item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID];
|
||||
if (rosterItem.name != nil)
|
||||
[item addAttributeWithName: @"name"
|
||||
stringValue: rosterItem.name];
|
||||
|
||||
for (OFString *group in rosterItem.groups)
|
||||
[item addChild: [OFXMLElement elementWithName: @"group"
|
||||
namespace: XMPP_NS_ROSTER
|
||||
namespace: XMPPRosterNS
|
||||
stringValue: group]];
|
||||
|
||||
[query addChild: item];
|
||||
|
@ -201,14 +196,12 @@ OF_ASSUME_NONNULL_END
|
|||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
|
||||
ID: [_connection generateStanzaID]];
|
||||
OFXMLElement *query = [OFXMLElement elementWithName: @"query"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
OFXMLElement *item = [OFXMLElement elementWithName: @"item"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
|
||||
[item addAttributeWithName: @"jid"
|
||||
stringValue: rosterItem.JID.bareJID];
|
||||
[item addAttributeWithName: @"subscription"
|
||||
stringValue: @"remove"];
|
||||
[item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID];
|
||||
[item addAttributeWithName: @"subscription" stringValue: @"remove"];
|
||||
|
||||
[query addChild: item];
|
||||
[IQ addChild: query];
|
||||
|
@ -259,13 +252,11 @@ OF_ASSUME_NONNULL_END
|
|||
[item setObject: rosterItem.groups
|
||||
forKey: @"groups"];
|
||||
|
||||
[items setObject: item
|
||||
forKey: rosterItem.JID.bareJID];
|
||||
[items setObject: item forKey: rosterItem.JID.bareJID];
|
||||
} else
|
||||
[items removeObjectForKey: rosterItem.JID.bareJID];
|
||||
|
||||
[_dataStorage setDictionary: items
|
||||
forPath: @"roster.items"];
|
||||
[_dataStorage setDictionary: items forPath: @"roster.items"];
|
||||
}
|
||||
|
||||
if (![rosterItem.subscription isEqual: @"remove"])
|
||||
|
@ -296,8 +287,7 @@ OF_ASSUME_NONNULL_END
|
|||
rosterItem.subscription = subscription;
|
||||
|
||||
for (OFXMLElement *groupElement in
|
||||
[element elementsForName: @"group"
|
||||
namespace: XMPP_NS_ROSTER])
|
||||
[element elementsForName: @"group" namespace: XMPPRosterNS])
|
||||
[groups addObject: groupElement.stringValue];
|
||||
|
||||
if (groups.count > 0)
|
||||
|
@ -310,7 +300,7 @@ OF_ASSUME_NONNULL_END
|
|||
IQ: (XMPPIQ *)IQ
|
||||
{
|
||||
OFXMLElement *rosterElement = [IQ elementForName: @"query"
|
||||
namespace: XMPP_NS_ROSTER];
|
||||
namespace: XMPPRosterNS];
|
||||
|
||||
if (connection.supportsRosterVersioning) {
|
||||
if (rosterElement == nil) {
|
||||
|
@ -342,7 +332,7 @@ OF_ASSUME_NONNULL_END
|
|||
XMPPRosterItem *rosterItem;
|
||||
|
||||
if (![element.name isEqual: @"item"] ||
|
||||
![element.namespace isEqual: XMPP_NS_ROSTER])
|
||||
![element.namespace isEqual: XMPPRosterNS])
|
||||
continue;
|
||||
|
||||
rosterItem = [self xmpp_rosterItemWithXMLElement: element];
|
||||
|
@ -355,8 +345,7 @@ OF_ASSUME_NONNULL_END
|
|||
if (connection.supportsRosterVersioning && rosterElement != nil) {
|
||||
OFString *ver =
|
||||
[rosterElement attributeForName: @"ver"].stringValue;
|
||||
[_dataStorage setStringValue: ver
|
||||
forPath: @"roster.ver"];
|
||||
[_dataStorage setStringValue: ver forPath: @"roster.ver"];
|
||||
[_dataStorage save];
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,7 @@
|
|||
|
||||
@interface XMPPSCRAMAuth ()
|
||||
- (OFString *)xmpp_genNonce;
|
||||
- (const uint8_t *)xmpp_HMACWithKey: (OFData *)key
|
||||
data: (OFData *)data;
|
||||
- (const uint8_t *)xmpp_HMACWithKey: (OFData *)key data: (OFData *)data;
|
||||
- (OFData *)xmpp_hiWithData: (OFData *)str
|
||||
salt: (OFData *)salt
|
||||
iterationCount: (intmax_t)i;
|
||||
|
@ -137,10 +136,8 @@
|
|||
|
||||
if (authzid) {
|
||||
OFMutableString *new = [[authzid mutableCopy] autorelease];
|
||||
[new replaceOccurrencesOfString: @"="
|
||||
withString: @"=3D"];
|
||||
[new replaceOccurrencesOfString: @","
|
||||
withString: @"=2C"];
|
||||
[new replaceOccurrencesOfString: @"=" withString: @"=3D"];
|
||||
[new replaceOccurrencesOfString: @"," withString: @"=2C"];
|
||||
[new makeImmutable];
|
||||
_authzid = [new copy];
|
||||
} else
|
||||
|
@ -155,10 +152,8 @@
|
|||
|
||||
if (authcid) {
|
||||
OFMutableString *new = [[authcid mutableCopy] autorelease];
|
||||
[new replaceOccurrencesOfString: @"="
|
||||
withString: @"=3D"];
|
||||
[new replaceOccurrencesOfString: @","
|
||||
withString: @"=2C"];
|
||||
[new replaceOccurrencesOfString: @"=" withString: @"=3D"];
|
||||
[new replaceOccurrencesOfString: @"," withString: @"=2C"];
|
||||
[new makeImmutable];
|
||||
_authcid = [new copy];
|
||||
} else
|
||||
|
@ -281,17 +276,13 @@
|
|||
count: channelBinding.count];
|
||||
}
|
||||
tmpString = tmpArray.stringByBase64Encoding;
|
||||
[ret addItems: "c="
|
||||
count: 2];
|
||||
[ret addItems: tmpString.UTF8String
|
||||
count: tmpString.UTF8StringLength];
|
||||
[ret addItems: "c=" count: 2];
|
||||
[ret addItems: tmpString.UTF8String count: tmpString.UTF8StringLength];
|
||||
|
||||
// Add r=<nonce>
|
||||
[ret addItem: ","];
|
||||
[ret addItems: "r="
|
||||
count: 2];
|
||||
[ret addItems: sNonce.UTF8String
|
||||
count: sNonce.UTF8StringLength];
|
||||
[ret addItems: "r=" count: 2];
|
||||
[ret addItems: sNonce.UTF8String count: sNonce.UTF8StringLength];
|
||||
|
||||
/*
|
||||
* IETF RFC 5802:
|
||||
|
@ -312,19 +303,17 @@
|
|||
[authMessage addItems: _clientFirstMessageBare.UTF8String
|
||||
count: _clientFirstMessageBare.UTF8StringLength];
|
||||
[authMessage addItem: ","];
|
||||
[authMessage addItems: data.items
|
||||
count: data.count * data.itemSize];
|
||||
[authMessage addItems: data.items count: data.count * data.itemSize];
|
||||
[authMessage addItem: ","];
|
||||
[authMessage addItems: ret.items
|
||||
count: ret.count];
|
||||
[authMessage addItems: ret.items count: ret.count];
|
||||
|
||||
/*
|
||||
* IETF RFC 5802:
|
||||
* ClientKey := HMAC(SaltedPassword, "Client Key")
|
||||
*/
|
||||
clientKey = [self xmpp_HMACWithKey: saltedPassword
|
||||
data: [OFData dataWithItems: "Client Key"
|
||||
count: 10]];
|
||||
clientKey = [self
|
||||
xmpp_HMACWithKey: saltedPassword
|
||||
data: [OFData dataWithItems: "Client Key" count: 10]];
|
||||
|
||||
/*
|
||||
* IETF RFC 5802:
|
||||
|
@ -346,9 +335,9 @@
|
|||
* IETF RFC 5802:
|
||||
* ServerKey := HMAC(SaltedPassword, "Server Key")
|
||||
*/
|
||||
serverKey = [self xmpp_HMACWithKey: saltedPassword
|
||||
data: [OFData dataWithItems: "Server Key"
|
||||
count: 10]];
|
||||
serverKey = [self
|
||||
xmpp_HMACWithKey: saltedPassword
|
||||
data: [OFData dataWithItems: "Server Key" count: 10]];
|
||||
|
||||
/*
|
||||
* IETF RFC 5802:
|
||||
|
@ -359,8 +348,7 @@
|
|||
|
||||
[_serverSignature release];
|
||||
_serverSignature = [[OFData alloc]
|
||||
initWithItems: [self xmpp_HMACWithKey: tmpArray
|
||||
data: authMessage]
|
||||
initWithItems: [self xmpp_HMACWithKey: tmpArray data: authMessage]
|
||||
count: [_hashType digestSize]];
|
||||
|
||||
/*
|
||||
|
@ -375,11 +363,9 @@
|
|||
|
||||
// Add p=<base64(ClientProof)>
|
||||
[ret addItem: ","];
|
||||
[ret addItems: "p="
|
||||
count: 2];
|
||||
[ret addItems: "p=" count: 2];
|
||||
tmpString = tmpArray.stringByBase64Encoding;
|
||||
[ret addItems: tmpString.UTF8String
|
||||
count: tmpString.UTF8StringLength];
|
||||
[ret addItems: tmpString.UTF8String count: tmpString.UTF8StringLength];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -447,11 +433,9 @@
|
|||
hashI = [[[_hashType alloc] init] autorelease];
|
||||
[hashI updateWithBuffer: key.items
|
||||
length: key.itemSize * key.count];
|
||||
[k addItems: hashI.digest
|
||||
count: hashI.digestSize];
|
||||
[k addItems: hashI.digest count: hashI.digestSize];
|
||||
} else
|
||||
[k addItems: key.items
|
||||
count: key.itemSize * key.count];
|
||||
[k addItems: key.items count: key.itemSize * key.count];
|
||||
|
||||
@try {
|
||||
kI = OFAllocMemory(1, blockSize);
|
||||
|
@ -508,24 +492,21 @@
|
|||
[salty addItems: "\0\0\0\1"
|
||||
count: 4];
|
||||
|
||||
uOld = [self xmpp_HMACWithKey: str
|
||||
data: salty];
|
||||
uOld = [self xmpp_HMACWithKey: str data: salty];
|
||||
|
||||
for (j = 0; j < digestSize; j++)
|
||||
result[j] ^= uOld[j];
|
||||
|
||||
for (j = 0; j < i - 1; j++) {
|
||||
tmp = [[OFMutableData alloc] init];
|
||||
[tmp addItems: uOld
|
||||
count: digestSize];
|
||||
[tmp addItems: uOld count: digestSize];
|
||||
|
||||
/* releases uOld and previous tmp */
|
||||
objc_autoreleasePoolPop(pool);
|
||||
pool = objc_autoreleasePoolPush();
|
||||
[tmp autorelease];
|
||||
|
||||
u = [self xmpp_HMACWithKey: str
|
||||
data: tmp];
|
||||
u = [self xmpp_HMACWithKey: str data: tmp];
|
||||
|
||||
for (k = 0; k < digestSize; k++)
|
||||
result[k] ^= u[k];
|
||||
|
@ -533,8 +514,7 @@
|
|||
uOld = u;
|
||||
}
|
||||
|
||||
ret = [OFData dataWithItems: result
|
||||
count: digestSize];
|
||||
ret = [OFData dataWithItems: result count: digestSize];
|
||||
} @finally {
|
||||
OFFreeMemory(result);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
|
@ -87,8 +87,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
* @param ID The value for the stanza's id attribute
|
||||
* @return A new autoreleased XMPPStanza
|
||||
*/
|
||||
+ (instancetype)stanzaWithName: (OFString *)name
|
||||
ID: (nullable OFString *)ID;
|
||||
+ (instancetype)stanzaWithName: (OFString *)name ID: (nullable OFString *)ID;
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* @return A initialized XMPPStanza
|
||||
*/
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
type: (nullable OFString *)type;
|
||||
- (instancetype)initWithName: (OFString *)name type: (nullable OFString *)type;
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* @return A initialized XMPPStanza
|
||||
*/
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
ID: (nullable OFString *)ID;
|
||||
- (instancetype)initWithName: (OFString *)name ID: (nullable OFString *)ID;
|
||||
|
||||
/*!
|
||||
* @brief Initializes an already allocated XMPPStanza with the specified name,
|
||||
|
|
|
@ -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>
|
||||
*
|
||||
* https://heap.zone/objxmpp/
|
||||
|
@ -36,18 +36,14 @@
|
|||
return [[[self alloc] initWithName: name] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)stanzaWithName: (OFString *)name
|
||||
type: (OFString *)type
|
||||
+ (instancetype)stanzaWithName: (OFString *)name type: (OFString *)type
|
||||
{
|
||||
return [[[self alloc] initWithName: name
|
||||
type: type] autorelease];
|
||||
return [[[self alloc] initWithName: name type: type] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)stanzaWithName: (OFString *)name
|
||||
ID: (OFString *)ID
|
||||
+ (instancetype)stanzaWithName: (OFString *)name ID: (OFString *)ID
|
||||
{
|
||||
return [[[self alloc] initWithName: name
|
||||
ID: ID] autorelease];
|
||||
return [[[self alloc] initWithName: name ID: ID] autorelease];
|
||||
}
|
||||
|
||||
+ (instancetype)stanzaWithName: (OFString *)name
|
||||
|
@ -70,8 +66,7 @@
|
|||
OF_INVALID_INIT_METHOD
|
||||
}
|
||||
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
namespace: (OFString *)namespace
|
||||
- (instancetype)initWithName: (OFString *)name namespace: (OFString *)namespace
|
||||
{
|
||||
OF_INVALID_INIT_METHOD
|
||||
}
|
||||
|
@ -95,25 +90,18 @@
|
|||
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
{
|
||||
return [self initWithName: name
|
||||
type: nil
|
||||
ID: nil];
|
||||
return [self initWithName: name type: nil ID: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
type: (OFString *)type
|
||||
- (instancetype)initWithName: (OFString *)name type: (OFString *)type
|
||||
{
|
||||
return [self initWithName: name
|
||||
type: type
|
||||
ID: nil];
|
||||
return [self initWithName: name type: type ID: nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
ID: (OFString *)ID
|
||||
{
|
||||
return [self initWithName: name
|
||||
type: nil
|
||||
ID: ID];
|
||||
return [self initWithName: name type: nil ID: ID];
|
||||
}
|
||||
|
||||
- (instancetype)initWithName: (OFString *)name
|
||||
|
@ -121,7 +109,7 @@
|
|||
ID: (OFString *)ID
|
||||
{
|
||||
self = [super initWithName: name
|
||||
namespace: XMPP_NS_CLIENT
|
||||
namespace: XMPPClientNS
|
||||
stringValue: nil];
|
||||
|
||||
@try {
|
||||
|
@ -129,9 +117,8 @@
|
|||
![name isEqual: @"presence"])
|
||||
@throw [OFInvalidArgumentException exception];
|
||||
|
||||
self.defaultNamespace = XMPP_NS_CLIENT;
|
||||
[self setPrefix: @"stream"
|
||||
forNamespace: XMPP_NS_STREAM];
|
||||
self.defaultNamespace = XMPPClientNS;
|
||||
[self setPrefix: @"stream" forNamespace: XMPPStreamNS];
|
||||
|
||||
if (type != nil)
|
||||
self.type = type;
|
||||
|
@ -193,8 +180,7 @@
|
|||
[self removeAttributeForName: @"from"];
|
||||
|
||||
if (from != nil)
|
||||
[self addAttributeWithName: @"from"
|
||||
stringValue: from.fullJID];
|
||||
[self addAttributeWithName: @"from" stringValue: from.fullJID];
|
||||
}
|
||||
|
||||
- (void)setTo: (XMPPJID *)to
|
||||
|
@ -206,8 +192,7 @@
|
|||
[self removeAttributeForName: @"to"];
|
||||
|
||||
if (to != nil)
|
||||
[self addAttributeWithName: @"to"
|
||||
stringValue: to.fullJID];
|
||||
[self addAttributeWithName: @"to" stringValue: to.fullJID];
|
||||
}
|
||||
|
||||
- (void)setType: (OFString *)type
|
||||
|
@ -219,8 +204,7 @@
|
|||
[self removeAttributeForName: @"type"];
|
||||
|
||||
if (type != nil)
|
||||
[self addAttributeWithName: @"type"
|
||||
stringValue: type];
|
||||
[self addAttributeWithName: @"type" stringValue: type];
|
||||
}
|
||||
|
||||
- (void)setID: (OFString *)ID
|
||||
|
@ -232,8 +216,7 @@
|
|||
[self removeAttributeForName: @"id"];
|
||||
|
||||
if (ID != nil)
|
||||
[self addAttributeWithName: @"id"
|
||||
stringValue: ID];
|
||||
[self addAttributeWithName: @"id" stringValue: ID];
|
||||
}
|
||||
|
||||
- (void)setLanguage: (OFString *)language
|
||||
|
|
|
@ -30,17 +30,13 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@protocol XMPPStorage <OFObject>
|
||||
- (void)save;
|
||||
- (void)setStringValue: (nullable OFString *)string
|
||||
forPath: (OFString *)path;
|
||||
- (void)setStringValue: (nullable OFString *)string forPath: (OFString *)path;
|
||||
- (nullable OFString *)stringValueForPath: (OFString *)path;
|
||||
- (void)setBooleanValue: (bool)boolean
|
||||
forPath: (OFString *)path;
|
||||
- (void)setBooleanValue: (bool)boolean forPath: (OFString *)path;
|
||||
- (bool)booleanValueForPath: (OFString *)path;
|
||||
- (void)setIntegerValue: (long long)integer
|
||||
forPath: (OFString *)path;
|
||||
- (void)setIntegerValue: (long long)integer forPath: (OFString *)path;
|
||||
- (long long)integerValueForPath: (OFString *)path;
|
||||
- (void)setArray: (nullable OFArray *)array
|
||||
forPath: (OFString *)path;
|
||||
- (void)setArray: (nullable OFArray *)array forPath: (OFString *)path;
|
||||
- (nullable OFArray *)arrayForPath: (OFString *)path;
|
||||
- (void)setDictionary: (nullable OFDictionary *)dictionary
|
||||
forPath: (OFString *)path;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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/
|
||||
*
|
||||
|
@ -60,7 +60,7 @@
|
|||
OFString *elementName = element.name;
|
||||
OFString *elementNS = element.namespace;
|
||||
|
||||
if ([elementNS isEqual: XMPP_NS_SM]) {
|
||||
if ([elementNS isEqual: XMPPSMNS]) {
|
||||
if ([elementName isEqual: @"enabled"]) {
|
||||
_receivedCount = 0;
|
||||
return;
|
||||
|
@ -74,7 +74,7 @@
|
|||
if ([elementName isEqual: @"r"]) {
|
||||
OFXMLElement *ack =
|
||||
[OFXMLElement elementWithName: @"a"
|
||||
namespace: XMPP_NS_SM];
|
||||
namespace: XMPPSMNS];
|
||||
OFString *stringValue = [OFString
|
||||
stringWithFormat: @"%" PRIu32, _receivedCount];
|
||||
[ack addAttributeWithName: @"h"
|
||||
|
@ -83,7 +83,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if ([elementNS isEqual: XMPP_NS_CLIENT] &&
|
||||
if ([elementNS isEqual: XMPPClientNS] &&
|
||||
([elementName isEqual: @"iq"] ||
|
||||
[elementName isEqual: @"presence"] ||
|
||||
[elementName isEqual: @"message"]))
|
||||
|
@ -97,12 +97,11 @@
|
|||
}
|
||||
*/
|
||||
|
||||
- (void)connection: (XMPPConnection *)connection
|
||||
wasBoundToJID: (XMPPJID *)JID
|
||||
- (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID
|
||||
{
|
||||
if (connection.supportsStreamManagement)
|
||||
[connection sendStanza:
|
||||
[OFXMLElement elementWithName: @"enable"
|
||||
namespace: XMPP_NS_SM]];
|
||||
namespace: XMPPSMNS]];
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -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/
|
||||
*
|
||||
|
@ -33,8 +33,7 @@
|
|||
@throw [OFMalformedXMLException exception];
|
||||
}
|
||||
|
||||
- (void)parser: (OFXMLParser *)parser
|
||||
foundComment: (OFString *)comment
|
||||
- (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment
|
||||
{
|
||||
@throw [OFMalformedXMLException exception];
|
||||
}
|
||||
|
|
|
@ -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/
|
||||
*
|
||||
|
@ -20,18 +20,18 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define XMPP_NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
|
||||
#define XMPP_NS_CAPS @"http://jabber.org/protocol/caps"
|
||||
#define XMPP_NS_CLIENT @"jabber:client"
|
||||
#define XMPP_NS_DISCO_INFO @"http://jabber.org/protocol/disco#info"
|
||||
#define XMPP_NS_DISCO_ITEMS @"http://jabber.org/protocol/disco#items"
|
||||
#define XMPP_NS_MUC @"http://jabber.org/protocol/muc"
|
||||
#define XMPP_NS_ROSTER @"jabber:iq:roster"
|
||||
#define XMPP_NS_ROSTERVER @"urn:xmpp:features:rosterver"
|
||||
#define XMPP_NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl"
|
||||
#define XMPP_NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session"
|
||||
#define XMPP_NS_SM @"urn:xmpp:sm:3"
|
||||
#define XMPP_NS_STANZAS @"urn:ietf:params:xml:ns:xmpp-stanzas"
|
||||
#define XMPP_NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls"
|
||||
#define XMPP_NS_STREAM @"http://etherx.jabber.org/streams"
|
||||
#define XMPP_NS_XMPP_STREAM @"urn:ietf:params:xml:ns:xmpp-streams"
|
||||
#define XMPPBindNS @"urn:ietf:params:xml:ns:xmpp-bind"
|
||||
#define XMPPCapsNS @"http://jabber.org/protocol/caps"
|
||||
#define XMPPClientNS @"jabber:client"
|
||||
#define XMPPDiscoInfoNS @"http://jabber.org/protocol/disco#info"
|
||||
#define XMPPDiscoItemsNS @"http://jabber.org/protocol/disco#items"
|
||||
#define XMPPMUCNS @"http://jabber.org/protocol/muc"
|
||||
#define XMPPRosterNS @"jabber:iq:roster"
|
||||
#define XMPPRosterVerNS @"urn:xmpp:features:rosterver"
|
||||
#define XMPPSASLNS @"urn:ietf:params:xml:ns:xmpp-sasl"
|
||||
#define XMPPSessionNS @"urn:ietf:params:xml:ns:xmpp-session"
|
||||
#define XMPPSMNS @"urn:xmpp:sm:3"
|
||||
#define XMPPStanzasNS @"urn:ietf:params:xml:ns:xmpp-stanzas"
|
||||
#define XMPPStartTLSNS @"urn:ietf:params:xml:ns:xmpp-tls"
|
||||
#define XMPPStreamNS @"http://etherx.jabber.org/streams"
|
||||
#define XMPPXMPPStreamNS @"urn:ietf:params:xml:ns:xmpp-streams"
|
||||
|
|
36
tests/test.m
36
tests/test.m
|
@ -81,8 +81,7 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
|||
@"from='alice@example.com'><body>Hello everyone</body>"
|
||||
@"</message>"]);
|
||||
|
||||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
|
||||
ID: @"128"];
|
||||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: @"128"];
|
||||
IQ.to = [XMPPJID JIDWithString: @"juliet@capulet.lit"];
|
||||
IQ.from = [XMPPJID JIDWithString: @"romeo@montague.lit"];
|
||||
assert([IQ.XMLString isEqual: @"<iq type='set' id='128' "
|
||||
|
@ -90,14 +89,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
|||
@"from='romeo@montague.lit'/>"]);
|
||||
|
||||
OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"];
|
||||
[elem addAttributeWithName: @"from"
|
||||
stringValue: @"bob@localhost"];
|
||||
[elem addAttributeWithName: @"to"
|
||||
stringValue: @"alice@localhost"];
|
||||
[elem addAttributeWithName: @"type"
|
||||
stringValue: @"get"];
|
||||
[elem addAttributeWithName: @"id"
|
||||
stringValue: @"42"];
|
||||
[elem addAttributeWithName: @"from" stringValue: @"bob@localhost"];
|
||||
[elem addAttributeWithName: @"to" stringValue: @"alice@localhost"];
|
||||
[elem addAttributeWithName: @"type" stringValue: @"get"];
|
||||
[elem addAttributeWithName: @"id" stringValue: @"42"];
|
||||
XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
|
||||
assert([elem.XMLString isEqual: [stanza XMLString]]);
|
||||
assert(([[OFString stringWithFormat: @"%@, %@, %@, %@",
|
||||
|
@ -147,8 +142,7 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
|||
OFLog(@"Auth successful");
|
||||
}
|
||||
|
||||
- (void)connection: (XMPPConnection *)conn_
|
||||
wasBoundToJID: (XMPPJID *)JID
|
||||
- (void)connection: (XMPPConnection *)conn_ wasBoundToJID: (XMPPJID *)JID
|
||||
{
|
||||
OFLog(@"Bound to JID: %@", JID.fullJID);
|
||||
OFLog(@"Supports SM: %@",
|
||||
|
@ -212,12 +206,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
|||
[conn sendStanza: pres];
|
||||
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"get"
|
||||
ID: [conn generateStanzaID]];
|
||||
XMPPIQ *IQ = [XMPPIQ IQWithType: @"get" ID: [conn generateStanzaID]];
|
||||
[IQ addChild: [OFXMLElement elementWithName: @"ping"
|
||||
namespace: @"urn:xmpp:ping"]];
|
||||
[conn sendIQ: IQ
|
||||
callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) {
|
||||
[conn sendIQ: IQ callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) {
|
||||
OFLog(@"Ping response: %@", resp);
|
||||
}];
|
||||
#endif
|
||||
|
@ -243,16 +235,14 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
|||
OFLog(@"Got roster push: %@", rosterItem);
|
||||
}
|
||||
|
||||
- (bool)connection: (XMPPConnection *)conn
|
||||
didReceiveIQ: (XMPPIQ *)iq
|
||||
- (bool)connection: (XMPPConnection *)conn didReceiveIQ: (XMPPIQ *)iq
|
||||
{
|
||||
OFLog(@"IQ: %@", iq);
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)connection: (XMPPConnection *)conn
|
||||
didReceiveMessage: (XMPPMessage *)msg
|
||||
- (void)connection: (XMPPConnection *)conn didReceiveMessage: (XMPPMessage *)msg
|
||||
{
|
||||
OFLog(@"Message: %@", msg);
|
||||
}
|
||||
|
@ -263,14 +253,12 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
|||
OFLog(@"Presence: %@", pres);
|
||||
}
|
||||
|
||||
- (void)connection: (XMPPConnection *)conn
|
||||
didThrowException: (id)e
|
||||
- (void)connection: (XMPPConnection *)conn didThrowException: (id)e
|
||||
{
|
||||
@throw e;
|
||||
}
|
||||
|
||||
- (void)connectionWasClosed: (XMPPConnection *)conn
|
||||
error: (OFXMLElement *)error
|
||||
- (void)connectionWasClosed: (XMPPConnection *)conn error: (OFXMLElement *)error
|
||||
{
|
||||
OFLog(@"Connection was closed: %@", error);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue