From 1f32f2279ce6581c6f92465d39225746cd78a3d2 Mon Sep 17 00:00:00 2001 From: Comma Device Date: Sun, 28 Apr 2024 03:48:55 +0000 Subject: [PATCH] wip --- .gitignore | 3 + system/clearpilot/dev/GithubSshKeys | 3 + system/clearpilot/dev/encrypt.sh | 14 +++++ system/clearpilot/dev/id_rsa.cpt | Bin 0 -> 2642 bytes system/clearpilot/dev/id_rsa.pub.cpt | Bin 0 -> 606 bytes system/clearpilot/dev/provision.sh | 51 ++++++++++++++++- system/clearpilot/tools/decrypt | 17 ++++++ system/clearpilot/tools/encrypt | 17 ++++++ system/clearpilot/tools/faketty.py | 81 +++++++++++++++++++++++++++ system/clearpilot/tools/provision.sh | 41 ++++++++++++++ system/clearpilot/tools/scrun | 37 ++++++++++++ 11 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 system/clearpilot/dev/GithubSshKeys create mode 100644 system/clearpilot/dev/encrypt.sh create mode 100644 system/clearpilot/dev/id_rsa.cpt create mode 100644 system/clearpilot/dev/id_rsa.pub.cpt create mode 100644 system/clearpilot/tools/decrypt create mode 100644 system/clearpilot/tools/encrypt create mode 100644 system/clearpilot/tools/faketty.py create mode 100644 system/clearpilot/tools/provision.sh create mode 100644 system/clearpilot/tools/scrun diff --git a/.gitignore b/.gitignore index 3da75aa..89f06dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +system/clearpilot/dev/reverse_ssh +system/clearpilot/dev/id_rsa +system/clearpilot/dev/id_rsa.pub venv/ .venv/ .ci_cache diff --git a/system/clearpilot/dev/GithubSshKeys b/system/clearpilot/dev/GithubSshKeys new file mode 100644 index 0000000..4d49e5f --- /dev/null +++ b/system/clearpilot/dev/GithubSshKeys @@ -0,0 +1,3 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQtHTzkeRlOXDWyK/IvO2RgjSdoq6V81u3YtcyIxBZVX2zCj1xzE9zWcUcVxloe63rB/DBasChODIRBtp1vGnWb/EkLWAuOqS2V5rzhlcSfM103++TI81e04A7HDspWSNUXRh5OD/mUvwtYIH7S4QAkBiCro5lAgSToXNAOR4b4cXgNQecf+RhPc0Nm3K8Is1wEeQajmlC1E22YWBDDV+uoB3Uagl90e58Psbp8PunCdbeY9EfqQsymyloiTeqzKwHnmHnMXSlZluh7A+ifoKgohDsarT1FixAgxT0LSIxxINORhE4P6em/7y3xpgubPhNpbuQSzDlb3op3fwMoFcAEEYKWg+d9OGOrdiWa13aV0g7UNdW/XmmF/BAaBdSOZeomVNnxmftmmJWfu3jtFdwTDRQpZn7nDYC+aZ1R3Q0Xd4lLuqkA/9smUXLZuiBDJXwM5nDyWQR9tESIwlTLcdKAUpj0gQqpcozVehksNksTekZBAg/mYb6DKyYCTY0ti0= +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCm/Vq50kqf94allqGq9luBGjDh2Do/rOCA719CRlDOErCvdY+ZaYNumQZ5AbFfU5KcPZwirJLBvhEoH/G0lEAg9TUaUgH/VvqBBztlpcmA1eplZHzEFLnTDn0oO4Tk46bXwjL0anOZfNaUGhbaO4Th7m+9+o16WUduEabPiyVbnqD6P44CANsvBJNKlyUDBzsdkE9z5gULp06i1+JqqXiGV81HoFWZe5YCFv4j4QUPvfmFhcBHViVrOFs87hS4Eu0gWNxQmQBhh6R1ZbjaBlGdE5GyDZQZwlofjfuO06e0HvCDuIAELSYqlGFCmUhlM/LZ6YkF79/HFrg5sS3gsuY5 +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHbrOZrByUb2Ci21DdJkhWv/4Bz4oghL9joraQYFq4Om diff --git a/system/clearpilot/dev/encrypt.sh b/system/clearpilot/dev/encrypt.sh new file mode 100644 index 0000000..0e31d2d --- /dev/null +++ b/system/clearpilot/dev/encrypt.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Encrypt SSH keys if source files exist using the custom encrypt tool +if [ -f /data/openpilot/system/clearpilot/dev/id_rsa.pub ]; then + bash /data/openpilot/system/clearpilot/tools/encrypt /data/openpilot/system/clearpilot/dev/id_rsa.pub /data/openpilot/system/clearpilot/dev/id_rsa.pub.cpt +fi + +if [ -f /data/openpilot/system/clearpilot/dev/id_rsa ]; then + bash /data/openpilot/system/clearpilot/tools/encrypt /data/openpilot/system/clearpilot/dev/id_rsa /data/openpilot/system/clearpilot/dev/id_rsa.cpt +fi + +if [ -f /data/openpilot/system/clearpilot/dev/reverse_ssh ]; then + bash /data/openpilot/system/clearpilot/tools/encrypt /data/openpilot/system/clearpilot/dev/reverse_ssh /data/openpilot/system/clearpilot/dev/reverse_ssh.cpt +fi diff --git a/system/clearpilot/dev/id_rsa.cpt b/system/clearpilot/dev/id_rsa.cpt new file mode 100644 index 0000000000000000000000000000000000000000..290617ab2081f9e40ff25b73871d378ad4437a5d GIT binary patch literal 2642 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 sCzMog)Js8FaQ7m literal 0 HcmV?d00001 diff --git a/system/clearpilot/dev/provision.sh b/system/clearpilot/dev/provision.sh index ce91fbb..be91775 100644 --- a/system/clearpilot/dev/provision.sh +++ b/system/clearpilot/dev/provision.sh @@ -1,4 +1,49 @@ +!/bin/bash + +# Provision script for BrianBot +# These actions only occur on BrianBot's comma device. + +# 1. Check the string in /data/params/d/DongleId +dongle_id=$(cat /data/params/d/DongleId) +if [[ ! $dongle_id == 90bb71a* ]]; then + echo "Invalid dongle ID." + exit 1 +fi + +echo "BrianBot dongle ID detected." + +# 2. Check if ccrypt is installed, install if not +if ! command -v ccrypt >/dev/null 2>&1; then + echo "Installing ccrypt..." + sudo apt-get update + sudo apt-get install -y ccrypt +fi + +# 3. Decrypt SSH keys if they have not been decrypted yet +if [ ! -f /data/openpilot/system/clearpilot/dev/id_rsa.pub ]; then + echo "Decrypting SSH keys..." + /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/id_rsa.pub.cpt /data/openpilot/system/clearpilot/dev/id_rsa.pub + /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/id_rsa.cpt /data/openpilot/system/clearpilot/dev/id_rsa + /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/reverse_ssh.cpt /data/openpilot/system/clearpilot/dev/reverse_ssh +fi + +# 4. Ensure .ssh directory and keys exist +ssh_dir="/data/ssh/.ssh" +if [[ ! -f "$ssh_dir/id_rsa" || ! -f "$ssh_dir/id_rsa.pub" ]]; then + echo "Setting up SSH directory and keys..." + mkdir -p "$ssh_dir" + cp /data/openpilot/system/clearpilot/dev/id_rsa /data/openpilot/system/clearpilot/dev/id_rsa.pub "$ssh_dir" + chmod 700 "$ssh_dir" + chmod 600 "$ssh_dir/id_rsa" "$ssh_dir/id_rsa.pub" + echo hansonxyz > /data/params/d/GithubUsername + cat /data/openpilot/system/clearpilot/dev/GithubSshKeys > /data/params/d/GithubSshKeys + echo 1 > /data/params/d/SshEnabled + sudo systemctl restart ssh + cd /data/openpilot + git remote remove origin + git remote add origin git@privategit.hanson.xyz:brianhansonxyz/clearpilot.git +fi + +echo "Script execution complete." +exit 0 -cd /data/openpilot -git remote remove origin -git remote add origin git@privategit.hanson.xyz:brianhansonxyz/clearpilot.git diff --git a/system/clearpilot/tools/decrypt b/system/clearpilot/tools/decrypt new file mode 100644 index 0000000..a736b82 --- /dev/null +++ b/system/clearpilot/tools/decrypt @@ -0,0 +1,17 @@ +#!/bin/bash + +# Check for the correct number of arguments +if [ "$#" -ne 2 ]; then + echo "Usage: $0 source destination" + exit 1 +fi + +# Set variables for source and destination +src="$1" +dest="$2" + +# Read DongleId for decryption key +dongle_id=/data/params/d/DongleId + +# Decrypt the file +cat "$src" | ccrypt -d -k "$dongle_id" > "$dest" diff --git a/system/clearpilot/tools/encrypt b/system/clearpilot/tools/encrypt new file mode 100644 index 0000000..9496892 --- /dev/null +++ b/system/clearpilot/tools/encrypt @@ -0,0 +1,17 @@ +#!/bin/bash + +# Check for the correct number of arguments +if [ "$#" -ne 2 ]; then + echo "Usage: $0 source destination" + exit 1 +fi + +# Set variables for source and destination +src="$1" +dest="$2" + +# Read DongleId for encryption key +dongle_id=/data/params/d/DongleId + +# Encrypt the file +cat "$src" | ccrypt -e -k "$dongle_id" > "$dest" diff --git a/system/clearpilot/tools/faketty.py b/system/clearpilot/tools/faketty.py new file mode 100644 index 0000000..51a9a94 --- /dev/null +++ b/system/clearpilot/tools/faketty.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +from sys import argv +import os +import signal + +# I've had problems with python's File objects at this low a level, so +# we're going to use integers to specify all files in this script. +stdin = 0 +stdout = 1 +stderr = 2 +# Include this if passing the command and arguments to fish to +# prevent fish from applying any expansions. +#import re +#def fish_escape(args): +# def escape_one(arg): +# return "'" + re.sub(r"('|\\)", r'\\\1', arg) + "'" +# escaped_args = map(escape_one, args) +# return ' '.join(escaped_args) + +if len(argv) < 2: + os.write(stderr, +b"""A tragically beautiful piece of hackery, made to fool programs like ls, +grep, rg, and fd into thinking they're actually connected to a terminal. +Its usage: + +pty command [arg1 arg2 ...] + +Examples: +pty ls --color -R | less -r +git log -p | pty rg | less -r +""") + exit(255) + +# We do not use forkpty here because it would block ^Cs from reaching the +# child process. And we don't need that. +ptm, pts = os.openpty() +pid = os.fork() +if pid == 0: + # The child runs this. + # To get the behaviour we want, we only need to replace the process's + # stdout with pts. Everything else should remain in place, so that things + # like `ps -eF | pty rg python | less -r` will still work as intended. + os.dup2(pts, stdout) + # This is not like a subprocess.call(). It replaces the entire child + # process with argv[1:], meaning execvp will not return! Web search + # "fork exec" for more. + os.execvp(argv[1], argv[1:]) + # Use this if calling fish. + #os.execvp('fish', ['fish', '-c', fish_escape(argv[1:])]) + + +# The parent runs this. + +# If the parent doesn't close the slave end, the script won't be able to +# exit. The next read on ptm after the child process terminates would hang +# forever because pts would technically still be open. +os.close(pts) + +# The whole process group gets SIGINT, including the child, so we don't need +# to react to it. We'll know when to leave, judging by what the child does. +signal.signal(signal.SIGINT, signal.SIG_IGN) + +while True: + try: + chunk = os.read(ptm, 4096) + except OSError: + break + try: + os.write(stdout, chunk) + except BrokenPipeError: + # This happens when the parent is piping output to another process in a + # pipeline, like in `pty ls --color -R | less -r`, and the receiving + # process is terminated before the child has exited. If the receiving + # process is less, this can happen very easily. It happens every time + # the user decides to quit less before it has displayed all output. So, + # we need to stop the child process now. + os.kill(pid, signal.SIGTERM) + break +wait_pid, status = os.waitpid(pid, 0) +exit(status >> 8) diff --git a/system/clearpilot/tools/provision.sh b/system/clearpilot/tools/provision.sh new file mode 100644 index 0000000..826201c --- /dev/null +++ b/system/clearpilot/tools/provision.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Provision script for BrianBot +# These actions only occur on BrianBot's comma device. + +# 1. Check the string in /data/params/d/DongleId +dongle_id=$(cat /data/params/d/DongleId) +if [[ ! $dongle_id == 90bb71a* ]]; then + echo "Invalid dongle ID." + exit 1 +fi + +echo "BrianBot dongle ID detected." + +# 2. Check if ccrypt is installed, install if not +if ! command -v ccrypt >/dev/null 2>&1; then + echo "Installing ccrypt..." + sudo apt-get update + sudo apt-get install -y ccrypt +fi + +# 3. Decrypt SSH keys if they have not been decrypted yet +if [ ! -f /data/openpilot/system/clearpilot/dev/id_rsa.pub ]; then + echo "Decrypting SSH keys..." + ccrypt -d -k "$dongle_id" /data/openpilot/system/clearpilot/dev/id_rsa.pub.ccrypt + ccrypt -d -k "$dongle_id" /data/openpilot/system/clearpilot/dev/id_rsa.ccrypt + ccrypt -d -k "$dongle_id" /data/openpilot/system/clearpilot/dev/reverse_ssh.ccrypt +fi + +# 4. Ensure .ssh directory and keys exist +ssh_dir="/home/comma/.ssh" +if [[ ! -f "$ssh_dir/id_rsa" || ! -f "$ssh_dir/id_rsa.pub" ]]; then + echo "Setting up SSH directory and keys..." + mkdir -p "$ssh_dir" + cp /data/openpilot/system/clearpilot/dev/id_rsa /data/openpilot/system/clearpilot/dev/id_rsa.pub "$ssh_dir" + chmod 700 "$ssh_dir" + chmod 600 "$ssh_dir/id_rsa" "$ssh_dir/id_rsa.pub" +fi + +echo "Script execution complete." +exit 0 diff --git a/system/clearpilot/tools/scrun b/system/clearpilot/tools/scrun new file mode 100644 index 0000000..074d598 --- /dev/null +++ b/system/clearpilot/tools/scrun @@ -0,0 +1,37 @@ +#!/bin/bash + +# Usage: +# scrun instancename command + +# - If instancename doesnt exist, starts a screen with instancename and executes the given command. +# - Does not run if the instance is already running. +# - Runs in the same context as a shell (loads environment variables). +# - Logs output into /var/log/scrun/instance/DATE.log, with rotation + +# bash -l -c "$@" + +# Based on https://gist.github.com/camperdave/980040 +echo "defshell -bash" > ~/.screenrc +echo "startup_message off" >> ~/.screenrc +echo "vbell off" >> ~/.screenrc +echo "deflogin on" >> ~/.screenrc +echo "defscrollback 10000" >> ~/.screenrc +echo "defutf8 on" >> ~/.screenrc +echo "defflow off" >> ~/.screenrc +echo "msgwait 20" >> ~/.screenrc +echo "term screen-256color-bce" >> ~/.screenrc + +#SCREENNAME=scrun_$1_ +SCREENNAME=$1 + +screen -wipe 2>/dev/null >/dev/null + +if ! screen -list | grep -q $SCREENNAME; then + cesc="${@:2}" # Everything but first one +# cesc="${cesc@Q}" # Escape it + screen -dmS $SCREENNAME python3 /data/openpilot/system/clearpilot/tools/faketty.py bash -l -c "$cesc" + echo screen -dmS $SCREENNAME python3 /data/openpilot/system/clearpilot/tools/faketty.py bash -l -c "$cesc" +# screen -dmS $1 "$@" +else + echo $SCREENNAME is already running +fi