Introducing optional ability to secure the ONOS karaf shell and to use raw ssh client.

Change-Id: I48cfc922eaf980d1cb8b9182b26999ce3c26b667
diff --git a/tools/build/onos-package b/tools/build/onos-package
index 5885562..8b36304 100755
--- a/tools/build/onos-package
+++ b/tools/build/onos-package
@@ -47,7 +47,8 @@
 sed "s/\$KARAF_VERSION/$KARAF_VERSION/g" \
     $ONOS_ROOT/tools/package/bin/onos-service > bin/onos-service
 sed "s/\$KARAF_VERSION/$KARAF_VERSION/g" \
-    $ONOS_ROOT/tools/package/bin/onos > bin/onos
+    $ONOS_ROOT/tools/package/bin/onos-client > bin/onos
+chmod a+x bin/onos-service bin/onos
 
 # Stage the ONOS bundles, but only those that match the version
 mkdir -p $ONOS_STAGE/$KARAF_DIST/system/org/onosproject
diff --git a/tools/package/bin/onos b/tools/package/bin/onos-client
similarity index 89%
rename from tools/package/bin/onos
rename to tools/package/bin/onos-client
index 84a41e0..2a37087 100755
--- a/tools/package/bin/onos
+++ b/tools/package/bin/onos-client
@@ -1,6 +1,6 @@
 #!/bin/bash
 # -----------------------------------------------------------------------------
-# ONOS command-line client
+# ONOS command-line client that uses the built-in Apache Karaf client.
 # -----------------------------------------------------------------------------
 
 if [ -z "${JAVA_HOME}" ]; then
diff --git a/tools/package/bin/onos-secure-ssh b/tools/package/bin/onos-secure-ssh
new file mode 100755
index 0000000..6c46904
--- /dev/null
+++ b/tools/package/bin/onos-secure-ssh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Enables secure access to ONOS console by removing default users & keys.
+# -----------------------------------------------------------------------------
+
+rm -f $(dirname $0)/onos
+
+set -e
+
+cd $(dirname $0)/../apache-karaf-*/etc
+USERS=users.properties
+KEYS=keys.properties
+
+# Remove the built-in users and keys to secure the access implicitly.
+egrep -v "^(karaf|onos)[ ]*=" $USERS > $USERS.new && mv $USERS.new $USERS
+egrep -v "^(#karaf|onos)[ ]*=" $KEYS > $KEYS.new && mv $KEYS.new $KEYS
+
+# Remove any previous known keys for the local host.
+ssh-keygen -f "$HOME/.ssh/known_hosts" -R [localhost]:8101
+
+# Swap the onos client to use the SSH variant
+ln -s $(dirname $0)/onos-ssh $(dirname $0)/onos
diff --git a/tools/package/bin/onos-ssh b/tools/package/bin/onos-ssh
new file mode 100755
index 0000000..7e082aa
--- /dev/null
+++ b/tools/package/bin/onos-ssh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS command-line client that uses raw ssh.
+# -----------------------------------------------------------------------------
+
+ssh -p 8101 localhost "$@"
\ No newline at end of file
diff --git a/tools/package/bin/onos-user-key b/tools/package/bin/onos-user-key
new file mode 100755
index 0000000..db24da1
--- /dev/null
+++ b/tools/package/bin/onos-user-key
@@ -0,0 +1,20 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Adds or removes a user key for managing passwordless loging to ONOS console.
+# -----------------------------------------------------------------------------
+
+[ $# -lt 2 ] && echo "usage: $(basename $0) user {key|remove}" && exit 1
+
+set -e
+
+user=$1
+[ -f $2 ] && key=$(cut -d\  -f2 $2) || key=$2
+
+cd $(dirname $0)/../apache-karaf-*/etc
+KEYS=keys.properties
+
+# Remove the user key first, in case one was already present
+egrep -v "^$user[ ]*=" $KEYS > $KEYS.new && mv $KEYS.new $KEYS
+if [ $key != "remove" ]; then
+    echo "$user=$key,_g_:admingroup" >> $KEYS
+fi
diff --git a/tools/test/bin/onos b/tools/test/bin/onos
index b18bae8..21f8f13 100755
--- a/tools/test/bin/onos
+++ b/tools/test/bin/onos
@@ -10,5 +10,12 @@
 [ "$1" = "-w" ] && shift && onos-wait-for-start $1
 
 [ -n "$1" ] && OCI=$(find_node $1) && shift
-unset KARAF_HOME
-client -h $OCI -u karaf "$@" 2>/dev/null
+
+if which -s client && [ -z "$ONOS_USE_SSH" ]; then
+    # Use Karaf client only if we can and are allowed to
+    unset KARAF_HOME
+    client -h $OCI -u karaf "$@" 2>/dev/null
+else
+    # Otherwise use raw ssh; strict checking is off for dev environments only
+    ssh -p 8101 -o StrictHostKeyChecking=no $OCI "$@"
+fi
diff --git a/tools/test/bin/onos-config b/tools/test/bin/onos-config
index 1a80e92..732aa8f 100755
--- a/tools/test/bin/onos-config
+++ b/tools/test/bin/onos-config
@@ -6,7 +6,8 @@
 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
 . $ONOS_ROOT/tools/build/envDefaults
 
-remote=$ONOS_USER@${1:-$OCI}
+node=${1:-$OCI}
+remote=$ONOS_USER@$node
 
 # ONOS boot features
 export ONOS_BOOT_FEATURES="${ONOS_BOOT_FEATURES:-webconsole,onos-api,onos-core,onos-incubator,onos-cli,onos-rest,onos-gui}"
diff --git a/tools/test/bin/onos-secure-ssh b/tools/test/bin/onos-secure-ssh
new file mode 100755
index 0000000..1ec0bff
--- /dev/null
+++ b/tools/test/bin/onos-secure-ssh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Secures the ONOS console for all instances in the cell ONOS cluster.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+
+for node in $nodes; do
+    # Setup passwordless login for the remote user on the local bench host
+    onos-user-key $node
+
+    # Prune the node entry from the known hosts file since server key changes
+    ssh-keygen -f "$HOME/.ssh/known_hosts" -R [$node]:8101
+
+    # Setup passwordless login for the local user on the remote node
+    ssh $ONOS_USER@$node "
+        [ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q
+        $ONOS_INSTALL_DIR/bin/onos-user-key \$(id -un) \$(cut -d\\  -f2 ~/.ssh/id_rsa.pub)
+        $ONOS_INSTALL_DIR/bin/onos-secure-ssh
+
+        # Implicitly accept the new server key in dev/test environments
+        while ! ssh -p 8101 -o StrictHostKeyChecking=no localhost list 2>/dev/null; do
+            echo Waiting for connection...
+            sleep 1
+        done
+    "
+done
+
diff --git a/tools/test/bin/onos-ssh b/tools/test/bin/onos-ssh
index a7be77a..eb6b88e 100755
--- a/tools/test/bin/onos-ssh
+++ b/tools/test/bin/onos-ssh
@@ -5,6 +5,7 @@
 
 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
 . $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
 
-[ -n "$1" ] && OCI=$1 && shift
+[ -n "$1" ] && OCI=$(find_node $1) && shift
 ssh -Y $ONOS_USER@$OCI "$@"
diff --git a/tools/test/bin/onos-untar-and-run b/tools/test/bin/onos-untar-and-run
index b6e6ef0..f6e8f9b 100755
--- a/tools/test/bin/onos-untar-and-run
+++ b/tools/test/bin/onos-untar-and-run
@@ -15,6 +15,7 @@
     tar zxf /tmp/$ONOS_BITS.tar.gz
 
     cd /tmp/$ONOS_BITS
+    export ONOS_NIC=$ONOS_NIC
     bin/onos-service server 1>/tmp/onos.out 2>/tmp/onos.err &
 
     # Setup a few symlinks to allow other tools to work
diff --git a/tools/test/bin/onos-user-key b/tools/test/bin/onos-user-key
new file mode 100755
index 0000000..b324c1a
--- /dev/null
+++ b/tools/test/bin/onos-user-key
@@ -0,0 +1,13 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Adds or removes a user key for managing passwordless loging to ONOS console.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+user=${2:-$(id -un)}
+key=${3:-$(cut -d\  -f2 ~/.ssh/id_rsa.pub)}
+
+ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-user-key $user $key
diff --git a/tools/test/bin/onos-wait-for-start b/tools/test/bin/onos-wait-for-start
index 030e5cc..2c90181 100755
--- a/tools/test/bin/onos-wait-for-start
+++ b/tools/test/bin/onos-wait-for-start
@@ -9,14 +9,15 @@
 remote=$ONOS_USER@${1:-$OCI}
 
 ssh -t $remote "
+    set -x
     # Wait until we reach the run-level 100
-    for i in \$(seq 1 20); do
+    for i in \$(seq 1 45); do
         $ONOS_INSTALL_DIR/bin/onos bundle:list 2>/dev/null | \
             grep -q 'START LEVEL 100' && break || sleep 2
     done
 
     # Wait until ApplicationManager is available
-    for i in \$(seq 1 5); do
+    for i in \$(seq 1 10); do
         grep -q \" ApplicationManager .* Started\" \
             $ONOS_INSTALL_DIR/log/karaf.log && break || sleep 1
     done
diff --git a/tools/test/scenarios/setup.xml b/tools/test/scenarios/setup.xml
index 8fefb81..463b53f 100644
--- a/tools/test/scenarios/setup.xml
+++ b/tools/test/scenarios/setup.xml
@@ -16,21 +16,27 @@
 <scenario name="setup" description="ONOS cluster setup">
     <group name="Setup">
         <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/>
+        <step name="Secure-SSH" exec="onos-secure-ssh" if="${ONOS_USE_SSH}"/>
 
         <parallel var="${OC#}">
-            <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}" unless="${OCT}"/>
+            <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}"
+                  unless="${OCT}"/>
             <step name="Uninstall-${#}" exec="onos-uninstall ${OC#}"/>
-            <step name="Kill-${#}" env="~" exec="onos-kill ${OC#}" requires="Uninstall-${#}"/>
+            <step name="Kill-${#}" env="~" exec="onos-kill ${OC#}"
+                  requires="Uninstall-${#}"/>
 
             <step name="Install-${#}" exec="onos-install ${OC#}"
                   requires="Kill-${#},Push-Bits-${#},Push-Bits"/>
 
+            <dependency name="Secure-SSH" requires="Install-${#}"/>
+
             <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}"
-                  requires="Install-${#}"/>
+                  requires="Install-${#},~Secure-SSH"/>
 
             <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}"
                   requires="~Wait-for-Start-${#}"/>
-            <step name="Check-Components-${#}" exec="onos-check-components ${OC#}"
+            <step name="Check-Components-${#}"
+                  exec="onos-check-components ${OC#}"
                   requires="~Wait-for-Start-${#},"/>
             <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#}"
                   requires="~Wait-for-Start-${#}"/>
diff --git a/tools/test/scenarios/tar-setup.xml b/tools/test/scenarios/tar-setup.xml
index b91cbf8..8420528 100644
--- a/tools/test/scenarios/tar-setup.xml
+++ b/tools/test/scenarios/tar-setup.xml
@@ -16,6 +16,7 @@
 <scenario name="tar-setup" description="ONOS cluster setup via onos.tar.gz">
     <group name="Setup-Instances">
         <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/>
+        <step name="Secure-SSH" exec="onos-secure-ssh" if="${ONOS_USE_SSH}"/>
 
         <parallel var="${OC#}">
             <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}" unless="${OCT}"/>
@@ -25,8 +26,10 @@
             <step name="Untar-And-Run-${#}" exec="onos-untar-and-run ${OC#}"
                   requires="Kill-${#},Push-Bits-${#},Push-Bits"/>
 
+            <dependency name="Secure-SSH" requires="Untar-And-Run-${#}"/>
+
             <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}"
-                  requires="Untar-And-Run-${#}"/>
+                  requires="Untar-And-Run-${#},~Secure-SSH"/>
 
             <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}"
                   requires="~Wait-for-Start-${#}"/>