Overview
Comment: | Implement certificate checking. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
91ee08a56a29e43e2be1e47e6a7b0095 |
User & Date: | florob@babelmonkeys.de on 2011-11-22 22:07:01 |
Other Links: | manifest | tags |
Context
2011-12-11
| ||
23:27 | Add a delegate for incoming/outgoing elements. check-in: 9ee7cd4433 user: js tags: trunk | |
2011-11-22
| ||
22:07 | Implement certificate checking. check-in: 91ee08a56a user: florob@babelmonkeys.de tags: trunk | |
2011-10-24
| ||
18:32 | Don't retain the delegate to prevent a reference cycle. check-in: 3d540fd517 user: js tags: trunk | |
Changes
Modified src/XMPPConnection.h from [344503b49e] to [57152f12f4].
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | @class XMPPJID; @class XMPPIQ; @class XMPPMessage; @class XMPPPresence; @class XMPPAuthenticator; @class XMPPRoster; @class XMPPRosterItem; @protocol XMPPConnectionDelegate #ifndef XMPP_CONNECTION_M <OFObject> #endif #ifdef OF_HAVE_OPTIONAL_PROTOCOLS @optional | > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | @class XMPPJID; @class XMPPIQ; @class XMPPMessage; @class XMPPPresence; @class XMPPAuthenticator; @class XMPPRoster; @class XMPPRosterItem; @class SSLSocket; @protocol XMPPConnectionDelegate #ifndef XMPP_CONNECTION_M <OFObject> #endif #ifdef OF_HAVE_OPTIONAL_PROTOCOLS @optional |
︙ | ︙ | |||
60 61 62 63 64 65 66 | * \brief A class which abstracts a connection to an XMPP service. */ @interface XMPPConnection: OFObject #ifdef OF_HAVE_OPTONAL_PROTOCOLS <OFXMLParserDelegate, OFXMLElementBuilderDelegate> #endif { | | | > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * \brief A class which abstracts a connection to an XMPP service. */ @interface XMPPConnection: OFObject #ifdef OF_HAVE_OPTONAL_PROTOCOLS <OFXMLParserDelegate, OFXMLElementBuilderDelegate> #endif { SSLSocket *sock; OFXMLParser *parser, *oldParser; OFXMLElementBuilder *elementBuilder, *oldElementBuilder; OFString *username, *password, *server, *resource; OFString *domain, *domainToASCII; XMPPJID *JID; uint16_t port; id <XMPPConnectionDelegate, OFObject> delegate; XMPPAuthenticator *authModule; BOOL needsSession; BOOL encryptionRequired, encrypted; unsigned int lastID; |
︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 | + connection; /** * Connects to the XMPP service. */ - (void)connect; /** * Starts a loop handling incomming data. */ - (void)handleConnection; /** * Parses the specified buffer. | > > > > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | + connection; /** * Connects to the XMPP service. */ - (void)connect; /** * Checks the certificate presented by the server. * Throws SSLInvalidCertificateException on failure. */ - (void)checkCertificate; /** * Starts a loop handling incomming data. */ - (void)handleConnection; /** * Parses the specified buffer. |
︙ | ︙ | |||
180 181 182 183 184 185 186 187 188 189 190 | - (void)XMPP_handleMessage: (XMPPMessage*)message; - (void)XMPP_handlePresence: (XMPPPresence*)presence; - (void)XMPP_handleFeatures: (OFXMLElement*)element; - (void)XMPP_sendResourceBind; - (void)XMPP_handleResourceBind: (XMPPIQ*)iq; - (void)XMPP_sendSession; - (void)XMPP_handleSession: (XMPPIQ*)iq; @end @interface OFObject (XMPPConnectionDelegate) <XMPPConnectionDelegate> @end | > | 188 189 190 191 192 193 194 195 196 197 198 199 | - (void)XMPP_handleMessage: (XMPPMessage*)message; - (void)XMPP_handlePresence: (XMPPPresence*)presence; - (void)XMPP_handleFeatures: (OFXMLElement*)element; - (void)XMPP_sendResourceBind; - (void)XMPP_handleResourceBind: (XMPPIQ*)iq; - (void)XMPP_sendSession; - (void)XMPP_handleSession: (XMPPIQ*)iq; - (OFString*)XMPP_IDNAToASCII: (OFString*)domain; @end @interface OFObject (XMPPConnectionDelegate) <XMPPConnectionDelegate> @end |
Modified src/XMPPConnection.m from [cdb3217ac3] to [ce3750af92].
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <assert.h> #include <stringprep.h> #include <idna.h> #import <ObjOpenSSL/SSLSocket.h> #import "XMPPConnection.h" #import "XMPPSRVLookup.h" #import "XMPPSCRAMAuth.h" #import "XMPPPLAINAuth.h" #import "XMPPStanza.h" #import "XMPPJID.h" | > > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <assert.h> #include <stringprep.h> #include <idna.h> #import <ObjOpenSSL/SSLSocket.h> #import <ObjOpenSSL/SSLInvalidCertificateException.h> #import <ObjOpenSSL/X509Certificate.h> #import "XMPPConnection.h" #import "XMPPSRVLookup.h" #import "XMPPSCRAMAuth.h" #import "XMPPPLAINAuth.h" #import "XMPPStanza.h" #import "XMPPJID.h" |
︙ | ︙ | |||
144 145 146 147 148 149 150 | { return [[resource copy] autorelease]; } - (void)setServer: (OFString*)server_ { OFString *old = server; | < < < < < < < < < | < < < < < < < | > > > | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | { return [[resource copy] autorelease]; } - (void)setServer: (OFString*)server_ { OFString *old = server; server = [self XMPP_IDNAToASCII: server_]; [old release]; } - (OFString*)server { return [[server copy] autorelease]; } - (void)setDomain: (OFString*)domain_ { OFString *oldDomain = domain; OFString *oldDomainToASCII = domainToASCII; char *srv; Stringprep_rc rc; if ((rc = stringprep_profile([domain_ UTF8String], &srv, "Nameprep", 0)) != STRINGPREP_OK) @throw [XMPPStringPrepFailedException exceptionWithClass: isa connection: self profile: @"Nameprep" string: domain_]; @try { domain = [[OFString alloc] initWithUTF8String: srv]; } @finally { free(srv); } [oldDomain release]; domainToASCII = [self XMPP_IDNAToASCII: domain]; [oldDomainToASCII release]; } - (OFString*)domain { return [[domain copy] autorelease]; } |
︙ | ︙ | |||
231 232 233 234 235 236 237 | - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; XMPPSRVEntry *candidate = nil; XMPPSRVLookup *SRVLookup = nil; OFEnumerator *enumerator; | < < < < < < < < < < < < < < < < < < | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; XMPPSRVEntry *candidate = nil; XMPPSRVLookup *SRVLookup = nil; OFEnumerator *enumerator; if (server) [sock connectToHost: server port: port]; else { @try { SRVLookup = [XMPPSRVLookup lookupWithDomain: domainToASCII]; } @catch (id e) { } enumerator = [SRVLookup objectEnumerator]; |
︙ | ︙ | |||
338 339 340 341 342 343 344 345 346 347 348 349 350 351 | encryptionRequired = required; } - (BOOL)encrypted { return encrypted; } - (void)sendStanza: (OFXMLElement*)element { of_log(@"Out: %@", element); [sock writeString: [element XMLString]]; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | encryptionRequired = required; } - (BOOL)encrypted { return encrypted; } - (void)checkCertificate { X509Certificate *cert; OFDictionary *SANs; BOOL serviceSpecific = NO; [sock verifyPeerCertificate]; cert = [sock peerCertificate]; SANs = [cert subjectAlternativeName]; if ([[SANs objectForKey: @"otherName"] objectForKey: OID_SRVName] || [SANs objectForKey: @"dNSName"] || [SANs objectForKey: @"uniformResourceIdentifier"]) serviceSpecific = YES; if ([cert hasSRVNameMatchingDomain: domainToASCII service: @"xmpp-client"] || [cert hasDNSNameMatchingDomain: domainToASCII]) return; if (serviceSpecific || ![cert hasCommonNameMatchingDomain: domainToASCII]) @throw [SSLInvalidCertificateException exceptionWithClass: isa reason: @"No matching identifier"]; } - (void)sendStanza: (OFXMLElement*)element { of_log(@"Out: %@", element); [sock writeString: [element XMLString]]; } |
︙ | ︙ | |||
872 873 874 875 876 877 878 879 880 881 882 883 884 885 | if ([delegate respondsToSelector: @selector(connection:wasBoundToJID:)]) [delegate connection: self wasBoundToJID: JID]; [sessionID release]; sessionID = nil; } - (XMPPJID*)JID { return [[JID copy] autorelease]; } - (void)setPort: (uint16_t)port_ | > > > > > > > > > > > > > > > > > > > > > > > | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | if ([delegate respondsToSelector: @selector(connection:wasBoundToJID:)]) [delegate connection: self wasBoundToJID: JID]; [sessionID release]; sessionID = nil; } - (OFString*)XMPP_IDNAToASCII: (OFString*)domain_ { OFString *ret; char *cDomain; Idna_rc rc; if ((rc = idna_to_ascii_8z([domain_ UTF8String], &cDomain, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) @throw [XMPPIDNATranslationFailedException exceptionWithClass: isa connection: self operation: @"ToASCII" string: domain_]; @try { ret = [[OFString alloc] initWithUTF8String: cDomain]; } @finally { free(cDomain); } return ret; } - (XMPPJID*)JID { return [[JID copy] autorelease]; } - (void)setPort: (uint16_t)port_ |
︙ | ︙ |
Modified tests/test.m from [5b97008ac4] to [c0b9f87604].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <assert.h> #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPJID.h" #import "XMPPStanza.h" #import "XMPPIQ.h" #import "XMPPMessage.h" #import "XMPPPresence.h" | > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <assert.h> #import <ObjFW/ObjFW.h> #import <ObjOpenSSL/SSLInvalidCertificateException.h> #import "XMPPConnection.h" #import "XMPPJID.h" #import "XMPPStanza.h" #import "XMPPIQ.h" #import "XMPPMessage.h" #import "XMPPPresence.h" |
︙ | ︙ | |||
131 132 133 134 135 136 137 138 139 140 141 142 143 144 | pres = [XMPPPresence presence]; [pres addPriority: 10]; [pres addStatus: @"ObjXMPP test is working!"]; [conn sendStanza: pres]; } - (void)connection: (XMPPConnection*)conn didReceiveRosterItem: (XMPPRosterItem*)rosterItem { of_log(@"Got roster push: %@", rosterItem); } | > > > > > > > > > > > > > > > | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | pres = [XMPPPresence presence]; [pres addPriority: 10]; [pres addStatus: @"ObjXMPP test is working!"]; [conn sendStanza: pres]; } - (void)connectionDidUpgradeToTLS: (XMPPConnection*)conn { @try { [conn checkCertificate]; } @catch (SSLInvalidCertificateException *e) { OFString *answer; [of_stdout writeString: @"Couldn't verify certificate: "]; [of_stdout writeFormat: @"%@\n", e]; [of_stdout writeString: @"Do you want to continue [y/N]? "]; answer = [of_stdin readLine]; if (![answer hasPrefix: @"y"]) @throw e; } } - (void)connection: (XMPPConnection*)conn didReceiveRosterItem: (XMPPRosterItem*)rosterItem { of_log(@"Got roster push: %@", rosterItem); } |
︙ | ︙ |