You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ng...@apache.org on 2011/01/03 11:17:13 UTC
svn commit: r1054572 - in /mina/vysper/branches/s2s/server: core-inttest/
core-inttest/src/test/java/org/apache/vysper/xmpp/server/
core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/
core-inttest/src/test/resources/ core/src/main/java/org/ap...
Author: ngn
Date: Mon Jan 3 10:17:12 2011
New Revision: 1054572
URL: http://svn.apache.org/viewvc?rev=1054572&view=rev
Log:
Refactoring XMPPServerConnector to use stanza handlers
Adding integration test case runner (for manual use)
Added:
mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/
mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/
mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/S2SIntegrationTestCase.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/FeaturesHandler.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/TlsProceedHandler.java
mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandlerTestCase.java
mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTestCase.java
- copied, changed from r1054458, mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTest.java
mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/server/s2s/Server2Server.java
Removed:
mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTest.java
Modified:
mina/vysper/branches/s2s/server/core-inttest/ (props changed)
mina/vysper/branches/s2s/server/core-inttest/src/test/resources/log4j.properties
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/StreamStartHandler.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbResultHandler.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandler.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/EncryptedProtocolWorker.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/StartedProtocolWorker.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/response/ServerResponses.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnector.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnectorRegistry.java
mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/XMPPServerConnectorRegistry.java
Propchange: mina/vysper/branches/s2s/server/core-inttest/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Jan 3 10:17:12 2011
@@ -2,3 +2,4 @@
target
.classpath
.project
+s2s-jabber.org.properties
Added: mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/S2SIntegrationTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/S2SIntegrationTestCase.java?rev=1054572&view=auto
==============================================================================
--- mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/S2SIntegrationTestCase.java (added)
+++ mina/vysper/branches/s2s/server/core-inttest/src/test/java/org/apache/vysper/xmpp/server/s2s/S2SIntegrationTestCase.java Mon Jan 3 10:17:12 2011
@@ -0,0 +1,210 @@
+package org.apache.vysper.xmpp.server.s2s;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.vysper.mina.TCPEndpoint;
+import org.apache.vysper.storage.StorageProviderRegistry;
+import org.apache.vysper.storage.inmemory.MemoryStorageProviderRegistry;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.authorization.AccountCreationException;
+import org.apache.vysper.xmpp.authorization.AccountManagement;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.XMPPServer;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class S2SIntegrationTestCase extends TestCase {
+
+ public static Test suite() {
+ File testsDir = new File(".");
+ File[] testFiles = testsDir.listFiles(new FilenameFilter() {
+ public boolean accept(File arg0, String name) {
+ return name.startsWith("s2s-");
+ }
+ });
+
+ TestSuite suite = new TestSuite("S2S integration tests");
+ for(File testFile : testFiles) {
+ try {
+ suite.addTest(new S2SIntegrationTestCase(testFile));
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ }
+ return suite;
+ }
+
+ private File testFile;
+ private Properties config = new Properties();
+
+ public S2SIntegrationTestCase(File testFile) throws IOException {
+ this.testFile = testFile;
+ config.load(new FileInputStream(testFile));
+ }
+
+ @Override
+ public String getName() {
+ return testFile.getName();
+ }
+
+ protected void runTest() throws Throwable {
+ Entity localServer = EntityImpl.parseUnchecked(config.getProperty("local.server"));
+ String localConnect = config.getProperty("local.connect", localServer.getFullQualifiedName());
+ Entity localUser = EntityImpl.parseUnchecked(config.getProperty("local.user"));
+ String localPassword = "password";
+ Entity remoteServer = EntityImpl.parseUnchecked(config.getProperty("remote.server"));
+ Entity remoteUser = EntityImpl.parseUnchecked(config.getProperty("remote.user"));
+ String remotePassword = config.getProperty("remote.password");
+
+ String keystorePath = config.getProperty("keystore.path");
+ String keystorePassword = config.getProperty("keystore.password");
+
+ XMPPServer server = createLocalServer(localServer, localUser, localPassword, keystorePath, keystorePassword);
+
+ Thread.sleep(2000);
+
+ System.out.println();
+ System.out.println();
+ System.out.println("Connecting local client");
+ System.out.println();
+ System.out.println();
+
+ LinkedBlockingQueue<Packet> localClientPackages = new LinkedBlockingQueue<Packet>();
+ LinkedBlockingQueue<Packet> remoteClientPackages = new LinkedBlockingQueue<Packet>();
+
+ XMPPConnection localClient = connectClient(localConnect, localUser, localPassword, keystorePath, keystorePassword, localClientPackages);
+
+ System.out.println();
+ System.out.println();
+ System.out.println("Connecting remote client");
+ System.out.println();
+ System.out.println();
+
+ XMPPConnection remoteClient = connectClient(remoteServer.getDomain(), remoteUser, remotePassword, keystorePath, keystorePassword, remoteClientPackages);
+
+ Thread.sleep(3000);
+
+ System.out.println();
+ System.out.println();
+ System.out.println("Sending message from local to remote");
+ System.out.println();
+ System.out.println();
+
+ remoteClientPackages.clear();
+ Message msg = new Message(remoteUser.getFullQualifiedName());
+ msg.setBody("Hello world");
+
+ localClient.sendPacket(msg);
+
+ Packet packet = remoteClientPackages.poll(15000, TimeUnit.MILLISECONDS);
+ if(packet != null && packet instanceof Message) {
+ System.out.println("!!!!!!" + ((Message)packet).getBody());
+ } else {
+ fail("Message not received by remote client");
+ }
+
+ Thread.sleep(3000);
+
+ System.out.println();
+ System.out.println();
+ System.out.println("Sending message from remote to local");
+ System.out.println();
+ System.out.println();
+
+ localClientPackages.clear();
+ msg = new Message(localUser.getFullQualifiedName());
+ msg.setBody("Hello world");
+
+ remoteClient.sendPacket(msg);
+
+ packet = localClientPackages.poll(15000, TimeUnit.MILLISECONDS);
+ if(packet != null && packet instanceof Message) {
+ System.out.println("!!!!!!" + ((Message)packet).getBody());
+ } else {
+ fail("Message not received by local client");
+ }
+
+ Thread.sleep(15000);
+ System.out.println();
+ System.out.println();
+ System.out.println("Closing down");
+ System.out.println();
+ System.out.println();
+
+ remoteClient.disconnect();
+ localClient.disconnect();
+
+ Thread.sleep(5000);
+
+ server.stop();
+ }
+
+ private XMPPConnection connectClient(String host, Entity user, String password, String keystorePath, String keystorePassword, final LinkedBlockingQueue<Packet> packageQueue)
+ throws XMPPException {
+ ConnectionConfiguration connectionConfiguration = new ConnectionConfiguration(host, 5222);
+ connectionConfiguration.setKeystorePath(keystorePath);
+ connectionConfiguration.setTruststorePath(keystorePath);
+ connectionConfiguration.setTruststorePassword(keystorePassword);
+ XMPPConnection client = new XMPPConnection(connectionConfiguration);
+
+ client.connect();
+ client.login(user.getNode(), password);
+ client.addPacketListener(new PacketListener() {
+ public void processPacket(Packet packet) {
+ System.out.println("# " + packet);
+ packageQueue.add(packet);
+ }
+ }, new PacketFilter() {
+ public boolean accept(Packet arg0) {
+ return true;
+ }
+ });
+
+
+ return client;
+ }
+
+ private XMPPServer createLocalServer(Entity localServer, Entity localUser, String password, String keystorePath,
+ String keystorePassword) throws AccountCreationException, FileNotFoundException, Exception {
+ XMPPServer server = new XMPPServer(localServer.getDomain());
+
+ StorageProviderRegistry providerRegistry = new MemoryStorageProviderRegistry();
+ final AccountManagement accountManagement = (AccountManagement) providerRegistry
+ .retrieve(AccountManagement.class);
+
+ if (!accountManagement.verifyAccountExists(localUser)) {
+ accountManagement.addUser(localUser.getFullQualifiedName(), password);
+ }
+
+ // S2S endpoint
+ TCPEndpoint s2sEndpoint = new TCPEndpoint();
+ s2sEndpoint.setPort(5269);
+ server.addEndpoint(s2sEndpoint);
+
+ // C2S endpoint
+ server.addEndpoint(new TCPEndpoint());
+
+ server.setStorageProviderRegistry(providerRegistry);
+ server.setTLSCertificateInfo(new File(keystorePath), keystorePassword);
+
+ server.start();
+ return server;
+ }
+}
Modified: mina/vysper/branches/s2s/server/core-inttest/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core-inttest/src/test/resources/log4j.properties?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core-inttest/src/test/resources/log4j.properties (original)
+++ mina/vysper/branches/s2s/server/core-inttest/src/test/resources/log4j.properties Mon Jan 3 10:17:12 2011
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-log4j.rootLogger=DEBUG, C
+log4j.rootLogger=INFO, C
log4j.logger.org.apache.vysper.mina.XmppIoHandlerAdapter=WARN,C
log4j.logger.org.apache.mina.filter.executor.ExecutorFilter=WARN,C
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/StreamStartHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/StreamStartHandler.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/StreamStartHandler.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/StreamStartHandler.java Mon Jan 3 10:17:12 2011
@@ -130,9 +130,8 @@ public class StreamStartHandler implemen
// RFC3920: 'to' attribute SHOULD be used by the initiating entity
String toValue = stanza.getAttributeValue("to");
if (toValue != null) {
- EntityImpl toEntity = null;
try {
- toEntity = EntityImpl.parse(toValue);
+ EntityImpl.parse(toValue);
} catch (EntityFormatException e) {
return new ResponseStanzaContainerImpl(ServerErrorResponses.getInstance().getStreamError(
StreamErrorCondition.IMPROPER_ADDRESSING, sessionContext.getXMLLang(),
@@ -145,7 +144,7 @@ public class StreamStartHandler implemen
// TODO RFC3920: 'from' attribute SHOULD be silently ignored by the receiving entity
// TODO RFC3920bis: 'from' attribute SHOULD be not ignored by the receiving entity and used as 'to' in responses
}
- responseStanza = new ServerResponses().getStreamOpener(clientCall, sessionContext.getServerJID(),
+ responseStanza = new ServerResponses().getStreamOpenerForClient(sessionContext.getServerJID(),
responseVersion, sessionContext);
} else if (serverCall) {
// RFC3920: 'from' attribute SHOULD be used by the receiving entity
@@ -162,8 +161,8 @@ public class StreamStartHandler implemen
// TODO set version correctly
responseVersion = XMPPVersion.VERSION_1_0;
- responseStanza = new ServerResponses().getStreamOpener(clientCall, sessionContext.getServerJID(),
- responseVersion, sessionContext);
+ responseStanza = new ServerResponses().getStreamOpenerForServerAcceptor(sessionContext.getServerJID(),
+ responseVersion, sessionContext, serverRuntimeContext.getSslContext() != null);
} else {
String descriptiveText = "one of the two namespaces must be present: " + NamespaceURIs.JABBER_CLIENT
+ " or " + NamespaceURIs.JABBER_SERVER;
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbResultHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbResultHandler.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbResultHandler.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbResultHandler.java Mon Jan 3 10:17:12 2011
@@ -29,9 +29,12 @@ import org.apache.vysper.xmpp.protocol.S
import org.apache.vysper.xmpp.protocol.StanzaHandler;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.server.SessionState;
import org.apache.vysper.xmpp.server.s2s.XMPPServerConnector;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*
@@ -39,6 +42,9 @@ import org.apache.vysper.xmpp.stanza.Sta
*/
public class DbResultHandler implements StanzaHandler {
+ private static final Logger LOG = LoggerFactory.getLogger(DbResultHandler.class);
+
+
public String getName() {
return "result";
}
@@ -64,6 +70,7 @@ public class DbResultHandler implements
String type = stanza.getAttributeValue("type");
if(type == null) {
+ // acting as the Receiving server
// start of dailback, respond
String streamId = sessionContext.getSessionId();
String dailbackId = stanza.getInnerText().getText();
@@ -97,6 +104,14 @@ public class DbResultHandler implements
return new ResponseStanzaContainerImpl(builder.build());
}
} else {
+ // acting as the Originating server
+ // receiving the result from the Receiving server
+ if("valid".equals(type)) {
+ sessionStateHolder.setState(SessionState.AUTHENTICATED);
+ Entity receiving = EntityImpl.parseUnchecked(stanza.getAttributeValue("from"));
+ LOG.info("XMPP server connector to {} authenticated using dialback", receiving);
+ }
+
return null;
}
}
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandler.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandler.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandler.java Mon Jan 3 10:17:12 2011
@@ -29,6 +29,8 @@ import org.apache.vysper.xmpp.protocol.S
import org.apache.vysper.xmpp.protocol.StanzaHandler;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.server.SessionState;
+import org.apache.vysper.xmpp.server.s2s.XMPPServerConnector;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;
@@ -55,35 +57,66 @@ public class DbVerifyHandler implements
}
public boolean isSessionRequired() {
- return false;
+ return true;
}
public ResponseStanzaContainer execute(Stanza stanza, ServerRuntimeContext serverRuntimeContext,
boolean isOutboundStanza, SessionContext sessionContext, SessionStateHolder sessionStateHolder) {
String type = stanza.getAttributeValue("type");
+ String id = stanza.getAttributeValue("id");
Entity receiving = EntityImpl.parseUnchecked(stanza.getAttributeValue("from"));
Entity originating = serverRuntimeContext.getServerEnitity();
-
if(type == null) {
- // ask for verification
+ // acting as a Authoritative server
+ // getting asked for verification from the Receiving server
String dailbackId = stanza.getInnerText().getText();
- String streamId = stanza.getAttributeValue("id");
StanzaBuilder builder = new StanzaBuilder("verify", NamespaceURIs.JABBER_SERVER_DIALBACK, "db");
builder.addAttribute("from", originating.getDomain());
builder.addAttribute("to", receiving.getDomain());
- builder.addAttribute("id", streamId);
+ builder.addAttribute("id", id);
- if(dailbackIdGenerator.verify(dailbackId, receiving, originating, streamId)) {
+ if(dailbackIdGenerator.verify(dailbackId, receiving, originating, id)) {
builder.addAttribute("type", "valid");
} else {
builder.addAttribute("type", "invalid");
}
-
return new ResponseStanzaContainerImpl(builder.build());
} else {
- throw new RuntimeException("Unexpected stanza");
+ // acting as a Receiving server
+ // getting a response from the Authoritative server
+ SessionStateHolder dialbackSessionStateHolder = (SessionStateHolder) sessionContext.getAttribute("DIALBACK_SESSION_STATE_HOLDER");
+ SessionContext dialbackSessionContext = (SessionContext) sessionContext.getAttribute("DIALBACK_SESSION_CONTEXT");
+
+// XMPPServerConnector connector = serverRuntimeContext.getServerConnectorRegistry().getConnectorBySessionId(id);
+
+// if(connector != null) {
+// SessionStateHolder dialbackSessionStateHolder = connector.getSessionStateHolder();
+// SessionContext dialbackSessionContext = connector.getSessionContext();
+
+
+ Entity otherServer = sessionContext.getInitiatingEntity();
+ String resultType = "invalid";
+ // dialbackSessionContext must be non-null or someone is trying to send this stanza in the wrong state
+ if("valid".equals(type)) {
+ dialbackSessionStateHolder.setState(SessionState.AUTHENTICATED);
+ dialbackSessionContext.setInitiatingEntity(otherServer);
+ resultType = "valid";
+ }
+
+ // <db:result xmlns:db="jabber:server:dialback" to="xmpp.protocol7.com" from="jabber.org" type="valid"></db:result>
+ StanzaBuilder builder = new StanzaBuilder("result", NamespaceURIs.JABBER_SERVER_DIALBACK, "db");
+ builder.addAttribute("from", originating.getDomain());
+ builder.addAttribute("to", otherServer.getDomain());
+ builder.addAttribute("type", resultType);
+
+ dialbackSessionContext.write(builder.build());
+// }
+
+ // close this session as we are now done checking dialback
+ sessionContext.close();
+ return null;
}
}
}
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java Mon Jan 3 10:17:12 2011
@@ -135,13 +135,13 @@ public class ProtocolWorker implements S
Entity to = stanza.getTo();
if(to == null) {
- // TODO what's the appropriate error?
+ // TODO what's the appropriate error? StreamErrorCondition.IMPROPER_ADDRESSING?
Stanza errorStanza = ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.BAD_REQUEST,
coreStanza, StanzaErrorType.MODIFY, "Missing to attribute", null, null);
ResponseWriter.writeResponse(sessionContext, errorStanza);
return;
} else if(!to.getDomain().equals(serverRuntimeContext.getServerEnitity().getDomain())) {
- // TODO what's the appropriate error?
+ // TODO what's the appropriate error? StreamErrorCondition.IMPROPER_ADDRESSING?
Stanza errorStanza = ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.BAD_REQUEST,
coreStanza, StanzaErrorType.MODIFY, "Invalid to attribute", null, null);
ResponseWriter.writeResponse(sessionContext, errorStanza);
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/EncryptedProtocolWorker.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/EncryptedProtocolWorker.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/EncryptedProtocolWorker.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/EncryptedProtocolWorker.java Mon Jan 3 10:17:12 2011
@@ -23,6 +23,7 @@ import org.apache.vysper.xmpp.modules.co
import org.apache.vysper.xmpp.modules.core.base.handler.XMLPrologHandler;
import org.apache.vysper.xmpp.modules.core.sasl.handler.AbstractSASLHandler;
import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DbResultHandler;
+import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DbVerifyHandler;
import org.apache.vysper.xmpp.protocol.ResponseWriter;
import org.apache.vysper.xmpp.protocol.SessionStateHolder;
import org.apache.vysper.xmpp.protocol.StanzaHandler;
@@ -44,6 +45,7 @@ public class EncryptedProtocolWorker ext
@Override
protected boolean checkState(SessionContext sessionContext, SessionStateHolder sessionStateHolder, Stanza stanza,
StanzaHandler stanzaHandler) {
+
if (stanzaHandler instanceof StreamStartHandler)
return true;
if (stanzaHandler instanceof AbstractSASLHandler)
@@ -52,6 +54,8 @@ public class EncryptedProtocolWorker ext
return true; // PSI client sends that.
if (sessionContext.isServerToServer() && stanzaHandler instanceof DbResultHandler)
return true;
+ if (sessionContext.isServerToServer() && stanzaHandler instanceof DbVerifyHandler)
+ return true;
ResponseWriter.writeUnsupportedStanzaError(sessionContext);
return false;
}
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/StartedProtocolWorker.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/StartedProtocolWorker.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/StartedProtocolWorker.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/protocol/worker/StartedProtocolWorker.java Mon Jan 3 10:17:12 2011
@@ -43,6 +43,7 @@ public class StartedProtocolWorker exten
@Override
protected boolean checkState(SessionContext sessionContext, SessionStateHolder sessionStateHolder, Stanza stanza,
StanzaHandler stanzaHandler) {
+
if (stanzaHandler instanceof StartTLSHandler)
return true;
if (sessionContext.isServerToServer() && stanzaHandler instanceof DbVerifyHandler)
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/response/ServerResponses.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/response/ServerResponses.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/response/ServerResponses.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/response/ServerResponses.java Mon Jan 3 10:17:12 2011
@@ -41,14 +41,6 @@ public class ServerResponses {
return getStreamOpener(forClient, from, null, version, errorStanza).build();
}
- public Stanza getStreamOpener(boolean forClient, Entity from, XMPPVersion version, SessionContext sessionContext) {
- if(forClient) {
- return getStreamOpenerForClient(from, version, sessionContext);
- } else {
- return getStreamOpenerForServerAcceptor(from, version, sessionContext);
- }
- }
-
public Stanza getStreamOpenerForClient(Entity from, XMPPVersion version, SessionContext sessionContext) {
Stanza innerFeatureStanza;
if (sessionContext.getState() == SessionState.INITIATED)
@@ -69,7 +61,7 @@ public class ServerResponses {
return stanzaBuilder.build();
}
- public Stanza getStreamOpenerForServerAcceptor(Entity from, XMPPVersion version, SessionContext sessionContext) {
+ public Stanza getStreamOpenerForServerAcceptor(Entity from, XMPPVersion version, SessionContext sessionContext, boolean tlsConfigured) {
StanzaBuilder featureBuilder = startFeatureStanza();
if (sessionContext.getState() == SessionState.INITIATED) {
featureBuilder.startInnerElement("starttls", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS).endInnerElement();
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnector.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnector.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnector.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnector.java Mon Jan 3 10:17:12 2011
@@ -1,5 +1,6 @@
package org.apache.vysper.xmpp.server.s2s;
import java.nio.channels.UnresolvedAddressException;
+import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
@@ -22,9 +23,11 @@ import org.apache.vysper.xmpp.delivery.f
import org.apache.vysper.xmpp.delivery.failure.RemoteServerTimeoutException;
import org.apache.vysper.xmpp.modules.extension.xep0119_xmppping.XmppPingListener;
import org.apache.vysper.xmpp.modules.extension.xep0119_xmppping.XmppPingModule;
-import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DialbackIdGenerator;
-import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DbResultHandler;
+import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DbVerifyHandler;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
import org.apache.vysper.xmpp.protocol.SessionStateHolder;
+import org.apache.vysper.xmpp.protocol.StanzaHandler;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.SessionContext;
import org.apache.vysper.xmpp.server.SessionState;
@@ -32,7 +35,6 @@ import org.apache.vysper.xmpp.server.XMP
import org.apache.vysper.xmpp.server.response.ServerResponses;
import org.apache.vysper.xmpp.server.s2s.XmppEndpointResolver.ResolvedAddress;
import org.apache.vysper.xmpp.stanza.Stanza;
-import org.apache.vysper.xmpp.stanza.StanzaBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,7 +59,7 @@ public class DefaultXMPPServerConnector
private SessionContext dialbackSessionContext;
private SessionStateHolder dialbackSessionStateHolder;
- private Timer pingTimer = new Timer("pingtimer", true);
+ private Timer pingTimer;
public DefaultXMPPServerConnector(Entity otherServer, ServerRuntimeContext serverRuntimeContext, SessionContext dialbackSessionContext, SessionStateHolder dialbackSessionStateHolder) {
this.serverRuntimeContext = serverRuntimeContext;
@@ -84,7 +86,6 @@ public class DefaultXMPPServerConnector
LOG.info("Connecting to XMPP server {} at {}", otherServer, address.getAddress());
connector = createConnector(authenticatedLatch);
-
ConnectFuture connectFuture = connector.connect(address.getAddress());
if(connectFuture.awaitUninterruptibly(connectTimeout) && connectFuture.isConnected()) {
// success on the TCP/IP level, now wait for the XMPP handshake
@@ -138,8 +139,9 @@ public class DefaultXMPPServerConnector
private void startPinging() {
- // is the XMPP ping module active?
- if(serverRuntimeContext.getModule(XmppPingModule.class) != null) {
+ // are pings not already running and is the XMPP ping module active?
+ if(pingTimer == null && serverRuntimeContext.getModule(XmppPingModule.class) != null) {
+ pingTimer = new Timer("pingtimer", true);
pingTimer.schedule(new PingTask(), pingPeriod, pingPeriod);
}
}
@@ -177,6 +179,14 @@ public class DefaultXMPPServerConnector
}
private final class ConnectorIoHandler extends IoHandlerAdapter {
+
+ private final List<StanzaHandler> handlers = Arrays.asList(
+ new DbVerifyHandler(),
+ new DbResultHandler(),
+ new TlsProceedHandler(),
+ new FeaturesHandler()
+ );
+
private final CountDownLatch authenticatedLatch;
private ConnectorIoHandler(CountDownLatch authenticatedLatch) {
@@ -185,13 +195,21 @@ public class DefaultXMPPServerConnector
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
- LOG.info("Exception thrown by XMPP server connector to {}, probably a bug in Vysper", otherServer);
+ LOG.warn("Exception thrown by XMPP server connector to " + otherServer + ", probably a bug in Vysper", cause);
}
+ private StanzaHandler lookupHandler(Stanza stanza) {
+ for(StanzaHandler handler : handlers) {
+ if(handler.verify(stanza)) {
+ return handler;
+ }
+ }
+ return null;
+ }
+
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
if(message == SslFilter.SESSION_SECURED) {
- // TODO handle unsecure
// connection secured, send stream opener
sessionStateHolder.setState(SessionState.ENCRYPTED);
@@ -203,93 +221,47 @@ public class DefaultXMPPServerConnector
Stanza opener = new ServerResponses().getStreamOpenerForServerConnector(serverRuntimeContext.getServerEnitity(), otherServer, XMPPVersion.VERSION_1_0, sessionContext);
sessionContext.write(opener);
- } else {
- Stanza msg = (Stanza) message;
+ } else if(message instanceof Stanza) {
+ Stanza stanza = (Stanza) message;
- if(msg.getName().equals("stream")) {
- sessionContext.setSessionId(msg.getAttributeValue("id"));
- } else if(msg.getName().equals("features")) {
- if(dialbackSessionContext != null) {
- // connector is being used for dialback verificiation, don't do further authentication
- session.setAttribute("DIALBACK_SESSION_CONTEXT", dialbackSessionContext);
- session.setAttribute("DIALBACK_SESSION_STATE_HOLDER", dialbackSessionStateHolder);
-
- sessionStateHolder.setState(SessionState.AUTHENTICATED);
- authenticatedLatch.countDown();
- } else {
- if(startTlsSupported(msg)) {
- LOG.info("XMPP server connector to {} is starting TLS", otherServer);
- Stanza startTlsStanza = new StanzaBuilder("starttls", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS).build();
-
- sessionContext.write(startTlsStanza);
-
- } else if(dialbackSupported(msg)) {
- Entity originating = serverRuntimeContext.getServerEnitity();
-
- String dailbackId = new DialbackIdGenerator().generate(otherServer, originating, sessionContext.getSessionId());
-
- Stanza dbResult = new StanzaBuilder("result", NamespaceURIs.JABBER_SERVER_DIALBACK, "db")
- .addAttribute("from", originating.getDomain())
- .addAttribute("to", otherServer.getDomain())
- .addText(dailbackId)
- .build();
-
- sessionContext.write(dbResult);
- } else {
- // TODO how to handle
- throw new RuntimeException("Unsupported features");
- }
+ // check for basic stanza handlers
+ StanzaHandler handler = lookupHandler(stanza);
+
+ if(handler != null) {
+ ResponseStanzaContainer container = handler.execute(stanza, serverRuntimeContext, false, sessionContext, sessionStateHolder);
+ if(container != null && container.hasResponse()) {
+ sessionContext.write(container.getResponseStanza());
}
- } else if(msg.getName().equals("proceed") && NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS.equals(msg.getNamespaceURI())) {
- sessionStateHolder.setState(SessionState.ENCRYPTION_STARTED);
-
- LOG.debug("XMPP server connector to {} switching to TLS", otherServer);
- sessionContext.switchToTLS(false, true);
- } else if(msg.getName().equals("result") && NamespaceURIs.JABBER_SERVER_DIALBACK.equals(msg.getNamespaceURI())) {
- // TODO check and handle dailback result
- sessionStateHolder.setState(SessionState.AUTHENTICATED);
-
- LOG.info("XMPP server connector to {} authenticated using dialback", otherServer);
- authenticatedLatch.countDown();
- // connection established, start pinging
- startPinging();
- } else if(msg.getName().equals("verify") && NamespaceURIs.JABBER_SERVER_DIALBACK.equals(msg.getNamespaceURI())) {
- Entity originating = serverRuntimeContext.getServerEnitity();
- String type = msg.getAttributeValue("type");
-
- String resultType = "invalid";
- if("valid".equals(type)) {
- dialbackSessionStateHolder.setState(SessionState.AUTHENTICATED);
- dialbackSessionContext.setInitiatingEntity(otherServer);
- resultType = "valid";
+ if(sessionStateHolder.getState() == SessionState.AUTHENTICATED) {
+ LOG.info("XMPP server connector to {} authenticated", otherServer);
+ authenticatedLatch.countDown();
+
+ // connection established, start pinging
+ startPinging();
}
+ // none of the handlers matched, stream start is handled separately
+ } else if(stanza.getName().equals("stream")) {
+ sessionContext.setSessionId(stanza.getAttributeValue("id"));
+ sessionContext.setInitiatingEntity(stanza.getFrom());
- // <db:result xmlns:db="jabber:server:dialback" to="xmpp.protocol7.com" from="jabber.org" type="valid"></db:result>
- StanzaBuilder builder = new StanzaBuilder("result", NamespaceURIs.JABBER_SERVER_DIALBACK, "db");
- builder.addAttribute("from", originating.getDomain());
- builder.addAttribute("to", otherServer.getDomain());
- builder.addAttribute("type", resultType);
-
- dialbackSessionContext.write(builder.build());
-
- // close this session as we are now done checking dialback
- close();
+ if(dialbackSessionContext != null) {
+ // connector is being used for dialback verification, don't do further authentication
+ sessionContext.putAttribute("DIALBACK_SESSION_CONTEXT", dialbackSessionContext);
+ sessionContext.putAttribute("DIALBACK_SESSION_STATE_HOLDER", dialbackSessionStateHolder);
+
+ sessionContext.setInitiatingEntity(stanza.getFrom());
+ sessionStateHolder.setState(SessionState.AUTHENTICATED);
+ authenticatedLatch.countDown();
+ }
} else {
// TODO other stanzas coming here?
}
+ } else {
+ throw new RuntimeException("Only handles SSL events and stanzas");
}
}
- private boolean startTlsSupported(Stanza stanza) {
- return !stanza.getInnerElementsNamed("starttls", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS).isEmpty();
- }
-
- private boolean dialbackSupported(Stanza stanza) {
- // TODO check for dialback namespace
- return !stanza.getInnerElementsNamed("dialback", NamespaceURIs.URN_XMPP_FEATURES_DIALBACK).isEmpty();
- }
-
@Override
public void sessionClosed(IoSession session) throws Exception {
// Socket was closed, make sure we close the connector
@@ -313,6 +285,4 @@ public class DefaultXMPPServerConnector
pingModule.ping(DefaultXMPPServerConnector.this, serverRuntimeContext.getServerEnitity(), otherServer, pingTimeout, DefaultXMPPServerConnector.this);
}
}
-
-
}
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnectorRegistry.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnectorRegistry.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnectorRegistry.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/DefaultXMPPServerConnectorRegistry.java Mon Jan 3 10:17:12 2011
@@ -24,14 +24,6 @@ public class DefaultXMPPServerConnectorR
*/
@SpecCompliant(spec = "draft-ietf-xmpp-3920bis-22", section = "10.4", status = SpecCompliant.ComplianceStatus.IN_PROGRESS, coverage = SpecCompliant.ComplianceCoverage.COMPLETE)
public synchronized XMPPServerConnector connect(Entity server) throws RemoteServerNotFoundException, RemoteServerTimeoutException {
- return connect(server, null, null);
- }
-
- public synchronized XMPPServerConnector connectForDialback(Entity server, SessionContext orginalSessionContext, SessionStateHolder originalSessionStateHolder) throws RemoteServerNotFoundException, RemoteServerTimeoutException {
- return connect(server, orginalSessionContext, originalSessionStateHolder);
- }
-
- private XMPPServerConnector connect(Entity server, SessionContext dialbackSessionContext, SessionStateHolder dialbackSessionStateHolder) throws RemoteServerNotFoundException, RemoteServerTimeoutException {
DefaultXMPPServerConnector connector = connectors.get(server);
if(connector != null && connector.isClosed()) {
@@ -40,18 +32,21 @@ public class DefaultXMPPServerConnectorR
}
if(connector == null) {
- connector = new DefaultXMPPServerConnector(server, serverRuntimeContext, dialbackSessionContext, dialbackSessionStateHolder);
+ connector = new DefaultXMPPServerConnector(server, serverRuntimeContext, null, null);
connector.start();
- // only register if we're not starting a connector for dialback
- if(dialbackSessionContext == null) {
- connectors.put(server, connector);
- }
+ connectors.put(server, connector);
}
return connector;
}
-
+
+ public synchronized XMPPServerConnector connectForDialback(Entity server, SessionContext orginalSessionContext, SessionStateHolder originalSessionStateHolder) throws RemoteServerNotFoundException, RemoteServerTimeoutException {
+ DefaultXMPPServerConnector connector = new DefaultXMPPServerConnector(server, serverRuntimeContext, orginalSessionContext, originalSessionStateHolder);
+ connector.start();
+ return connector;
+ }
+
/* (non-Javadoc)
* @see org.apache.vysper.xmpp.server.s2s.XMPPServerConnectorRegistry#close()
*/
@@ -60,4 +55,6 @@ public class DefaultXMPPServerConnectorR
connector.close();
}
}
+
+
}
Added: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/FeaturesHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/FeaturesHandler.java?rev=1054572&view=auto
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/FeaturesHandler.java (added)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/FeaturesHandler.java Mon Jan 3 10:17:12 2011
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.vysper.xmpp.server.s2s;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DialbackIdGenerator;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainerImpl;
+import org.apache.vysper.xmpp.protocol.SessionStateHolder;
+import org.apache.vysper.xmpp.protocol.StanzaHandler;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.server.SessionState;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class FeaturesHandler implements StanzaHandler {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FeaturesHandler.class);
+
+ public String getName() {
+ return "features";
+ }
+
+ public boolean verify(Stanza stanza) {
+ if (stanza == null) return false;
+ if (!getName().equals(stanza.getName())) return false;
+ String namespaceURI = stanza.getNamespaceURI();
+ if (namespaceURI == null) return false;
+ return namespaceURI.equals(NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS);
+ }
+
+ public boolean isSessionRequired() {
+ return true;
+ }
+
+ public ResponseStanzaContainer execute(Stanza stanza, ServerRuntimeContext serverRuntimeContext,
+ boolean isOutboundStanza, SessionContext sessionContext, SessionStateHolder sessionStateHolder) {
+ if(sessionStateHolder.getState() != SessionState.AUTHENTICATED) {
+ Entity otherServer = sessionContext.getInitiatingEntity();
+
+ if(startTlsSupported(stanza) && serverRuntimeContext.getSslContext() != null) {
+ // remote server support TLS and we got keys set up
+ LOG.info("XMPP server connector to {} is starting TLS", otherServer);
+ Stanza startTlsStanza = new StanzaBuilder("starttls", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS).build();
+
+ return new ResponseStanzaContainerImpl(startTlsStanza);
+ } else if(dialbackSupported(stanza)) {
+ Entity originating = serverRuntimeContext.getServerEnitity();
+
+ String dailbackId = new DialbackIdGenerator().generate(otherServer, originating, sessionContext.getSessionId());
+
+ Stanza dbResult = new StanzaBuilder("result", NamespaceURIs.JABBER_SERVER_DIALBACK, "db")
+ .addAttribute("from", originating.getDomain())
+ .addAttribute("to", otherServer.getDomain())
+ .addText(dailbackId)
+ .build();
+
+ return new ResponseStanzaContainerImpl(dbResult);
+ } else {
+ // TODO how to handle
+ throw new RuntimeException("Unsupported features");
+ }
+ }
+
+ return null;
+ }
+
+ private boolean startTlsSupported(Stanza stanza) {
+ return !stanza.getInnerElementsNamed("starttls", NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS).isEmpty();
+ }
+
+ private boolean dialbackSupported(Stanza stanza) {
+ return !stanza.getInnerElementsNamed("dialback", NamespaceURIs.URN_XMPP_FEATURES_DIALBACK).isEmpty();
+ }
+
+
+}
Added: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/TlsProceedHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/TlsProceedHandler.java?rev=1054572&view=auto
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/TlsProceedHandler.java (added)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/TlsProceedHandler.java Mon Jan 3 10:17:12 2011
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.vysper.xmpp.server.s2s;
+
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
+import org.apache.vysper.xmpp.protocol.SessionStateHolder;
+import org.apache.vysper.xmpp.protocol.StanzaHandler;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.server.SessionState;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class TlsProceedHandler implements StanzaHandler {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TlsProceedHandler.class);
+
+ public String getName() {
+ return "proceed";
+ }
+
+ public boolean verify(Stanza stanza) {
+ if (stanza == null) return false;
+ if (!getName().equals(stanza.getName())) return false;
+ String namespaceURI = stanza.getNamespaceURI();
+ if (namespaceURI == null) return false;
+ return namespaceURI.equals(NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_TLS);
+ }
+
+ public boolean isSessionRequired() {
+ return true;
+ }
+
+ public ResponseStanzaContainer execute(Stanza stanza, ServerRuntimeContext serverRuntimeContext,
+ boolean isOutboundStanza, SessionContext sessionContext, SessionStateHolder sessionStateHolder) {
+ sessionStateHolder.setState(SessionState.ENCRYPTION_STARTED);
+
+ LOG.debug("XMPP server connector switching to TLS");
+ sessionContext.switchToTLS(false, true);
+
+ return null;
+ }
+}
Modified: mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/XMPPServerConnectorRegistry.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/XMPPServerConnectorRegistry.java?rev=1054572&r1=1054571&r2=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/XMPPServerConnectorRegistry.java (original)
+++ mina/vysper/branches/s2s/server/core/src/main/java/org/apache/vysper/xmpp/server/s2s/XMPPServerConnectorRegistry.java Mon Jan 3 10:17:12 2011
@@ -14,7 +14,6 @@ public interface XMPPServerConnectorRegi
XMPPServerConnector connectForDialback(Entity server, SessionContext sessionContext, SessionStateHolder sessionStateHolder) throws RemoteServerNotFoundException,
RemoteServerTimeoutException;
-
void close();
}
\ No newline at end of file
Added: mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandlerTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandlerTestCase.java?rev=1054572&view=auto
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandlerTestCase.java (added)
+++ mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DbVerifyHandlerTestCase.java Mon Jan 3 10:17:12 2011
@@ -0,0 +1,63 @@
+package org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.mockito.Mockito;
+
+
+public class DbVerifyHandlerTestCase extends TestCase {
+
+ private static final Entity FROM = EntityImpl.parseUnchecked("from.org");
+ private static final Entity TO = EntityImpl.parseUnchecked("to.org");
+ private static final String ID = "D60000229F";
+
+ private DbVerifyHandler handler = new DbVerifyHandler();
+
+ public void testVerify() {
+ Stanza correct = new StanzaBuilder("verify", NamespaceURIs.JABBER_SERVER_DIALBACK).build();
+ Stanza invalidNamespace = new StanzaBuilder("verify", "dummy").build();
+ Stanza invalidName = new StanzaBuilder("dummy", NamespaceURIs.JABBER_SERVER_DIALBACK).build();
+
+ Assert.assertTrue(handler.verify(correct));
+ Assert.assertFalse(handler.verify(invalidNamespace));
+ Assert.assertFalse(handler.verify(invalidName));
+ }
+
+ public void testExecuteValidVerification() {
+ String token = new DialbackIdGenerator().generate(FROM, TO, ID);
+ assertExecuteVerification(token, "valid");
+ }
+
+ public void testExecuteInvalidVerification() {
+ assertExecuteVerification("12345", "invalid");
+ }
+
+ private void assertExecuteVerification(String token, String expectedType) {
+ ServerRuntimeContext serverRuntimeContext = Mockito.mock(ServerRuntimeContext.class);
+ Mockito.when(serverRuntimeContext.getServerEnitity()).thenReturn(TO);
+
+ Stanza stanza = new StanzaBuilder("verify", NamespaceURIs.JABBER_SERVER_DIALBACK)
+ .addAttribute("from", FROM.getFullQualifiedName())
+ .addAttribute("to", TO.getFullQualifiedName())
+ .addAttribute("id", ID)
+ .addText(token)
+ .build();
+
+ Stanza response = handler.execute(stanza, serverRuntimeContext, false, null, null).getResponseStanza();
+
+ Assert.assertNotNull(response);
+ Assert.assertEquals(TO, response.getFrom());
+ Assert.assertEquals(FROM, response.getTo());
+ Assert.assertEquals(ID, response.getAttributeValue("id"));
+ Assert.assertEquals(expectedType, response.getAttributeValue("type"));
+ }
+
+
+
+}
Copied: mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTestCase.java (from r1054458, mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTest.java)
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTestCase.java?p2=mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTestCase.java&p1=mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTest.java&r1=1054458&r2=1054572&rev=1054572&view=diff
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTest.java (original)
+++ mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0220_server_dailback/DialbackIdGeneratorTestCase.java Mon Jan 3 10:17:12 2011
@@ -7,7 +7,7 @@ import org.apache.vysper.xmpp.addressing
import org.apache.vysper.xmpp.modules.extension.xep0220_server_dailback.DialbackIdGenerator;
-public class DialbackIdGeneratorTest extends TestCase {
+public class DialbackIdGeneratorTestCase extends TestCase {
private Entity receiving = EntityImpl.parseUnchecked("xmpp.example.com");
private Entity originating = EntityImpl.parseUnchecked("example.org");
Added: mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/server/s2s/Server2Server.java
URL: http://svn.apache.org/viewvc/mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/server/s2s/Server2Server.java?rev=1054572&view=auto
==============================================================================
--- mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/server/s2s/Server2Server.java (added)
+++ mina/vysper/branches/s2s/server/core/src/test/java/org/apache/vysper/xmpp/server/s2s/Server2Server.java Mon Jan 3 10:17:12 2011
@@ -0,0 +1,133 @@
+package org.apache.vysper.xmpp.server.s2s;
+import java.io.File;
+
+import org.apache.vysper.mina.TCPEndpoint;
+import org.apache.vysper.storage.StorageProviderRegistry;
+import org.apache.vysper.storage.inmemory.MemoryStorageProviderRegistry;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.authorization.AccountManagement;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.XMPPServer;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Packet;
+
+
+public class Server2Server {
+
+ public static void main(String[] args) throws Exception {
+ Entity localServer = EntityImpl.parseUnchecked(args[0]);
+ Entity localUser = EntityImpl.parseUnchecked(args[1]);
+ Entity remoteServer = EntityImpl.parseUnchecked(args[2]);
+ Entity remoteUser = EntityImpl.parseUnchecked(args[3]);
+ String remotePassword = args[4];
+
+ String keystorePath;
+ String keystorePassword;
+ if(args.length > 5) {
+ keystorePath = args[5];
+ keystorePassword = args[6];
+ } else {
+ keystorePath = "src/main/config/bogus_mina_tls.cert";
+ keystorePassword = "boguspw";
+ }
+
+ XMPPServer server = new XMPPServer(localServer.getDomain());
+
+ StorageProviderRegistry providerRegistry = new MemoryStorageProviderRegistry();
+ final AccountManagement accountManagement = (AccountManagement) providerRegistry
+ .retrieve(AccountManagement.class);
+
+ if (!accountManagement.verifyAccountExists(localUser)) {
+ accountManagement.addUser(localUser.getFullQualifiedName(), "password1");
+ }
+
+ // S2S endpoint
+ TCPEndpoint s2sEndpoint = new TCPEndpoint();
+ s2sEndpoint.setPort(5269);
+ server.addEndpoint(s2sEndpoint);
+
+ // C2S endpoint
+ server.addEndpoint(new TCPEndpoint());
+
+ server.setStorageProviderRegistry(providerRegistry);
+ server.setTLSCertificateInfo(new File(keystorePath), keystorePassword);
+
+ server.start();
+
+ // enable server connection to use ping
+ //server.addModule(new XmppPingModule());
+
+ ServerRuntimeContext serverRuntimeContext = server.getServerRuntimeContext();
+
+ Thread.sleep(2000);
+
+// XMPPServerConnectorRegistry registry = serverRuntimeContext.getServerConnectorRegistry();
+//
+// XMPPServerConnector connector = registry.getConnector(remoteServer);
+//
+// Stanza stanza = new StanzaBuilder("message", NamespaceURIs.JABBER_SERVER)
+// .addAttribute("from", localUser.getFullQualifiedName())
+// .addAttribute("to", remoteUser.getFullQualifiedName())
+// .startInnerElement("body", NamespaceURIs.JABBER_SERVER)
+// .addText("Hello world")
+// .endInnerElement()
+// .build();
+//
+// connector.write(stanza);
+
+ ConnectionConfiguration localConnectionConfiguration = new ConnectionConfiguration("localhost", 5222);
+ localConnectionConfiguration.setKeystorePath(keystorePath);
+ localConnectionConfiguration.setTruststorePath(keystorePath);
+ localConnectionConfiguration.setTruststorePassword(keystorePassword);
+ XMPPConnection localClient = new XMPPConnection(localConnectionConfiguration);
+
+ localClient.connect();
+ localClient.login(localUser.getNode(), "password1");
+ localClient.addPacketListener(new PacketListener() {
+ public void processPacket(Packet packet) {
+ System.out.println("# " + packet);
+ }
+ }, new PacketFilter() {
+ public boolean accept(Packet arg0) {
+ return true;
+ }
+ });
+
+
+ ConnectionConfiguration remoteConnectionConfiguration = new ConnectionConfiguration(remoteServer.getFullQualifiedName(), 5222);
+ remoteConnectionConfiguration.setKeystorePath(keystorePath);
+ remoteConnectionConfiguration.setTruststorePath(keystorePath);
+ remoteConnectionConfiguration.setTruststorePassword(keystorePassword);
+ XMPPConnection remoteClient = new XMPPConnection(remoteConnectionConfiguration);
+
+ remoteClient.connect();
+ remoteClient.login(remoteUser.getNode(), remotePassword);
+
+ Thread.sleep(3000);
+
+ Message msg = new Message(remoteUser.getFullQualifiedName());
+// Message msg = new Message(localUser.getFullQualifiedName());
+ msg.setBody("Hello world");
+
+ localClient.sendPacket(msg);
+// remoteClient.sendPacket(msg);
+
+
+ Thread.sleep(8000);
+ remoteClient.disconnect();
+ localClient.disconnect();
+
+ Thread.sleep(50000);
+
+ server.stop();
+ }
+
+}