alpha-release

pull/10/head
sobolevn 8 years ago
parent 5e07948831
commit b7a343e1eb

@ -1,572 +0,0 @@
#!/usr/bin/env bash
# Global variables:
WORKING_DIRECTORY="$PWD"
# Folders:
SECRETS_DIR=".gitsecret"
SECRETS_DIR_KEYS="$SECRETS_DIR/keys"
SECRETS_DIR_PATHS="$SECRETS_DIR/paths"
# Files:
SECRETS_DIR_KEYS_MAPPING="$SECRETS_DIR_KEYS/mapping.cfg"
SECRETS_DIR_KEYS_PUBRING="$SECRETS_DIR_KEYS/pubring.gpg"
SECRETS_DIR_KEYS_TRUSTDB="$SECRETS_DIR_KEYS/trustdb.gpg"
SECRETS_DIR_PATHS_MAPPING="$SECRETS_DIR_PATHS/mapping.cfg"
: ${SECRETS_GPG_COMMAND:="gpg"}
GPGLOCAL="$SECRETS_GPG_COMMAND --homedir=$SECRETS_DIR_KEYS --no-permission-warning"
: ${SECRETS_EXTENSION:=".secret"}
# Inner bash :
function _function_exists {
declare -f -F "$1" > /dev/null
echo $?
}
# OS based :
function _os_based {
# Pass function name as first parameter.
# It will be invoked as os-based function with the postfix.
case "$(uname -s)" in
Darwin)
$1_osx ${@:2}
;;
Linux)
$1_linux ${@:2}
;;
# TODO: add MS Windows support.
# CYGWIN*|MINGW32*|MSYS*)
# $1_ms ${@:2}
# ;;
*)
_abort 'unsupported OS.'
;;
esac
}
# File System :
function _set_config {
# First parameter is the KEY, second is VALUE, third is filename.
# The exit status is 0 (true) if the name was found, 1 (false) if not:
local contains=$(grep -Fq "$1" $3; echo $?)
if [[ $contains -eq 0 ]]; then
_os_based __replace_in_file $@
elif [[ $contains -eq 1 ]]; then
echo "$1 = $2" >> "$3"
fi
}
function _file_has_line {
# First parameter is the KEY, second is the filename.
local contains=$(grep -qw "$1" "$2"; echo $?)
# 0 on contains, 1 for error.
echo $contains;
}
function _delete_line {
_os_based __delete_line $@
}
function _temporary_file {
# This function creates temporary file
# which will be removed on system exit.
filename=$(_os_based __temp_file) # is not `local` on purpose.
trap "echo 'cleaning up...'; rm -f $filename;" EXIT
}
function _unique_filename {
# First parameter is base-path, second is filename,
# third is optional extension.
local n=0 result=$2
while [[ 1 ]]; do
if [[ ! -f "$1/$result" ]]; then
break
fi
n=$(( $n + 1 ))
result="$2-$n"
done
echo $result
}
# VCS :
function _check_ignore {
git check-ignore -q "$1";
echo $?
}
# Logic :
function _abort {
>&2 echo "$1 abort."
exit 1
}
function _secrets_dir_exists {
if [[ ! -d $SECRETS_DIR ]]; then
_abort "$SECRETS_DIR does not exist."
fi
}
function _user_required {
_secrets_dir_exists
local error_message="no users found. run 'git secret tell' before adding files."
if [[ ! -f "$SECRETS_DIR_KEYS_PUBRING" ]] ||
[[ ! -f "$SECRETS_DIR_KEYS_TRUSTDB" ]]; then
_abort "$error_message"
fi
local keys_exist=$($GPGLOCAL -n --list-keys)
if [[ -z $keys_exist ]]; then
_abort "$error_message"
fi
}
function _get_raw_filename {
echo "$(dirname "$1")/$(basename "$1" "$SECRETS_EXTENSION")" | sed -e 's#^\./##'
}
function _get_encrypted_filename {
echo "$(dirname "$1")/$(basename "$1" "$SECRETS_EXTENSION")$SECRETS_EXTENSION" | sed -e 's#^\./##'
}
#!/usr/bin/env bash
function __replace_in_file_linux {
sed -i.bak -c "s/^\($1\s*=\s*\).*\$/\1$2/" "$3"
}
function __delete_line_linux {
sed -i.bak -c "/$1/d" "$2"
}
function __temp_file_linux {
local filename=$(mktemp)
echo "$filename"
}
#!/usr/bin/env bash
function __replace_in_file_osx {
sed -i.bak "s/^\($1[[:space:]]*=[[:space:]]*\).*\$/\1$2/" "$3"
}
function __delete_line_osx {
sed -i.bak "/$1/d" "$2"
}
function __temp_file_osx {
: "${TMPDIR:=/tmp}"
local filename=$(mktemp -t _gitsecrets_ )
echo "$filename";
}
#!/usr/bin/env bash
function add {
_user_required
local not_ignored=()
for item in $@; do
# Checking if all files in options are ignored:
if [[ ! -f $item ]]; then
_abort "$item is not a file."
fi
local ignored=$(_check_ignore "$item")
if [[ ! $ignored -eq 0 ]]; then
# collect unignored files.
not_ignored+=("$item")
fi
done
if [[ ! ${#not_ignored[@]} -eq 0 ]]; then
# and show them all at once.
_abort "these files are not ignored: ${not_ignored[@]} ;"
fi
for item in $@; do
# adding files into system, skipping duplicates.
local already_in=$(_file_has_line "$item" "$SECRETS_DIR_PATHS_MAPPING")
if [[ $already_in -eq 1 ]]; then
echo $item >> $SECRETS_DIR_PATHS_MAPPING
fi
done
echo "${#@} items added."
}
#!/usr/bin/env bash
function _show_help_clean {
echo "usage: git secret clean"
echo "removes all the hidden files."
echo
echo " -v shows which files are deleted."
exit 0
}
function clean {
OPTIND=1
local verbose=""
while getopts "vh" opt; do
case "$opt" in
v)
verbose="v"
;;
h)
_show_help_clean
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
[[ ! -z $verbose ]] && echo && echo "cleaing:" || : # bug with custom bash on OSX
find . -name *$SECRETS_EXTENSION -type f | xargs rm -f$verbose
[[ ! -z $verbose ]] && echo || : # bug with custom bash on OSX
}
#!/usr/bin/env bash
function _show_help_hide {
echo "usage: git secret hide"
echo "encrypts all the files added by the 'add' command."
echo
echo " -c clean files before creating new ones."
echo " -v shows which files are deleted."
exit 0
}
function _optional_clean {
OPTIND=1
local clean=0
local opt_string=""
while getopts "cvh" opt; do
case "$opt" in
c) # -c is used for guaranted clean encryption.
clean=1
;;
h)
_show_help_hide
;;
*)
opt_string="$opt_string -$opt"
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
if [[ $clean -eq 1 ]]; then
clean ${opt_string}
fi
}
function hide {
_user_required
_optional_clean $@
local counter=0
while read line; do
local encrypted_filename=$(_get_encrypted_filename $line)
local recipients=$($GPGLOCAL --list-keys | sed -n 's/.*<\(.*\)>.*/-r\1/p')
$GPGLOCAL --use-agent --yes --trust-model=always --encrypt $recipients -o "$encrypted_filename" "$line"
counter=$((counter+1))
done < $SECRETS_DIR_PATHS_MAPPING
echo "done. all $counter files are hidden."
}
#!/usr/bin/env bash
function init {
if [[ -d "$SECRETS_DIR" ]]; then
_abort "already inited."
fi
local ignores=$(_check_ignore "$SECRETS_DIR"/)
if [[ ! $ignores -eq 1 ]]; then
_abort "'${SECRETS_DIR}/' is ignored."
fi
mkdir "$SECRETS_DIR" "$SECRETS_DIR_KEYS" "$SECRETS_DIR_PATHS"
touch "$SECRETS_DIR_KEYS_MAPPING" "$SECRETS_DIR_PATHS_MAPPING"
echo "'${SECRETS_DIR}/' created."
}
#!/usr/bin/env bash
function killperson {
_user_required
if [[ ${#@} -eq 0 ]]; then
_abort "email is required."
fi
$GPGLOCAL --batch --yes --delete-key "$1"
}
#!/usr/bin/env bash
function remove {
_user_required
for item in $@; do
if [[ ! -f "$item" ]]; then
_abort "$item is not a file."
fi
_delete_line "$item" "$SECRETS_DIR_PATHS_MAPPING"
done
local all=${@}
echo "removed from index."
echo "ensure that files: [$all] are now not ignored."
}
#!/usr/bin/env bash
function _show_help_reveal {
echo "usage: git secret reveal"
echo "unencrypts all the files added by the 'add' command."
echo
echo " -d specifies --homedir option for gpg."
exit 0
}
function reveal {
_user_required
OPTIND=1
local homedir=""
local passphrase=""
while getopts "hd:p:" opt; do
case "$opt" in
h)
_show_help_reveal
;;
p)
passphrase=$OPTARG
;;
d)
homedir=$OPTARG
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
local counter=0
while read line; do
local encrypted_filename=$(_get_encrypted_filename "$line")
echo "$line: $encrypted_filename"
local base="$SECRETS_GPG_COMMAND --use-agent -q --decrypt"
if [[ ! -z "$homedir" ]]; then
base="$base --homedir=$homedir"
fi
if [[ ! -z "$passphrase" ]]; then
base="$base --batch --yes --passphrase $passphrase"
fi
$base -o "$line" "$encrypted_filename"
counter=$((counter+1))
done < "$SECRETS_DIR_PATHS_MAPPING"
echo "done. all $counter files are revealed."
}
#!/usr/bin/env bash
function tell {
_secrets_dir_exists
# A POSIX variable
# Reset in case getopts has been used previously in the shell.
OPTIND=1
local email
local homedir
while getopts "h?md:" opt; do
case "$opt" in
h|\?)
usage
;;
m) # Set email of the git current user:
email=$(git config user.email) || email=""
if [[ -z $email ]]; then
_abort "empty email for current git user."
else
echo "$email is not empty"
fi
;;
d)
homedir=$OPTARG
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# Custom argument-parsing:
if [[ -z $email ]]; then
# Email was not set via `-m` and is in $1:
email="$1"
if [[ -z $email ]]; then
_abort "first argument must be an email address."
fi
shift
fi
# This file will be removed automatically:
_temporary_file
local keyfile=$filename
if [[ -z $homedir ]]; then
$SECRETS_GPG_COMMAND --export -a "$email" > "$keyfile"
else
# It means that homedir is set as an extra argument via `-d`:
$SECRETS_GPG_COMMAND --no-permission-warning --homedir="$homedir" --export -a "$email" > "$keyfile"
fi
if [[ ! -s $keyfile ]]; then
_abort 'gpg key is empty. check your key name: `gpg --list-keys`.'
fi
# Importing public key to the local keychain:
$GPGLOCAL --import "$keyfile" > /dev/null 2>&1
echo
echo "done. $email added as a person who knows the secret."
}
#!/usr/bin/env bash
function usage {
if [[ ! -z "$1" ]]; then
echo $@
fi
local commands=""
local separator="|"
for com in `compgen -A function`
do
if [[ ! $com == _* ]]; then
commands+="$com$separator"
fi
done
echo "usage: git secret [${commands%?}]"
exit 0
}
#!/usr/bin/env bash
# encryption: https://www.gnupg.org/gph/en/manual.html#AEN111
# git hooks: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
# adding files to git on pre_commit hook:
# http://stackoverflow.com/questions/3284292/can-a-git-hook-automatically-add-files-to-the-commit
function _check_setup {
# Checking git and secret-plugin setup:
if [[ ! -d ".git" ]] || [[ ! -d ".git/hooks" ]]; then
_abort "repository is broken. try running 'git init' or 'git clone'."
fi
# Checking gpg setup:
local secring="$SECRETS_DIR_KEYS/secring.gpg"
if [[ -f $secring ]] && [[ -s $secring ]]; then
# secring.gpg is not empty, someone has imported a private key.
_abort "it seems that someone has imported a secret key."
fi
}
function _init_script {
# checking for proper set-up:
_check_setup
if [[ $# == 0 ]]; then
usage "no input parameters provided."
fi
# load dependencies:
# for f in ${0%/*}/src/*/*; do [[ -f "$f" ]] && . "$f"; done
# routing the input command:
if [[ `_function_exists $1` == 0 ]] && [[ ! $1 == _* ]]; then
$1 "${@:2}"
else
usage "command $1 not found."
fi
}
set -e
_init_script $@
Loading…
Cancel
Save