summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2009-07-11 19:04:05 -0400
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>2009-07-11 19:04:05 -0400
commit0e288e3ce07ff84830aeaa414191666fad55db6b (patch)
tree563dc8669574489be4efdc4cf7c2ead745daa665
parent0538dfc4b534ecc9e6d660bdb540abdbfdf97268 (diff)
parent56f591cdd4f4e7032d573f2942f7b6cf3a01c8c2 (diff)
Merge commit 'jrollins/master'
-rw-r--r--packaging/debian/changelog9
-rw-r--r--packaging/debian/control2
-rwxr-xr-xsrc/monkeysphere3
-rwxr-xr-xsrc/monkeysphere-authentication2
-rwxr-xr-xsrc/monkeysphere-host3
-rw-r--r--src/share/common9
-rw-r--r--src/share/m/ssh_proxycommand169
-rw-r--r--src/share/ma/add_certifier4
-rw-r--r--src/share/ma/remove_certifier3
-rw-r--r--src/share/ma/setup6
-rw-r--r--src/share/mh/add_hostname5
-rw-r--r--src/share/mh/add_revoker6
-rw-r--r--src/share/mh/publish_key5
-rw-r--r--src/share/mh/revoke_hostname16
-rw-r--r--src/share/mh/revoke_key6
-rw-r--r--src/share/mh/set_expire3
-rw-r--r--tests/common3
17 files changed, 155 insertions, 99 deletions
diff --git a/packaging/debian/changelog b/packaging/debian/changelog
index f4efc0d..b5d067b 100644
--- a/packaging/debian/changelog
+++ b/packaging/debian/changelog
@@ -12,10 +12,13 @@ monkeysphere (0.25-1~pre) UNRELEASED; urgency=low
- some portability improvements
- properly handle translation of keys with fingerprints with leading
all-zero bytes.
- - resolve symlinks when checking paths (thanks Silvio Rhatto) (closes MS #917)
- * update Standard-Version to 3.8.1
+ - resolve symlinks when checking paths (thanks Silvio Rhatto)
+ (closes MS #917)
+ - explicitly set and use MONKEYSPHERE_GROUP from system "groups"
+ (closes: #534008)
+ * update Standard-Version to 3.8.2
- -- Jameson Graef Rollins <jrollins@finestructure.net> Mon, 29 Jun 2009 11:27:33 -0400
+ -- Jameson Graef Rollins <jrollins@finestructure.net> Sat, 11 Jul 2009 18:55:25 -0400
monkeysphere (0.24-1) unstable; urgency=low
diff --git a/packaging/debian/control b/packaging/debian/control
index 3601c10..5f1444c 100644
--- a/packaging/debian/control
+++ b/packaging/debian/control
@@ -4,7 +4,7 @@ Priority: extra
Maintainer: Jameson Graef Rollins <jrollins@finestructure.net>
Uploaders: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Build-Depends: debhelper (>= 7.0), socat, openssh-server, gnupg, libcrypt-openssl-rsa-perl, libdigest-sha1-perl, lockfile-progs | procmail
-Standards-Version: 3.8.1
+Standards-Version: 3.8.2
Homepage: http://web.monkeysphere.info/
Vcs-Git: git://git.monkeysphere.info/monkeysphere
Dm-Upload-Allowed: yes
diff --git a/src/monkeysphere b/src/monkeysphere
index 6f43632..341b9fd 100755
--- a/src/monkeysphere
+++ b/src/monkeysphere
@@ -144,7 +144,8 @@ check_gpg_authentication_subkey() {
if [ "$validity" = 'u' ] ; then
echo "A valid authentication key already exists for primary key '$keyID'." 1>&2
if [ "$PROMPT" = "true" ] ; then
- read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
+ printf "Are you sure you would like to generate another one? (y/N) " >&2
+ read OK; OK=${OK:N}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "aborting."
fi
diff --git a/src/monkeysphere-authentication b/src/monkeysphere-authentication
index 5b98153..5b30628 100755
--- a/src/monkeysphere-authentication
+++ b/src/monkeysphere-authentication
@@ -120,6 +120,7 @@ LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=$LOG_LEVEL}
KEYSERVER=${MONKEYSPHERE_KEYSERVER:=$KEYSERVER}
CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=$CHECK_KEYSERVER}
MONKEYSPHERE_USER=${MONKEYSPHERE_MONKEYSPHERE_USER:=$MONKEYSPHERE_USER}
+MONKEYSPHERE_GROUP=$(get_primary_group "$MONKEYSPHERE_USER")
PROMPT=${MONKEYSPHERE_PROMPT:=$PROMPT}
AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:=$AUTHORIZED_USER_IDS}
RAW_AUTHORIZED_KEYS=${MONKEYSPHERE_RAW_AUTHORIZED_KEYS:=$RAW_AUTHORIZED_KEYS}
@@ -137,6 +138,7 @@ export MODE
export LOG_LEVEL
export KEYSERVER
export MONKEYSPHERE_USER
+export MONKEYSPHERE_GROUP
export PROMPT
export CHECK_KEYSERVER
export REQUIRED_USER_KEY_CAPABILITY
diff --git a/src/monkeysphere-host b/src/monkeysphere-host
index 507b47f..d498065 100755
--- a/src/monkeysphere-host
+++ b/src/monkeysphere-host
@@ -226,6 +226,7 @@ LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=$LOG_LEVEL}
KEYSERVER=${MONKEYSPHERE_KEYSERVER:=$KEYSERVER}
CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=$CHECK_KEYSERVER}
MONKEYSPHERE_USER=${MONKEYSPHERE_MONKEYSPHERE_USER:=$MONKEYSPHERE_USER}
+MONKEYSPHERE_GROUP=$(get_primary_group "$MONKEYSPHERE_USER")
PROMPT=${MONKEYSPHERE_PROMPT:=$PROMPT}
# other variables
@@ -238,6 +239,7 @@ export LOG_LEVEL
export KEYSERVER
export CHECK_KEYSERVER
export MONKEYSPHERE_USER
+export MONKEYSPHERE_GROUP
export PROMPT
export GNUPGHOME_HOST
export GNUPGHOME
@@ -304,6 +306,7 @@ case $COMMAND in
;;
'diagnostics'|'d')
+ check_host_no_key
load_fingerprint
source "${MHSHAREDIR}/diagnostics"
diagnostics
diff --git a/src/share/common b/src/share/common
index bd887d3..8e2232d 100644
--- a/src/share/common
+++ b/src/share/common
@@ -291,7 +291,8 @@ Please specify how long the key should be valid.
<n>y = key expires in n years
EOF
while [ -z "$keyExpire" ] ; do
- read -p "Key is valid for? (0) " keyExpire
+ printf "Key is valid for? (0) " >&2
+ read keyExpire
if ! test_gpg_expire ${keyExpire:=0} ; then
echo "invalid value" >&2
unset keyExpire
@@ -483,6 +484,12 @@ get_homedir() {
eval "echo ~${uname}"
}
+# return the primary group of a user
+get_primary_group() {
+ local uname=${1:-`whoami`}
+ groups "$uname" | sed 's/^..* : //' | awk '{ print $1 }'
+}
+
### CONVERSION UTILITIES
# output the ssh key for a given key ID
diff --git a/src/share/m/ssh_proxycommand b/src/share/m/ssh_proxycommand
index 74b0f85..322937b 100644
--- a/src/share/m/ssh_proxycommand
+++ b/src/share/m/ssh_proxycommand
@@ -15,6 +15,55 @@
# established. Can be added to ~/.ssh/config as follows:
# ProxyCommand monkeysphere ssh-proxycommand %h %p
+# output the key info, including the RSA fingerprint
+show_key_info() {
+ local keyid="$1"
+ local sshKeyGPGFile
+ local sshFingerprint
+ local gpgSigOut
+ local otherUids
+
+ # get the ssh key of the gpg key
+ sshKeyGPGFile=$(msmktempfile)
+ gpg2ssh "$keyid" >"$sshKeyGPGFile"
+ sshFingerprint=$(ssh-keygen -l -f "$sshKeyGPGFile" | \
+ awk '{ print $2 }')
+ rm -f "$sshKeyGPGFile"
+
+ # get the sigs for the matching key
+ gpgSigOut=$(gpg_user --check-sigs \
+ --list-options show-uid-validity \
+ "$keyid")
+
+ echo | log info
+
+ # output the sigs, but only those on the user ID
+ # we are looking for
+ echo "$gpgSigOut" | awk '
+{
+if (match($0,"^pub")) { print; }
+if (match($0,"^uid")) { ok=0; }
+if (match($0,"^uid.*'$userID'$")) { ok=1; print; }
+if (ok) { if (match($0,"^sig")) { print; } }
+}
+'
+
+ # output ssh fingerprint
+ cat <<EOF
+RSA key fingerprint is ${sshFingerprint}.
+EOF
+
+ # output the other user IDs for reference
+ otherUids=$(echo "$gpgSigOut" | grep "^uid" | grep -v "$userID")
+ if [ "$otherUids" ] ; then
+ log info <<EOF
+Other user IDs on this key:
+EOF
+ echo "$otherUids" | log info
+ fi
+
+}
+
# "marginal case" ouput in the case that there is not a full
# validation path to the host
output_no_valid_key() {
@@ -28,8 +77,6 @@ output_no_valid_key() {
local usage
local sshKeyGPG
local tmpkey
- local sshFingerprint
- local gpgSigOut
local returnCode=0
userID="ssh://${HOSTP}"
@@ -51,63 +98,34 @@ output_no_valid_key() {
Monkeysphere found OpenPGP keys for this hostname, but none had full validity.
EOF
- # if the host key is retrieved from the host, check against known
- # OpenPGP keys
- if [ "$sshKeyOffered" ] ; then
- # find all 'pub' and 'sub' lines in the gpg output, which each
- # represent a retrieved key for the user ID
- echo "$gpgOut" | cut -d: -f1,2,5,10,12 | \
- while IFS=: read -r type validity keyid uidfpr usage ; do
- case $type in
- 'pub'|'sub')
- # get the ssh key of the gpg key
- sshKeyGPG=$(gpg2ssh "$keyid")
+ # output message if host key could not be retrieved from the host
+ if [ -z "$sshKeyOffered" ] ; then
+ log info <<EOF
+Could not retrieve RSA host key from $HOST.
+The following keys were found with marginal validity:
+EOF
+ fi
+
+ # find all 'pub' and 'sub' lines in the gpg output, which each
+ # represent a retrieved key for the user ID
+ echo "$gpgOut" | cut -d: -f1,2,5,10,12 | \
+ while IFS=: read -r type validity keyid uidfpr usage ; do
+ case $type in
+ 'pub'|'sub')
+ # get the ssh key of the gpg key
+ sshKeyGPG=$(gpg2ssh "$keyid")
+
+ # if a key was retrieved from the host...
+ if [ "$sshKeyOffered" ] ; then
# if one of keys found matches the one offered by the
# host, then output info
if [ "$sshKeyGPG" = "$sshKeyOffered" ] ; then
log info <<EOF
An OpenPGP key matching the ssh key offered by the host was found:
-
EOF
- sshKeyGPGFile=$(msmktempfile)
- printf "%s" "$sshKeyGPG" >"$sshKeyGPGFile"
- sshFingerprint=$(ssh-keygen -l -f "$sshKeyGPGFile" | \
- awk '{ print $2 }')
- rm -f "$sshKeyGPGFile"
-
- # get the sigs for the matching key
- gpgSigOut=$(gpg_user --check-sigs \
- --list-options show-uid-validity \
- "$keyid")
-
- # output the sigs, but only those on the user ID
- # we are looking for
- echo "$gpgSigOut" | awk '
-{
-if (match($0,"^pub")) { print; }
-if (match($0,"^uid")) { ok=0; }
-if (match($0,"^uid.*'$userID'$")) { ok=1; print; }
-if (ok) { if (match($0,"^sig")) { print; } }
-}
-' | log info
- echo | log info
-
- # output the other user IDs for reference
- if (echo "$gpgSigOut" | grep "^uid" | grep -v -q "$userID") ; then
- log info <<EOF
-Other user IDs on this key:
-
-EOF
- echo "$gpgSigOut" | grep "^uid" | grep -v "$userID" | log info
- echo | log info
- fi
-
- # output ssh fingerprint
- log info <<EOF
-RSA key fingerprint is ${sshFingerprint}.
-EOF
+ show_key_info "$keyid" | log info
# this whole process is in a "while read"
# subshell. the only way to get information
@@ -117,30 +135,47 @@ EOF
# for the ssh key offered by the host
return 1
fi
- ;;
- esac
- done || returnCode="$?"
- # if no key match was made (and the "while read" subshell
- # returned 1) output how many keys were found
- if (( returnCode != 1 )) ; then
+ # else if a key was not retrieved from the host
+ else
+
+ # if the current key is marginal, show info
+ if [ "$validity" = 'm' -o "$validity" = 'f' ] ; then
+ show_key_info "$keyid" | log info
+ fi
+
+ fi
+ ;;
+ esac
+ done || returnCode="$?"
+
+ # if no key match was made (and the "while read" subshell
+ # returned 1) output how many keys were found
+ if (( returnCode != 1 )) ; then
+
+ echo | log info
+
+ # output different footer messages depending on if a key had
+ # been retrieved from the host
+ if [ "$sshKeyOffered" ] ; then
log info <<EOF
None of the found keys matched the key offered by the host.
-Run the following command for more info about the found keys:
-gpg --check-sigs --list-options show-uid-validity =${userID}
EOF
-
- # FIXME: should we do anything extra here if the retrieved
- # host key is actually in the known_hosts file and the ssh
- # connection will succeed? Should the user be warned?
- # prompted?
+ else
+ log info <<EOF
+There may be other keys with less than marginal validity for this hostname.
+EOF
fi
- # if host key could not be retrieved from the host, output message
- else
log info <<EOF
-Could not retrieve RSA host key from $HOST.
+Run the following command for more info about the found keys:
+gpg --check-sigs --list-options show-uid-validity =${userID}
EOF
+
+ # FIXME: should we do anything extra here if the retrieved
+ # host key is actually in the known_hosts file and the ssh
+ # connection will succeed? Should the user be warned?
+ # prompted?
fi
# output footer
diff --git a/src/share/ma/add_certifier b/src/share/ma/add_certifier
index 402da08..1601997 100644
--- a/src/share/ma/add_certifier
+++ b/src/share/ma/add_certifier
@@ -136,8 +136,8 @@ EOF
gpg_sphere "--fingerprint 0x${fingerprint}!"
if [ "$PROMPT" = "true" ] ; then
- echo "Are you sure you want to add the above key as a certifier"
- read -p "of users on this system? (Y/n) " OK; OK=${OK:-Y}
+ printf "Are you sure you want to add the above key as a certifier\nof users on this system? (Y/n) " >&2
+ read OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "Identity certifier not added."
fi
diff --git a/src/share/ma/remove_certifier b/src/share/ma/remove_certifier
index 6c90358..79f1cda 100644
--- a/src/share/ma/remove_certifier
+++ b/src/share/ma/remove_certifier
@@ -27,7 +27,8 @@ fi
gpg_core --list-key --fingerprint "0x${keyID}!" || failure
if [ "$PROMPT" = "true" ] ; then
- read -p "Really remove the above listed identity certifier? (Y/n) " OK; OK=${OK:-Y}
+ printf "Really remove the above listed identity certifier? (Y/n) " >&2
+ read OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "Identity certifier not removed."
fi
diff --git a/src/share/ma/setup b/src/share/ma/setup
index 4c87009..0ed0406 100644
--- a/src/share/ma/setup
+++ b/src/share/ma/setup
@@ -16,10 +16,10 @@ setup() {
log debug "checking authentication directory structure..."
mkdir -p "${MADATADIR}"
chmod 0750 "${MADATADIR}"
- chgrp "$MONKEYSPHERE_USER" "${MADATADIR}"
+ chgrp "$MONKEYSPHERE_GROUP" "${MADATADIR}"
mkdir -p "${MATMPDIR}"
chmod 0750 "${MATMPDIR}"
- chgrp "$MONKEYSPHERE_USER" "${MATMPDIR}"
+ chgrp "$MONKEYSPHERE_GROUP" "${MATMPDIR}"
mkdir -p "${GNUPGHOME_CORE}"
chmod 0700 "${GNUPGHOME_CORE}"
mkdir -p "${GNUPGHOME_SPHERE}"
@@ -48,7 +48,7 @@ EOF
# make sure the monkeysphere user owns everything in the sphere
# gnupghome
log debug "fixing sphere gnupg home ownership..."
- chown "$MONKEYSPHERE_USER:$MONKEYSPHERE_USER" "${GNUPGHOME_SPHERE}" "${GNUPGHOME_SPHERE}"/gpg.conf
+ chown "$MONKEYSPHERE_USER:$MONKEYSPHERE_GROUP" "${GNUPGHOME_SPHERE}" "${GNUPGHOME_SPHERE}"/gpg.conf
# get fingerprint of core key. this should be empty on unconfigured systems.
local CORE_FPR=$(core_fingerprint)
diff --git a/src/share/mh/add_hostname b/src/share/mh/add_hostname
index 36f174d..9465d96 100644
--- a/src/share/mh/add_hostname
+++ b/src/share/mh/add_hostname
@@ -32,9 +32,8 @@ find_host_userid > /dev/null && \
failure "Host userID '$userID' already exists."
if [ "$PROMPT" = "true" ] ; then
- read -p "The following user ID will be added to the host key:
- $userID
-Are you sure you would like to add this user ID? (Y/n) " OK; OK=${OK:=Y}
+ printf "The following user ID will be added to the host key:\n %s\nAre you sure you would like to add this user ID? (Y/n) " "$userID" >&2
+ read OK; OK=${OK:=Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "User ID not added."
fi
diff --git a/src/share/mh/add_revoker b/src/share/mh/add_revoker
index 077b0d0..89e6fcf 100644
--- a/src/share/mh/add_revoker
+++ b/src/share/mh/add_revoker
@@ -64,7 +64,7 @@ else
# fix permissions and ownership on temporary directory which will
# be used by monkeysphere user for storing the downloaded key
chmod 0700 "$tmpDir"
- chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_USER" "$tmpDir"
+ chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_GROUP" "$tmpDir"
# download the key from the keyserver as the monkeysphere user
log verbose "searching keyserver $KEYSERVER for keyID $keyID..."
@@ -90,8 +90,8 @@ EOF
su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --fingerprint 0x${fingerprint}!"
if [ "$PROMPT" = "true" ] ; then
- read -p "Are you sure you want to add the above key as a revoker
-of the host key? (Y/n) " OK; OK=${OK:-Y}
+ printf "Are you sure you want to add the above key as a revoker\nof the host key? (Y/n) " >&2
+ read OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "revoker not added."
fi
diff --git a/src/share/mh/publish_key b/src/share/mh/publish_key
index b0ffd93..48e4cbb 100644
--- a/src/share/mh/publish_key
+++ b/src/share/mh/publish_key
@@ -18,7 +18,8 @@ publish_key() {
local GNUPGHOME
if [ "$PROMPT" = "true" ] ; then
- read -p "Really publish host key to $KEYSERVER? (Y/n) " OK; OK=${OK:=Y}
+ printf "Really publish host key to $KEYSERVER? (Y/n) " >&2
+ read OK; OK=${OK:=Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "key not published."
fi
@@ -29,7 +30,7 @@ fi
# create a temporary gnupg directory from which to publish the key
export GNUPGHOME=$(msmktempdir)
chmod 0700 "$GNUPGHOME"
-chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_USER" "$GNUPGHOME"
+chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_GROUP" "$GNUPGHOME"
# trap to remove tmp dir if break
trap "rm -rf $GNUPGHOME" EXIT
diff --git a/src/share/mh/revoke_hostname b/src/share/mh/revoke_hostname
index 5dc327f..44ba312 100644
--- a/src/share/mh/revoke_hostname
+++ b/src/share/mh/revoke_hostname
@@ -27,11 +27,12 @@ if [ -z "$1" ] ; then
failure "You must specify a hostname to revoke."
fi
-echo "WARNING: There is a known bug in this function."
-echo "This function has been known to occasionally revoke the wrong hostname."
-echo "Please see the following bug report for more information:"
-echo "https://labs.riseup.net/code/issues/show/422"
-read -p "Are you sure you would like to proceed? (y/N) " OK; OK=${OK:=N}
+echo "WARNING: There is a known bug in this function.
+This function has been known to occasionally revoke the wrong hostname.
+Please see the following bug report for more information:
+https://labs.riseup.net/code/issues/show/422" >&2
+printf "Are you sure you would like to proceed? (y/N) " >&2
+read OK; OK=${OK:=N}
if [ ${OK/y/Y} != 'Y' ] ; then
failure "aborting."
fi
@@ -43,9 +44,8 @@ uidIndex=$(find_host_userid) || \
failure "No non-revoked user ID found matching '$userID'."
if [ "$PROMPT" = "true" ] ; then
- read -p "The following host key user ID will be revoked:
- $userID
-Are you sure you would like to revoke this user ID? (Y/n) " OK; OK=${OK:=Y}
+ printf "The following host key user ID will be revoked:\n %s\nAre you sure you would like to revoke this user ID? (Y/n) " "$userID" >&2
+ read OK; OK=${OK:=Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "User ID not revoked."
fi
diff --git a/src/share/mh/revoke_key b/src/share/mh/revoke_key
index ad68d5f..5460e51 100644
--- a/src/share/mh/revoke_key
+++ b/src/share/mh/revoke_key
@@ -33,7 +33,8 @@ Publishing this certificate will IMMEDIATELY and PERMANENTLY revoke
your host key!
EOF
- read -p "Publish the certificate after generation? (y/n/Q) " publish
+ printf "Publish the certificate after generation? (y/n/Q) " >&2
+ read publish
if ! [ "${publish/y/Y}" = 'Y' -o "${publish/n/N}" = 'N' ] ; then
failure "aborting at user request"
@@ -87,7 +88,8 @@ y
if [ "${publish/y/Y}" = 'Y' ] ; then
printf "\n" >&2
- read -p "Really publish this cert to $KEYSERVER ? (Y/n) " really
+ printf "Really publish this cert to $KEYSERVER ? (Y/n) " >&2
+ read really
if [ "${really/n/N}" = 'N' ] ; then
printf "Not publishing.\n" >&2
else
diff --git a/src/share/mh/set_expire b/src/share/mh/set_expire
index a6bf1f1..9889e76 100644
--- a/src/share/mh/set_expire
+++ b/src/share/mh/set_expire
@@ -22,7 +22,8 @@ local extendTo
extendTo=$(get_gpg_expiration "$1")
if [ "$PROMPT" = "true" ] ; then
- read -p "Are you sure you want to change the expiration on the host key to '$extendTo'? (Y/n) " OK; OK=${OK:-Y}
+ printf "Are you sure you want to change the expiration on the host key to '%s'? (Y/n) " "$extendTo" >&2
+ read OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "expiration not set."
fi
diff --git a/tests/common b/tests/common
index 6d732c8..727ad0f 100644
--- a/tests/common
+++ b/tests/common
@@ -4,7 +4,8 @@ failed_cleanup() {
# FIXME: can we be more verbose here?
echo 'FAILED!'
if [ -z "$MONKEYSPHERE_TEST_NO_EXAMINE" ] ; then
- read -p "press enter to cleanup and remove tmp (or type 'bash' for a subshell to examine): " XX
+ printf "press enter to cleanup and remove tmp (or type 'bash' for a subshell to examine): " >&2
+ read XX
if [ "$XX" = bash ] ; then
echo "Entering subshell..."
cd "$TEMPDIR"