1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-12-22 18:48:00 +01:00

Merge branch '4.2'

This commit is contained in:
Florian Schmaus 2017-03-20 14:57:42 +01:00
commit 08c228ef99
21 changed files with 3190 additions and 59 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1066.6667 800"
height="800"
width="1066.6667"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse"><path
id="path16"
d="M 0,600 H 800 V 0 H 0 Z" /></clipPath><clipPath
id="clipPath30"
clipPathUnits="userSpaceOnUse"><path
id="path28"
d="m 351.001,359.31 c -17.234,-7.3 -51.945,15.909 -51.945,15.909 v 0 c 0,0 31.115,-33.702 27.068,-47.102 v 0 c -4.048,-13.401 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.173,5.823 53.705,-8.205 v 0 c 2.528,-14.031 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.887,37.471 39.897,36.872 v 0 c 14.012,-0.597 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.952,54.186 v 0 c 10.225,10.229 53.706,8.205 53.706,8.205 v 0 c 0,0 -43.02,12.932 -44.827,30.694 v 0 c -1.81,17.759 27.07,47.102 27.07,47.102 v 0 c 0,0 -35.718,-23.04 -51.948,-15.909 v 0 c -16.232,7.13 -19.951,50.533 -19.951,50.533 v 0 c 0,0 -2.718,-43.232 -19.947,-50.533" /></clipPath><radialGradient
id="radialGradient40"
spreadMethod="pad"
gradientTransform="matrix(89.254456,0,0,-89.254456,370.9502,322.4375)"
gradientUnits="userSpaceOnUse"
r="1"
cy="0"
cx="0"
fy="0"
fx="0"><stop
id="stop36"
offset="0"
style="stop-opacity:1;stop-color:#fdbe10" /><stop
id="stop38"
offset="1"
style="stop-opacity:1;stop-color:#f16422" /></radialGradient></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,800)"
id="g10"><g
id="g12"><g
clip-path="url(#clipPath18)"
id="g14"><g
transform="translate(370.9482,472.6006)"
id="g20"><path
id="path22"
style="fill:#fdbe10;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,0 6.213,-72.485 33.318,-84.392 27.104,-11.905 86.753,26.569 86.753,26.569 0,0 -48.228,-49.006 -45.209,-78.665 3.022,-29.661 74.864,-51.262 74.864,-51.262 0,0 -72.61,3.382 -89.688,-13.703 -17.078,-17.084 6.597,-90.49 6.597,-90.49 0,0 -43.237,60.579 -66.635,61.578 -23.4,1.003 -66.633,-61.578 -66.633,-61.578 0,0 10.826,67.062 6.601,90.49 -4.229,23.431 -89.694,13.703 -89.694,13.703 0,0 68.108,28.882 74.865,51.262 6.757,22.378 -45.21,78.665 -45.21,78.665 0,0 57.978,-38.76 86.757,-26.569 C -4.54,-72.2 0,0 0,0" /></g></g></g><g
id="g24"><g
clip-path="url(#clipPath30)"
id="g26"><g
id="g32"><g
id="g34"><path
id="path42"
style="fill:url(#radialGradient40);stroke:none"
d="m 351.001,359.31 c -17.234,-7.3 -51.945,15.909 -51.945,15.909 v 0 c 0,0 31.115,-33.702 27.068,-47.102 v 0 c -4.048,-13.401 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.173,5.823 53.705,-8.205 v 0 c 2.528,-14.031 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.887,37.471 39.897,36.872 v 0 c 14.012,-0.597 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.952,54.186 v 0 c 10.225,10.229 53.706,8.205 53.706,8.205 v 0 c 0,0 -43.02,12.932 -44.827,30.694 v 0 c -1.81,17.759 27.07,47.102 27.07,47.102 v 0 c 0,0 -35.718,-23.04 -51.948,-15.909 v 0 c -16.232,7.13 -19.951,50.533 -19.951,50.533 v 0 c 0,0 -2.718,-43.232 -19.947,-50.533" /></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1066.6667 800"
height="800"
width="1066.6667"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse"><path
id="path16"
d="M 0,600 H 800 V 0 H 0 Z" /></clipPath><clipPath
id="clipPath30"
clipPathUnits="userSpaceOnUse"><path
id="path28"
d="m 200.001,337.31 c -17.233,-7.3 -51.946,15.909 -51.946,15.909 v 0 c 0,0 31.116,-33.703 27.069,-47.103 v 0 c -4.048,-13.4 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.174,5.824 53.704,-8.204 v 0 c 2.528,-14.032 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.889,37.471 39.898,36.872 v 0 c 14.012,-0.598 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.951,54.186 v 0 c 10.224,10.229 53.705,8.204 53.705,8.204 v 0 c 0,0 -43.02,12.933 -44.827,30.694 v 0 c -1.811,17.761 27.07,47.103 27.07,47.103 v 0 c 0,0 -35.719,-23.04 -51.948,-15.909 v 0 c -16.232,7.131 -19.951,50.532 -19.951,50.532 v 0 c 0,0 -2.719,-43.23 -19.947,-50.532" /></clipPath><radialGradient
id="radialGradient40"
spreadMethod="pad"
gradientTransform="matrix(89.254456,0,0,-89.254456,219.9502,300.4375)"
gradientUnits="userSpaceOnUse"
r="1"
cy="0"
cx="0"
fy="0"
fx="0"><stop
id="stop36"
offset="0"
style="stop-opacity:1;stop-color:#fdbe10" /><stop
id="stop38"
offset="1"
style="stop-opacity:1;stop-color:#f16422" /></radialGradient><clipPath
id="clipPath50"
clipPathUnits="userSpaceOnUse"><path
id="path48"
d="M 0,600 H 800 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,800)"
id="g10"><g
id="g12"><g
clip-path="url(#clipPath18)"
id="g14"><g
transform="translate(219.9482,450.6006)"
id="g20"><path
id="path22"
style="fill:#fdbe10;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,0 6.213,-72.485 33.318,-84.392 27.104,-11.905 86.753,26.569 86.753,26.569 0,0 -48.228,-49.006 -45.208,-78.665 3.021,-29.661 74.863,-51.262 74.863,-51.262 0,0 -72.61,3.382 -89.688,-13.703 -17.079,-17.084 6.597,-90.49 6.597,-90.49 0,0 -43.237,60.579 -66.635,61.578 -23.4,1.003 -66.633,-61.578 -66.633,-61.578 0,0 10.826,67.062 6.601,90.49 -4.229,23.431 -89.694,13.703 -89.694,13.703 0,0 68.108,28.882 74.865,51.262 6.757,22.378 -45.21,78.665 -45.21,78.665 0,0 57.978,-38.76 86.757,-26.569 C -4.54,-72.2 0,0 0,0" /></g></g></g><g
id="g24"><g
clip-path="url(#clipPath30)"
id="g26"><g
id="g32"><g
id="g34"><path
id="path42"
style="fill:url(#radialGradient40);stroke:none"
d="m 200.001,337.31 c -17.233,-7.3 -51.946,15.909 -51.946,15.909 v 0 c 0,0 31.116,-33.703 27.069,-47.103 v 0 c -4.048,-13.4 -44.827,-30.694 -44.827,-30.694 v 0 c 0,0 51.174,5.824 53.704,-8.204 v 0 c 2.528,-14.032 -3.951,-54.186 -3.951,-54.186 v 0 c 0,0 25.889,37.471 39.898,36.872 v 0 c 14.012,-0.598 39.902,-36.872 39.902,-36.872 v 0 c 0,0 -14.178,43.955 -3.951,54.186 v 0 c 10.224,10.229 53.705,8.204 53.705,8.204 v 0 c 0,0 -43.02,12.933 -44.827,30.694 v 0 c -1.811,17.761 27.07,47.103 27.07,47.103 v 0 c 0,0 -35.719,-23.04 -51.948,-15.909 v 0 c -16.232,7.131 -19.951,50.532 -19.951,50.532 v 0 c 0,0 -2.719,-43.23 -19.947,-50.532" /></g></g></g></g><g
id="g44"><g
clip-path="url(#clipPath50)"
id="g46"><g
transform="translate(407.4561,274.8086)"
id="g52"><path
id="path54"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 3.747,-1.967 9.743,-3.935 15.833,-3.935 6.559,0 10.025,2.719 10.025,6.934 0,3.841 -2.999,6.185 -10.587,8.807 -10.494,3.747 -17.427,9.556 -17.427,18.833 0,10.773 9.089,18.925 23.891,18.925 7.216,0 12.369,-1.406 16.116,-3.186 l -3.186,-11.43 c -2.436,1.218 -7.026,2.997 -13.116,2.997 -6.184,0 -9.183,-2.903 -9.183,-6.09 0,-4.027 3.467,-5.809 11.712,-8.993 11.15,-4.124 16.303,-9.931 16.303,-18.924 0,-10.59 -8.057,-19.584 -25.392,-19.584 -7.213,0 -14.333,1.966 -17.894,3.934 z" /></g><g
transform="translate(456.9297,291.3926)"
id="g56"><path
id="path58"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C 0,5.716 -0.189,10.495 -0.376,14.615 H 11.71 l 0.562,-6.276 h 0.281 c 1.968,2.999 6.09,7.308 13.868,7.308 5.996,0 10.587,-3.092 12.554,-7.871 h 0.186 c 1.78,2.436 3.749,4.311 5.997,5.622 2.53,1.406 5.342,2.249 8.715,2.249 8.807,0 15.459,-6.185 15.459,-19.865 v -26.98 H 55.464 v 24.827 c 0,6.652 -2.154,10.493 -6.744,10.493 -3.373,0 -5.622,-2.248 -6.653,-4.967 -0.282,-1.028 -0.469,-2.434 -0.469,-3.559 V -31.198 H 27.731 v 25.672 c 0,5.713 -2.06,9.648 -6.652,9.648 -3.653,0 -5.808,-2.81 -6.65,-5.059 -0.47,-1.124 -0.564,-2.436 -0.564,-3.655 V -31.198 H 0 Z" /></g><g
transform="translate(561.8691,281.835)"
id="g60"><path
id="path62"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -7.496,0 -13.304,-1.78 -13.304,-7.214 0,-3.653 2.435,-5.433 5.62,-5.433 3.467,0 6.466,2.341 7.403,5.247 C -0.094,-6.652 0,-5.808 0,-4.966 Z m 13.772,-10.587 c 0,-4.308 0.187,-8.525 0.749,-11.054 H 1.686 l -0.843,4.589 H 0.562 c -2.999,-3.654 -7.682,-5.621 -13.118,-5.621 -9.274,0 -14.802,6.746 -14.802,14.054 0,11.898 10.681,17.522 26.89,17.522 v 0.562 c 0,2.434 -1.312,5.901 -8.339,5.901 -4.685,0 -9.65,-1.593 -12.649,-3.374 l -2.623,9.091 c 3.185,1.779 9.463,4.122 17.802,4.122 15.272,0 20.049,-8.995 20.049,-19.768 z" /></g><g
transform="translate(621.3672,261.3164)"
id="g64"><path
id="path66"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -2.529,-1.216 -7.309,-2.154 -12.742,-2.154 -14.803,0 -24.266,9.087 -24.266,23.517 0,13.399 9.181,24.361 26.233,24.361 3.749,0 7.87,-0.657 10.869,-1.78 L -2.155,33.355 c -1.687,0.75 -4.217,1.407 -7.964,1.407 -7.495,0 -12.366,-5.34 -12.273,-12.837 0,-8.433 5.621,-12.928 12.554,-12.928 3.373,0 5.996,0.561 8.151,1.499 z" /></g><g
transform="translate(643.4795,286.6143)"
id="g68"><path
id="path70"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h 0.188 c 1.031,1.967 2.155,3.841 3.278,5.526 l 9.276,13.868 H 29.888 L 13.492,0.845 32.23,-26.42 H 14.709 L 3.56,-7.588 0,-12.18 V -26.42 H -14.24 V 40.101 H 0 Z" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 7 KiB

View file

@ -472,7 +472,16 @@ public abstract class ConnectionConfiguration {
return enabledSaslMechanisms.contains(saslMechanism); return enabledSaslMechanisms.contains(saslMechanism);
} }
/**
* Return the explicitly enabled SASL mechanisms. May return <code>null</code> if no SASL mechanisms where
* explicitly enabled, i.e. all SALS mechanisms supported and announced by the service will be considered.
*
* @return the enabled SASL mechanisms or <code>null</code>.
*/
public Set<String> getEnabledSaslMechanisms() { public Set<String> getEnabledSaslMechanisms() {
if (enabledSaslMechanisms == null) {
return null;
}
return Collections.unmodifiableSet(enabledSaslMechanisms); return Collections.unmodifiableSet(enabledSaslMechanisms);
} }

View file

@ -34,9 +34,9 @@ import javax.security.auth.callback.CallbackHandler;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -90,10 +90,10 @@ public final class SASLAuthentication {
* @return the registered SASLMechanism sorted by the level of preference. * @return the registered SASLMechanism sorted by the level of preference.
*/ */
public static Map<String, String> getRegisterdSASLMechanisms() { public static Map<String, String> getRegisterdSASLMechanisms() {
Map<String, String> answer = new HashMap<String, String>(); Map<String, String> answer = new LinkedHashMap<String, String>();
synchronized (REGISTERED_MECHANISMS) { synchronized (REGISTERED_MECHANISMS) {
for (SASLMechanism mechanism : REGISTERED_MECHANISMS) { for (SASLMechanism mechanism : REGISTERED_MECHANISMS) {
answer.put(mechanism.getClass().getName(), mechanism.getName()); answer.put(mechanism.getClass().getName(), mechanism.toString());
} }
} }
return answer; return answer;

View file

@ -226,6 +226,16 @@ public class SynchronizationPoint<E extends Exception> {
} }
} }
public E getFailureException() {
connectionLock.lock();
try {
return failureException;
}
finally {
connectionLock.unlock();
}
}
/** /**
* Wait for the condition to become something else as {@link State#RequestSent} or {@link State#Initial}. * Wait for the condition to become something else as {@link State#RequestSent} or {@link State#Initial}.
* {@link #reportSuccess()}, {@link #reportFailure()} and {@link #reportFailure(Exception)} will either set this * {@link #reportSuccess()}, {@link #reportFailure()} and {@link #reportFailure(Exception)} will either set this

View file

@ -279,6 +279,11 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
*/ */
public abstract String getName(); public abstract String getName();
/**
* Get the priority of this SASL mechanism. Lower values mean higher priority.
*
* @return the priority of this SASL mechanism.
*/
public abstract int getPriority(); public abstract int getPriority();
public abstract void checkIfSuccessfulOrThrow() throws SmackException; public abstract void checkIfSuccessfulOrThrow() throws SmackException;
@ -314,4 +319,9 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
} }
return string; return string;
} }
@Override
public final String toString() {
return "SASL Mech: " + getName() + ", Prio: " + getPriority();
}
} }

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2014-2016 Florian Schmaus * Copyright 2014-2017 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,8 @@ import org.jivesoftware.smack.util.MAC;
public class SCRAMSHA1Mechanism extends ScramMechanism { public class SCRAMSHA1Mechanism extends ScramMechanism {
static final int PRIORITY = 110;
static { static {
SHA_1_SCRAM_HMAC = new ScramHmac() { SHA_1_SCRAM_HMAC = new ScramHmac() {
@Override @Override
@ -47,7 +49,7 @@ public class SCRAMSHA1Mechanism extends ScramMechanism {
@Override @Override
public int getPriority() { public int getPriority() {
return 110; return PRIORITY;
} }
@Override @Override

View file

@ -249,6 +249,9 @@ public abstract class ScramMechanism extends SASLMechanism {
} }
protected String getChannelBindingName() { protected String getChannelBindingName() {
// Check if we are using TLS and if a "-PLUS" variant of this mechanism is enabled. Assuming that the "-PLUS"
// variants always have precedence before the non-"-PLUS" variants this means that the server did not announce
// the "-PLUS" variant, as otherwise we would have tried it.
if (sslSession != null && connectionConfiguration.isEnabledSaslMechanism(getName() + "-PLUS")) { if (sslSession != null && connectionConfiguration.isEnabledSaslMechanism(getName() + "-PLUS")) {
// Announce that we support Channel Binding, i.e., the '-PLUS' flavor of this SASL mechanism, but that we // Announce that we support Channel Binding, i.e., the '-PLUS' flavor of this SASL mechanism, but that we
// believe the server does not. // believe the server does not.

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2016 Florian Schmaus * Copyright 2016-2017 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ public class ScramSha1PlusMechanism extends ScramPlusMechanism {
@Override @Override
public int getPriority() { public int getPriority() {
return 110; return SCRAMSHA1Mechanism.PRIORITY - 10;
} }
@Override @Override

View file

@ -17,15 +17,16 @@
package org.jivesoftware.smackx.bytestreams.ibb; package org.jivesoftware.smackx.bytestreams.ibb;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.AbstractConnectionClosedListener; import org.jivesoftware.smack.AbstractConnectionClosedListener;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
@ -79,7 +80,7 @@ import org.jxmpp.jid.Jid;
* *
* @author Henning Staib * @author Henning Staib
*/ */
public final class InBandBytestreamManager implements BytestreamManager { public final class InBandBytestreamManager extends Manager implements BytestreamManager {
/** /**
* Stanzas that can be used to encapsulate In-Band Bytestream data packets. * Stanzas that can be used to encapsulate In-Band Bytestream data packets.
@ -140,10 +141,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
private final static Random randomGenerator = new Random(); private final static Random randomGenerator = new Random();
/* stores one InBandBytestreamManager for each XMPP connection */ /* stores one InBandBytestreamManager for each XMPP connection */
private final static Map<XMPPConnection, InBandBytestreamManager> managers = new HashMap<XMPPConnection, InBandBytestreamManager>(); private final static Map<XMPPConnection, InBandBytestreamManager> managers = new WeakHashMap<>();
/* XMPP connection */
private final XMPPConnection connection;
/* /*
* assigns a user to a listener that is informed if an In-Band Bytestream request for this user * assigns a user to a listener that is informed if an In-Band Bytestream request for this user
@ -208,7 +206,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
* @param connection the XMPP connection * @param connection the XMPP connection
*/ */
private InBandBytestreamManager(XMPPConnection connection) { private InBandBytestreamManager(XMPPConnection connection) {
this.connection = connection; super(connection);
// register bytestream open packet listener // register bytestream open packet listener
this.initiationListener = new InitiationListener(this); this.initiationListener = new InitiationListener(this);
@ -434,11 +432,13 @@ public final class InBandBytestreamManager implements BytestreamManager {
Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza); Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
byteStreamRequest.setTo(targetJID); byteStreamRequest.setTo(targetJID);
final XMPPConnection connection = connection();
// sending packet will throw exception on timeout or error reply // sending packet will throw exception on timeout or error reply
connection.createStanzaCollectorAndSend(byteStreamRequest).nextResultOrThrow(); connection.createStanzaCollectorAndSend(byteStreamRequest).nextResultOrThrow();
InBandBytestreamSession inBandBytestreamSession = new InBandBytestreamSession( InBandBytestreamSession inBandBytestreamSession = new InBandBytestreamSession(
this.connection, byteStreamRequest, targetJID); connection, byteStreamRequest, targetJID);
this.sessions.put(sessionID, inBandBytestreamSession); this.sessions.put(sessionID, inBandBytestreamSession);
return inBandBytestreamSession; return inBandBytestreamSession;
@ -454,7 +454,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
*/ */
protected void replyRejectPacket(IQ request) throws NotConnectedException, InterruptedException { protected void replyRejectPacket(IQ request) throws NotConnectedException, InterruptedException {
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.not_acceptable); IQ error = IQ.createErrorResponse(request, XMPPError.Condition.not_acceptable);
this.connection.sendStanza(error); connection().sendStanza(error);
} }
/** /**
@ -467,7 +467,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
*/ */
protected void replyResourceConstraintPacket(IQ request) throws NotConnectedException, InterruptedException { protected void replyResourceConstraintPacket(IQ request) throws NotConnectedException, InterruptedException {
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.resource_constraint); IQ error = IQ.createErrorResponse(request, XMPPError.Condition.resource_constraint);
this.connection.sendStanza(error); connection().sendStanza(error);
} }
/** /**
@ -480,7 +480,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
*/ */
protected void replyItemNotFoundPacket(IQ request) throws NotConnectedException, InterruptedException { protected void replyItemNotFoundPacket(IQ request) throws NotConnectedException, InterruptedException {
IQ error = IQ.createErrorResponse(request, XMPPError.Condition.item_not_found); IQ error = IQ.createErrorResponse(request, XMPPError.Condition.item_not_found);
this.connection.sendStanza(error); connection().sendStanza(error);
} }
/** /**
@ -501,7 +501,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
* @return the XMPP connection * @return the XMPP connection
*/ */
protected XMPPConnection getConnection() { protected XMPPConnection getConnection() {
return this.connection; return connection();
} }
/** /**
@ -548,6 +548,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
* internal status, which includes removing this instance from the managers map. * internal status, which includes removing this instance from the managers map.
*/ */
private void disableService() { private void disableService() {
final XMPPConnection connection = connection();
// remove manager from static managers map // remove manager from static managers map
managers.remove(connection); managers.remove(connection);

View file

@ -40,13 +40,12 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
private final StreamNegotiator primaryNegotiator; private final StreamNegotiator primaryNegotiator;
private final StreamNegotiator secondaryNegotiator; private final StreamNegotiator secondaryNegotiator;
private final XMPPConnection connection;
public FaultTolerantNegotiator(XMPPConnection connection, StreamNegotiator primary, public FaultTolerantNegotiator(XMPPConnection connection, StreamNegotiator primary,
StreamNegotiator secondary) { StreamNegotiator secondary) {
super(connection);
this.primaryNegotiator = primary; this.primaryNegotiator = primary;
this.secondaryNegotiator = secondary; this.secondaryNegotiator = secondary;
this.connection = connection;
} }
@Override @Override
@ -64,7 +63,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
@Override @Override
public InputStream createIncomingStream(final StreamInitiation initiation) throws SmackException, XMPPErrorException, InterruptedException { public InputStream createIncomingStream(final StreamInitiation initiation) throws SmackException, XMPPErrorException, InterruptedException {
// This could be either an xep47 ibb 'open' iq or an xep65 streamhost iq // This could be either an xep47 ibb 'open' iq or an xep65 streamhost iq
IQ initationSet = initiateIncomingStream(connection, initiation); IQ initationSet = initiateIncomingStream(connection(), initiation);
StreamNegotiator streamNegotiator = determineNegotiator(initationSet); StreamNegotiator streamNegotiator = determineNegotiator(initationSet);

View file

@ -44,8 +44,6 @@ import org.jxmpp.jid.Jid;
*/ */
public class IBBTransferNegotiator extends StreamNegotiator { public class IBBTransferNegotiator extends StreamNegotiator {
private XMPPConnection connection;
private InBandBytestreamManager manager; private InBandBytestreamManager manager;
/** /**
@ -54,7 +52,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
* @param connection The connection which this negotiator works on. * @param connection The connection which this negotiator works on.
*/ */
protected IBBTransferNegotiator(XMPPConnection connection) { protected IBBTransferNegotiator(XMPPConnection connection) {
this.connection = connection; super(connection);
this.manager = InBandBytestreamManager.getByteStreamManager(connection); this.manager = InBandBytestreamManager.getByteStreamManager(connection);
} }
@ -75,7 +73,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
*/ */
this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID()); this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
Stanza streamInitiation = initiateIncomingStream(this.connection, initiation); Stanza streamInitiation = initiateIncomingStream(connection(), initiation);
return negotiateIncomingStream(streamInitiation); return negotiateIncomingStream(streamInitiation);
} }

View file

@ -43,13 +43,11 @@ import org.jxmpp.jid.Jid;
*/ */
public class Socks5TransferNegotiator extends StreamNegotiator { public class Socks5TransferNegotiator extends StreamNegotiator {
private XMPPConnection connection;
private Socks5BytestreamManager manager; private Socks5BytestreamManager manager;
Socks5TransferNegotiator(XMPPConnection connection) { Socks5TransferNegotiator(XMPPConnection connection) {
this.connection = connection; super(connection);
this.manager = Socks5BytestreamManager.getBytestreamManager(this.connection); this.manager = Socks5BytestreamManager.getBytestreamManager(connection);
} }
@Override @Override
@ -75,7 +73,7 @@ public class Socks5TransferNegotiator extends StreamNegotiator {
*/ */
this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID()); this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID());
Stanza streamInitiation = initiateIncomingStream(this.connection, initiation); Stanza streamInitiation = initiateIncomingStream(connection(), initiation);
return negotiateIncomingStream(streamInitiation); return negotiateIncomingStream(streamInitiation);
} }

View file

@ -16,6 +16,7 @@
*/ */
package org.jivesoftware.smackx.filetransfer; package org.jivesoftware.smackx.filetransfer;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
@ -42,7 +43,11 @@ import java.io.OutputStream;
* *
* @author Alexander Wenckus * @author Alexander Wenckus
*/ */
public abstract class StreamNegotiator { public abstract class StreamNegotiator extends Manager {
protected StreamNegotiator(XMPPConnection connection) {
super(connection);
}
/** /**
* A event manager for stream initiation requests send to us. * A event manager for stream initiation requests send to us.

View file

@ -0,0 +1,45 @@
/**
*
* Copyright 2017 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.pubsub;
import org.jxmpp.jid.BareJid;
public abstract class PubSubAssertionError extends AssertionError {
/**
*
*/
private static final long serialVersionUID = 1L;
protected PubSubAssertionError(String message) {
super(message);
}
public static class DiscoInfoNodeAssertionError extends PubSubAssertionError {
/**
*
*/
private static final long serialVersionUID = 1L;
DiscoInfoNodeAssertionError(BareJid pubSubService, String nodeId) {
super("PubSub service '" + pubSubService + "' returned disco info result for node '" + nodeId
+ "', but it did not contain an Identity of type 'leaf' or 'collection' (and category 'pubsub'), which is not allowed according to XEP-60 5.3.");
}
}
}

View file

@ -16,6 +16,8 @@
*/ */
package org.jivesoftware.smackx.pubsub; package org.jivesoftware.smackx.pubsub;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -34,6 +36,7 @@ import org.jivesoftware.smack.packet.EmptyResultIQ;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
@ -246,12 +249,7 @@ public final class PubSubManager extends Manager {
// XEP-60 5.3 states that // XEP-60 5.3 states that
// "The 'disco#info' result MUST include an identity with a category of 'pubsub' and a type of either 'leaf' or 'collection'." // "The 'disco#info' result MUST include an identity with a category of 'pubsub' and a type of either 'leaf' or 'collection'."
// If this is not the case, then we are dealing with an PubSub implementation that doesn't follow the specification. // If this is not the case, then we are dealing with an PubSub implementation that doesn't follow the specification.
throw new AssertionError( throw new PubSubAssertionError.DiscoInfoNodeAssertionError(pubSubService, id);
"PubSub service '"
+ pubSubService
+ "' returned disco info result for node '"
+ id
+ "', but it did not contain an Identity of type 'leaf' or 'collection' (and category 'pubsub'), which is not allowed according to XEP-60 5.3.");
} }
nodeMap.put(id, node); nodeMap.put(id, node);
} }
@ -260,6 +258,71 @@ public final class PubSubManager extends Manager {
return res; return res;
} }
/**
* Try to get a leaf node and create one if it does not already exist.
*
* @param id The unique ID of the node.
* @return the leaf node.
* @throws NoResponseException
* @throws NotConnectedException
* @throws InterruptedException
* @throws XMPPErrorException
* @since 4.2.1
*/
public LeafNode getOrCreateLeafNode(final String id)
throws NoResponseException, NotConnectedException, InterruptedException, XMPPErrorException {
try {
return getNode(id);
}
catch (XMPPErrorException e1) {
if (e1.getXMPPError().getCondition() == Condition.item_not_found) {
try {
return createNode(id);
}
catch (XMPPErrorException e2) {
if (e2.getXMPPError().getCondition() == Condition.conflict) {
// The node was created in the meantime, re-try getNode(). Note that this case should be rare.
return getNode(id);
}
throw e2;
}
}
throw e1;
}
catch (PubSubAssertionError.DiscoInfoNodeAssertionError e) {
// This could be caused by Prosody bug #805 (see https://prosody.im/issues/issue/805). Prosody does not
// answer to disco#info requests on the node ID, which makes it undecidable if a node is a leaf or
// collection node.
LOGGER.warning("The PubSub service " + pubSubService
+ " threw an DiscoInfoNodeAssertionError, trying workaround for Prosody bug #805 (https://prosody.im/issues/issue/805)");
return getOrCreateLeafNodeProsodyWorkaround(id);
}
}
private LeafNode getOrCreateLeafNodeProsodyWorkaround(final String id)
throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
try {
return createNode(id);
}
catch (XMPPErrorException e1) {
if (e1.getXMPPError().getCondition() == Condition.conflict) {
Constructor<?> constructor = LeafNode.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
LeafNode res;
try {
res = (LeafNode) constructor.newInstance(this, id);
}
catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e2) {
throw new AssertionError(e2);
}
// TODO: How to verify that this is actually a leafe node and not a conflict with a collection node?
return res;
}
throw e1;
}
}
/** /**
* Get all the nodes that currently exist as a child of the specified * Get all the nodes that currently exist as a child of the specified
* collection node. If the service does not support collection nodes * collection node. If the service does not support collection nodes

View file

@ -180,6 +180,7 @@ public class IntTestUtil {
ServiceAdministrationManager adminManager = ServiceAdministrationManager.getInstanceFor(connection); ServiceAdministrationManager adminManager = ServiceAdministrationManager.getInstanceFor(connection);
try { try {
adminManager.deleteUser(accountToDelete); adminManager.deleteUser(accountToDelete);
break;
} }
catch (NoResponseException | XMPPErrorException | NotConnectedException | InterruptedException e) { catch (NoResponseException | XMPPErrorException | NotConnectedException | InterruptedException e) {
LOGGER.log(Level.WARNING, "Exception deleting account for " + connection, e); LOGGER.log(Level.WARNING, "Exception deleting account for " + connection, e);

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2015 Florian Schmaus * Copyright 2015-2017 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,6 +40,10 @@ public class WaitForClosingStreamElementTest extends AbstractSmackLowLevelIntegr
Field closingStreamReceivedField = connection.getClass().getDeclaredField("closingStreamReceived"); Field closingStreamReceivedField = connection.getClass().getDeclaredField("closingStreamReceived");
closingStreamReceivedField.setAccessible(true); closingStreamReceivedField.setAccessible(true);
SynchronizationPoint<?> closingStreamReceived = (SynchronizationPoint<?>) closingStreamReceivedField.get(connection); SynchronizationPoint<?> closingStreamReceived = (SynchronizationPoint<?>) closingStreamReceivedField.get(connection);
Exception failureException = closingStreamReceived.getFailureException();
if (failureException != null) {
throw new AssertionError("Sync poing yielded failure exception", failureException);
}
assertTrue(closingStreamReceived.wasSuccessful()); assertTrue(closingStreamReceived.wasSuccessful());
} }
} }

View file

@ -1424,26 +1424,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
// unacknowledgedStanzas is not null. // unacknowledgedStanzas is not null.
unacknowledgedStanzas = new ArrayBlockingQueue<>(QUEUE_SIZE); unacknowledgedStanzas = new ArrayBlockingQueue<>(QUEUE_SIZE);
} }
// Check if the stream element should be put to the unacknowledgedStanza maybeAddToUnacknowledgedStanzas(packet);
// queue. Note that we can not do the put() in sendStanzaInternal() and the
// packet order is not stable at this point (sendStanzaInternal() can be
// called concurrently).
if (unacknowledgedStanzas != null && packet != null) {
// If the unacknowledgedStanza queue is nearly full, request an new ack
// from the server in order to drain it
if (unacknowledgedStanzas.size() == 0.8 * XMPPTCPConnection.QUEUE_SIZE) {
writer.write(AckRequest.INSTANCE.toXML().toString());
writer.flush();
}
try {
// It is important the we put the stanza in the unacknowledged stanza
// queue before we put it on the wire
unacknowledgedStanzas.put(packet);
}
catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
CharSequence elementXml = element.toXML(); CharSequence elementXml = element.toXML();
if (elementXml instanceof XmlStringBuilder) { if (elementXml instanceof XmlStringBuilder) {
@ -1465,6 +1446,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
try { try {
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Element packet = queue.remove(); Element packet = queue.remove();
if (packet instanceof Stanza) {
Stanza stanza = (Stanza) packet;
maybeAddToUnacknowledgedStanzas(stanza);
}
writer.write(packet.toXML().toString()); writer.write(packet.toXML().toString());
} }
writer.flush(); writer.flush();
@ -1523,6 +1508,29 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
} }
} }
private void maybeAddToUnacknowledgedStanzas(Stanza stanza) throws IOException {
// Check if the stream element should be put to the unacknowledgedStanza
// queue. Note that we can not do the put() in sendStanzaInternal() and the
// packet order is not stable at this point (sendStanzaInternal() can be
// called concurrently).
if (unacknowledgedStanzas != null && stanza != null) {
// If the unacknowledgedStanza queue is nearly full, request an new ack
// from the server in order to drain it
if (unacknowledgedStanzas.size() == 0.8 * XMPPTCPConnection.QUEUE_SIZE) {
writer.write(AckRequest.INSTANCE.toXML().toString());
writer.flush();
}
try {
// It is important the we put the stanza in the unacknowledged stanza
// queue before we put it on the wire
unacknowledgedStanzas.put(stanza);
}
catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}
} }
/** /**