Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -7,10 +7,11 @@ SRCS = XMPPAuthenticator.m \ XMPPCallback.m \ XMPPConnection.m \ XMPPExceptions.m \ + XMPPEXTERNALAuth.m \ XMPPIQ.m \ XMPPJID.m \ XMPPMessage.m \ XMPPPLAINAuth.m \ XMPPPresence.m \ Index: src/XMPPConnection.h ================================================================== --- src/XMPPConnection.h +++ src/XMPPConnection.h @@ -71,10 +71,11 @@ { id sock; OFXMLParser *parser, *oldParser; OFXMLElementBuilder *elementBuilder, *oldElementBuilder; OFString *username, *password, *server, *resource; + OFString *privateKeyFile, *certificateFile; OFString *domain, *domainToASCII; XMPPJID *JID; uint16_t port; id delegate; OFMutableDictionary *callbacks; @@ -86,10 +87,11 @@ XMPPRoster *roster; } #ifdef OF_HAVE_PROPERTIES @property (copy) OFString *username, *password, *server, *domain, *resource; +@property (copy) OFString *privateKeyFile, *certificateFile; @property (copy, readonly) XMPPJID *JID; @property (assign) uint16_t port; @property (assign) id delegate; @property (readonly, retain) XMPPRoster *roster; @property (readonly, retain, getter=socket) OFTCPSocket *sock; Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -37,10 +37,11 @@ #import #import "XMPPConnection.h" #import "XMPPCallback.h" #import "XMPPSRVLookup.h" +#import "XMPPEXTERNALAuth.h" #import "XMPPSCRAMAuth.h" #import "XMPPPLAINAuth.h" #import "XMPPStanza.h" #import "XMPPJID.h" #import "XMPPIQ.h" @@ -80,10 +81,12 @@ [sock release]; [parser release]; [elementBuilder release]; [username release]; [password release]; + [privateKeyFile release]; + [certificateFile release]; [server release]; [domain release]; [resource release]; [JID release]; [callbacks release]; @@ -217,10 +220,30 @@ - (OFString*)password { return [[password copy] autorelease]; } + +- (void)setPrivateKeyFile: (OFString*)file +{ + OF_SETTER(privateKeyFile, file, YES, YES) +} + +- (OFString*)privateKeyFile +{ + OF_GETTER(privateKeyFile, YES) +} + +- (void)setCertificateFile: (OFString*)file +{ + OF_SETTER(certificateFile, file, YES, YES) +} + +- (OFString*)certificateFile +{ + OF_GETTER(certificateFile, YES) +} - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; XMPPSRVEntry *candidate = nil; @@ -671,11 +694,13 @@ if ([delegate respondsToSelector: @selector(connectionWillUpgradeToTLS:)]) [delegate connectionWillUpgradeToTLS: self]; - newSock = [[SSLSocket alloc] initWithSocket: sock]; + newSock = [[SSLSocket alloc] initWithSocket: sock + privateKeyFile: privateKeyFile + certificateFile: certificateFile]; [sock release]; sock = newSock; encrypted = YES; @@ -816,10 +841,17 @@ OFXMLElement *mech; enumerator = [[mechs children] objectEnumerator]; while ((mech = [enumerator nextObject]) != nil) [mechanisms addObject: [mech stringValue]]; + + if (privateKeyFile && certificateFile && + [mechanisms containsObject: @"EXTERNAL"]) { + authModule = [[XMPPEXTERNALAuth alloc] init]; + [self XMPP_sendAuth: @"EXTERNAL"]; + return; + } if ([mechanisms containsObject: @"SCRAM-SHA-1-PLUS"]) { authModule = [[XMPPSCRAMAuth alloc] initWithAuthcid: username password: password