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