-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsecrecy.sh
256 lines (235 loc) · 6.97 KB
/
secrecy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#!/bin/bash
HISTCONTROL=ignorespace:ignoredups
function unlock-secrets {
if ! [[ -f $HOME/.secrets ]]; then
msg-info "This is your first time setting up a secret hoard"
PASS1=''
while [[ -z $PASS1 ]]; do
ask-password "What is a great secure password for encrypting your secrets?"
PASS1="$ASK"
ask-password "What was the password again?"
PASS2="$ASK"
if [[ "$PASS1" == "$PASS2" ]]; then
msg-success "Passwords match, creating secret hoard"
SECRET_PASSWORD="$PASS1"
else
msg-error "Passwords do not match"
PASS1=''
fi
done
echo '{}' | openssl enc -aes-256-cbc -k "$SECRET_PASSWORD" -out $HOME/.secrets
fi
while [[ "$SECRET_PASSWORD" == "" ]]; do
ask-password "What is the secret password?"
SECRET_PASSWORD="$ASK"
if ALL_SECRETS=`openssl enc -d -aes-256-cbc -k "$SECRET_PASSWORD" -in $HOME/.secrets`; then
msg-success "Secret hoard unlocked"
else
msg-error "Wrong password"
SECRET_PASSWORD=''
fi
done
}
function dump-secrets {
unlock-secrets
if [ -f $HOME/.secrets ]; then
ALL_SECRETS=`openssl enc -d -aes-256-cbc -k "$SECRET_PASSWORD" -in $HOME/.secrets 2>/dev/null`
if [ "$?" == "0" ]; then
echo "$ALL_SECRETS"
else
msg-error "Wrong password, try again" 1>&2
SECRET_PASSWORD=''
return 2
fi
else
msg-error "No secrets found" 1>&2
return 1
fi
ALL_SECRETS=""
}
PYTHON_PRINT_SECRET_CODE='
import json,sys
stdin_content=sys.stdin.read()
all_secrets=json.loads(stdin_content)
key=sys.argv[1]
print(all_secrets[key])
'
function print-secret {
unlock-secrets
if ALL_SECRETS=`dump-secrets`; then
echo "$ALL_SECRETS" | python3 -c "$PYTHON_PRINT_SECRET_CODE" "$1" 2> /dev/null
RETCODE="$?"
else
RETCODE=1
fi
ALL_SECRETS=""
return $RETCODE
}
PYTHON_SET_SECRET_CODE='
import json,sys
stdin_content=sys.stdin.read()
all_secrets=json.loads(stdin_content)
key=sys.argv[1]
value=sys.argv[2]
all_secrets[key] = value
print(json.dumps(all_secrets))
'
function set-secret {
unlock-secrets
if ! [ -f $HOME/.secrets ]; then
NEW_SECRETS="{ \"$1\": \"$2\" }"
else
ALL_SECRETS=`openssl enc -d -aes-256-cbc -k "$SECRET_PASSWORD" -in $HOME/.secrets`
NEW_SECRETS=`echo "$ALL_SECRETS" | python3 -c "$PYTHON_SET_SECRET_CODE" "$1" "$2"`
fi
echo "$NEW_SECRETS" | openssl enc -aes-256-cbc -k "$SECRET_PASSWORD" -out $HOME/.secrets
ALL_SECRETS=""
}
function shell_quote {
# run in a subshell to protect the caller's environment
(
sep=''
for arg in "$@"; do
sqesc=$(printf '%s\n' "${arg}" | sed -e "s/'/'\\\\''/g")
printf '%s' "${sep}'${sqesc}'"
sep=' '
done
)
}
function sudo-pass {
local PASSWORD="$1"
shift 1
local PROGRAM=`shell_quote "$@"`
local ASKPASS_SCRIPT=$'#!/bin/bash\necho '"'$PASSWORD'"
local SCRIPT="
echo \"$ASKPASS_SCRIPT\""' > $HOME/askpass.sh
chmod 700 $HOME/askpass.sh
SUDO_ASKPASS=$HOME/askpass.sh sudo -A '"$PROGRAM"'
rm $HOME/askpass.sh
'
echo "$SCRIPT"
}
function ssh-password-sudo {
REMOTE_PASSWORD="$1"
REMOTE_HOST="$2"
shift 2
if [[ "$#" == "0" ]]; then
REMOTE_PROGRAM='bash --rcfile $HOME/bashrc/main'
else
REMOTE_PROGRAM=`shell_quote "$@"`
fi
ASKPASS_SCRIPT=$'#!/bin/bash\necho '"'$REMOTE_PASSWORD'"
X="
echo \"$ASKPASS_SCRIPT\""' > $HOME/askpass.sh
chmod 700 $HOME/askpass.sh
SUDO_ASKPASS=$HOME/askpass.sh sudo -A '"$REMOTE_PROGRAM"'
rm $HOME/askpass.sh
'
ssh -q -t "$REMOTE_HOST" -- "$X"
}
function op_login {
if ! [ -x "$HOME/bin/op" ]; then
msg-error "You must install the 1Password CLI to $HOME/bin/"
msg-error "https://support.1password.com/command-line/"
return 1
else
if [ -f "$HOME/.op/config" ]; then
SHORTHAND=`cat "$HOME/.op/config" | jq '.accounts[0].shorthand' | tr -d '"'`
eval $(op signin "$SHORTHAND")
else
ask-default "What is your 1Password login host?" "my.1password.com"
OP_HOST="$ASK"
ask "What is your email (ex. [email protected]) ?"
OP_EMAIL="$ASK"
ask-default "What is your 1Password account master key?" "AA-BBBBBB-CCCCCC-DDDDDD-EEEEEE-FFFFF-GGGG"
OP_ACCOUNT_KEY="$ASK"
eval $(op signin "$OP_HOST" "$OP_EMAIL" "$OP_ACCOUNT_KEY")
fi
fi
}
function op_ensure_login {
if ! env | grep -q OP_SESSION; then
op_login
fi
}
function op_get_root_password {
URL="$1"
op_ensure_login
SHORTNAME=`echo "$URL" | cut -d'.' -f1`
ALL_ROOT_ITEMS=`op list items | jq '[.[] | select(.overview.ainfo == "root")]'`
Q="[.[] | select(.overview.url == \"$URL\")]"
URL_ITEM=`echo "$ALL_ROOT_ITEMS" | jq "$Q"`
if [ "$URL_ITEM" == '[]' ]; then
# msg-dry "Finding by title"
Q="[.[] | select(.overview.title | contains(\"$SHORTNAME\"))]"
# echo "$Q"
URL_ITEM=`echo "$ALL_ROOT_ITEMS" | jq "$Q"`
fi
if [ "$URL_ITEM" == '[]' ]; then
# msg-dry "Finding by URL"
Q="[.[] | select(.overview.URLs) | select(.overview.URLs | contains([{"u":\"$URL\"}]))]"
# echo "$Q"
URL_ITEM=`echo "$ALL_ROOT_ITEMS" | jq "$Q"`
fi
if [ "$URL_ITEM" == '[]' ]; then
# msg-dry "Finding by URL SHORTNAME"
Q="[.[] | select(.overview.URLs) | select(.overview.URLs | contains([{"u":\"$SHORTNAME\"}]))]"
# echo "$Q"
URL_ITEM=`echo "$ALL_ROOT_ITEMS" | jq "$Q"`
fi
# msg-info "$URL_ITEM"
ITEM_ID=`echo "$URL_ITEM" | jq '.[0].uuid' | tr -d '"'`
# msg-info "$ITEM_ID"
ITEM_DETAILS=`op get item "$ITEM_ID"`
# msg-info "$ITEM_DETAILS"
SUDO_PASS=`echo "$ITEM_DETAILS" | jq '.details.fields[] | select(.name == "password") | .value' | tr -d '"'`
# Fail if the SUDO_PASS is empty
[ "$SUDO_PASS" != "" ]
}
function get-sudo-secret {
REMOTE_HOST="$1"
unlock-secrets
SUDO_PASS=`print-secret "sudo-${REMOTE_HOST}"`
if [[ "$?" != "0" ]]; then
SUDO_PASS=''
echo-err "sudo-${REMOTE_HOST} secret not set"
if [[ "$(type -t op_get_root_password)" == "function" ]]; then
echo-err "Querying 1Password"
op_get_root_password "${REMOTE_HOST}"
fi
if [[ "$?" != "0" ]] || [[ "$SUDO_PASS" == "" ]]; then
ask-password "What is the password to become root?"
SUDO_PASS="$ASK"
fi
set-secret "sudo-${REMOTE_HOST}" "$SUDO_PASS"
ASK=""
fi
}
function ssh-sudo {
REMOTE_HOST="$1"
shift
get-sudo-secret "$REMOTE_HOST"
ssh-password-sudo "$SUDO_PASS" "$REMOTE_HOST" "$@"
}
alias rsync-sudo &>/dev/null && unalias rsync-sudo
function rsync-sudo {
local REMOTE_HOST
for ARG in "$@"; do
if [[ "$ARG" =~ .*:.* ]]; then
REMOTE_HOST=`echo "$ARG" | cut -d: -f1`
fi
done
echo $REMOTE_HOST
get-sudo-secret "$REMOTE_HOST"
rsync --no-owner --no-group -e "$HOME/bin/ssh-password-sudo.sh '$SUDO_PASS'" --progress "$@"
}
if [[ "$shell" == "bash" ]]; then
complete -F _ssh ssh-sudo
complete -F _ssh ssh-password-sudo
complete -F _ssh get-sudo-secret
complete -F _ssh op_get_root_password
complete -F _ssh get-sudo-secret
complete -F _ssh get-sudo-secret
complete -F _ssh get-sudo-secret
complete -F _rsync rsync-sudo
fi