Add support for anonymous authentication
This commit is contained in:
parent
d76fc4129d
commit
b1c3f82596
5 changed files with 127 additions and 41 deletions
|
@ -6,7 +6,8 @@ FRAMEWORK = ${OBJXMPP_FRAMEWORK}
|
||||||
LIB_MAJOR = 0
|
LIB_MAJOR = 0
|
||||||
LIB_MINOR = 0
|
LIB_MINOR = 0
|
||||||
|
|
||||||
SRCS = XMPPAuthenticator.m \
|
SRCS = XMPPANONYMOUSAuth.m \
|
||||||
|
XMPPAuthenticator.m \
|
||||||
XMPPCallback.m \
|
XMPPCallback.m \
|
||||||
XMPPConnection.m \
|
XMPPConnection.m \
|
||||||
XMPPContact.m \
|
XMPPContact.m \
|
||||||
|
|
35
src/XMPPANONYMOUSAuth.h
Normal file
35
src/XMPPANONYMOUSAuth.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Jonathan Schleifer <js@heap.zone>
|
||||||
|
*
|
||||||
|
* 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 <ObjFW/ObjFW.h>
|
||||||
|
|
||||||
|
#import "XMPPAuthenticator.h"
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief A class to authenticate using SASL ANONYMOUS.
|
||||||
|
*/
|
||||||
|
@interface XMPPANONYMOUSAuth: XMPPAuthenticator
|
||||||
|
@end
|
||||||
|
|
||||||
|
OF_ASSUME_NONNULL_END
|
28
src/XMPPANONYMOUSAuth.m
Normal file
28
src/XMPPANONYMOUSAuth.m
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Jonathan Schleifer <js@heap.zone>
|
||||||
|
*
|
||||||
|
* 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
|
|
@ -147,109 +147,113 @@ OF_ASSUME_NONNULL_BEGIN
|
||||||
OF_KINDOF(OFTCPSocket *) _socket;
|
OF_KINDOF(OFTCPSocket *) _socket;
|
||||||
OFXMLParser *_parser, *_oldParser;
|
OFXMLParser *_parser, *_oldParser;
|
||||||
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
|
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
|
||||||
OFString *_username, *_password, *_server, *_resource;
|
OFString *_Nullable _username, *_Nullable _password, *_Nullable _server;
|
||||||
OFString *_privateKeyFile, *_certificateFile;
|
OFString *_Nullable _resource;
|
||||||
const char *_privateKeyPassphrase;
|
bool _usesAnonymousAuthentication;
|
||||||
OFString *_domain, *_domainToASCII;
|
OFString *_Nullable _privateKeyFile, *_Nullable _certificateFile;
|
||||||
XMPPJID *_JID;
|
const char *_Nullable _privateKeyPassphrase;
|
||||||
|
OFString *_Nullable _domain, *_Nullable _domainToASCII;
|
||||||
|
XMPPJID *_Nullable _JID;
|
||||||
uint16_t _port;
|
uint16_t _port;
|
||||||
id <XMPPStorage> _dataStorage;
|
id <XMPPStorage> _Nullable _dataStorage;
|
||||||
OFString *_language;
|
OFString *_Nullable _language;
|
||||||
XMPPMulticastDelegate *_delegates;
|
XMPPMulticastDelegate *_delegates;
|
||||||
OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks;
|
OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks;
|
||||||
XMPPAuthenticator *_authModule;
|
XMPPAuthenticator *_authModule;
|
||||||
bool _streamOpen;
|
bool _streamOpen, _needsSession, _encryptionRequired, _encrypted;
|
||||||
bool _needsSession;
|
bool _supportsRosterVersioning, _supportsStreamManagement;
|
||||||
bool _encryptionRequired, _encrypted;
|
|
||||||
bool _supportsRosterVersioning;
|
|
||||||
bool _supportsStreamManagement;
|
|
||||||
unsigned int _lastID;
|
unsigned int _lastID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* The username to use for authentication.
|
* @brief The username to use for authentication.
|
||||||
*/
|
*/
|
||||||
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *username;
|
@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;
|
@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.
|
* This is useful if the address of the server is different from the domain.
|
||||||
*/
|
*/
|
||||||
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *server;
|
@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;
|
@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;
|
@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;
|
@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;
|
@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;
|
@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;
|
@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 <XMPPStorage> dataStorage;
|
@property OF_NULLABLE_PROPERTY (nonatomic, assign) id <XMPPStorage> dataStorage;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* The socket used for the connection.
|
* @brief The socket used for the connection.
|
||||||
*/
|
*/
|
||||||
@property (readonly, nonatomic) OF_KINDOF(OFTCPSocket *) socket;
|
@property (readonly, nonatomic) OF_KINDOF(OFTCPSocket *) socket;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Whether encryption is required.
|
* @brief Whether encryption is required.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic) bool encryptionRequired;
|
@property (nonatomic) bool encryptionRequired;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Whether the connection is encrypted.
|
* @brief Whether the connection is encrypted.
|
||||||
*/
|
*/
|
||||||
@property (readonly, nonatomic) bool encrypted;
|
@property (readonly, nonatomic) bool encrypted;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Whether roster versioning is supported.
|
* @brief Whether roster versioning is supported.
|
||||||
*/
|
*/
|
||||||
@property (readonly, nonatomic) bool supportsRosterVersioning;
|
@property (readonly, nonatomic) bool supportsRosterVersioning;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Whether stream management is supported.
|
* @brief Whether stream management is supported.
|
||||||
*/
|
*/
|
||||||
@property (readonly, nonatomic) bool supportsStreamManagement;
|
@property (readonly, nonatomic) bool supportsStreamManagement;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Creates a new autoreleased XMPPConnection.
|
* @brief Creates a new autoreleased XMPPConnection.
|
||||||
*
|
*
|
||||||
* @return A new autoreleased XMPPConnection
|
* @return A new autoreleased XMPPConnection
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,18 +38,20 @@
|
||||||
#import <ObjFW/OFInvalidArgumentException.h>
|
#import <ObjFW/OFInvalidArgumentException.h>
|
||||||
|
|
||||||
#import "XMPPConnection.h"
|
#import "XMPPConnection.h"
|
||||||
|
#import "XMPPANONYMOUSAuth.h"
|
||||||
#import "XMPPCallback.h"
|
#import "XMPPCallback.h"
|
||||||
#import "XMPPEXTERNALAuth.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 "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 "XMPPXMLElementBuilder.h"
|
||||||
|
|
||||||
#import "namespaces.h"
|
#import "namespaces.h"
|
||||||
|
|
||||||
#import <ObjFW/macros.h>
|
#import <ObjFW/macros.h>
|
||||||
|
@ -99,6 +101,7 @@
|
||||||
@implementation XMPPConnection
|
@implementation XMPPConnection
|
||||||
@synthesize username = _username, resource = _resource, server = _server;
|
@synthesize username = _username, resource = _resource, server = _server;
|
||||||
@synthesize domain = _domain, password = _password, JID = _JID, port = _port;
|
@synthesize domain = _domain, password = _password, JID = _JID, port = _port;
|
||||||
|
@synthesize usesAnonymousAuthentication = _usesAnonymousAuthentication;
|
||||||
@synthesize language = _language, privateKeyFile = _privateKeyFile;
|
@synthesize language = _language, privateKeyFile = _privateKeyFile;
|
||||||
@synthesize certificateFile = _certificateFile, socket = _socket;
|
@synthesize certificateFile = _certificateFile, socket = _socket;
|
||||||
@synthesize encryptionRequired = _encryptionRequired, encrypted = _encrypted;
|
@synthesize encryptionRequired = _encryptionRequired, encrypted = _encrypted;
|
||||||
|
@ -1014,6 +1017,18 @@
|
||||||
for (OFXMLElement *mech in [mechs children])
|
for (OFXMLElement *mech in [mechs children])
|
||||||
[mechanisms addObject: [mech stringValue]];
|
[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 &&
|
if (_privateKeyFile != nil && _certificateFile != nil &&
|
||||||
[mechanisms containsObject: @"EXTERNAL"]) {
|
[mechanisms containsObject: @"EXTERNAL"]) {
|
||||||
_authModule = [[XMPPEXTERNALAuth alloc] init];
|
_authModule = [[XMPPEXTERNALAuth alloc] init];
|
||||||
|
@ -1051,7 +1066,10 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
@throw [XMPPAuthFailedException
|
||||||
|
exceptionWithConnection: self
|
||||||
|
reason: @"No supported auth mechanism"];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session != nil && [session elementForName: @"optional"
|
if (session != nil && [session elementForName: @"optional"
|
||||||
|
@ -1075,7 +1093,7 @@
|
||||||
namespace: XMPP_NS_SASL];
|
namespace: XMPP_NS_SASL];
|
||||||
[authTag addAttributeWithName: @"mechanism"
|
[authTag addAttributeWithName: @"mechanism"
|
||||||
stringValue: authName];
|
stringValue: authName];
|
||||||
if (initialMessage) {
|
if (initialMessage != nil) {
|
||||||
if ([initialMessage count] == 0)
|
if ([initialMessage count] == 0)
|
||||||
[authTag setStringValue: @"="];
|
[authTag setStringValue: @"="];
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue