GEODE-83 Add support for Redis AUTH command
Also added Geode property "redis-password" so the authentication password can 
be set by xml or through GFSH


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/111d6154
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/111d6154
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/111d6154

Branch: refs/heads/feature/GEODE-77
Commit: 111d61546f2958cf4ad36872677b95ca50269dfd
Parents: e8672d0
Author: Vito Gavrilov <vgavri...@pivotal.io>
Authored: Tue Jul 14 08:00:36 2015 -0700
Committer: Vito Gavrilov <vgavri...@pivotal.io>
Committed: Tue Jul 21 14:32:12 2015 -0700

----------------------------------------------------------------------
 .../gemfire/distributed/DistributedSystem.java  |  6 ++
 .../internal/AbstractDistributionConfig.java    | 21 ++++++-
 .../internal/DistributionConfig.java            | 12 ++++
 .../internal/DistributionConfigImpl.java        | 16 ++++-
 .../gemstone/gemfire/internal/redis/Coder.java  | 12 +++-
 .../internal/redis/ExecutionHandlerContext.java | 66 +++++++++++++++-----
 .../internal/redis/RedisCommandType.java        | 21 +++++++
 .../gemfire/internal/redis/RedisConstants.java  |  4 ++
 .../internal/redis/executor/AuthExecutor.java   | 38 +++++++++++
 .../cli/commands/LauncherLifecycleCommands.java |  5 ++
 .../internal/cli/i18n/CliStrings.java           |  2 +
 .../gemfire/redis/GemFireRedisServer.java       | 14 ++---
 12 files changed, 190 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java
index 5b2992d..b7b2cd8 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/DistributedSystem.java
@@ -837,6 +837,12 @@ import 
com.gemstone.gemfire.security.GemFireSecurityException;
  *   <dd><U>Default</U>: ""</dd>
  * </dl>
  * 
+ * <dl>
+ *   <a name="redis-password"><dt>redis-password</dt></a>
+ *   <dd><U>Description</U>: Specifies the password to authenticate a client 
of {@link GemFireRedisServer}</dd>
+ *   <dd><U>Default</U>: ""</dd>
+ * </dl>
+ * 
  * <B>Asynchronous Message Properties</B>
  *
  * <dl>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java
index f34a985..472959d 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/AbstractDistributionConfig.java
@@ -1395,6 +1395,11 @@ public abstract class AbstractDistributionConfig
           }));
     }
   }
+  
+  protected void checkRedisPassword(String value) {
+    
+  }
+  
   public boolean isRedisBindAddressModifiable() {
     return _modifiableDefault();
   }
@@ -1402,6 +1407,10 @@ public abstract class AbstractDistributionConfig
   public boolean isRedisPortModifiable() {
     return _modifiableDefault();
   }
+  
+  public boolean isRedisPasswordModifiable() {
+    return _modifiableDefault();
+  }
 
   public boolean isOffHeapMemorySizeModifiable() {
     return _modifiableDefault();
@@ -1553,6 +1562,7 @@ public abstract class AbstractDistributionConfig
       MEMCACHED_BIND_ADDRESS_NAME,
       REDIS_PORT_NAME,
       REDIS_BIND_ADDRESS_NAME,
+      REDIS_PASSWORD_NAME,
       USER_COMMAND_PACKAGES,
       ENABLE_CLUSTER_CONFIGURATION_NAME,
       USE_CLUSTER_CONFIGURATION_NAME,
@@ -1806,6 +1816,8 @@ public abstract class AbstractDistributionConfig
       this.setRedisPort(((Integer)attValue).intValue());
     } else if (attName.equalsIgnoreCase(REDIS_BIND_ADDRESS_NAME)) {
       this.setRedisBindAddress((String)attValue);
+    } else if (attName.equalsIgnoreCase(REDIS_PASSWORD_NAME)) {
+      this.setRedisPassword((String)attValue);
     } else if (attName.equalsIgnoreCase(USER_COMMAND_PACKAGES)) {
       this.setUserCommandPackages((String)attValue);
     } else if (attName.equalsIgnoreCase(ENABLE_CLUSTER_CONFIGURATION_NAME)) {
@@ -2094,6 +2106,8 @@ public abstract class AbstractDistributionConfig
       return this.getRedisPort();
     } else if (attName.equalsIgnoreCase(REDIS_BIND_ADDRESS_NAME)) {
       return this.getRedisBindAddress();
+    } else if (attName.equalsIgnoreCase(REDIS_PASSWORD_NAME)) {
+      return this.getRedisPassword();
     } else if (attName.equalsIgnoreCase(USER_COMMAND_PACKAGES)) {
       return this.getUserCommandPackages();
     } else if (attName.equalsIgnoreCase(ENABLE_CLUSTER_CONFIGURATION_NAME)) {
@@ -2383,6 +2397,8 @@ public abstract class AbstractDistributionConfig
       return this.isRedisPortModifiable();
     } else if (attName.equalsIgnoreCase(REDIS_BIND_ADDRESS_NAME)) {
       return this.isRedisBindAddressModifiable();
+    } else if (attName.equalsIgnoreCase(REDIS_PASSWORD_NAME)) {
+      return this.isRedisPasswordModifiable();
     } else if (attName.equalsIgnoreCase(USER_COMMAND_PACKAGES)) {
       return this.isUserCommandPackagesModifiable();
     } else if (attName.equalsIgnoreCase(ENABLE_CLUSTER_CONFIGURATION_NAME)) {
@@ -2674,7 +2690,9 @@ public abstract class AbstractDistributionConfig
       return Integer.class;
     } else if (attName.equalsIgnoreCase(REDIS_BIND_ADDRESS_NAME)) {
       return String.class;
-    }else if (attName.equalsIgnoreCase(USER_COMMAND_PACKAGES)) {
+    } else if (attName.equalsIgnoreCase(REDIS_PASSWORD_NAME)) {
+      return String.class;
+    } else if (attName.equalsIgnoreCase(USER_COMMAND_PACKAGES)) {
       return String.class;
     } else if (attName.equalsIgnoreCase(ENABLE_CLUSTER_CONFIGURATION_NAME)) {
       return Boolean.class;
@@ -3130,6 +3148,7 @@ public abstract class AbstractDistributionConfig
     m.put(MEMCACHED_BIND_ADDRESS_NAME, "The address the GemFireMemcachedServer 
will listen on for remote connections. Default is \"\" which causes the 
GemFireMemcachedServer to listen on the host's default address. This property 
is ignored if memcached-port is \"0\".");
     m.put(REDIS_PORT_NAME, "The port GemFireRedisServer will listen on. 
Default is 0. Set to zero to disable GemFireRedisServer.");
     m.put(REDIS_BIND_ADDRESS_NAME, "The address the GemFireRedisServer will 
listen on for remote connections. Default is \"\" which causes the 
GemFireRedisServer to listen on the host's default address. This property is 
ignored if redis-port is \"0\".");
+    m.put(REDIS_PASSWORD_NAME, "The password which client of 
GemFireRedisServer must use to authenticate themselves. The default is none and 
no authentication will be required.");
     m.put(ENABLE_CLUSTER_CONFIGURATION_NAME, 
LocalizedStrings.AbstractDistributionConfig_ENABLE_SHARED_CONFIGURATION.toLocalizedString());
     m.put(USE_CLUSTER_CONFIGURATION_NAME, 
LocalizedStrings.AbstractDistributionConfig_USE_SHARED_CONFIGURATION.toLocalizedString());
     m.put(LOAD_CLUSTER_CONFIG_FROM_DIR_NAME, 
LocalizedStrings.AbstractDistributionConfig_LOAD_SHARED_CONFIGURATION_FROM_DIR.toLocalizedString(SharedConfiguration.CLUSTER_CONFIG_ARTIFACTS_DIR_NAME));

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java
index 6429642..10094a9 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfig.java
@@ -2861,6 +2861,18 @@ public interface DistributionConfig extends Config, 
LogConfig {
   public boolean isRedisBindAddressModifiable();
   public static String REDIS_BIND_ADDRESS_NAME = "redis-bind-address";
   public static String DEFAULT_REDIS_BIND_ADDRESS = "";
+  
+  /**
+   * Returns the value of the <a
+   * href="../DistributedSystem.html#redis-password">"redis-password"</a> 
property
+   * @return the authentication password for GemFireRedisServer
+   * @since 8.0
+   */
+  public String getRedisPassword();
+  public void setRedisPassword(String password);
+  public boolean isRedisPasswordModifiable();
+  public static String REDIS_PASSWORD_NAME = "redis-password";
+  public static String DEFAULT_REDIS_PASSWORD = "";
 
 
   //Added for the HTTP service

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java
index 83eb7ae..b8dfeb3 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/DistributionConfigImpl.java
@@ -30,6 +30,7 @@ import com.gemstone.gemfire.internal.ConfigSource;
 import com.gemstone.gemfire.internal.SocketCreator;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.process.ProcessLauncherContext;
+import com.gemstone.gemfire.internal.redis.Coder;
 import com.gemstone.gemfire.memcached.GemFireMemcachedServer;
 
 /**
@@ -309,12 +310,14 @@ public class DistributionConfigImpl
   /**
    * port on which {@link GemFireRedisServer} is started
    */
-  private int redisPort;
+  private int redisPort = DEFAULT_REDIS_PORT;
   
   /**
    * Bind address for GemFireRedisServer
    */
   private String redisBindAddress = DEFAULT_REDIS_BIND_ADDRESS;
+  
+  private String redisPassword = DEFAULT_REDIS_PASSWORD;
 
   private boolean jmxManager = 
Boolean.getBoolean(InternalLocator.FORCE_LOCATOR_DM_TYPE) ? true : 
DEFAULT_JMX_MANAGER;
   private boolean jmxManagerStart = DEFAULT_JMX_MANAGER_START;
@@ -509,6 +512,7 @@ public class DistributionConfigImpl
     this.memcachedBindAddress = other.getMemcachedBindAddress();
     this.redisPort = other.getRedisPort();
     this.redisBindAddress = other.getRedisBindAddress();
+    this.redisPassword = other.getRedisPassword();
     this.userCommandPackages = other.getUserCommandPackages();
     
     // following added for 8.0
@@ -3230,6 +3234,16 @@ public class DistributionConfigImpl
   }
   
   @Override
+  public String getRedisPassword() {
+    return this.redisPassword;
+  }
+  
+  @Override
+  public void setRedisPassword(String password) {
+    this.redisPassword = password;
+  }
+  
+  @Override
   public String getOffHeapMemorySize() {
     return this.offHeapMemorySize;
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/Coder.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/Coder.java 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/Coder.java
index 90e28fb..4792eec 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/Coder.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/Coder.java
@@ -65,7 +65,7 @@ public class Coder {
   public static final byte[] bEMPTY_ARRAY = stringToBytes("*0\r\n"); // {'*', 
'0', '\r', '\n'};
 
   public static final byte[] err = stringToBytes("ERR ");
-
+  public static final byte[] noAuth = stringToBytes("NOAUTH ");
   public static final byte[] wrongType = stringToBytes("WRONGTYPE ");
 
   /**
@@ -272,6 +272,16 @@ public class Coder {
     response.writeBytes(CRLFar);
     return response;
   }
+  
+  public static final ByteBuf getNoAuthResponse(ByteBufAllocator alloc, String 
error) {
+    byte[] errorAr = stringToBytes(error);
+    ByteBuf response = alloc.buffer(errorAr.length + 25);
+    response.writeByte(ERROR_ID);
+    response.writeBytes(noAuth);
+    response.writeBytes(errorAr);
+    response.writeBytes(CRLFar);
+    return response;
+  }
 
   public static final ByteBuf getWrongTypeResponse(ByteBufAllocator alloc, 
String error) {
     byte[] errorAr = stringToBytes(error);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/ExecutionHandlerContext.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/ExecutionHandlerContext.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/ExecutionHandlerContext.java
index 848d4bb..5f51c35 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/ExecutionHandlerContext.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/ExecutionHandlerContext.java
@@ -45,9 +45,11 @@ public class ExecutionHandlerContext extends 
ChannelInboundHandlerAdapter {
    */
   private Queue<Command> transactionQueue;
   private final RegionCache regionCache;
+  private final byte[] authPwd;
 
+  private boolean isAuthenticated;
 
-  public ExecutionHandlerContext(Channel ch, Cache cache, RegionCache regions, 
GemFireRedisServer server) {
+  public ExecutionHandlerContext(Channel ch, Cache cache, RegionCache regions, 
GemFireRedisServer server, byte[] pwd) {
     this.cache = cache;
     this.server = server;
     this.logger = cache.getLogger();
@@ -66,6 +68,8 @@ public class ExecutionHandlerContext extends 
ChannelInboundHandlerAdapter {
     this.transactionID = null;
     this.transactionQueue = null; // Lazy
     this.regionCache = regions;
+    this.authPwd = pwd;
+    this.isAuthenticated = pwd != null ? false : true;
   }
 
   private void flushChannel() {
@@ -137,22 +141,35 @@ public class ExecutionHandlerContext extends 
ChannelInboundHandlerAdapter {
    */
   public void executeCommand(ChannelHandlerContext ctx, Command command) 
throws Exception {
     RedisCommandType type = command.getCommandType();
-    if (type == RedisCommandType.SHUTDOWN) {
-      this.server.shutdown();
-      return;
-    }
     Executor exec = type.getExecutor();
-    if (hasTransaction() && !(exec instanceof TransactionExecutor))
-      executeWithTransaction(ctx, exec, command);
-    else
-      executeWithoutTransaction(exec, command, MAXIMUM_NUM_RETRIES); 
-
-    if (hasTransaction() && command.getCommandType() != RedisCommandType.MULTI)
-      writeToChannel(Coder.getSimpleStringResponse(this.byteBufAllocator, 
RedisConstants.COMMAND_QUEUED));
-    else 
-      writeToChannel(command.getResponse());
-    if (type == RedisCommandType.QUIT) {
+    if (isAuthenticated) {
+      if (type == RedisCommandType.SHUTDOWN) {
+        this.server.shutdown();
+        return;
+      }
+      if (hasTransaction() && !(exec instanceof TransactionExecutor))
+        executeWithTransaction(ctx, exec, command);
+      else
+        executeWithoutTransaction(exec, command, MAXIMUM_NUM_RETRIES); 
+
+      if (hasTransaction() && command.getCommandType() != 
RedisCommandType.MULTI) {
+        writeToChannel(Coder.getSimpleStringResponse(this.byteBufAllocator, 
RedisConstants.COMMAND_QUEUED));
+      } else {
+        ByteBuf response = command.getResponse();
+        writeToChannel(response);
+      }
+    } else if (type == RedisCommandType.QUIT) {
+      exec.executeCommand(command, this);
+      ByteBuf response = command.getResponse();
+      writeToChannel(response);
       channelInactive(ctx);
+    } else if (type == RedisCommandType.AUTH) {
+      exec.executeCommand(command, this);
+      ByteBuf response = command.getResponse();
+      writeToChannel(response);
+    } else {
+      ByteBuf r = Coder.getNoAuthResponse(this.byteBufAllocator, 
RedisConstants.ERROR_NOT_AUTH);
+      writeToChannel(r);
     }
   }
 
@@ -271,4 +288,23 @@ public class ExecutionHandlerContext extends 
ChannelInboundHandlerAdapter {
     return this.cache.getCacheTransactionManager();
   }
 
+  public LogWriter getLogger() {
+    return this.cache.getLogger();
+  }
+
+  public Channel getChannel() {
+    return this.channel;
+  }
+
+  public byte[] getAuthPwd() {
+    return this.authPwd;
+  }
+
+  public boolean isAuthenticated() {
+    return this.isAuthenticated;
+  }
+
+  public void setAuthenticationVerified() {
+    this.isAuthenticated = true;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisCommandType.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisCommandType.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisCommandType.java
index 96b6595..3dd6be1 100755
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisCommandType.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisCommandType.java
@@ -1,6 +1,7 @@
 
 package com.gemstone.gemfire.internal.redis;
 
+import com.gemstone.gemfire.internal.redis.executor.AuthExecutor;
 import com.gemstone.gemfire.internal.redis.executor.DBSizeExecutor;
 import com.gemstone.gemfire.internal.redis.executor.DelExecutor;
 import com.gemstone.gemfire.internal.redis.executor.EchoExecutor;
@@ -128,6 +129,26 @@ public enum RedisCommandType {
    ***************************************/
 
   /**
+   * AUTH password <p>
+   * Authenticate to the server
+   */
+  AUTH {
+    private Executor executor;
+    @Override
+    public Executor getExecutor() {
+      if (executor == null) {
+        executor = new AuthExecutor();
+      }
+      return executor;
+    }
+    private final RedisDataType dataType = RedisDataType.NONE;
+    @Override
+    public RedisDataType getDataType() {
+      return this.dataType;
+    }
+  }, 
+  
+  /**
    * DEL key [key ...] <p>
    * Delete a key
    */

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisConstants.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisConstants.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisConstants.java
index ed593c7..6fe77d7 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisConstants.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/RedisConstants.java
@@ -31,6 +31,9 @@ public class RedisConstants {
   public static final String ERROR_OUT_OF_RANGE = "The number provided is out 
of range";
   public static final String ERROR_NESTED_MULTI = "The MULTI command cannot be 
nested";
   public static final String ERROR_NAN_INF_INCR = "increment would produce NaN 
or Infinity";
+  public static final String ERROR_NO_PASS = "Attempting to authenticate when 
no password has been set";
+  public static final String ERROR_INVALID_PWD = "Attemping to authenticate 
with an invalid password";
+  public static final String ERROR_NOT_AUTH = "Must authenticate before 
sending any requests";
   
   public static class ArityDef {
 
@@ -38,6 +41,7 @@ public class RedisConstants {
      * General 
      */
     public static final int DBSIZE_ARITY = 0;
+    public static final String AUTH =           "The wrong number of arguments 
or syntax was provided, the format for the AUTH command is \"AUTH password\"";
     public static final String DBSIZE =         null;
     public static final String DEL =            "The wrong number of arguments 
or syntax was provided, the format for the DEL command is \"DEL key [key 
...]\"";
     public static final String ECHO =           "The wrong number of arguments 
or syntax was provided, the format for the ECHO command is \"ECHO message\"";

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/AuthExecutor.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/AuthExecutor.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/AuthExecutor.java
new file mode 100644
index 0000000..3734af3
--- /dev/null
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/redis/executor/AuthExecutor.java
@@ -0,0 +1,38 @@
+package com.gemstone.gemfire.internal.redis.executor;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.gemstone.gemfire.internal.redis.Coder;
+import com.gemstone.gemfire.internal.redis.Command;
+import com.gemstone.gemfire.internal.redis.ExecutionHandlerContext;
+import com.gemstone.gemfire.internal.redis.Executor;
+import com.gemstone.gemfire.internal.redis.RedisConstants;
+import com.gemstone.gemfire.internal.redis.RedisConstants.ArityDef;
+
+public class AuthExecutor implements Executor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) 
{
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), 
ArityDef.AUTH));
+      return;
+    }
+    byte[] pwd = context.getAuthPwd();
+    if (pwd == null) {
+      
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), 
RedisConstants.ERROR_NO_PASS));
+      return;
+    }
+    boolean correct = Arrays.equals(commandElems.get(1), pwd);
+
+    if (correct) {
+      context.setAuthenticationVerified();
+      
command.setResponse(Coder.getSimpleStringResponse(context.getByteBufAllocator(),
 "OK"));
+    } else {
+      
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), 
RedisConstants.ERROR_INVALID_PWD));
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
index e1f42e9..302d7bb 100755
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommands.java
@@ -1512,6 +1512,10 @@ public class LauncherLifecycleCommands extends 
AbstractCommandsSupport {
                                       unspecifiedDefaultValue = 
CliMetaData.ANNOTATION_NULL_VALUE,
                                       help = 
CliStrings.START_SERVER__REDIS_BIND_ADDRESS__HELP)
                             final String redisBindAddress,
+                            @CliOption(key = 
CliStrings.START_SERVER__REDIS_PASSWORD,
+                                       unspecifiedDefaultValue = 
CliMetaData.ANNOTATION_NULL_VALUE,
+                                       help = 
CliStrings.START_SERVER__REDIS_PASSWORD__HELP)
+                            final String redisPassword,
                             @CliOption(key = 
CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE,
                                        unspecifiedDefaultValue = 
CliMetaData.ANNOTATION_NULL_VALUE,
                                        help = 
CliStrings.START_SERVER__MESSAGE__TIME__TO__LIVE__HELP)
@@ -1621,6 +1625,7 @@ public class LauncherLifecycleCommands extends 
AbstractCommandsSupport {
       
gemfireProperties.setProperty(DistributionConfig.MEMCACHED_BIND_ADDRESS_NAME, 
StringUtils.valueOf(memcachedBindAddress, StringUtils.EMPTY_STRING));
       gemfireProperties.setProperty(DistributionConfig.REDIS_PORT_NAME, 
StringUtils.valueOf(redisPort, StringUtils.EMPTY_STRING));
       
gemfireProperties.setProperty(DistributionConfig.REDIS_BIND_ADDRESS_NAME, 
StringUtils.valueOf(redisBindAddress, StringUtils.EMPTY_STRING));
+      gemfireProperties.setProperty(DistributionConfig.REDIS_PASSWORD_NAME, 
StringUtils.valueOf(redisPassword, StringUtils.EMPTY_STRING));
       
gemfireProperties.setProperty(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME, 
StringUtils.valueOf(statisticsArchivePathname, StringUtils.EMPTY_STRING));
       
gemfireProperties.setProperty(DistributionConfig.USE_CLUSTER_CONFIGURATION_NAME,
 StringUtils.valueOf(requestSharedConfiguration, Boolean.TRUE.toString()));
       gemfireProperties.setProperty(DistributionConfig.LOCK_MEMORY_NAME, 
StringUtils.valueOf(lockMemory, StringUtils.EMPTY_STRING));

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
 
b/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
index 3ddb519..c65212f 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/management/internal/cli/i18n/CliStrings.java
@@ -1839,6 +1839,8 @@ public class CliStrings {
   public static final String START_SERVER__REDIS_PORT__HELP = "Sets the port 
that the GemFire Redis service listens on for Redis clients.";
   public static final String START_SERVER__REDIS_BIND_ADDRESS = 
"redis-bind-address";
   public static final String START_SERVER__REDIS_BIND_ADDRESS__HELP = "Sets 
the IP address the GemFire Redis service listens on for Redis clients. The 
default is to bind to the first non-loopback address for this machine.";
+  public static final String START_SERVER__REDIS_PASSWORD = "redis-password";
+  public static final String START_SERVER__REDIS_PASSWORD__HELP = "Sets the 
authentication password for GemFireRedisServer";
   public static final String START_SERVER__SECURITY_PROPERTIES = 
"security-properties-file";
   public static final String START_SERVER__SECURITY_PROPERTIES__HELP = "The 
gfsecurity.properties file for configuring the Server's security configuration 
in the distributed system. The file's path can be absolute or relative to gfsh 
directory.";
   public static final String START_SERVER__REBALANCE = "rebalance";

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/111d6154/gemfire-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
----------------------------------------------------------------------
diff --git 
a/gemfire-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java 
b/gemfire-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
index e25e003..662e0a8 100644
--- 
a/gemfire-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
+++ 
b/gemfire-core/src/main/java/com/gemstone/gemfire/redis/GemFireRedisServer.java
@@ -92,7 +92,7 @@ import 
com.gemstone.gemfire.internal.redis.executor.hll.HyperLogLogPlus;
  * <p>
  * Supported Transaction commands - DISCARD, EXEC, MULTI
  * <P>
- * Supported Server commands - ECHO, PING, TIME, QUIT
+ * Supported Server commands - AUTH, ECHO, PING, TIME, QUIT
  * <p>
  * <p>
  * The command executors are not explicitly documented but the functionality
@@ -132,12 +132,6 @@ public class GemFireRedisServer {
   public static final int DEFAULT_REDIS_SERVER_PORT = 6379;
 
   /**
-   * This field specifies the number of threads the will be working to 
interpret
-   * and execute the commands
-   *
-  private static final int DEFAULT_WORKER_THREADS_PER_CORE = 4;
-   */
-  /**
    * The number of threads that will work on handling requests
    */
   private final int numWorkerThreads;
@@ -486,7 +480,9 @@ public class GemFireRedisServer {
       workerGroup = new NioEventLoopGroup(this.numWorkerThreads, 
workerThreadFactory);
       socketClass = NioServerSocketChannel.class;
     }
-
+    InternalDistributedSystem system = (InternalDistributedSystem) 
cache.getDistributedSystem();
+    String pwd = system.getConfig().getRedisPassword();
+    final byte[] pwdB = Coder.stringToBytes(pwd);
     ServerBootstrap b = new ServerBootstrap();
     b.group(bossGroup, workerGroup)
     .channel(socketClass)
@@ -497,7 +493,7 @@ public class GemFireRedisServer {
           logger.fine("GemFireRedisServer-Connection established with " + 
ch.remoteAddress());
         ChannelPipeline p = ch.pipeline();
         p.addLast(ByteToCommandDecoder.class.getSimpleName(), new 
ByteToCommandDecoder());
-        p.addLast(ExecutionHandlerContext.class.getSimpleName(), new 
ExecutionHandlerContext(ch, cache, regionCache, GemFireRedisServer.this));
+        p.addLast(ExecutionHandlerContext.class.getSimpleName(), new 
ExecutionHandlerContext(ch, cache, regionCache, GemFireRedisServer.this, pwdB));
       }
     })
     .option(ChannelOption.SO_REUSEADDR, true)

Reply via email to