From 2cc820e931a7b0f35348ddaeea37408f071a95d7 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 2 Jul 2013 15:28:27 +0200 Subject: [PATCH] github sync --- sshbackup | 11 ++++ sshsudo | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100755 sshsudo diff --git a/sshbackup b/sshbackup index c24c2d3..a8d1b5a 100755 --- a/sshbackup +++ b/sshbackup @@ -24,6 +24,7 @@ bandwidth=0 limit=0 list=0 noroot=0 +deploy=0 options=$* @@ -51,6 +52,7 @@ usage() echo " -s, --sshkey alternate sshkey [~/.ssh/id_rsa]" echo " -b, --bandwidth bandwidth limit in kbit/s" echo + echo " -d, --deploy deploy settings to remote host" echo " -n, --no-root run without root privileges" echo } @@ -110,9 +112,11 @@ preflight() fi done < /etc/passwd + #if $sshkeyfile is not set use this path if [ -z $sshkeyfile ]; then sshkeyfile="$home/.ssh/id_rsa" fi + if [ -r $sshkeyfile ]; then #ssh key found : @@ -224,6 +228,9 @@ for option in $options; do -n|--no-root) noroot=1 ;; + -d|--deploy) + deploy=1 + ;; *) if [ $config -eq 1 ]; then if [ -r "$option" ]; then @@ -256,6 +263,10 @@ for option in $options; do echo "aborting mission. cannot read listfile. [$option]" exit 1 fi + elif [ $deploy -eq 1 ]; then + #TODO: do nothing for now + : + deploy=0 else if [[ $option =~ ^-.* ]]; then echo "aborting mission. unknown option given. [$option]" diff --git a/sshsudo b/sshsudo new file mode 100755 index 0000000..2c7d449 --- /dev/null +++ b/sshsudo @@ -0,0 +1,146 @@ +#!/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 $*