From 5abf07c7bcbc48d7c40e8fe49a909b895b9990c7 Mon Sep 17 00:00:00 2001 From: Vito Botta Date: Mon, 16 Oct 2023 22:50:52 +0300 Subject: [PATCH] Encrypt the history with openssl --- README.md | 10 +++++----- install.sh | 11 ++++++++--- sync-history.sh | 34 +++++++++++++++++++--------------- zsh.include.sh | 4 ++-- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 6d6693b..48cf466 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # zsh-history-sync -Syncs your zsh shell history between computers using git, easily. Only requirement is to have a **private** git repository on Github or similar. +Syncs your zsh shell history between computers using git and in encrypted format (using openssl), easily. Only requirement is to have a git repository on Github or similar (recommended private although the history is encrypted). Notes: - To eliminate or at least minimise the frequency of conflicts, the history is synced only when the last command was executed at least 15 seconds ago. This way even if you switch from a computer to another quickly, the chance of a sync conflict is greatly reduced compared to a sync at each command. @@ -10,13 +10,13 @@ Notes: ## Installation -You need to clone this repo with the scripts somewhere and run the install script. The install script accepts a single argument for the path of the file to keep in sync in your private git repo, that will contain the synchronised history. The install script updates your .zshrc to load the sync functions. +You need to clone this repo with the scripts somewhere and run the install script. The install will ask you for the path of your git repository that you want to use to synchronise the history, as well as a password to encrypt it (the password will be stored in ~/.zsh-history-sync.encryption-key). The install script then updates your .zshrc to load what's required to trigger the synchronisation in background. ```bash git clone https://github.com/vitobotta/zsh-history-sync.git cd zsh-history-sync -./install.sh +./install.sh source ~/.zshrc ``` @@ -24,13 +24,13 @@ source ~/.zshrc I recommend you also schedule a sync every minute (just to ensure every command is synced since the automatic sync depends on when the ladt command was executed). It's better to specify an offset on the second computer, so to minimise the risk of sync conflicts. Using crontab, on the first computer: ``` -* * * * * /path/of/zsh-history-sync/sync-history.sh /path/of/synced/file +* * * * * /path/of/zsh-history-sync/sync-history.sh /path/of/your/repo ``` On the second computer: ``` -* * * * * sleep 30; /path/of/zsh-history-sync/sync-history.sh /path/of/synced/file +* * * * * sleep 30; /path/of/zsh-history-sync/sync-history.sh /path/of/your/repo ``` diff --git a/install.sh b/install.sh index ee5ba26..7e42847 100755 --- a/install.sh +++ b/install.sh @@ -1,10 +1,15 @@ #!/bin/bash -FILE_TO_SYNC=$1 +echo "Please enter the full path to the git repository you want to use for the syncing:" +read GIT_REPO_PATH + +echo "Please enter the password to use for encryption:" +read -s ENCRYPTION_PASSWORD SCRIPT_PATH="$(readlink -f "$0")" SCRIPT_DIR="$(dirname "$SCRIPT_PATH")" -echo ZSH_HISTORY_SYNC_SCRIPT_PATH="${SCRIPT_DIR}/sync-history.sh" >> ~/.zshrc -echo ZSH_HISTORY_SYNC_FILE_PATH="${FILE_TO_SYNC}" >> ~/.zshrc +echo "export ZSH_HISTORY_SYNC_SCRIPT_PATH=${SCRIPT_DIR}/sync-history.sh" >> ~/.zshrc +echo "export ZSH_HISTORY_SYNC_GIT_REPO_PATH=${GIT_REPO_PATH}" >> ~/.zshrc +echo "${ENCRYPTION_PASSWORD}" > ${HOME}/.zsh-history-sync.encryption-key echo source "${SCRIPT_DIR}/zsh.include.sh" >> ~/.zshrc diff --git a/sync-history.sh b/sync-history.sh index bc18357..92ef7db 100755 --- a/sync-history.sh +++ b/sync-history.sh @@ -1,12 +1,13 @@ -#!/bin/zsh +#!/usr/bin/env zsh -home=$HOME +home="$HOME" +repo_dir="$1" +force_sync="$2" source_file="${home}/.zsh_history" -sync_file=$1 -last_command_timestamp_file="${HOME}/.zsh-last-sync" -force_sync=$2 -identifier=$(hostname) -repo_dir=$(dirname $sync_file) +sync_file="${repo_dir}/zsh_history.enc" +last_command_timestamp_file="${HOME}/.zsh-history-sync.last-sync" +encryption_key_file="${HOME}/.zsh-history-sync.encryption-key" +identifier="$(hostname)" read_file() { if [ ! -f $1 ]; then @@ -22,10 +23,6 @@ read_file() { done } -write_file() { - echo -e "$2" > $1 -} - current_time=$(date +%s) last_executed_time=$(cat $last_command_timestamp_file 2>/dev/null || echo 0) @@ -33,12 +30,20 @@ if (( current_time - last_executed_time >= 15 )) || [ "$force_sync" = "-f" ]; th { git -C $repo_dir pull > /dev/null 2>&1 + if [[ -f $sync_file ]]; then + temp_sync_file=$(mktemp) + openssl enc -aes-256-cbc -md sha256 -d -in "$sync_file" -out "$temp_sync_file" -pass file:"$encryption_key_file" -pbkdf2 + new_items=$(read_file "$temp_sync_file") + rm "$temp_sync_file" + else + new_items="" + fi + source_items=$(read_file $source_file) - new_items=$(read_file $sync_file) items=$(echo -e "$source_items\n$new_items" | sort | uniq) - write_file $source_file "$items" - write_file $sync_file "$items" + echo -e "$items" > $source_file + echo -e "$items" | openssl enc -aes-256-cbc -md sha256 -out "$sync_file" -pass file:"$encryption_key_file" -pbkdf2 fc -R $source_file @@ -49,4 +54,3 @@ if (( current_time - last_executed_time >= 15 )) || [ "$force_sync" = "-f" ]; th git -C $repo_dir push > /dev/null 2>&1 } & fi - diff --git a/zsh.include.sh b/zsh.include.sh index f0c7322..a95e9f0 100644 --- a/zsh.include.sh +++ b/zsh.include.sh @@ -10,7 +10,7 @@ __reload_history() { } __sync_history() { - $ZSH_HISTORY_SYNC_SCRIPT_PATH $ZSH_HISTORY_SYNC_FILE_PATH + $ZSH_HISTORY_SYNC_SCRIPT_PATH $ZSH_HISTORY_SYNC_GIT_REPO_PATH } add-zsh-hook preexec __reload_history @@ -21,4 +21,4 @@ bindkey '^r' fzf-history-widget bindkey '^[[A' fzf-history-widget bindkey '^[OA' fzf-history-widget -alias synchistory="$ZSH_HISTORY_SYNC_SCRIPT_PATH $ZSH_HISTORY_SYNC_FILE_PATH" +alias synchistory="$ZSH_HISTORY_SYNC_SCRIPT_PATH $ZSH_HISTORY_SYNC_GIT_REPO_PATH"