diff --git a/src/Makefile b/src/Makefile index 6f88e00..c99040f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,8 @@ FRAMEWORK = ${OBJXMPP_FRAMEWORK} LIB_MAJOR = 0 LIB_MINOR = 0 -SRCS = XMPPAuthenticator.m \ +SRCS = XMPPANONYMOUSAuth.m \ + XMPPAuthenticator.m \ XMPPCallback.m \ XMPPConnection.m \ XMPPContact.m \ diff --git a/src/XMPPANONYMOUSAuth.h b/src/XMPPANONYMOUSAuth.h new file mode 100644 index 0000000..a0b87d7 --- /dev/null +++ b/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 diff --git a/src/XMPPANONYMOUSAuth.m b/src/XMPPANONYMOUSAuth.m new file mode 100644 index 0000000..05a40ed --- /dev/null +++ b/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 diff --git a/src/XMPPConnection.h b/src/XMPPConnection.h index e6c8a13..07957a4 100644 --- a/src/XMPPConnection.h +++ b/src/XMPPConnection.h @@ -147,109 +147,113 @@ OF_ASSUME_NONNULL_BEGIN 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 */ diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index 091f7e8..7c79a6a 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -38,18 +38,20 @@ #import #import "XMPPConnection.h" +#import "XMPPANONYMOUSAuth.h" #import "XMPPCallback.h" #import "XMPPEXTERNALAuth.h" -#import "XMPPSCRAMAuth.h" -#import "XMPPPLAINAuth.h" -#import "XMPPStanza.h" -#import "XMPPJID.h" -#import "XMPPIQ.h" -#import "XMPPMessage.h" -#import "XMPPPresence.h" -#import "XMPPMulticastDelegate.h" #import "XMPPExceptions.h" +#import "XMPPIQ.h" +#import "XMPPJID.h" +#import "XMPPMessage.h" +#import "XMPPMulticastDelegate.h" +#import "XMPPPLAINAuth.h" +#import "XMPPPresence.h" +#import "XMPPSCRAMAuth.h" +#import "XMPPStanza.h" #import "XMPPXMLElementBuilder.h" + #import "namespaces.h" #import @@ -99,6 +101,7 @@ @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; @@ -1014,6 +1017,18 @@ 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]; @@ -1051,7 +1066,10 @@ return; } - assert(0); + @throw [XMPPAuthFailedException + exceptionWithConnection: self + reason: @"No supported auth mechanism"]; + } if (session != nil && [session elementForName: @"optional" @@ -1075,7 +1093,7 @@ namespace: XMPP_NS_SASL]; [authTag addAttributeWithName: @"mechanism" stringValue: authName]; - if (initialMessage) { + if (initialMessage != nil) { if ([initialMessage count] == 0) [authTag setStringValue: @"="]; else