Comment: | Adjust to ObjFW changes |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
2faf18cba740568fdb3ecd3cc4bb6fdf |
User & Date: | js on 2017-05-13 15:03:44 |
Other Links: | manifest | tags |
2017-07-23
| ||
11:19 | Adjust to ObjFW changes & small fixes check-in: efaee4fc4c user: js tags: trunk | |
2017-05-13
| ||
15:03 | Adjust to ObjFW changes check-in: 2faf18cba7 user: js tags: trunk | |
2017-04-30
| ||
15:04 | Fix URL in copyright header check-in: 4663b00cb4 user: js tags: trunk | |
Modified src/XMPPAuthenticator.h from [32835f9423] to [d2168a1fd5].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> /** * \brief A base class for classes implementing authentication mechanisms */ @interface XMPPAuthenticator: OFObject { OFString *_authzid, *_authcid, *_password; } /// \brief The authzid to get authorization for | > > | | | | | | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN /** * \brief A base class for classes implementing authentication mechanisms */ @interface XMPPAuthenticator: OFObject { OFString *_authzid, *_authcid, *_password; } /// \brief The authzid to get authorization for @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *authzid; /// \brief The authcid to authenticate with @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *authcid; /// \brief The password to authenticate with @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *password; /** * \brief Initializes an already allocated XMPPAuthenticator with an authcid * and password. * * \param authcid The authcid to authenticate with * \param password The password to authenticate with * \return A initialized XMPPAuthenticator */ - initWithAuthcid: (nullable OFString *)authcid password: (nullable OFString *)password; /** * \brief Initializes an already allocated XMPPSCRAMAuthenticator with an * authzid, authcid and password. * * \param authzid The authzid to get authorization for * \param authcid The authcid to authenticate with * \param password The password to authenticate with * \return A initialized XMPPAuthenticator */ - initWithAuthzid: (nullable OFString *)authzid authcid: (nullable OFString *)authcid password: (nullable OFString *)password OF_DESIGNATED_INITIALIZER; /** * \brief Returns an OFDataArray containing the initial authentication message. * * \return An OFDataAray containing the initial authentication message */ - (OFDataArray *)initialMessage; /** * \brief Continue authentication with the specified data. * * \param data The continuation data send by the server * \return The appropriate response if the data was a challenge, nil otherwise */ - (nullable OFDataArray *)continueWithData: (OFDataArray *)data; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPAuthenticator.m from [ff883875bb] to [8f69cece0e].
︙ | ︙ | |||
26 27 28 29 30 31 32 | #endif #import "XMPPAuthenticator.h" @implementation XMPPAuthenticator @synthesize authzid = _authzid, authcid = _authcid, password = _password; | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #endif #import "XMPPAuthenticator.h" @implementation XMPPAuthenticator @synthesize authzid = _authzid, authcid = _authcid, password = _password; - initWithAuthcid: (OFString *)authcid password: (OFString *)password { return [self initWithAuthzid: nil authcid: authcid password: password]; } - initWithAuthzid: (OFString *)authzid authcid: (OFString *)authcid password: (OFString *)password { self = [super init]; @try { _authzid = [authzid copy]; _authcid = [authcid copy]; _password = [password copy]; |
︙ | ︙ | |||
61 62 63 64 65 66 67 | [_authzid release]; [_authcid release]; [_password release]; [super dealloc]; } | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | [_authzid release]; [_authcid release]; [_password release]; [super dealloc]; } - (OFDataArray *)initialMessage { return nil; } - (OFDataArray *)continueWithData: (OFDataArray *)challenge { return nil; } @end |
Modified src/XMPPCallback.h from [48a5d16844] to [ee73746306].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> @class XMPPConnection; @class XMPPIQ; #ifdef OF_HAVE_BLOCKS | > > | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @class XMPPConnection; @class XMPPIQ; #ifdef OF_HAVE_BLOCKS typedef void (^xmpp_callback_block_t)(XMPPConnection *_Nonnull, XMPPIQ *_Nonnull); #endif @interface XMPPCallback: OFObject { id _target; SEL _selector; #ifdef OF_HAVE_BLOCKS |
︙ | ︙ | |||
44 45 46 47 48 49 50 | #endif + (instancetype)callbackWithTarget: (id)target selector: (SEL)selector; - initWithTarget: (id)target selector: (SEL)selector; | | | > > | 47 48 49 50 51 52 53 54 55 56 57 58 | #endif + (instancetype)callbackWithTarget: (id)target selector: (SEL)selector; - initWithTarget: (id)target selector: (SEL)selector; - (void)runWithIQ: (XMPPIQ *)iq connection: (XMPPConnection *)connection; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPCallback.m from [e144c7f667] to [7b928d9476].
︙ | ︙ | |||
26 27 28 29 30 31 32 | #import "XMPPCallback.h" @implementation XMPPCallback #ifdef OF_HAVE_BLOCKS + (instancetype)callbackWithBlock: (xmpp_callback_block_t)block { | > | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #import "XMPPCallback.h" @implementation XMPPCallback #ifdef OF_HAVE_BLOCKS + (instancetype)callbackWithBlock: (xmpp_callback_block_t)block { return [[(XMPPCallback *)[self alloc] initWithBlock: block] autorelease]; } - initWithBlock: (xmpp_callback_block_t)block { self = [super init]; @try { |
︙ | ︙ | |||
72 73 74 75 76 77 78 | #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } | | | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (void)runWithIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(connection, IQ); else #endif [_target performSelector: _selector withObject: connection withObject: IQ]; } @end |
Modified src/XMPPConnection.h from [d8b74359c0] to [423e3fef12].
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | */ #import <ObjFW/ObjFW.h> #import "XMPPCallback.h" #import "XMPPStorage.h" @class XMPPConnection; @class XMPPJID; @class XMPPIQ; @class XMPPMessage; @class XMPPPresence; @class XMPPAuthenticator; @class SSLSocket; @class XMPPMulticastDelegate; /** | > > | | < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | */ #import <ObjFW/ObjFW.h> #import "XMPPCallback.h" #import "XMPPStorage.h" OF_ASSUME_NONNULL_BEGIN @class XMPPConnection; @class XMPPJID; @class XMPPIQ; @class XMPPMessage; @class XMPPPresence; @class XMPPAuthenticator; @class SSLSocket; @class XMPPMulticastDelegate; /** * \brief A protocol that should be (partially) implemented by delegates of a * @ref XMPPConnection */ @protocol XMPPConnectionDelegate @optional /** * \brief This callback is called when the connection received an element. * * \param connection The connection that received the element * \param element The element that was received */ - (void)connection: (XMPPConnection *)connection didReceiveElement: (OFXMLElement *)element; /** * \brief This callback is called when the connection sent an element. * * \param connection The connection that sent the element * \param element The element that was sent */ - (void)connection: (XMPPConnection *)connection didSendElement: (OFXMLElement *)element; /** * \brief This callback is called when the connection sucessfully authenticated. * * \param connection The connection that was authenticated */ - (void)connectionWasAuthenticated: (XMPPConnection *)connection; /** * \brief This callback is called when the connection was bound to a JID. * * \param connection The connection that was bound to a JID * \param JID The JID the conecction was bound to */ - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID; /** * \brief This callback is called when the connection received an IQ stanza. * * \param connection The connection that received the stanza * \param iq The IQ stanza that was received */ - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)iq; /** * \brief This callback is called when the connection received a presence * stanza. * * \param connection The connection that received the stanza * \param presence The presence stanza that was received */ - (void)connection: (XMPPConnection *)connection didReceivePresence: (XMPPPresence *)presence; /** * \brief This callback is called when the connection received a message stanza. * * \param connection The connection that received the stanza * \param message The message stanza that was received */ - (void)connection: (XMPPConnection *)connection didReceiveMessage: (XMPPMessage *)message; /** * \brief This callback is called when the connection was closed. * * \param connection The connection that was closed */ - (void)connectionWasClosed: (XMPPConnection *)connection; /*! * @brief This callback is called when the connection threw an exception. * * This is only called for connections on which * @ref XMPPConnection::handleConnection has been called. * * @param connection The connection which threw an exception * @param exception The exception the connection threw */ - (void)connection: (XMPPConnection *)connection didThrowException: (OFException *)exception; /** * \brief This callback is called when the connection is about to upgrade to * TLS. * * \param connection The connection that will upgraded to TLS */ - (void)connectionWillUpgradeToTLS: (XMPPConnection *)connection; /** * \brief This callback is called when the connection was upgraded to use TLS. * * \param connection The connection that was upgraded to TLS */ - (void)connectionDidUpgradeToTLS: (XMPPConnection *)connection; @end /** * \brief A class which abstracts a connection to an XMPP service. */ @interface XMPPConnection: OFObject <OFXMLParserDelegate, OFXMLElementBuilderDelegate> { id _socket; OFXMLParser *_parser, *_oldParser; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; OFString *_username, *_password, *_server, *_resource; OFString *_privateKeyFile, *_certificateFile; const char *_privateKeyPassphrase; OFString *_domain, *_domainToASCII; XMPPJID *_JID; uint16_t _port; id <XMPPStorage> _dataStorage; OFString *_language; XMPPMulticastDelegate *_delegates; OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks; XMPPAuthenticator *_authModule; bool _streamOpen; bool _needsSession; bool _encryptionRequired, _encrypted; bool _supportsRosterVersioning; bool _supportsStreamManagement; unsigned int _lastID; } /// \brief The username to use for authentication @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *username; /// \brief The password to use for authentication @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *password; /** * \brief The server to use for the connection * * This is useful if the address of the server is different from the domain. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *server; /// \brief The domain to connect to @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *domain; /// \brief The resource to request for the connection @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *resource; /// \brief The language to request for the connection @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *language; /// \brief A private key file to use for authentication @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *privateKeyFile; /// \brief A certificate file to use for authentication @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *certificateFile; /// \brief The JID the server assigned to the connection after binding @property (readonly, nonatomic) XMPPJID *JID; /// \brief The port to connect to @property uint16_t port; /// \brief An object for data storage, conforming to the XMPPStorage protocol @property OF_NULLABLE_PROPERTY (assign) id <XMPPStorage> dataStorage; /// \brief The socket used for the connection @property (readonly, nonatomic) OFTCPSocket *socket; /// \brief Whether encryption is required @property bool encryptionRequired; /// \brief Whether the connection is encrypted @property (readonly) bool encrypted; /// \brief Whether roster versioning is supported @property (readonly) bool supportsRosterVersioning; /// \brief Whether stream management is supported |
︙ | ︙ | |||
243 244 245 246 247 248 249 | * pointer to the reason why the certificate is not valid * * \param reason A pointer to an OFString which is set to a reason in case the * certificate is not valid (otherwise, it does not touch it). * Passing NULL means the reason is not stored anywhere. * \return Whether the certificate is valid */ | | > | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | * pointer to the reason why the certificate is not valid * * \param reason A pointer to an OFString which is set to a reason in case the * certificate is not valid (otherwise, it does not touch it). * Passing NULL means the reason is not stored anywhere. * \return Whether the certificate is valid */ - (bool)checkCertificateAndGetReason: (OFString *__autoreleasing _Nonnull *_Nullable)reason; /** * \brief Adds the connection to the run loop. */ - (void)handleConnection; /** |
︙ | ︙ | |||
265 266 267 268 269 270 271 | * * This is useful for handling multiple connections at once. * * \param buffer The buffer to parse * \param length The length of the buffer. If length is 0, it is assumed that * the connection was closed. */ | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | * * This is useful for handling multiple connections at once. * * \param buffer The buffer to parse * \param length The length of the buffer. If length is 0, it is assumed that * the connection was closed. */ - (void)parseBuffer: (const void *)buffer length: (size_t)length; /** * \brief Sends an OFXMLElement, usually an XMPPStanza. * * \param element The element to send */ - (void)sendStanza: (OFXMLElement *)element; /*! * @brief Sends an XMPPIQ, registering a callback method. * * @param IQ The IQ to send * @param target The object that contains the callback method * @param selector The selector of the callback method, * must take exactly one parameter of type `XMPPIQ *` */ - (void)sendIQ: (XMPPIQ *)IQ callbackTarget: (id)target selector: (SEL)selector; #ifdef OF_HAVE_BLOCKS /*! * @brief Sends an XMPPIQ, registering a callback block. * * @param IQ The IQ to send * @param block The callback block */ - (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (xmpp_callback_block_t)block; #endif /** * \brief Generates a new, unique stanza ID. * * \return A new, generated, unique stanza ID. */ - (OFString *)generateStanzaID; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPConnection.m from [26c4d1cce6] to [e5df95b15f].
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #import "XMPPExceptions.h" #import "XMPPXMLElementBuilder.h" #import "namespaces.h" #import <ObjFW/macros.h> #define BUFFER_LENGTH 512 @interface XMPPConnection_ConnectThread: OFThread { OFThread *_sourceThread; XMPPConnection *_connection; } | > > > > > > > > > > > > > > > > > > > > > > > > > | | > > | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #import "XMPPExceptions.h" #import "XMPPXMLElementBuilder.h" #import "namespaces.h" #import <ObjFW/macros.h> #define BUFFER_LENGTH 512 OF_ASSUME_NONNULL_BEGIN @interface XMPPConnection () - (void)XMPP_startStream; - (void)XMPP_handleStream: (OFXMLElement *)element; - (void)XMPP_handleTLS: (OFXMLElement *)element; - (void)XMPP_handleSASL: (OFXMLElement *)element; - (void)XMPP_handleStanza: (OFXMLElement *)element; - (void)XMPP_sendAuth: (OFString *)authName; - (void)XMPP_sendResourceBind; - (void)XMPP_sendStreamError: (OFString *)condition text: (nullable OFString *)text; - (void)XMPP_handleIQ: (XMPPIQ *)IQ; - (void)XMPP_handleMessage: (XMPPMessage *)message; - (void)XMPP_handlePresence: (XMPPPresence *)presence; - (void)XMPP_handleFeatures: (OFXMLElement *)element; - (void)XMPP_handleResourceBindForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ; - (void)XMPP_sendSession; - (void)XMPP_handleSessionForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ; - (OFString *)XMPP_IDNAToASCII: (OFString *)domain; - (XMPPMulticastDelegate *)XMPP_delegates; @end @interface XMPPConnection_ConnectThread: OFThread { OFThread *_sourceThread; XMPPConnection *_connection; } - initWithSourceThread: (OFThread *)sourceThread connection: (XMPPConnection *)connection; @end OF_ASSUME_NONNULL_END @implementation XMPPConnection_ConnectThread - initWithSourceThread: (OFThread *)sourceThread connection: (XMPPConnection *)connection { self = [super init]; @try { _sourceThread = [sourceThread retain]; _connection = [connection retain]; } @catch (id e) { |
︙ | ︙ | |||
114 115 116 117 118 119 120 | [pool release]; return nil; } @end @implementation XMPPConnection | > > | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | [pool release]; return nil; } @end @implementation XMPPConnection @synthesize username = _username, resource = _resource, server = _server; @synthesize domain = _domain, password = _password, language = _language; @synthesize privateKeyFile = _privateKeyFile; @synthesize certificateFile = _certificateFile, socket = _socket; @synthesize encryptionRequired = _encryptionRequired, encrypted = _encrypted; @synthesize supportsRosterVersioning = _supportsRosterVersioning; @synthesize supportsStreamManagement = _supportsStreamManagement; + (instancetype)connection { |
︙ | ︙ | |||
161 162 163 164 165 166 167 | [_delegates release]; [_callbacks release]; [_authModule release]; [super dealloc]; } | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | [_delegates release]; [_callbacks release]; [_authModule release]; [super dealloc]; } - (void)setUsername: (OFString *)username { OFString *old = _username; if (username != nil) { char *node; Stringprep_rc rc; |
︙ | ︙ | |||
187 188 189 190 191 192 193 | } } else _username = nil; [old release]; } | < < < < < | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | } } else _username = nil; [old release]; } - (void)setResource: (OFString *)resource { OFString *old = _resource; if (resource != nil) { char *res; Stringprep_rc rc; |
︙ | ︙ | |||
218 219 220 221 222 223 224 | } } else _resource = nil; [old release]; } | < < < < < | < < < < < | | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | } } else _resource = nil; [old release]; } - (void)setServer: (OFString *)server { OFString *old = _server; if (server != nil) _server = [self XMPP_IDNAToASCII: server]; else _server = nil; [old release]; } - (void)setDomain: (OFString *)domain { OFString *oldDomain = _domain; OFString *oldDomainToASCII = _domainToASCII; if (domain != nil) { char *srv; Stringprep_rc rc; |
︙ | ︙ | |||
272 273 274 275 276 277 278 | _domainToASCII = nil; } [oldDomain release]; [oldDomainToASCII release]; } | < < < < < | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | _domainToASCII = nil; } [oldDomain release]; [oldDomainToASCII release]; } - (void)setPassword: (OFString *)password { OFString *old = _password; if (password != nil) { char *pass; Stringprep_rc rc; |
︙ | ︙ | |||
303 304 305 306 307 308 309 | } } else _password = nil; [old release]; } | < < < < < | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | } } else _password = nil; [old release]; } - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; XMPPSRVEntry *candidate = nil; XMPPSRVLookup *SRVLookup = nil; OFEnumerator *enumerator; |
︙ | ︙ | |||
378 379 380 381 382 383 384 | [[[[XMPPConnection_ConnectThread alloc] initWithSourceThread: [OFThread currentThread] connection: self] autorelease] start]; [pool release]; } | | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | [[[[XMPPConnection_ConnectThread alloc] initWithSourceThread: [OFThread currentThread] connection: self] autorelease] start]; [pool release]; } - (bool)XMPP_parseBuffer: (const void *)buffer length: (size_t)length { if ([_socket isAtEndOfStream]) { [_delegates broadcastSelector: @selector(connectionWasClosed:) withObject: self]; return false; } |
︙ | ︙ | |||
400 401 402 403 404 405 406 | [self close]; return false; } return true; } | | | | | | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | [self close]; return false; } return true; } - (void)parseBuffer: (const void *)buffer length: (size_t)length { [self XMPP_parseBuffer: buffer length: length]; [_oldParser release]; [_oldElementBuilder release]; _oldParser = nil; _oldElementBuilder = nil; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (char *)buffer length: (size_t)length exception: (OFException *)exception { if (exception != nil) { [_delegates broadcastSelector: @selector(connection: didThrowException:) withObject: self withObject: exception]; [self close]; |
︙ | ︙ | |||
465 466 467 468 469 470 471 | } - (bool)streamOpen { return _streamOpen; } | | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | } - (bool)streamOpen { return _streamOpen; } - (bool)checkCertificateAndGetReason: (OFString **)reason { X509Certificate *cert; OFDictionary *SANs; bool serviceSpecific = false; @try { [_socket verifyPeerCertificate]; |
︙ | ︙ | |||
501 502 503 504 505 506 507 | if (!serviceSpecific && [cert hasCommonNameMatchingDomain: _domainToASCII]) return true; return false; } | | | | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | if (!serviceSpecific && [cert hasCommonNameMatchingDomain: _domainToASCII]) return true; return false; } - (void)sendStanza: (OFXMLElement *)element { [_delegates broadcastSelector: @selector(connection:didSendElement:) withObject: self withObject: element]; [_socket writeString: [element XMLString]]; } - (void)sendIQ: (XMPPIQ *)IQ callbackTarget: (id)target selector: (SEL)selector { OFAutoreleasePool *pool; XMPPCallback *callback; OFString *ID, *key; |
︙ | ︙ | |||
541 542 543 544 545 546 547 | forKey: key]; [pool release]; [self sendStanza: IQ]; } #ifdef OF_HAVE_BLOCKS | | | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | forKey: key]; [pool release]; [self sendStanza: IQ]; } #ifdef OF_HAVE_BLOCKS - (void)sendIQ: (XMPPIQ *)IQ callbackBlock: (xmpp_callback_block_t)block { OFAutoreleasePool *pool; XMPPCallback *callback; OFString *ID, *key; pool = [[OFAutoreleasePool alloc] init]; |
︙ | ︙ | |||
570 571 572 573 574 575 576 | forKey: key]; [pool release]; [self sendStanza: IQ]; } #endif | | | | | | | < < < | | < | | | | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 | forKey: key]; [pool release]; [self sendStanza: IQ]; } #endif - (OFString *)generateStanzaID { return [OFString stringWithFormat: @"objxmpp_%u", _lastID++]; } - (void)parser: (OFXMLParser *)parser didStartElement: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)NS attributes: (OFArray *)attributes { if (![name isEqual: @"stream"]) { // No dedicated stream error for this, may not even be XMPP [self close]; [_socket close]; return; } if (![prefix isEqual: @"stream"]) { [self XMPP_sendStreamError: @"bad-namespace-prefix" text: nil]; return; } if (![NS isEqual: XMPP_NS_STREAM]) { [self XMPP_sendStreamError: @"invalid-namespace" text: nil]; return; } for (OFXMLAttribute *attribute in attributes) { if ([[attribute name] isEqual: @"from"] && ![[attribute stringValue] isEqual: _domain]) { [self XMPP_sendStreamError: @"invalid-from" text: nil]; return; } if ([[attribute name] isEqual: @"version"] && ![[attribute stringValue] isEqual: @"1.0"]) { [self XMPP_sendStreamError: @"unsupported-version" text: nil]; return; } } [parser setDelegate: _elementBuilder]; } - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildElement: (OFXMLElement *)element { /* Ignore whitespace elements */ if ([element name] == nil) return; [element setDefaultNamespace: XMPP_NS_CLIENT]; [element setPrefix: @"stream" |
︙ | ︙ | |||
650 651 652 653 654 655 656 | if ([[element namespace] isEqual: XMPP_NS_STARTTLS]) [self XMPP_handleTLS: element]; if ([[element namespace] isEqual: XMPP_NS_SASL]) [self XMPP_handleSASL: element]; } | | | | | | 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 | if ([[element namespace] isEqual: XMPP_NS_STARTTLS]) [self XMPP_handleTLS: element]; if ([[element namespace] isEqual: XMPP_NS_SASL]) [self XMPP_handleSASL: element]; } - (void)elementBuilder: (OFXMLElementBuilder *)builder didNotExpectCloseTag: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)ns { if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || ![ns isEqual: XMPP_NS_STREAM]) @throw [OFMalformedXMLException exception]; else { [self close]; } |
︙ | ︙ | |||
718 719 720 721 722 723 724 | [_JID release]; _JID = nil; _streamOpen = _needsSession = _encrypted = false; _supportsRosterVersioning = _supportsStreamManagement = false; _lastID = 0; } | | | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | [_JID release]; _JID = nil; _streamOpen = _needsSession = _encrypted = false; _supportsRosterVersioning = _supportsStreamManagement = false; _lastID = 0; } - (void)XMPP_handleStanza: (OFXMLElement *)element { if ([[element name] isEqual: @"iq"]) { [self XMPP_handleIQ: [XMPPIQ stanzaWithElement: element]]; return; } if ([[element name] isEqual: @"message"]) { |
︙ | ︙ | |||
742 743 744 745 746 747 748 | } [self XMPP_sendStreamError: @"unsupported-stanza-type" text: nil]; } | | | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 | } [self XMPP_sendStreamError: @"unsupported-stanza-type" text: nil]; } - (void)XMPP_handleStream: (OFXMLElement *)element { if ([[element name] isEqual: @"features"]) { [self XMPP_handleFeatures: element]; return; } if ([[element name] isEqual: @"error"]) { |
︙ | ︙ | |||
846 847 848 849 850 851 852 | reason: reason]; return; } assert(0); } | | | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 | reason: reason]; return; } assert(0); } - (void)XMPP_handleTLS: (OFXMLElement *)element { if ([[element name] isEqual: @"proceed"]) { /* FIXME: Catch errors here */ SSLSocket *newSock; [_delegates broadcastSelector: @selector( connectionWillUpgradeToTLS:) |
︙ | ︙ | |||
887 888 889 890 891 892 893 | if ([[element name] isEqual: @"failure"]) /* TODO: Find/create an exception to throw here */ @throw [OFException exception]; assert(0); } | | | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | if ([[element name] isEqual: @"failure"]) /* TODO: Find/create an exception to throw here */ @throw [OFException exception]; assert(0); } - (void)XMPP_handleSASL: (OFXMLElement *)element { if ([[element name] isEqual: @"challenge"]) { OFXMLElement *responseTag; OFDataArray *challenge = [OFDataArray dataArrayWithBase64EncodedString: [element stringValue]]; OFDataArray *response = [_authModule continueWithData: challenge]; |
︙ | ︙ | |||
935 936 937 938 939 940 941 | exceptionWithConnection: self reason: [element XMLString]]; } assert(0); } | | | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | exceptionWithConnection: self reason: [element XMLString]]; } assert(0); } - (void)XMPP_handleIQ: (XMPPIQ *)IQ { bool handled = false; XMPPCallback *callback; OFString *key; if ((key = [[IQ from] fullJID]) == nil) key = [_JID bareJID]; |
︙ | ︙ | |||
966 967 968 969 970 971 972 | if (!handled && ![[IQ type] isEqual: @"error"] && ![[IQ type] isEqual: @"result"]) { [self sendStanza: [IQ errorIQWithType: @"cancel" condition: @"service-unavailable"]]; } } | | | | | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 | if (!handled && ![[IQ type] isEqual: @"error"] && ![[IQ type] isEqual: @"result"]) { [self sendStanza: [IQ errorIQWithType: @"cancel" condition: @"service-unavailable"]]; } } - (void)XMPP_handleMessage: (XMPPMessage *)message { [_delegates broadcastSelector: @selector(connection:didReceiveMessage:) withObject: self withObject: message]; } - (void)XMPP_handlePresence: (XMPPPresence *)presence { [_delegates broadcastSelector: @selector(connection:didReceivePresence:) withObject: self withObject: presence]; } - (void)XMPP_handleFeatures: (OFXMLElement *)element { OFXMLElement *startTLS = [element elementForName: @"starttls" namespace: XMPP_NS_STARTTLS]; OFXMLElement *bind = [element elementForName: @"bind" namespace: XMPP_NS_BIND]; OFXMLElement *session = [element elementForName: @"session" namespace: XMPP_NS_SESSION]; |
︙ | ︙ | |||
1019 1020 1021 1022 1023 1024 1025 | OFEnumerator *enumerator; OFXMLElement *mech; enumerator = [[mechs children] objectEnumerator]; while ((mech = [enumerator nextObject]) != nil) [mechanisms addObject: [mech stringValue]]; | | | 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | OFEnumerator *enumerator; OFXMLElement *mech; enumerator = [[mechs children] objectEnumerator]; while ((mech = [enumerator nextObject]) != nil) [mechanisms addObject: [mech stringValue]]; if (_privateKeyFile != nil && _certificateFile != nil && [mechanisms containsObject: @"EXTERNAL"]) { _authModule = [[XMPPEXTERNALAuth alloc] init]; [self XMPP_sendAuth: @"EXTERNAL"]; return; } if ([mechanisms containsObject: @"SCRAM-SHA-1-PLUS"]) { |
︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 | [self XMPP_sendAuth: @"PLAIN"]; return; } assert(0); } | | | | | 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 | [self XMPP_sendAuth: @"PLAIN"]; return; } assert(0); } if (session != nil && [session elementForName: @"optional" namespace: XMPP_NS_SESSION] == nil) _needsSession = true; if (bind != nil) { [self XMPP_sendResourceBind]; return; } assert(0); } - (void)XMPP_sendAuth: (OFString *)authName { OFXMLElement *authTag; OFDataArray *initialMessage = [_authModule initialMessage]; authTag = [OFXMLElement elementWithName: @"auth" namespace: XMPP_NS_SASL]; [authTag addAttributeWithName: @"mechanism" |
︙ | ︙ | |||
1115 1116 1117 1118 1119 1120 1121 | [self sendIQ: IQ callbackTarget: self selector: @selector(XMPP_handleResourceBindForConnection: IQ:)]; } | | | | | | < | | | | < < | | > | > | | | | | | | 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 | [self sendIQ: IQ callbackTarget: self selector: @selector(XMPP_handleResourceBindForConnection: IQ:)]; } - (void)XMPP_sendStreamError: (OFString *)condition text: (OFString *)text { OFXMLElement *error = [OFXMLElement elementWithName: @"error" namespace: XMPP_NS_STREAM]; [error setPrefix: @"stream" forNamespace: XMPP_NS_STREAM]; [error addChild: [OFXMLElement elementWithName: condition namespace: XMPP_NS_XMPP_STREAM]]; if (text) [error addChild: [OFXMLElement elementWithName: @"text" namespace: XMPP_NS_XMPP_STREAM stringValue: text]]; [_parser setDelegate: nil]; [self sendStanza: error]; [self close]; } - (void)XMPP_handleResourceBindForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ { OFXMLElement *bindElement, *JIDElement; assert([[IQ type] isEqual: @"result"]); bindElement = [IQ elementForName: @"bind" namespace: XMPP_NS_BIND]; assert(bindElement != nil); JIDElement = [bindElement elementForName: @"jid" namespace: XMPP_NS_BIND]; _JID = [[XMPPJID alloc] initWithString: [JIDElement stringValue]]; if (_needsSession) { [self XMPP_sendSession]; return; } [_delegates broadcastSelector: @selector(connection:wasBoundToJID:) withObject: self withObject: _JID]; } - (void)XMPP_sendSession { XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [self generateStanzaID]]; [IQ addChild: [OFXMLElement elementWithName: @"session" namespace: XMPP_NS_SESSION]]; [self sendIQ: IQ callbackTarget: self selector: @selector(XMPP_handleSessionForConnection:IQ:)]; } - (void)XMPP_handleSessionForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ { if (![[IQ type] isEqual: @"result"]) OF_ENSURE(0); [_delegates broadcastSelector: @selector(connection:wasBoundToJID:) withObject: self withObject: _JID]; } - (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) |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 | } - (void)removeDelegate: (id <XMPPConnectionDelegate>)delegate { [_delegates removeDelegate: delegate]; } | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 | } - (void)removeDelegate: (id <XMPPConnectionDelegate>)delegate { [_delegates removeDelegate: delegate]; } - (XMPPMulticastDelegate *)XMPP_delegates { return _delegates; } @end |
Added src/XMPPContact+Private.h version [19b0cc5ea8].
Modified src/XMPPContact.h from [160c8854c7] to [3375b65268].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> @class XMPPConnection; @class XMPPJID; @class XMPPRosterItem; @class XMPPMessage; @class XMPPPresence; /** * \brief A class describing a contact tracked by a XMPPContactManager */ @interface XMPPContact: OFObject { XMPPRosterItem *_rosterItem; OFMutableDictionary *_presences; XMPPJID *_lockedOnJID; } /// \brief The XMPPRosterItem corresponding to this contact | > > | | | | > < | < < < < | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @class XMPPConnection; @class XMPPJID; @class XMPPRosterItem; @class XMPPMessage; @class XMPPPresence; /** * \brief A class describing a contact tracked by a XMPPContactManager */ @interface XMPPContact: OFObject { XMPPRosterItem *_rosterItem; OFMutableDictionary *_presences; XMPPJID *_lockedOnJID; } /// \brief The XMPPRosterItem corresponding to this contact @property (readonly, nonatomic) XMPPRosterItem *rosterItem; /// \brief The XMPPPresences of this contact with the resources as keys @property (readonly, nonatomic) OFDictionary *presences; /** * \brief Sends a message to the contact honoring resource locking * * \param message The message to send * \param connection The connection to use for sending the message */ - (void)sendMessage: (XMPPMessage *)message connection: (XMPPConnection *)connection; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPContact.m from [c409a8ce2b] to [f961d31c3a].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPContact.h" #import "XMPPMessage.h" #import "XMPPConnection.h" @implementation XMPPContact @synthesize rosterItem = _rosterItem; @synthesize presences = _presences; | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPContact.h" #import "XMPPContact+Private.h" #import "XMPPMessage.h" #import "XMPPConnection.h" @implementation XMPPContact @synthesize rosterItem = _rosterItem; @synthesize presences = _presences; |
︙ | ︙ | |||
46 47 48 49 50 51 52 | - (void)dealloc { [_presences release]; [super dealloc]; } | | | | | | | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | - (void)dealloc { [_presences release]; [super dealloc]; } - (void)sendMessage: (XMPPMessage *)message connection: (XMPPConnection *)connection { if (_lockedOnJID == nil) [message setTo: [_rosterItem JID]]; else [message setTo: _lockedOnJID]; [connection sendStanza: message]; } - (void)XMPP_setRosterItem: (XMPPRosterItem *)rosterItem { XMPPRosterItem *old = _rosterItem; _rosterItem = [rosterItem retain]; [old release]; } - (void)XMPP_setPresence: (XMPPPresence *)presence resource: (OFString *)resource { if (resource != nil) [_presences setObject: presence forKey: resource]; else [_presences setObject: presence forKey: @""]; [self XMPP_setLockedOnJID: nil]; } - (void)XMPP_removePresenceForResource: (OFString *)resource { if (resource != nil) { [_presences removeObjectForKey: resource]; } else { [_presences release]; _presences = [[OFMutableDictionary alloc] init]; } [self XMPP_setLockedOnJID: nil]; } - (void)XMPP_setLockedOnJID: (XMPPJID *)JID; { XMPPJID *old = _lockedOnJID; _lockedOnJID = [JID retain]; [old release]; } @end |
Modified src/XMPPContactManager.h from [13b68822fb] to [ffd20ba38a].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | */ #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPRoster.h" @class XMPPContact; @class XMPPContactManager; @class XMPPMulticastDelegate; @class XMPPPresence; /** * \brief A protocol that should be (partially) implemented by delegates * of a XMPPContactManager */ @protocol XMPPContactManagerDelegate <OFObject> @optional /** * \brief This callback is called whenever a new contact enters the users roster * * \param manager The contact manager that added the contact * \param contact The contact that was added */ | > > | | | | | | | | | | | | | > | | | | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | */ #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPRoster.h" OF_ASSUME_NONNULL_BEGIN @class XMPPContact; @class XMPPContactManager; @class XMPPMulticastDelegate; @class XMPPPresence; /** * \brief A protocol that should be (partially) implemented by delegates * of a XMPPContactManager */ @protocol XMPPContactManagerDelegate <OFObject> @optional /** * \brief This callback is called whenever a new contact enters the users roster * * \param manager The contact manager that added the contact * \param contact The contact that was added */ - (void)contactManager: (XMPPContactManager *)manager didAddContact: (XMPPContact *)contact; /** * \brief This callback is called whenever a contact is no longer present in * the users roster * * \param manager The contact manager that removed the contact * \param contact The contact that was removed */ - (void)contactManager: (XMPPContactManager *)manager didRemoveContact: (XMPPContact *)contact; /** * \brief This callback is called when a subscription request is received * * \param manager The contact manager that received the request * \param presence The type=subscribe presence */ - (void)contactManager: (XMPPContactManager *)manager didReceiveSubscriptionRequest: (XMPPPresence *)presence; /** * \brief This callback is called whenever a contact is about to change its * roster item * * \param contact The contact about to updated its roster item * \param rosterItem The roster item the contact is going to update with */ - (void)contact: (XMPPContact *)contact willUpdateWithRosterItem: (XMPPRosterItem *)rosterItem; /** * \brief This callback is called whenever a contact send a presence stanza * * \param contact The contact that send the presence * \param presence The presence which was send by the contact */ - (void)contact: (XMPPContact *)contact didSendPresence: (XMPPPresence *)presence; /** * \brief This callback is called whenever a contact send a message stanza * * \param contact The contact that send the message * \param message The message which was send by the contact */ - (void)contact: (XMPPContact *)contact didSendMessage: (XMPPMessage *)message; @end /** * \brief A class tracking a XMPPContact instance for each contact in the roster * * This class delegates to a XMPPConnection and a XMPPRoster, thereby tracking * each contacts presences and the current XMPPRosterItem. */ @interface XMPPContactManager: OFObject <XMPPConnectionDelegate, XMPPRosterDelegate> { OFMutableDictionary *_contacts; XMPPConnection *_connection; XMPPRoster *_roster; XMPPMulticastDelegate *_delegates; } /// \brief The tracked contacts, with their bare JID as key @property (readonly, nonatomic) OFDictionary OF_GENERIC(OFString *, XMPPContact *) *contacts; /*! * @brief Initializes an already allocated XMPPContactManager. * * @param connection The connection to be used to track contacts * @param roster The roster used by the contact manager * @return An initialized XMPPContactManager */ - initWithConnection: (XMPPConnection *)connection roster: (XMPPRoster *)roster OF_DESIGNATED_INITIALIZER; - (void)sendSubscribedToJID: (XMPPJID *)subscriber; - (void)sendUnsubscribedToJID: (XMPPJID *)subscriber; /** * \brief Adds the specified delegate. * * \param delegate The delegate to add */ - (void)addDelegate: (id <XMPPContactManagerDelegate>)delegate; /** * \brief Removes the specified delegate. * * \param delegate The delegate to remove */ - (void)removeDelegate: (id <XMPPContactManagerDelegate>)delegate; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPContactManager.m from [3f134700d1] to [e40b256e89].
︙ | ︙ | |||
17 18 19 20 21 22 23 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPContact.h" | > | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPContactManager.h" #import "XMPPContact.h" #import "XMPPContact+Private.h" #import "XMPPJID.h" #import "XMPPMulticastDelegate.h" #import "XMPPPresence.h" #import "XMPPRosterItem.h" @implementation XMPPContactManager @synthesize contacts = _contacts; - initWithConnection: (XMPPConnection *)connection roster: (XMPPRoster *)roster { self = [super init]; @try { _connection = connection; [_connection addDelegate: self]; _roster = roster; |
︙ | ︙ | |||
58 59 60 61 62 63 64 | [_delegates release]; [_contacts release]; [super dealloc]; } | | | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | [_delegates release]; [_contacts release]; [super dealloc]; } - (void)sendSubscribedToJID: (XMPPJID *)subscriber { XMPPPresence *presence = [XMPPPresence presenceWithType: @"subscribed"]; [presence setTo: subscriber]; [_connection sendStanza: presence]; } - (void)sendUnsubscribedToJID: (XMPPJID *)subscriber { XMPPPresence *presence = [XMPPPresence presenceWithType: @"unsubscribed"]; [presence setTo: subscriber]; [_connection sendStanza: presence]; } - (void)addDelegate: (id <XMPPContactManagerDelegate>)delegate { [_delegates addDelegate: delegate]; } - (void)removeDelegate: (id <XMPPContactManagerDelegate>)delegate { [_delegates removeDelegate: delegate]; } - (void)rosterWasReceived: (XMPPRoster *)roster { OFEnumerator *contactEnumerator; XMPPContact *contact; OFDictionary *rosterItems; OFEnumerator *rosterItemEnumerator; OFString *bareJID; |
︙ | ︙ | |||
116 117 118 119 120 121 122 | [_delegates broadcastSelector: @selector(contactManager: didAddContact:) withObject: self withObject: contact]; } } | | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | [_delegates broadcastSelector: @selector(contactManager: didAddContact:) withObject: self withObject: contact]; } } - (void)roster: (XMPPRoster *)roster didReceiveRosterItem: (XMPPRosterItem *)rosterItem { XMPPContact *contact; OFString *bareJID = [[rosterItem JID] bareJID]; contact = [_contacts objectForKey: bareJID]; if ([[rosterItem subscription] isEqual: @"remove"]) { |
︙ | ︙ | |||
152 153 154 155 156 157 158 | willUpdateWithRosterItem:) withObject: contact withObject: rosterItem]; [contact XMPP_setRosterItem: rosterItem]; } } | | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | willUpdateWithRosterItem:) withObject: contact withObject: rosterItem]; [contact XMPP_setRosterItem: rosterItem]; } } - (void)connection: (XMPPConnection *)connection didReceivePresence: (XMPPPresence *)presence { XMPPContact *contact; XMPPJID *JID = [presence from]; OFString *type = [presence type]; /* Subscription request */ if ([type isEqual: @"subscribe"]) { |
︙ | ︙ | |||
195 196 197 198 199 200 201 | didSendPresence:) withObject: contact withObject: presence]; return; } } | | | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | didSendPresence:) withObject: contact withObject: presence]; return; } } - (void)connection: (XMPPConnection *)connection didReceiveMessage: (XMPPMessage *)message { XMPPJID *JID = [message from]; XMPPContact *contact = [_contacts objectForKey: [JID bareJID]]; if (contact == nil) return; |
︙ | ︙ |
Modified src/XMPPDiscoEntity.h from [675c041e84] to [1a213e145c].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | */ #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPDiscoNode.h" @class XMPPJID; /** * \brief A class representing an entity responding to Service Discovery * queries */ @interface XMPPDiscoEntity: XMPPDiscoNode <XMPPConnectionDelegate> | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | */ #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPDiscoNode.h" OF_ASSUME_NONNULL_BEGIN @class XMPPJID; /** * \brief A class representing an entity responding to Service Discovery * queries */ @interface XMPPDiscoEntity: XMPPDiscoNode <XMPPConnectionDelegate> |
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 | @property (readonly) OFDictionary *discoNodes; /** * The node advertised for the entity's capabilites. */ @property (readonly) OFString *capsNode; /** * \brief Creates a new autoreleased XMPPDiscoEntity with the specified * connection. * * \param connection The XMPPConnection to serve responses on. * \return A new autoreleased XMPPDiscoEntity */ | > > > > > > | | | > > > > > > | | | | | > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | @property (readonly) OFDictionary *discoNodes; /** * The node advertised for the entity's capabilites. */ @property (readonly) OFString *capsNode; + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (nullable OFString *)node OF_UNAVAILABLE; + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (nullable OFString *)node name: (nullable OFString *)name OF_UNAVAILABLE; /** * \brief Creates a new autoreleased XMPPDiscoEntity with the specified * connection. * * \param connection The XMPPConnection to serve responses on. * \return A new autoreleased XMPPDiscoEntity */ + (instancetype)discoEntityWithConnection: (XMPPConnection *)connection; /** * \brief Creates a new autoreleased XMPPDiscoEntity with the specified * connection. * * \param connection The XMPPConnection to serve responses on. * \param capsNode The node advertised for the entity's capabilites * \return A new autoreleased XMPPDiscoEntity */ + (instancetype)discoEntityWithConnection: (XMPPConnection *)connection capsNode: (OFString *)capsNode; - initWithJID: (XMPPJID *)JID node: (nullable OFString *)node OF_UNAVAILABLE; - initWithJID: (XMPPJID *)JID node: (nullable OFString *)node name: (nullable OFString *)name OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPDiscoEntity with the specified * connection. * * \param connection The XMPPConnection to serve responses on. * This must already be bound to a resource) * \return An initialized XMPPDiscoEntity */ - initWithConnection: (XMPPConnection *)connection; /** * \brief Initializes an already allocated XMPPDiscoEntity with the specified * connection. * * \param connection The XMPPConnection to serve responses on. * This must already be bound to a resource) * \param capsNode The node advertised for the entity's capabilites * \return An initialized XMPPDiscoEntity */ - initWithConnection: (XMPPConnection *)connection capsNode: (nullable OFString *)capsNode OF_DESIGNATED_INITIALIZER; /** * \brief Adds a XMPPDiscoNode to provide responses for. * * \param node The XMPPDiscoNode to provide responses for */ - (void)addDiscoNode: (XMPPDiscoNode *)node; /** * \brief Calculates the Entity Capabilities Hash of the entity * * \return A OFString containing the capabilities hash */ - (OFString *)capsHash; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPDiscoEntity.m from [35881ca3b2] to [f708ffe294].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPDiscoEntity.h" #import "XMPPDiscoIdentity.h" #import "XMPPIQ.h" #import "namespaces.h" @implementation XMPPDiscoEntity @synthesize discoNodes = _discoNodes, capsNode = _capsNode; | > > | | | | > > > > > > > | | | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPDiscoEntity.h" #import "XMPPDiscoNode.h" #import "XMPPDiscoNode+Private.h" #import "XMPPDiscoIdentity.h" #import "XMPPIQ.h" #import "namespaces.h" @implementation XMPPDiscoEntity @synthesize discoNodes = _discoNodes, capsNode = _capsNode; + (instancetype)discoEntityWithConnection: (XMPPConnection *)connection { return [[[self alloc] initWithConnection: connection] autorelease]; } + (instancetype)discoEntityWithConnection: (XMPPConnection *)connection capsNode: (OFString *)capsNode { return [[[self alloc] initWithConnection: connection capsNode: capsNode] autorelease]; } - initWithConnection: (XMPPConnection *)connection { return [self initWithConnection: connection capsNode: nil]; } - initWithJID: (XMPPJID *)JID node: (nullable OFString *)node name: (nullable OFString *)name { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection capsNode: (OFString *)capsNode { self = [super initWithJID: [connection JID] node: nil name: nil]; @try { _discoNodes = [[OFMutableDictionary alloc] init]; _connection = connection; _capsNode = [capsNode copy]; [_connection addDelegate: self]; |
︙ | ︙ | |||
71 72 73 74 75 76 77 | { [_connection removeDelegate: self]; [_discoNodes release]; [super dealloc]; } | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | { [_connection removeDelegate: self]; [_discoNodes release]; [super dealloc]; } - (void)addDiscoNode: (XMPPDiscoNode *)node { [_discoNodes setObject: node forKey: [node node]]; } - (OFString *)capsHash { OFEnumerator *enumerator; XMPPDiscoIdentity *identity; OFString *feature; OFMutableString *caps = [OFMutableString string]; OFSHA1Hash *hash = [OFSHA1Hash cryptoHash]; OFDataArray *digest = [OFDataArray dataArray]; |
︙ | ︙ | |||
104 105 106 107 108 109 110 | [digest addItems: [hash digest] count: [OFSHA1Hash digestSize]]; return [digest stringByBase64Encoding]; } | | | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | [digest addItems: [hash digest] count: [OFSHA1Hash digestSize]]; return [digest stringByBase64Encoding]; } - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID { _JID = [JID copy]; } - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ { if (![[IQ to] isEqual: _JID]) return false; OFXMLElement *query = [IQ elementForName: @"query" namespace: XMPP_NS_DISCO_ITEMS]; |
︙ | ︙ |
Modified src/XMPPDiscoIdentity.h from [574d3c2fee] to [969a73bffe].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> /** * \brief A class describing a Service Discovery Identity */ @interface XMPPDiscoIdentity: OFObject <OFComparing> { OFString *_category, *_name, *_type; } /// \brief The category of the identity | > > | | | | | | | | > > | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN /** * \brief A class describing a Service Discovery Identity */ @interface XMPPDiscoIdentity: OFObject <OFComparing> { OFString *_category, *_name, *_type; } /// \brief The category of the identity @property (readonly, nonatomic) OFString *category; /// \brief The name of the identity, might be unset @property (readonly, nonatomic) OFString *name; /// \brief The type of the identity @property (readonly, nonatomic) OFString *type; /** * \brief Creates a new autoreleased XMPPDiscoIdentity with the specified * category, type and name. * * \param category The category of the identity * \param type The type of the identity * \param name The name of the identity * \return A new autoreleased XMPPDiscoIdentity */ + (instancetype)identityWithCategory: (OFString *)category type: (OFString *)type name: (nullable OFString *)name; /** * \brief Creates a new autoreleased XMPPDiscoIdentity with the specified * category and type. * * \param category The category of the identity * \param type The type of the identity * \return A new autoreleased XMPPDiscoIdentity */ + (instancetype)identityWithCategory: (OFString *)category type: (OFString *)type; - init OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPDiscoIdentity with the specified * category, type and name. * * \param category The category of the identity * \param type The type of the identity * \param name The name of the identity * \return An initialized XMPPDiscoIdentity */ - initWithCategory: (OFString *)category type: (OFString *)type name: (nullable OFString *)name OF_DESIGNATED_INITIALIZER; /** * \brief Initializes an already allocated XMPPDiscoIdentity with the specified * category and type. * * \param category The category of the identity * \param type The type of the identity * \return An initialized XMPPDiscoIdentity */ - initWithCategory: (OFString *)category type: (OFString *)type; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPDiscoIdentity.m from [95bd037e63] to [52a90e08e0].
︙ | ︙ | |||
22 23 24 25 26 27 28 | */ #import "XMPPDiscoIdentity.h" @implementation XMPPDiscoIdentity @synthesize category = _category, name = _name, type = _type; | | | | | | | | | | | < < < < < < | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | */ #import "XMPPDiscoIdentity.h" @implementation XMPPDiscoIdentity @synthesize category = _category, name = _name, type = _type; + (instancetype)identityWithCategory: (OFString *)category type: (OFString *)type name: (OFString *)name { return [[[self alloc] initWithCategory: category type: type name: name] autorelease]; } + (instancetype)identityWithCategory: (OFString *)category type: (OFString *)type { return [[[self alloc] initWithCategory: category type: type] autorelease]; } - initWithCategory: (OFString *)category type: (OFString *)type name: (OFString *)name { self = [super init]; @try { if (category == nil || type == nil) @throw [OFInvalidArgumentException exception]; _category = [category copy]; _name = [name copy]; _type = [type copy]; } @catch (id e) { [self release]; @throw e; } return self; } - initWithCategory: (OFString *)category type: (OFString *)type { return [self initWithCategory: category type: type name: nil]; } - init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_category release]; [_name release]; [_type release]; |
︙ | ︙ | |||
135 136 137 138 139 140 141 | if (object == self) return OF_ORDERED_SAME; if (![object isKindOfClass: [XMPPDiscoIdentity class]]) @throw [OFInvalidArgumentException exception]; | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | if (object == self) return OF_ORDERED_SAME; if (![object isKindOfClass: [XMPPDiscoIdentity class]]) @throw [OFInvalidArgumentException exception]; identity = (XMPPDiscoIdentity *)object; categoryResult = [_category compare: identity->_category]; if (categoryResult != OF_ORDERED_SAME) return categoryResult; typeResult = [_type compare: identity->_type]; if (typeResult != OF_ORDERED_SAME) return typeResult; return [_name compare: identity->_name]; } @end |
Added src/XMPPDiscoNode+Private.h version [e20421d02a].
Modified src/XMPPDiscoNode.h from [fa28e0da2b] to [04990bb259].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> @class XMPPDiscoIdentity; @class XMPPJID; /** * \brief A class describing a Service Discovery Node */ @interface XMPPDiscoNode: OFObject { XMPPJID *_JID; OFString *_node; OFString *_name; OFSortedList *_identities; OFSortedList *_features; OFMutableDictionary *_childNodes; } /// \brief The JID this node lives on | > > | | | | | | | | | | | | | | | | | | | > < | < < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @class XMPPDiscoIdentity; @class XMPPJID; /** * \brief A class describing a Service Discovery Node */ @interface XMPPDiscoNode: OFObject { XMPPJID *_JID; OFString *_node; OFString *_name; OFSortedList *_identities; OFSortedList *_features; OFMutableDictionary *_childNodes; } /// \brief The JID this node lives on @property (readonly, nonatomic) XMPPJID *JID; /// \brief The node's opaque name of the node @property (readonly, nonatomic) OFString *node; /// \brief The node's human friendly name (may be unspecified) @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *name; /// \brief The node's list of identities @property (readonly, nonatomic) OFSortedList *identities; /// \brief The node's list of features @property (readonly, nonatomic) OFSortedList *features; /// \brief The node's children @property (readonly, nonatomic) OFDictionary *childNodes; /** * \brief Creates a new autoreleased XMPPDiscoNode with the specified * JID and node * * \param JID The JID this node lives on * \param node The node's opaque name * \return A new autoreleased XMPPDiscoNode */ + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (nullable OFString *)node; /** * \brief Creates a new autoreleased XMPPDiscoNode with the specified * JID, node and name * * \param JID The JID this node lives on * \param node The node's opaque name * \param name The node's human friendly name * \return A new autoreleased XMPPDiscoNode */ + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (nullable OFString *)node name: (nullable OFString *)name; /** * \brief Initializes an already allocated XMPPDiscoNode with the specified * JID and node * * \param JID The JID this node lives on * \param node The node's opaque name * \return An initialized XMPPDiscoNode */ - initWithJID: (XMPPJID *)JID node: (nullable OFString *)node; /** * \brief Initializes an already allocated XMPPDiscoNode with the specified * JID, node and name * * \param JID The JID this node lives on * \param node The node's opaque name * \param name The node's human friendly name * \return An initialized XMPPDiscoNode */ - initWithJID: (XMPPJID *)JID node: (nullable OFString *)node name: (nullable OFString *)name OF_DESIGNATED_INITIALIZER; /** * \brief Adds an XMPPDiscoIdentity to the node * * \param identity The XMPPDiscoIdentity to add */ - (void)addIdentity: (XMPPDiscoIdentity *)identity; /** * \brief Adds a feature to the node * * \param feature The feature to add */ - (void)addFeature: (OFString *)feature; /** * \brief Adds a XMPPDiscoNode as child of the node * * \param node The XMPPDiscoNode to add as child */ - (void)addChildNode: (XMPPDiscoNode *)node; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPDiscoNode.m from [adea212c4a] to [07959d2558].
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPConnection.h" #import "XMPPIQ.h" #import "XMPPJID.h" #import "XMPPDiscoEntity.h" | > > < | | | | | | | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPDiscoNode.h" #import "XMPPDiscoNode+Private.h" #import "XMPPConnection.h" #import "XMPPIQ.h" #import "XMPPJID.h" #import "XMPPDiscoEntity.h" #import "XMPPDiscoIdentity.h" #import "namespaces.h" @implementation XMPPDiscoNode @synthesize JID = _JID, node = _node, name = _name, identities = _identities; @synthesize features = _features, childNodes = _childNodes; + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node; { return [[[self alloc] initWithJID: JID node: node] autorelease]; } + (instancetype)discoNodeWithJID: (XMPPJID *)JID node: (OFString *)node name: (OFString *)name { return [[[self alloc] initWithJID: JID node: node name: name] autorelease]; } - initWithJID: (XMPPJID *)JID node: (OFString *)node { return [self initWithJID: JID node: node name: nil]; } - initWithJID: (XMPPJID *)JID node: (OFString *)node name: (OFString *)name { self = [super init]; @try { if (JID == nil && ![self isKindOfClass: [XMPPDiscoEntity class]]) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
94 95 96 97 98 99 100 | [_identities release]; [_features release]; [_childNodes release]; [super dealloc]; } | > > > > > | | | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | [_identities release]; [_features release]; [_childNodes release]; [super dealloc]; } - (OFDictionary *)childNodes { return [[_childNodes copy] autorelease]; } - (void)addIdentity: (XMPPDiscoIdentity *)identity { [_identities insertObject: identity]; } - (void)addFeature: (OFString *)feature { [_features insertObject: feature]; } - (void)addChildNode: (XMPPDiscoNode *)node { [_childNodes setObject: node forKey: [node node]]; } - (bool)XMPP_handleItemsIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { XMPPIQ *resultIQ; OFXMLElement *response; XMPPDiscoNode *child; OFEnumerator *enumerator; OFXMLElement *query = [IQ elementForName: @"query" namespace: XMPP_NS_DISCO_ITEMS]; |
︙ | ︙ | |||
152 153 154 155 156 157 158 | } [connection sendStanza: resultIQ]; return true; } | | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | } [connection sendStanza: resultIQ]; return true; } - (bool)XMPP_handleInfoIQ: (XMPPIQ *)IQ connection: (XMPPConnection *)connection { XMPPIQ *resultIQ; OFXMLElement *response; OFEnumerator *enumerator; OFString *feature; XMPPDiscoIdentity *identity; |
︙ | ︙ |
Modified src/XMPPEXTERNALAuth.h from [87300c70b8] to [0051e84d45].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> #import "XMPPAuthenticator.h" /** * \brief A class to authenticate using SASL EXTERNAL */ @interface XMPPEXTERNALAuth: XMPPAuthenticator /** * \brief Creates a new autoreleased XMPPEXTERNALAuth. * * \return A new autoreleased XMPPEXTERNALAuth */ + (instancetype)EXTERNALAuth; /** * \brief Creates a new autoreleased XMPPEXTERNALAuth with an authzid. * * \param authzid The authzid to get authorization for * \return A new autoreleased XMPPEXTERNALAuth */ | > > | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> #import "XMPPAuthenticator.h" OF_ASSUME_NONNULL_BEGIN /** * \brief A class to authenticate using SASL EXTERNAL */ @interface XMPPEXTERNALAuth: XMPPAuthenticator /** * \brief Creates a new autoreleased XMPPEXTERNALAuth. * * \return A new autoreleased XMPPEXTERNALAuth */ + (instancetype)EXTERNALAuth; /** * \brief Creates a new autoreleased XMPPEXTERNALAuth with an authzid. * * \param authzid The authzid to get authorization for * \return A new autoreleased XMPPEXTERNALAuth */ + (instancetype)EXTERNALAuthWithAuthzid: (nullable OFString *)authzid; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPEXTERNALAuth.m from [4c3013d555] to [c6103d3079].
︙ | ︙ | |||
29 30 31 32 33 34 35 | @implementation XMPPEXTERNALAuth: XMPPAuthenticator + (instancetype)EXTERNALAuth { return [[[self alloc] initWithAuthcid: nil password: nil] autorelease]; } | | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | @implementation XMPPEXTERNALAuth: XMPPAuthenticator + (instancetype)EXTERNALAuth { return [[[self alloc] initWithAuthcid: nil password: nil] autorelease]; } + (instancetype)EXTERNALAuthWithAuthzid: (OFString *)authzid { return [[[self alloc] initWithAuthzid: authzid authcid: nil password: nil] autorelease]; } - (OFDataArray *)initialMessage { OFDataArray *message = [OFDataArray dataArray]; /* authzid */ if (_authzid) [message addItem: _authzid]; |
︙ | ︙ |
Modified src/XMPPExceptions.h from [69b290104a] to [679b6851a0].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> @class XMPPConnection; @class XMPPAuthenticator; /** * \brief A base class for XMPP related exceptions */ @interface XMPPException: OFException { XMPPConnection *_connection; } /// \brief The connection the exception relates to | > > | | > > | > | | | | | > > | | | | | | | | > > | | | | | | | | > > | | | | | | > > | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @class XMPPConnection; @class XMPPAuthenticator; /** * \brief A base class for XMPP related exceptions */ @interface XMPPException: OFException { XMPPConnection *_connection; } /// \brief The connection the exception relates to @property OF_NULLABLE_PROPERTY (readonly, nonatomic) XMPPConnection *connection; /** * \brief Creates a new XMPPException. * * \param connection The connection that received the data responsible * for this exception * \return A new XMPPException */ + (instancetype)exceptionWithConnection: (nullable XMPPConnection *)connection; - init OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPException. * * \param connection The connection that received the data responsible * for this exception * \return An initialized XMPPException */ - initWithConnection: (nullable XMPPConnection *)connection OF_DESIGNATED_INITIALIZER; @end /** * \brief An exception indicating a stream error was received */ @interface XMPPStreamErrorException: XMPPException { OFString *_condition, *_reason; } /// \brief The defined error condition specified by the stream error @property (readonly, nonatomic) OFString *condition; /// \brief The descriptive free-form text specified by the stream error @property (readonly, nonatomic) OFString *reason; /** * \brief Creates a new XMPPStreamErrorException. * * \param connection The connection that received the stream error * \param condition The defined error condition specified by the stream error * \param reason The descriptive free-form text specified by the stream error * \return A new XMPPStreamErrorException */ + (instancetype)exceptionWithConnection: (nullable XMPPConnection *)connection condition: (OFString *)condition reason: (OFString *)reason; - initWithConnection: (nullable XMPPConnection *)connection OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPStreamErrorException. * * \param connection The connection that received the stream error * \param condition The defined error condition specified by the stream error * \param reason The descriptive free-form text specified by the stream error * \return An initialized XMPPStreamErrorException */ - initWithConnection: (nullable XMPPConnection *)connection condition: (OFString *)condition reason: (OFString *)reason OF_DESIGNATED_INITIALIZER; @end /** * \brief An exception indicating a stringprep profile * did not apply to a string */ @interface XMPPStringPrepFailedException: XMPPException { OFString *_profile, *_string; } /// \brief The name of the stringprep profile that did not apply @property (readonly, nonatomic) OFString *profile; /// \brief The string that failed the stringprep profile @property (readonly, nonatomic) OFString *string; /** * \brief Creates a new XMPPStringPrepFailedException. * * \param connection The connection the string relates to * \param profile The name of the stringprep profile that did not apply * \param string The string that failed the stringprep profile * \return A new XMPPStringPrepFailedException */ + (instancetype)exceptionWithConnection: (nullable XMPPConnection *)connection profile: (OFString *)profile string: (OFString *)string; - initWithConnection: (nullable XMPPConnection *)connection OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPStringPrepFailedException. * * \param connection The connection the string relates to * \param profile The name of the stringprep profile that did not apply * \param string The string that failed the stringprep profile * \return An initialized XMPPStringPrepFailedException */ - initWithConnection: (nullable XMPPConnection *)connection profile: (OFString *)profile string: (OFString *)string OF_DESIGNATED_INITIALIZER; @end /** * \brief An exception indicating IDNA translation of a string failed */ @interface XMPPIDNATranslationFailedException: XMPPException { OFString *_operation, *_string; } /// \brief The IDNA translation operation which failed @property (readonly, nonatomic) OFString *operation; /// \brief The string that could not be translated @property (readonly, nonatomic) OFString *string; /** * \brief Creates a new XMPPIDNATranslationFailedException. * * \param connection The connection the string relates to * \param operation The name of the stringprep profile that did not apply * \param string The string that could not be translated * \return A new XMPPIDNATranslationFailedException */ + (instancetype)exceptionWithConnection: (nullable XMPPConnection *)connection operation: (OFString *)operation string: (OFString *)string; - initWithConnection: (nullable XMPPConnection *)connection OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPIDNATranslationFailedException. * * \param connection The connection the string relates to * \param operation The name of the stringprep profile that did not apply * \param string The string that could not be translated * \return An initialized XMPPIDNATranslationFailedException */ - initWithConnection: (nullable XMPPConnection *)connection operation: (OFString *)operation string: (OFString *)string; @end /** * \brief An exception indicating authentication failed */ @interface XMPPAuthFailedException: XMPPException { OFString *_reason; } /// \brief The reason the authentication failed @property (readonly, nonatomic) OFString *reason; /** * \brief Creates a new XMPPAuthFailedException. * * \param connection The connection that could not be authenticated * \param reason The reason the authentication failed * \return A new XMPPAuthFailedException */ + (instancetype)exceptionWithConnection: (nullable XMPPConnection *)connection reason: (OFString *)reason; - initWithConnection: (nullable XMPPConnection *)connection OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPAuthFailedException. * * \param connection The connection that could not be authenticated * \param reason The reason the authentication failed * \return An initialized XMPPAuthFailedException */ - initWithConnection: (nullable XMPPConnection *)connection reason: (OFString *)reason OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPExceptions.m from [d64ce8e761] to [b482b72e53].
︙ | ︙ | |||
29 30 31 32 33 34 35 | #import "XMPPExceptions.h" #import "XMPPConnection.h" @implementation XMPPException @synthesize connection = _connection; | | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #import "XMPPExceptions.h" #import "XMPPConnection.h" @implementation XMPPException @synthesize connection = _connection; + (instancetype)exceptionWithConnection: (XMPPConnection *)connection { return [[[self alloc] initWithConnection: connection] autorelease]; } - init { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection { self = [super init]; @try { _connection = [connection retain]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
64 65 66 67 68 69 70 | [super dealloc]; } @end @implementation XMPPStreamErrorException @synthesize condition = _condition, reason = _reason; | | | | | | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | [super dealloc]; } @end @implementation XMPPStreamErrorException @synthesize condition = _condition, reason = _reason; + (instancetype)exceptionWithConnection: (XMPPConnection *)connection condition: (OFString *)condition reason: (OFString *)reason; { return [[[self alloc] initWithConnection: connection condition: condition reason: reason] autorelease]; } - initWithConnection: (XMPPConnection *)connection { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection condition: (OFString *)condition reason: (OFString *)reason { self = [super initWithConnection: connection]; @try { _condition = [condition copy]; _reason = [reason copy]; } @catch (id e) { |
︙ | ︙ | |||
103 104 105 106 107 108 109 | { [_condition release]; [_reason release]; [super dealloc]; } | | | | | | | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | { [_condition release]; [_reason release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Got stream error: %@. Reason: %@!", _condition, _reason]; } @end @implementation XMPPStringPrepFailedException @synthesize profile = _profile, string = _string; + (instancetype)exceptionWithConnection: (XMPPConnection *)connection profile: (OFString *)profile string: (OFString *)string { return [[[self alloc] initWithConnection: connection profile: profile string: string] autorelease]; } - initWithConnection: (XMPPConnection *)connection { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection profile: (OFString *)profile string: (OFString *)string { self = [super initWithConnection: connection]; @try { _profile = [profile copy]; _string = [string copy]; } @catch (id e) { |
︙ | ︙ | |||
152 153 154 155 156 157 158 | { [_profile release]; [_string release]; [super dealloc]; } | | | | | | | | | | 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 193 | { [_profile release]; [_string release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Stringprep with profile %@ failed on string '%@'!", _profile, _string]; } @end @implementation XMPPIDNATranslationFailedException @synthesize operation = _operation, string = _string; + (instancetype)exceptionWithConnection: (XMPPConnection *)connection operation: (OFString *)operation string: (OFString *)string { return [[[self alloc] initWithConnection: connection operation: operation string: string] autorelease]; } - initWithConnection: (XMPPConnection *)connection { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection operation: (OFString *)operation string: (OFString *)string { self = [super initWithConnection: connection]; @try { _operation = [operation copy]; _string = [string copy]; } @catch (id e) { |
︙ | ︙ | |||
202 203 204 205 206 207 208 | { [_operation release]; [_string release]; [super dealloc]; } | | | | | | | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | { [_operation release]; [_string release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"IDNA operation %@ failed on string '%@'!", _operation, _string]; } @end @implementation XMPPAuthFailedException @synthesize reason = _reason; + (instancetype)exceptionWithConnection: (XMPPConnection *)connection reason: (OFString *)reason; { return [[[self alloc] initWithConnection: connection reason: reason] autorelease]; } - initWithConnection: (XMPPConnection *)connection { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection reason: (OFString *)reason { self = [super initWithConnection: connection]; @try { _reason = [reason copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_reason release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Authentication failed. Reason: %@!", _reason]; } @end |
Modified src/XMPPFileStorage.h from [8262bc5c51] to [7e93a8c354].
︙ | ︙ | |||
19 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. */ #import <ObjFW/OFObject.h> #import "XMPPStorage.h" @class OFMutableDictionary; @interface XMPPFileStorage: OFObject <XMPPStorage> { OFString *_file; OFMutableDictionary *_data; } | > > > | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFObject.h> #import "XMPPStorage.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableDictionary; @interface XMPPFileStorage: OFObject <XMPPStorage> { OFString *_file; OFMutableDictionary *_data; } - init OF_UNAVAILABLE; - initWithFile: (OFString *)file; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPFileStorage.m from [522ef88dbb] to [d3dafb0daf].
︙ | ︙ | |||
36 37 38 39 40 41 42 | #import <ObjFW/OFNotImplementedException.h> #import "XMPPFileStorage.h" @implementation XMPPFileStorage - init { | < < < < < < | < | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #import <ObjFW/OFNotImplementedException.h> #import "XMPPFileStorage.h" @implementation XMPPFileStorage - init { OF_INVALID_INIT_METHOD } - initWithFile: (OFString *)file { self = [super init]; @try { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; _file = [file copy]; |
︙ | ︙ | |||
84 85 86 87 88 89 90 | - (void)save { [[_data messagePackRepresentation] writeToFile: _file]; } - (void)XMPP_setObject: (id)object | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | - (void)save { [[_data messagePackRepresentation] writeToFile: _file]; } - (void)XMPP_setObject: (id)object forPath: (OFString *)path { OFArray *pathComponents = [path componentsSeparatedByString: @"."]; OFMutableDictionary *iter = _data; OFEnumerator *enumerator = [pathComponents objectEnumerator]; OFString *component; size_t i = 0, components = [pathComponents count]; |
︙ | ︙ | |||
114 115 116 117 118 119 120 | if (object != nil) [iter setObject: object forKey: [pathComponents lastObject]]; else [iter removeObjectForKey: [pathComponents lastObject]]; } | | < < < | | | | | | | | | | | | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | if (object != nil) [iter setObject: object forKey: [pathComponents lastObject]]; else [iter removeObjectForKey: [pathComponents lastObject]]; } - (id)XMPP_objectForPath: (OFString *)path { id object = _data; for (OFString *component in [path componentsSeparatedByString: @"."]) object = [object objectForKey: component]; return object; } - (void)setStringValue: (OFString *)string forPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self XMPP_setObject: string forPath: path]; [pool release]; } - (OFString *)stringValueForPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFString *string; string = [self XMPP_objectForPath: path]; [pool release]; return string; } - (void)setBooleanValue: (bool)boolean forPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self XMPP_setObject: [OFNumber numberWithBool: boolean] forPath: path]; [pool release]; } - (bool)booleanValueForPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; bool boolean; boolean = [[self XMPP_objectForPath: path] boolValue]; [pool release]; return boolean; } - (void)setIntegerValue: (intmax_t)integer forPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self XMPP_setObject: [OFNumber numberWithIntMax: integer] forPath: path]; [pool release]; } - (intmax_t)integerValueForPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; intmax_t integer; integer = [[self XMPP_objectForPath: path] intMaxValue]; [pool release]; return integer; } - (void)setArray: (OFArray *)array forPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self XMPP_setObject: array forPath: path]; [pool release]; } - (OFArray *)arrayForPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFArray *array; array = [self XMPP_objectForPath: path]; [pool release]; return array; } - (void)setDictionary: (OFDictionary *)dictionary forPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self XMPP_setObject: dictionary forPath: path]; [pool release]; } - (OFDictionary *)dictionaryForPath: (OFString *)path { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDictionary *dictionary; dictionary = [self XMPP_objectForPath: path]; [pool release]; return dictionary; } @end |
Modified src/XMPPIQ.h from [15421246e4] to [e565b6e506].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPStanza.h" /** * \brief A class describing an IQ stanza. */ @interface XMPPIQ: XMPPStanza /** * \brief Creates a new XMPPIQ with the specified type and ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPIQ */ | > > | | | | | | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPStanza.h" OF_ASSUME_NONNULL_BEGIN /** * \brief A class describing an IQ stanza. */ @interface XMPPIQ: XMPPStanza /** * \brief Creates a new XMPPIQ with the specified type and ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPIQ */ + (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID; /** * \brief Initializes an already allocated XMPPIQ with the specified type and * ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return An initialized XMPPIQ */ - initWithType: (OFString *)type ID: (OFString *)ID; /** * \brief Generates a result IQ for the receiving object. * * \return A new autoreleased XMPPIQ */ - (XMPPIQ *)resultIQ; /** * \brief Generates an error IQ for the receiving object. * * \param type An error type as defined by RFC 6120 * \param condition An error condition as defined by RFC 6120 * \param text A descriptive text * \return A new autoreleased XMPPIQ */ - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition text: (nullable OFString *)text; /** * \brief Generates an error IQ for the receiving object. * * \param type An error type as defined by RFC 6120 * \param condition A defined conditions from RFC 6120 * \return A new autoreleased XMPPIQ */ - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPIQ.m from [a625c5453d] to [4202e71e12].
︙ | ︙ | |||
25 26 27 28 29 30 31 | # include "config.h" #endif #import "namespaces.h" #import "XMPPIQ.h" @implementation XMPPIQ | | | | | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | # include "config.h" #endif #import "namespaces.h" #import "XMPPIQ.h" @implementation XMPPIQ + (instancetype)IQWithType: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - initWithType: (OFString *)type ID: (OFString *)ID { self = [super initWithName: @"iq" type: type ID: ID]; @try { if (![type isEqual: @"get"] && ![type isEqual: @"set"] && ![type isEqual: @"result"] && ![type isEqual: @"error"]) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; } return self; } - (XMPPIQ *)resultIQ { XMPPIQ *ret = [XMPPIQ IQWithType: @"result" ID: [self ID]]; [ret setTo: [self from]]; [ret setFrom: nil]; return ret; } - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition text: (OFString *)text { XMPPIQ *ret = [XMPPIQ IQWithType: @"error" ID: [self ID]]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFXMLElement *error = [OFXMLElement elementWithName: @"error" namespace: XMPP_NS_CLIENT]; |
︙ | ︙ | |||
87 88 89 90 91 92 93 | [ret setFrom: nil]; [pool release]; return ret; } | | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | [ret setFrom: nil]; [pool release]; return ret; } - (XMPPIQ *)errorIQWithType: (OFString *)type condition: (OFString *)condition { return [self errorIQWithType: type condition: condition text: nil]; } @end |
Modified src/XMPPJID.h from [db8b96c7e4] to [bbf76b475f].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> /** * \brief A class for easy handling of JIDs. */ @interface XMPPJID: OFObject <OFCopying> { OFString *_node, *_domain, *_resource; } /// \brief The JID's localpart | > > | | | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN /** * \brief A class for easy handling of JIDs. */ @interface XMPPJID: OFObject <OFCopying> { OFString *_node, *_domain, *_resource; } /// \brief The JID's localpart @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *node; /// \brief The JID's domainpart @property (nonatomic, copy) OFString *domain; /// \brief The JID's resourcepart @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *resource; /** * \brief Creates a new autoreleased XMPPJID. * * \return A new autoreleased XMPPJID */ + (instancetype)JID; /** * \brief Creates a new autoreleased XMPPJID from a string. * * \param string The string to parse into a JID object * \return A new autoreleased XMPPJID */ + (instancetype)JIDWithString: (OFString *)string; /** * \brief Initializes an already allocated XMPPJID with a string. * * \param string The string to parse into a JID object * \return A initialized XMPPJID */ - initWithString: (OFString *)string; /** * \brief Returns the bare JID. * * \return An OFString containing the bare JID */ - (OFString *)bareJID; /** * \brief Returns the full JID. * * \return An OFString containing the full JID */ - (OFString *)fullJID; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPJID.m from [48ba6c2d57] to [bccd623ec3].
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 | #include <stringprep.h> #import "XMPPJID.h" #import "XMPPExceptions.h" @implementation XMPPJID + (instancetype)JID { return [[[self alloc] init] autorelease]; } | > > | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include <stringprep.h> #import "XMPPJID.h" #import "XMPPExceptions.h" @implementation XMPPJID @synthesize node = _node, domain = _domain, resource = _resource; + (instancetype)JID { return [[[self alloc] init] autorelease]; } + (instancetype)JIDWithString: (OFString *)string { return [[[self alloc] initWithString: string] autorelease]; } - initWithString: (OFString *)string { size_t nodesep, resourcesep; self = [super init]; if (string == nil) { [self release]; |
︙ | ︙ | |||
99 100 101 102 103 104 105 | [new release]; @throw e; } return new; } | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | [new release]; @throw e; } return new; } - (void)setNode: (OFString *)node { OFString *old = _node; char *nodepart; Stringprep_rc rc; if (node == nil) { [old release]; |
︙ | ︙ | |||
128 129 130 131 132 133 134 | } @finally { free(nodepart); } [old release]; } | < < < < < | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | } @finally { free(nodepart); } [old release]; } - (void)setDomain: (OFString *)domain { OFString *old = _domain; char *srv; Stringprep_rc rc; if (((rc = stringprep_profile([domain UTF8String], &srv, "Nameprep", 0)) != STRINGPREP_OK) || (srv[0] == '\0') || |
︙ | ︙ | |||
156 157 158 159 160 161 162 | } @finally { free(srv); } [old release]; } | < < < < < | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | } @finally { free(srv); } [old release]; } - (void)setResource: (OFString *)resource { OFString *old = _resource; char *res; Stringprep_rc rc; if (resource == nil) { [old release]; |
︙ | ︙ | |||
190 191 192 193 194 195 196 | } @finally { free(res); } [old release]; } | < < < < < | | | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | } @finally { free(res); } [old release]; } - (OFString *)bareJID { if (_node != nil) return [OFString stringWithFormat: @"%@@%@", _node, _domain]; else return [OFString stringWithFormat: @"%@", _domain]; } - (OFString *)fullJID { /* If we don't have a resource, the full JID is equal to the bare JID */ if (_resource == nil) return [self bareJID]; if (_node != nil) return [OFString stringWithFormat: @"%@@%@/%@", _node, _domain, _resource]; else return [OFString stringWithFormat: @"%@/%@", _domain, _resource]; } - (OFString *)description { return [self fullJID]; } - (bool)isEqual: (id)object { XMPPJID *JID; |
︙ | ︙ |
Modified src/XMPPMessage.h from [546573fa68] to [c499d3c2dc].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPStanza.h" /** * \brief A class describing a message stanza. */ @interface XMPPMessage: XMPPStanza /** The text content of the body of the message. */ @property (copy) OFString *body; /** * \brief Creates a new autoreleased XMPPMessage. * * \return A new autoreleased XMPPMessage */ + (instancetype)message; /** * \brief Creates a new autoreleased XMPPMessage with the specified ID. * * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPMessage */ | > > | | | | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPStanza.h" OF_ASSUME_NONNULL_BEGIN /** * \brief A class describing a message stanza. */ @interface XMPPMessage: XMPPStanza /** The text content of the body of the message. */ @property (copy) OFString *body; /** * \brief Creates a new autoreleased XMPPMessage. * * \return A new autoreleased XMPPMessage */ + (instancetype)message; /** * \brief Creates a new autoreleased XMPPMessage with the specified ID. * * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPMessage */ + (instancetype)messageWithID: (nullable OFString *)ID; /** * \brief Creates a new autoreleased XMPPMessage with the specified type. * * \param type The value for the stanza's type attribute * \return A new autoreleased XMPPMessage */ + (instancetype)messageWithType: (nullable OFString *)type; /** * \brief Creates a new autoreleased XMPPMessage with the specified type and ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPMessage */ + (instancetype)messageWithType: (nullable OFString *)type ID: (nullable OFString *)ID; /** * \brief Initializes an already allocated XMPPMessage with the specified ID. * * \param ID The value for the stanza's id attribute * \return A initialized XMPPMessage */ - initWithID: (nullable OFString *)ID; /** * \brief Initializes an already allocated XMPPMessage with the specified type. * * \param type The value for the stanza's type attribute * \return A initialized XMPPMessage */ - initWithType: (nullable OFString *)type; /** * \brief Initializes an already allocated XMPPMessage with the specified type * and ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A initialized XMPPMessage */ - initWithType: (nullable OFString *)type ID: (nullable OFString *)ID OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPMessage.m from [19d004e57c] to [64ae4d9271].
︙ | ︙ | |||
30 31 32 33 34 35 36 | @implementation XMPPMessage + (instancetype)message { return [[[self alloc] init] autorelease]; } | | | | | | | | | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | @implementation XMPPMessage + (instancetype)message { return [[[self alloc] init] autorelease]; } + (instancetype)messageWithID: (OFString *)ID { return [[[self alloc] initWithID: ID] autorelease]; } + (instancetype)messageWithType: (OFString *)type { return [[[self alloc] initWithType: type] autorelease]; } + (instancetype)messageWithType: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - init { return [self initWithType: nil ID: nil]; } - initWithID: (OFString *)ID { return [self initWithType: nil ID: ID]; } - initWithType: (OFString *)type { return [self initWithType: type ID: nil]; } - initWithType: (OFString *)type ID: (OFString *)ID { return [super initWithName: @"message" type: type ID: ID]; } - (void)setBody: (OFString *)body { OFXMLElement *oldBody = [self elementForName: @"body" namespace: XMPP_NS_CLIENT]; if (oldBody != nil) [self removeChild: oldBody]; if (body != nil) [self addChild: [OFXMLElement elementWithName: @"body" namespace: XMPP_NS_CLIENT stringValue: body]]; } - (OFString *)body { return [[self elementForName: @"body" namespace: XMPP_NS_CLIENT] stringValue]; } @end |
Modified src/XMPPMulticastDelegate.h from [9c7e2a3fbd] to [51673325c7].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFObject.h> @class OFDataArray; /** * \brief A class to provide multiple delegates in a single class */ @interface XMPPMulticastDelegate: OFObject { | > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFObject.h> OF_ASSUME_NONNULL_BEGIN @class OFDataArray; /** * \brief A class to provide multiple delegates in a single class */ @interface XMPPMulticastDelegate: OFObject { |
︙ | ︙ | |||
49 50 51 52 53 54 55 | /** * \brief Broadcasts a selector with an object to all registered delegates. * * \param selector The selector to broadcast * \param object The object to broadcast */ - (bool)broadcastSelector: (SEL)selector | | | | > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /** * \brief Broadcasts a selector with an object to all registered delegates. * * \param selector The selector to broadcast * \param object The object to broadcast */ - (bool)broadcastSelector: (SEL)selector withObject: (nullable id)object; /** * \brief Broadcasts a selector with two objects to all registered delegates. * * \param selector The selector to broadcast * \param object1 The first object to broadcast * \param object2 The second object to broadcast */ - (bool)broadcastSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPPLAINAuth.h from [5dfa895145] to [3c1bd83caf].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> #import "XMPPAuthenticator.h" /** * \brief A class to authenticate using SASL PLAIN */ @interface XMPPPLAINAuth: XMPPAuthenticator /** * \brief Creates a new autoreleased XMPPPLAINAuth with an authcid and password. * * \param authcid The authcid to authenticate with * \param password The password to authenticate with * \return A new autoreleased XMPPPLAINAuth */ | > > | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> #import "XMPPAuthenticator.h" OF_ASSUME_NONNULL_BEGIN /** * \brief A class to authenticate using SASL PLAIN */ @interface XMPPPLAINAuth: XMPPAuthenticator /** * \brief Creates a new autoreleased XMPPPLAINAuth with an authcid and password. * * \param authcid The authcid to authenticate with * \param password The password to authenticate with * \return A new autoreleased XMPPPLAINAuth */ + (instancetype)PLAINAuthWithAuthcid: (nullable OFString *)authcid password: (nullable OFString *)password; /** * \brief Creates a new autoreleased XMPPPLAINAuth with an authzid, authcid and * password. * * \param authzid The authzid to get authorization for * \param authcid The authcid to authenticate with * \param password The password to authenticate with * \return A new autoreleased XMPPPLAINAuth */ + (instancetype)PLAINAuthWithAuthzid: (nullable OFString *)authzid authcid: (nullable OFString *)authcid password: (nullable OFString *)password; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPPLAINAuth.m from [9d4992173d] to [9f0783c62c].
︙ | ︙ | |||
24 25 26 27 28 29 30 | # include "config.h" #endif #import "XMPPPLAINAuth.h" #import "XMPPExceptions.h" @implementation XMPPPLAINAuth | | | | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # include "config.h" #endif #import "XMPPPLAINAuth.h" #import "XMPPExceptions.h" @implementation XMPPPLAINAuth + (instancetype)PLAINAuthWithAuthcid: (OFString *)authcid password: (OFString *)password { return [[[self alloc] initWithAuthcid: authcid password: password] autorelease]; } + (instancetype)PLAINAuthWithAuthzid: (OFString *)authzid authcid: (OFString *)authcid password: (OFString *)password { return [[[self alloc] initWithAuthzid: authzid authcid: authcid password: password] autorelease]; } - (OFDataArray *)initialMessage { OFDataArray *message = [OFDataArray dataArray]; /* authzid */ if (_authzid) [message addItem: _authzid]; |
︙ | ︙ |
Modified src/XMPPPresence.h from [3d03c9db92] to [0497c404f5].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPStanza.h" /** * \brief A class describing a presence stanza. */ @interface XMPPPresence: XMPPStanza <OFComparing> { OFString *_status, *_show; OFNumber *_priority; } /** * The text content of the status element. */ | > > > > > > > | | | | | | | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPStanza.h" OF_ASSUME_NONNULL_BEGIN /** * \brief A class describing a presence stanza. */ @interface XMPPPresence: XMPPStanza <OFComparing> { OFString *_status, *_show; OFNumber *_priority; } /** * The value of the stanza's type attribute. */ @property OF_NULL_RESETTABLE_PROPERTY (nonatomic, copy) OFString *type; /** * The text content of the status element. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *status; /** * The text content of the show element of the presence stanza. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *show; /** * The numeric content of the priority element. */ @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFNumber *priority; /** * \brief Creates a new autoreleased XMPPPresence. * * \return A new autoreleased XMPPPresence */ + (instancetype)presence; /** * \brief Creates a new autoreleased XMPPPresence with the specified ID. * * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPPresence */ + (instancetype)presenceWithID: (nullable OFString *)ID; /** * \brief Creates a new autoreleased XMPPPresence with the specified type. * * \param type The value for the stanza's type attribute * \return A new autoreleased XMPPPresence */ + (instancetype)presenceWithType: (nullable OFString *)type; /** * \brief Creates a new autoreleased XMPPPresence with the specified type and * ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPPresence */ + (instancetype)presenceWithType: (nullable OFString *)type ID: (nullable OFString *)ID; /** * \brief Initializes an already allocated XMPPPresence with the specified ID. * * \param ID The value for the stanza's id attribute * \return A initialized XMPPPresence */ - initWithID: (nullable OFString *)ID; /** * \brief Initializes an already allocated XMPPPresence with the specified type. * * \param type The value for the stanza's type attribute * \return A initialized XMPPPresence */ - initWithType: (nullable OFString *)type; /** * \brief Initializes an already allocated XMPPPresence with the specified type * and ID. * * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A initialized XMPPPresence */ - initWithType: (nullable OFString *)type ID: (nullable OFString *)ID; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPPresence.m from [5c903aded4] to [defd4ee1a6].
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 | if ([show isEqual: @"xa"]) return 4; OF_ENSURE(0); } @implementation XMPPPresence + (instancetype)presence { return [[[self alloc] init] autorelease]; } | > > | | | | | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | if ([show isEqual: @"xa"]) return 4; OF_ENSURE(0); } @implementation XMPPPresence @dynamic type; + (instancetype)presence { return [[[self alloc] init] autorelease]; } + (instancetype)presenceWithID: (OFString *)ID { return [[[self alloc] initWithID: ID] autorelease]; } + (instancetype)presenceWithType: (OFString *)type { return [[[self alloc] initWithType: type] autorelease]; } + (instancetype)presenceWithType: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithType: type ID: ID] autorelease]; } - init { return [self initWithType: nil ID: nil]; } - initWithID: (OFString *)ID { return [self initWithType: nil ID: ID]; } - initWithType: (OFString *)type { return [self initWithType: type ID: nil]; } - initWithType: (OFString *)type ID: (OFString *)ID { return [super initWithName: @"presence" type: type ID: ID]; } - initWithElement: (OFXMLElement *)element { self = [super initWithElement: element]; @try { OFXMLElement *subElement; if ((subElement = [element elementForName: @"show" |
︙ | ︙ | |||
131 132 133 134 135 136 137 | [_status release]; [_show release]; [_priority release]; [super dealloc]; } | | | | | | < < < < < | < < < < < | | < < < < < | | 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 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | [_status release]; [_show release]; [_priority release]; [super dealloc]; } - (void)setType: (OFString *)type { if (type == nil) type = @"available"; [super setType: type]; } - (void)setShow: (OFString *)show { OFXMLElement *oldShow = [self elementForName: @"show" namespace: XMPP_NS_CLIENT]; OFString *old; if (oldShow != nil) [self removeChild: oldShow]; if (show != nil) [self addChild: [OFXMLElement elementWithName: @"show" namespace: XMPP_NS_CLIENT stringValue: show]]; old = _show; _show = [show copy]; [old release]; } - (void)setStatus: (OFString *)status { OFXMLElement *oldStatus = [self elementForName: @"status" namespace: XMPP_NS_CLIENT]; OFString *old; if (oldStatus != nil) [self removeChild: oldStatus]; if (status != nil) [self addChild: [OFXMLElement elementWithName: @"status" namespace: XMPP_NS_CLIENT stringValue: status]]; old = _status; _status = [status copy]; [old release]; } - (void)setPriority: (OFNumber *)priority { intmax_t prio = [priority intMaxValue]; OFNumber *old; if ((prio < -128) || (prio > 127)) @throw [OFInvalidArgumentException exception]; OFXMLElement *oldPriority = [self elementForName: @"priority" namespace: XMPP_NS_CLIENT]; if (oldPriority != nil) [self removeChild: oldPriority]; OFString *priority_s = [OFString stringWithFormat: @"%" @PRId8, [priority int8Value]]; [self addChild: [OFXMLElement elementWithName: @"priority" namespace: XMPP_NS_CLIENT stringValue: priority_s]]; old = _priority; _priority = [priority copy]; [old release]; } - (of_comparison_result_t)compare: (id <OFComparing>)object { XMPPPresence *otherPresence; OFNumber *otherPriority; OFString *otherShow; of_comparison_result_t priorityOrder; if (object == self) return OF_ORDERED_SAME; if (![object isKindOfClass: [XMPPPresence class]]) @throw [OFInvalidArgumentException exception]; otherPresence = (XMPPPresence *)object; otherPriority = [otherPresence priority]; if (otherPriority == nil) otherPriority = [OFNumber numberWithInt8: 0]; if (_priority != nil) priorityOrder = [_priority compare: otherPriority]; else |
︙ | ︙ |
Modified src/XMPPRoster.h from [9f74b009a4] to [7a62e71bc2].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | */ #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPStorage.h" @class XMPPRosterItem; @class XMPPIQ; @class XMPPRoster; @class XMPPMulticastDelegate; /** * \brief A protocol that should be (partially) implemented by delegates * of a XMPPRoster */ @protocol XMPPRosterDelegate | > > < < < | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | */ #import <ObjFW/ObjFW.h> #import "XMPPConnection.h" #import "XMPPStorage.h" OF_ASSUME_NONNULL_BEGIN @class XMPPRosterItem; @class XMPPIQ; @class XMPPRoster; @class XMPPMulticastDelegate; /** * \brief A protocol that should be (partially) implemented by delegates * of a XMPPRoster */ @protocol XMPPRosterDelegate @optional /** * \brief This callback is called after the roster was received (as a result of * calling -requestRoster). * * \param roster The roster that was received */ - (void)rosterWasReceived: (XMPPRoster *)roster; /** * \brief This callback is called whenever a roster push was received. * * \param roster The roster that was updated by the roster push * \param rosterItem The roster item received in the push */ - (void)roster: (XMPPRoster *)roster didReceiveRosterItem: (XMPPRosterItem *)rosterItem; @end /** * \brief A class implementing roster related functionality. */ @interface XMPPRoster: OFObject <XMPPConnectionDelegate> { |
︙ | ︙ | |||
76 77 78 79 80 81 82 | @property (readonly, assign) XMPPConnection *connection; /** * \brief An object for data storage, conforming to the XMPPStorage protocol. * * Inherited from the connection if not overridden. */ | | | > > > | | | | | | < < < < < < < > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | @property (readonly, assign) XMPPConnection *connection; /** * \brief An object for data storage, conforming to the XMPPStorage protocol. * * Inherited from the connection if not overridden. */ @property (nonatomic, assign) id <XMPPStorage> dataStorage; /** * \brief The list of contacts as an OFDictionary with the bare JID as a string * as key. */ @property (readonly, nonatomic) OFDictionary OF_GENERIC(OFString *, XMPPRosterItem *) *rosterItems; - init OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPRoster. * * \param connection The connection roster related stanzas are send and * received over * \return An initialized XMPPRoster */ - initWithConnection: (XMPPConnection *)connection OF_DESIGNATED_INITIALIZER; /** * \brief Requests the roster from the server. */ - (void)requestRoster; /** * \brief Adds a new contact to the roster. * * \param rosterItem The roster item to add to the roster */ - (void)addRosterItem: (XMPPRosterItem *)rosterItem; /** * \brief Updates an already existing contact in the roster. * * \param rosterItem The roster item to update */ - (void)updateRosterItem: (XMPPRosterItem *)rosterItem; /** * \brief Delete a contact from the roster. * * \param rosterItem The roster item to delete */ - (void)deleteRosterItem: (XMPPRosterItem *)rosterItem; /** * \brief Adds the specified delegate. * * \param delegate The delegate to add */ - (void)addDelegate: (id <XMPPRosterDelegate>)delegate; /** * \brief Removes the specified delegate. * * \param delegate The delegate to remove */ - (void)removeDelegate: (id <XMPPRosterDelegate>)delegate; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPRoster.m from [8b7b6f027e] to [7642c78519].
︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 | #import "XMPPRoster.h" #import "XMPPRosterItem.h" #import "XMPPConnection.h" #import "XMPPIQ.h" #import "XMPPJID.h" #import "XMPPMulticastDelegate.h" #import "namespaces.h" @implementation XMPPRoster @synthesize connection = _connection, dataStorage = _dataStorage; @synthesize rosterItems = _rosterItems; | > > > > > > > > > > > > > > > > | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #import "XMPPRoster.h" #import "XMPPRosterItem.h" #import "XMPPConnection.h" #import "XMPPIQ.h" #import "XMPPJID.h" #import "XMPPMulticastDelegate.h" #import "namespaces.h" OF_ASSUME_NONNULL_BEGIN @interface XMPPRoster () - (void)XMPP_updateRosterItem: (XMPPRosterItem *)rosterItem; - (void)XMPP_handleInitialRosterForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ; - (XMPPRosterItem *)XMPP_rosterItemWithXMLElement: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END @implementation XMPPRoster @synthesize connection = _connection, dataStorage = _dataStorage; @synthesize rosterItems = _rosterItems; - init { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection { self = [super init]; @try { _rosterItems = [[OFMutableDictionary alloc] init]; _connection = connection; [_connection addDelegate: self]; |
︙ | ︙ | |||
98 99 100 101 102 103 104 | [_connection sendIQ: iq callbackTarget: self selector: @selector(XMPP_handleInitialRosterForConnection: IQ:)]; } | | | | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | [_connection sendIQ: iq callbackTarget: self selector: @selector(XMPP_handleInitialRosterForConnection: IQ:)]; } - (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ { OFXMLElement *rosterElement; OFXMLElement *element; XMPPRosterItem *rosterItem; OFString *origin; rosterElement = [IQ elementForName: @"query" namespace: XMPP_NS_ROSTER]; if (rosterElement == nil) return false; if (![[IQ type] isEqual: @"set"]) return false; // Ensure the roster push has been sent by the server origin = [[IQ from] fullJID]; if (origin != nil && ![origin isEqual: [[connection JID] bareJID]]) return false; element = [rosterElement elementForName: @"item" namespace: XMPP_NS_ROSTER]; if (element != nil) { |
︙ | ︙ | |||
142 143 144 145 146 147 148 | OFString *ver = [[rosterElement attributeForName: @"ver"] stringValue]; [_dataStorage setStringValue: ver forPath: @"roster.ver"]; [_dataStorage save]; } | | | | | 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 | OFString *ver = [[rosterElement attributeForName: @"ver"] stringValue]; [_dataStorage setStringValue: ver forPath: @"roster.ver"]; [_dataStorage save]; } [connection sendStanza: [IQ resultIQ]]; return true; } - (void)addRosterItem: (XMPPRosterItem *)rosterItem { [self updateRosterItem: rosterItem]; } - (void)updateRosterItem: (XMPPRosterItem *)rosterItem { XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [_connection generateStanzaID]]; OFXMLElement *query = [OFXMLElement elementWithName: @"query" namespace: XMPP_NS_ROSTER]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPP_NS_ROSTER]; |
︙ | ︙ | |||
181 182 183 184 185 186 187 | [query addChild: item]; [IQ addChild: query]; [_connection sendStanza: IQ]; } | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | [query addChild: item]; [IQ addChild: query]; [_connection sendStanza: IQ]; } - (void)deleteRosterItem: (XMPPRosterItem *)rosterItem { XMPPIQ *IQ = [XMPPIQ IQWithType: @"set" ID: [_connection generateStanzaID]]; OFXMLElement *query = [OFXMLElement elementWithName: @"query" namespace: XMPP_NS_ROSTER]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPP_NS_ROSTER]; |
︙ | ︙ | |||
220 221 222 223 224 225 226 | if (_rosterRequested) /* FIXME: Find a better exception! */ @throw [OFInvalidArgumentException exception]; _dataStorage = dataStorage; } | < < < < < < < < < < | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | if (_rosterRequested) /* FIXME: Find a better exception! */ @throw [OFInvalidArgumentException exception]; _dataStorage = dataStorage; } - (void)XMPP_updateRosterItem: (XMPPRosterItem *)rosterItem { if ([_connection supportsRosterVersioning]) { OFMutableDictionary *items = [[[_dataStorage dictionaryForPath: @"roster.items"] mutableCopy] autorelease]; if (items == nil) items = [OFMutableDictionary dictionary]; |
︙ | ︙ | |||
270 271 272 273 274 275 276 | if (![[rosterItem subscription] isEqual: @"remove"]) [_rosterItems setObject: rosterItem forKey: [[rosterItem JID] bareJID]]; else [_rosterItems removeObjectForKey: [[rosterItem JID] bareJID]]; } | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | if (![[rosterItem subscription] isEqual: @"remove"]) [_rosterItems setObject: rosterItem forKey: [[rosterItem JID] bareJID]]; else [_rosterItems removeObjectForKey: [[rosterItem JID] bareJID]]; } - (XMPPRosterItem *)XMPP_rosterItemWithXMLElement: (OFXMLElement *)element { OFString *subscription; OFEnumerator *groupEnumerator; OFXMLElement *groupElement; OFMutableArray *groups = [OFMutableArray array]; XMPPRosterItem *rosterItem = [XMPPRosterItem rosterItem]; [rosterItem setJID: [XMPPJID JIDWithString: |
︙ | ︙ | |||
306 307 308 309 310 311 312 | if ([groups count] > 0) [rosterItem setGroups: groups]; return rosterItem; } | | | | < < < < | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | if ([groups count] > 0) [rosterItem setGroups: groups]; return rosterItem; } - (void)XMPP_handleInitialRosterForConnection: (XMPPConnection *)connection IQ: (XMPPIQ *)IQ { OFXMLElement *rosterElement = [IQ elementForName: @"query" namespace: XMPP_NS_ROSTER]; if ([connection supportsRosterVersioning]) { if (rosterElement == nil) { OFDictionary *items = [_dataStorage dictionaryForPath: @"roster.items"]; OFEnumerator *enumerator = [items objectEnumerator]; OFDictionary *item; |
︙ | ︙ | |||
346 347 348 349 350 351 352 | forKey: [JID bareJID]]; } } else [_dataStorage setDictionary: nil forPath: @"roster.items"]; } | | < | 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | forKey: [JID bareJID]]; } } else [_dataStorage setDictionary: nil forPath: @"roster.items"]; } for (OFXMLElement *element in [rosterElement children]) { OFAutoreleasePool *pool; XMPPRosterItem *rosterItem; if (![[element name] isEqual: @"item"] || ![[element namespace] isEqual: XMPP_NS_ROSTER]) continue; |
︙ | ︙ |
Modified src/XMPPRosterItem.h from [fbf33416fb] to [b424f574a0].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> @class XMPPJID; /** * \brief A class for representing an item in the roster. */ @interface XMPPRosterItem: OFObject { XMPPJID *_JID; OFString *_name; OFString *_subscription; OFArray *_groups; } /// \brief The JID of the roster item | > > | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @class XMPPJID; /** * \brief A class for representing an item in the roster. */ @interface XMPPRosterItem: OFObject { XMPPJID *_JID; OFString *_name; OFString *_subscription; OFArray *_groups; } /// \brief The JID of the roster item @property (nonatomic, copy) XMPPJID *JID; /// \brief The name of the roster item to show to the user @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *name; /// \brief The subscription for the roster item @property (nonatomic, copy) OFString *subscription; /// \brief An array of groups in which the roster item is @property (nonatomic, copy) OFArray OF_GENERIC(OFString *) *groups; /** * \brief Creates a new autoreleased roster item. * * \return A new autoreleased roster item. */ + (instancetype)rosterItem; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPRosterItem.m from [896b51646c] to [5e285f3028].
︙ | ︙ | |||
62 63 64 65 66 67 68 | [new release]; @throw e; } return new; } | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | [new release]; @throw e; } return new; } - (OFString *)description { return [OFString stringWithFormat: @"<XMPPRosterItem, JID=%@, name=%@, " @"subscription=%@, groups=%@>", _JID, _name, _subscription, _groups]; } @end |
Modified src/XMPPSCRAMAuth.h from [caa9d18a81] to [fc2ab6d5ef].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> #import "XMPPAuthenticator.h" #import "XMPPConnection.h" /** * \brief A class to authenticate using SCRAM */ @interface XMPPSCRAMAuth: XMPPAuthenticator { Class _hashType; OFString *_cNonce; | > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> #import "XMPPAuthenticator.h" #import "XMPPConnection.h" OF_ASSUME_NONNULL_BEGIN /** * \brief A class to authenticate using SCRAM */ @interface XMPPSCRAMAuth: XMPPAuthenticator { Class _hashType; OFString *_cNonce; |
︙ | ︙ | |||
45 46 47 48 49 50 51 | * \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 */ | | | | | | | | > > > > > > | | | | | | | | > < | < < < < < < < < < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | * \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 */ + (instancetype)SCRAMAuthWithAuthcid: (nullable OFString *)authcid password: (nullable OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable; /** * \brief Creates a new autoreleased XMPPSCRAMAuth with an authzid, authcid and * password. * * \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 */ + (instancetype)SCRAMAuthWithAuthzid: (nullable OFString *)authzid authcid: (nullable OFString *)authcid password: (nullable OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable; - initWithAuthcid: (nullable OFString *)authcid password: (nullable OFString *)password OF_UNAVAILABLE; - initWithAuthzid: (nullable OFString *)authzid authcid: (nullable OFString *)authcid password: (nullable OFString *)password OF_UNAVAILABLE; /** * \brief 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: (nullable OFString *)authcid password: (nullable OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable; /** * \brief Initializes an already allocated XMPPSCRAMAuth with a authzid, * authcid and password. * * \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: (nullable OFString *)authzid authcid: (nullable OFString *)authcid password: (nullable OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPSCRAMAuth.m from [ec991072f9] to [e2f43c5d67].
︙ | ︙ | |||
32 33 34 35 36 37 38 39 40 | #import <ObjOpenSSL/SSLSocket.h> #import "XMPPSCRAMAuth.h" #import "XMPPExceptions.h" #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c @implementation XMPPSCRAMAuth | > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #import <ObjOpenSSL/SSLSocket.h> #import "XMPPSCRAMAuth.h" #import "XMPPExceptions.h" #define HMAC_IPAD 0x36 #define HMAC_OPAD 0x5c OF_ASSUME_NONNULL_BEGIN @interface XMPPSCRAMAuth () - (OFString *)XMPP_genNonce; - (const uint8_t *)XMPP_HMACWithKey: (OFDataArray *)key data: (OFDataArray *)data; - (OFDataArray *)XMPP_hiWithData: (OFDataArray *)str salt: (OFDataArray *)salt iterationCount: (intmax_t)i; - (OFDataArray *)XMPP_parseServerFirstMessage: (OFDataArray *)data; - (OFDataArray *)XMPP_parseServerFinalMessage: (OFDataArray *)data; @end OF_ASSUME_NONNULL_END @implementation XMPPSCRAMAuth + (instancetype)SCRAMAuthWithAuthcid: (OFString *)authcid password: (OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable { return [[[self alloc] initWithAuthcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable] autorelease]; } + (instancetype)SCRAMAuthWithAuthzid: (OFString *)authzid authcid: (OFString *)authcid password: (OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable { return [[[self alloc] initWithAuthzid: authzid authcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable] autorelease]; } - initWithAuthcid: (OFString *)authcid password: (OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable { return [self initWithAuthzid: nil authcid: authcid password: password connection: connection hash: hash plusAvailable: plusAvailable]; } - initWithAuthzid: (OFString *)authzid authcid: (OFString *)authcid password: (OFString *)password connection: (XMPPConnection *)connection hash: (Class)hash plusAvailable: (bool)plusAvailable { self = [super initWithAuthzid: authzid authcid: authcid password: password]; |
︙ | ︙ | |||
105 106 107 108 109 110 111 | [_serverSignature release]; [_cNonce release]; [_connection release]; [super dealloc]; } | | | | | 120 121 122 123 124 125 126 127 128 129 130 131 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 161 162 163 164 165 166 167 168 | [_serverSignature release]; [_cNonce release]; [_connection release]; [super dealloc]; } - (void)setAuthzid: (OFString *)authzid { OFString *old = _authzid; if (authzid) { OFMutableString *new = [[authzid mutableCopy] autorelease]; [new replaceOccurrencesOfString: @"=" withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"]; _authzid = [new retain]; } else _authzid = nil; [old release]; } - (void)setAuthcid: (OFString *)authcid { OFString *old = _authcid; if (authcid) { OFMutableString *new = [[authcid mutableCopy] autorelease]; [new replaceOccurrencesOfString: @"=" withString: @"=3D"]; [new replaceOccurrencesOfString: @"," withString: @"=2C"]; _authcid = [new retain]; } else _authcid = nil; [old release]; } - (OFDataArray *)initialMessage { OFDataArray *ret = [OFDataArray dataArray]; /* New authentication attempt, reset status */ [_cNonce release]; _cNonce = nil; [_GS2Header release]; |
︙ | ︙ | |||
176 177 178 179 180 181 182 | [ret addItems: [_clientFirstMessageBare UTF8String] count: [_clientFirstMessageBare UTF8StringLength]]; return ret; } | | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | [ret addItems: [_clientFirstMessageBare UTF8String] count: [_clientFirstMessageBare UTF8StringLength]]; return ret; } - (OFDataArray *)continueWithData: (OFDataArray *)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDataArray *ret; if (!_serverSignature) ret = [self XMPP_parseServerFirstMessage: data]; else ret = [self XMPP_parseServerFinalMessage: data]; [ret retain]; [pool release]; return [ret autorelease]; } - (OFDataArray *)XMPP_parseServerFirstMessage: (OFDataArray *)data { size_t i; const uint8_t *clientKey, *serverKey, *clientSignature; intmax_t iterCount = 0; id <OFCryptoHash> hash; OFDataArray *ret, *authMessage, *tmpArray, *salt = nil, *saltedPassword; OFString *tmpString, *sNonce = nil; |
︙ | ︙ | |||
249 250 251 252 253 254 255 | @throw [OFInvalidServerReplyException exception]; // Add c=<base64(GS2Header+channelBindingData)> tmpArray = [OFDataArray dataArray]; [tmpArray addItems: [_GS2Header UTF8String] count: [_GS2Header UTF8StringLength]]; if (_plusAvailable && [_connection encrypted]) { | | > | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | @throw [OFInvalidServerReplyException exception]; // Add c=<base64(GS2Header+channelBindingData)> tmpArray = [OFDataArray dataArray]; [tmpArray addItems: [_GS2Header UTF8String] count: [_GS2Header UTF8StringLength]]; if (_plusAvailable && [_connection encrypted]) { OFDataArray *channelBinding = [((SSLSocket *)[_connection socket]) channelBindingDataWithType: @"tls-unique"]; [tmpArray addItems: [channelBinding items] count: [channelBinding count]]; } tmpString = [tmpArray stringByBase64Encoding]; [ret addItems: "c=" count: 2]; |
︙ | ︙ | |||
308 309 310 311 312 313 314 | clientKey = [self XMPP_HMACWithKey: saltedPassword data: tmpArray]; /* * IETF RFC 5802: * StoredKey := H(ClientKey) */ | | | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | clientKey = [self XMPP_HMACWithKey: saltedPassword data: tmpArray]; /* * IETF RFC 5802: * StoredKey := H(ClientKey) */ [hash updateWithBuffer: (void *)clientKey length: [_hashType digestSize]]; tmpArray = [OFDataArray dataArray]; [tmpArray addItems: [hash digest] count: [_hashType digestSize]]; /* * IETF RFC 5802: |
︙ | ︙ | |||
364 365 366 367 368 369 370 | tmpString = [tmpArray stringByBase64Encoding]; [ret addItems: [tmpString UTF8String] count: [tmpString UTF8StringLength]]; return ret; } | | | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | tmpString = [tmpArray stringByBase64Encoding]; [ret addItems: [tmpString UTF8String] count: [tmpString UTF8StringLength]]; return ret; } - (OFDataArray *)XMPP_parseServerFinalMessage: (OFDataArray *)data { OFString *mess, *value; /* * server-final-message already received, * we were just waiting for the last word from the server */ |
︙ | ︙ | |||
394 395 396 397 398 399 400 | } else @throw [XMPPAuthFailedException exceptionWithConnection: nil reason: value]; return nil; } | | | | | | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | } else @throw [XMPPAuthFailedException exceptionWithConnection: nil reason: value]; return nil; } - (OFString *)XMPP_genNonce { uint8_t buf[64]; size_t i; assert(RAND_pseudo_bytes(buf, 64) >= 0); for (i = 0; i < 64; i++) { // Restrict salt to printable range, but do not include '~'... buf[i] = (buf[i] % ('~' - '!')) + '!'; // ...so we can use it to replace ',' if (buf[i] == ',') buf[i] = '~'; } return [OFString stringWithCString: (char *)buf encoding: OF_STRING_ENCODING_ASCII length: 64]; } - (const uint8_t *)XMPP_HMACWithKey: (OFDataArray *)key data: (OFDataArray *)data { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDataArray *k = [OFDataArray dataArray]; size_t i, kSize, blockSize = [_hashType blockSize]; uint8_t *kI = NULL, *kO = NULL; id <OFCryptoHash> hashI, hashO; |
︙ | ︙ | |||
449 450 451 452 453 454 455 | for (i = 0; i < blockSize; i++) { kI[i] ^= HMAC_IPAD; kO[i] ^= HMAC_OPAD; } hashI = [[[_hashType alloc] init] autorelease]; | | | | | | | | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | for (i = 0; i < blockSize; i++) { kI[i] ^= HMAC_IPAD; kO[i] ^= HMAC_OPAD; } hashI = [[[_hashType alloc] init] autorelease]; [hashI updateWithBuffer: (char *)kI length: blockSize]; [hashI updateWithBuffer: [data items] length: [data itemSize] * [data count]]; hashO = [[[_hashType alloc] init] autorelease]; [hashO updateWithBuffer: (char *)kO length: blockSize]; [hashO updateWithBuffer: (char *)[hashI digest] length: [_hashType digestSize]]; } @finally { [self freeMemory: kI]; [self freeMemory: kO]; } [hashO retain]; [pool release]; return [[hashO autorelease] digest]; } - (OFDataArray *)XMPP_hiWithData: (OFDataArray *)str salt: (OFDataArray *)salt iterationCount: (intmax_t)i { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; size_t digestSize = [_hashType digestSize]; uint8_t *result = NULL; const uint8_t *u, *uOld; intmax_t j, k; OFDataArray *salty, *tmp, *ret; |
︙ | ︙ |
Modified src/XMPPSRVLookup.h from [f29224bbe8] to [c9768d0ace].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | */ #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> #import <ObjFW/ObjFW.h> @interface XMPPSRVEntry: OFObject { uint16_t _priority; uint16_t _weight; uint32_t _accumulatedWeight; uint16_t _port; OFString *_target; } @property (readonly) uint16_t priority; @property (readonly) uint16_t weight; @property uint32_t accumulatedWeight; @property (readonly) uint16_t port; | > > | | > | | | > | < < < > | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | */ #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @interface XMPPSRVEntry: OFObject { uint16_t _priority; uint16_t _weight; uint32_t _accumulatedWeight; uint16_t _port; OFString *_target; } @property (readonly) uint16_t priority; @property (readonly) uint16_t weight; @property uint32_t accumulatedWeight; @property (readonly) uint16_t port; @property (readonly, nonatomic) OFString *target; + (instancetype)entryWithPriority: (uint16_t)priority weight: (uint16_t)weight port: (uint16_t)port target: (OFString *)target; + (instancetype)entryWithResourceRecord: (ns_rr)resourceRecord handle: (ns_msg)handle; - init OF_UNAVAILABLE; - initWithPriority: (uint16_t)priority weight: (uint16_t)weight port: (uint16_t)port target: (OFString *)target; - initWithResourceRecord: (ns_rr)resourceRecord handle: (ns_msg)handle; @end @interface XMPPSRVLookup: OFObject <OFEnumerating> { OFString *_domain; struct __res_state _resState; OFList *_list; } @property (readonly, nonatomic) OFString *domain; + (instancetype)lookupWithDomain: (OFString *)domain; - init OF_UNAVAILABLE; - initWithDomain: (OFString *)domain; @end @interface XMPPSRVEnumerator: OFEnumerator { OFList *_list; of_list_object_t *_listIter; OFList *_subListCopy; bool _done; } - init OF_UNAVAILABLE; - initWithList: (OFList *)list; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPSRVLookup.m from [b57e70e54d] to [e13fa9dc89].
︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include <netdb.h> #include <sys/types.h> #include <openssl/rand.h> #import "XMPPSRVLookup.h" #import <ObjFW/OFLocalization.h> @implementation XMPPSRVEntry @synthesize priority = _priority, weight = _weight; @synthesize accumulatedWeight = _accumulatedWeight, port = _port; @synthesize target = _target; + (instancetype)entryWithPriority: (uint16_t)priority weight: (uint16_t)weight port: (uint16_t)port | > > > > > > > > > | < < < < < < | < | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | #include <netdb.h> #include <sys/types.h> #include <openssl/rand.h> #import "XMPPSRVLookup.h" #import <ObjFW/OFLocalization.h> OF_ASSUME_NONNULL_BEGIN @interface XMPPSRVLookup () - (void)XMPP_lookup; - (void)XMPP_addEntry: (XMPPSRVEntry *)item; @end OF_ASSUME_NONNULL_END @implementation XMPPSRVEntry @synthesize priority = _priority, weight = _weight; @synthesize accumulatedWeight = _accumulatedWeight, port = _port; @synthesize target = _target; + (instancetype)entryWithPriority: (uint16_t)priority weight: (uint16_t)weight port: (uint16_t)port target: (OFString *)target { return [[[self alloc] initWithPriority: priority weight: weight port: port target: target] autorelease]; } + (instancetype)entryWithResourceRecord: (ns_rr)resourceRecord handle: (ns_msg)handle { return [[[self alloc] initWithResourceRecord: resourceRecord handle: handle] autorelease]; } - init { OF_INVALID_INIT_METHOD } - initWithPriority: (uint16_t)priority weight: (uint16_t)weight port: (uint16_t)port target: (OFString *)target { self = [super init]; @try { _priority = priority; _weight = weight; _port = port; |
︙ | ︙ | |||
100 101 102 103 104 105 106 | { self = [super init]; @try { const uint16_t *rdata; char buffer[NS_MAXDNAME]; | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | { self = [super init]; @try { const uint16_t *rdata; char buffer[NS_MAXDNAME]; rdata = (const uint16_t *)(void *)ns_rr_rdata(resourceRecord); _priority = ntohs(rdata[0]); _weight = ntohs(rdata[1]); _port = ntohs(rdata[2]); if (dn_expand(ns_msg_base(handle), ns_msg_end(handle), (uint8_t *)&rdata[3], buffer, NS_MAXDNAME) < 1) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; _target = [[OFString alloc] initWithCString: buffer encoding: [OFLocalization encoding]]; } @catch (id e) { |
︙ | ︙ | |||
128 129 130 131 132 133 134 | - (void)dealloc { [_target release]; [super dealloc]; } | | | > > > > > | | 130 131 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 161 162 163 164 165 | - (void)dealloc { [_target release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"<%@ priority: %" PRIu16 @", weight: %" PRIu16 @", target: %@:%" PRIu16 @">", [self class], _priority, _weight, _target, _port]; } @end @implementation XMPPSRVLookup @synthesize domain = _domain; + (instancetype)lookupWithDomain: (OFString *)domain { return [[[self alloc] initWithDomain: domain] autorelease]; } - init { OF_INVALID_INIT_METHOD } - initWithDomain: (OFString *)domain { self = [super init]; @try { _list = [[OFList alloc] init]; _domain = [domain copy]; |
︙ | ︙ | |||
227 228 229 230 231 232 233 | res_ndestroy(&_resState); #endif } [pool release]; } | | | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | res_ndestroy(&_resState); #endif } [pool release]; } - (void)XMPP_addEntry: (XMPPSRVEntry *)entry { OFAutoreleasePool *pool; OFList *subList; of_list_object_t *iter; /* Look if there already is a list with the priority */ for (iter = [_list firstListObject]; iter != NULL; iter = iter->next) { |
︙ | ︙ | |||
269 270 271 272 273 274 275 | beforeListObject: iter]; else [_list appendObject: subList]; [pool release]; } | | > > > > > | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | beforeListObject: iter]; else [_list appendObject: subList]; [pool release]; } - (OFEnumerator *)objectEnumerator { return [[[XMPPSRVEnumerator alloc] initWithList: _list] autorelease]; } @end @implementation XMPPSRVEnumerator - init { OF_INVALID_INIT_METHOD } - initWithList: (OFList *)list { self = [super init]; @try { _list = [list copy]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
317 318 319 320 321 322 323 | totalWeight += [iter->object weight]; [iter->object setAccumulatedWeight: totalWeight]; } if ([_subListCopy count] > 0) { uint32_t randomWeight; | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | totalWeight += [iter->object weight]; [iter->object setAccumulatedWeight: totalWeight]; } if ([_subListCopy count] > 0) { uint32_t randomWeight; RAND_pseudo_bytes((uint8_t *)&randomWeight, sizeof(uint32_t)); randomWeight %= (totalWeight + 1); for (iter = [_subListCopy firstListObject]; iter != NULL; iter = iter->next) { if ([iter->object accumulatedWeight] >= randomWeight) { ret = [[iter->object retain] autorelease]; |
︙ | ︙ |
Modified src/XMPPStanza.h from [7ce6b98454] to [a0d35df9af].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> @class XMPPJID; /** * \brief A class describing an XMPP Stanza. */ @interface XMPPStanza: OFXMLElement { XMPPJID *_from, *_to; OFString *_type, *_ID, *_language; } /// \brief The value of the stanza's from attribute | > > | | | | | | | | | | | | | | > > > > > > > > > > | | | | | | | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 161 162 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/ObjFW.h> OF_ASSUME_NONNULL_BEGIN @class XMPPJID; /** * \brief A class describing an XMPP Stanza. */ @interface XMPPStanza: OFXMLElement { XMPPJID *_from, *_to; OFString *_type, *_ID, *_language; } /// \brief The value of the stanza's from attribute @property OF_NULLABLE_PROPERTY (nonatomic, copy) XMPPJID *from; /// \brief The value of the stanza's to attribute @property OF_NULLABLE_PROPERTY (nonatomic, copy) XMPPJID *to; /// \brief The value of the stanza's type attribute @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *type; /// \brief The value of the stanza's id attribute @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *ID; /// \brief The stanza's xml:lang @property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *language; /** * \brief Creates a new autoreleased XMPPStanza with the specified name. * * \param name The stanza's name (one of iq, message or presence) * \return A new autoreleased XMPPStanza */ + (instancetype)stanzaWithName: (OFString *)name; /** * \brief Creates a new autoreleased XMPPStanza with the specified name and * type. * * \param name The stanza's name (one of iq, message or presence) * \param type The value for the stanza's type attribute * \return A new autoreleased XMPPStanza */ + (instancetype)stanzaWithName: (OFString *)name type: (nullable OFString *)type; /** * \brief Creates a new autoreleased XMPPStanza with the specified name and ID. * * \param name The stanza's name (one of iq, message or presence) * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPStanza */ + (instancetype)stanzaWithName: (OFString *)name ID: (nullable OFString *)ID; /** * \brief Creates a new autoreleased XMPPStanza with the specified name, type * and ID. * * \param name The stanza's name (one of iq, message or presence) * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A new autoreleased XMPPStanza */ + (instancetype)stanzaWithName: (OFString *)name type: (nullable OFString *)type ID: (nullable OFString *)ID; /** * \brief Creates a new autoreleased XMPPStanza from an OFXMLElement. * * \param element The element to base the XMPPStanza on * \return A new autoreleased XMPPStanza */ + (instancetype)stanzaWithElement: (OFXMLElement *)element; - initWithName: (OFString *)name stringValue: (nullable OFString *)stringValue OF_UNAVAILABLE; - initWithName: (OFString *)name namespace: (nullable OFString *)namespace OF_UNAVAILABLE; - initWithName: (OFString *)name namespace: (nullable OFString *)namespace stringValue: (nullable OFString *)stringValue OF_UNAVAILABLE; - initWithXMLString: (OFString *)string OF_UNAVAILABLE; - initWithFile: (OFString *)path OF_UNAVAILABLE; /** * \brief Initializes an already allocated XMPPStanza with the specified name. * * \param name The stanza's name (one of iq, message or presence) * \return A initialized XMPPStanza */ - initWithName: (OFString *)name; /** * \brief Initializes an already allocated XMPPStanza with the specified name * and type. * * \param name The stanza's name (one of iq, message or presence) * \param type The value for the stanza's type attribute * \return A initialized XMPPStanza */ - initWithName: (OFString *)name type: (nullable OFString *)type; /** * \brief Initializes an already allocated XMPPStanza with the specified name * and ID. * * \param name The stanza's name (one of iq, message or presence) * \param ID The value for the stanza's id attribute * \return A initialized XMPPStanza */ - initWithName: (OFString *)name ID: (nullable OFString *)ID; /** * \brief Initializes an already allocated XMPPStanza with the specified name, * type and ID. * * \param name The stanza's name (one of iq, message or presence) * \param type The value for the stanza's type attribute * \param ID The value for the stanza's id attribute * \return A initialized XMPPStanza */ - initWithName: (OFString *)name type: (nullable OFString *)type ID: (nullable OFString *)ID; /** * \brief Initializes an already allocated XMPPStanza based on a OFXMLElement. * * \param element The element to base the XMPPStanza on * \return A initialized XMPPStanza */ - initWithElement: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPStanza.m from [62c85c1076] to [26c7c49d18].
︙ | ︙ | |||
26 27 28 29 30 31 32 | #endif #import "XMPPStanza.h" #import "XMPPJID.h" #import "namespaces.h" @implementation XMPPStanza | > > > | | | | | | | | | | > > > > > > > > > > > > > > > > > | | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #endif #import "XMPPStanza.h" #import "XMPPJID.h" #import "namespaces.h" @implementation XMPPStanza @synthesize from = _from, to = _to, type = _type, ID = _ID; @synthesize language = _language; + (instancetype)stanzaWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } + (instancetype)stanzaWithName: (OFString *)name type: (OFString *)type { return [[[self alloc] initWithName: name type: type] autorelease]; } + (instancetype)stanzaWithName: (OFString *)name ID: (OFString *)ID { return [[[self alloc] initWithName: name ID: ID] autorelease]; } + (instancetype)stanzaWithName: (OFString *)name type: (OFString *)type ID: (OFString *)ID { return [[[self alloc] initWithName: name type: type ID: ID] autorelease]; } + (instancetype)stanzaWithElement: (OFXMLElement *)element { return [[[self alloc] initWithElement: element] autorelease]; } - initWithName: (OFString *)name namespace: (nullable OFString *)namespace stringValue: (nullable OFString *)stringValue { OF_INVALID_INIT_METHOD } - initWithXMLString: (OFString *)string { OF_INVALID_INIT_METHOD } - initWithFile: (OFString *)path { OF_INVALID_INIT_METHOD } - initWithName: (OFString *)name { return [self initWithName: name type: nil ID: nil]; } - initWithName: (OFString *)name type: (OFString *)type { return [self initWithName: name type: type ID: nil]; } - initWithName: (OFString *)name ID: (OFString *)ID { return [self initWithName: name type: nil ID: ID]; } - initWithName: (OFString *)name type: (OFString *)type ID: (OFString *)ID { self = [super initWithName: name namespace: XMPP_NS_CLIENT]; @try { if (![name isEqual: @"iq"] && ![name isEqual: @"message"] && ![name isEqual: @"presence"]) |
︙ | ︙ | |||
111 112 113 114 115 116 117 | [self release]; @throw e; } return self; } | | | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | [self release]; @throw e; } return self; } - initWithElement: (OFXMLElement *)element { self = [super initWithElement: element]; @try { OFXMLAttribute *attribute; if ((attribute = [element attributeForName: @"from"])) |
︙ | ︙ | |||
149 150 151 152 153 154 155 | [_to release]; [_type release]; [_ID release]; [super dealloc]; } | | < < < < < | < < < < < | < < < < < | < < < < < | < < < < < | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | [_to release]; [_type release]; [_ID release]; [super dealloc]; } - (void)setFrom: (XMPPJID *)from { XMPPJID *old = _from; _from = [from copy]; [old release]; [self removeAttributeForName: @"from"]; if (from != nil) [self addAttributeWithName: @"from" stringValue: [from fullJID]]; } - (void)setTo: (XMPPJID *)to { XMPPJID *old = _to; _to = [to copy]; [old release]; [self removeAttributeForName: @"to"]; if (to != nil) [self addAttributeWithName: @"to" stringValue: [to fullJID]]; } - (void)setType: (OFString *)type { OFString *old = _type; _type = [type copy]; [old release]; [self removeAttributeForName: @"type"]; if (type != nil) [self addAttributeWithName: @"type" stringValue: type]; } - (void)setID: (OFString *)ID { OFString *old = _ID; _ID = [ID copy]; [old release]; [self removeAttributeForName: @"id"]; if (ID != nil) [self addAttributeWithName: @"id" stringValue: ID]; } - (void)setLanguage: (OFString *)language { OFString *old = _language; _language = [language copy]; [old release]; [self removeAttributeForName: @"lang" namespace: @"http://www.w3.org/XML/1998/namespace"]; if (language != nil) [self addAttributeWithName: @"lang" namespace: @"http://www.w3.org/XML/1998/" @"namespace" stringValue: language]; } @end |
Modified src/XMPPStorage.h from [f2a91237cc] to [1c089b9216].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFObject.h> @class OFString; @class OFArray; @class OFDictionary; @protocol XMPPStorage <OFObject> - (void)save; | > > | | | | | | | | | | | | | > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFObject.h> OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFArray; @class OFDictionary; @protocol XMPPStorage <OFObject> - (void)save; - (void)setStringValue: (nullable OFString *)string forPath: (OFString *)path; - (nullable OFString *)stringValueForPath: (OFString *)path; - (void)setBooleanValue: (bool)boolean forPath: (OFString *)path; - (bool)booleanValueForPath: (OFString *)path; - (void)setIntegerValue: (intmax_t)integer forPath: (OFString *)path; - (intmax_t)integerValueForPath: (OFString *)path; - (void)setArray: (nullable OFArray *)array forPath: (OFString *)path; - (nullable OFArray *)arrayForPath: (OFString *)path; - (void)setDictionary: (nullable OFDictionary *)dictionary forPath: (OFString *)path; - (nullable OFDictionary *)dictionaryForPath: (OFString *)path; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPStreamManagement.h from [dbbf14c9a5] to [eba4bbe440].
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPConnection.h" @interface XMPPStreamManagement: OFObject <XMPPConnectionDelegate> { XMPPConnection *_connection; uint32_t _receivedCount; } | > > > | > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPConnection.h" OF_ASSUME_NONNULL_BEGIN @interface XMPPStreamManagement: OFObject <XMPPConnectionDelegate> { XMPPConnection *_connection; uint32_t _receivedCount; } - init OF_UNAVAILABLE; - initWithConnection: (XMPPConnection *)connection; @end OF_ASSUME_NONNULL_END |
Modified src/XMPPStreamManagement.m from [9dc52c523a] to [57b85a948f].
︙ | ︙ | |||
22 23 24 25 26 27 28 | #include <inttypes.h> #import "XMPPStreamManagement.h" #import "namespaces.h" @implementation XMPPStreamManagement | > > > > > | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <inttypes.h> #import "XMPPStreamManagement.h" #import "namespaces.h" @implementation XMPPStreamManagement - init { OF_INVALID_INIT_METHOD } - initWithConnection: (XMPPConnection *)connection { self = [super init]; @try { _connection = connection; [_connection addDelegate: self]; } @catch (id e) { |
︙ | ︙ | |||
44 45 46 47 48 49 50 | - (void)dealloc { [_connection removeDelegate: self]; [super dealloc]; } | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | - (void)dealloc { [_connection removeDelegate: self]; [super dealloc]; } - (void)connection: (XMPPConnection *)connection didReceiveElement: (OFXMLElement *)element { OFString *elementName = [element name]; OFString *elementNS = [element namespace]; if ([elementNS isEqual: XMPP_NS_SM]) { if ([elementName isEqual: @"enabled"]) { _receivedCount = 0; |
︙ | ︙ | |||
81 82 83 84 85 86 87 | ([elementName isEqual: @"iq"] || [elementName isEqual: @"presence"] || [elementName isEqual: @"message"])) _receivedCount++; } /* TODO: Count outgoing stanzas here and cache them, send own ACK requests | | | | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | ([elementName isEqual: @"iq"] || [elementName isEqual: @"presence"] || [elementName isEqual: @"message"])) _receivedCount++; } /* TODO: Count outgoing stanzas here and cache them, send own ACK requests - (void)connection: (XMPPConnection *)connection didSendElement: (OFXMLElement *)element { } */ - (void)connection: (XMPPConnection *)connection wasBoundToJID: (XMPPJID *)JID { if ([connection supportsStreamManagement]) [connection sendStanza: [OFXMLElement elementWithName: @"enable" namespace: XMPP_NS_SM]]; } @end |
Modified src/XMPPXMLElementBuilder.h from [e6038a457f] to [60ea5de24d].
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFXMLElementBuilder.h> @interface XMPPXMLElementBuilder: OFXMLElementBuilder @end | > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <ObjFW/OFXMLElementBuilder.h> OF_ASSUME_NONNULL_BEGIN @interface XMPPXMLElementBuilder: OFXMLElementBuilder @end OF_ASSUME_NONNULL_END |
Modified src/XMPPXMLElementBuilder.m from [c3e2053f34] to [757efe5b8a].
︙ | ︙ | |||
25 26 27 28 29 30 31 | #endif #import "XMPPXMLElementBuilder.h" #import <ObjFW/OFMalformedXMLException.h> @implementation XMPPXMLElementBuilder | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #endif #import "XMPPXMLElementBuilder.h" #import <ObjFW/OFMalformedXMLException.h> @implementation XMPPXMLElementBuilder - (void)parser: (OFXMLParser *)parser foundProcessingInstructions: (OFString *)pi { @throw [OFMalformedXMLException exception]; } - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment { @throw [OFMalformedXMLException exception]; } @end |
Modified tests/test.m from [1e6a6151cf] to [a93ba6280b].
︙ | ︙ | |||
34 35 36 37 38 39 40 | #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" #import "XMPPStreamManagement.h" #import "XMPPFileStorage.h" @interface AppDelegate: OFObject | < < | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" #import "XMPPStreamManagement.h" #import "XMPPFileStorage.h" @interface AppDelegate: OFObject <OFApplicationDelegate, XMPPConnectionDelegate, XMPPRosterDelegate> { XMPPConnection *conn; XMPPRoster *roster; } @end OF_APPLICATION_DELEGATE(AppDelegate) |
︙ | ︙ | |||
127 128 129 130 131 132 133 | [conn setUsername: [arguments objectAtIndex: 1]]; [conn setPassword: [arguments objectAtIndex: 2]]; [conn setResource: @"ObjXMPP"]; [conn asyncConnectAndHandle]; } | | | | | | | | | 125 126 127 128 129 130 131 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 | [conn setUsername: [arguments objectAtIndex: 1]]; [conn setPassword: [arguments objectAtIndex: 2]]; [conn setResource: @"ObjXMPP"]; [conn asyncConnectAndHandle]; } - (void)connection: (XMPPConnection *)conn didReceiveElement: (OFXMLElement *)element { of_log(@"In: %@", element); } - (void)connection: (XMPPConnection *)conn didSendElement: (OFXMLElement *)element { of_log(@"Out: %@", element); } - (void)connectionWasAuthenticated: (XMPPConnection *)conn { of_log(@"Auth successful"); } - (void)connection: (XMPPConnection *)conn_ wasBoundToJID: (XMPPJID *)jid { of_log(@"Bound to JID: %@", [jid fullJID]); of_log(@"Supports SM: %@", [conn_ supportsStreamManagement] ? @"true" : @"false"); XMPPDiscoEntity *discoEntity = [[XMPPDiscoEntity alloc] initWithConnection: conn]; |
︙ | ︙ | |||
196 197 198 199 200 201 202 | [discoEntity addDiscoNode: nodeClueso]; [discoEntity addDiscoNode: nodeStop]; [discoEntity addDiscoNode: nodeChicago]; [roster requestRoster]; } | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | [discoEntity addDiscoNode: nodeClueso]; [discoEntity addDiscoNode: nodeStop]; [discoEntity addDiscoNode: nodeChicago]; [roster requestRoster]; } - (void)rosterWasReceived: (XMPPRoster *)roster_ { XMPPPresence *pres; of_log(@"Got roster: %@", [roster_ rosterItems]); pres = [XMPPPresence presence]; [pres setPriority: [OFNumber numberWithInt8: 10]]; |
︙ | ︙ | |||
220 221 222 223 224 225 226 | [conn sendIQ: iq callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) { of_log(@"Ping response: %@", resp); }]; #endif } | | | | | | | | | | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | [conn sendIQ: iq callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) { of_log(@"Ping response: %@", resp); }]; #endif } - (void)connectionDidUpgradeToTLS: (XMPPConnection *)conn_ { OFString *reason; if (![conn_ checkCertificateAndGetReason: &reason]) { [of_stdout writeString: @"Couldn't verify certificate: "]; [of_stdout writeFormat: @"%@\n", reason]; [of_stdout writeString: @"Do you want to continue [y/N]? "]; if (![[of_stdin readLine] hasPrefix: @"y"]) [OFApplication terminateWithStatus: 1]; } } - (void)roster: (XMPPRoster *)roster_ didReceiveRosterItem: (XMPPRosterItem *)rosterItem { of_log(@"Got roster push: %@", rosterItem); } - (bool)connection: (XMPPConnection *)conn didReceiveIQ: (XMPPIQ *)iq { of_log(@"IQ: %@", iq); return NO; } - (void)connection: (XMPPConnection *)conn didReceiveMessage: (XMPPMessage *)msg { of_log(@"Message: %@", msg); } - (void)connection: (XMPPConnection *)conn didReceivePresence: (XMPPPresence *)pres { of_log(@"Presence: %@", pres); } - (void)connection: (XMPPConnection *)conn didThrowException: (id)e { @throw e; } - (void)connectionWasClosed: (XMPPConnection *)conn { of_log(@"Connection was closed!"); } @end |