Add support for SCRAM-SHA-1-PLUS
This commit is contained in:
parent
b24c7500fd
commit
62d2bd2ba5
4 changed files with 88 additions and 18 deletions
|
@ -73,6 +73,7 @@
|
||||||
id <XMPPConnectionDelegate, OFObject> delegate;
|
id <XMPPConnectionDelegate, OFObject> delegate;
|
||||||
XMPPAuthenticator *authModule;
|
XMPPAuthenticator *authModule;
|
||||||
BOOL needsSession;
|
BOOL needsSession;
|
||||||
|
BOOL encrypted;
|
||||||
unsigned int lastID;
|
unsigned int lastID;
|
||||||
OFString *bindID, *sessionID;
|
OFString *bindID, *sessionID;
|
||||||
XMPPRoster *roster;
|
XMPPRoster *roster;
|
||||||
|
@ -85,6 +86,7 @@
|
||||||
@property (retain) id <XMPPConnectionDelegate> delegate;
|
@property (retain) id <XMPPConnectionDelegate> delegate;
|
||||||
@property (readonly, retain) XMPPRoster *roster;
|
@property (readonly, retain) XMPPRoster *roster;
|
||||||
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
|
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
|
||||||
|
@property (readonly) BOOL encrypted;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,6 +121,11 @@
|
||||||
*/
|
*/
|
||||||
- (OFTCPSocket*)socket;
|
- (OFTCPSocket*)socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \return Whether the connection is encrypted
|
||||||
|
*/
|
||||||
|
- (BOOL)encrypted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an OFXMLElement, usually an XMPPStanza.
|
* Sends an OFXMLElement, usually an XMPPStanza.
|
||||||
*
|
*
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
@try {
|
@try {
|
||||||
sock = [[OFTCPSocket alloc] init];
|
sock = [[OFTCPSocket alloc] init];
|
||||||
port = 5222;
|
port = 5222;
|
||||||
|
encrypted = NO;
|
||||||
} @catch (id e) {
|
} @catch (id e) {
|
||||||
[self release];
|
[self release];
|
||||||
@throw e;
|
@throw e;
|
||||||
|
@ -328,6 +329,11 @@
|
||||||
return [[sock retain] autorelease];
|
return [[sock retain] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)encrypted
|
||||||
|
{
|
||||||
|
return encrypted;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)sendStanza: (OFXMLElement*)element
|
- (void)sendStanza: (OFXMLElement*)element
|
||||||
{
|
{
|
||||||
of_log(@"Out: %@", element);
|
of_log(@"Out: %@", element);
|
||||||
|
@ -577,6 +583,8 @@
|
||||||
[sock release];
|
[sock release];
|
||||||
sock = newSock;
|
sock = newSock;
|
||||||
|
|
||||||
|
encrypted = YES;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
if ([delegate respondsToSelector:
|
||||||
@selector(connectionDidUpgradeToTLS:)])
|
@selector(connectionDidUpgradeToTLS:)])
|
||||||
[delegate connectionDidUpgradeToTLS: self];
|
[delegate connectionDidUpgradeToTLS: self];
|
||||||
|
@ -711,16 +719,29 @@
|
||||||
while ((mech = [enumerator nextObject]) != nil)
|
while ((mech = [enumerator nextObject]) != nil)
|
||||||
[mechanisms addObject: [mech stringValue]];
|
[mechanisms addObject: [mech stringValue]];
|
||||||
|
|
||||||
|
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"]) {
|
if ([mechanisms containsObject: @"SCRAM-SHA-1"]) {
|
||||||
authModule = [[XMPPSCRAMAuth alloc]
|
authModule = [[XMPPSCRAMAuth alloc]
|
||||||
initWithAuthcid: username
|
initWithAuthcid: username
|
||||||
password: password
|
password: password
|
||||||
hash: [OFSHA1Hash class]];
|
connection: self
|
||||||
|
hash: [OFSHA1Hash class]
|
||||||
|
plusAvailable: NO];
|
||||||
[self XMPP_sendAuth: @"SCRAM-SHA-1"];
|
[self XMPP_sendAuth: @"SCRAM-SHA-1"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([mechanisms containsObject: @"PLAIN"]) {
|
if ([mechanisms containsObject: @"PLAIN"] && encrypted) {
|
||||||
authModule = [[XMPPPLAINAuth alloc]
|
authModule = [[XMPPPLAINAuth alloc]
|
||||||
initWithAuthcid: username
|
initWithAuthcid: username
|
||||||
password: password];
|
password: password];
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#import <ObjFW/ObjFW.h>
|
#import <ObjFW/ObjFW.h>
|
||||||
#import "XMPPAuthenticator.h"
|
#import "XMPPAuthenticator.h"
|
||||||
|
#import "XMPPConnection.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A class to authenticate using SCRAM
|
* \brief A class to authenticate using SCRAM
|
||||||
|
@ -33,6 +34,8 @@
|
||||||
OFString *GS2Header;
|
OFString *GS2Header;
|
||||||
OFString *clientFirstMessageBare;
|
OFString *clientFirstMessageBare;
|
||||||
OFDataArray *serverSignature;
|
OFDataArray *serverSignature;
|
||||||
|
XMPPConnection *connection;
|
||||||
|
BOOL plusAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,12 +43,16 @@
|
||||||
*
|
*
|
||||||
* \param authcid The authcid to authenticate with
|
* \param authcid The authcid to authenticate with
|
||||||
* \param password The password to authenticate with
|
* \param password The password to authenticate with
|
||||||
|
* \param connection The connection over which authentication is done
|
||||||
* \param hash The class to use for calulating hashes
|
* \param hash The class to use for calulating hashes
|
||||||
|
* \param plusAvailable Whether the PLUS variant was offered
|
||||||
* \return A new autoreleased XMPPSCRAMAuth
|
* \return A new autoreleased XMPPSCRAMAuth
|
||||||
*/
|
*/
|
||||||
+ SCRAMAuthWithAuthcid: (OFString*)authcid
|
+ SCRAMAuthWithAuthcid: (OFString*)authcid
|
||||||
password: (OFString*)password
|
password: (OFString*)password
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new autoreleased XMPPSCRAMAuth with an authzid,
|
* Creates a new autoreleased XMPPSCRAMAuth with an authzid,
|
||||||
|
@ -54,25 +61,33 @@
|
||||||
* \param authzid The authzid to get authorization for
|
* \param authzid The authzid to get authorization for
|
||||||
* \param authcid The authcid to authenticate with
|
* \param authcid The authcid to authenticate with
|
||||||
* \param password The password to authenticate with
|
* \param password The password to authenticate with
|
||||||
|
* \param connection The connection over which authentication is done
|
||||||
* \param hash The class to use for calulating hashes
|
* \param hash The class to use for calulating hashes
|
||||||
|
* \param plusAvailable Whether the PLUS variant was offered
|
||||||
* \return A new autoreleased XMPPSCRAMAuth
|
* \return A new autoreleased XMPPSCRAMAuth
|
||||||
*/
|
*/
|
||||||
+ SCRAMAuthWithAuthzid: (OFString*)authzid
|
+ SCRAMAuthWithAuthzid: (OFString*)authzid
|
||||||
authcid: (OFString*)authcid
|
authcid: (OFString*)authcid
|
||||||
password: (OFString*)password
|
password: (OFString*)password
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an already allocated XMPPSCRAMAuth with an authcid and password.
|
* Initializes an already allocated XMPPSCRAMAuth with an authcid and password.
|
||||||
*
|
*
|
||||||
* \param authcid The authcid to authenticate with
|
* \param authcid The authcid to authenticate with
|
||||||
* \param password The password to authenticate with
|
* \param password The password to authenticate with
|
||||||
|
* \param connection The connection over which authentication is done
|
||||||
* \param hash The class to use for calulating hashes
|
* \param hash The class to use for calulating hashes
|
||||||
|
* \param plusAvailable Whether the PLUS variant was offered
|
||||||
* \return A initialized XMPPSCRAMAuth
|
* \return A initialized XMPPSCRAMAuth
|
||||||
*/
|
*/
|
||||||
- initWithAuthcid: (OFString*)authcid
|
- initWithAuthcid: (OFString*)authcid
|
||||||
password: (OFString*)password
|
password: (OFString*)password
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an already allocated XMPPSCRAMAuth with a authzid,
|
* Initializes an already allocated XMPPSCRAMAuth with a authzid,
|
||||||
|
@ -81,13 +96,17 @@
|
||||||
* \param authzid The authzid to get authorization for
|
* \param authzid The authzid to get authorization for
|
||||||
* \param authcid The authcid to authenticate with
|
* \param authcid The authcid to authenticate with
|
||||||
* \param password The password to authenticate with
|
* \param password The password to authenticate with
|
||||||
|
* \param connection The connection over which authentication is done
|
||||||
* \param hash The class to use for calulating hashes
|
* \param hash The class to use for calulating hashes
|
||||||
|
* \param plusAvailable Whether the PLUS variant was offered
|
||||||
* \return A initialized XMPPSCRAMAuth
|
* \return A initialized XMPPSCRAMAuth
|
||||||
*/
|
*/
|
||||||
- initWithAuthzid: (OFString*)authzid
|
- initWithAuthzid: (OFString*)authzid
|
||||||
authcid: (OFString*)authcid
|
authcid: (OFString*)authcid
|
||||||
password: (OFString*)password
|
password: (OFString*)password
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable;
|
||||||
|
|
||||||
- (OFString*)XMPP_genNonce;
|
- (OFString*)XMPP_genNonce;
|
||||||
- (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key
|
- (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
#import <ObjOpenSSL/SSLSocket.h>
|
||||||
|
|
||||||
#import "XMPPSCRAMAuth.h"
|
#import "XMPPSCRAMAuth.h"
|
||||||
#import "XMPPExceptions.h"
|
#import "XMPPExceptions.h"
|
||||||
|
|
||||||
|
@ -40,44 +40,60 @@
|
||||||
@implementation XMPPSCRAMAuth
|
@implementation XMPPSCRAMAuth
|
||||||
+ SCRAMAuthWithAuthcid: (OFString*)authcid
|
+ SCRAMAuthWithAuthcid: (OFString*)authcid
|
||||||
password: (OFString*)password
|
password: (OFString*)password
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection_
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable_
|
||||||
{
|
{
|
||||||
return [[[self alloc] initWithAuthcid: authcid
|
return [[[self alloc] initWithAuthcid: authcid
|
||||||
password: password
|
password: password
|
||||||
hash: hash] autorelease];
|
connection: connection_
|
||||||
|
hash: hash
|
||||||
|
plusAvailable: plusAvailable_] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ SCRAMAuthWithAuthzid: (OFString*)authzid
|
+ SCRAMAuthWithAuthzid: (OFString*)authzid
|
||||||
authcid: (OFString*)authcid
|
authcid: (OFString*)authcid
|
||||||
password: (OFString*)password
|
password: (OFString*)password
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection_
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable_
|
||||||
{
|
{
|
||||||
return [[[self alloc] initWithAuthzid: authzid
|
return [[[self alloc] initWithAuthzid: authzid
|
||||||
authcid: authcid
|
authcid: authcid
|
||||||
password: password
|
password: password
|
||||||
hash: hash] autorelease];
|
connection: connection_
|
||||||
|
hash: hash
|
||||||
|
plusAvailable: plusAvailable_] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithAuthcid: (OFString*)authcid_
|
- initWithAuthcid: (OFString*)authcid_
|
||||||
password: (OFString*)password_
|
password: (OFString*)password_
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection_
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable_
|
||||||
{
|
{
|
||||||
return [self initWithAuthzid: nil
|
return [self initWithAuthzid: nil
|
||||||
authcid: authcid_
|
authcid: authcid_
|
||||||
password: password_
|
password: password_
|
||||||
hash: hash];
|
connection: connection_
|
||||||
|
hash: hash
|
||||||
|
plusAvailable: plusAvailable_];
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithAuthzid: (OFString*)authzid_
|
- initWithAuthzid: (OFString*)authzid_
|
||||||
authcid: (OFString*)authcid_
|
authcid: (OFString*)authcid_
|
||||||
password: (OFString*)password_
|
password: (OFString*)password_
|
||||||
hash: (Class)hash;
|
connection: (XMPPConnection*)connection_
|
||||||
|
hash: (Class)hash
|
||||||
|
plusAvailable: (BOOL)plusAvailable_
|
||||||
{
|
{
|
||||||
self = [super initWithAuthzid: authzid_
|
self = [super initWithAuthzid: authzid_
|
||||||
authcid: authcid_
|
authcid: authcid_
|
||||||
password: password_];
|
password: password_];
|
||||||
|
|
||||||
hashType = hash;
|
hashType = hash;
|
||||||
|
plusAvailable = plusAvailable_;
|
||||||
|
connection = [connection_ retain];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +104,7 @@
|
||||||
[clientFirstMessageBare release];
|
[clientFirstMessageBare release];
|
||||||
[serverSignature release];
|
[serverSignature release];
|
||||||
[cNonce release];
|
[cNonce release];
|
||||||
|
[connection release];
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -134,10 +151,10 @@
|
||||||
GS2Header = nil;
|
GS2Header = nil;
|
||||||
|
|
||||||
if (authzid)
|
if (authzid)
|
||||||
GS2Header = [[OFString alloc] initWithFormat: @"n,a=%@,",
|
GS2Header = [[OFString alloc] initWithFormat: @"%@,a=%@,",
|
||||||
authzid];
|
(plusAvailable ? @"p=tls-unique" : @"y"), authzid];
|
||||||
else
|
else
|
||||||
GS2Header = @"n,,";
|
GS2Header = plusAvailable ? @"p=tls-unique,," : @"y,,";
|
||||||
|
|
||||||
[cNonce release];
|
[cNonce release];
|
||||||
cNonce = nil;
|
cNonce = nil;
|
||||||
|
@ -216,6 +233,12 @@
|
||||||
tmpArray = [OFDataArray dataArrayWithItemSize: 1];
|
tmpArray = [OFDataArray dataArrayWithItemSize: 1];
|
||||||
[tmpArray addNItems: [GS2Header cStringLength]
|
[tmpArray addNItems: [GS2Header cStringLength]
|
||||||
fromCArray: [GS2Header cString]];
|
fromCArray: [GS2Header cString]];
|
||||||
|
if (plusAvailable && [connection encrypted]) {
|
||||||
|
OFDataArray *channelBinding = [((SSLSocket*)[connection socket])
|
||||||
|
channelBindingDataWithType: @"tls-unique"];
|
||||||
|
[tmpArray addNItems: [channelBinding count]
|
||||||
|
fromCArray: [channelBinding cArray]];
|
||||||
|
}
|
||||||
tmpString = [tmpArray stringByBase64Encoding];
|
tmpString = [tmpArray stringByBase64Encoding];
|
||||||
[ret addNItems: 2
|
[ret addNItems: 2
|
||||||
fromCArray: "c="];
|
fromCArray: "c="];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue