Skip to content

Commit

Permalink
Merge pull request #24 from dokku/jdg-bashstyle
Browse files Browse the repository at this point in the history
Conform to progrium/bashstyle
  • Loading branch information
josegonzalez committed Apr 3, 2016
2 parents e902535 + 006a560 commit dda571a
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 91 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ install:

lint:
@echo linting...
@$(QUIET) find . -not -path '*/\.*' | xargs file | egrep "shell|bash" | awk '{ print $$1 }' | sed 's/://g' | xargs shellcheck
# SC2034: VAR appears unused - https://github.com/koalaman/shellcheck/wiki/SC2034
# desc is used to declare the description of the function
@$(QUIET) find . -not -path '*/\.*' | xargs file | egrep "shell|bash" | awk '{ print $$1 }' | sed 's/://g' | xargs shellcheck -e SC2034

unit-tests:
@echo running unit tests...
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ ssh ls@server <your-args>

## Commands

$ sshcommand create <user> <command> # creates a user forced to run command when SSH connects
$ sshcommand acl-add <user> <ssh-key-name> # adds named SSH key to user from STDIN
$ sshcommand acl-remove <user> <ssh-key-name> # removes SSH key by name
$ sshcommand help # displays the usage help message

```shell
sshcommand create <USER> <COMMAND> # Creates a user forced to run command when SSH connects
sshcommand acl-add <USER> <NAME> # Adds named SSH key to user from STDIN or argument
sshcommand acl-remove <USER> <NAME> # Removes SSH key by name
sshcommand help <COMMAND> # Shows help information
```

## Example

Expand Down
249 changes: 164 additions & 85 deletions sshcommand
Original file line number Diff line number Diff line change
@@ -1,106 +1,185 @@
#!/bin/bash
set -e
#!/usr/bin/env bash
set -eo pipefail; [[ $SSHCOMMAND_TRACE ]] && set -x

shopt -s nocasematch #For case insensitive string matching, for the first parameter

OSRELEASE=/etc/os-release
readonly OSRELEASE=/etc/os-release

f_print_os_name() {
sed -n 's#^NAME="\(.*\)"#\1#p' $OSRELEASE
cmd-help() {
declare desc="Shows help information for a command"
declare args="$*"
if [[ "$args" ]]; then
for cmd; do true; done # last arg
local fn="sshcommand-$cmd"
fn-info "$fn" 1
fi
}

fn-args() {
declare desc="Inspect a function's arguments"
local argline
argline=$(type "$1" | grep declare | grep -v "declare desc" | head -1)
echo -e "${argline// /"\n"}" | awk -F= '/=/{print "<"$1">"}' | tr "\n" " "
}

fn-desc() {
declare desc="Inspect a function's description"
desc=""
eval "$(type "$1" | grep desc | head -1)"; echo $desc
}

fn-info() {
declare desc="Inspects a function"
declare fn="$1" showsource="$2"
local fn_name="${1//sshcommand-/}"
echo "$fn_name $(fn-args "$fn")"
echo " $(fn-desc "$fn")"
echo
if [[ "$showsource" ]]; then
type "$fn" | tail -n +2
echo
fi
}

fn-print-os-name() {
declare desc="Returns the release name of the operating system"
sed -n 's#^NAME="\(.*\)"#\1#p' "$OSRELEASE" | sed 's/./\L&/g'
return 0
}

f_adduser() {
fn-adduser() {
declare desc="Add a user to the system"
local l_user l_platform

l_user=$1
l_platform="$(f_print_os_name)"
l_platform="$(fn-print-os-name)"
case $l_platform in
Debian*|Ubuntu|Raspbian*)
debian*|ubuntu|raspbian*)
adduser --disabled-password --gecos "" "$l_user"
;;
*)
useradd -m -s /bin/bash "$l_user"
groupadd "$l_user"
usermod -L -aG "$l_user" "$l_user"
;;

esac
}

case "$1" in
create) # sshcommand create <user> <command>
if [[ $# -ne 3 ]]; then
echo "Usage : sshcommand create user command"
exit -1
fi
USER="$2"; COMMAND="$3"

if id -u "$USER" >/dev/null 2>&1; then
echo "User '$USER' already exists"
else
f_adduser "$USER"
fi

USERHOME=$(sh -c "echo ~$USER")
mkdir -p "$USERHOME/.ssh"
touch "$USERHOME/.ssh/authorized_keys"
echo "$COMMAND" > "$USERHOME/.sshcommand"
chown -R "$USER" "$USERHOME"
;;

acl-add) # sshcommand acl-add <user> <identifier>
if [[ $# -ne 3 ]]; then
echo "Usage : sshcommand acl-add user identifier"
exit -1
fi
USER="$2"; NAME="$3"

getent passwd "$USER" > /dev/null || false
USERHOME=$(sh -c "echo ~$USER")

NEW_KEY=$(grep "NAME=\\\\\"$NAME"\\\\\" "$USERHOME/.ssh/authorized_keys" || true)
if [ ! -z "$NEW_KEY" ]; then
echo "Duplicate SSH Key name" >&2
exit -1
fi

KEY_FILE=$(mktemp)
KEY=$(tee "$KEY_FILE")
delete_key_file() {
rm -f "$KEY_FILE"
}
trap delete_key_file INT EXIT
FINGERPRINT=$(ssh-keygen -lf "$KEY_FILE" | awk '{print $2}')

if [[ ! "$FINGERPRINT" =~ :.* ]]; then
echo "Invalid ssh public key"
exit -1
fi

KEY_PREFIX="command=\"FINGERPRINT=$FINGERPRINT NAME=\\\"$NAME\\\" \`cat $USERHOME/.sshcommand\` \$SSH_ORIGINAL_COMMAND\",no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
echo "$KEY_PREFIX $KEY" >> "$USERHOME/.ssh/authorized_keys"
echo "$FINGERPRINT"
;;

acl-remove) # sshcommand acl-remove <user> <identifier>
if [[ $# -ne 3 ]]; then
echo "Usage : sshcommand acl-remove user identifier"
exit -1
fi
USER="$2"; NAME="$3"

getent passwd "$USER" > /dev/null || false
USERHOME=$(sh -c "echo ~$USER")

sed --in-place "/ NAME=\\\\\"$NAME\\\\\" /d" "$USERHOME/.ssh/authorized_keys"
;;

help|*) # sshcommand help
echo "Usage : sshcommand create user command"
echo " sshcommand acl-add user identifier"
echo " sshcommand acl-remove user identifier"
echo " sshcommand help # shows this usage message"
;;

esac
log-fail() {
declare desc="Log fail formatter"
echo "$@" 1>&2
exit -1
}

log-verbose() {
declare desc="Log verbose formatter"
if [[ ! -z "$SSHCOMMAND_VERBOSE_OUTPUT" ]]; then
echo "$@"
fi
}

sshcommand-create() {
declare desc="Creates a user forced to run command when SSH connects"
declare USER="$1" COMMAND="$2"
local USERHOME

if [[ -z "$USER" ]] || [[ -z "$COMMAND" ]]; then
log-fail "Usage: sshcommand create" "$(fn-args "sshcommand-create")"
fi

if id -u "$USER" >/dev/null 2>&1; then
log-verbose "User '$USER' already exists"
else
fn-adduser "$USER"
fi

USERHOME=$(sh -c "echo ~$USER")
mkdir -p "$USERHOME/.ssh"
touch "$USERHOME/.ssh/authorized_keys"
echo "$COMMAND" > "$USERHOME/.sshcommand"
chown -R "$USER" "$USERHOME"
}

sshcommand-acl-add() {
declare desc="Adds named SSH key to user from STDIN or argument"
declare USER="$1" NAME="$2"
local FINGERPRINT KEY KEY_FILE KEY_PREFIX NEW_KEY USERHOME

if [[ -z "$USER" ]] || [[ -z "$NAME" ]]; then
log-fail "Usage: sshcommand acl-add" "$(fn-args "sshcommand-acl-add")"
fi

getent passwd "$USER" > /dev/null || false
USERHOME=$(sh -c "echo ~$USER")

NEW_KEY=$(grep "NAME=\\\\\"$NAME"\\\\\" "$USERHOME/.ssh/authorized_keys" || true)
if [[ ! -z "$NEW_KEY" ]]; then
log-fail "Duplicate SSH Key name"
fi

KEY_FILE=$(mktemp)
KEY=$(tee "$KEY_FILE")
delete_key_file() {
rm -f "$KEY_FILE"
}
trap delete_key_file INT EXIT
FINGERPRINT=$(ssh-keygen -lf "$KEY_FILE" | awk '{print $2}')

if [[ ! "$FINGERPRINT" =~ :.* ]]; then
log-fail "Invalid ssh public key"
fi

KEY_PREFIX="command=\"FINGERPRINT=$FINGERPRINT NAME=\\\"$NAME\\\" \`cat $USERHOME/.sshcommand\` \$SSH_ORIGINAL_COMMAND\",no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
echo "$KEY_PREFIX $KEY" >> "$USERHOME/.ssh/authorized_keys"
echo "$FINGERPRINT"
}

sshcommand-acl-remove() {
declare desc="Removes SSH key by name"
declare USER="$1" NAME="$2"
local USERHOME

if [[ -z "$USER" ]] || [[ -z "$NAME" ]]; then
log-fail "Usage: sshcommand acl-remove" "$(fn-args "sshcommand-acl-remove")"
fi

getent passwd "$USER" > /dev/null || false
USERHOME=$(sh -c "echo ~$USER")

sed --in-place "/ NAME=\\\\\"$NAME\\\\\" /d" "$USERHOME/.ssh/authorized_keys"
}

sshcommand-help() {
declare desc="Shows help information"
declare COMMAND="$1"

if [[ -n "$COMMAND" ]]; then
cmd-help "$COMMAND"
return 0
fi

echo "sshcommand"
echo ""
printf " %-10s %-26s %s\n" "create" "$(fn-args "sshcommand-create")" "$(fn-desc "sshcommand-create")"
printf " %-10s %-26s %s\n" "acl-add" "$(fn-args "sshcommand-acl-add")" "$(fn-desc "sshcommand-acl-add")"
printf " %-10s %-26s %s\n" "acl-remove" "$(fn-args "sshcommand-acl-remove")" "$(fn-desc "sshcommand-acl-remove")"
printf " %-10s %-26s %s\n" "help" "$(fn-args "sshcommand-help")" "$(fn-desc "sshcommand-help")"
}

main() {
if [[ -z "$1" ]]; then
sshcommand-help "$@"
exit 1
fi

local cmd="sshcommand-$1"
shift 1

if declare -f $cmd > /dev/null; then
$cmd "$@"
else
log-fail "Invalid command"
fi
}

main "$@"

0 comments on commit dda571a

Please sign in to comment.