Comment: | Prefix all ivars with an underscore. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8dfcb8771729c7fab6409e4c7724e3d0 |
User & Date: | js on 2013-02-12 21:36:39 |
Other Links: | manifest | tags |
2013-02-13
| ||
23:18 | Don't cache the description of exceptions. check-in: 178390a16f user: js tags: trunk | |
2013-02-12
| ||
21:36 | Prefix all ivars with an underscore. check-in: 8dfcb87717 user: js tags: trunk | |
18:43 | Add missing files to Xcode project. check-in: 3c7399a750 user: js tags: trunk | |
Modified src/XMPPAuthenticator.h from [4aad1313b8] to [e94cafe039].
︙ | ︙ | |||
24 25 26 27 28 29 30 | /** * \brief A base class for classes implementing authentication mechanisms */ @interface XMPPAuthenticator: OFObject { /// \cond internal | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /** * \brief A base class for classes implementing authentication mechanisms */ @interface XMPPAuthenticator: OFObject { /// \cond internal OFString *_authzid; OFString *_authcid; OFString *_password; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The authzid to get authorization for @property (copy) OFString *authzid; /// \brief The authcid to authenticate with |
︙ | ︙ |
Modified src/XMPPAuthenticator.m from [6839baae99] to [e2fbdc8bf6].
︙ | ︙ | |||
23 24 25 26 27 28 29 | #ifdef HAVE_CONFIG_H # include "config.h" #endif #import "XMPPAuthenticator.h" @implementation XMPPAuthenticator | | | | | | | | | | | | | | | | | | | | | | | | 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 89 90 91 92 93 94 95 96 97 98 99 | #ifdef HAVE_CONFIG_H # include "config.h" #endif #import "XMPPAuthenticator.h" @implementation XMPPAuthenticator - initWithAuthcid: (OFString*)authcid password: (OFString*)password { return [self initWithAuthzid: nil authcid: authcid password: password]; } - initWithAuthzid: (OFString*)authzid authcid: (OFString*)authcid password: (OFString*)password { self = [super init]; @try { _authzid = [authzid copy]; _authcid = [authcid copy]; _password = [password copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_authzid release]; [_authcid release]; [_password release]; [super dealloc]; } - (void)setAuthzid: (OFString*)authzid { OF_SETTER(_authzid, authzid, YES, YES) } - (OFString*)authzid { OF_GETTER(_authzid, YES) } - (void)setAuthcid: (OFString*)authcid { OF_SETTER(_authcid, authcid, YES, YES) } - (OFString*)authcid { OF_GETTER(_authcid, YES) } - (void)setPassword: (OFString*)password { OF_SETTER(_password, password, YES, YES) } - (OFString*)password { OF_GETTER(_password, YES) } - (OFDataArray*)initialMessage { return nil; } |
︙ | ︙ |
Modified src/XMPPCallback.h from [aac49145b2] to [8400224fd5].
︙ | ︙ | |||
27 28 29 30 31 32 33 | #ifdef OF_HAVE_BLOCKS typedef void(^xmpp_callback_block_t)(XMPPConnection*, XMPPIQ*); #endif @interface XMPPCallback: OFObject { | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #ifdef OF_HAVE_BLOCKS typedef void(^xmpp_callback_block_t)(XMPPConnection*, XMPPIQ*); #endif @interface XMPPCallback: OFObject { id _target; SEL _selector; #ifdef OF_HAVE_BLOCKS xmpp_callback_block_t block; #endif } #ifdef OF_HAVE_BLOCKS + callbackWithBlock: (xmpp_callback_block_t)callback; |
︙ | ︙ |
Modified src/XMPPCallback.m from [2e45d71ec9] to [c850447926].
︙ | ︙ | |||
56 57 58 59 60 61 62 | } - initWithTarget: (id)target_ selector: (SEL)selector_ { self = [super init]; | | | | | | | | 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 | } - 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 [a0ab2db5e3] to [dc62e1592b].
︙ | ︙ | |||
149 150 151 152 153 154 155 | */ @interface XMPPConnection: OFObject #ifdef OF_HAVE_OPTONAL_PROTOCOLS <OFXMLParserDelegate, OFXMLElementBuilderDelegate> #endif { /// \cond internal | | | | | | | | | | | | | | | | | | | | | 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 | */ @interface XMPPConnection: OFObject #ifdef OF_HAVE_OPTONAL_PROTOCOLS <OFXMLParserDelegate, OFXMLElementBuilderDelegate> #endif { /// \cond internal id _socket; OFXMLParser *_parser, *_oldParser; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; OFString *_username, *_password, *_server, *_resource; OFString *_privateKeyFile, *_certificateFile; OFString *_domain, *_domainToASCII; XMPPJID *_JID; uint16_t _port; id <XMPPStorage> _dataStorage; OFString *_language; XMPPMulticastDelegate *_delegates; OFMutableDictionary *_callbacks; XMPPAuthenticator *_authModule; BOOL _streamOpen; BOOL _needsSession; BOOL _encryptionRequired, _encrypted; BOOL _supportsRosterVersioning; BOOL _supportsStreamManagement; unsigned int _lastID; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The username to use for authentication @property (copy) OFString *username; /// \brief The password to use for authentication |
︙ | ︙ | |||
199 200 201 202 203 204 205 | /// \brief The JID the server assigned to the connection after binding @property (copy, readonly) XMPPJID *JID; /// \brief The port to connect to @property uint16_t port; /// \brief An object for data storage, conforming to the XMPPStorage protocol @property (assign) id <XMPPStorage> dataStorage; /// \brief The socket used for the connection | | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | /// \brief The JID the server assigned to the connection after binding @property (copy, readonly) XMPPJID *JID; /// \brief The port to connect to @property uint16_t port; /// \brief An object for data storage, conforming to the XMPPStorage protocol @property (assign) id <XMPPStorage> dataStorage; /// \brief The socket used for the connection @property (readonly, retain) OFTCPSocket *socket; /// \brief Whether encryption is required @property BOOL encryptionRequired; /// \brief Whether the connection is encrypted @property (readonly) BOOL encrypted; /// \brief Whether roster versioning is supported @property (readonly) BOOL supportsRosterVersioning; /// \brief Whether stream management is supported |
︙ | ︙ |
Modified src/XMPPConnection.m from [7c6a173624] to [66ac2fa939].
︙ | ︙ | |||
123 124 125 126 127 128 129 | } - init { self = [super init]; @try { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 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 266 267 268 269 270 271 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 324 325 326 327 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 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 383 384 385 386 387 388 389 390 391 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 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 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 530 531 532 533 534 535 536 537 538 539 540 541 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 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | } - init { self = [super init]; @try { _port = 5222; _encrypted = NO; _streamOpen = NO; _delegates = [[XMPPMulticastDelegate alloc] init]; _callbacks = [[OFMutableDictionary alloc] init]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_socket release]; [_parser release]; [_elementBuilder release]; [_username release]; [_password release]; [_privateKeyFile release]; [_certificateFile release]; [_server release]; [_domain release]; [_resource release]; [_JID release]; [_delegates release]; [_callbacks release]; [_authModule release]; [super dealloc]; } - (void)setUsername: (OFString*)username { OFString *old = _username; if (username != nil) { char *node; Stringprep_rc rc; if ((rc = stringprep_profile([username UTF8String], &node, "SASLprep", 0)) != STRINGPREP_OK) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: self profile: @"SASLprep" string: username]; @try { _username = [[OFString alloc] initWithUTF8String: node]; } @finally { free(node); } } else _username = nil; [old release]; } - (OFString*)username { return [[_username copy] autorelease]; } - (void)setResource: (OFString*)resource { OFString *old = _resource; if (resource != nil) { char *res; Stringprep_rc rc; if ((rc = stringprep_profile([resource UTF8String], &res, "Resourceprep", 0)) != STRINGPREP_OK) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: self profile: @"Resourceprep" string: resource]; @try { _resource = [[OFString alloc] initWithUTF8String: res]; } @finally { free(res); } } else _resource = nil; [old release]; } - (OFString*)resource { return [[_resource copy] autorelease]; } - (void)setServer: (OFString*)server { OFString *old = _server; if (server != nil) _server = [self XMPP_IDNAToASCII: server]; else _server = nil; [old release]; } - (OFString*)server { return [[_server copy] autorelease]; } - (void)setDomain: (OFString*)domain_ { OFString *oldDomain = _domain; OFString *oldDomainToASCII = _domainToASCII; if (domain_ != nil) { char *srv; Stringprep_rc rc; if ((rc = stringprep_profile([domain_ UTF8String], &srv, "Nameprep", 0)) != STRINGPREP_OK) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: self profile: @"Nameprep" string: domain_]; @try { _domain = [[OFString alloc] initWithUTF8String: srv]; } @finally { free(srv); } _domainToASCII = [self XMPP_IDNAToASCII: _domain]; } else { _domain = nil; _domainToASCII = nil; } [oldDomain release]; [oldDomainToASCII release]; } - (OFString*)domain { return [[_domain copy] autorelease]; } - (void)setPassword: (OFString*)password { OFString *old = _password; if (password != nil) { char *pass; Stringprep_rc rc; if ((rc = stringprep_profile([password UTF8String], &pass, "SASLprep", 0)) != STRINGPREP_OK) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: self profile: @"SASLprep" string: password]; @try { _password = [[OFString alloc] initWithUTF8String: pass]; } @finally { free(pass); } } else _password = nil; [old release]; } - (OFString*)password { return [[_password copy] autorelease]; } - (void)setPrivateKeyFile: (OFString*)privateKeyFile { OF_SETTER(_privateKeyFile, privateKeyFile, YES, YES) } - (OFString*)privateKeyFile { OF_GETTER(_privateKeyFile, YES) } - (void)setCertificateFile: (OFString*)certificateFile { OF_SETTER(_certificateFile, certificateFile, YES, YES) } - (OFString*)certificateFile { OF_GETTER(_certificateFile, YES) } - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; XMPPSRVEntry *candidate = nil; XMPPSRVLookup *SRVLookup = nil; OFEnumerator *enumerator; if (_socket != nil) @throw [OFAlreadyConnectedException exceptionWithClass: [self class]]; _socket = [[OFTCPSocket alloc] init]; if (_server) [_socket connectToHost: _server port: _port]; else { @try { SRVLookup = [XMPPSRVLookup lookupWithDomain: _domainToASCII]; } @catch (id e) { } enumerator = [SRVLookup objectEnumerator]; /* Iterate over SRV records, if any */ if ((candidate = [enumerator nextObject]) != nil) { do { @try { [_socket connectToHost: [candidate target] port: [candidate port]]; break; } @catch (OFAddressTranslationFailedException *e) { } @catch (OFConnectionFailedException *e) { } } while ((candidate = [enumerator nextObject]) != nil); } else /* No SRV records -> fall back to A / AAAA record */ [_socket connectToHost: _domainToASCII port: _port]; } [self XMPP_startStream]; [pool release]; } - (void)handleConnection { char *buffer = [self allocMemoryWithSize: BUFFER_LENGTH]; [_socket asyncReadIntoBuffer: buffer length: BUFFER_LENGTH target: self selector: @selector(stream:didReadIntoBuffer:length: exception:)]; } - (void)asyncConnectAndHandle { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [[[[XMPPConnection_ConnectThread alloc] initWithSourceThread: [OFThread currentThread] connection: self] autorelease] start]; [pool release]; } - (BOOL)XMPP_parseBuffer: (const void*)buffer length: (size_t)length { if ([_socket isAtEndOfStream]) { [_delegates broadcastSelector: @selector(connectionWasClosed:) withObject: self]; return NO; } @try { [_parser parseBuffer: buffer length: length]; } @catch (OFMalformedXMLException *e) { [self XMPP_sendStreamError: @"bad-format" text: nil]; [self close]; return NO; } return YES; } - (void)parseBuffer: (const void*)buffer length: (size_t)length { [self XMPP_parseBuffer: buffer length: length]; [_oldParser release]; [_oldElementBuilder release]; _oldParser = nil; _oldElementBuilder = nil; } - (BOOL)stream: (OFStream*)stream didReadIntoBuffer: (char*)buffer length: (size_t)length exception: (OFException*)exception { if (exception != nil) { [_delegates broadcastSelector: @selector(connection: didThrowException:) withObject: self withObject: exception]; [self close]; return NO; } @try { if (![self XMPP_parseBuffer: buffer length: length]) return NO; } @catch (id e) { [_delegates broadcastSelector: @selector(connection: didThrowException:) withObject: self withObject: e]; [self close]; return NO; } if (_oldParser != nil || _oldElementBuilder != nil) { [_oldParser release]; [_oldElementBuilder release]; _oldParser = nil; _oldElementBuilder = nil; [_socket asyncReadIntoBuffer: buffer length: BUFFER_LENGTH target: self selector: @selector(stream: didReadIntoBuffer:length: exception:)]; return NO; } return YES; } - (OFTCPSocket*)socket { return [[_socket retain] autorelease]; } - (BOOL)encryptionRequired { return _encryptionRequired; } - (void)setEncryptionRequired: (BOOL)encryptionRequired { _encryptionRequired = encryptionRequired; } - (BOOL)encrypted { return _encrypted; } - (BOOL)streamOpen { return _streamOpen; } - (BOOL)supportsRosterVersioning { return _supportsRosterVersioning; } - (BOOL)supportsStreamManagement { return _supportsStreamManagement; } - (BOOL)checkCertificateAndGetReason: (OFString**)reason { X509Certificate *cert; OFDictionary *SANs; BOOL serviceSpecific = NO; @try { [_socket verifyPeerCertificate]; } @catch (SSLInvalidCertificateException *e) { if (reason != NULL) *reason = [[[e reason] copy] autorelease]; return NO; } cert = [_socket peerCertificate]; SANs = [cert subjectAlternativeName]; if ([[SANs objectForKey: @"otherName"] objectForKey: OID_SRVName] != nil || [SANs objectForKey: @"dNSName"] != nil || [SANs objectForKey: @"uniformResourceIdentifier"] != nil) serviceSpecific = YES; if ([cert hasSRVNameMatchingDomain: _domainToASCII service: @"xmpp-client"] || [cert hasDNSNameMatchingDomain: _domainToASCII]) return YES; if (!serviceSpecific && [cert hasCommonNameMatchingDomain: _domainToASCII]) return YES; return NO; } - (void)sendStanza: (OFXMLElement*)element { [_delegates broadcastSelector: @selector(connection:didSendElement:) withObject: self withObject: element]; [_socket writeString: [element XMLString]]; } - (void)sendIQ: (XMPPIQ*)iq callbackTarget: (id)target selector: (SEL)selector { OFAutoreleasePool *pool; XMPPCallback *callback; if (![iq ID]) [iq setID: [self generateStanzaID]]; pool = [[OFAutoreleasePool alloc] init]; callback = [XMPPCallback callbackWithTarget: target selector: selector]; [_callbacks setObject: callback forKey: [iq ID]]; [pool release]; [self sendStanza: iq]; } #ifdef OF_HAVE_BLOCKS - (void)sendIQ: (XMPPIQ*)iq callbackBlock: (xmpp_callback_block_t)block { OFAutoreleasePool *pool; XMPPCallback *callback; if (![iq ID]) [iq setID: [self generateStanzaID]]; pool = [[OFAutoreleasePool alloc] init]; callback = [XMPPCallback callbackWithBlock: block]; [_callbacks setObject: callback forKey: [iq ID]]; [pool release]; [self sendStanza: iq]; } #endif - (OFString*)generateStanzaID { return [OFString stringWithFormat: @"objxmpp_%u", _lastID++]; } - (void)parser: (OFXMLParser*)p didStartElement: (OFString*)name prefix: (OFString*)prefix namespace: (OFString*)ns attributes: (OFArray*)attributes { OFEnumerator *enumerator; OFXMLAttribute *attribute; if (![name isEqual: @"stream"]) { // 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 (![ns isEqual: XMPP_NS_STREAM]) { [self XMPP_sendStreamError: @"invalid-namespace" text: nil]; return; } enumerator = [attributes objectEnumerator]; while ((attribute = [enumerator nextObject]) != nil) { if ([[attribute name] isEqual: @"from"] && ![[attribute stringValue] isEqual: _domain]) { [self XMPP_sendStreamError: @"invalid-from" text: nil]; return; } if ([[attribute name] isEqual: @"version"] && ![[attribute stringValue] isEqual: @"1.0"]) { [self XMPP_sendStreamError: @"unsupported-version" text: nil]; return; } } [_parser setDelegate: _elementBuilder]; } - (void)elementBuilder: (OFXMLElementBuilder*)builder didBuildElement: (OFXMLElement*)element { /* Ignore whitespace elements */ if ([element name] == nil) return; [element setDefaultNamespace: XMPP_NS_CLIENT]; [element setPrefix: @"stream" forNamespace: XMPP_NS_STREAM]; [_delegates broadcastSelector: @selector(connection:didReceiveElement:) withObject: self withObject: element]; if ([[element namespace] isEqual: XMPP_NS_CLIENT]) [self XMPP_handleStanza: element]; if ([[element namespace] isEqual: XMPP_NS_STREAM]) [self XMPP_handleStream: element]; |
︙ | ︙ | |||
698 699 700 701 702 703 704 | } - (void)XMPP_startStream { OFString *langString = @""; /* Make sure we don't get any old events */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | } - (void)XMPP_startStream { OFString *langString = @""; /* Make sure we don't get any old events */ [_parser setDelegate: nil]; [_elementBuilder setDelegate: nil]; /* * We can't release them now, as we are currently inside them. Release * them the next time the parser returns. */ _oldParser = _parser; _oldElementBuilder = _elementBuilder; _parser = [[OFXMLParser alloc] init]; [_parser setDelegate: self]; _elementBuilder = [[XMPPXMLElementBuilder alloc] init]; [_elementBuilder setDelegate: self]; if (_language != nil) langString = [OFString stringWithFormat: @"xml:lang='%@' ", _language]; [_socket writeFormat: @"<?xml version='1.0'?>\n" @"<stream:stream to='%@' " @"xmlns='" XMPP_NS_CLIENT @"' " @"xmlns:stream='" XMPP_NS_STREAM @"' %@" @"version='1.0'>", _domain, langString]; _streamOpen = YES; } - (void)close { if (_streamOpen) [_socket writeString: @"</stream:stream>"]; [_oldParser release]; _oldParser = nil; [_oldElementBuilder release]; _oldElementBuilder = nil; [_authModule release]; _authModule = nil; [_socket release]; _socket = nil; [_JID release]; _JID = nil; _streamOpen = _needsSession = _encrypted = NO; _supportsRosterVersioning = _supportsStreamManagement = NO; _lastID = 0; } - (void)XMPP_handleStanza: (OFXMLElement*)element { if ([[element name] isEqual: @"iq"]) { [self XMPP_handleIQ: [XMPPIQ stanzaWithElement: element]]; return; |
︙ | ︙ | |||
782 783 784 785 786 787 788 | [self XMPP_handleFeatures: element]; return; } if ([[element name] isEqual: @"error"]) { OFString *condition, *reason; [self close]; | | | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 | [self XMPP_handleFeatures: element]; return; } if ([[element name] isEqual: @"error"]) { OFString *condition, *reason; [self close]; [_socket close]; // Remote has already closed his stream if ([element elementForName: @"bad-format" namespace: XMPP_NS_XMPP_STREAM]) condition = @"bad-format"; else if ([element elementForName: @"bad-namespace-prefix" namespace: XMPP_NS_XMPP_STREAM]) condition = @"bad-namespace-prefix"; |
︙ | ︙ | |||
883 884 885 886 887 888 889 | - (void)XMPP_handleTLS: (OFXMLElement*)element { if ([[element name] isEqual: @"proceed"]) { /* FIXME: Catch errors here */ SSLSocket *newSock; | | | | | | | | | | | | | | | | | | | 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 | - (void)XMPP_handleTLS: (OFXMLElement*)element { if ([[element name] isEqual: @"proceed"]) { /* FIXME: Catch errors here */ SSLSocket *newSock; [_delegates broadcastSelector: @selector( connectionWillUpgradeToTLS:) withObject: self]; newSock = [[SSLSocket alloc] initWithSocket: _socket privateKeyFile: _privateKeyFile certificateFile: _certificateFile]; [_socket release]; _socket = newSock; _encrypted = YES; [_delegates broadcastSelector: @selector( connectionDidUpgradeToTLS:) withObject: self]; /* Stream restart */ [self XMPP_startStream]; return; } if ([[element name] isEqual: @"failure"]) /* TODO: Find/create an exception to throw here */ @throw [OFException exceptionWithClass: [self class]]; assert(0); } - (void)XMPP_handleSASL: (OFXMLElement*)element { if ([[element name] isEqual: @"challenge"]) { OFXMLElement *responseTag; OFDataArray *challenge = [OFDataArray dataArrayWithBase64EncodedString: [element stringValue]]; OFDataArray *response = [_authModule continueWithData: challenge]; responseTag = [OFXMLElement elementWithName: @"response" namespace: XMPP_NS_SASL]; if (response) { if ([response count] == 0) [responseTag setStringValue: @"="]; else [responseTag setStringValue: [response stringByBase64Encoding]]; } [self sendStanza: responseTag]; return; } if ([[element name] isEqual: @"success"]) { [_authModule continueWithData: [OFDataArray dataArrayWithBase64EncodedString: [element stringValue]]]; [_delegates broadcastSelector: @selector( connectionWasAuthenticated:) withObject: self]; /* Stream restart */ [self XMPP_startStream]; return; } |
︙ | ︙ | |||
966 967 968 969 970 971 972 | } - (void)XMPP_handleIQ: (XMPPIQ*)iq { BOOL handled = NO; XMPPCallback *callback; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 | } - (void)XMPP_handleIQ: (XMPPIQ*)iq { BOOL handled = NO; XMPPCallback *callback; if ((callback = [_callbacks objectForKey: [iq ID]])) { [callback runWithIQ: iq connection: self]; [_callbacks removeObjectForKey: [iq ID]]; return; } handled = [_delegates broadcastSelector: @selector( connection:didReceiveIQ:) withObject: self withObject: iq]; if (!handled && ![[iq type] isEqual: @"error"] && ![[iq type] isEqual: @"result"]) { [self sendStanza: [iq errorIQWithType: @"cancel" condition: @"service-unavailable"]]; } } - (void)XMPP_handleMessage: (XMPPMessage*)message { [_delegates broadcastSelector: @selector(connection:didReceiveMessage:) withObject: self withObject: message]; } - (void)XMPP_handlePresence: (XMPPPresence*)presence { [_delegates broadcastSelector: @selector(connection:didReceivePresence:) withObject: self withObject: presence]; } - (void)XMPP_handleFeatures: (OFXMLElement*)element { OFXMLElement *startTLS = [element elementForName: @"starttls" namespace: XMPP_NS_STARTTLS]; OFXMLElement *bind = [element elementForName: @"bind" namespace: XMPP_NS_BIND]; OFXMLElement *session = [element elementForName: @"session" namespace: XMPP_NS_SESSION]; OFXMLElement *mechs = [element elementForName: @"mechanisms" namespace: XMPP_NS_SASL]; OFMutableSet *mechanisms = [OFMutableSet set]; if (!_encrypted && startTLS != nil) { [self sendStanza: [OFXMLElement elementWithName: @"starttls" namespace: XMPP_NS_STARTTLS]]; return; } if (_encryptionRequired && !_encrypted) /* TODO: Find/create an exception to throw here */ @throw [OFException exceptionWithClass: [self class]]; if ([element elementForName: @"ver" namespace: XMPP_NS_ROSTERVER] != nil) _supportsRosterVersioning = YES; if ([element elementForName: @"sm" namespace: XMPP_NS_SM] != nil) _supportsStreamManagement = YES; if (mechs != nil) { OFEnumerator *enumerator; OFXMLElement *mech; enumerator = [[mechs children] objectEnumerator]; while ((mech = [enumerator nextObject]) != nil) [mechanisms addObject: [mech stringValue]]; if (_privateKeyFile && _certificateFile && [mechanisms containsObject: @"EXTERNAL"]) { _authModule = [[XMPPEXTERNALAuth alloc] init]; [self XMPP_sendAuth: @"EXTERNAL"]; return; } if ([mechanisms containsObject: @"SCRAM-SHA-1-PLUS"]) { _authModule = [[XMPPSCRAMAuth alloc] initWithAuthcid: _username password: _password connection: self hash: [OFSHA1Hash class] plusAvailable: YES]; [self XMPP_sendAuth: @"SCRAM-SHA-1-PLUS"]; return; } if ([mechanisms containsObject: @"SCRAM-SHA-1"]) { _authModule = [[XMPPSCRAMAuth alloc] initWithAuthcid: _username password: _password connection: self hash: [OFSHA1Hash class] plusAvailable: NO]; [self XMPP_sendAuth: @"SCRAM-SHA-1"]; return; } if ([mechanisms containsObject: @"PLAIN"] && _encrypted) { _authModule = [[XMPPPLAINAuth alloc] initWithAuthcid: _username password: _password]; [self XMPP_sendAuth: @"PLAIN"]; return; } assert(0); } if (session != nil) _needsSession = YES; if (bind != nil) { [self XMPP_sendResourceBind]; return; } assert(0); } - (void)XMPP_sendAuth: (OFString*)authName { OFXMLElement *authTag; OFDataArray *initialMessage = [_authModule initialMessage]; authTag = [OFXMLElement elementWithName: @"auth" namespace: XMPP_NS_SASL]; [authTag addAttributeWithName: @"mechanism" stringValue: authName]; if (initialMessage) { if ([initialMessage count] == 0) [authTag setStringValue: @"="]; else [authTag setStringValue: [initialMessage stringByBase64Encoding]]; } [self sendStanza: authTag]; } - (void)XMPP_sendResourceBind { XMPPIQ *IQ; OFXMLElement *bind; IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]]; bind = [OFXMLElement elementWithName: @"bind" namespace: XMPP_NS_BIND]; if (_resource != nil) [bind addChild: [OFXMLElement elementWithName: @"resource" namespace: XMPP_NS_BIND 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: XMPP_NS_STREAM]; [error setPrefix: @"stream" forNamespace: XMPP_NS_STREAM]; [error addChild: [OFXMLElement elementWithName: condition namespace: XMPP_NS_XMPP_STREAM]]; if (text) [error addChild: [OFXMLElement elementWithName: @"text" namespace: XMPP_NS_XMPP_STREAM stringValue: text]]; [_parser setDelegate: nil]; [self sendStanza: error]; [self close]; } - (void)XMPP_handleResourceBindForConnection: (XMPPConnection*)connection IQ: (XMPPIQ*)iq { OFXMLElement *bindElement; OFXMLElement *jidElement; assert([[iq type] isEqual: @"result"]); bindElement = [iq elementForName: @"bind" namespace: XMPP_NS_BIND]; assert(bindElement != nil); jidElement = [bindElement elementForName: @"jid" namespace: XMPP_NS_BIND]; _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; iq = [XMPPIQ IQWithType: @"set" |
︙ | ︙ | |||
1199 1200 1201 1202 1203 1204 1205 | - (void)XMPP_handleSessionForConnection: (XMPPConnection*)connection IQ: (XMPPIQ*)iq { if (![[iq type] isEqual: @"result"]) assert(0); | | | | | 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 | - (void)XMPP_handleSessionForConnection: (XMPPConnection*)connection IQ: (XMPPIQ*)iq { if (![[iq type] isEqual: @"result"]) assert(0); [_delegates broadcastSelector: @selector(connection:wasBoundToJID:) withObject: self withObject: _JID]; } - (OFString*)XMPP_IDNAToASCII: (OFString*)domain_ { OFString *ret; char *cDomain; Idna_rc rc; |
︙ | ︙ | |||
1229 1230 1231 1232 1233 1234 1235 | } return ret; } - (XMPPJID*)JID { | | | | | | | | | | | | | | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 | } return ret; } - (XMPPJID*)JID { return [[_JID copy] autorelease]; } - (void)setPort: (uint16_t)port { _port = port; } - (uint16_t)port { return _port; } - (void)setDataStorage: (id <XMPPStorage>)dataStorage { if (_streamOpen) @throw [OFInvalidArgumentException exceptionWithClass: [self class]]; _dataStorage = dataStorage; } - (id <XMPPStorage>)dataStorage { return _dataStorage; } - (void)setLanguage: (OFString*)language { OF_SETTER(_language, language, YES, YES) } - (OFString*)language { OF_GETTER(_language, YES) } - (void)addDelegate: (id <XMPPConnectionDelegate>)delegate { [_delegates addDelegate: delegate]; } - (void)removeDelegate: (id <XMPPConnectionDelegate>)delegate { [_delegates removeDelegate: delegate]; } - (XMPPMulticastDelegate*)XMPP_delegates { return _delegates; } @end |
Modified src/XMPPContact.h from [e36b41f1a9] to [9b2c9af3b3].
︙ | ︙ | |||
30 31 32 33 34 35 36 | /** * \brief A class describing a contact tracked by a XMPPContactManager */ @interface XMPPContact: OFObject { /// \cond internal | | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /** * \brief A class describing a contact tracked by a XMPPContactManager */ @interface XMPPContact: OFObject { /// \cond internal XMPPRosterItem *_rosterItem; OFMutableDictionary *_presences; XMPPJID *_lockedOnJID; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The XMPPRosterItem corresponding to this contact @property (readonly) XMPPRosterItem *rosterItem; /// \brief The XMPPPresences of this contact with the resources as keys @property (readonly) OFDictionary *presences; |
︙ | ︙ |
Modified src/XMPPContact.m from [2a7d3a0187] to [fc587e181a].
︙ | ︙ | |||
26 27 28 29 30 31 32 | @implementation XMPPContact - init { self = [super init]; @try { | | | | | | | | | | | | | | | | | | | | | 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | @implementation XMPPContact - init { self = [super init]; @try { _presences = [[OFMutableDictionary alloc] init]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_presences release]; [super dealloc]; } - (XMPPRosterItem*)rosterItem { OF_GETTER(_rosterItem, YES); } - (OFDictionary*)presences { OF_GETTER(_presences, YES); } - (void)sendMessage: (XMPPMessage*)message connection: (XMPPConnection*)connection { if (_lockedOnJID == nil) [message setTo: [_rosterItem JID]]; else [message setTo: _lockedOnJID]; [connection sendStanza: message]; } - (void)XMPP_setRosterItem: (XMPPRosterItem*)rosterItem { OF_SETTER(_rosterItem, rosterItem, YES, 0); } - (void)XMPP_setPresence: (XMPPPresence*)presence resource: (OFString*)resource { if (resource != nil) [_presences setObject: presence forKey: resource]; else [_presences setObject: presence forKey: @""]; OF_SETTER(_lockedOnJID, nil, YES, 0); } - (void)XMPP_removePresenceForResource: (OFString*)resource { if (resource != nil) { [_presences removeObjectForKey: resource]; } else { [_presences release]; _presences = [[OFMutableDictionary alloc] init]; } OF_SETTER(_lockedOnJID, nil, YES, 0); } - (void)XMPP_setLockedOnJID: (XMPPJID*)JID; { OF_SETTER(_lockedOnJID, JID, YES, 0); } @end |
Modified src/XMPPContactManager.h from [f32fa83767] to [a7556ed65c].
︙ | ︙ | |||
94 95 96 97 98 99 100 | */ @interface XMPPContactManager: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS <XMPPConnectionDelegate, XMPPRosterDelegate> #endif { /// \cond internal | | | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | */ @interface XMPPContactManager: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS <XMPPConnectionDelegate, XMPPRosterDelegate> #endif { /// \cond internal OFMutableDictionary *_contacts; XMPPConnection *_connection; XMPPRoster *_roster; XMPPMulticastDelegate *_delegates; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The tracked contacts, with their bare JID as key @property (readonly) OFDictionary *contacts; #endif |
︙ | ︙ |
Modified src/XMPPContactManager.m from [c51574c9fb] to [3fde85a014].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @implementation XMPPContactManager - initWithConnection: (XMPPConnection*)connection_ roster: (XMPPRoster*)roster_ { self = [super init]; @try { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 | @implementation XMPPContactManager - initWithConnection: (XMPPConnection*)connection_ roster: (XMPPRoster*)roster_ { self = [super init]; @try { _connection = connection_; [_connection addDelegate: self]; _roster = roster_; [_roster addDelegate: self]; _contacts = [[OFMutableDictionary alloc] init]; _delegates = [[XMPPMulticastDelegate alloc] init]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_connection removeDelegate: self]; [_roster removeDelegate: self]; [_delegates release]; [_contacts release]; [super dealloc]; } - (void)addDelegate: (id <XMPPConnectionDelegate>)delegate { [_delegates addDelegate: delegate]; } - (void)removeDelegate: (id <XMPPConnectionDelegate>)delegate { [_delegates removeDelegate: delegate]; } - (OFDictionary*)contacts { OF_GETTER(_contacts, YES); } - (void)rosterWasReceived: (XMPPRoster*)roster_ { OFEnumerator *contactEnumerator; XMPPContact *contact; OFDictionary *rosterItems; OFEnumerator *rosterItemEnumerator; OFString *bareJID; contactEnumerator = [_contacts objectEnumerator]; while ((contact = [contactEnumerator nextObject]) != nil) { [_delegates broadcastSelector: @selector(contactManager: didRemoveContact:) withObject: self withObject: contact]; } [_contacts release]; _contacts = [[OFMutableDictionary alloc] init]; rosterItems = [roster_ rosterItems]; rosterItemEnumerator = [rosterItems keyEnumerator]; while ((bareJID = [rosterItemEnumerator nextObject]) != nil) { contact = [[XMPPContact new] autorelease]; [contact XMPP_setRosterItem: [rosterItems objectForKey: bareJID]]; [_contacts setObject: contact forKey: bareJID]; [_delegates broadcastSelector: @selector(contactManager: didAddContact:) withObject: self withObject: contact]; } } - (void)roster: (XMPPRoster*)roster didReceiveRosterItem: (XMPPRosterItem*)rosterItem { XMPPContact *contact; OFString *bareJID = [[rosterItem JID] bareJID]; contact = [_contacts objectForKey: bareJID]; if ([[rosterItem subscription] isEqual: @"remove"]) { [_contacts removeObjectForKey: bareJID]; if (contact != nil) [_delegates broadcastSelector: @selector(contactManager: didRemoveContact:) withObject: self withObject: contact]; return; } if (contact == nil) { contact = [[XMPPContact new] autorelease]; [contact XMPP_setRosterItem: rosterItem]; [_contacts setObject: contact forKey: bareJID]; [_delegates broadcastSelector: @selector(contactManager: didAddContact:) withObject: self withObject: contact]; } else { [_delegates broadcastSelector: @selector(contact: willUpdateWithRosterItem:) withObject: contact withObject: rosterItem]; [contact XMPP_setRosterItem: rosterItem]; } } - (void)connection: (XMPPConnection*)connection didReceivePresence: (XMPPPresence*)presence { XMPPJID *JID = [presence from]; XMPPContact *contact = [_contacts objectForKey: [JID bareJID]]; if (contact == nil) return; // We only care for available and unavailable here, not subscriptions if ([[presence type] isEqual: @"available"]) { [contact XMPP_setPresence: presence resource: [JID resource]]; [_delegates broadcastSelector: @selector(contact: didSendPresence:) withObject: contact withObject: presence]; } else if ([[presence type] isEqual: @"unavailable"]) { [contact XMPP_removePresenceForResource: [JID resource]]; [_delegates broadcastSelector: @selector(contact: didSendPresence:) withObject: contact withObject: presence]; } } - (void)connection: (XMPPConnection*)connection didReceiveMessage: (XMPPMessage*)message { XMPPJID *JID = [message from]; XMPPContact *contact = [_contacts objectForKey: [JID bareJID]]; if (contact == nil) return; [contact XMPP_setLockedOnJID: JID]; [_delegates broadcastSelector: @selector(contact:didSendMessage:) withObject: contact withObject: message]; } @end |
Modified src/XMPPEXTERNALAuth.m from [43238a3887] to [d46bce778e].
︙ | ︙ | |||
29 30 31 32 33 34 35 | @implementation XMPPEXTERNALAuth: XMPPAuthenticator + EXTERNALAuth { return [[[self alloc] initWithAuthcid: nil password: nil] autorelease]; } | | | | | | 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 | @implementation XMPPEXTERNALAuth: XMPPAuthenticator + EXTERNALAuth { return [[[self alloc] initWithAuthcid: nil password: nil] autorelease]; } + EXTERNALAuthWithAuthzid: (OFString*)authzid { return [[[self alloc] initWithAuthzid: authzid authcid: nil password: nil] autorelease]; } - (OFDataArray*)initialMessage { OFDataArray *message = [OFDataArray dataArray]; /* authzid */ if (_authzid) [message addItem: _authzid]; return message; } @end |
Modified src/XMPPExceptions.h from [32c743040e] to [fe124580d4].
︙ | ︙ | |||
27 28 29 30 31 32 33 | /** * \brief A base class for XMPP related exceptions */ @interface XMPPException: OFException { /// \cond internal | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** * \brief A base class for XMPP related exceptions */ @interface XMPPException: OFException { /// \cond internal XMPPConnection *_connection; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The connection the exception relates to @property (readonly, assign) XMPPConnection *connection; #endif |
︙ | ︙ |
Modified src/XMPPExceptions.m from [8255027a48] to [b762333688].
︙ | ︙ | |||
45 46 47 48 49 50 51 | - initWithClass: (Class)class_ connection: (XMPPConnection*)conn { self = [super initWithClass: class_]; @try { | | | | | | | | | | 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 | - initWithClass: (Class)class_ connection: (XMPPConnection*)conn { self = [super initWithClass: class_]; @try { _connection = [conn retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_connection release]; [super dealloc]; } - (OFString*)description { if (_description != nil) return _description; _description = [[OFString alloc] initWithFormat: @"An exception occurred in class %@!", _inClass]; return _description; } - (XMPPConnection*)connection { return _connection; } @end @implementation XMPPStreamErrorException + exceptionWithClass: (Class)class_ connection: (XMPPConnection*)conn condition: (OFString*)condition_ |
︙ | ︙ | |||
128 129 130 131 132 133 134 | [reason release]; [super dealloc]; } - (OFString*)description { | | | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | [reason release]; [super dealloc]; } - (OFString*)description { if (_description != nil) return _description; _description = [[OFString alloc] initWithFormat: @"Got stream error: %@. Reason: %@!", condition, reason]; return _description; } - (OFString*)condition { return condition; } |
︙ | ︙ | |||
198 199 200 201 202 203 204 | [string release]; [super dealloc]; } - (OFString*)description { | | | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | [string release]; [super dealloc]; } - (OFString*)description { if (_description != nil) return _description; _description = [[OFString alloc] initWithFormat: @"Stringprep with profile %@ failed on string '%@'!", profile, string]; return _description; } - (OFString*)profile { return profile; } |
︙ | ︙ | |||
269 270 271 272 273 274 275 | [string release]; [super dealloc]; } - (OFString*)description { | | | | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | [string release]; [super dealloc]; } - (OFString*)description { if (_description != nil) return _description; _description = [[OFString alloc] initWithFormat: @"IDNA operation %@ failed on string '%@'!", operation, string]; return _description; } - (OFString*)operation { return operation; } |
︙ | ︙ | |||
334 335 336 337 338 339 340 | [reason release]; [super dealloc]; } - (OFString*)description { | | | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | [reason release]; [super dealloc]; } - (OFString*)description { if (_description != nil) return _description; _description = [[OFString alloc] initWithFormat: @"Authentication failed. Reason: %@!", reason]; return _description; } - (OFString*)reason { return reason; } @end |
Modified src/XMPPIQ.m from [951ee83820] to [56a714ea1b].
︙ | ︙ | |||
25 26 27 28 29 30 31 | # include "config.h" #endif #import "namespaces.h" #import "XMPPIQ.h" @implementation XMPPIQ | | | | | | | | | | | | 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 | # include "config.h" #endif #import "namespaces.h" #import "XMPPIQ.h" @implementation XMPPIQ + IQWithType: (OFString*)type ID: (OFString*)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - 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 exceptionWithClass: [self class] selector: _cmd]; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ |
Modified src/XMPPJID.h from [17db6817a9] to [3705738b93].
︙ | ︙ | |||
25 26 27 28 29 30 31 | /** * \brief A class for easy handling of JIDs. */ @interface XMPPJID: OFObject <OFCopying> { /// \cond internal | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** * \brief A class for easy handling of JIDs. */ @interface XMPPJID: OFObject <OFCopying> { /// \cond internal OFString *_node; OFString *_domain; OFString *_resource; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The JID's localpart @property (copy) OFString *node; /// \brief The JID's domainpart |
︙ | ︙ | |||
50 51 52 53 54 55 56 | * \return A new autoreleased XMPPJID */ + JID; /** * \brief Creates a new autoreleased XMPPJID from a string. * | | | | | 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 | * \return A new autoreleased XMPPJID */ + JID; /** * \brief Creates a new autoreleased XMPPJID from a string. * * \param string The string to parse into a JID object * \return A new autoreleased XMPPJID */ + JIDWithString: (OFString*)string; /** * \brief Initializes an already allocated XMPPJID with a string. * * \param str The string to parse into a JID object * \return A initialized XMPPJID */ - initWithString: (OFString*)string; /** * \brief Returns the bare JID. * * \return An OFString containing the bare JID */ - (OFString*)bareJID; |
︙ | ︙ |
Modified src/XMPPJID.m from [e0809705cc] to [2b87940ac6].
︙ | ︙ | |||
34 35 36 37 38 39 40 | @implementation XMPPJID + JID { return [[[self alloc] init] autorelease]; } | | | | | | | > | | | | | > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | 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 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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | @implementation XMPPJID + JID { return [[[self alloc] init] autorelease]; } + JIDWithString: (OFString*)string { return [[[self alloc] initWithString: string] autorelease]; } - initWithString: (OFString*)string { size_t nodesep, resourcesep; self = [super init]; if (string == nil) { [self release]; return nil; } nodesep = [string rangeOfString: @"@"].location; resourcesep = [string rangeOfString: @"/"].location; if (nodesep == SIZE_MAX) [self setNode: nil]; else [self setNode: [string substringWithRange: of_range(0, nodesep)]]; if (resourcesep == SIZE_MAX) { [self setResource: nil]; resourcesep = [string length]; } else { of_range_t range = of_range(resourcesep + 1, [string length] - resourcesep - 1); [self setResource: [string substringWithRange: range]]; } [self setDomain: [string substringWithRange: of_range(nodesep + 1, resourcesep - nodesep - 1)]]; return self; } - (void)dealloc { [_node release]; [_domain release]; [_resource release]; [super dealloc]; } - copy { XMPPJID *new = [[XMPPJID alloc] init]; @try { new->_node = [_node copy]; new->_domain = [_domain copy]; new->_resource = [_resource copy]; } @catch (id e) { [new release]; @throw e; } return new; } - (void)setNode: (OFString*)node { OFString *old = _node; char *nodepart; Stringprep_rc rc; if (node == nil) { [old release]; _node = nil; return; } if (((rc = stringprep_profile([node UTF8String], &nodepart, "Nodeprep", 0)) != STRINGPREP_OK) || (nodepart[0] == '\0') || (strlen(nodepart) > 1023)) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: nil profile: @"Nodeprep" string: node]; @try { _node = [[OFString alloc] initWithUTF8String: nodepart]; } @finally { free(nodepart); } [old release]; } - (OFString*)node { return [[_node copy] autorelease]; } - (void)setDomain: (OFString*)domain { OFString *old = _domain; char *srv; Stringprep_rc rc; if (((rc = stringprep_profile([domain UTF8String], &srv, "Nameprep", 0)) != STRINGPREP_OK) || (srv[0] == '\0') || (strlen(srv) > 1023)) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: nil profile: @"Nameprep" string: domain]; @try { _domain = [[OFString alloc] initWithUTF8String: srv]; } @finally { free(srv); } [old release]; } - (OFString*)domain { return [[_domain copy] autorelease]; } - (void)setResource: (OFString*)resource { OFString *old = _resource; char *res; Stringprep_rc rc; if (resource == nil) { [old release]; _resource = nil; return; } if (((rc = stringprep_profile([resource UTF8String], &res, "Resourceprep", 0)) != STRINGPREP_OK) || (res[0] == '\0') || (strlen(res) > 1023)) @throw [XMPPStringPrepFailedException exceptionWithClass: [self class] connection: nil profile: @"Resourceprep" string: resource]; @try { _resource = [[OFString alloc] initWithUTF8String: res]; } @finally { free(res); } [old release]; } - (OFString*)resource { return [[_resource copy] autorelease]; } - (OFString*)bareJID { if (_node != nil) return [OFString stringWithFormat: @"%@@%@", _node, _domain]; else return [OFString stringWithFormat: @"%@", _domain]; } - (OFString*)fullJID { /* If we don't have a resource, the full JID is equal to the bare JID */ if (_resource == nil) return [self bareJID]; if (_node != nil) return [OFString stringWithFormat: @"%@@%@/%@", _node, _domain, _resource]; else return [OFString stringWithFormat: @"%@/%@", _domain, _resource]; } - (OFString*)description { return [self fullJID]; } - (BOOL)isEqual: (id)object { XMPPJID *JID; if (object == self) return YES; if (![object isKindOfClass: [XMPPJID class]]) return NO; JID = object; if ([_node isEqual: JID->_node] && [_domain isEqual: JID->_domain] && [_resource isEqual: JID->_resource]) return YES; return NO; } - (uint32_t) hash { |
︙ | ︙ |
Modified src/XMPPJSONFileStorage.h from [7f0183b9e7] to [5505b46086].
︙ | ︙ | |||
24 25 26 27 28 29 30 | #import "XMPPStorage.h" @class OFMutableDictionary; @interface XMPPJSONFileStorage: OFObject <XMPPStorage> { | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 | #import "XMPPStorage.h" @class OFMutableDictionary; @interface XMPPJSONFileStorage: OFObject <XMPPStorage> { OFString *_file; OFMutableDictionary *_data; } - initWithFile: (OFString*)file; @end |
Modified src/XMPPJSONFileStorage.m from [f859e69a55] to [0ded529f90].
︙ | ︙ | |||
46 47 48 49 50 51 52 | - initWithFile: (OFString*)file_ { self = [super init]; @try { OFAutoreleasePool *pool = [OFAutoreleasePool new]; | | | | | | | | | | 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 90 91 92 93 94 | - initWithFile: (OFString*)file_ { self = [super init]; @try { OFAutoreleasePool *pool = [OFAutoreleasePool new]; _file = [file_ copy]; @try { _data = [[[OFString stringWithContentsOfFile: _file] JSONValue] retain]; } @catch (id e) { _data = [OFMutableDictionary new]; } [pool release]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_file release]; [_data release]; [super dealloc]; } - (void)save { [[_data JSONRepresentation] writeToFile: _file]; } - (void)XMPP_setObject: (id)object forPath: (OFString*)path { OFArray *pathComponents = [path componentsSeparatedByString: @"."]; OFMutableDictionary *iter = _data; OFEnumerator *enumerator = [pathComponents objectEnumerator]; OFString *component; size_t i = 0, components = [pathComponents count]; while ((component = [enumerator nextObject]) != nil) { if (i++ == components - 1) continue; |
︙ | ︙ | |||
112 113 114 115 116 117 118 | } - (id)XMPP_objectForPath: (OFString*)path { OFArray *pathComponents = [path componentsSeparatedByString: @"."]; OFEnumerator *enumerator = [pathComponents objectEnumerator]; OFString *component; | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | } - (id)XMPP_objectForPath: (OFString*)path { OFArray *pathComponents = [path componentsSeparatedByString: @"."]; OFEnumerator *enumerator = [pathComponents objectEnumerator]; OFString *component; id object = _data; while ((component = [enumerator nextObject]) != nil) object = [object objectForKey: component]; return object; } |
︙ | ︙ |
Modified src/XMPPMessage.m from [8346a27c76] to [e5cbaf0e95].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @implementation XMPPMessage + message { return [[[self alloc] init] autorelease]; } | | | | | | | | | | | | | | | | | | 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 | @implementation XMPPMessage + message { return [[[self alloc] init] autorelease]; } + messageWithID: (OFString*)ID { return [[[self alloc] initWithID: ID] autorelease]; } + messageWithType: (OFString*)type { return [[[self alloc] initWithType: type] autorelease]; } + messageWithType: (OFString*)type ID: (OFString*)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - init { return [self initWithType: nil ID: nil]; } - initWithID: (OFString*)ID { return [self initWithType: nil ID: ID]; } - initWithType: (OFString*)type { return [self initWithType: type ID: nil]; } - initWithType: (OFString*)type ID: (OFString*)ID { return [super initWithName: @"message" type: type ID: ID]; } - (void)setBody: (OFString*)body { OFXMLElement *oldBody = [self elementForName: @"body" namespace: XMPP_NS_CLIENT]; |
︙ | ︙ |
Modified src/XMPPMulticastDelegate.h from [45287c4c88] to [3d08dfb767].
︙ | ︙ | |||
26 27 28 29 30 31 32 | /** * \brief A class to provide multiple delegates in a single class */ @interface XMPPMulticastDelegate: OFObject { /// \cond internal | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /** * \brief A class to provide multiple delegates in a single class */ @interface XMPPMulticastDelegate: OFObject { /// \cond internal OFDataArray *_delegates; /// \endcond } /** * \brief Adds a delegate which should receive the broadcasts. * * \param delegate The delegate to add |
︙ | ︙ |
Modified src/XMPPMulticastDelegate.m from [0af7f26680] to [0321dd1eed].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @implementation XMPPMulticastDelegate - init { self = [super init]; @try { | | | | | | | | | | | | | | | | | | | 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | @implementation XMPPMulticastDelegate - init { self = [super init]; @try { _delegates = [[OFDataArray alloc] initWithItemSize: sizeof(id)]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_delegates release]; [super dealloc]; } - (void)addDelegate: (id)delegate { [_delegates addItem: &delegate]; } - (void)removeDelegate: (id)delegate { id *items = [_delegates items]; size_t i, count = [_delegates count]; for (i = 0; i < count; i++) { if (items[i] == delegate) { [_delegates removeItemAtIndex: i]; return; } } } - (BOOL)broadcastSelector: (SEL)selector withObject: (id)object { id *items = [_delegates items]; size_t i, count = [_delegates count]; BOOL handled = NO; for (i = 0; i < count; i++) { if (![items[i] respondsToSelector: selector]) continue; BOOL (*imp)(id, SEL, id) = (BOOL(*)(id, SEL, id)) [items[i] methodForSelector: selector]; handled |= imp(items[i], selector, object); } return handled; } - (BOOL)broadcastSelector: (SEL)selector withObject: (id)object1 withObject: (id)object2 { id *items = [_delegates items]; size_t i, count = [_delegates count]; BOOL handled = NO; for (i = 0; i < count; i++) { if (![items[i] respondsToSelector: selector]) continue; BOOL (*imp)(id, SEL, id, id) = (BOOL(*)(id, SEL, id, id)) [items[i] methodForSelector: selector]; handled |= imp(items[i], selector, object1, object2); } return handled; } @end |
Modified src/XMPPPLAINAuth.m from [ea90fec7bf] to [9b4707618f].
︙ | ︙ | |||
45 46 47 48 49 50 51 | } - (OFDataArray*)initialMessage { OFDataArray *message = [OFDataArray dataArray]; /* authzid */ | | | | | | | | 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 | } - (OFDataArray*)initialMessage { OFDataArray *message = [OFDataArray dataArray]; /* authzid */ if (_authzid) [message addItem: _authzid]; /* separator */ [message addItem: ""]; /* authcid */ [message addItems: [_authcid UTF8String] count: [_authcid UTF8StringLength]]; /* separator */ [message addItem: ""]; /* passwd */ [message addItems: [_password UTF8String] count: [_password UTF8StringLength]]; return message; } @end |
Modified src/XMPPPresence.h from [cd5efafbb3] to [64aa77b770].
︙ | ︙ | |||
25 26 27 28 29 30 31 | /** * \brief A class describing a presence stanza. */ @interface XMPPPresence: XMPPStanza <OFComparing> { /// \cond internal | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** * \brief A class describing a presence stanza. */ @interface XMPPPresence: XMPPStanza <OFComparing> { /// \cond internal OFString *_status; OFString *_show; OFNumber *_priority; /// \endcond } #ifdef OF_HAVE_PROPERTIES @property (copy) OFString *status; @property (copy) OFString *show; @property (copy) OFNumber *priority; #endif |
︙ | ︙ |
Modified src/XMPPPresence.m from [2470b625ea] to [cd7ef53266].
︙ | ︙ | |||
44 45 46 47 48 49 50 | @implementation XMPPPresence + presence { return [[[self alloc] init] autorelease]; } | | | | | | | | | | | | | | | | | | 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 90 91 92 93 94 95 96 97 98 | @implementation XMPPPresence + presence { return [[[self alloc] init] autorelease]; } + presenceWithID: (OFString*)ID { return [[[self alloc] initWithID: ID] autorelease]; } + presenceWithType: (OFString*)type { return [[[self alloc] initWithType: type] autorelease]; } + presenceWithType: (OFString*)type ID: (OFString*)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - init { return [self initWithType: nil ID: nil]; } - initWithID: (OFString*)ID { return [self initWithType: nil ID: ID]; } - initWithType: (OFString*)type { return [self initWithType: type ID: nil]; } - initWithType: (OFString*)type ID: (OFString*)ID { return [super initWithName: @"presence" type: type ID: ID]; } - initWithElement: (OFXMLElement*)element { self = [super initWithElement: element]; @try { |
︙ | ︙ | |||
118 119 120 121 122 123 124 | return self; } - (void)dealloc { | | | | | | | | | | | | | | | | | | | | | | | 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 212 213 214 215 | return self; } - (void)dealloc { [_status release]; [_show release]; [_priority release]; [super dealloc]; } - (OFString*)type { if (_type == nil) return @"available"; return [[_type copy] autorelease]; } - (void)setShow: (OFString*)show { OFXMLElement *oldShow = [self elementForName: @"show" namespace: XMPP_NS_CLIENT]; if (oldShow != nil) [self removeChild: oldShow]; if (show != nil) [self addChild: [OFXMLElement elementWithName: @"show" namespace: XMPP_NS_CLIENT stringValue: show]]; OF_SETTER(_show, show, YES, 1); } - (OFString*)show { return [[_show copy] autorelease]; } - (void)setStatus: (OFString*)status { OFXMLElement *oldStatus = [self elementForName: @"status" namespace: XMPP_NS_CLIENT]; if (oldStatus != nil) [self removeChild: oldStatus]; if (status != nil) [self addChild: [OFXMLElement elementWithName: @"status" namespace: XMPP_NS_CLIENT stringValue: status]]; OF_SETTER(_status, status, YES, 1); } - (OFString*)status { return [[_status copy] autorelease]; } - (void)setPriority: (OFNumber*)priority { intmax_t prio = [priority intMaxValue]; if ((prio < -128) || (prio > 127)) @throw [OFInvalidArgumentException exceptionWithClass: [self class] selector: _cmd]; OFXMLElement *oldPriority = [self elementForName: @"priority" namespace: XMPP_NS_CLIENT]; if (oldPriority != nil) [self removeChild: oldPriority]; OFString* priority_s = [OFString stringWithFormat: @"%" @PRId8, [priority int8Value]]; [self addChild: [OFXMLElement elementWithName: @"priority" namespace: XMPP_NS_CLIENT stringValue: priority_s]]; OF_SETTER(_priority, priority, YES, 1); } - (OFNumber*)priority { return [[_priority copy] autorelease]; } - (of_comparison_result_t)compare: (id <OFComparing>)object { XMPPPresence *otherPresence; OFNumber *otherPriority; OFString *otherShow; |
︙ | ︙ | |||
224 225 226 227 228 229 230 | selector: _cmd]; otherPresence = (XMPPPresence*)object; otherPriority = [otherPresence priority]; if (otherPriority == nil) otherPriority = [OFNumber numberWithInt8: 0]; | | | | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | selector: _cmd]; otherPresence = (XMPPPresence*)object; otherPriority = [otherPresence priority]; if (otherPriority == nil) otherPriority = [OFNumber numberWithInt8: 0]; if (_priority != nil) priorityOrder = [_priority compare: otherPriority]; else priorityOrder = [[OFNumber numberWithInt8: 0] compare: otherPriority]; if (priorityOrder != OF_ORDERED_SAME) return priorityOrder; otherShow = [otherPresence show]; if ([_show isEqual: otherShow]) return OF_ORDERED_SAME; if (show_to_int(_show) < show_to_int(otherShow)) return OF_ORDERED_ASCENDING; return OF_ORDERED_DESCENDING; } @end |
Modified src/XMPPRoster.h from [e0bd743e89] to [ed9a1820f5].
︙ | ︙ | |||
65 66 67 68 69 70 71 | */ @interface XMPPRoster: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS <XMPPConnectionDelegate> #endif { /// \cond internal | | | | | | | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | */ @interface XMPPRoster: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS <XMPPConnectionDelegate> #endif { /// \cond internal XMPPConnection *_connection; OFMutableDictionary *_rosterItems; XMPPMulticastDelegate *_delegates; id <XMPPStorage> _dataStorage; BOOL _rosterRequested; /// \endcond } #ifdef OF_HAVE_PROPERTIES /** * \brief The connection to which the roster belongs */ |
︙ | ︙ |
Modified src/XMPPRoster.m from [1569eac957] to [025bb21619].
︙ | ︙ | |||
41 42 43 44 45 46 47 | @implementation XMPPRoster - initWithConnection: (XMPPConnection*)connection_ { self = [super init]; @try { | | | | | | | | | | | | | | | | | | | 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | @implementation XMPPRoster - initWithConnection: (XMPPConnection*)connection_ { self = [super init]; @try { _rosterItems = [[OFMutableDictionary alloc] init]; _connection = connection_; [_connection addDelegate: self]; _delegates = [[XMPPMulticastDelegate alloc] init]; _dataStorage = [_connection dataStorage]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_connection removeDelegate: self]; [_delegates release]; [_rosterItems release]; [super dealloc]; } - (OFDictionary*)rosterItems { return [[_rosterItems copy] autorelease]; } - (void)requestRoster { XMPPIQ *iq; OFXMLElement *query; _rosterRequested = YES; iq = [XMPPIQ IQWithType: @"get" ID: [_connection generateStanzaID]]; query = [OFXMLElement elementWithName: @"query" namespace: XMPP_NS_ROSTER]; 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; rosterElement = [iq elementForName: @"query" |
︙ | ︙ | |||
121 122 123 124 125 126 127 | element = [rosterElement elementForName: @"item" namespace: XMPP_NS_ROSTER]; if (element != nil) { rosterItem = [self XMPP_rosterItemWithXMLElement: element]; | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | element = [rosterElement elementForName: @"item" namespace: XMPP_NS_ROSTER]; 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 YES; } - (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: XMPP_NS_ROSTER]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPP_NS_ROSTER]; OFEnumerator *enumerator; OFString *group; [item addAttributeWithName: @"jid" stringValue: [[rosterItem JID] bareJID]]; if ([rosterItem name] != nil) [item addAttributeWithName: @"name" stringValue: [rosterItem name]]; enumerator = [[rosterItem groups] objectEnumerator]; while ((group = [enumerator nextObject]) != nil) [item addChild: [OFXMLElement elementWithName: @"group" namespace: XMPP_NS_ROSTER 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: XMPP_NS_ROSTER]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPP_NS_ROSTER]; [item addAttributeWithName: @"jid" stringValue: [[rosterItem JID] bareJID]]; [item addAttributeWithName: @"subscription" stringValue: @"remove"]; [query addChild: item]; [IQ addChild: query]; [_connection sendStanza: IQ]; } - (void)addDelegate: (id <XMPPRosterDelegate>)delegate { [_delegates addDelegate: delegate]; } - (void)removeDelegate: (id <XMPPRosterDelegate>)delegate { [_delegates removeDelegate: delegate]; } - (void)setDataStorage: (id <XMPPStorage>)dataStorage { if (_rosterRequested) @throw [OFInvalidArgumentException exceptionWithClass: [self class]]; _dataStorage = dataStorage; } - (XMPPConnection*)connection { return _connection; } - (id <XMPPStorage>)dataStorage { return _dataStorage; } - (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem { if ([_connection supportsRosterVersioning]) { OFMutableDictionary *items = [[[_dataStorage dictionaryForPath: @"roster.items"] mutableCopy] autorelease]; if (items == nil) items = [OFMutableDictionary dictionary]; if (![[rosterItem subscription] isEqual: @"remove"]) { OFMutableDictionary *item = [OFMutableDictionary |
︙ | ︙ | |||
254 255 256 257 258 259 260 | forKey: @"groups"]; [items setObject: item forKey: [[rosterItem JID] bareJID]]; } else [items removeObjectForKey: [[rosterItem JID] bareJID]]; | | | | | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | 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]]; } - (XMPPRosterItem*)XMPP_rosterItemWithXMLElement: (OFXMLElement*)element { OFString *subscription; OFEnumerator *groupEnumerator; OFXMLElement *groupElement; |
︙ | ︙ | |||
311 312 313 314 315 316 317 | OFXMLElement *rosterElement; OFEnumerator *enumerator; OFXMLElement *element; rosterElement = [iq elementForName: @"query" namespace: XMPP_NS_ROSTER]; | | | | | | | | | | | | | | 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 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 | OFXMLElement *rosterElement; OFEnumerator *enumerator; OFXMLElement *element; rosterElement = [iq elementForName: @"query" namespace: XMPP_NS_ROSTER]; if ([_connection supportsRosterVersioning]) { if (rosterElement == nil) { OFDictionary *items = [_dataStorage dictionaryForPath: @"roster.items"]; OFEnumerator *enumerator = [items objectEnumerator]; OFDictionary *item; while ((item = [enumerator nextObject]) != nil) { XMPPRosterItem *rosterItem; XMPPJID *JID; rosterItem = [XMPPRosterItem rosterItem]; JID = [XMPPJID JIDWithString: [item objectForKey: @"JID"]]; [rosterItem setJID: JID]; [rosterItem setName: [item objectForKey: @"name"]]; [rosterItem setSubscription: [item objectForKey: @"subscription"]]; [rosterItem setGroups: [item objectForKey: @"groups"]]; [_rosterItems setObject: rosterItem forKey: [JID bareJID]]; } } else [_dataStorage setDictionary: nil forPath: @"roster.items"]; } enumerator = [[rosterElement children] objectEnumerator]; while ((element = [enumerator nextObject]) != nil) { OFAutoreleasePool *pool; XMPPRosterItem *rosterItem; if (![[element name] isEqual: @"item"] || ![[element namespace] isEqual: XMPP_NS_ROSTER]) continue; pool = [OFAutoreleasePool new]; rosterItem = [self XMPP_rosterItemWithXMLElement: element]; [self XMPP_updateRosterItem: rosterItem]; [pool release]; } 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/XMPPRosterItem.h from [c9a8690e71] to [c478b3e124].
︙ | ︙ | |||
26 27 28 29 30 31 32 | /** * \brief A class for representing an item in the roster. */ @interface XMPPRosterItem: OFObject { /// \cond internal | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /** * \brief A class for representing an item in the roster. */ @interface XMPPRosterItem: OFObject { /// \cond internal XMPPJID *_JID; OFString *_name; OFString *_subscription; OFArray *_groups; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The JID of the roster item @property (copy) XMPPJID *JID; /// \brief The name of the roster item to show to the user |
︙ | ︙ |
Modified src/XMPPRosterItem.m from [b55c3a6bd9] to [aca510ff6a].
︙ | ︙ | |||
33 34 35 36 37 38 39 | + rosterItem { return [[[self alloc] init] autorelease]; } - (void)dealloc { | | | | | | | | | | | | < < | | | < < | | | < < | | | | | 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | + rosterItem { return [[[self alloc] init] autorelease]; } - (void)dealloc { [_JID release]; [_name release]; [_subscription release]; [_groups release]; [super dealloc]; } - copy { XMPPRosterItem *new = [[XMPPRosterItem alloc] init]; @try { new->_JID = [_JID copy]; new->_name = [_name copy]; new->_subscription = [_subscription copy]; new->_groups = [_groups copy]; } @catch (id e) { [new release]; @throw e; } return new; } - (OFString*)description { return [OFString stringWithFormat: @"<XMPPRosterItem, JID=%@, name=%@, " @"subscription=%@, groups=%@>", _JID, _name, _subscription, _groups]; } - (void)setJID: (XMPPJID*)JID { OF_SETTER(_JID, JID, YES, YES) } - (XMPPJID*)JID { OF_GETTER(_JID, YES) } - (void)setName: (OFString*)name { OF_SETTER(_name, name, YES, YES) } - (OFString*)name { OF_GETTER(_name, YES) } - (void)setSubscription: (OFString*)subscription { OF_SETTER(_subscription, subscription, YES, YES) } - (OFString*)subscription { OF_GETTER(_subscription, YES) } - (void)setGroups: (OFArray*)groups { OF_SETTER(_groups, groups, YES, YES) } - (OFArray*)groups { OF_GETTER(_groups, YES) } @end |
Modified src/XMPPSCRAMAuth.h from [21b60945ae] to [ad81f25e28].
︙ | ︙ | |||
26 27 28 29 30 31 32 | /** * \brief A class to authenticate using SCRAM */ @interface XMPPSCRAMAuth: XMPPAuthenticator { /// \cond internal | | | | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /** * \brief A class to authenticate using SCRAM */ @interface XMPPSCRAMAuth: XMPPAuthenticator { /// \cond internal Class _hashType; OFString *_cNonce; OFString *_GS2Header; OFString *_clientFirstMessageBare; OFDataArray *_serverSignature; XMPPConnection *_connection; BOOL _plusAvailable; BOOL _authenticated; /// \endcond } /** * \brief Creates a new autoreleased XMPPSCRAMAuth with an authcid and password. * * \param authcid The authcid to authenticate with |
︙ | ︙ |
Modified src/XMPPSCRAMAuth.m from [bc4fed3ba5] to [8e4d89c37f].
︙ | ︙ | |||
36 37 38 39 40 41 42 | #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c @implementation XMPPSCRAMAuth + SCRAMAuthWithAuthcid: (OFString*)authcid password: (OFString*)password | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 | #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c @implementation XMPPSCRAMAuth + SCRAMAuthWithAuthcid: (OFString*)authcid password: (OFString*)password connection: (XMPPConnection*)connection hash: (Class)hash plusAvailable: (BOOL)plusAvailable { return [[[self alloc] initWithAuthcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable] autorelease]; } + SCRAMAuthWithAuthzid: (OFString*)authzid authcid: (OFString*)authcid password: (OFString*)password connection: (XMPPConnection*)connection hash: (Class)hash plusAvailable: (BOOL)plusAvailable { return [[[self alloc] initWithAuthzid: authzid authcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable] autorelease]; } - initWithAuthcid: (OFString*)authcid password: (OFString*)password connection: (XMPPConnection*)connection hash: (Class)hash plusAvailable: (BOOL)plusAvailable { return [self initWithAuthzid: nil authcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable]; } - initWithAuthzid: (OFString*)authzid authcid: (OFString*)authcid password: (OFString*)password connection: (XMPPConnection*)connection hash: (Class)hash plusAvailable: (BOOL)plusAvailable { self = [super initWithAuthzid: authzid authcid: authcid password: password]; _hashType = hash; _plusAvailable = plusAvailable; _connection = [connection retain]; return self; } - (void)dealloc { [_GS2Header release]; [_clientFirstMessageBare release]; [_serverSignature release]; [_cNonce release]; [_connection release]; [super dealloc]; } - (void)setAuthzid: (OFString*)authzid { OFString *old = _authzid; if (authzid) { OFMutableString *new = [[authzid mutableCopy] autorelease]; [new replaceOccurrencesOfString: @"=" withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"]; _authzid = [new retain]; } 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"]; _authcid = [new retain]; } else _authcid = nil; [old release]; } - (OFDataArray*)initialMessage { OFDataArray *ret = [OFDataArray dataArray]; /* New authentication attempt, reset status */ [_cNonce release]; _cNonce = nil; [_GS2Header release]; _GS2Header = nil; [_serverSignature release]; _serverSignature = nil; _authenticated = NO; if (_authzid) _GS2Header = [[OFString alloc] initWithFormat: @"%@,a=%@,", (_plusAvailable ? @"p=tls-unique" : @"y"), _authzid]; else _GS2Header = (_plusAvailable ? @"p=tls-unique,," : @"y,,"); _cNonce = [[self XMPP_genNonce] retain]; [_clientFirstMessageBare release]; _clientFirstMessageBare = nil; _clientFirstMessageBare = [[OFString alloc] initWithFormat: @"n=%@,r=%@", _authcid, _cNonce]; [ret addItems: [_GS2Header UTF8String] count: [_GS2Header UTF8StringLength]]; [ret addItems: [_clientFirstMessageBare UTF8String] count: [_clientFirstMessageBare UTF8StringLength]]; return ret; } - (OFDataArray*)continueWithData: (OFDataArray*)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDataArray *ret; if (!_serverSignature) ret = [self XMPP_parseServerFirstMessage: data]; else ret = [self XMPP_parseServerFinalMessage: data]; [ret retain]; [pool release]; |
︙ | ︙ | |||
209 210 211 212 213 214 215 | OFString *comp; enum { GOT_SNONCE = 0x01, GOT_SALT = 0x02, GOT_ITERCOUNT = 0x04 } got = 0; | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | OFString *comp; enum { GOT_SNONCE = 0x01, GOT_SALT = 0x02, GOT_ITERCOUNT = 0x04 } got = 0; hash = [[[_hashType alloc] init] autorelease]; ret = [OFDataArray dataArray]; authMessage = [OFDataArray dataArray]; OFString *chal = [OFString stringWithUTF8String: [data items] length: [data count] * [data itemSize]]; enumerator = [[chal componentsSeparatedByString: @","] objectEnumerator]; while ((comp = [enumerator nextObject]) != nil) { OFString *entry = [comp substringWithRange: of_range(2, [comp length] - 2)]; if ([comp hasPrefix: @"r="]) { if (![entry hasPrefix: _cNonce]) @throw [XMPPAuthFailedException exceptionWithClass: [self class] connection: nil reason: @"Received wrong " @"nonce"]; sNonce = entry; |
︙ | ︙ | |||
249 250 251 252 253 254 255 | if (got != (GOT_SNONCE | GOT_SALT | GOT_ITERCOUNT)) @throw [OFInvalidServerReplyException exceptionWithClass: [self class]]; // Add c=<base64(GS2Header+channelBindingData)> tmpArray = [OFDataArray dataArray]; | | | | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | if (got != (GOT_SNONCE | GOT_SALT | GOT_ITERCOUNT)) @throw [OFInvalidServerReplyException exceptionWithClass: [self class]]; // Add c=<base64(GS2Header+channelBindingData)> tmpArray = [OFDataArray dataArray]; [tmpArray addItems: [_GS2Header UTF8String] count: [_GS2Header UTF8StringLength]]; if (_plusAvailable && [_connection encrypted]) { OFDataArray *channelBinding = [((SSLSocket*)[_connection socket]) channelBindingDataWithType: @"tls-unique"]; [tmpArray addItems: [channelBinding items] count: [channelBinding count]]; } tmpString = [tmpArray stringByBase64Encoding]; [ret addItems: "c=" count: 2]; |
︙ | ︙ | |||
275 276 277 278 279 280 281 | count: [sNonce UTF8StringLength]]; /* * IETF RFC 5802: * SaltedPassword := Hi(Normalize(password), salt, i) */ tmpArray = [OFDataArray dataArray]; | | | | | | 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 | count: [sNonce UTF8StringLength]]; /* * IETF RFC 5802: * SaltedPassword := Hi(Normalize(password), salt, i) */ tmpArray = [OFDataArray dataArray]; [tmpArray addItems: [_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]]; |
︙ | ︙ | |||
312 313 314 315 316 317 318 | data: tmpArray]; /* * IETF RFC 5802: * StoredKey := H(ClientKey) */ [hash updateWithBuffer: (void*) clientKey | | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | data: tmpArray]; /* * IETF RFC 5802: * StoredKey := H(ClientKey) */ [hash updateWithBuffer: (void*) clientKey length: [_hashType digestSize]]; tmpArray = [OFDataArray dataArray]; [tmpArray addItems: [hash digest] count: [_hashType digestSize]]; /* * IETF RFC 5802: * ClientSignature := HMAC(StoredKey, AuthMessage) */ clientSignature = [self XMPP_HMACWithKey: tmpArray data: authMessage]; |
︙ | ︙ | |||
340 341 342 343 344 345 346 | /* * IETF RFC 5802: * ServerSignature := HMAC(ServerKey, AuthMessage) */ tmpArray = [OFDataArray dataArray]; [tmpArray addItems: serverKey | | | | | | | 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 | /* * IETF RFC 5802: * ServerSignature := HMAC(ServerKey, AuthMessage) */ tmpArray = [OFDataArray dataArray]; [tmpArray addItems: serverKey count: [_hashType digestSize]]; _serverSignature = [[OFDataArray alloc] init]; [_serverSignature addItems: [self XMPP_HMACWithKey: tmpArray data: authMessage] count: [_hashType digestSize]]; /* * IETF RFC 5802: * ClientProof := ClientKey XOR ClientSignature */ tmpArray = [OFDataArray dataArray]; 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=" |
︙ | ︙ | |||
375 376 377 378 379 380 381 | { OFString *mess, *value; /* * server-final-message already received, * we were just waiting for the last word from the server */ | | | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | { OFString *mess, *value; /* * server-final-message already received, * we were just waiting for the last word from the server */ if (_authenticated) return nil; mess = [OFString stringWithUTF8String: [data items] length: [data count] * [data itemSize]]; value = [mess substringWithRange: of_range(2, [mess length] - 2)]; if ([mess hasPrefix: @"v="]) { if (![value isEqual: [_serverSignature stringByBase64Encoding]]) @throw [XMPPAuthFailedException exceptionWithClass: [self class] connection: nil reason: @"Received wrong " @"ServerSignature"]; _authenticated = YES; } else @throw [XMPPAuthFailedException exceptionWithClass: [self class] connection: nil reason: value]; return nil; } |
︙ | ︙ | |||
425 426 427 428 429 430 431 | } - (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key data: (OFDataArray*)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDataArray *k = [OFDataArray dataArray]; | | | | | | | | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | } - (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key data: (OFDataArray*)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDataArray *k = [OFDataArray dataArray]; size_t i, kSize, blockSize = [_hashType blockSize]; uint8_t *kI = NULL, *kO = NULL; OFHash *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: [_hashType digestSize]]; } else [k addItems: [key items] count: [key itemSize] * [key count]]; @try { kI = [self allocMemoryWithSize: blockSize]; kO = [self allocMemoryWithSize: blockSize]; kSize = [k count]; memcpy(kI, [k items], kSize); memset(kI + kSize, 0, blockSize - kSize); memcpy(kO, kI, blockSize); for (i = 0; i < blockSize; i++) { kI[i] ^= HMAC_IPAD; kO[i] ^= HMAC_OPAD; } hashI = [[[_hashType alloc] init] autorelease]; [hashI updateWithBuffer: (char*)kI length: blockSize]; [hashI updateWithBuffer: [data items] length: [data itemSize] * [data count]]; hashO = [[[_hashType alloc] init] autorelease]; [hashO updateWithBuffer: (char*)kO length: blockSize]; [hashO updateWithBuffer: (char*)[hashI digest] length: [_hashType digestSize]]; } @finally { [self freeMemory: kI]; [self freeMemory: kO]; } [hashO retain]; [pool release]; return [[hashO autorelease] digest]; } - (OFDataArray*)XMPP_hiWithData: (OFDataArray *)str salt: (OFDataArray *)salt_ iterationCount: (intmax_t)i { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; size_t digestSize = [_hashType digestSize]; uint8_t *result = NULL, *u, *uOld; intmax_t j, k; OFDataArray *salty, *tmp, *ret; result = [self allocMemoryWithSize: digestSize]; @try { |
︙ | ︙ |
Modified src/XMPPSRVLookup.h from [5ef397d2de] to [b7bd64c83f].
︙ | ︙ | |||
24 25 26 27 28 29 30 | #include <arpa/nameser.h> #include <resolv.h> #import <ObjFW/ObjFW.h> @interface XMPPSRVEntry: OFObject { | | | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <arpa/nameser.h> #include <resolv.h> #import <ObjFW/ObjFW.h> @interface XMPPSRVEntry: OFObject { uint16_t _priority; uint16_t _weight; uint32_t _accumulatedWeight; uint16_t _port; OFString *_target; } #ifdef OF_HAVE_PROPERTIES @property (readonly) uint16_t priority; @property (readonly) uint16_t weight; @property uint32_t accumulatedWeight; @property (readonly) uint16_t port; |
︙ | ︙ | |||
61 62 63 64 65 66 67 | - (void)setAccumulatedWeight: (uint32_t)accumulatedWeight; - (uint16_t)port; - (OFString*)target; @end @interface XMPPSRVLookup: OFObject <OFEnumerating> { | | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | - (void)setAccumulatedWeight: (uint32_t)accumulatedWeight; - (uint16_t)port; - (OFString*)target; @end @interface XMPPSRVLookup: OFObject <OFEnumerating> { OFString *_domain; struct __res_state _resState; OFList *_list; } #ifdef OF_HAVE_PROPERTIES @property (readonly, copy) OFString *domain; #endif + lookupWithDomain: (OFString*)domain; |
︙ | ︙ |
Modified src/XMPPSRVLookup.m from [8dac8d7c43] to [dde19bea60].
︙ | ︙ | |||
57 58 59 60 61 62 63 | { Class c = [self class]; [self release]; @throw [OFNotImplementedException exceptionWithClass: c selector: _cmd]; } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 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 266 267 268 269 270 271 272 273 274 | { Class c = [self class]; [self release]; @throw [OFNotImplementedException exceptionWithClass: c selector: _cmd]; } - initWithPriority: (uint16_t)priority weight: (uint16_t)weight port: (uint16_t)port target: (OFString*)target { self = [super init]; @try { _priority = priority; _weight = weight; _port = port; _target = [target copy]; } @catch (id e) { [self release]; @throw e; } return self; } - initWithResourceRecord: (ns_rr)resourceRecord handle: (ns_msg)handle { self = [super init]; @try { const uint16_t *rdata; char buffer[NS_MAXDNAME]; rdata = (const uint16_t*)(void*)ns_rr_rdata(resourceRecord); _priority = ntohs(rdata[0]); _weight = ntohs(rdata[1]); _port = ntohs(rdata[2]); if (dn_expand(ns_msg_base(handle), ns_msg_end(handle), (uint8_t*)&rdata[3], buffer, NS_MAXDNAME) < 1) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; _target = [[OFString alloc] initWithCString: buffer encoding: OF_STRING_ENCODING_NATIVE]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_target release]; [super dealloc]; } - (OFString*)description { return [OFString stringWithFormat: @"<%@ priority: %" PRIu16 @", weight: %" PRIu16 @", target: %@:%" PRIu16 @">", [self class], _priority, _weight, _target, _port]; } - (uint16_t)priority { return _priority; } - (uint16_t)weight { return _weight; } - (void)setAccumulatedWeight: (uint32_t)accumulatedWeight { _accumulatedWeight = accumulatedWeight; } - (uint32_t)accumulatedWeight { return _accumulatedWeight; } - (uint16_t)port { return _port; } - (OFString*)target { OF_GETTER(_target, YES) } @end @implementation XMPPSRVLookup + lookupWithDomain: (OFString*)domain { return [[[self alloc] initWithDomain: domain] autorelease]; } - initWithDomain: (OFString*)domain { self = [super init]; @try { _list = [[OFList alloc] init]; _domain = [domain copy]; [self XMPP_lookup]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_list release]; [_domain release]; [super dealloc]; } - (OFString*)domain; { OF_GETTER(_domain, YES) } - (void)XMPP_lookup { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; unsigned char *answer = NULL; size_t pageSize = [OFSystemInfo pageSize]; OFString *request; request = [OFString stringWithFormat: @"_xmpp-client._tcp.%@", _domain]; @try { int answerLen, resourceRecordCount, i; ns_rr resourceRecord; ns_msg handle; if (res_ninit(&_resState)) @throw [OFAddressTranslationFailedException exceptionWithClass: [self class] socket: nil host: _domain]; answer = [self allocMemoryWithSize: pageSize]; answerLen = res_nsearch(&_resState, [request cStringWithEncoding: OF_STRING_ENCODING_NATIVE], ns_c_in, ns_t_srv, answer, (int)pageSize); if ((answerLen == -1) && ((h_errno == HOST_NOT_FOUND) || (h_errno == NO_DATA))) return; if (answerLen < 1 || answerLen > pageSize) { @throw [OFAddressTranslationFailedException exceptionWithClass: [self class] socket: nil host: _domain]; } if (ns_initparse(answer, answerLen, &handle)) @throw [OFAddressTranslationFailedException exceptionWithClass: [self class] socket: nil host: _domain]; resourceRecordCount = ns_msg_count(handle, ns_s_an); for (i = 0; i < resourceRecordCount; i++) { if (ns_parserr(&handle, ns_s_an, i, &resourceRecord)) continue; if (ns_rr_type(resourceRecord) != ns_t_srv || ns_rr_class(resourceRecord) != ns_c_in) continue; [self XMPP_addEntry: [XMPPSRVEntry entryWithResourceRecord: resourceRecord handle: handle]]; } } @finally { [self freeMemory: answer]; #ifdef HAVE_RES_NDESTROY res_ndestroy(&_resState); #endif } [pool release]; } - (void)XMPP_addEntry: (XMPPSRVEntry*)entry { OFAutoreleasePool *pool; OFList *subList; of_list_object_t *iter; /* Look if there already is a list with the priority */ for (iter = [_list firstListObject]; iter != NULL; iter = iter->next) { if ([[iter->object firstObject] priority] == [entry priority]) { /* * RFC 2782 says those with weight 0 should be at the * beginning of the list. */ if ([entry weight] > 0) [iter->object appendObject: entry]; |
︙ | ︙ | |||
285 286 287 288 289 290 291 | pool = [[OFAutoreleasePool alloc] init]; subList = [OFList list]; [subList appendObject: entry]; if (iter != NULL) | | | | | | 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 | pool = [[OFAutoreleasePool alloc] init]; subList = [OFList list]; [subList appendObject: entry]; if (iter != NULL) [_list insertObject: subList beforeListObject: iter]; else [_list appendObject: subList]; [pool release]; } - (OFEnumerator*)objectEnumerator { return [[[XMPPSRVEnumerator alloc] initWithList: _list] autorelease]; } @end @implementation XMPPSRVEnumerator - initWithList: (OFList*)list_ { self = [super init]; |
︙ | ︙ |
Modified src/XMPPStanza.h from [f45f15ec37] to [e1be48da02].
︙ | ︙ | |||
27 28 29 30 31 32 33 | /** * \brief A class describing an XMPP Stanza. */ @interface XMPPStanza: OFXMLElement { /// \cond internal | | | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /** * \brief A class describing an XMPP Stanza. */ @interface XMPPStanza: OFXMLElement { /// \cond internal XMPPJID *_from; XMPPJID *_to; OFString *_type; OFString *_ID; OFString *_language; /// \endcond } #ifdef OF_HAVE_PROPERTIES /// \brief The value of the stanza's from attribute @property (copy) XMPPJID *from; /// \brief The value of the stanza's to attribute |
︙ | ︙ |
Modified src/XMPPStanza.m from [fbf43a1a52] to [8ed21f56f2].
︙ | ︙ | |||
32 33 34 35 36 37 38 | @implementation XMPPStanza + stanzaWithName: (OFString*)name { return [[[self alloc] initWithName: name] autorelease]; } + stanzaWithName: (OFString*)name | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 | @implementation XMPPStanza + stanzaWithName: (OFString*)name { return [[[self alloc] initWithName: name] autorelease]; } + stanzaWithName: (OFString*)name type: (OFString*)type { return [[[self alloc] initWithName: name type: type] autorelease]; } + stanzaWithName: (OFString*)name ID: (OFString*)ID { return [[[self alloc] initWithName: name ID: ID] autorelease]; } + stanzaWithName: (OFString*)name type: (OFString*)type ID: (OFString*)ID { return [[[self alloc] initWithName: name type: type ID: ID] autorelease]; } + stanzaWithElement: (OFXMLElement*)element { return [[[self alloc] initWithElement: element] autorelease]; } - initWithName: (OFString*)name { return [self initWithName: name type: nil ID: nil]; } - initWithName: (OFString*)name type: (OFString*)type { return [self initWithName: name type: type ID: nil]; } - initWithName: (OFString*)name ID: (OFString*)ID { return [self initWithName: name type: nil ID: ID]; } - initWithName: (OFString*)name type: (OFString*)type ID: (OFString*)ID { self = [super initWithName: name namespace: XMPP_NS_CLIENT]; @try { if (![name isEqual: @"iq"] && ![name isEqual: @"message"] && ![name isEqual: @"presence"]) @throw [OFInvalidArgumentException exceptionWithClass: [self class] selector: _cmd]; [self setDefaultNamespace: XMPP_NS_CLIENT]; [self setPrefix: @"stream" forNamespace: XMPP_NS_STREAM]; if (type != nil) [self setType: type]; if (ID != nil) [self setID: ID]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
143 144 145 146 147 148 149 | } return self; } - (void)dealloc { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | } return self; } - (void)dealloc { [_from release]; [_to release]; [_type release]; [_ID release]; [super dealloc]; } - (void)setFrom: (XMPPJID*)from { XMPPJID *old = _from; _from = [from copy]; [old release]; [self removeAttributeForName: @"from"]; if (from != nil) [self addAttributeWithName: @"from" stringValue: [from fullJID]]; } - (XMPPJID*)from { return [[_from copy] autorelease]; } - (void)setTo: (XMPPJID*)to { XMPPJID *old = _to; _to = [to copy]; [old release]; [self removeAttributeForName: @"to"]; if (to != nil) [self addAttributeWithName: @"to" stringValue: [to fullJID]]; } - (XMPPJID*)to { return [[_to copy] autorelease]; } - (void)setType: (OFString*)type { OFString *old = _type; _type = [type copy]; [old release]; [self removeAttributeForName: @"type"]; if (type != nil) [self addAttributeWithName: @"type" stringValue: type]; } - (OFString*)type { return [[_type copy] autorelease]; } - (void)setID: (OFString*)ID { OFString *old = _ID; _ID = [ID copy]; [old release]; [self removeAttributeForName: @"id"]; if (ID != nil) [self addAttributeWithName: @"id" stringValue: ID]; } - (OFString*)ID { return [[_ID copy] autorelease]; } - (void)setLanguage: (OFString*)language { OFString *old = _language; _language = [language copy]; [old release]; [self removeAttributeForName: @"lang" namespace: @"http://www.w3.org/XML/1998/namespace"]; if (language != nil) [self addAttributeWithName: @"lang" namespace: @"http://www.w3.org/XML/1998/" @"namespace" stringValue: language]; } - (OFString*)language { return [[_language copy] autorelease]; } @end |
Modified src/XMPPStreamManagement.h from [b1e66795db] to [c73319cf59].
︙ | ︙ | |||
24 25 26 27 28 29 30 | @interface XMPPStreamManagement: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS <XMPPConnectionDelegate> #endif { /// \cond internal | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | @interface XMPPStreamManagement: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS <XMPPConnectionDelegate> #endif { /// \cond internal XMPPConnection *_connection; uint32_t receivedCount; /// \endcond } - initWithConnection: (XMPPConnection*)connection; @end |
Modified src/XMPPStreamManagement.m from [b0ffeb590a] to [fbee9ca5ca].
︙ | ︙ | |||
25 26 27 28 29 30 31 | @implementation XMPPStreamManagement - initWithConnection: (XMPPConnection*)connection_ { self = [super init]; @try { | | | | | 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 | @implementation XMPPStreamManagement - initWithConnection: (XMPPConnection*)connection_ { self = [super init]; @try { _connection = connection_; [_connection addDelegate: self]; receivedCount = 0; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_connection removeDelegate: self]; [super dealloc]; } - (void)connection: (XMPPConnection*)connection_ didReceiveElement: (OFXMLElement*)element { |
︙ | ︙ |