Author: [email protected]
Date: Wed May 23 14:49:52 2012
New Revision: 2387

Log:
[AMDATUAUTH-157] Disabled nonce validation

Added:
   branches/amdatu-auth-0.2.2/oauth-server/src/test/
   branches/amdatu-auth-0.2.2/oauth-server/src/test/java/
   branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/
   branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/
   branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/
   branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/
   
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/
   
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/
   
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/
   
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/OAuthNonceStorageProviderMock.java
   
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/OAuthServerTest.java
Modified:
   
branches/amdatu-auth-0.2.2/oauth-server/src/main/java/org/amdatu/auth/oauth/server/service/PluggableOAuthValidator.java

Modified: 
branches/amdatu-auth-0.2.2/oauth-server/src/main/java/org/amdatu/auth/oauth/server/service/PluggableOAuthValidator.java
==============================================================================
--- 
branches/amdatu-auth-0.2.2/oauth-server/src/main/java/org/amdatu/auth/oauth/server/service/PluggableOAuthValidator.java
     (original)
+++ 
branches/amdatu-auth-0.2.2/oauth-server/src/main/java/org/amdatu/auth/oauth/server/service/PluggableOAuthValidator.java
     Wed May 23 14:49:52 2012
@@ -174,7 +174,12 @@
         long timestamp = 
Long.parseLong(message.getParameter(OAuth.OAUTH_TIMESTAMP));
         long now = currentTimeMsec();
         validateTimestamp(message, timestamp, now);
-        validateNonce(message, timestamp, now);
+
+        // FIXME: due to AMDATUAUTH-157 the nonce validation is disabled for 
now. It requires
+        // more refactoring and an API change, therefore the fix is postponed 
to at least 0.3.0
+        // Note that leaving out the nonce validation causes a (minor) 
vulnerability to replay attacks,
+        // but because of this issue the nonce validation has never worked.
+        // validateNonce(message, timestamp, now);
     }
 
     /** Throw an exception if the timestamp [sec] is out of range. */
@@ -205,7 +210,7 @@
         // consumer or using a different token will never result in a nonce 
conflict (which could happen
         // if they use the same nonce by coincidence)
         String[] requestParams = new String[] {message.getConsumerKey(), 
message.getToken()};
-        boolean valid = m_nonceStore.addNonce(currentTimeMsec, nonce, 
requestParams);
+        boolean valid = m_nonceStore.addNonce(timestamp, nonce, requestParams);
         if (!valid) {
             throw new OAuthProblemException(OAuth.Problems.NONCE_USED);
         }

Added: 
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/OAuthNonceStorageProviderMock.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/OAuthNonceStorageProviderMock.java
     Wed May 23 14:49:52 2012
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010-2012 The Amdatu Foundation
+ *
+ * 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.amdatu.auth.test.unit.oauth.server;
+
+import org.amdatu.auth.oauth.server.OAuthNonceStorageProvider;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class OAuthNonceStorageProviderMock implements 
OAuthNonceStorageProvider {
+
+    private final Set<UsedNonce> m_usedNonces = new TreeSet<UsedNonce>();
+
+    public boolean addNonce(long timestamp, String nonce, String[] 
requestParams) {
+        String[] nonceEtc;
+        if (requestParams != null) {
+            nonceEtc = new String[requestParams.length + 1];
+        }
+        else {
+            nonceEtc = new String[1];
+        }
+        nonceEtc[0] = nonce;
+        if (requestParams != null) {
+            for (int i = 0; i < requestParams.length; i++) {
+                nonceEtc[i + 1] = requestParams[i];
+            }
+        }
+        UsedNonce usedNonce = new UsedNonce(timestamp, nonceEtc);
+        return m_usedNonces.add(usedNonce);
+    }
+
+    public void removeExpiredNonces(long timestamp) {
+        UsedNonce min = new UsedNonce(timestamp, new String[0]);
+        synchronized (m_usedNonces) {
+            // Because usedNonces is a TreeSet, its iterator produces
+            // elements from oldest to newest (their natural order).
+            for (Iterator<UsedNonce> iter = m_usedNonces.iterator(); 
iter.hasNext();) {
+                UsedNonce used = iter.next();
+                if (min.compareTo(used) <= 0) {
+                    break; // all the rest are also new enough
+                }
+                iter.remove(); // too old
+            }
+        }
+    }
+
+    /**
+     * Selected parameters from an OAuth request, in a form suitable for
+     * detecting duplicate requests. The implementation is optimized for the
+     * comparison operations (compareTo, equals and hashCode).
+     * 
+     * @author John Kristian
+     */
+    private static class UsedNonce implements Comparable<UsedNonce> {
+        private static final String ENCODING = "UTF-8";
+
+        private final String m_sortKey;
+
+        /**
+         * Construct an object containing the given timestamp, nonce and other
+         * parameters. The order of parameters is significant.
+         */
+        UsedNonce(final long timestamp, final String[] nonceEtc) {
+            StringBuilder key = new StringBuilder(String.format("%20d", 
Long.valueOf(timestamp)));
+            // The blank padding ensures that timestamps are compared as 
numbers.
+            for (String etc : nonceEtc) {
+                key.append("&");
+                if (etc == null) {
+                    key.append(" ");
+                }
+                else {
+                    key.append(percentEncode(etc));
+                }
+                // A null value is different from "" or any other String.
+            }
+            m_sortKey = key.toString();
+        }
+
+        private static String percentEncode(final String s) {
+            if (s == null) {
+                return "";
+            }
+            try {
+                return URLEncoder.encode(s, ENCODING)
+                    // OAuth encodes some characters differently:
+                    .replace("+", "%20").replace("*", "%2A")
+                    .replace("%7E", "~");
+                // This could be done faster with more hand-crafted code.
+            }
+            catch (UnsupportedEncodingException wow) {
+                throw new RuntimeException(wow.getMessage(), wow);
+            }
+        }
+
+        /**
+         * Determine the relative order of <code>this</code> and
+         * <code>that</code>, as specified by Comparable. The timestamp is most
+         * significant; that is, if the timestamps are different, return 1 or
+         * -1. If <code>this</code> contains only a timestamp (with no nonce
+         * etc.), return -1 or 0. The treatment of the nonce etc. is murky,
+         * although 0 is returned only if they're all equal.
+         */
+        public int compareTo(final UsedNonce that) {
+            if (that == null) {
+                return 1;
+            }
+            else {
+                return m_sortKey.compareTo(that.m_sortKey);
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return m_sortKey.hashCode();
+        }
+
+        /**
+         * Return true iff <code>this</code> and <code>that</code> contain 
equal
+         * timestamps, nonce etc., in the same order.
+         */
+        @Override
+        public boolean equals(final Object that) {
+            if (that == null) {
+                return false;
+            }
+            if (that == this) {
+                return true;
+            }
+            if (that.getClass() != getClass()) {
+                return false;
+            }
+            return m_sortKey.equals(((UsedNonce) that).m_sortKey);
+        }
+
+        @Override
+        public String toString() {
+            return m_sortKey;
+        }
+    }
+}

Added: 
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/OAuthServerTest.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-auth-0.2.2/oauth-server/src/test/java/org/amdatu/auth/test/unit/oauth/server/OAuthServerTest.java
   Wed May 23 14:49:52 2012
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010-2012 The Amdatu Foundation
+ *
+ * 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.amdatu.auth.test.unit.oauth.server;
+
+import net.oauth.OAuthConsumer;
+import net.oauth.OAuthException;
+import net.oauth.OAuthMessage;
+import net.oauth.OAuthServiceProvider;
+
+import org.amdatu.auth.oauth.api.OAuthAccessor;
+import org.amdatu.auth.oauth.server.service.PluggableOAuthValidator;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class OAuthServerTest {
+    private static final String REQUEST_TOKEN_URL = 
"http://test.nl/requestToken";;
+    private static final String AUTHORIZE_TOKEN_URL = 
"http://test.nl/authorizeToken";;
+    private static final String ACCESS_TOKEN_URL = 
"http://test.nl/accessToken";;
+    private static final String CONSUMER_KEY = "example_consumer_key";
+    private static final String CONSUMER_SECRET = "r01Bh0KuXWXx9AAwbLVtN8B";
+    private static final String CALLBACK_URL = null;
+
+    @BeforeClass
+    public static void setUpOnce() throws OAuthException, IOException, 
URISyntaxException {
+        OAuthServiceProvider provider =
+            new OAuthServiceProvider(REQUEST_TOKEN_URL, AUTHORIZE_TOKEN_URL, 
ACCESS_TOKEN_URL);
+        OAuthConsumer consumer = new OAuthConsumer(CALLBACK_URL, CONSUMER_KEY, 
CONSUMER_SECRET, provider);
+        OAuthAccessor accessor = new OAuthAccessor(consumer);
+        OAuthMessage message = accessor.newRequestMessage(OAuthMessage.GET, 
"http://test.nl";, null);
+        PluggableOAuthValidator validator = new PluggableOAuthValidator(new 
OAuthNonceStorageProviderMock());
+
+        // Validate twice within the same millisec should not fail, see 
AMDATUAUTH-157.
+        // However, we need more refactoring to resolve this issue and 
therefore this test is disabled for now
+        validator.validateMessage(message, accessor);
+        // validator.validateMessage(message, accessor);
+
+        // Manipulate the request and try again, this should result in an 
invalid signature
+        message.addParameter("key", "value");
+        try {
+            validator.validateMessage(message, accessor);
+            Assert.fail("Manipulation of http request does not result in an 
invalid signature");
+        }
+        catch (OAuthException e) {
+            // Expected result
+        }
+
+        // Trigger the same request again
+    }
+
+    @Before
+    public void setUp() {
+
+    }
+
+    @Test
+    public void testRobustness() {
+
+    }
+}
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to