Repository: knox
Updated Branches:
  refs/heads/master 834d64325 -> 6212381ec


KNOX-1171: Handle invalid hadoop.auth cookie returned by Oozie


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/6212381e
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/6212381e
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/6212381e

Branch: refs/heads/master
Commit: 6212381ec38e1e7ad18a6ffb30656a8fe3c742fd
Parents: 834d643
Author: Kevin Minder <[email protected]>
Authored: Tue Feb 6 09:27:28 2018 -0500
Committer: Kevin Minder <[email protected]>
Committed: Tue Feb 6 09:30:03 2018 -0500

----------------------------------------------------------------------
 .../apache/knox/gateway/SpiGatewayMessages.java |   5 +
 .../gateway/dispatch/HadoopAuthCookieStore.java | 115 ++++++++++++++++++-
 .../dispatch/HadoopAuthCookieStoreTest.java     |  73 ++++++++++++
 3 files changed, 191 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/6212381e/gateway-spi/src/main/java/org/apache/knox/gateway/SpiGatewayMessages.java
----------------------------------------------------------------------
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/SpiGatewayMessages.java 
b/gateway-spi/src/main/java/org/apache/knox/gateway/SpiGatewayMessages.java
index ddcc073..8718b1d 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/SpiGatewayMessages.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/SpiGatewayMessages.java
@@ -17,6 +17,7 @@
  */
 package org.apache.knox.gateway;
 
+import org.apache.http.cookie.Cookie;
 import org.apache.knox.gateway.i18n.messages.Message;
 import org.apache.knox.gateway.i18n.messages.MessageLevel;
 import org.apache.knox.gateway.i18n.messages.Messages;
@@ -73,4 +74,8 @@ public interface SpiGatewayMessages {
 
   @Message( level = MessageLevel.WARN, text = "Error ocurred while accessing 
params in query string: {0}" )
   void unableToGetParamsFromQueryString(@StackTrace(level=MessageLevel.WARN) 
Exception e);
+
+  @Message( level = MessageLevel.DEBUG, text = "Accepting service cookie: {0}" 
)
+  void acceptingServiceCookie( Cookie cookie );
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/6212381e/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStore.java
----------------------------------------------------------------------
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStore.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStore.java
index bed8517..1bab384 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStore.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStore.java
@@ -17,15 +17,126 @@
  */
 package org.apache.knox.gateway.dispatch;
 
+import java.lang.reflect.Field;
+import java.util.Date;
+
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.http.cookie.Cookie;
 import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.knox.gateway.SpiGatewayMessages;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 
 public class HadoopAuthCookieStore extends BasicCookieStore {
 
+  private static SpiGatewayMessages LOG = MessagesFactory.get( 
SpiGatewayMessages.class );
+
   @Override
   public void addCookie(Cookie cookie) {
     if (cookie.getName().equals("hadoop.auth") || 
cookie.getName().equals("hive.server2.auth")) {
-      super.addCookie(cookie);
+      Wrapper wrapper = new Wrapper( cookie );
+      LOG.acceptingServiceCookie( wrapper );
+      super.addCookie( wrapper );
     }
   }
-}
+
+  private static class Wrapper extends BasicClientCookie {
+
+    private Cookie delegate;
+
+    Wrapper( Cookie delegate ) {
+      super( delegate.getName(), delegate.getValue() );
+      this.delegate = delegate;
+    }
+
+    @Override
+    public String getName() {
+      return delegate.getName();
+    }
+
+    /**
+     * Checks the cookie value returned by the delegate and wraps it in double 
quotes if the value isn't
+     * null, empty or already wrapped in double quotes.
+     *
+     * This change is required to workaround Oozie 4.3/Hadoop 2.4 not properly 
formatting the hadoop.auth cookie.
+     * See the following jiras for additional context:
+     *   https://issues.apache.org/jira/browse/HADOOP-10710
+     *   https://issues.apache.org/jira/browse/HADOOP-10379
+     * This issue was further compounded by another Oozie issue resulting in 
Kerberos replay attacks.
+     *   https://issues.apache.org/jira/browse/OOZIE-2427
+     */
+    @Override
+    public String getValue() {
+      String value = delegate.getValue();
+      if ( value != null && !value.isEmpty() ) {
+        if( !value.startsWith( "\"" ) ) {
+          value = "\"" + value;
+        }
+        if( !value.endsWith( "\"" ) ) {
+          value = value + "\"";
+        }
+      }
+      return value;
+    }
+
+    @Override
+    public String getComment() {
+      return delegate.getComment();
+    }
+
+    @Override
+    public String getCommentURL() {
+      return delegate.getCommentURL();
+    }
+
+    @Override
+    public Date getExpiryDate() {
+      return delegate.getExpiryDate();
+    }
+
+    @Override
+    public boolean isPersistent() {
+      return delegate.isPersistent();
+    }
+
+    @Override
+    public String getDomain() {
+      return delegate.getDomain();
+    }
+
+    @Override
+    public String getPath() {
+      return delegate.getPath();
+    }
+
+    @Override
+    public int[] getPorts() {
+      return delegate.getPorts();
+    }
+
+    @Override
+    public boolean isSecure() {
+      return delegate.isSecure();
+    }
+
+    @Override
+    public int getVersion() {
+      return delegate.getVersion();
+    }
+
+    @Override
+    public boolean isExpired( Date date ) {
+      return delegate.isExpired( date );
+    }
+
+    public String toString() {
+      return (new ReflectionToStringBuilder(this) {
+        protected boolean accept(Field f) {
+          return super.accept(f) && !f.getName().equals("delegate");
+        }
+      }).toString();
+    }
+
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/6212381e/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStoreTest.java
----------------------------------------------------------------------
diff --git 
a/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStoreTest.java
 
b/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStoreTest.java
new file mode 100644
index 0000000..93070d5
--- /dev/null
+++ 
b/gateway-spi/src/test/java/org/apache/knox/gateway/dispatch/HadoopAuthCookieStoreTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.knox.gateway.dispatch;
+
+import java.util.List;
+
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.cookie.BasicClientCookie;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.*;
+
+public class HadoopAuthCookieStoreTest {
+
+  /**
+   * Test for the issue reported as KNOX-1171
+   * Tests the required to workaround Oozie 4.3/Hadoop 2.4 not properly 
formatting the hadoop.auth cookie.
+   * See the following jiras for additional context:
+   *   https://issues.apache.org/jira/browse/HADOOP-10710
+   *   https://issues.apache.org/jira/browse/HADOOP-10379
+   */
+  @Test
+  public void testOozieCookieWorkaroundKnox1171() {
+    String rawValue = 
"u=knox&p=knox/[email protected]&t=kerberos&e=1517900515610&s=HpSXUOhoXR/2wXrsgPz5lSbNuf8=";
+    String quotedValue = "\""+rawValue+"\"";
+
+    HadoopAuthCookieStore store;
+    List<Cookie> cookies;
+    Cookie cookie;
+
+    store = new HadoopAuthCookieStore();
+    store.addCookie( new BasicClientCookie( "hadoop.auth", rawValue ) );
+    cookies = store.getCookies();
+    cookie = cookies.get( 0 );
+    assertThat( cookie.getValue(), is(quotedValue) );
+
+    store = new HadoopAuthCookieStore();
+    store.addCookie( new BasicClientCookie( "hadoop.auth", quotedValue ) );
+    cookies = store.getCookies();
+    cookie = cookies.get( 0 );
+    assertThat( cookie.getValue(), is(quotedValue) );
+
+    store = new HadoopAuthCookieStore();
+    store.addCookie( new BasicClientCookie( "hadoop.auth", null ) );
+    cookies = store.getCookies();
+    cookie = cookies.get( 0 );
+    assertThat( cookie.getValue(), is(nullValue()) );
+
+    store = new HadoopAuthCookieStore();
+    store.addCookie( new BasicClientCookie( "hadoop.auth", "" ) );
+    cookies = store.getCookies();
+    cookie = cookies.get( 0 );
+    assertThat( cookie.getValue(), is("") );
+  }
+
+}
\ No newline at end of file

Reply via email to