Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
be5eab5
commit e29af14
Showing
27 changed files
with
1,937 additions
and
1,137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#import <Foundation/Foundation.h> | ||
#import "XMPPSASLAuthentication.h" | ||
#import "XMPP.h" | ||
|
||
|
||
@interface XMPPAnonymousAuthentication : NSObject <XMPPSASLAuthentication> | ||
|
||
- (id)initWithStream:(XMPPStream *)stream; | ||
|
||
// This class implements the XMPPSASLAuthentication protocol. | ||
// | ||
// See XMPPSASLAuthentication.h for more information. | ||
|
||
@end | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
#pragma mark - | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
@interface XMPPStream (XMPPAnonymousAuthentication) | ||
|
||
/** | ||
* Returns whether or not the server support anonymous authentication. | ||
* | ||
* This information is available after the stream is connected. | ||
* In other words, after the delegate has received xmppStreamDidConnect: notification. | ||
**/ | ||
- (BOOL)supportsAnonymousAuthentication; | ||
|
||
/** | ||
* This method attempts to start the anonymous authentication process. | ||
* | ||
* This method is asynchronous. | ||
* | ||
* If there is something immediately wrong, | ||
* such as the stream is not connected or doesn't support anonymous authentication, | ||
* the method will return NO and set the error. | ||
* Otherwise the delegate callbacks are used to communicate auth success or failure. | ||
* | ||
* @see xmppStreamDidAuthenticate: | ||
* @see xmppStream:didNotAuthenticate: | ||
**/ | ||
- (BOOL)authenticateAnonymously:(NSError **)errPtr; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
#import "XMPPAnonymousAuthentication.h" | ||
#import "XMPP.h" | ||
#import "XMPPLogging.h" | ||
#import "XMPPInternal.h" | ||
#import "NSXMLElement+XMPP.h" | ||
|
||
#if ! __has_feature(objc_arc) | ||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). | ||
#endif | ||
|
||
// Log levels: off, error, warn, info, verbose | ||
#if DEBUG | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_INFO; // | XMPP_LOG_FLAG_TRACE; | ||
#else | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; | ||
#endif | ||
|
||
/** | ||
* Seeing a return statements within an inner block | ||
* can sometimes be mistaken for a return point of the enclosing method. | ||
* This makes inline blocks a bit easier to read. | ||
**/ | ||
#define return_from_block return | ||
|
||
|
||
@implementation XMPPAnonymousAuthentication | ||
{ | ||
#if __has_feature(objc_arc_weak) | ||
__weak XMPPStream *xmppStream; | ||
#else | ||
__unsafe_unretained XMPPStream *xmppStream; | ||
#endif | ||
} | ||
|
||
+ (NSString *)mechanismName | ||
{ | ||
return @"ANONYMOUS"; | ||
} | ||
|
||
- (id)initWithStream:(XMPPStream *)stream | ||
{ | ||
if ((self = [super init])) | ||
{ | ||
xmppStream = stream; | ||
} | ||
return self; | ||
} | ||
|
||
- (id)initWithStream:(XMPPStream *)stream password:(NSString *)password | ||
{ | ||
return [self initWithStream:stream]; | ||
} | ||
|
||
- (BOOL)start:(NSError **)errPtr | ||
{ | ||
// <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="ANONYMOUS" /> | ||
|
||
NSXMLElement *auth = [NSXMLElement elementWithName:@"auth" xmlns:@"urn:ietf:params:xml:ns:xmpp-sasl"]; | ||
[auth addAttributeWithName:@"mechanism" stringValue:@"ANONYMOUS"]; | ||
|
||
[xmppStream sendAuthElement:auth]; | ||
|
||
return YES; | ||
} | ||
|
||
- (XMPPHandleAuthResponse)handleAuth:(NSXMLElement *)authResponse | ||
{ | ||
// We're expecting a success response. | ||
// If we get anything else we can safely assume it's the equivalent of a failure response. | ||
|
||
if ([[authResponse name] isEqualToString:@"success"]) | ||
{ | ||
return XMPP_AUTH_SUCCESS; | ||
} | ||
else | ||
{ | ||
return XMPP_AUTH_FAIL; | ||
} | ||
} | ||
|
||
@end | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
#pragma mark - | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
@implementation XMPPStream (XMPPAnonymousAuthentication) | ||
|
||
- (BOOL)supportsAnonymousAuthentication | ||
{ | ||
return [self supportsAuthenticationMechanism:[XMPPAnonymousAuthentication mechanismName]]; | ||
} | ||
|
||
- (BOOL)authenticateAnonymously:(NSError **)errPtr | ||
{ | ||
XMPPLogTrace(); | ||
|
||
__block BOOL result = YES; | ||
__block NSError *err = nil; | ||
|
||
dispatch_block_t block = ^{ @autoreleasepool { | ||
|
||
if ([self supportsAnonymousAuthentication]) | ||
{ | ||
XMPPAnonymousAuthentication *anonymousAuth = [[XMPPAnonymousAuthentication alloc] initWithStream:self]; | ||
|
||
result = [self authenticate:anonymousAuth error:&err]; | ||
} | ||
else | ||
{ | ||
NSString *errMsg = @"The server does not support anonymous authentication."; | ||
NSDictionary *info = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey]; | ||
|
||
err = [NSError errorWithDomain:XMPPStreamErrorDomain code:XMPPStreamUnsupportedAction userInfo:info]; | ||
|
||
result = NO; | ||
} | ||
}}; | ||
|
||
if (dispatch_get_current_queue() == xmppQueue) | ||
block(); | ||
else | ||
dispatch_sync(xmppQueue, block); | ||
|
||
if (errPtr) | ||
*errPtr = err; | ||
|
||
return result; | ||
} | ||
|
||
@end |
22 changes: 22 additions & 0 deletions
22
Authentication/Deprecated-Digest/XMPPDeprecatedDigestAuthentication.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#import <Foundation/Foundation.h> | ||
#import "XMPPSASLAuthentication.h" | ||
#import "XMPPStream.h" | ||
|
||
|
||
@interface XMPPDeprecatedDigestAuthentication : NSObject <XMPPSASLAuthentication> | ||
|
||
// This class implements the XMPPSASLAuthentication protocol. | ||
// | ||
// See XMPPSASLAuthentication.h for more information. | ||
|
||
@end | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
#pragma mark - | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
@interface XMPPStream (XMPPDeprecatedDigestAuthentication) | ||
|
||
- (BOOL)supportsDeprecatedDigestAuthentication; | ||
|
||
@end |
162 changes: 162 additions & 0 deletions
162
Authentication/Deprecated-Digest/XMPPDeprecatedDigestAuthentication.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
#import "XMPPDeprecatedDigestAuthentication.h" | ||
#import "XMPP.h" | ||
#import "XMPPInternal.h" | ||
#import "XMPPLogging.h" | ||
#import "NSData+XMPP.h" | ||
#import "NSXMLElement+XMPP.h" | ||
|
||
#if ! __has_feature(objc_arc) | ||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). | ||
#endif | ||
|
||
// Log levels: off, error, warn, info, verbose | ||
#if DEBUG | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_INFO; // | XMPP_LOG_FLAG_TRACE; | ||
#else | ||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; | ||
#endif | ||
|
||
|
||
@implementation XMPPDeprecatedDigestAuthentication | ||
{ | ||
#if __has_feature(objc_arc_weak) | ||
__weak XMPPStream *xmppStream; | ||
#else | ||
__unsafe_unretained XMPPStream *xmppStream; | ||
#endif | ||
|
||
NSString *password; | ||
} | ||
|
||
+ (NSString *)mechanismName | ||
{ | ||
// This deprecated method isn't listed in the normal mechanisms list | ||
return nil; | ||
} | ||
|
||
- (id)initWithStream:(XMPPStream *)stream password:(NSString *)inPassword | ||
{ | ||
if ((self = [super init])) | ||
{ | ||
xmppStream = stream; | ||
password = inPassword; | ||
} | ||
return self; | ||
} | ||
|
||
- (BOOL)start:(NSError **)errPtr | ||
{ | ||
XMPPLogTrace(); | ||
|
||
// The server does not appear to support SASL authentication (at least any type we can use) | ||
// So we'll revert back to the old fashioned jabber:iq:auth mechanism | ||
|
||
XMPPJID *myJID = xmppStream.myJID; | ||
|
||
NSString *username = [myJID user]; | ||
NSString *resource = [myJID resource]; | ||
|
||
if ([resource length] == 0) | ||
{ | ||
// If resource is nil or empty, we need to auto-create one | ||
|
||
resource = [XMPPStream generateUUID]; | ||
} | ||
|
||
NSString *rootID = [[[xmppStream rootElement] attributeForName:@"id"] stringValue]; | ||
NSString *digestStr = [NSString stringWithFormat:@"%@%@", rootID, password]; | ||
|
||
NSString *digest = [[[digestStr dataUsingEncoding:NSUTF8StringEncoding] sha1Digest] hexStringValue]; | ||
|
||
NSXMLElement *query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:auth"]; | ||
[query addChild:[NSXMLElement elementWithName:@"username" stringValue:username]]; | ||
[query addChild:[NSXMLElement elementWithName:@"resource" stringValue:resource]]; | ||
[query addChild:[NSXMLElement elementWithName:@"digest" stringValue:digest]]; | ||
|
||
XMPPIQ *iq = [XMPPIQ iqWithType:@"set"]; | ||
[iq addChild:query]; | ||
|
||
[xmppStream sendAuthElement:iq]; | ||
|
||
return YES; | ||
} | ||
|
||
- (XMPPHandleAuthResponse)handleAuth:(NSXMLElement *)authResponse | ||
{ | ||
XMPPLogTrace(); | ||
|
||
// We used the old fashioned jabber:iq:auth mechanism | ||
|
||
if ([[authResponse attributeStringValueForName:@"type"] isEqualToString:@"error"]) | ||
{ | ||
return XMPP_AUTH_FAIL; | ||
} | ||
else | ||
{ | ||
return XMPP_AUTH_SUCCESS; | ||
} | ||
} | ||
|
||
- (BOOL)shouldResendOpeningNegotiationAfterSuccessfulAuthentication | ||
{ | ||
return NO; | ||
} | ||
|
||
@end | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
#pragma mark - | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
@implementation XMPPStream (XMPPDeprecatedDigestAuthentication) | ||
|
||
/** | ||
* This method only applies to servers that don't support XMPP version 1.0, as defined in RFC 3920. | ||
* With these servers, we attempt to discover supported authentication modes via the jabber:iq:auth namespace. | ||
**/ | ||
- (BOOL)supportsDeprecatedDigestAuthentication | ||
{ | ||
__block BOOL result = NO; | ||
|
||
dispatch_block_t block = ^{ @autoreleasepool { | ||
|
||
// The root element can be properly queried for authentication mechanisms anytime after the | ||
// stream:features are received, and TLS has been setup (if required) | ||
if (state >= STATE_XMPP_POST_NEGOTIATION) | ||
{ | ||
// Search for an iq element within the rootElement. | ||
// Recall that some servers might stupidly add a "jabber:client" namespace which might cause problems | ||
// if we simply used the elementForName method. | ||
|
||
NSXMLElement *iq = nil; | ||
|
||
NSUInteger i, count = [rootElement childCount]; | ||
for (i = 0; i < count; i++) | ||
{ | ||
NSXMLNode *childNode = [rootElement childAtIndex:i]; | ||
|
||
if ([childNode kind] == NSXMLElementKind) | ||
{ | ||
if ([[childNode name] isEqualToString:@"iq"]) | ||
{ | ||
iq = (NSXMLElement *)childNode; | ||
} | ||
} | ||
} | ||
|
||
NSXMLElement *query = [iq elementForName:@"query" xmlns:@"jabber:iq:auth"]; | ||
NSXMLElement *digest = [query elementForName:@"digest"]; | ||
|
||
result = (digest != nil); | ||
} | ||
}}; | ||
|
||
if (dispatch_get_current_queue() == xmppQueue) | ||
block(); | ||
else | ||
dispatch_sync(xmppQueue, block); | ||
|
||
return result; | ||
} | ||
|
||
@end |
22 changes: 22 additions & 0 deletions
22
Authentication/Deprecated-Plain/XMPPDeprecatedPlainAuthentication.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#import <Foundation/Foundation.h> | ||
#import "XMPPSASLAuthentication.h" | ||
#import "XMPPStream.h" | ||
|
||
|
||
@interface XMPPDeprecatedPlainAuthentication : NSObject <XMPPSASLAuthentication> | ||
|
||
// This class implements the XMPPSASLAuthentication protocol. | ||
// | ||
// See XMPPSASLAuthentication.h for more information. | ||
|
||
@end | ||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
#pragma mark - | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
@interface XMPPStream (XMPPDeprecatedPlainAuthentication) | ||
|
||
- (BOOL)supportsDeprecatedPlainAuthentication; | ||
|
||
@end |
Oops, something went wrong.