veyron/tools/mgmt/vbash: rename vsh to vbash to avoid conflict with tunnel client.

Change-Id: I65e1a1e4c74d467485178fb1637276dfcc5bdd0b
diff --git a/tools/mgmt/vbash b/tools/mgmt/vbash
new file mode 100755
index 0000000..9a04701
--- /dev/null
+++ b/tools/mgmt/vbash
@@ -0,0 +1,182 @@
+#!/bin/bash
+#
+# Starts up a shell running under the security agent.
+#
+# Specifically:
+#
+# 1. Fetches the binaries needed to set up the security environment.  If it
+# can't fetch fresh binaries, it issues a warning but proceeds with existing
+# binaries, if any.
+#
+# 2. Starts a shell under the agent, optionally fetching a remote blessing if
+# the principal is missing.
+#
+# Uses ~/.vbash to store its files, including binaries and the principal.
+#
+# Usage:
+#
+# # Gets binaries from local repository
+# ./vbash
+#
+# # Gets binaries from local filesystem
+# ./vbash /path/to/binaries
+#
+# # Gets binaries from HTTP server
+# ./vbash http://host/path
+#
+# Limitations:
+# This only works on Linux and was only tested on goobuntu.
+# TODO(caprita): Make it work on Mac.
+set -e
+
+readonly BIN_NAMES=(principal agentd)
+
+# TODO(caprita): share copy_binaries and get_binaries with nminstall.
+
+###############################################################################
+# Copies one binary from source to destination.
+# Arguments:
+#   name of the binary
+#   source dir of binary
+#   destination dir of binary
+# Returns:
+#   None
+###############################################################################
+copy_binary() {
+  local -r BIN_NAME="$1"
+  local -r BIN_SRC_DIR="$2"
+  local -r BIN_DEST_DIR="$3"
+  local -r SOURCE="${BIN_SRC_DIR}/${BIN_NAME}"
+  if [[ -x "${SOURCE}" ]]; then
+    local -r DESTINATION="${BIN_DEST_DIR}/${BIN_NAME}"
+    cp "${SOURCE}" "${DESTINATION}"
+    chmod 700 "${DESTINATION}"
+  else
+    echo "couldn't find ${SOURCE}"
+    exit 1
+  fi
+}
+
+###############################################################################
+# Fetches binaries needed by node manager installation.
+# Globals:
+#   BIN_NAMES
+#   VEYRON_ROOT
+# Arguments:
+#   destination for binaries
+#   source of binaries
+# Returns:
+#   None
+###############################################################################
+get_binaries() {
+  local -r BIN_INSTALL="$1"
+  local -r BIN_SOURCE="$2"
+
+  local bin_names_str=""
+  for bin_name in "${BIN_NAMES[@]}"; do
+    bin_names_str+=" ${bin_name}"
+  done
+
+  # If source is not specified, try to look for it in the repository.
+  if [[ -z "${BIN_SOURCE}" ]]; then
+    if [[ -z "${VEYRON_ROOT}" ]]; then
+      echo 'ERROR: binary source not specified and no local repository available'
+      exit 1
+    fi
+    local -r REPO_BIN_DIR="${VEYRON_ROOT}/veyron/go/bin"
+    echo "Fetching binaries:${bin_names_str} from build repository: ${REPO_BIN_DIR} ..."
+    for bin_name in "${BIN_NAMES[@]}"; do
+      copy_binary "${bin_name}" "${REPO_BIN_DIR}" "${BIN_INSTALL}"
+    done
+    return
+  fi
+
+  # If the source is specified as an existing local filesystem path,
+  # look for the binaries there.
+  if [[ -d "${BIN_SOURCE}" ]]; then
+      echo "Fetching binaries:${bin_names_str} locally from: ${BIN_SOURCE} ..."
+      for bin_name in "${BIN_NAMES[@]}"; do
+        copy_binary "${bin_name}" "${BIN_SOURCE}" "${BIN_INSTALL}"
+      done
+      return
+  fi
+
+  # If the source looks like a URL, use HTTP to fetch.
+  local -r URL_REGEXP='^(https?|ftp|file)://'
+  if [[ "${BIN_SOURCE}" =~ ${URL_REGEXP} ]]; then
+    echo "Fetching binaries:${bin_names_str} remotely from: ${BIN_SOURCE} ..."
+      for bin_name in "${BIN_NAMES[@]}"; do
+        local DEST="${BIN_INSTALL}/${bin_name}"
+        curl -f -o "${DEST}" "${BIN_SOURCE}/${bin_name}"
+        chmod 700 "${DEST}"
+      done
+      return
+  fi
+
+  echo "WARNING: couldn't fetch binaries."
+}
+
+main() {
+  if [[ ! -z "${VBASH_INDICATOR}" ]]; then
+    echo "Disallowing running VBASH within VBASH."
+    echo "https://memegen.googleplex.com/5551020600983552"
+    exit 1
+  fi
+  export VBASH_INDICATOR="1"
+
+  local -r INSTALL_DIR="${HOME}/.vbash"
+  if [[ ! -e "${INSTALL_DIR}" ]]; then
+    mkdir -m 700 "${INSTALL_DIR}"
+  fi
+  if [[ ! -d "${INSTALL_DIR}" ]]; then
+    echo "${INSTALL_DIR} is not a directory!"
+    exit 1
+  fi
+
+  local -r BIN_INSTALL="${INSTALL_DIR}/bin"
+  if [[ ! -e "${BIN_INSTALL}" ]]; then
+    mkdir -m 700 "${BIN_INSTALL}"
+  fi
+  if [[ ! -d "${BIN_INSTALL}" ]]; then
+    echo "${BIN_INSTALL} is not a directory!"
+    exit 1
+  fi
+
+  # Fetch the binaries.
+  local -r BIN_SOURCE="$1"
+  get_binaries "${BIN_INSTALL}" "${BIN_SOURCE}"
+  for bin_name in "${BIN_NAMES[@]}"; do
+    local BINARY="${BIN_INSTALL}/${bin_name}"
+    if [[ ! -s "${BINARY}" ]]; then
+      echo "${BINARY} is empty."
+      exit 1
+    fi
+  done
+  echo "Using binaries in ${BIN_INSTALL}."
+
+  # Set up the script to be run by the agent.  It first optionally seeks a
+  # blessing, and then runs an interactive shell.
+
+  local -r CREDENTIALS_DIR="${INSTALL_DIR}/principal"
+  if [[ ! -d "${CREDENTIALS_DIR}" ]]; then
+    SEEK_BLESSING="1"
+  fi
+
+  # Use a custom rcfile to optionally get a blessing and also to modify the
+  # shell prompt to include the default veyron blessing.
+  cat <<EOF > "${INSTALL_DIR}/rcfile"
+if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
+if [[ "${SEEK_BLESSING}" -eq "1" ]]; then
+  "${BIN_INSTALL}/principal" seekblessings
+fi
+GREENBOLD="\[\033[1;32m\]"
+default_blessing() {
+  "${BIN_INSTALL}/principal" dump | grep "Default blessings" | sed -e 's/Default blessings: //'
+}
+export PS1="\${PS1}(\${GREENBOLD}\$(default_blessing)\[\033[0m\])$ "
+EOF
+
+VEYRON_CREDENTIALS="${CREDENTIALS_DIR}" exec "${BIN_INSTALL}/agentd" bash --rcfile "${INSTALL_DIR}/rcfile"
+}
+
+main "$@"