in case hostAddresses was null, the isEmpty() check before the log()
invocation would throw an NPE. Thanks to Ingo Bauersachs for reporting
this.
Fixes SMACK-788.
A stanza with <error><text>Some text</text></error>, i.e. without a
xml:lang attribute, did not return the value 'Some text' in
getDescriptiveText().
Insert the empty string as key when the attribute is not present while
parsing the xml. When writing, omit the attribute if the key is the
empty string.
Previously StanzaListeners and Collectors where able to receive IQ of
type 'get' or 'set' (i.e., IQ requests) when no IQRequestHandler was
registered. By moving the 'return' statement one level down, even
listeners/collectors won't receive them.
I'm not sure why i've put the removeAsyncStanzaListener() call into
the finally block. If callback.processStanza(Stanza) takes a long
time (or even blocks), then it would appear to the "no response"
handling Runnable as if there was no response, when in fact there was
one.
instead of an EntityFullJid, because according to XEP-0045 § 7.8.1.:
"The <room@service> itself MUST then add a 'from' address to the
<invite/> element whose value is the bare JID, full JID, or occupant
JID of the inviter …"
Fixes the following exception thrown if the user had entered a non-existend XMPP domain:
java.lang.IllegalArgumentException: Must provide at least one InetAddress
at org.jivesoftware.smack.util.dns.HostAddress.<init>(HostAddress.java:55)
at org.jivesoftware.smack.util.dns.DNSResolver.lookupHostAddress(DNSResolver.java: 56)
at org.jivesoftware.smack.util.DNSUtil.resolveDomain(DNSUtil.java:209)
at org.jivesoftware.smack.util.DNSUtil.resolveXMPPServiceDomain(DNSUtil.java:136)
at org.jivesoftware.smack.AbstractXMPPConnection.populateHostAddresses(AbstractXMP PConnection.java:626)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPC onnection.java:556)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection. java:888)
at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.ja va:377)
Thanks to Grigory Fedorov for reporting.
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)
In previous Smack versions, it was possible to set the host's IP
address via setHost(String), this is no longer possible (since the
support for DNSSEC was introduced). The new
setHostAddress(InetAddress) allows it again to explicitly specifiy the
XMPP service's host IP.
capturing all outoing presences of type 'available' would also capture
presences not used for presence broadcast, e.g., MUC presences.
This caused the EntityCaps integration test (localEntityCaps) to fail
if the MUC integration test was run before.
The pattern
if (now > deadline) break;
wait(deadline - now);
is insufficient in case "now == deadline" because the result would be
wait() being called with 0, which would mean "wait until
notified". Thus, the timeout would become infinite.
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
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
Because of the condition "c >= 32", Smack would possible return a
c-nonce containing ASCII whitespace characters (32d, 0x20), which are
not allowed in the c-nonce as per RFC 5802.
This commit applies the correct condition: "c > 32".
Fixes SMACK-735.
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.
Don't log the exception for now because the stack trace makes to much
noise in the log output. This is mostly caused by Googles outdated
Entity Capabilities implementation.
instead of feature-not-implemented.
Changes to send service-unavailable for not handled iq as said in
RFC6120 § 8.4: https://tools.ietf.org/html/rfc6120#page-128
"""
o If an intended recipient receives an IQ stanza of type "get" or
"set" containing a child element qualified by a namespace it does
not understand, then the entity MUST return an IQ stanza of type
"error" with an error condition of <service-unavailable/>.
"""
replaces DefaultExtensionElement which is now deprecated.
Also changes Stanza (and MultiMap) API so that there can be duplicate extension
elements, as this change is required for StandardExtensionElement and by
the XMPP standard.
remove (set|get)ItemStatus. This was always the ask status, which can
only be set to 'subscribe' or is non-existent.
Use the standard (de-)serialization facilities for DirectoryRosterStore.
Fixes Smack-657.
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>
And replace all instances where String.Builder.append() is called with a
String of length one with append(char).
Also adds StringUtils.toStringBuilder(Collection, String).
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).
if the connection is not connected in sendStanzaWithResponseCallback and
in PacketCollector.
Also decrease log level if roster result listener's exeption callback is
invoked with a NotConnectedException.
Also don't override eventually send presences on
updateLocalEntityCaps(), instead save the last sent Presence stanza and
re-send that stanza.
SMACK-669.
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.
as otherwhise SynchronizationPoint may report NoResponseException when
there was in fact a success or failure reported in case there are
multiple threads waiting for the condition.
to prevent a thread from not being notified about a change of the state
of the SynchronizationPoint.
If two threads are waiting for a change, which could happen e.g. because
of a connectivity change and one thread does instantShutdown() while the
other handles connectionClosedOnError(), then only one thread, usually
the one handling connectionClosedOnError(), would be notified and
resumed.
Fixes SMACK-652.
We now treat warnings as errors (-Werror).
In order to do so, it was necessary to remove Java7HostnameVerifier
since it depended on internal properietary API. XmppHostnameVerifier
take the place of it.
Until now the reconnection used a fixed policy using random
increasing delay as the number of attempts grows. Even if
that policy is still the default one, it is now possible to
select a fixed delay policy that always waits a fixed amount
of time before trying to reconnect
- 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
instead of throwing XmlPullParserException, IOException and
SmackException.
Add a guard to AbstractXMPPConnection.processPacket() to always re-throw
RuntimeExceptions.
- Made jid of type BareJid
- Made it implement TypedCloneable
- Made it implement Serializable
- Made it immutable
Also update its parsing code. And add some convenience methods to
ParserUtils.
With bb8dcc9874 the concept if IQ request
handlers was introduced in Smack. This doesn't allow packet/stanza
collectors/listeners to filter for incoming IQ requests. Unfortunately
the file transfer code relied on this being able, so it broke with the
change.
There were two places where the file transfer code was listening for
incoming IQ requests:
- InitationListener(s)
- Negotiator(s)
With this change, we let the InitiationListener signal the existence of
an incoming initation request, send by an IQ of type 'set', using the
newly created EventManager utility.
The negotiator waits for those events to arrive and proceedes as it would
have done when the packet collector was used.
the combination with concurrencyLevel and LinkedBlockingQueue never
worked as intented. The idea was that the cachedExecutorService would
spawn new threads until maximumPoolSize (=concurrencyLevel) is reached,
and then start queing the Runnables.
But this was not the case, since ThreadPoolExecutor does not take into
consideration if the worker threads is busy, i.e. executing a Runnable,
or idle, i.e. waiting for a Runnable.
This means that if a busy Worker would execute a Runnable, which would
block, because it's waiting for an event (e.g. an incoming IQ
request), then the handling of those incoming IQ request would be
queued by ThreadPoolExecutor, because no fewer threads then corePoolSize
are running and the task can be queued (since the LinkedBlockingQueue is
unbounded).
Using the term 'enabled' was a terriable choice from a security
perspective, as it gives the user the impression that the security is
"enabled". In fact this setting is only slightly better then
"disabled".
Make that fact clear in the javadoc too.
The XMPPConnection interface does not define methods to manipulate the
connection state (e.g. connect(), disconnect()). The example should use
the connection type as declared type.
Since e6045c6593 the cached executor
services maximum pool size is limited to concurrencyLevel (was
previously Integer.MAX_VALUE). In order to prevent
RejectExecutionException we need to use an queue which max size is
greater than 1 (i.e. nont an SynchronousQueue).
Connection closed with error java.util.concurrent.RejectedExecutionException: Task org.jivesoftware.smack.tcp.XMPPTCPConnection$2@41dce200 rejected from java.util.concurrent.ThreadPoolExecutor@41d59150[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 4]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2011)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:793)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1339)
at org.jivesoftware.smack.AbstractXMPPConnection.asyncGo(AbstractXMPPConnection.java:1583)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.processHandledCount(XMPPTCPConnection.java:1655)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2300(XMPPTCPConnection.java:137)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1083)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:896)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:911)
at java.lang.Thread.run(Thread.java:841)
and remove getConnectionID().
Also make streamId a field of AbstractXMPPConnection. Most XMPP
connection types have a streamId, it appears to be optional when BOSH
is used though.
RFC 6121 § 5.2.2:
"""
If an application receives a message with no 'type' attribute or the
application does not understand the value of the 'type' attribute
provided, it MUST consider the message to be of type "normal" (i.e.,
"normal" is the default).
"""
Otherwise we may get an NPE if the key was cached:
Connection closed with error java.lang.NullPointerException: Attempt to get length of null array
at org.jivesoftware.smack.util.stringencoder.Base64.encodeToString(Base64.java:43)
at org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism.evaluateChallenge(SCRAMSHA1Mechanism.java:201)
at org.jivesoftware.smack.sasl.SASLMechanism.challengeReceived(SASLMechanism.java:230)
at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthentication.java:328)
at org.jivesoftware.smack.SASLAuthentication.authenticated(SASLAuthentication.java:347)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:894)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:909)
at java.lang.Thread.run(Thread.java:818)
instead of just logging a warning if the XMPP domain has no DNS SRV
lookups, create the failedAddresses list now within DNSUtil and add the
information that the SRV lookup failed.
In initConnection, only initReaderAndWriter() throws IOException.
connectUsingConfiguration doesn't need to take an argument.
PacketReader.init does not throw a SmackException.
Use Async.go() in PacketWriter, just like it's already done in PacketReader.
Also limit the max pool size of the remove callbacks service and use the
same keep alive time for idle threads as the cached executor service
uses.
Note that it would be possible to merge those two. But this could lead
to tasks from the cached executor service blocking the removal of
callbacks, which we don't want.
Make 'order' an long
Parse fall-through case's child elements (message, iq, presence-in,
presence-out)
Remove
privacy.addExtension(new DefaultPacketExtension(parser.getName(), parser.getNamespace()));
at the beginning of PrivacyProvider. Was there since day one for an
unknown reason.
since this method is not only used to determine the key for the
presence map, but also for the 'entries' map.
The logic is in both cases the same: If somehow an entry with an
resourcepart went into the roster (RFC 6121 does not explicity forbid
JIDs with an resourcepart in the roster), then use the full JID as
key, otherwise use the bare JID.
See also SMACK-19.
add a new AutoReceiptMode enum that specifies how delivery receipt
requests are handled. Default is to send receipts if the requstor is
subscribed to the user's presence.
Also make sure that messages contain an id if a receipt request is
added to it.
instead of getMessage(), because some Exceptions, e.g. Android's
NetworkOnMainThreadException, will return null on
getMessage(). Exception.toString() does what we want, i.e. returns
- the exception class name
- and the return value of getLocalizedMessage()
from o.jsmack.tcp.sm, as XEP-198 Stream Management is not an "XMPP over
TCP" exclusive feature. It could also be use together with the Websocket
binding of XMPP, so we may have a smack-streammangement in the
future. This change prepares for that by moving the SM code out of the
XMPP TCP package namespace.
if connect() was not previously called. Previously calling login() with
arguments would not check for the preconditions.
The check to throw needs to be performed in AbstractXMPPConnection
before every 'abstract login(Non)Anonymously()' call. That's the two
lines that check the preconditions are duplicated.
Also fix NPE in
XMPPTCPConnection.throwNotConnectedExceptionIfAppropriate() when
packetWrite is null (i.e. if the connection was never connected before).
(yeah, I know)
Sometimes "a friend" has setup an XMPP service which uses a self-signed
cert. While we can get a decent amount of security by using techniques
like e.g. the MemorizingTrustManager, there's still a pitfall. If the
service's TLS certificates contains no or the wrong service/hostname
information, Smack will throw an CertificateException. Therefore provide
an API call to disable hostname verification.
This is useful for cases where a result set is requested, as it's the
case in XEP-13 and XEP-313.
Also adds
XMPPConnection.createPacketCollector(PacketCollector.Configuration).
InterruptedExceptions should be treated as the users intention to
'cancel' the current thread's task. There is no such thing as a
spurious interrupt (not to be confused with "spurious wakeups").
after at most 12 hours.
Also set a keep alive time for the removeCallbacksService to 30 seconds
and add AbstractXMPPConnection.schedule(Runnable, long, TimeUnit).
isAnonymous() is now a bit weakened since it also considers
allowNullorEmptyUsername.
SaslExternalMechanism of smack-sasl-provided now also doesn't throw an
UnsupportedOperationException.
Follow up on 7e4e3699a1
to avoid confusion between the IQ element 'iq' and the IQs child
element. ELEMENT defined in an IQ sublcass should contain the *child*
element.
Add element to StreamInitation and fix FileTransferManager which still
used a packet listener instead of an IQ request handler to handle
incoming stream initiation requests.
to ConnectionConfiguration.Builder().
And prepare SASL EXTERNAL for empty or null usernames.
Also clarify some parts regarding the user field.
Fixes SMACK-627
This also moves the logic to send error IQ replies from "when there is
no IQ provider registerd" to "when there is no IQ request handler
registered". Which has for example the advantage that IQ parsing no
longer asks for a connection instance.
It's important to know if the stream was resumed. authenticated() is the
ideal callback for Managers to reset their state (e.g. cached values of
the connection state). But if the stream was resumed, the cached values
don't have to be reset.
notably add a cache for the active and default privacy list to avoid
IQ get/response round-trips.
Also add a few methods to PrivacyListManager to get the privacy list
names. The already existing methods always returned the whole list
together with the name, which caused two round-trips.
Simplified some code.
Properly escape Privacy XML.