From b4ba7b50a266a52d19d15c569f3831ff1de9a4a7 Mon Sep 17 00:00:00 2001 From: david Date: Thu, 4 Jul 2013 22:31:21 +0200 Subject: [PATCH] added a sshsudo draft --- sshbackup | 36 ++++++++++++++ sshsudo | 146 ------------------------------------------------------ 2 files changed, 36 insertions(+), 146 deletions(-) delete mode 100755 sshsudo diff --git a/sshbackup b/sshbackup index a8d1b5a..e0f0b9b 100755 --- a/sshbackup +++ b/sshbackup @@ -65,6 +65,42 @@ version() echo } +pipewrap() +{ + echo $1 + local lockfile=$2; + while true; do + if [ ! -e $lockfile ]; then + return 0 + fi + read -t 1 line + if [ $? -eq 0 ]; then + echo $line + fi + done +} + +sshsudo() +{ + local machine=$1 + local password="" + local script=$2 + local arguments=$3 + + read -s -p "please enter your [sudo] password for $machine:" password + echo + + local remotescript=/tmp/sshsudo_`date +%s` + + sshpass -p "$password" scp -q "$script" "$machine:'$remotescript'" + sshpass -p "$password" ssh -q "machine" "sudo -K" + + local lockfile=`mktemp` + + eval pipewrap '$password' '$lockfile' | (sshpass -p "$password" ssh -q "$machine" "sudo -S '$remotescript' $arguments"; rm "$lockfile") + sshpass -p $password ssh -q "$machine" rm $remotescript +} + interactive() { tty -s diff --git a/sshsudo b/sshsudo deleted file mode 100755 index 2c7d449..0000000 --- a/sshsudo +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash - -pipewrap() -{ - # This function reads in the input from a terminal and output the same. - # The only purpose is to insert PASSWORD for "sudo -S" command. - # After initially insert the password, it simply copy input from terminal - # and send it to ssh command directly - echo $1 # which is password - local lockFile=$2; - while true; do - # The function will exit when output pipe is closed, - if [ ! -e $lockFile ]; then - return 0 - fi - # i.e., the ssh - read -t 1 line - if [ $? -eq 0 ]; then - # successfully read - echo $line - fi - done -} - -runsudo() -{ - # receive its arguments - local ACCOUNT=$1; - local PASSWORD=$2; - local COMMAND=$3; - local ARGUMENTS=$4; - local DEFAULTUSER=$5; - local COPY=$6; - local VERBOSE=$7; - - # Parse account which has the form user@computer.domain - local REMOTEUSER=${ACCOUNT%%@*} - local REMOTECOMPUTER=${ACCOUNT#*@} - local REMOTESCRIPT= - local REMOTECOMMAND="$COMMAND" - if [ $REMOTEUSER = $REMOTECOMPUTER ]; then - # There is no @, i.e., only computer name is given - REMOTEUSER=$DEFAULTUSER - fi - #echo =========================${REMOTEUSER}@$REMOTECOMPUTER: sudo $COMMAND $ARGUMENTS - if [ $COPY -ne 0 ]; then - # Make a script + seconds since 1970-01-01 - REMOTESCRIPT=/tmp/$COMMAND`date +%s` - if [ $VERBOSE -ne 0 ]; then - echo $REMOTECOMPUTER: Secure copy \"$COMMAND\" to \"$REMOTESCRIPT\" - fi - # Copy to remote computer. Quote target name on the remote computer for script name - # that contains " " - sshpass -p "$PASSWORD" scp -q "$COMMAND" "$REMOTEUSER@$REMOTECOMPUTER:'$REMOTESCRIPT'" - REMOTECOMMAND=$REMOTESCRIPT - fi - - # Assume we are lucky, result is fine. - local RES=DONE - # Invalidate the sudo timestamp. Simplify the situation. Henceforth sudo always ask for a password - sshpass -p "$PASSWORD" ssh -q "$REMOTEUSER@$REMOTECOMPUTER" "sudo -K" - - # Use lock file to inform pipewrap function to exit. - local lockFile=`mktemp` - eval pipewrap '$PASSWORD' '$lockFile' | (sshpass -p "$PASSWORD" ssh -q "$REMOTEUSER@$REMOTECOMPUTER" "sudo -S '$REMOTECOMMAND' $ARGUMENTS"; rm "$lockFile") - - if [ $? -ne 0 ]; then - RES=FAILED - fi - if [ $COPY -ne 0 ]; then - sshpass -p $PASSWORD ssh -q "$REMOTEUSER@$REMOTECOMPUTER" rm \'$REMOTESCRIPT\' - if [ $VERBOSE -ne 0 ]; then - echo Remove temporary script \"$REMOTESCRIPT\" at [$REMOTECOMPUTER] - fi - fi - #echo ----------------------------------${RES}!!---------------------------------------- -} - -sshsudo() -{ - # Set default values for variables - COMMAND= - ARGUMENTS= - COPY=0 - VERBOSE=0 - ACCOUNTLIST= - DEFAULTUSER=$USER - - # Parse the command line arguments with '-' - while getopts u:rv o ; do - case "$o" in - [?]) echo "unknown option(s): $0 " - exit 1;; - u) DEFAULTUSER=$OPTARG;; - v) VERBOSE=1;; - r) COPY=1;; - esac - done - - # Read the rest command line arguments - if [ $(($#-$OPTIND+1)) -lt 2 ]; then - echo Error: Account list and command have to be in the arguments - exit 4 - fi - - shift $(($OPTIND-1)) - ACCOUNTLIST=$1 - shift - COMMAND=$1 - shift - for PARAM; do - ARGUMENTS=$ARGUMENTS\'$PARAM\'" " - done - - # Check the validity of the script command if remote copy is needed - if [ $COPY -ne 0 ]; then - if [ ! -e "$COMMAND" ]; then - echo \"$COMMAND\" does not exist. - exit 3 - fi - if [ ! -x "$COMMAND" ]; then - echo \"$COMMAND\" can not be executed. - exit 3 - fi - fi - - # Read in the password from the STDIN - read -s -p "Please enter your password:" PASSWORD - echo - - # Start running - if [ -e $ACCOUNTLIST ]; then # read accounts from a file - for ACCOUNT in `cat $ACCOUNTLIST`; do - runsudo "$ACCOUNT" "$PASSWORD" "$COMMAND" "$ARGUMENTS" "$DEFAULTUSER" "$COPY" "$VERBOSE"; - done - - else # ACCOUNTLIST is a comma separated list of user@computer strings. - # Change the internal separation field. - IFS=, - for ACCOUNT in $ACCOUNTLIST; do - runsudo "$ACCOUNT" "$PASSWORD" "$COMMAND" "$ARGUMENTS" "$DEFAULTUSER" "$COPY" "$VERBOSE"; - done - fi -} - -sshsudo $*