Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -4,11 +4,12 @@ STATIC_LIB = ${OBJXMPP_STATIC_LIB} FRAMEWORK = ${OBJXMPP_FRAMEWORK} LIB_MAJOR = 0 LIB_MINOR = 0 -SRCS = XMPPAuthenticator.m \ +SRCS = XMPPANONYMOUSAuth.m \ + XMPPAuthenticator.m \ XMPPCallback.m \ XMPPConnection.m \ XMPPContact.m \ XMPPContactManager.m \ XMPPDiscoEntity.m \ ADDED src/XMPPANONYMOUSAuth.h Index: src/XMPPANONYMOUSAuth.h ================================================================== --- src/XMPPANONYMOUSAuth.h +++ src/XMPPANONYMOUSAuth.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, Jonathan Schleifer + * + * https://heap.zone/objxmpp/ + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "XMPPAuthenticator.h" + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @brief A class to authenticate using SASL ANONYMOUS. + */ +@interface XMPPANONYMOUSAuth: XMPPAuthenticator +@end + +OF_ASSUME_NONNULL_END ADDED src/XMPPANONYMOUSAuth.m Index: src/XMPPANONYMOUSAuth.m ================================================================== --- src/XMPPANONYMOUSAuth.m +++ src/XMPPANONYMOUSAuth.m @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, Jonathan Schleifer + * + * https://heap.zone/objxmpp/ + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#import "XMPPANONYMOUSAuth.h" + +@implementation XMPPANONYMOUSAuth: XMPPAuthenticator +@end Index: src/XMPPConnection.h ================================================================== --- src/XMPPConnection.h +++ src/XMPPConnection.h @@ -145,113 +145,117 @@ OFXMLElementBuilderDelegate> { OF_KINDOF(OFTCPSocket *) _socket; OFXMLParser *_parser, *_oldParser; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; - OFString *_username, *_password, *_server, *_resource; - OFString *_privateKeyFile, *_certificateFile; - const char *_privateKeyPassphrase; - OFString *_domain, *_domainToASCII; - XMPPJID *_JID; + OFString *_Nullable _username, *_Nullable _password, *_Nullable _server; + OFString *_Nullable _resource; + bool _usesAnonymousAuthentication; + OFString *_Nullable _privateKeyFile, *_Nullable _certificateFile; + const char *_Nullable _privateKeyPassphrase; + OFString *_Nullable _domain, *_Nullable _domainToASCII; + XMPPJID *_Nullable _JID; uint16_t _port; - id _dataStorage; - OFString *_language; + id _Nullable _dataStorage; + OFString *_Nullable _language; XMPPMulticastDelegate *_delegates; OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks; XMPPAuthenticator *_authModule; - bool _streamOpen; - bool _needsSession; - bool _encryptionRequired, _encrypted; - bool _supportsRosterVersioning; - bool _supportsStreamManagement; + bool _streamOpen, _needsSession, _encryptionRequired, _encrypted; + bool _supportsRosterVersioning, _supportsStreamManagement; unsigned int _lastID; } /*! - * The username to use for authentication. + * @brief The username to use for authentication. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *username; /*! - * The password to use for authentication. + * @brief The password to use for authentication. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *password; /*! - * The server to use for the connection. + * @brief The server to use for the connection. * * This is useful if the address of the server is different from the domain. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *server; /*! - * The domain to connect to. + * @brief The domain to connect to. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *domain; /*! - * The resource to request for the connection. + * @brief The resource to request for the connection. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *resource; /*! - * The language to request for the connection. + * @brief Whether the connection uses SASL ANONYMOUS authentication. + */ +@property (nonatomic) bool usesAnonymousAuthentication; + +/*! + * @brief The language to request for the connection. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *language; /*! - * A private key file to use for authentication. + * @brief A private key file to use for authentication. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *privateKeyFile; /*! - * A certificate file to use for authentication. + * @brief A certificate file to use for authentication. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *certificateFile; /*! - * The JID the server assigned to the connection after binding. + * @brief The JID the server assigned to the connection after binding. */ -@property (readonly, nonatomic) XMPPJID *JID; +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) XMPPJID *JID; /*! - * The port to connect to. + * @brief The port to connect to. */ @property (nonatomic) uint16_t port; /*! - * An object for data storage, conforming to the XMPPStorage protocol. + * @brief An object for data storage, conforming to the XMPPStorage protocol. */ @property OF_NULLABLE_PROPERTY (nonatomic, assign) id dataStorage; /*! - * The socket used for the connection. + * @brief The socket used for the connection. */ @property (readonly, nonatomic) OF_KINDOF(OFTCPSocket *) socket; /*! - * Whether encryption is required. + * @brief Whether encryption is required. */ @property (nonatomic) bool encryptionRequired; /*! - * Whether the connection is encrypted. + * @brief Whether the connection is encrypted. */ @property (readonly, nonatomic) bool encrypted; /*! - * Whether roster versioning is supported. + * @brief Whether roster versioning is supported. */ @property (readonly, nonatomic) bool supportsRosterVersioning; /*! - * Whether stream management is supported. + * @brief Whether stream management is supported. */ @property (readonly, nonatomic) bool supportsStreamManagement; /*! - * Creates a new autoreleased XMPPConnection. + * @brief Creates a new autoreleased XMPPConnection. * * @return A new autoreleased XMPPConnection */ + (instancetype)connection; Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -36,22 +36,24 @@ #import #import #import "XMPPConnection.h" +#import "XMPPANONYMOUSAuth.h" #import "XMPPCallback.h" #import "XMPPEXTERNALAuth.h" -#import "XMPPSCRAMAuth.h" -#import "XMPPPLAINAuth.h" -#import "XMPPStanza.h" +#import "XMPPExceptions.h" +#import "XMPPIQ.h" #import "XMPPJID.h" -#import "XMPPIQ.h" #import "XMPPMessage.h" +#import "XMPPMulticastDelegate.h" +#import "XMPPPLAINAuth.h" #import "XMPPPresence.h" -#import "XMPPMulticastDelegate.h" -#import "XMPPExceptions.h" +#import "XMPPSCRAMAuth.h" +#import "XMPPStanza.h" #import "XMPPXMLElementBuilder.h" + #import "namespaces.h" #import #define BUFFER_LENGTH 512 @@ -97,10 +99,11 @@ @end @implementation XMPPConnection @synthesize username = _username, resource = _resource, server = _server; @synthesize domain = _domain, password = _password, JID = _JID, port = _port; +@synthesize usesAnonymousAuthentication = _usesAnonymousAuthentication; @synthesize language = _language, privateKeyFile = _privateKeyFile; @synthesize certificateFile = _certificateFile, socket = _socket; @synthesize encryptionRequired = _encryptionRequired, encrypted = _encrypted; @synthesize supportsRosterVersioning = _supportsRosterVersioning; @synthesize supportsStreamManagement = _supportsStreamManagement; @@ -1011,10 +1014,22 @@ _supportsStreamManagement = true; if (mechs != nil) { for (OFXMLElement *mech in [mechs children]) [mechanisms addObject: [mech stringValue]]; + + if (_usesAnonymousAuthentication) { + if (![mechanisms containsObject: @"ANONYMOUS"]) + @throw [XMPPAuthFailedException + exceptionWithConnection: self + reason: @"No supported " + @"auth mechanism"]; + + _authModule = [[XMPPANONYMOUSAuth alloc] init]; + [self xmpp_sendAuth: @"ANONYMOUS"]; + return; + } if (_privateKeyFile != nil && _certificateFile != nil && [mechanisms containsObject: @"EXTERNAL"]) { _authModule = [[XMPPEXTERNALAuth alloc] init]; [self xmpp_sendAuth: @"EXTERNAL"]; @@ -1049,11 +1064,14 @@ password: _password]; [self xmpp_sendAuth: @"PLAIN"]; return; } - assert(0); + @throw [XMPPAuthFailedException + exceptionWithConnection: self + reason: @"No supported auth mechanism"]; + } if (session != nil && [session elementForName: @"optional" namespace: XMPP_NS_SESSION] == nil) _needsSession = true; @@ -1073,11 +1091,11 @@ authTag = [OFXMLElement elementWithName: @"auth" namespace: XMPP_NS_SASL]; [authTag addAttributeWithName: @"mechanism" stringValue: authName]; - if (initialMessage) { + if (initialMessage != nil) { if ([initialMessage count] == 0) [authTag setStringValue: @"="]; else [authTag setStringValue: [initialMessage stringByBase64Encoding]];