#!/bin/sh . "$(dirname "$0")/utils" check_bin openssl check_bin http usage() { echo "Usage: $0 <--fake|--agent> " echo "" echo "Modes:" echo " --fake Register a fake device via API (no agent/tunnel)" echo " --agent Spawn a real agent container (SSH, SCP, tunnel)" echo "" echo "Examples:" echo " $0 --fake 00000000-0000-4000-0000-000000000000" echo " $0 --agent 00000000-0000-4000-0000-000000000000" } ssh_uint32() { printf "$(printf '\\%03o\\%03o\\%03o\\%03o' $(($1 >> 24 & 255)) $(($1 >> 16 & 255)) $(($1 >> 8 & 255)) $(($1 & 255)))" } ssh_string_file() { ssh_uint32 "$(wc -c < "$1" | tr -d ' ')" cat "$1" } ssh_string() { printf %s "$1" > "$WORK_DIR/field" ssh_string_file "$WORK_DIR/field" } add_fake_device() { TENANT_ID=$1 ID=$(echo "raspbian ubuntucore arch debian ubuntu" | cut -d' ' -f$(shuf -i1-5 -n1)) PRETTY_NAME=$ID MACADDR=$(echo -n 02; dd bs=1 count=5 if=/dev/random 2>/dev/null | hexdump -v -e '/1 ":%02X"') WORK_DIR=$(mktemp -d) trap 'rm -rf "$WORK_DIR"' EXIT openssl genpkey -algorithm RSA -out "$WORK_DIR/key" -pkeyopt rsa_keygen_bits:2048 2> /dev/null openssl rsa -in "$WORK_DIR/key" -out "$WORK_DIR/key.pub" -pubout 2> /dev/null CHALLENGE=$(http --ignore-stdin --check-status --body post "$SHELLHUB_URL/api/devices/auth/challenge" | sed -n 's/.*"challenge" *: *"\([^"]*\)".*/\1/p') [ -z "$CHALLENGE" ] && echo "Error: the server issued no device auth challenge" && exit 1 { ssh_string "shellhub-device-auth-v1" ssh_string "$CHALLENGE" ssh_string "$TENANT_ID" ssh_string "" ssh_string_file "$WORK_DIR/key.pub" } > "$WORK_DIR/statement" openssl dgst -sha256 -sign "$WORK_DIR/key" -out "$WORK_DIR/signature" "$WORK_DIR/statement" SIGNATURE=$({ ssh_string "rsa-sha2-256" ssh_string_file "$WORK_DIR/signature" } | base64 | tr -d '\n') http --ignore-stdin --check-status post "$SHELLHUB_URL/api/devices/auth" \ sessions:='[]' \ info:="{\"id\": \"$ID\", \"pretty_name\": \"$PRETTY_NAME\", \"version\": \"latest\", \"platform\": \"native\"}" \ identity:="{\"mac\": \"$MACADDR\"}" \ public_key=@"$WORK_DIR/key.pub" \ tenant_id="$TENANT_ID" \ challenge="$CHALLENGE" \ signature="$SIGNATURE" && echo "Device added!" } add_agent_device() { TENANT_ID=$1 TIMESTAMP=$(date +%s) CONTAINER_NAME="shellhub-test-${TIMESTAMP}" HOSTNAME="test-${TIMESTAMP}" echo "Starting real agent container: ${CONTAINER_NAME}" echo "" "${SHELLHUB_PATH}/bin/docker-compose" run \ --name "${CONTAINER_NAME}" \ --detach \ --no-deps \ -e "SHELLHUB_TENANT_ID=${TENANT_ID}" \ -e "SHELLHUB_PREFERRED_HOSTNAME=${HOSTNAME}" \ -e "SHELLHUB_PREFERRED_IDENTITY=root" \ agent echo "" echo "Container: ${CONTAINER_NAME}" echo "Hostname: ${HOSTNAME}" echo "" echo "Useful commands:" echo " docker logs -f ${CONTAINER_NAME}" echo " docker stop ${CONTAINER_NAME} && docker rm ${CONTAINER_NAME}" } case "${1:-}" in --fake) [ -z "${2:-}" ] && echo "Error: is required" && echo "" && usage && exit 1 add_fake_device "$2" ;; --agent) [ -z "${2:-}" ] && echo "Error: is required" && echo "" && usage && exit 1 add_agent_device "$2" ;; --help|-h) usage exit 0 ;; *) usage exit 1 ;; esac