You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by be...@apache.org on 2008/06/06 20:54:44 UTC

svn commit: r664077 - in /labs/vysper/src: main/java/org/apache/vysper/xmpp/addressing/stringprep/ main/java/org/apache/vysper/xmpp/protocol/ main/java/org/apache/vysper/xmpp/stanza/ test/java/org/apache/vysper/xmpp/protocol/

Author: berndf
Date: Fri Jun  6 11:54:44 2008
New Revision: 664077

URL: http://svn.apache.org/viewvc?rev=664077&view=rev
Log:
[vysper] basic FROM checks for every stanza

Modified:
    labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ResponseWriter.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/Stanza.java
    labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/XMPPCoreStanza.java
    labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/CallTestStanzaHandler.java
    labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/ProtocolWorkerProcessTestCase.java

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/addressing/stringprep/NodePrep.java Fri Jun  6 11:54:44 2008
@@ -43,8 +43,7 @@
 	protected Map<String, String> buildMapping() {
 		Map<String, String> mapping = new HashMap<String, String>();
 		mapping.putAll(StringPrepConstants.B_1_CommonlyMappedtoNothing);
-		mapping
-				.putAll(StringPrepConstants.B_2_MappingForCaseFoldingUsedWithKFC);
+		mapping.putAll(StringPrepConstants.B_2_MappingForCaseFoldingUsedWithKFC);
 
 		return mapping;
 	}

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ProtocolWorker.java Fri Jun  6 11:54:44 2008
@@ -35,6 +35,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.List;
 
 /**
  * responsible for high-level XMPP protocol logic.
@@ -117,18 +118,33 @@
 
         // make sure that 'from' (if present) matches the bare authorized entity
         // else repond with a stanza error 'unknown-sender'
-        // see rfc3920_draft-saintandre-rfc3920bis-04.txt 8.5.4
-        if (sessionContext.getInitiatingEntity() != null) {
-            XMPPCoreStanza coreStanza = XMPPCoreStanza.getWrapper(stanza);
-            if (coreStanza != null && coreStanza.getFrom() != null) {
-                Entity from = coreStanza.getFrom().getBareJID();
-                Entity initiatingEntity = sessionContext.getInitiatingEntity();
-                if (!initiatingEntity.equals(from)) {
-                    responseWriter.handleWrongFromJID(sessionContext, coreStanza);
-                    return;
-                }
+        // see rfc3920_draft-saintandre-rfc3920bis-04.txt#8.5.4
+        Entity from = stanza.getFrom();
+        if (from != null && sessionContext.getInitiatingEntity() != null) {
+            Entity fromBare = from.getBareJID();
+            Entity initiatingEntity = sessionContext.getInitiatingEntity();
+            if (!initiatingEntity.equals(fromBare)) {
+                responseWriter.handleWrongFromJID(sessionContext, stanza);
+                return;
+            }
+        }
+        // make sure that there is a bound resource entry for that from's resource id attribute!
+        if (from != null && from.getResource() != null) {
+            List<String> boundResources = sessionContext.getServerRuntimeContext().getResourceRegistry().getBoundResources(from, false);
+            if (boundResources.size() == 0) {
+                responseWriter.handleWrongFromJID(sessionContext, stanza);
+                return;
+            }
+        }
+        // make sure that there is a full from entity given in cases where more than one resource is bound 
+        // in the same session.  
+        // see rfc3920_draft-saintandre-rfc3920bis-04.txt#8.5.4
+        if (from != null && from.getResource() == null) {
+            List<String> boundResources = sessionContext.getServerRuntimeContext().getResourceRegistry().getResourcesForSession(sessionContext);
+            if (boundResources.size() > 1) {
+                responseWriter.handleWrongFromJID(sessionContext, stanza);
+                return;
             }
-            
         }
 
         stateAwareProtocolWorker.processStanza(sessionContext, sessionStateHolder,

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ResponseWriter.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ResponseWriter.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ResponseWriter.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/protocol/ResponseWriter.java Fri Jun  6 11:54:44 2008
@@ -92,9 +92,15 @@
         writeErrorAndClose(sessionContext, errorStanza);
     }
 
-    public void handleWrongFromJID(SessionContext sessionContext, XMPPCoreStanza receivedStanza) {
+    public void handleWrongFromJID(SessionContext sessionContext, Stanza receivedStanza) {
+        XMPPCoreStanza receivedCoreStanza = XMPPCoreStanza.getWrapper(receivedStanza);
+        if (receivedCoreStanza == null) {
+            handleNotAuthorized(sessionContext, receivedStanza);
+            return;
+        } 
+        
         Stanza errorStanza = ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.UNKNOWN_SENDER,
-                                                          receivedStanza,
+                                                          receivedCoreStanza,
                                                           StanzaErrorType.MODIFY,
                                                           "from attribute does not match authorized entity",
                                                           null, null);

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/Stanza.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/Stanza.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/Stanza.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/Stanza.java Fri Jun  6 11:54:44 2008
@@ -20,6 +20,9 @@
 import org.apache.vysper.xmpp.xmlfragment.Attribute;
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 import org.apache.vysper.xmpp.xmlfragment.XMLFragment;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.addressing.EntityFormatException;
 
 import java.util.List;
 
@@ -46,4 +49,25 @@
     }
 
 
+    public Entity getTo() {
+        return parseEntityAttribute("to");
+    }
+
+    public Entity getFrom() {
+        return parseEntityAttribute("from");
+    }
+
+    public Entity parseEntityAttribute(String attributeName) {
+        boolean isPresent = getVerifier().attributePresent(attributeName);
+        EntityImpl entity = null;
+        if (isPresent) {
+            String attributeValue = getAttribute(attributeName).getValue();
+            try {
+                entity = EntityImpl.parse(attributeValue);
+            } catch (EntityFormatException e) {
+                return null;
+            }
+        }
+        return entity;
+    }
 }

Modified: labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/XMPPCoreStanza.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/XMPPCoreStanza.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/XMPPCoreStanza.java (original)
+++ labs/vysper/src/main/java/org/apache/vysper/xmpp/stanza/XMPPCoreStanza.java Fri Jun  6 11:54:44 2008
@@ -55,14 +55,6 @@
     }
 
     abstract public String getName();
-    
-    public Entity getTo() {
-        return getEntity("to");
-    }
-
-    public Entity getFrom() {
-        return getEntity("from");
-    }
 
     public String getType() {
         return getVerifier().attributePresent("type") ? getAttribute("type").getValue() : null;
@@ -80,21 +72,5 @@
         return getNamespace().equals(NamespaceURIs.JABBER_SERVER);
     }
 
-    private EntityImpl getEntity(String attributeName) {
-        boolean isPresent = getVerifier().attributePresent(attributeName);
-        EntityImpl entity = null;
-        if (isPresent) {
-            String attributeValue = getAttribute(attributeName).getValue();
-            try {
-                entity = EntityImpl.parse(attributeValue);
-            } catch (EntityFormatException e) {
-                return null;
-            }
-        }
-        return entity;
-    }
-
-
-
 
 }

Modified: labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/CallTestStanzaHandler.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/CallTestStanzaHandler.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/CallTestStanzaHandler.java (original)
+++ labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/CallTestStanzaHandler.java Fri Jun  6 11:54:44 2008
@@ -19,6 +19,7 @@
 
 import org.apache.vysper.xmpp.server.SessionContext;
 import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 
 public class CallTestStanzaHandler implements StanzaHandler {
     private boolean handlerCalled = false;
@@ -43,8 +44,19 @@
     public boolean verify(Stanza stanza) {
         verifyCalled = true;
         if (name != null && !name.equals(stanza.getName())) return false;
-        if (namespaceURI != null && !namespaceURI.equals(stanza.getNamespace())) return false;
-        return true;
+        if (namespaceURI == null) return true;
+        
+        boolean elementNamespaceMatches = false;
+        if (namespaceURI != null && namespaceURI.equals(stanza.getNamespace())) elementNamespaceMatches = true;
+        
+        boolean outerNamespaceMatches = false;
+        boolean innerNamespaceMatches = false;
+        if (namespaceURI != null && namespaceURI.equals(stanza.getVerifier().getUniqueXMLNSValue())) outerNamespaceMatches = true;
+        XMLElement firstInnerElement = stanza.getFirstInnerElement();
+        if (firstInnerElement != null) {
+            if (namespaceURI != null && namespaceURI.equals(firstInnerElement.getVerifier().getUniqueXMLNSValue())) innerNamespaceMatches = true;
+        }
+        return elementNamespaceMatches || outerNamespaceMatches || innerNamespaceMatches;
     }
 
     public boolean isVerifyCalled() {
@@ -66,5 +78,6 @@
 
     public void assertHandlerCalled() {
         if (!handlerCalled) throw new RuntimeException("handler not called");
+        handlerCalled = false;
     }
 }

Modified: labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/ProtocolWorkerProcessTestCase.java
URL: http://svn.apache.org/viewvc/labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/ProtocolWorkerProcessTestCase.java?rev=664077&r1=664076&r2=664077&view=diff
==============================================================================
--- labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/ProtocolWorkerProcessTestCase.java (original)
+++ labs/vysper/src/test/java/org/apache/vysper/xmpp/protocol/ProtocolWorkerProcessTestCase.java Fri Jun  6 11:54:44 2008
@@ -31,6 +31,7 @@
 import org.apache.vysper.xmpp.xmlfragment.XMLElement;
 import org.apache.vysper.xmpp.xmlfragment.XMLSemanticError;
 import org.apache.vysper.xmpp.delivery.StanzaReceiverRelay;
+import org.apache.vysper.xmpp.resourcebinding.BindException;
 import junit.framework.TestCase;
 
 /**
@@ -154,16 +155,18 @@
         assertTrue("closed", sessionContext.isClosed());
     }
 
-    public void testTrackProperFromAddress() throws XMLSemanticError {
+    public void testDetectWrongFromAddress() throws XMLSemanticError {
 
         Entity server = sessionContext.getServerRuntimeContext().getServerEnitity();
         sessionContext.setSessionState(SessionState.AUTHENTICATED);
+        // the session is running for 'mark'
         sessionContext.setInitiatingEntity(new EntityImpl("mark", server.getDomain(), null));
 
-        CallTestStanzaHandler stanzaHandler = new CallTestStanzaHandler("ProtocolWorkerProcessTestCase");
+        CallTestStanzaHandler stanzaHandler = new CallTestStanzaHandler("iq");
         namespaceHandlerDictionary.register(stanzaHandler);
 
         StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(IQStanzaType.GET, "test");
+        // we set a different from user name 'ernest'!
         stanzaBuilder.addAttribute("from", new EntityImpl("ernest", server.getDomain(), null).getFullQualifiedName());
         stanzaBuilder.startInnerElement("query").addNamespaceAttribute("jabber:iq:roster").endInnerElement();
         
@@ -176,6 +179,107 @@
             // not called, OK
         }
         Stanza recordedResponse = sessionContext.getRecordedResponse();
+        assertUnknownSenderError(recordedResponse);
+    }
+
+    public void testAllowProperFromResourceId() throws XMLSemanticError, BindException {
+
+        Entity server = sessionContext.getServerRuntimeContext().getServerEnitity();
+        sessionContext.setSessionState(SessionState.AUTHENTICATED);
+        // the session is running for 'charlotte'
+        sessionContext.setInitiatingEntity(new EntityImpl("charlotte", server.getDomain(), null));
+
+        CallTestStanzaHandler stanzaHandler = new CallTestStanzaHandler("iq", "testNSURI");
+        namespaceHandlerDictionary.register(stanzaHandler);
+
+        String onlyBoundResource = sessionContext.bindResource();
+
+        StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(IQStanzaType.GET, "test");
+        stanzaBuilder.addAttribute("from", new EntityImpl("charlotte", server.getDomain(), onlyBoundResource).getFullQualifiedName());
+        stanzaBuilder.startInnerElement("query").addNamespaceAttribute("testNSURI").endInnerElement();
+        
+        protocolWorker.processStanza(sessionContext, stanzaBuilder.getFinalStanza(), sessionStateHolder);
+
+        stanzaHandler.assertHandlerCalled();
+    }
+
+    public void testDetectWrongFromResourceId() throws XMLSemanticError, BindException {
+
+        Entity server = sessionContext.getServerRuntimeContext().getServerEnitity();
+        sessionContext.setSessionState(SessionState.AUTHENTICATED);
+        // the session is running for 'charlotte'
+        sessionContext.setInitiatingEntity(new EntityImpl("charlotte", server.getDomain(), null));
+
+        CallTestStanzaHandler stanzaHandler = new CallTestStanzaHandler("iq", "testNSURI");
+        namespaceHandlerDictionary.register(stanzaHandler);
+
+        String onlyBoundResource = sessionContext.bindResource();
+        String arbitraryUnboundResource = "unboundResourceID";
+        
+        StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(IQStanzaType.GET, "test");
+        
+        stanzaBuilder.addAttribute("from", new EntityImpl("charlotte", server.getDomain(), arbitraryUnboundResource).getFullQualifiedName());
+        stanzaBuilder.startInnerElement("query").addNamespaceAttribute("testNSURI").endInnerElement();
+        
+        protocolWorker.processStanza(sessionContext, stanzaBuilder.getFinalStanza(), sessionStateHolder);
+
+        try {
+            stanzaHandler.assertHandlerCalled();
+            fail("handler called");
+        } catch (Exception e) {
+            // not called, OK
+        }
+        Stanza recordedResponse = sessionContext.getRecordedResponse();
+        assertUnknownSenderError(recordedResponse);
+    }
+
+    public void testAllowBareFromEntityOnlyOnSingleBoundResource() throws XMLSemanticError, BindException {
+        // from="client@vysper.org" is only allowed when a single resource is bound
+        // if there is more than one resource bound in the same session, from must come 
+        // fully qualified, e.g. from="client@vysper.org/resourceId"
+        
+        Entity server = sessionContext.getServerRuntimeContext().getServerEnitity();
+        sessionContext.setSessionState(SessionState.AUTHENTICATED);
+        // the session is running for 'lea'
+        sessionContext.setInitiatingEntity(new EntityImpl("lea", server.getDomain(), null));
+
+        CallTestStanzaHandler stanzaHandler = new CallTestStanzaHandler("iq", "testNSURI");
+        namespaceHandlerDictionary.register(stanzaHandler);
+
+        String firstBoundResource = sessionContext.bindResource();
+        String secondBoundResource = sessionContext.bindResource();
+
+        StanzaBuilder stanzaBuilder = StanzaBuilder.createIQStanza(IQStanzaType.GET, "test");
+        stanzaBuilder.addAttribute("from", new EntityImpl("lea", server.getDomain(), null).getFullQualifiedName());
+        stanzaBuilder.startInnerElement("query").addNamespaceAttribute("testNSURI").endInnerElement();
+        
+        protocolWorker.processStanza(sessionContext, stanzaBuilder.getFinalStanza(), sessionStateHolder);
+        Stanza recordedResponse = sessionContext.getRecordedResponse();
+        assertUnknownSenderError(recordedResponse); // not allowed, bare id without resource and two resources bound
+        sessionContext.write(null); // reset
+        
+        // unbind second resource, leaving only one
+        sessionContext.getServerRuntimeContext().getResourceRegistry().unbindResource(secondBoundResource);
+        
+        // bare id allowed, only one resource is bound
+        stanzaBuilder = StanzaBuilder.createIQStanza(IQStanzaType.GET, "test");
+        stanzaBuilder.addAttribute("from", new EntityImpl("lea", server.getDomain(), null).getFullQualifiedName());
+        stanzaBuilder.startInnerElement("query").addNamespaceAttribute("testNSURI").endInnerElement();
+        protocolWorker.processStanza(sessionContext, stanzaBuilder.getFinalStanza(), sessionStateHolder);
+        stanzaHandler.assertHandlerCalled();
+        sessionContext.write(null); // reset
+
+        // second resource is now invalid and cannot be used anymore in a full qualified entity
+        stanzaBuilder = StanzaBuilder.createIQStanza(IQStanzaType.GET, "test");
+        stanzaBuilder.addAttribute("from", new EntityImpl("lea", server.getDomain(), secondBoundResource).getFullQualifiedName());
+        stanzaBuilder.startInnerElement("query").addNamespaceAttribute("testNSURI").endInnerElement();
+        protocolWorker.processStanza(sessionContext, stanzaBuilder.getFinalStanza(), sessionStateHolder);
+        recordedResponse = sessionContext.getRecordedResponse();
+        assertUnknownSenderError(recordedResponse);
+        
+    }
+
+    private void assertUnknownSenderError(Stanza recordedResponse) throws XMLSemanticError {
         XMLElementVerifier verifier = recordedResponse.getVerifier();
         assertEquals("iq stanza error", "iq", recordedResponse.getName());
         IQStanza iqStanza = (IQStanza) XMPPCoreStanza.getWrapper(recordedResponse);



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org