bool Client::handleNormalNode( Tag* tag ) { if( tag->name() == "features" && tag->xmlns() == XMLNS_STREAM ) { m_streamFeatures = getStreamFeatures( tag ); if( m_tls == TLSRequired && !m_encryptionActive && ( !m_encryption || !( m_streamFeatures & StreamFeatureStartTls ) ) ) { logInstance().err( LogAreaClassClient, "Client is configured to require" " TLS but either the server didn't offer TLS or" " TLS support is not compiled in." ); disconnect( ConnTlsNotAvailable ); } else if( m_tls > TLSDisabled && m_encryption && !m_encryptionActive && ( m_streamFeatures & StreamFeatureStartTls ) ) { notifyStreamEvent( StreamEventEncryption ); startTls(); } else if( m_compress && m_compression && !m_compressionActive && ( m_streamFeatures & StreamFeatureCompressZlib ) ) { notifyStreamEvent( StreamEventCompression ); logInstance().warn( LogAreaClassClient, "The server offers compression, but negotiating Compression at this stage is not recommended. See XEP-0170 for details. We'll continue anyway." ); negotiateCompression( StreamFeatureCompressZlib ); } else if( m_sasl ) { if( m_authed ) { if( m_streamFeatures & StreamFeatureBind ) { notifyStreamEvent( StreamEventResourceBinding ); bindResource( resource() ); } } else if( m_doAuth && !username().empty() && !password().empty() ) { if( m_streamFeatures & SaslMechDigestMd5 && m_availableSaslMechs & SaslMechDigestMd5 && !m_forceNonSasl ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechDigestMd5 ); } else if( m_streamFeatures & SaslMechPlain && m_availableSaslMechs & SaslMechPlain && !m_forceNonSasl ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechPlain ); } else if( m_streamFeatures & StreamFeatureIqAuth || m_forceNonSasl ) { notifyStreamEvent( StreamEventAuthentication ); nonSaslLogin(); } else { logInstance().err( LogAreaClassClient, "the server doesn't support" " any auth mechanisms we know about" ); disconnect( ConnNoSupportedAuth ); } } else if( m_doAuth && !m_clientCerts.empty() && !m_clientKey.empty() && m_streamFeatures & SaslMechExternal && m_availableSaslMechs & SaslMechExternal ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechExternal ); } #ifdef _WIN32 else if( m_doAuth && m_streamFeatures & SaslMechGssapi && m_availableSaslMechs & SaslMechGssapi ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechGssapi ); } #endif else if( m_doAuth && m_streamFeatures & SaslMechAnonymous && m_availableSaslMechs & SaslMechAnonymous ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechAnonymous ); } else { notifyStreamEvent( StreamEventFinished ); connected(); } } else if( m_compress && m_compression && !m_compressionActive && ( m_streamFeatures & StreamFeatureCompressZlib ) ) { notifyStreamEvent( StreamEventCompression ); negotiateCompression( StreamFeatureCompressZlib ); } // else if( ( m_streamFeatures & StreamFeatureCompressDclz ) // && m_connection->initCompression( StreamFeatureCompressDclz ) ) // { // negotiateCompression( StreamFeatureCompressDclz ); // } else if( m_streamFeatures & StreamFeatureIqAuth ) { notifyStreamEvent( StreamEventAuthentication ); nonSaslLogin(); } else { logInstance().err( LogAreaClassClient, "fallback: the server doesn't " "support any auth mechanisms we know about" ); disconnect( ConnNoSupportedAuth ); } } else { const std::string& name = tag->name(), xmlns = tag->findAttribute( XMLNS ); if( name == "proceed" && xmlns == XMLNS_STREAM_TLS ) { logInstance().dbg( LogAreaClassClient, "starting TLS handshake..." ); if( m_encryption ) { m_encryptionActive = true; m_encryption->handshake(); } } else if( name == "failure" ) { if( xmlns == XMLNS_STREAM_TLS ) { logInstance().err( LogAreaClassClient, "TLS handshake failed (server-side)!" ); disconnect( ConnTlsFailed ); } else if( xmlns == XMLNS_COMPRESSION ) { logInstance().err( LogAreaClassClient, "stream compression init failed!" ); disconnect( ConnCompressionFailed ); } else if( xmlns == XMLNS_STREAM_SASL ) { logInstance().err( LogAreaClassClient, "SASL authentication failed!" ); processSASLError( tag ); disconnect( ConnAuthenticationFailed ); } } else if( name == "compressed" && xmlns == XMLNS_COMPRESSION ) { logInstance().dbg( LogAreaClassClient, "stream compression inited" ); m_compressionActive = true; header(); } else if( name == "challenge" && xmlns == XMLNS_STREAM_SASL ) { logInstance().dbg( LogAreaClassClient, "processing SASL challenge" ); processSASLChallenge( tag->cdata() ); } else if( name == "success" && xmlns == XMLNS_STREAM_SASL ) { logInstance().dbg( LogAreaClassClient, "SASL authentication successful" ); setAuthed( true ); header(); } else return false; } return true; }
bool Client::handleNormalNode( Stanza *stanza ) { if( stanza->name() == "stream:features" ) { m_streamFeatures = getStreamFeatures( stanza ); if( m_tls == TLSRequired && !m_encryptionActive && ( !m_encryption || !( m_streamFeatures & StreamFeatureStartTls ) ) ) { logInstance().log( LogLevelError, LogAreaClassClient, "Client is configured to require TLS but either the server didn't offer TLS or " "TLS support is not compiled in." ); disconnect( ConnTlsNotAvailable ); } else if( m_tls > TLSDisabled && m_encryption && !m_encryptionActive && ( m_streamFeatures & StreamFeatureStartTls ) ) { notifyStreamEvent( StreamEventEncryption ); startTls(); } else if( m_sasl ) { if( m_authed ) { if( m_streamFeatures & StreamFeatureBind ) { notifyStreamEvent( StreamEventResourceBinding ); bindResource(); } } else if( m_doAuth && !username().empty() && !password().empty() ) { if( !login() ) { logInstance().log( LogLevelError, LogAreaClassClient, "the server doesn't support any auth mechanisms we know about" ); disconnect( ConnNoSupportedAuth ); } } else if( m_doAuth && !m_clientCerts.empty() && !m_clientKey.empty() && m_streamFeatures & SaslMechExternal && m_availableSaslMechs & SaslMechExternal ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechExternal ); } #ifdef _WIN32 else if( m_doAuth && m_streamFeatures & SaslMechGssapi && m_availableSaslMechs & SaslMechGssapi ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechGssapi ); } #endif else if( m_doAuth && m_streamFeatures & SaslMechAnonymous && m_availableSaslMechs & SaslMechAnonymous ) { notifyStreamEvent( StreamEventAuthentication ); startSASL( SaslMechAnonymous ); } else { notifyStreamEvent( StreamEventFinished ); connected(); } } else if( m_compress && m_compression && !m_compressionActive && ( m_streamFeatures & StreamFeatureCompressZlib ) ) { notifyStreamEvent( StreamEventCompression ); negotiateCompression( StreamFeatureCompressZlib ); } // else if( ( m_streamFeatures & StreamFeatureCompressDclz ) // && m_connection->initCompression( StreamFeatureCompressDclz ) ) // { // negotiateCompression( StreamFeatureCompressDclz ); // } else if( m_streamFeatures & StreamFeatureIqAuth ) { notifyStreamEvent( StreamEventAuthentication ); nonSaslLogin(); } else { logInstance().log( LogLevelError, LogAreaClassClient, "fallback: the server doesn't support any auth mechanisms we know about" ); disconnect( ConnNoSupportedAuth ); } } else if( ( stanza->name() == "proceed" ) && stanza->hasAttribute( "xmlns", XMLNS_STREAM_TLS ) ) { logInstance().log( LogLevelDebug, LogAreaClassClient, "starting TLS handshake..." ); if( m_encryption ) { m_encryptionActive = true; m_encryption->handshake(); } } else if( ( stanza->name() == "failure" ) && stanza->hasAttribute( "xmlns", XMLNS_STREAM_TLS ) ) { logInstance().log( LogLevelError, LogAreaClassClient, "TLS handshake failed (server-side)!" ); disconnect( ConnTlsFailed ); } else if( ( stanza->name() == "failure" ) && stanza->hasAttribute( "xmlns", XMLNS_COMPRESSION ) ) { logInstance().log( LogLevelError, LogAreaClassClient, "stream compression init failed!" ); disconnect( ConnCompressionFailed ); } else if( ( stanza->name() == "compressed" ) && stanza->hasAttribute( "xmlns", XMLNS_COMPRESSION ) ) { logInstance().log( LogLevelDebug, LogAreaClassClient, "stream compression inited" ); m_compressionActive = true; header(); } else if( ( stanza->name() == "challenge" ) && stanza->hasAttribute( "xmlns", XMLNS_STREAM_SASL ) ) { logInstance().log( LogLevelDebug, LogAreaClassClient, "processing SASL challenge" ); processSASLChallenge( stanza->cdata() ); } else if( ( stanza->name() == "failure" ) && stanza->hasAttribute( "xmlns", XMLNS_STREAM_SASL ) ) { logInstance().log( LogLevelError, LogAreaClassClient, "SASL authentication failed!" ); processSASLError( stanza ); disconnect( ConnAuthenticationFailed ); } else if( ( stanza->name() == "success" ) && stanza->hasAttribute( "xmlns", XMLNS_STREAM_SASL ) ) { logInstance().log( LogLevelDebug, LogAreaClassClient, "SASL authentication successful" ); setAuthed( true ); header(); } else { if( ( stanza->name() == "iq" ) && stanza->hasAttribute( "id", "bind" ) ) { processResourceBind( stanza ); } else if( ( stanza->name() == "iq" ) && stanza->hasAttribute( "id", "session" ) ) { processCreateSession( stanza ); } else return false; } return true; }