blob: 9a0470140f16be51bc1af4c59451772ab6667f04 [file] [log] [blame]
Bogdan Capritadff07252014-11-12 13:36:55 -08001#!/bin/bash
2#
3# Starts up a shell running under the security agent.
4#
5# Specifically:
6#
7# 1. Fetches the binaries needed to set up the security environment. If it
8# can't fetch fresh binaries, it issues a warning but proceeds with existing
9# binaries, if any.
10#
11# 2. Starts a shell under the agent, optionally fetching a remote blessing if
12# the principal is missing.
13#
Bogdan Caprita9ba7e582014-11-13 20:50:01 -080014# Uses ~/.vbash to store its files, including binaries and the principal.
Bogdan Capritadff07252014-11-12 13:36:55 -080015#
16# Usage:
17#
18# # Gets binaries from local repository
Bogdan Caprita9ba7e582014-11-13 20:50:01 -080019# ./vbash
Bogdan Capritadff07252014-11-12 13:36:55 -080020#
21# # Gets binaries from local filesystem
Bogdan Caprita9ba7e582014-11-13 20:50:01 -080022# ./vbash /path/to/binaries
Bogdan Capritadff07252014-11-12 13:36:55 -080023#
24# # Gets binaries from HTTP server
Bogdan Caprita9ba7e582014-11-13 20:50:01 -080025# ./vbash http://host/path
Bogdan Capritadff07252014-11-12 13:36:55 -080026#
27# Limitations:
28# This only works on Linux and was only tested on goobuntu.
29# TODO(caprita): Make it work on Mac.
30set -e
31
32readonly BIN_NAMES=(principal agentd)
33
34# TODO(caprita): share copy_binaries and get_binaries with nminstall.
35
36###############################################################################
37# Copies one binary from source to destination.
38# Arguments:
39# name of the binary
40# source dir of binary
41# destination dir of binary
42# Returns:
43# None
44###############################################################################
45copy_binary() {
46 local -r BIN_NAME="$1"
47 local -r BIN_SRC_DIR="$2"
48 local -r BIN_DEST_DIR="$3"
49 local -r SOURCE="${BIN_SRC_DIR}/${BIN_NAME}"
50 if [[ -x "${SOURCE}" ]]; then
51 local -r DESTINATION="${BIN_DEST_DIR}/${BIN_NAME}"
52 cp "${SOURCE}" "${DESTINATION}"
53 chmod 700 "${DESTINATION}"
54 else
55 echo "couldn't find ${SOURCE}"
56 exit 1
57 fi
58}
59
60###############################################################################
61# Fetches binaries needed by node manager installation.
62# Globals:
63# BIN_NAMES
64# VEYRON_ROOT
65# Arguments:
66# destination for binaries
67# source of binaries
68# Returns:
69# None
70###############################################################################
71get_binaries() {
72 local -r BIN_INSTALL="$1"
73 local -r BIN_SOURCE="$2"
74
75 local bin_names_str=""
76 for bin_name in "${BIN_NAMES[@]}"; do
77 bin_names_str+=" ${bin_name}"
78 done
79
80 # If source is not specified, try to look for it in the repository.
81 if [[ -z "${BIN_SOURCE}" ]]; then
82 if [[ -z "${VEYRON_ROOT}" ]]; then
83 echo 'ERROR: binary source not specified and no local repository available'
84 exit 1
85 fi
86 local -r REPO_BIN_DIR="${VEYRON_ROOT}/veyron/go/bin"
87 echo "Fetching binaries:${bin_names_str} from build repository: ${REPO_BIN_DIR} ..."
88 for bin_name in "${BIN_NAMES[@]}"; do
89 copy_binary "${bin_name}" "${REPO_BIN_DIR}" "${BIN_INSTALL}"
90 done
91 return
92 fi
93
94 # If the source is specified as an existing local filesystem path,
95 # look for the binaries there.
96 if [[ -d "${BIN_SOURCE}" ]]; then
97 echo "Fetching binaries:${bin_names_str} locally from: ${BIN_SOURCE} ..."
98 for bin_name in "${BIN_NAMES[@]}"; do
99 copy_binary "${bin_name}" "${BIN_SOURCE}" "${BIN_INSTALL}"
100 done
101 return
102 fi
103
104 # If the source looks like a URL, use HTTP to fetch.
105 local -r URL_REGEXP='^(https?|ftp|file)://'
106 if [[ "${BIN_SOURCE}" =~ ${URL_REGEXP} ]]; then
107 echo "Fetching binaries:${bin_names_str} remotely from: ${BIN_SOURCE} ..."
108 for bin_name in "${BIN_NAMES[@]}"; do
109 local DEST="${BIN_INSTALL}/${bin_name}"
110 curl -f -o "${DEST}" "${BIN_SOURCE}/${bin_name}"
111 chmod 700 "${DEST}"
112 done
113 return
114 fi
115
116 echo "WARNING: couldn't fetch binaries."
117}
118
119main() {
Bogdan Caprita9ba7e582014-11-13 20:50:01 -0800120 if [[ ! -z "${VBASH_INDICATOR}" ]]; then
121 echo "Disallowing running VBASH within VBASH."
Bogdan Capritadff07252014-11-12 13:36:55 -0800122 echo "https://memegen.googleplex.com/5551020600983552"
123 exit 1
124 fi
Bogdan Caprita9ba7e582014-11-13 20:50:01 -0800125 export VBASH_INDICATOR="1"
Bogdan Capritadff07252014-11-12 13:36:55 -0800126
Bogdan Caprita9ba7e582014-11-13 20:50:01 -0800127 local -r INSTALL_DIR="${HOME}/.vbash"
Bogdan Capritadff07252014-11-12 13:36:55 -0800128 if [[ ! -e "${INSTALL_DIR}" ]]; then
129 mkdir -m 700 "${INSTALL_DIR}"
130 fi
131 if [[ ! -d "${INSTALL_DIR}" ]]; then
132 echo "${INSTALL_DIR} is not a directory!"
133 exit 1
134 fi
135
136 local -r BIN_INSTALL="${INSTALL_DIR}/bin"
137 if [[ ! -e "${BIN_INSTALL}" ]]; then
138 mkdir -m 700 "${BIN_INSTALL}"
139 fi
140 if [[ ! -d "${BIN_INSTALL}" ]]; then
141 echo "${BIN_INSTALL} is not a directory!"
142 exit 1
143 fi
144
145 # Fetch the binaries.
146 local -r BIN_SOURCE="$1"
147 get_binaries "${BIN_INSTALL}" "${BIN_SOURCE}"
148 for bin_name in "${BIN_NAMES[@]}"; do
149 local BINARY="${BIN_INSTALL}/${bin_name}"
150 if [[ ! -s "${BINARY}" ]]; then
151 echo "${BINARY} is empty."
152 exit 1
153 fi
154 done
155 echo "Using binaries in ${BIN_INSTALL}."
156
157 # Set up the script to be run by the agent. It first optionally seeks a
158 # blessing, and then runs an interactive shell.
159
160 local -r CREDENTIALS_DIR="${INSTALL_DIR}/principal"
161 if [[ ! -d "${CREDENTIALS_DIR}" ]]; then
162 SEEK_BLESSING="1"
163 fi
164
165 # Use a custom rcfile to optionally get a blessing and also to modify the
166 # shell prompt to include the default veyron blessing.
167 cat <<EOF > "${INSTALL_DIR}/rcfile"
168if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
169if [[ "${SEEK_BLESSING}" -eq "1" ]]; then
170 "${BIN_INSTALL}/principal" seekblessings
171fi
172GREENBOLD="\[\033[1;32m\]"
173default_blessing() {
174 "${BIN_INSTALL}/principal" dump | grep "Default blessings" | sed -e 's/Default blessings: //'
175}
176export PS1="\${PS1}(\${GREENBOLD}\$(default_blessing)\[\033[0m\])$ "
177EOF
178
179VEYRON_CREDENTIALS="${CREDENTIALS_DIR}" exec "${BIN_INSTALL}/agentd" bash --rcfile "${INSTALL_DIR}/rcfile"
180}
181
182main "$@"