Comment: | Adjust to ObjFW style |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
9919057cb8bb237afb11f251210a1764 |
User & Date: | js on 2021-04-29 00:06:23 |
Other Links: | manifest | tags |
2021-04-29
| ||
00:14 | Avoid string duplication check-in: b31637cfd1 user: js tags: trunk | |
00:06 | Adjust to ObjFW style check-in: 9919057cb8 user: js tags: trunk | |
2021-04-28
| ||
23:20 | Adjust to ObjFW changes check-in: 46f67c971b user: js tags: trunk | |
Modified src/XMPPAuthenticator.m from [ac8c536c98] to [e84a1b1fd8].
1 2 | /* * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2016, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | @implementation XMPPAuthenticator @synthesize authzid = _authzid, authcid = _authcid, password = _password; - (instancetype)initWithAuthcid: (OFString *)authcid password: (OFString *)password { | | < < | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | @implementation XMPPAuthenticator @synthesize authzid = _authzid, authcid = _authcid, password = _password; - (instancetype)initWithAuthcid: (OFString *)authcid password: (OFString *)password { return [self initWithAuthzid: nil authcid: authcid password: password]; } - (instancetype)initWithAuthzid: (OFString *)authzid authcid: (OFString *)authcid password: (OFString *)password { self = [super init]; |
︙ | ︙ |
Modified src/XMPPCallback.h from [3047c2358f] to [42591349b1].
1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * | > | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | OF_ASSUME_NONNULL_BEGIN @class XMPPConnection; @class XMPPIQ; #ifdef OF_HAVE_BLOCKS | | < | | | | < | < | < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | OF_ASSUME_NONNULL_BEGIN @class XMPPConnection; @class XMPPIQ; #ifdef OF_HAVE_BLOCKS typedef void (^XMPPCallbackBlock)(XMPPConnection *_Nonnull, XMPPIQ *_Nonnull); #endif @interface XMPPCallback: OFObject { id _target; SEL _selector; #ifdef OF_HAVE_BLOCKS XMPPCallbackBlock _block; #endif } #ifdef OF_HAVE_BLOCKS + (instancetype)callbackWithBlock: (XMPPCallbackBlock)callback; - (instancetype)initWithBlock: (XMPPCallbackBlock)callback; #endif + (instancetype)callbackWithTarget: (id)target selector: (SEL)selector; - (instancetype)initWithTarget: (id)target selector: (SEL)selector; - (void)runWithIQ: (XMPPIQ *)iq connection: (XMPPConnection *)connection; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPCallback.m from [aac405c1ea] to [1ccfe848fa].
1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * | > | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #include "config.h" #import "XMPPCallback.h" @implementation XMPPCallback #ifdef OF_HAVE_BLOCKS | | | | < | < | < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #include "config.h" #import "XMPPCallback.h" @implementation XMPPCallback #ifdef OF_HAVE_BLOCKS + (instancetype)callbackWithBlock: (XMPPCallbackBlock)block { return [[(XMPPCallback *)[self alloc] initWithBlock: block] autorelease]; } - (instancetype)initWithBlock: (XMPPCallbackBlock)block { self = [super init]; @try { _block = [block copy]; } @catch (id e) { [self release]; @throw e; } return self; } #endif + (instancetype)callbackWithTarget: (id)target selector: (SEL)selector { return [[[self alloc] initWithTarget: target selector: selector] autorelease]; } - (instancetype)initWithTarget: (id)target selector: (SEL)selector { self = [super init]; _target = [target retain]; _selector = selector; return self; } - (void)dealloc { [_target release]; #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (void)runWithIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(connection, IQ); else #endif [_target performSelector: _selector withObject: connection withObject: IQ]; } @end |
Modified src/XMPPConnection.h from [3eae11716b] to [63a2bd57ee].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2010, 2011, 2012, 2013, 2016, 2017, 2018, 2021 * Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above |
︙ | ︙ | |||
25 26 27 28 29 30 31 | #import <ObjFW/ObjFW.h> #import "XMPPCallback.h" #import "XMPPStorage.h" OF_ASSUME_NONNULL_BEGIN | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #import <ObjFW/ObjFW.h> #import "XMPPCallback.h" #import "XMPPStorage.h" OF_ASSUME_NONNULL_BEGIN #define XMPPConnectionBufferLength 512 @class XMPPConnection; @class XMPPJID; @class XMPPIQ; @class XMPPMessage; @class XMPPPresence; @class XMPPAuthenticator; |
︙ | ︙ | |||
73 74 75 76 77 78 79 | /*! * @brief This callback is called when the connection was bound to a JID. * * @param connection The connection that was bound to a JID * @param JID The JID the conecction was bound to */ | | < | | < | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /*! * @brief This callback is called when the connection was bound to a JID. * * @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; /*! * @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 */ - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ; /*! * @brief This callback is called when the connection received a presence * stanza. * * @param connection The connection that received the stanza * @param presence The presence stanza that was received |
︙ | ︙ | |||
144 145 146 147 148 149 150 | /*! * @brief A class which abstracts a connection to an XMPP service. */ @interface XMPPConnection: OFObject { OFTCPSocket *_socket; | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /*! * @brief A class which abstracts a connection to an XMPP service. */ @interface XMPPConnection: OFObject { OFTCPSocket *_socket; char _buffer[XMPPConnectionBufferLength]; OFXMLParser *_parser, *_oldParser; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; OFString *_Nullable _username, *_Nullable _password, *_Nullable _server; OFString *_Nullable _resource; bool _usesAnonymousAuthentication; OFString *_Nullable _privateKeyFile, *_Nullable _certificateFile; const char *_Nullable _privateKeyPassphrase; |
︙ | ︙ | |||
305 306 307 308 309 310 311 | * * This is useful for handling multiple connections at once. * * @param buffer The buffer to parse * @param length The length of the buffer. If length is 0, it is assumed that * the connection was closed. */ | | < | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | * * This is useful for handling multiple connections at once. * * @param buffer The buffer to parse * @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; /*! * @brief Sends an OFXMLElement, usually an XMPPStanza. * * @param element The element to send */ - (void)sendStanza: (OFXMLElement *)element; |
︙ | ︙ | |||
334 335 336 337 338 339 340 | #ifdef OF_HAVE_BLOCKS /*! * @brief Sends an XMPPIQ, registering a callback block. * * @param IQ The IQ to send * @param block The callback block */ | | < | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | #ifdef OF_HAVE_BLOCKS /*! * @brief Sends an XMPPIQ, registering a callback block. * * @param IQ The IQ to send * @param block The callback block */ - (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (XMPPCallbackBlock)block; #endif /*! * @brief Generates a new, unique stanza ID. * * @return A new, generated, unique stanza ID. */ - (OFString *)generateStanzaID; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPConnection.m from [dc8d242d03] to [2a81d5959c].
︙ | ︙ | |||
55 56 57 58 59 60 61 | #import "namespaces.h" #import <ObjFW/macros.h> @interface XMPPConnection () <OFDNSResolverQueryDelegate, OFTCPSocketDelegate, OFXMLParserDelegate, OFXMLElementBuilderDelegate> - (void)xmpp_tryNextSRVRecord; | | < | < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #import "namespaces.h" #import <ObjFW/macros.h> @interface XMPPConnection () <OFDNSResolverQueryDelegate, OFTCPSocketDelegate, OFXMLParserDelegate, OFXMLElementBuilderDelegate> - (void)xmpp_tryNextSRVRecord; - (bool)xmpp_parseBuffer: (const void *)buffer length: (size_t)length; - (void)xmpp_startStream; - (void)xmpp_handleStanza: (OFXMLElement *)element; - (void)xmpp_handleStream: (OFXMLElement *)element; - (void)xmpp_handleTLS: (OFXMLElement *)element; - (void)xmpp_handleSASL: (OFXMLElement *)element; - (void)xmpp_handleIQ: (XMPPIQ *)IQ; - (void)xmpp_handleMessage: (XMPPMessage *)message; - (void)xmpp_handlePresence: (XMPPPresence *)presence; - (void)xmpp_handleFeatures: (OFXMLElement *)element; - (void)xmpp_sendAuth: (OFString *)authName; - (void)xmpp_sendResourceBind; - (void)xmpp_sendStreamError: (OFString *)condition text: (OFString *)text; - (void)xmpp_handleResourceBindForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ; - (void)xmpp_sendSession; - (void)xmpp_handleSessionForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ; - (OFString *)xmpp_IDNAToASCII: (OFString *)domain; - (XMPPMulticastDelegate *)xmpp_delegates; |
︙ | ︙ | |||
274 275 276 277 278 279 280 | withObject: exception]; return; } [self xmpp_startStream]; [_socket asyncReadIntoBuffer: _buffer | | | < | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | withObject: exception]; return; } [self xmpp_startStream]; [_socket asyncReadIntoBuffer: _buffer length: XMPPConnectionBufferLength]; } - (void)xmpp_tryNextSRVRecord { OFSRVDNSResourceRecord *record = [[[_nextSRVRecords objectAtIndex: 0] copy] autorelease]; if (_nextSRVRecords.count == 0) { [_nextSRVRecords release]; _nextSRVRecords = nil; } [_socket asyncConnectToHost: record.target port: record.port]; } - (void)resolver: (OFDNSResolver *)resolver didPerformQuery: (OFString *)domainName response: (OFDNSResponse *)response exception: (id)exception { |
︙ | ︙ | |||
311 312 313 314 315 316 317 | [records addObject: record]; /* TODO: Sort records */ [records makeImmutable]; if (records.count == 0) { /* Fall back to A / AAAA record. */ | | < | < | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | [records addObject: record]; /* TODO: Sort records */ [records makeImmutable]; if (records.count == 0) { /* Fall back to A / AAAA record. */ [_socket asyncConnectToHost: _domainToASCII port: _port]; return; } [_nextSRVRecords release]; _nextSRVRecords = nil; _nextSRVRecords = [records mutableCopy]; [self xmpp_tryNextSRVRecord]; } - (void)asyncConnect { void *pool = objc_autoreleasePoolPush(); if (_socket != nil) @throw [OFAlreadyConnectedException exception]; _socket = [[OFTCPSocket alloc] init]; [_socket setDelegate: self]; if (_server != nil) [_socket asyncConnectToHost: _server port: _port]; else { OFString *SRVDomain = [_domainToASCII stringByPrependingString: @"_xmpp-client._tcp."]; OFDNSQuery *query = [OFDNSQuery queryWithDomainName: SRVDomain DNSClass: OFDNSClassIN recordType: OFDNSRecordTypeSRV]; |
︙ | ︙ | |||
361 362 363 364 365 366 367 | error:) withObject: self withObject: nil]; return false; } @try { | | < | < | < | < | 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | error:) withObject: self withObject: nil]; return false; } @try { [_parser parseBuffer: buffer length: length]; } @catch (OFMalformedXMLException *e) { [self xmpp_sendStreamError: @"bad-format" text: nil]; [self close]; return false; } return true; } - (void)parseBuffer: (const void *)buffer length: (size_t)length { [self xmpp_parseBuffer: buffer length: length]; [_oldParser release]; [_oldElementBuilder release]; _oldParser = nil; _oldElementBuilder = nil; } |
︙ | ︙ | |||
401 402 403 404 405 406 407 | withObject: self withObject: exception]; [self close]; return false; } @try { | | < | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | withObject: self withObject: exception]; [self close]; return false; } @try { if (![self xmpp_parseBuffer: buffer length: length]) return false; } @catch (id e) { [_delegates broadcastSelector: @selector(connection: didThrowException:) withObject: self withObject: e]; [self close]; return false; } if (_oldParser != nil || _oldElementBuilder != nil) { [_oldParser release]; [_oldElementBuilder release]; _oldParser = nil; _oldElementBuilder = nil; [_socket asyncReadIntoBuffer: _buffer length: XMPPConnectionBufferLength]; return false; } return true; } - (bool)streamOpen |
︙ | ︙ | |||
498 499 500 501 502 503 504 | if ((key = IQ.to.fullJID) == nil) key = _JID.bareJID; if (key == nil) // Only happens for resource bind key = @"bind"; key = [key stringByAppendingString: ID]; | | < | < | < | < | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | if ((key = IQ.to.fullJID) == nil) key = _JID.bareJID; if (key == nil) // Only happens for resource bind key = @"bind"; key = [key stringByAppendingString: ID]; callback = [XMPPCallback callbackWithTarget: target selector: selector]; [_callbacks setObject: callback forKey: key]; objc_autoreleasePoolPop(pool); [self sendStanza: IQ]; } #ifdef OF_HAVE_BLOCKS - (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (XMPPCallbackBlock)block { void *pool = objc_autoreleasePoolPush(); XMPPCallback *callback; OFString *ID, *key; if ((ID = IQ.ID) == nil) { ID = [self generateStanzaID]; IQ.ID = ID; } if ((key = IQ.to.fullJID) == nil) key = _JID.bareJID; if (key == nil) // Connection not yet bound, can't send stanzas @throw [OFInvalidArgumentException exception]; key = [key stringByAppendingString: ID]; callback = [XMPPCallback callbackWithBlock: block]; [_callbacks setObject: callback forKey: key]; objc_autoreleasePoolPop(pool); [self sendStanza: IQ]; } #endif |
︙ | ︙ | |||
556 557 558 559 560 561 562 | // No dedicated stream error for this, may not even be XMPP [self close]; [_socket close]; return; } if (![prefix isEqual: @"stream"]) { | | < | | < | < | | < | | | | | | 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 | // No dedicated stream error for this, may not even be XMPP [self close]; [_socket close]; return; } if (![prefix isEqual: @"stream"]) { [self xmpp_sendStreamError: @"bad-namespace-prefix" text: nil]; return; } 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]; return; } if ([attribute.name isEqual: @"version"] && ![attribute.stringValue isEqual: @"1.0"]) { [self xmpp_sendStreamError: @"unsupported-version" text: nil]; return; } } parser.delegate = _elementBuilder; } - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildElement: (OFXMLElement *)element { /* Ignore whitespace elements */ if (element.name == nil) return; element.defaultNamespace = XMPPClientNS; [element setPrefix: @"stream" forNamespace: XMPPStreamNS]; [_delegates broadcastSelector: @selector(connection:didReceiveElement:) withObject: self withObject: element]; if ([element.namespace isEqual: XMPPClientNS]) [self xmpp_handleStanza: element]; if ([element.namespace isEqual: XMPPStreamNS]) [self xmpp_handleStream: element]; if ([element.namespace isEqual: XMPPStartTLSNS]) [self xmpp_handleTLS: element]; if ([element.namespace isEqual: XMPPSASLNS]) [self xmpp_handleSASL: element]; } - (void)elementBuilder: (OFXMLElementBuilder *)builder didNotExpectCloseTag: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)ns { if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || ![ns isEqual: XMPPStreamNS]) @throw [OFMalformedXMLException exception]; else [self close]; } - (void)xmpp_startStream { |
︙ | ︙ | |||
652 653 654 655 656 657 658 | if (_language != nil) langString = [OFString stringWithFormat: @"xml:lang='%@' ", _language]; [_socket writeFormat: @"<?xml version='1.0'?>\n" @"<stream:stream to='%@' " | | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 | if (_language != nil) langString = [OFString stringWithFormat: @"xml:lang='%@' ", _language]; [_socket writeFormat: @"<?xml version='1.0'?>\n" @"<stream:stream to='%@' " @"xmlns='" XMPPClientNS @"' " @"xmlns:stream='" XMPPStreamNS @"' %@" @"version='1.0'>", _domain, langString]; _streamOpen = true; } - (void)close { |
︙ | ︙ | |||
698 699 700 701 702 703 704 | if ([element.name isEqual: @"presence"]) { [self xmpp_handlePresence: [XMPPPresence stanzaWithElement: element]]; return; } | | < | | | < | | 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 | if ([element.name isEqual: @"presence"]) { [self xmpp_handlePresence: [XMPPPresence stanzaWithElement: element]]; return; } [self xmpp_sendStreamError: @"unsupported-stanza-type" text: nil]; } - (void)xmpp_handleStream: (OFXMLElement *)element { if ([element.name isEqual: @"features"]) { [self xmpp_handleFeatures: element]; return; } if ([element.name isEqual: @"error"]) { OFString *condition, *reason; [self close]; [_delegates broadcastSelector: @selector(connectionWasClosed:) withObject: self withObject: element]; condition = [[element elementsForNamespace: XMPPXMPPStreamNS] .firstObject name]; if (condition == nil) condition = @"undefined"; reason = [element elementForName: @"text" namespace: XMPPXMPPStreamNS].stringValue; @throw [XMPPStreamErrorException exceptionWithConnection: self condition: condition reason: reason]; return; } |
︙ | ︙ | |||
789 790 791 792 793 794 795 | if ([element.name isEqual: @"challenge"]) { OFXMLElement *responseTag; OFData *challenge = [OFData dataWithBase64EncodedString: element.stringValue]; OFData *response = [_authModule continueWithData: challenge]; responseTag = [OFXMLElement elementWithName: @"response" | | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | if ([element.name isEqual: @"challenge"]) { OFXMLElement *responseTag; OFData *challenge = [OFData dataWithBase64EncodedString: element.stringValue]; OFData *response = [_authModule continueWithData: challenge]; responseTag = [OFXMLElement elementWithName: @"response" namespace: XMPPSASLNS]; if (response) { if (response.count == 0) responseTag.stringValue = @"="; else responseTag.stringValue = response.stringByBase64Encoding; } |
︙ | ︙ | |||
839 840 841 842 843 844 845 | if ((key = IQ.from.fullJID) == nil) key = _JID.bareJID; if (key == nil) // Only happens for resource bind key = @"bind"; key = [key stringByAppendingString: IQ.ID]; if ((callback = [_callbacks objectForKey: key])) { | | < | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | if ((key = IQ.from.fullJID) == nil) key = _JID.bareJID; if (key == nil) // Only happens for resource bind key = @"bind"; key = [key stringByAppendingString: IQ.ID]; if ((callback = [_callbacks objectForKey: key])) { [callback runWithIQ: IQ connection: self]; [_callbacks removeObjectForKey: key]; return; } handled = [_delegates broadcastSelector: @selector( connection:didReceiveIQ:) withObject: self |
︙ | ︙ | |||
874 875 876 877 878 879 880 | withObject: self withObject: presence]; } - (void)xmpp_handleFeatures: (OFXMLElement *)element { OFXMLElement *startTLS = [element elementForName: @"starttls" | | | | | | | < | < | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 | withObject: self withObject: presence]; } - (void)xmpp_handleFeatures: (OFXMLElement *)element { OFXMLElement *startTLS = [element elementForName: @"starttls" namespace: XMPPStartTLSNS]; OFXMLElement *bind = [element elementForName: @"bind" namespace: XMPPBindNS]; OFXMLElement *session = [element elementForName: @"session" namespace: XMPPSessionNS]; OFXMLElement *mechs = [element elementForName: @"mechanisms" namespace: XMPPSASLNS]; OFMutableSet *mechanisms = [OFMutableSet set]; if (!_encrypted && startTLS != nil) { [self sendStanza: [OFXMLElement elementWithName: @"starttls" namespace: XMPPStartTLSNS]]; return; } if (_encryptionRequired && !_encrypted) /* TODO: Find/create an exception to throw here */ @throw [OFException exception]; if ([element elementForName: @"ver" namespace: XMPPRosterVerNS] != nil) _supportsRosterVersioning = true; if ([element elementForName: @"sm" namespace: XMPPSMNS] != nil) _supportsStreamManagement = true; if (mechs != nil) { for (OFXMLElement *mech in mechs.children) [mechanisms addObject: mech.stringValue]; if (_usesAnonymousAuthentication) { |
︙ | ︙ | |||
962 963 964 965 966 967 968 | @throw [XMPPAuthFailedException exceptionWithConnection: self reason: @"No supported auth mechanism"]; } if (session != nil && [session elementForName: @"optional" | | | < | < | < | < | | | < | | | < | < | < | | 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 | @throw [XMPPAuthFailedException exceptionWithConnection: self reason: @"No supported auth mechanism"]; } if (session != nil && [session elementForName: @"optional" namespace: XMPPSessionNS] == nil) _needsSession = true; if (bind != nil) { [self xmpp_sendResourceBind]; return; } assert(0); } - (void)xmpp_sendAuth: (OFString *)authName { OFXMLElement *authTag; OFData *initialMessage = [_authModule initialMessage]; authTag = [OFXMLElement elementWithName: @"auth" namespace: XMPPSASLNS]; [authTag addAttributeWithName: @"mechanism" stringValue: authName]; if (initialMessage != nil) { if (initialMessage.count == 0) authTag.stringValue = @"="; else authTag.stringValue = initialMessage.stringByBase64Encoding; } [self sendStanza: authTag]; } - (void)xmpp_sendResourceBind { XMPPIQ *IQ; OFXMLElement *bind; IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]]; bind = [OFXMLElement elementWithName: @"bind" namespace: XMPPBindNS]; if (_resource != nil) [bind addChild: [OFXMLElement elementWithName: @"resource" namespace: XMPPBindNS stringValue: _resource]]; [IQ addChild: bind]; [self sendIQ: IQ callbackTarget: self selector: @selector(xmpp_handleResourceBindForConnection: IQ:)]; } - (void)xmpp_sendStreamError: (OFString *)condition text: (OFString *)text { OFXMLElement *error = [OFXMLElement elementWithName: @"error" namespace: XMPPStreamNS]; [error setPrefix: @"stream" forNamespace: XMPPStreamNS]; [error addChild: [OFXMLElement elementWithName: condition namespace: XMPPXMPPStreamNS]]; if (text) [error addChild: [OFXMLElement elementWithName: @"text" namespace: XMPPXMPPStreamNS stringValue: text]]; _parser.delegate = nil; [self sendStanza: error]; [self close]; } - (void)xmpp_handleResourceBindForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ { OFXMLElement *bindElement, *JIDElement; assert([IQ.type isEqual: @"result"]); bindElement = [IQ elementForName: @"bind" namespace: XMPPBindNS]; assert(bindElement != nil); JIDElement = [bindElement elementForName: @"jid" namespace: XMPPBindNS]; _JID = [[XMPPJID alloc] initWithString: JIDElement.stringValue]; if (_needsSession) { [self xmpp_sendSession]; return; } [_delegates broadcastSelector: @selector(connection:wasBoundToJID:) withObject: self withObject: _JID]; } - (void)xmpp_sendSession { XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]]; [IQ addChild: [OFXMLElement elementWithName: @"session" namespace: XMPPSessionNS]]; [self sendIQ: IQ callbackTarget: self selector: @selector(xmpp_handleSessionForConnection:IQ:)]; } - (void)xmpp_handleSessionForConnection: (XMPPConnection *)connection |
︙ | ︙ |
Modified src/XMPPContact.m from [7b7906a48d] to [e56e86f81a].
1 2 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, 2016, 2019, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
71 72 73 74 75 76 77 | [old release]; } - (void)xmpp_setPresence: (XMPPPresence *)presence resource: (OFString *)resource { if (resource != nil) | | < | < | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | [old release]; } - (void)xmpp_setPresence: (XMPPPresence *)presence resource: (OFString *)resource { if (resource != nil) [_presences setObject: presence forKey: resource]; else [_presences setObject: presence forKey: @""]; self.xmpp_lockedOnJID = nil; } - (void)xmpp_removePresenceForResource: (OFString *)resource { if (resource != nil) { |
︙ | ︙ |
Modified src/XMPPContactManager.h from [274d8d6d35] to [e8e5dfa5b9].
1 2 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, 2016, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
88 89 90 91 92 93 94 | /*! * @brief This callback is called whenever a contact send a message stanza * * @param contact The contact that send the message * @param message The message which was send by the contact */ | | < | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /*! * @brief This callback is called whenever a contact send a message stanza * * @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; @end /*! * @brief A class tracking a XMPPContact instance for each contact in the roster * * This class delegates to a XMPPConnection and a XMPPRoster, thereby tracking * each contacts presences and the current XMPPRosterItem. |
︙ | ︙ |
Modified src/XMPPContactManager.m from [59c5b114c5] to [24c872061c].
︙ | ︙ | |||
103 104 105 106 107 108 109 | _contacts = [[OFMutableDictionary alloc] init]; rosterItems = roster.rosterItems; for (OFString *bareJID in rosterItems) { XMPPContact *contact = [[[XMPPContact alloc] init] autorelease]; contact.rosterItem = [rosterItems objectForKey: bareJID]; | | < | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | _contacts = [[OFMutableDictionary alloc] init]; rosterItems = roster.rosterItems; for (OFString *bareJID in rosterItems) { XMPPContact *contact = [[[XMPPContact alloc] init] autorelease]; contact.rosterItem = [rosterItems objectForKey: bareJID]; [_contacts setObject: contact forKey: bareJID]; [_delegates broadcastSelector: @selector(contactManager: didAddContact:) withObject: self withObject: contact]; } } |
︙ | ︙ | |||
133 134 135 136 137 138 139 | [_contacts removeObjectForKey: bareJID]; return; } if (contact == nil) { contact = [[[XMPPContact alloc] init] autorelease]; contact.rosterItem = rosterItem; | | < | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | [_contacts removeObjectForKey: bareJID]; return; } if (contact == nil) { contact = [[[XMPPContact alloc] init] autorelease]; contact.rosterItem = rosterItem; [_contacts setObject: contact forKey: bareJID]; [_delegates broadcastSelector: @selector(contactManager: didAddContact:) withObject: self withObject: contact]; } else { [_delegates broadcastSelector: @selector(contact: willUpdateWithRosterItem:) |
︙ | ︙ | |||
170 171 172 173 174 175 176 | contact = [_contacts objectForKey: JID.bareJID]; if (contact == nil) return; /* Available presence */ if ([type isEqual: @"available"]) { | | < | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | contact = [_contacts objectForKey: JID.bareJID]; if (contact == nil) return; /* Available presence */ if ([type isEqual: @"available"]) { [contact xmpp_setPresence: presence resource: JID.resource]; [_delegates broadcastSelector: @selector(contact: didSendPresence:) withObject: contact withObject: presence]; return; } |
︙ | ︙ |
Modified src/XMPPDiscoEntity.m from [99bc6fd072] to [8c0b92b7c2].
︙ | ︙ | |||
28 29 30 31 32 33 34 | #import "XMPPIQ.h" #import "XMPPJID.h" #import "namespaces.h" @implementation XMPPDiscoEntity @synthesize discoNodes = _discoNodes, capsNode = _capsNode; | | < | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #import "XMPPIQ.h" #import "XMPPJID.h" #import "namespaces.h" @implementation XMPPDiscoEntity @synthesize discoNodes = _discoNodes, capsNode = _capsNode; + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node { OF_UNRECOGNIZED_SELECTOR } + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node name: (OFString *)name |
︙ | ︙ | |||
53 54 55 56 57 58 59 | + (instancetype)discoEntityWithConnection: (XMPPConnection *)connection capsNode: (OFString *)capsNode { return [[[self alloc] initWithConnection: connection capsNode: capsNode] autorelease]; } | | < | < < | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | + (instancetype)discoEntityWithConnection: (XMPPConnection *)connection capsNode: (OFString *)capsNode { return [[[self alloc] initWithConnection: connection capsNode: capsNode] autorelease]; } - (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node { OF_INVALID_INIT_METHOD } - (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node name: (nullable OFString *)name { OF_INVALID_INIT_METHOD } - (instancetype)initWithConnection: (XMPPConnection *)connection { return [self initWithConnection: connection capsNode: nil]; } - (instancetype)initWithConnection: (XMPPConnection *)connection capsNode: (OFString *)capsNode { self = [super initWithJID: [connection JID] node: nil name: nil]; @try { _discoNodes = [[OFMutableDictionary alloc] init]; _connection = connection; _capsNode = [capsNode copy]; [_connection addDelegate: self]; |
︙ | ︙ | |||
103 104 105 106 107 108 109 | [_discoNodes release]; [super dealloc]; } - (void)addDiscoNode: (XMPPDiscoNode *)node { | | < | < | < | | < | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | [_discoNodes release]; [super dealloc]; } - (void)addDiscoNode: (XMPPDiscoNode *)node { [_discoNodes setObject: node forKey: node.node]; } - (OFString *)capsHash { OFMutableString *caps = [OFMutableString string]; OFSHA1Hash *hash = [OFSHA1Hash hashWithAllowsSwappableMemory: true]; OFData *digest; for (XMPPDiscoIdentity *identity in _identities) [caps appendFormat: @"%@/%@//%@<", identity.category, identity.type, identity.name]; for (OFString *feature in _features) [caps appendFormat: @"%@<", feature]; [hash updateWithBuffer: caps.UTF8String length: caps.UTF8StringLength]; digest = [OFData dataWithItems: hash.digest count: hash.digestSize]; return digest.stringByBase64Encoding; } - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID { _JID = [JID copy]; } - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ { if (![IQ.to isEqual: _JID]) return false; OFXMLElement *query = [IQ elementForName: @"query" namespace: XMPPDiscoItemsNS]; if (query != nil) { OFString *node = [query attributeForName: @"node"].stringValue; if (node == nil) return [self xmpp_handleItemsIQ: IQ connection: connection]; XMPPDiscoNode *responder = [_discoNodes objectForKey: node]; if (responder != nil) return [responder xmpp_handleItemsIQ: IQ connection: connection]; return false; } query = [IQ elementForName: @"query" namespace: XMPPDiscoInfoNS]; if (query != nil) { OFString *node = [query attributeForName: @"node"].stringValue; if (node == nil) return [self xmpp_handleInfoIQ: IQ connection: connection]; |
︙ | ︙ |
Modified src/XMPPDiscoIdentity.h from [201199f107] to [31e1f632cf].
1 2 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, 2016, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
92 93 94 95 96 97 98 | * @brief Initializes an already allocated XMPPDiscoIdentity with the specified * category and type. * * @param category The category of the identity * @param type The type of the identity * @return An initialized XMPPDiscoIdentity */ | | < | 92 93 94 95 96 97 98 99 100 101 102 | * @brief Initializes an already allocated XMPPDiscoIdentity with the specified * category and type. * * @param category The category of the identity * @param type The type of the identity * @return An initialized XMPPDiscoIdentity */ - (instancetype)initWithCategory: (OFString *)category type: (OFString *)type; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPDiscoIdentity.m from [6198736245] to [c6ea2ee8fb].
︙ | ︙ | |||
59 60 61 62 63 64 65 | [self release]; @throw e; } return self; } | | < | < < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | [self release]; @throw e; } return self; } - (instancetype)initWithCategory: (OFString *)category type: (OFString *)type { return [self initWithCategory: category type: type name: nil]; } - (instancetype)init { OF_INVALID_INIT_METHOD } |
︙ | ︙ |
Modified src/XMPPDiscoNode.h from [2f2951260b] to [26dd55ea62].
1 2 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, 2016, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
99 100 101 102 103 104 105 | * @brief Initializes an already allocated XMPPDiscoNode with the specified * JID and node * * @param JID The JID this node lives on * @param node The node's opaque name * @return An initialized XMPPDiscoNode */ | | < | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | * @brief Initializes an already allocated XMPPDiscoNode with the specified * JID and node * * @param JID The JID this node lives on * @param node The node's opaque name * @return An initialized XMPPDiscoNode */ - (instancetype)initWithJID: (XMPPJID *)JID node: (nullable OFString *)node; /*! * @brief Initializes an already allocated XMPPDiscoNode with the specified * JID, node and name * * @param JID The JID this node lives on * @param node The node's opaque name |
︙ | ︙ |
Modified src/XMPPDiscoNode.m from [270f41c89f] to [36daf5bc27].
1 2 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, 2016, 2019, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | #import "namespaces.h" @implementation XMPPDiscoNode @synthesize JID = _JID, node = _node, name = _name, identities = _identities; @synthesize features = _features, childNodes = _childNodes; | | < | < | < | < < | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #import "namespaces.h" @implementation XMPPDiscoNode @synthesize JID = _JID, node = _node, name = _name, identities = _identities; @synthesize features = _features, childNodes = _childNodes; + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node; { return [[[self alloc] initWithJID: JID node: node] autorelease]; } + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node name: (OFString *)name { return [[[self alloc] initWithJID: JID node: node name: name] autorelease]; } - (instancetype)initWithJID: (XMPPJID *)JID node: (OFString *)node { return [self initWithJID: JID node: node name: nil]; } - (instancetype)initWithJID: (XMPPJID *)JID node: (OFString *)node name: (OFString *)name { self = [super init]; @try { if (JID == nil && ![self isKindOfClass: [XMPPDiscoEntity class]]) @throw [OFInvalidArgumentException exception]; _JID = [JID copy]; _node = [node copy]; _name = [name copy]; _identities = [[OFSortedList alloc] init]; _features = [[OFSortedList alloc] init]; _childNodes = [[OFMutableDictionary alloc] init]; [self addFeature: XMPPDiscoItemsNS]; [self addFeature: XMPPDiscoInfoNS]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
122 123 124 125 126 127 128 | - (bool)xmpp_handleItemsIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { XMPPIQ *resultIQ; OFXMLElement *response; OFXMLElement *query = [IQ elementForName: @"query" | | | | | < | | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | - (bool)xmpp_handleItemsIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { XMPPIQ *resultIQ; OFXMLElement *response; OFXMLElement *query = [IQ elementForName: @"query" namespace: XMPPDiscoItemsNS]; OFString *node = [[query attributeForName: @"node"] stringValue]; if (!(node == _node) && ![node isEqual: _node]) return false; resultIQ = [IQ resultIQ]; response = [OFXMLElement elementWithName: @"query" namespace: XMPPDiscoItemsNS]; [resultIQ addChild: response]; for (XMPPDiscoNode *child in _childNodes) { OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPPDiscoItemsNS]; [item addAttributeWithName: @"jid" stringValue: child.JID.fullJID]; if (child.node != nil) [item addAttributeWithName: @"node" stringValue: child.node]; if (child.name != nil) [item addAttributeWithName: @"name" stringValue: child.name]; [response addChild: item]; } [connection sendStanza: resultIQ]; return true; } - (bool)xmpp_handleInfoIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { XMPPIQ *resultIQ; OFXMLElement *response; resultIQ = [IQ resultIQ]; response = [OFXMLElement elementWithName: @"query" namespace: XMPPDiscoInfoNS]; [resultIQ addChild: response]; for (XMPPDiscoIdentity *identity in _identities) { OFXMLElement *identityElement = [OFXMLElement elementWithName: @"identity" namespace: XMPPDiscoInfoNS]; [identityElement addAttributeWithName: @"category" stringValue: identity.category]; [identityElement addAttributeWithName: @"type" stringValue: identity.type]; if (identity.name != nil) [identityElement addAttributeWithName: @"name" stringValue: identity.name]; [response addChild: identityElement]; } for (OFString *feature in _features) { OFXMLElement *featureElement = [OFXMLElement elementWithName: @"feature" namespace: XMPPDiscoInfoNS]; [featureElement addAttributeWithName: @"var" stringValue: feature]; [response addChild: featureElement]; } [connection sendStanza: resultIQ]; return true; } @end |
Modified src/XMPPEXTERNALAuth.m from [e1c935f11f] to [534be00067].
1 2 | /* * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2019, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | #include "config.h" #import "XMPPEXTERNALAuth.h" @implementation XMPPEXTERNALAuth: XMPPAuthenticator + (instancetype)EXTERNALAuth { | | < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include "config.h" #import "XMPPEXTERNALAuth.h" @implementation XMPPEXTERNALAuth: XMPPAuthenticator + (instancetype)EXTERNALAuth { return [[[self alloc] initWithAuthcid: nil password: nil] autorelease]; } + (instancetype)EXTERNALAuthWithAuthzid: (OFString *)authzid { return [[[self alloc] initWithAuthzid: authzid authcid: nil password: nil] autorelease]; |
︙ | ︙ |
Modified src/XMPPFileStorage.m from [18e0ab5705] to [34f603d038].
︙ | ︙ | |||
88 89 90 91 92 93 94 | if (i++ == components - 1) continue; OFMutableDictionary *iter2 = [iter objectForKey: component]; if (iter2 == nil) { iter2 = [OFMutableDictionary dictionary]; | | < | < | < | < | < | < | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | if (i++ == components - 1) continue; OFMutableDictionary *iter2 = [iter objectForKey: component]; if (iter2 == nil) { iter2 = [OFMutableDictionary dictionary]; [iter setObject: iter2 forKey: component]; } iter = iter2; } if (object != nil) [iter setObject: object forKey: [pathComponents lastObject]]; else [iter removeObjectForKey: pathComponents.lastObject]; } - (id)xmpp_objectForPath: (OFString *)path { id object = _data; for (OFString *component in [path componentsSeparatedByString: @"."]) object = [object objectForKey: component]; return object; } - (void)setStringValue: (OFString *)string forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self xmpp_setObject: string forPath: path]; objc_autoreleasePoolPop(pool); } - (OFString *)stringValueForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *string; string = [self xmpp_objectForPath: path]; objc_autoreleasePoolPop(pool); return string; } - (void)setBooleanValue: (bool)boolean forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self xmpp_setObject: [OFNumber numberWithBool: boolean] forPath: path]; objc_autoreleasePoolPop(pool); } - (bool)booleanValueForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); bool boolean; boolean = [[self xmpp_objectForPath: path] boolValue]; objc_autoreleasePoolPop(pool); return boolean; } - (void)setIntegerValue: (long long)integer forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self xmpp_setObject: [OFNumber numberWithLongLong: integer] forPath: path]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
181 182 183 184 185 186 187 | integer = [[self xmpp_objectForPath: path] longLongValue]; objc_autoreleasePoolPop(pool); return integer; } | | < | < | < | < | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | integer = [[self xmpp_objectForPath: path] longLongValue]; objc_autoreleasePoolPop(pool); return integer; } - (void)setArray: (OFArray *)array forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self xmpp_setObject: array forPath: path]; objc_autoreleasePoolPop(pool); } - (OFArray *)arrayForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFArray *array; array = [self xmpp_objectForPath: path]; objc_autoreleasePoolPop(pool); return array; } - (void)setDictionary: (OFDictionary *)dictionary forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self xmpp_setObject: dictionary forPath: path]; objc_autoreleasePoolPop(pool); } - (OFDictionary *)dictionaryForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ |
Modified src/XMPPIQ.h from [bbf1907353] to [ddd145d879].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, 2021, Jonathan Schleifer <js@nil.im> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
32 33 34 35 36 37 38 | /*! * @brief Creates a new XMPPIQ with the specified type and ID. * * @param type The value for the stanza's type attribute * @param ID The value for the stanza's id attribute * @return A new autoreleased XMPPIQ */ | | < | < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /*! * @brief Creates a new XMPPIQ with the specified type and ID. * * @param type The value for the stanza's type attribute * @param ID The value for the stanza's id attribute * @return A new autoreleased XMPPIQ */ + (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID; /*! * @brief Initializes an already allocated XMPPIQ with the specified type and * ID. * * @param type The value for the stanza's type attribute * @param ID The value for the stanza's id attribute * @return An initialized XMPPIQ */ - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID; /*! * @brief Generates a result IQ for the receiving object. * * @return A new autoreleased XMPPIQ */ - (XMPPIQ *)resultIQ; |
︙ | ︙ | |||
72 73 74 75 76 77 78 | /*! * @brief Generates an error IQ for the receiving object. * * @param type An error type as defined by RFC 6120 * @param condition A defined conditions from RFC 6120 * @return A new autoreleased XMPPIQ */ | | < | 70 71 72 73 74 75 76 77 78 79 80 | /*! * @brief Generates an error IQ for the receiving object. * * @param type An error type as defined by RFC 6120 * @param condition A defined conditions from RFC 6120 * @return A new autoreleased XMPPIQ */ - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPIQ.m from [a98a2208b8] to [011f9d770f].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, 2019, 2021, Jonathan Schleifer <js@nil.im> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #include "config.h" #import "namespaces.h" #import "XMPPIQ.h" @implementation XMPPIQ | | < | < | < | < < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include "config.h" #import "namespaces.h" #import "XMPPIQ.h" @implementation XMPPIQ + (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID { self = [super initWithName: @"iq" type: type ID: ID]; @try { if (![type isEqual: @"get"] && ![type isEqual: @"set"] && ![type isEqual: @"result"] && ![type isEqual: @"error"]) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
66 67 68 69 70 71 72 | condition: (OFString *)condition text: (OFString *)text { XMPPIQ *ret = [XMPPIQ IQWithType: @"error" ID: self.ID]; void *pool = objc_autoreleasePoolPush(); OFXMLElement *error = [OFXMLElement elementWithName: @"error" | | | < | | | < | < < | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | condition: (OFString *)condition text: (OFString *)text { XMPPIQ *ret = [XMPPIQ IQWithType: @"error" ID: self.ID]; void *pool = objc_autoreleasePoolPush(); OFXMLElement *error = [OFXMLElement elementWithName: @"error" namespace: XMPPClientNS]; [error addAttributeWithName: @"type" stringValue: type]; [error addChild: [OFXMLElement elementWithName: condition namespace: XMPPStanzasNS]]; if (text) [error addChild: [OFXMLElement elementWithName: @"text" namespace: XMPPStanzasNS stringValue: text]]; [ret addChild: error]; ret.to = self.from; ret.from = nil; objc_autoreleasePoolPop(pool); return ret; } - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition { return [self errorIQWithType: type condition: condition text: nil]; } @end |
Modified src/XMPPMessage.m from [5fedee525e] to [3d98a688a4].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, 2012, 2013, 2019, 2021, Jonathan Schleifer <js@nil.im> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
38 39 40 41 42 43 44 | } + (instancetype)messageWithType: (OFString *)type { return [[[self alloc] initWithType: type] autorelease]; } | | < | < | < | < | < | < | < < | | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | } + (instancetype)messageWithType: (OFString *)type { return [[[self alloc] initWithType: type] autorelease]; } + (instancetype)messageWithType: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - (instancetype)init { return [self initWithType: nil ID: nil]; } - (instancetype)initWithID: (OFString *)ID { return [self initWithType: nil ID: ID]; } - (instancetype)initWithType: (OFString *)type { return [self initWithType: type ID: nil]; } - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID { return [super initWithName: @"message" type: type ID: ID]; } - (void)setBody: (OFString *)body { OFXMLElement *oldBody = [self elementForName: @"body" namespace: XMPPClientNS]; if (oldBody != nil) [self removeChild: oldBody]; if (body != nil) [self addChild: [OFXMLElement elementWithName: @"body" namespace: XMPPClientNS stringValue: body]]; } - (OFString *)body { return [self elementForName: @"body" namespace: XMPPClientNS].stringValue; } @end |
Modified src/XMPPMulticastDelegate.h from [f5ae1a7771] to [21e7d5e356].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2012, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | /*! * @brief Broadcasts a selector with an object to all registered delegates. * * @param selector The selector to broadcast * @param object The object to broadcast */ | | < | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /*! * @brief Broadcasts a selector with an object to all registered delegates. * * @param selector The selector to broadcast * @param object The object to broadcast */ - (bool)broadcastSelector: (SEL)selector withObject: (nullable id)object; /*! * @brief Broadcasts a selector with two objects to all registered delegates. * * @param selector The selector to broadcast * @param object1 The first object to broadcast * @param object2 The second object to broadcast |
︙ | ︙ |
Modified src/XMPPMulticastDelegate.m from [7d0f01d54a] to [275190de72].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2012, 2019, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
65 66 67 68 69 70 71 | continue; [_delegates removeItemAtIndex: i]; return; } } | | < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | continue; [_delegates removeItemAtIndex: i]; return; } } - (bool)broadcastSelector: (SEL)selector withObject: (id)object { void *pool = objc_autoreleasePoolPush(); OFMutableData *currentDelegates = [[_delegates copy] autorelease]; id const *items = currentDelegates.items; size_t i, count = currentDelegates.count; bool handled = false; |
︙ | ︙ |
Modified src/XMPPPresence.m from [a2a1eacbe7] to [9e6205b31f].
︙ | ︙ | |||
61 62 63 64 65 66 67 | } + (instancetype)presenceWithType: (OFString *)type { return [[[self alloc] initWithType: type] autorelease]; } | | < | < | < | < | < | < | < < | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | } + (instancetype)presenceWithType: (OFString *)type { return [[[self alloc] initWithType: type] autorelease]; } + (instancetype)presenceWithType: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - (instancetype)init { return [self initWithType: nil ID: nil]; } - (instancetype)initWithID: (OFString *)ID { return [self initWithType: nil ID: ID]; } - (instancetype)initWithType: (OFString *)type { return [self initWithType: type ID: nil]; } - (instancetype)initWithType: (OFString *)type ID: (OFString *)ID { return [super initWithName: @"presence" type: type ID: ID]; } - (instancetype)initWithElement: (OFXMLElement *)element { self = [super initWithElement: element]; @try { OFXMLElement *subElement; if ((subElement = [element elementForName: @"show" namespace: XMPPClientNS])) self.show = subElement.stringValue; if ((subElement = [element elementForName: @"status" namespace: XMPPClientNS])) self.status = subElement.stringValue; if ((subElement = [element elementForName: @"priority" namespace: XMPPClientNS])) self.priority = [OFNumber numberWithLongLong: [subElement longLongValueWithBase: 10]]; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
133 134 135 136 137 138 139 | [super dealloc]; } - (void)setShow: (OFString *)show { OFXMLElement *oldShow = [self elementForName: @"show" | | | | | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | [super dealloc]; } - (void)setShow: (OFString *)show { OFXMLElement *oldShow = [self elementForName: @"show" namespace: XMPPClientNS]; OFString *old; if (oldShow != nil) [self removeChild: oldShow]; if (show != nil) [self addChild: [OFXMLElement elementWithName: @"show" namespace: XMPPClientNS stringValue: show]]; old = _show; _show = [show copy]; [old release]; } - (void)setStatus: (OFString *)status { OFXMLElement *oldStatus = [self elementForName: @"status" namespace: XMPPClientNS]; OFString *old; if (oldStatus != nil) [self removeChild: oldStatus]; if (status != nil) [self addChild: [OFXMLElement elementWithName: @"status" namespace: XMPPClientNS stringValue: status]]; old = _status; _status = [status copy]; [old release]; } - (void)setPriority: (OFNumber *)priority { long long prio = priority.longLongValue; OFNumber *old; if ((prio < -128) || (prio > 127)) @throw [OFInvalidArgumentException exception]; OFXMLElement *oldPriority = [self elementForName: @"priority" namespace: XMPPClientNS]; if (oldPriority != nil) [self removeChild: oldPriority]; OFString *priority_s = [OFString stringWithFormat: @"%hhd", priority.charValue]; [self addChild: [OFXMLElement elementWithName: @"priority" namespace: XMPPClientNS stringValue: priority_s]]; old = _priority; _priority = [priority copy]; [old release]; } |
︙ | ︙ |
Modified src/XMPPRoster.m from [7c662ebfbc] to [af88dd61ac].
1 | /* | | > | 1 2 3 4 5 6 7 8 9 10 | /* * 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/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
87 88 89 90 91 92 93 | - (void)requestRoster { XMPPIQ *IQ; OFXMLElement *query; _rosterRequested = true; | | < | | < | < | < | | < | | | < | | | | < | < | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | - (void)requestRoster { XMPPIQ *IQ; OFXMLElement *query; _rosterRequested = true; IQ = [XMPPIQ IQWithType: @"get" ID: [_connection generateStanzaID]]; query = [OFXMLElement elementWithName: @"query" namespace: XMPPRosterNS]; if (_connection.supportsRosterVersioning) { OFString *ver = [_dataStorage stringValueForPath: @"roster.ver"]; if (ver == nil) ver = @""; [query addAttributeWithName: @"ver" stringValue: ver]; } [IQ addChild: query]; [_connection sendIQ: IQ callbackTarget: self selector: @selector(xmpp_handleInitialRosterForConnection: IQ:)]; } - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ { OFXMLElement *rosterElement; OFXMLElement *element; XMPPRosterItem *rosterItem; OFString *origin; rosterElement = [IQ elementForName: @"query" namespace: XMPPRosterNS]; if (rosterElement == nil) return false; if (![IQ.type isEqual: @"set"]) return false; // Ensure the roster push has been sent by the server origin = IQ.from.fullJID; if (origin != nil && ![origin isEqual: connection.JID.bareJID]) return false; element = [rosterElement elementForName: @"item" namespace: XMPPRosterNS]; if (element != nil) { rosterItem = [self xmpp_rosterItemWithXMLElement: element]; [_delegates broadcastSelector: @selector( roster:didReceiveRosterItem:) withObject: self withObject: rosterItem]; [self xmpp_updateRosterItem: rosterItem]; } if (_connection.supportsRosterVersioning) { OFString *ver = [rosterElement attributeForName: @"ver"].stringValue; [_dataStorage setStringValue: ver forPath: @"roster.ver"]; [_dataStorage save]; } [connection sendStanza: [IQ resultIQ]]; return true; } - (void)addRosterItem: (XMPPRosterItem *)rosterItem { [self updateRosterItem: rosterItem]; } - (void)updateRosterItem: (XMPPRosterItem *)rosterItem { XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [_connection generateStanzaID]]; OFXMLElement *query = [OFXMLElement elementWithName: @"query" namespace: XMPPRosterNS]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPPRosterNS]; [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: XMPPRosterNS stringValue: group]]; [query addChild: item]; [IQ addChild: query]; [_connection sendStanza: IQ]; } - (void)deleteRosterItem: (XMPPRosterItem *)rosterItem { XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [_connection generateStanzaID]]; OFXMLElement *query = [OFXMLElement elementWithName: @"query" namespace: XMPPRosterNS]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPPRosterNS]; [item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID]; [item addAttributeWithName: @"subscription" stringValue: @"remove"]; [query addChild: item]; [IQ addChild: query]; [_connection sendStanza: IQ]; } |
︙ | ︙ | |||
255 256 257 258 259 260 261 | [item setObject: rosterItem.name forKey: @"name"]; if ([rosterItem groups] != nil) [item setObject: rosterItem.groups forKey: @"groups"]; | | < | < | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | [item setObject: rosterItem.name forKey: @"name"]; if ([rosterItem groups] != nil) [item setObject: rosterItem.groups forKey: @"groups"]; [items setObject: item forKey: rosterItem.JID.bareJID]; } else [items removeObjectForKey: rosterItem.JID.bareJID]; [_dataStorage setDictionary: items forPath: @"roster.items"]; } if (![rosterItem.subscription isEqual: @"remove"]) [_rosterItems setObject: rosterItem forKey: rosterItem.JID.bareJID]; else [_rosterItems removeObjectForKey: rosterItem.JID.bareJID]; |
︙ | ︙ | |||
292 293 294 295 296 297 298 | ![subscription isEqual: @"both"] && ![subscription isEqual: @"remove"]) subscription = @"none"; rosterItem.subscription = subscription; for (OFXMLElement *groupElement in | | < | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | ![subscription isEqual: @"both"] && ![subscription isEqual: @"remove"]) subscription = @"none"; rosterItem.subscription = subscription; for (OFXMLElement *groupElement in [element elementsForName: @"group" namespace: XMPPRosterNS]) [groups addObject: groupElement.stringValue]; if (groups.count > 0) rosterItem.groups = groups; return rosterItem; } - (void)xmpp_handleInitialRosterForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ { OFXMLElement *rosterElement = [IQ elementForName: @"query" namespace: XMPPRosterNS]; if (connection.supportsRosterVersioning) { if (rosterElement == nil) { for (OFDictionary *item in [_dataStorage dictionaryForPath: @"roster.items"]) { XMPPRosterItem *rosterItem; XMPPJID *JID; |
︙ | ︙ | |||
338 339 340 341 342 343 344 | } for (OFXMLElement *element in rosterElement.children) { void *pool = objc_autoreleasePoolPush(); XMPPRosterItem *rosterItem; if (![element.name isEqual: @"item"] || | | | < | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | } for (OFXMLElement *element in rosterElement.children) { void *pool = objc_autoreleasePoolPush(); XMPPRosterItem *rosterItem; if (![element.name isEqual: @"item"] || ![element.namespace isEqual: XMPPRosterNS]) continue; rosterItem = [self xmpp_rosterItemWithXMLElement: element]; [self xmpp_updateRosterItem: rosterItem]; objc_autoreleasePoolPop(pool); } if (connection.supportsRosterVersioning && rosterElement != nil) { OFString *ver = [rosterElement attributeForName: @"ver"].stringValue; [_dataStorage setStringValue: ver forPath: @"roster.ver"]; [_dataStorage save]; } [_delegates broadcastSelector: @selector(rosterWasReceived:) withObject: self]; } @end |
Modified src/XMPPSCRAMAuth.m from [b14abcbfc5] to [07128503d9].
︙ | ︙ | |||
33 34 35 36 37 38 39 | #import "XMPPExceptions.h" #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c @interface XMPPSCRAMAuth () - (OFString *)xmpp_genNonce; | | < | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #import "XMPPExceptions.h" #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c @interface XMPPSCRAMAuth () - (OFString *)xmpp_genNonce; - (const uint8_t *)xmpp_HMACWithKey: (OFData *)key data: (OFData *)data; - (OFData *)xmpp_hiWithData: (OFData *)str salt: (OFData *)salt iterationCount: (intmax_t)i; - (OFData *)xmpp_parseServerFirstMessage: (OFData *)data; - (OFData *)xmpp_parseServerFinalMessage: (OFData *)data; @end |
︙ | ︙ | |||
133 134 135 136 137 138 139 | - (void)setAuthzid: (OFString *)authzid { OFString *old = _authzid; if (authzid) { OFMutableString *new = [[authzid mutableCopy] autorelease]; | | < | < | < | < | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | - (void)setAuthzid: (OFString *)authzid { OFString *old = _authzid; if (authzid) { OFMutableString *new = [[authzid mutableCopy] autorelease]; [new replaceOccurrencesOfString: @"=" withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"]; [new makeImmutable]; _authzid = [new copy]; } else _authzid = nil; [old release]; } - (void)setAuthcid: (OFString *)authcid { OFString *old = _authcid; if (authcid) { OFMutableString *new = [[authcid mutableCopy] autorelease]; [new replaceOccurrencesOfString: @"=" withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"]; [new makeImmutable]; _authcid = [new copy]; } else _authcid = nil; [old release]; } |
︙ | ︙ | |||
277 278 279 280 281 282 283 | if (_plusAvailable && _connection.encrypted) { OFData *channelBinding = [((SSLSocket *)[_connection socket]) channelBindingDataWithType: @"tls-unique"]; [tmpArray addItems: channelBinding.items count: channelBinding.count]; } tmpString = tmpArray.stringByBase64Encoding; | | < | < | < | < | < | < > | | < | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | if (_plusAvailable && _connection.encrypted) { OFData *channelBinding = [((SSLSocket *)[_connection socket]) channelBindingDataWithType: @"tls-unique"]; [tmpArray addItems: channelBinding.items count: channelBinding.count]; } tmpString = tmpArray.stringByBase64Encoding; [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]; /* * IETF RFC 5802: * SaltedPassword := Hi(Normalize(password), salt, i) */ tmpArray = [OFMutableData dataWithItems: _password.UTF8String count: _password.UTF8StringLength]; saltedPassword = [self xmpp_hiWithData: tmpArray salt: salt iterationCount: iterCount]; /* * IETF RFC 5802: * AuthMessage := client-first-message-bare + "," + * server-first-message + "," + * client-final-message-without-proof */ [authMessage addItems: _clientFirstMessageBare.UTF8String count: _clientFirstMessageBare.UTF8StringLength]; [authMessage addItem: ","]; [authMessage addItems: data.items count: data.count * data.itemSize]; [authMessage addItem: ","]; [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]]; /* * IETF RFC 5802: * StoredKey := H(ClientKey) */ [hash updateWithBuffer: (void *)clientKey length: [_hashType digestSize]]; |
︙ | ︙ | |||
342 343 344 345 346 347 348 | count: hash.digestSize] data: authMessage]; /* * IETF RFC 5802: * ServerKey := HMAC(SaltedPassword, "Server Key") */ | > | | < | < | < | < | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | count: hash.digestSize] data: authMessage]; /* * IETF RFC 5802: * ServerKey := HMAC(SaltedPassword, "Server Key") */ serverKey = [self xmpp_HMACWithKey: saltedPassword data: [OFData dataWithItems: "Server Key" count: 10]]; /* * IETF RFC 5802: * ServerSignature := HMAC(ServerKey, AuthMessage) */ tmpArray = [OFMutableData dataWithItems: serverKey count: [_hashType digestSize]]; [_serverSignature release]; _serverSignature = [[OFData alloc] initWithItems: [self xmpp_HMACWithKey: tmpArray data: authMessage] count: [_hashType digestSize]]; /* * IETF RFC 5802: * ClientProof := ClientKey XOR ClientSignature */ tmpArray = [OFMutableData dataWithCapacity: [_hashType digestSize]]; for (i = 0; i < [_hashType digestSize]; i++) { uint8_t c = clientKey[i] ^ clientSignature[i]; [tmpArray addItem: &c]; } // Add p=<base64(ClientProof)> [ret addItem: ","]; [ret addItems: "p=" count: 2]; tmpString = tmpArray.stringByBase64Encoding; [ret addItems: tmpString.UTF8String count: tmpString.UTF8StringLength]; return ret; } - (OFData *)xmpp_parseServerFinalMessage: (OFData *)data { OFString *mess, *value; |
︙ | ︙ | |||
443 444 445 446 447 448 449 | uint8_t *kI = NULL, *kO = NULL; id <OFCryptographicHash> hashI, hashO; if (key.itemSize * key.count > blockSize) { hashI = [[[_hashType alloc] init] autorelease]; [hashI updateWithBuffer: key.items length: key.itemSize * key.count]; | | < | < | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | uint8_t *kI = NULL, *kO = NULL; id <OFCryptographicHash> hashI, hashO; if (key.itemSize * key.count > blockSize) { hashI = [[[_hashType alloc] init] autorelease]; [hashI updateWithBuffer: key.items length: key.itemSize * key.count]; [k addItems: hashI.digest count: hashI.digestSize]; } else [k addItems: key.items count: key.itemSize * key.count]; @try { kI = OFAllocMemory(1, blockSize); kO = OFAllocMemory(1, blockSize); kSize = k.count; memcpy(kI, k.items, kSize); |
︙ | ︙ | |||
504 505 506 507 508 509 510 | @try { memset(result, 0, digestSize); salty = [[salt mutableCopy] autorelease]; [salty addItems: "\0\0\0\1" count: 4]; | | < | < | < | < | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | @try { memset(result, 0, digestSize); salty = [[salt mutableCopy] autorelease]; [salty addItems: "\0\0\0\1" count: 4]; 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]; /* releases uOld and previous tmp */ objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); [tmp autorelease]; u = [self xmpp_HMACWithKey: str data: tmp]; for (k = 0; k < digestSize; k++) result[k] ^= u[k]; uOld = u; } ret = [OFData dataWithItems: result count: digestSize]; } @finally { OFFreeMemory(result); } [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/XMPPStanza.h from [832de87656] to [adb824adc5].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, 2012, 2013, 2016, 2021, Jonathan Schleifer <js@nil.im> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
83 84 85 86 87 88 89 | /*! * @brief Creates a new autoreleased XMPPStanza with the specified name and ID. * * @param name The stanza's name (one of iq, message or presence) * @param ID The value for the stanza's id attribute * @return A new autoreleased XMPPStanza */ | | < | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /*! * @brief Creates a new autoreleased XMPPStanza with the specified name and ID. * * @param name The stanza's name (one of iq, message or presence) * @param ID The value for the stanza's id attribute * @return A new autoreleased XMPPStanza */ + (instancetype)stanzaWithName: (OFString *)name ID: (nullable OFString *)ID; /*! * @brief Creates a new autoreleased XMPPStanza with the specified name, type * and ID. * * @param name The stanza's name (one of iq, message or presence) * @param type The value for the stanza's type attribute |
︙ | ︙ | |||
133 134 135 136 137 138 139 | * @brief Initializes an already allocated XMPPStanza with the specified name * and type. * * @param name The stanza's name (one of iq, message or presence) * @param type The value for the stanza's type attribute * @return A initialized XMPPStanza */ | | < | < | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | * @brief Initializes an already allocated XMPPStanza with the specified name * and type. * * @param name The stanza's name (one of iq, message or presence) * @param type The value for the stanza's type attribute * @return A initialized XMPPStanza */ - (instancetype)initWithName: (OFString *)name type: (nullable OFString *)type; /*! * @brief Initializes an already allocated XMPPStanza with the specified name * and ID. * * @param name The stanza's name (one of iq, message or presence) * @param ID The value for the stanza's id attribute * @return A initialized XMPPStanza */ - (instancetype)initWithName: (OFString *)name ID: (nullable OFString *)ID; /*! * @brief Initializes an already allocated XMPPStanza with the specified name, * type and ID. * * @param name The stanza's name (one of iq, message or presence) * @param type The value for the stanza's type attribute |
︙ | ︙ |
Modified src/XMPPStanza.m from [127836dc56] to [b5e09c3ebc].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2011, 2012, 2013, 2019, 2021, Jonathan Schleifer <js@nil.im> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
32 33 34 35 36 37 38 | @synthesize language = _language; + (instancetype)stanzaWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } | | < | < | < | < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | @synthesize language = _language; + (instancetype)stanzaWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } + (instancetype)stanzaWithName: (OFString *)name type: (OFString *)type { return [[[self alloc] initWithName: name type: type] autorelease]; } + (instancetype)stanzaWithName: (OFString *)name ID: (OFString *)ID { return [[[self alloc] initWithName: name ID: ID] autorelease]; } + (instancetype)stanzaWithName: (OFString *)name type: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithName: name |
︙ | ︙ | |||
66 67 68 69 70 71 72 | - (instancetype)initWithName: (OFString *)name stringValue: (OFString *)stringValue { OF_INVALID_INIT_METHOD } | | < | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | - (instancetype)initWithName: (OFString *)name stringValue: (OFString *)stringValue { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name namespace: (OFString *)namespace { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)namespace stringValue: (nullable OFString *)stringValue |
︙ | ︙ | |||
91 92 93 94 95 96 97 | - (instancetype)initWithFile: (OFString *)path { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name { | | < < | < | < < | < < | | | < | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | - (instancetype)initWithFile: (OFString *)path { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name { return [self initWithName: name type: nil ID: nil]; } - (instancetype)initWithName: (OFString *)name type: (OFString *)type { return [self initWithName: name type: type ID: nil]; } - (instancetype)initWithName: (OFString *)name ID: (OFString *)ID { return [self initWithName: name type: nil ID: ID]; } - (instancetype)initWithName: (OFString *)name type: (OFString *)type ID: (OFString *)ID { self = [super initWithName: name namespace: XMPPClientNS stringValue: nil]; @try { if (![name isEqual: @"iq"] && ![name isEqual: @"message"] && ![name isEqual: @"presence"]) @throw [OFInvalidArgumentException exception]; self.defaultNamespace = XMPPClientNS; [self setPrefix: @"stream" forNamespace: XMPPStreamNS]; if (type != nil) self.type = type; if (ID != nil) self.ID = ID; } @catch (id e) { |
︙ | ︙ | |||
189 190 191 192 193 194 195 | XMPPJID *old = _from; _from = [from copy]; [old release]; [self removeAttributeForName: @"from"]; if (from != nil) | | < | < | < | < | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | XMPPJID *old = _from; _from = [from copy]; [old release]; [self removeAttributeForName: @"from"]; if (from != nil) [self addAttributeWithName: @"from" stringValue: from.fullJID]; } - (void)setTo: (XMPPJID *)to { XMPPJID *old = _to; _to = [to copy]; [old release]; [self removeAttributeForName: @"to"]; if (to != nil) [self addAttributeWithName: @"to" stringValue: to.fullJID]; } - (void)setType: (OFString *)type { OFString *old = _type; _type = [type copy]; [old release]; [self removeAttributeForName: @"type"]; if (type != nil) [self addAttributeWithName: @"type" stringValue: type]; } - (void)setID: (OFString *)ID { OFString *old = _ID; _ID = [ID copy]; [old release]; [self removeAttributeForName: @"id"]; if (ID != nil) [self addAttributeWithName: @"id" stringValue: ID]; } - (void)setLanguage: (OFString *)language { OFString *old = _language; _language = [language copy]; [old release]; |
︙ | ︙ |
Modified src/XMPPStorage.h from [d938a6605c] to [2c1c8e337b].
︙ | ︙ | |||
26 27 28 29 30 31 32 | @class OFString; @class OFArray; @class OFDictionary; @protocol XMPPStorage <OFObject> - (void)save; | | < | < | < | < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | @class OFString; @class OFArray; @class OFDictionary; @protocol XMPPStorage <OFObject> - (void)save; - (void)setStringValue: (nullable OFString *)string forPath: (OFString *)path; - (nullable OFString *)stringValueForPath: (OFString *)path; - (void)setBooleanValue: (bool)boolean forPath: (OFString *)path; - (bool)booleanValueForPath: (OFString *)path; - (void)setIntegerValue: (long long)integer forPath: (OFString *)path; - (long long)integerValueForPath: (OFString *)path; - (void)setArray: (nullable OFArray *)array forPath: (OFString *)path; - (nullable OFArray *)arrayForPath: (OFString *)path; - (void)setDictionary: (nullable OFDictionary *)dictionary forPath: (OFString *)path; - (nullable OFDictionary *)dictionaryForPath: (OFString *)path; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPStreamManagement.m from [72de3d76fb] to [efb12f06e8].
1 2 | /* * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> | | | 1 2 3 4 5 6 7 8 9 10 | /* * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2019, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
56 57 58 59 60 61 62 | - (void)connection: (XMPPConnection *)connection didReceiveElement: (OFXMLElement *)element { OFString *elementName = element.name; OFString *elementNS = element.namespace; | | | | | < | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | - (void)connection: (XMPPConnection *)connection didReceiveElement: (OFXMLElement *)element { OFString *elementName = element.name; OFString *elementNS = element.namespace; if ([elementNS isEqual: XMPPSMNS]) { if ([elementName isEqual: @"enabled"]) { _receivedCount = 0; return; } if ([elementName isEqual: @"failed"]) { /* TODO: How do we handle this? */ return; } if ([elementName isEqual: @"r"]) { OFXMLElement *ack = [OFXMLElement elementWithName: @"a" namespace: XMPPSMNS]; OFString *stringValue = [OFString stringWithFormat: @"%" PRIu32, _receivedCount]; [ack addAttributeWithName: @"h" stringValue: stringValue]; [connection sendStanza: ack]; } } if ([elementNS isEqual: XMPPClientNS] && ([elementName isEqual: @"iq"] || [elementName isEqual: @"presence"] || [elementName isEqual: @"message"])) _receivedCount++; } /* TODO: Count outgoing stanzas here and cache them, send own ACK requests - (void)connection: (XMPPConnection *)connection didSendElement: (OFXMLElement *)element { } */ - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID { if (connection.supportsStreamManagement) [connection sendStanza: [OFXMLElement elementWithName: @"enable" namespace: XMPPSMNS]]; } @end |
Modified src/XMPPXMLElementBuilder.m from [327ef75abe] to [7d9e681687].
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2012, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | @implementation XMPPXMLElementBuilder - (void)parser: (OFXMLParser *)parser foundProcessingInstructions: (OFString *)pi { @throw [OFMalformedXMLException exception]; } | | < | 29 30 31 32 33 34 35 36 37 38 39 40 | @implementation XMPPXMLElementBuilder - (void)parser: (OFXMLParser *)parser foundProcessingInstructions: (OFString *)pi { @throw [OFMalformedXMLException exception]; } - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment { @throw [OFMalformedXMLException exception]; } @end |
Modified src/namespaces.h from [d898a2eb7d] to [8bdb649238].
1 | /* | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Copyright (c) 2011, 2021, Jonathan Schleifer <js@nil.im> * * https://heap.zone/objxmpp/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #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" |
Modified tests/test.m from [c9e6f90b6f] to [36a51c1323].
︙ | ︙ | |||
77 78 79 80 81 82 83 | msg.to = [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]; msg.from = [XMPPJID JIDWithString: @"alice@example.com"]; assert([msg.XMLString isEqual: @"<message type='chat' " @"to='jdev@conference.jabber.org' " @"from='alice@example.com'><body>Hello everyone</body>" @"</message>"]); | | < | < | < | < | < | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | msg.to = [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]; msg.from = [XMPPJID JIDWithString: @"alice@example.com"]; assert([msg.XMLString isEqual: @"<message type='chat' " @"to='jdev@conference.jabber.org' " @"from='alice@example.com'><body>Hello everyone</body>" @"</message>"]); 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' " @"to='juliet@capulet.lit' " @"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"]; XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem]; assert([elem.XMLString isEqual: [stanza XMLString]]); assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", stanza.from.fullJID, stanza.to.fullJID, stanza.type, stanza.ID] isEqual: @"bob@localhost, alice@localhost, get, 42"])); |
︙ | ︙ | |||
143 144 145 146 147 148 149 | } - (void)connectionWasAuthenticated: (XMPPConnection *)conn { OFLog(@"Auth successful"); } | | < | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | } - (void)connectionWasAuthenticated: (XMPPConnection *)conn { OFLog(@"Auth successful"); } - (void)connection: (XMPPConnection *)conn_ wasBoundToJID: (XMPPJID *)JID { OFLog(@"Bound to JID: %@", JID.fullJID); OFLog(@"Supports SM: %@", conn_.supportsStreamManagement ? @"true" : @"false"); XMPPDiscoEntity *discoEntity = [[XMPPDiscoEntity alloc] initWithConnection: conn]; |
︙ | ︙ | |||
208 209 210 211 212 213 214 | pres = [XMPPPresence presence]; pres.priority = [OFNumber numberWithChar: 10]; pres.status = @"ObjXMPP test is working!"; [conn sendStanza: pres]; #ifdef OF_HAVE_BLOCKS | | < < | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | pres = [XMPPPresence presence]; pres.priority = [OFNumber numberWithChar: 10]; pres.status = @"ObjXMPP test is working!"; [conn sendStanza: pres]; #ifdef OF_HAVE_BLOCKS 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) { OFLog(@"Ping response: %@", resp); }]; #endif } - (void)connectionDidUpgradeToTLS: (XMPPConnection *)conn_ { |
︙ | ︙ | |||
239 240 241 242 243 244 245 | - (void)roster: (XMPPRoster *)roster_ didReceiveRosterItem: (XMPPRosterItem *)rosterItem { OFLog(@"Got roster push: %@", rosterItem); } | | < | < | < | < | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | - (void)roster: (XMPPRoster *)roster_ didReceiveRosterItem: (XMPPRosterItem *)rosterItem { OFLog(@"Got roster push: %@", rosterItem); } - (bool)connection: (XMPPConnection *)conn didReceiveIQ: (XMPPIQ *)iq { OFLog(@"IQ: %@", iq); return NO; } - (void)connection: (XMPPConnection *)conn didReceiveMessage: (XMPPMessage *)msg { OFLog(@"Message: %@", msg); } - (void)connection: (XMPPConnection *)conn didReceivePresence: (XMPPPresence *)pres { OFLog(@"Presence: %@", pres); } - (void)connection: (XMPPConnection *)conn didThrowException: (id)e { @throw e; } - (void)connectionWasClosed: (XMPPConnection *)conn error: (OFXMLElement *)error { OFLog(@"Connection was closed: %@", error); } @end |