This caused the WaitForClosingStreamElementTest integration test to
fail, because the last presences stanzas, which are send after done()
in the writer thread would return true, are not added to the
unacknowledgedStanzas queue.
The result was:
SEVERE: WaitForClosingStreamElementTest.waitForClosingStreamElementTest (LowLevel): Failed
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.invokeLowLevel(SmackIntegrationTestFramework.java:466)
at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runTests(SmackIntegrationTestFramework.java:375)
at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.run(SmackIntegrationTestFramework.java:165)
at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.main(SmackIntegrationTestFramework.java:84)
Caused by: java.lang.AssertionError: Sync poing yielded failure exception
at org.jivesoftware.smack.WaitForClosingStreamElementTest.waitForClosingStreamElementTest(WaitForClosingStreamElementTest.java:46)
... 8 more
Caused by: org.jivesoftware.smack.sm.StreamManagementException$StreamManagementCounterError: There was an error regarding the Stream Mangement counters. Server reported 3 handled stanzas, which means that the 3 recently send stanzas by client are now acked by the server. But Smack had only 1 to acknowledge. The stanza id of the last acked outstanding stanza is FqL1X-144
at org.jivesoftware.smack.tcp.XMPPTCPConnection.processHandledCount(XMPPTCPConnection.java:1847)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2600(XMPPTCPConnection.java:149)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1176)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:980)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:996)
at java.lang.Thread.run(Thread.java:745)
Before this, if there was a stream error response by the server to our
stream open, that error response would only be handled in the reader
thread, and the user would get a message like:
"org.jivesoftware.smack.SmackException$NoResponseException: No
response received within reply timeout. Timeout was
5000ms (~5s). While waiting for SASL mechanisms stream feature from
server"
while the server may actually sent something like
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='6785787028201586334'
from='jabbim.com'
version='1.0'
xml:lang='en'>
<stream:error>
<policy-violation xmlns='urn:ietf:params:xml:ns:xmpp-streams'>
</policy-violation>
<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>
Too many (2) failed authentications from this IP
address (1xx.66.xx.xxx). The address will be unblocked at 04:24:00
06.01.2017 UTC
</text>
</stream:error>
</stream:stream>
It was necessary to change saslFeatureReceived from SmackException to
XMPPException in order to return the StreamErrorException at this sync
point. But this change in return required the introduction of a
tlsHandled sync point for SmackException (which just acts as a wrapper
for the various exception types that could occurn when establishing
TLS). The tlsHandled sync point is marked successful even if no TLS
was established in case none was required and/or if not supported by
the server.
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.charAt(String.java:658)
at org.jivesoftware.smack.util.dns.HostAddress.<init>(HostAddress.java:48)
at org.jivesoftware.smack.util.dns.HostAddress.<init>(HostAddress.java:62)
It was a *very* bad idea to perform the SecurityMode.Required check in
the connection's reader thread and not at the end of
AbstractXMPPConnectin's connect(). :/
This behavior dates back to 8e750912a7
Fixes SMACK-739
as otherwhise the following could happen:
WARNING: Connection XMPPTCPConnection[not-authenticated] (0) closed with error
java.security.KeyStoreException: Uninitialized keystore
at java.security.KeyStore.aliases(KeyStore.java:1233)
at sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:127)
at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:739)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1000(XMPPTCPConnection.java:146)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1026)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:960)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:975)
at java.lang.Thread.run(Thread.java:745)
org.jivesoftware.smack.SmackException: java.security.KeyStoreException: Uninitialized keystore
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1033)
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:960)
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:975)
java.lang.Thread.run(Thread.java:745)
java.security.KeyStoreException: Uninitialized keystore
java.security.KeyStore.aliases(KeyStore.java:1233)
sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:127)
sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256)
org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:739)
org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1000(XMPPTCPConnection.java:146)
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1026)
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:960)
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:975)
java.lang.Thread.run(Thread.java:745)
in order to improve support for Tor connections.
This makes it possible to establish a connection to an .onion domain by
manually setting host and port in the ConnectionConfiguration and
configuring a Socks5Proxy pointing to a Tor node.
Fixes SMACK-720.
The problem caused by opening input/ output stream before setting ssl
parameters to SSLSession and fixed by changing order of this operations.
Fixes SMACK-712.
Minor-Modifications-By: Florian Schmaus <flo@geekplace.eu>
The method was changed in c6594aec2f, but
this change causes issues if Smack is used on Android *without* a custom
SSLContext:
Caused by: java.security.KeyStoreException: java.security.NoSuchAlgorithmException: KeyStore jks implementation not found
at java.security.KeyStore.getInstance(KeyStore.java:119)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:697)
Caused by: java.security.NoSuchAlgorithmException: KeyManagerFactory SunX509 implementation not found
at org.apache.harmony.security.fortress.Engine.notFound(Engine.java:177)
at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:151)
at javax.net.ssl.KeyManagerFactory.getInstance(KeyManagerFactory.java:77)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:708)
by changing
stanzasToResend.addAll(unacknowledgedStanzas);
to
unacknowledgedStanzas.drainTo(stanzasToResend);
Also use sendStanzaInternal to call the callbacks, which also requires
the smEnabledSyncPoint to got signaled.
Fixes SMACK-700. Thanks to Juan Antonio for reporting this.
This adds the ability to provide a distinct authorization identifier for use
by SASL mechanisms. Not all SASL mechanisms support this operation, in
particular CRAM-MD5.
Both the javax and provided SASL implementations are extended, and an authzid
parameter added to the authenticate method.
The authorization identifier is passed as a EntityBareJid in order to assure the
correct form.
Resolves SMACK-677.
Minor-Modifications-By: Florian Schmaus <flo@geekplace.eu>
Instead of extending SocketFactory, the proxy support classes now
implement ProxySocketConnection. This removes a lot of unnecessary
code.
Also re-enables proxy support, which was broken in previous versions
because none of extended SocketFactories did override
createSocket() (SMACK-683).
in afterFeaturesReceived. As this will cause
maybeCompressFeaturesReceived.reportSuccess() never to be called if the
server announces 'starttls' but security mode is set to 'disabled' and
if 'compression' is also announced.
Fixes SMACK-678.
A sequence of connect(), disconnect(), and connect() could cause the
connection to get disconnected again by the old reader thread, which was
blocking on disconnect because a closing stream tag was read. If the
second connect() was processed before the disconnect(), then the
connectin would get disconnected right after the second connect().
This showed up as a "strange" sequence of stanzas in the XMPP servers
log. Note that the stanza ID of the unavailable presence has a lower
number then the previous stanzas:
Jun 11 23:11:11 c2s18c2370 debug Resource bound: smack-inttest-two-93t70@geekplace.eu/two-93t70
Jun 11 23:11:11 c2s18c2370 debug Received[c2s]: <iq id='qn03S-26' type='get'>
Jun 11 23:11:11 c2s18c2370 debug Received[c2s]: <presence id='qn03S-27'>
Jun 11 23:11:11 c2s18c2370 debug Received[c2s]: <presence id='qn03S-23' type='unavailable'>
Jun 11 23:11:11 c2s18c2370 debug Received </stream:stream>
This is because the disconnect() of the first reader thread could
generate the unavailable presence, but was blocked afterwards when
entering the synchronized disconnect(Presence unavailablePresence).
SMACK-633.
Instead of allocating one big continuous memory block before "writing"
the XMPP stream element to the socket, write the single CharSequences of
LazyStringBuilder/XmlStringBuilder.
Also change Obserable writer to only notify the listeners after a
flush *or* if a certain limit has been reached since the last
notification. Otherwise the debugger would "print" every single XML part
as result of this change.
Add
- performSaslAnonymousAuthentication()
- performSaslExternalAuthentication(SSLContext)
- addEnabledSaslMechanism(String)
- addEnabledSaslMechanisms(Collection<String>)
to ConnectionConfiguration.Builder.
Instead of providing a special API call for anonymous authentication,
Smack now has a configuration builder method to set anonymous/external
authentication. This also removes a lot of duplicate code within
Smack.
Also move SASLAnonymous into o.j.smack.sasl.core.
Fixes SMACK-629.
The cases where reversed. Change the condition for better readability.
Also fix int and long handling in the computation of
maxResumptionMillies.
Fixes SMACK-654.
- Lines containing tab(s) after space
- Usage of printStackTrace
- Usage of println
- Add SupressionCommentFilter module
SuppressionCommentFilter can be enabled with
// CHECKSTYLE:OFF
and disabled with
// CHECKSTYLE:ON
Previously Smack would put messages in the unacknowledgedStanzas queue
after it received the 'enabled' element, when it should do so right
after sending the 'enable' stream element.
Imagine a session where '-->' denotes "received from server" and '<--'
"sent to server"
<-- enable
--> iq roster push set
--> presence some presence
<-- iq roster push result
--> enabled
then Smack would not add the iq roster push result stanza to the
unacknowledgedStanzas queue.
This fixes the issue by initializing the unacknowledgedStanzas queue
when the writer thread encounters a 'Enable' stream element.
The additional 'instanceof' invocation in the writer thread should not
be a big performance issue, since the existing "instanceof Stanza" check
should be the common case and the "instanceof Enable" is an exclusive
alternative to this case.
Instead of always bundling when the queue is empty, only bundle once the
queue has become empty and then only if it has been become empty again.
The previous algorithm would also bundle and defer the last element
found in the queue. This is not the case now.
in XMPPTCPConnection.
So that the hostname and not the IP is available to the SSLSocket and
the SSLSession, which handed over to HostnameVerifier. This leaves the
HostnameVerifier with the
- name of the XMPP service (first argument of verify(String, SSLSession)
- name of the used host (found in the SSLSession)
allowing more complex verification mechanisms performed by the
HostnameVerifier.
to allow graceful connectionClosedOnError() disconnects, since we
received a bunch of reports where the counter seems wrong, which is
causing a NPE in a thread pool executor, causing the VM or Android App
to terminate.
Now we throw the StreamManagementCounterError instead.