-
Notifications
You must be signed in to change notification settings - Fork 0
/
spm.sh
executable file
·394 lines (353 loc) · 9.96 KB
/
spm.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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
#!/bin/bash
#Copyright (C) 2015 JChase2
#This code is free software; you can redistribute it and/or
#modify it under the terms of the GNU Library General Public
#License as published by the Free Software Foundation; either
#version 2 of the License, or (at your option) any later version.
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#Library General Public License for more details.
# Variables invocation and description.
GLOBV="" #Stores initial user input.
SGLOBV="" #Choice of header or string for search function.
ENDVAR="END" #End of block delimiter.
USEKEY="" # Name of private key to encrypt with.
CHKVAR="" #Check if string exists for use in other functions.
# Check if GPG is installed.
type gpg >/dev/null 2>&1 || { echo $'\n' >&2 "GPG does not appear to be installed, exiting." $'\n'; exit 1; }
#Read in filename of GPG file.
gpg_function(){
check_mem
echo "Use tab to search / for completion"
echo -n "GPG Encrypted Password File Path: "
read -e pwfile
PVAR=$(gpg --decrypt $pwfile)
welcome_function
}
# Creates a backup directory and creates
# a backup upon pw file change.
backup_function(){
if [ ! -d pwbackup ] ; then
mkdir pwbackup
fi
cp -a -- "$pwfile" "pwbackup/$pwfile-$(date +"%Y%m%d-%H%M%S")"
if [ $? -gt 0 ]; then # If cp exits with non-zero return.
echo "Backup Failed."
else
echo "Successful Backup."
fi
}
#welcome function
welcome_function(){
echo $'\n'
echo 'Welcome to simple-password-manager.'
echo 'Type '?' or 'help' to print options.'
read -r -p "Command: " GLOBV
input_function
}
again(){
echo -n 'Search Again? (y/n): '
read searchagain
if [[ $searchagain =~ [yY](es)* ]] ; then
echo 'Type 's' to search for a string.'
echo 'Type 'h' to search for a header.'
read -r -p "Command: " GLOBV
input_function
else
welcome_function
fi
}
input_function(){
USRINPUT="$GLOBV"
if [[ $USRINPUT =~ ^([sS])$ ]] ; then
SGLOBV=0
search_function
elif [[ $USRINPUT =~ ^([hH])$ ]] ; then
SGLOBV=1
search_function
elif [[ $USRINPUT =~ ^([lL])$ ]] ; then
list_sections
elif [[ $USRINPUT =~ ^([iI])$ ]] ; then
new_pw
elif [[ $USRINPUT =~ ^([bB])$ ]] ; then
insert_block
elif [[ $USRINPUT =~ ^([kK])$ ]] ; then
remove_string
elif [[ $USRINPUT =~ ^([oO])$ ]] ; then
gpg_function
elif [[ $USRINPUT =~ ^([fF])$ ]] ; then
new_file
elif [[ $USRINPUT =~ ^([nN])$ ]] ; then
add_section
elif [[ $USRINPUT =~ ^([rR])$ ]] ; then
read_file
elif [[ $USRINPUT =~ ^([dD])$ ]] ; then
remove_section
elif [[ $USRINPUT =~ ^([?])$ ]] || [[ $USRINPUT == "help" ]] ; then
print_options
elif [[ $USRINPUT =~ ^([qQ])$ ]] ; then
unset PVAR
exit
else
echo 'Bad input, try again.'
welcome_function
fi
}
print_options(){
echo $'\n'
echo 'Type 'o' to open a password file.'
echo 'Type 'r' to read the entire file.'
echo 'Type 's' to search for a string.'
echo 'Type 'h' to search for a section.'
echo 'Type 'l' to list all sections / headers.'
echo 'Type 'i' to insert a single new line. (e.g a username:password combo.)'
echo 'Type 'b' to insert multiple lines at a time.'
echo 'Type 'n' to create a new section.'
echo 'Type 'd' to delete a section and its contents.'
echo 'Type 'k' to delete a string from a section.'
echo 'Type 'f' to create and open a new encrypted pw file.'
echo 'Type 'q' to quit.'
welcome_function
}
# Check if string exists...
string_exists(){
pattern=$1
lower_a="$pattern" | awk '{print tolower($0)}'
lower_b="$PVAR" | awk '{print tolower($0)}'
for s in "$lower_b"; do
if case ${s} in *"${lower_a}"*) true;; *) false;; esac; then
CHKVAR=0 # Exists...
else
CHKVAR=1
fi
done
}
#Check if gpg file is opened, go to welcome if no.
file_opened(){
if [ -z "$PVAR" ]; then
echo $'\n'
echo 'No password file has been opened, type "o"'
welcome_function
fi
}
search_function() {
tmpresult="$SGLOBV"
file_opened
if [ $tmpresult -eq '1' ] ; then
echo -n 'Type header name to search for: '
read VAR
string_exists "==== $VAR ===="
echo $'\n'
if [ $CHKVAR -eq 0 ]; then
BBVAR=$(grep -i -e "==== $VAR ====" <<< "$PVAR")
AVAR=$(sed -n "/$BBVAR/,/$ENDVAR/p" <<< "$PVAR")
echo "$AVAR"
again
else
echo 'Header does not exist.'
again
fi
elif [ $tmpresult -eq '0' ] ; then
echo -n 'Type string to search for: '
read VVAR
string_exists "$VVAR"
if [ $CHKVAR -eq 0 ]; then
echo $'\n'
NVAR=$(grep -i -e "$VVAR" <<< "$PVAR")
echo "$NVAR"
again
else
echo 'String does not exist.'
again
fi
else
echo "This shouldn't happen."
welcome_function
fi
}
list_sections() {
file_opened
echo -n 'List of section headers:'
echo $'\n'
HSTORE=""
HSTORE=$(sed -n "/====.*====/p" <<< "$PVAR")
HSTORE=$(grep -v "==== $ENDVAR ====" <<< "$HSTORE")
echo "$HSTORE"
welcome_function
}
check_mem(){
cat /proc/meminfo >> meminfodne.txt
AVAR=$(sed -n "/MemFree:/p" meminfodne.txt)
AVAR=$(tr -d -c 0-9 <<< $AVAR)
rm meminfodne.txt
if [ "$AVAR" -lt 100000 ] ; then
echo "You have less than 100mb of ram left. Having a low amount of free ram may"
echo -n "cause data to overflow into swap on the drive. Would you like to continue? y/n: "
read YN
if [[ $YN =~ [yY](es)* ]] ; then
echo "Continuing anyway."
else
exit
fi
else
echo "Memory ok."
fi
}
new_pw(){
file_opened
echo -n 'Enter section to insert information into: '
read VAR
string_exists "==== $VAR ===="
if [ $CHKVAR -eq 1 ]; then
echo $'\n'
echo "Section does not exist."
welcome_function
fi
backup_function
echo -n 'Enter string to insert: '
read NEWPW
string_exists "$NEWPW"
if [ $CHKVAR -eq 0 ]; then
echo $'\n'
echo "String with this name already exists somewhere in the file..."
echo -n "Continue anyway? y/n: "
read ANLVAR
if [[ $ANLVAR =~ [yY](es)* ]] ; then
string_exists "==== $NEWPW ===="
if [ $CHKVAR -eq 0 ]; then
echo $'\n'
echo 'ERROR: PW is the same as a header name. This can'
echo 'create conflicts where removing a pw removes'
echo 'a header name... Operation not complete.'
welcome_function
fi
echo "Continuing Anyway"
else
welcome_function
fi
fi
# This reads in the whole file, IFS= disables delimiting by spaces.
# This preserves leading and trailing whitespaces for formatting purposes.
# -r allows us to get new lines intead of a single really long line.
# Everything is pushed into AVAR, after grep does its thing.
AVAR=$(while IFS= read -r line; do
echo $line
echo $line | grep -qx "==== $VAR ===="
[ $? -eq 0 ] && echo -e "$NEWPW"
done <<< "$PVAR")
PVAR="$AVAR"
get_key
echo "$PVAR" | gpg -o "$pwfile" --encrypt --recipient "$USEKEY"
welcome_function
}
insert_block(){
file_opened
ABLOCK=""
BBLOCK=""
CHECKRESULTS=""
LINECOUNT=0
SAVERESULT=""
echo $'\n'
echo 'Insert data one line at a time, type "quit" and press enter to stop.'
echo $'\n'
while [ "$ABLOCK" != "quit" ]; do
LINECOUNT=$((LINECOUNT+1))
echo -n "Line "$LINECOUNT": "
read -e ABLOCK
if [ "$ABLOCK" != "quit" ]; then
BBLOCK+=$'\n'$ABLOCK
fi
done
echo -n "Would you like to review input?: "
read CHECKRESULTS
if [[ "$CHECKRESULTS" =~ [yY](es)* ]]; then
echo "$BBLOCK" | less
echo -n "Save changes?: "
read SAVERESULT
if [[ "$SAVERESULT" =~ [yY](es)* ]]; then
PVAR+=$'\n'$BBLOCK
welcome_function
fi
fi
PVAR+=$'\n'$BBLOCK
welcome_function
}
new_file(){
echo -n "Enter file name: "
read pwfile
get_key
echo "---simple-pass-manager file---" | gpg -o "$pwfile" --encrypt --recipient "$USEKEY"
PVAR=$(gpg --decrypt $pwfile)
welcome_function
}
read_file(){
file_opened
echo -e "$PVAR" | less
welcome_function
}
get_key(){
echo 'List of your secret Keys: '
gpg --list-secret-keys
echo $'\n'
echo -n 'Type in user ID (name) of key to use from list above: '
read USEKEY
}
add_section(){
file_opened
echo -n "Enter Section Name: "
read USRSEC
string_exists "==== $USRSEC ===="
# Not allowing creation of duplicate headers because deleting
# one will automatically delete the other...
if [ $CHKVAR -eq 0 ]; then
echo $'\n'
echo "A section with this name already exists."
welcome_function
fi
backup_function
PVAR+=$'\n'
PVAR+="==== "$USRSEC" ===="
PVAR+=$'\n'
PVAR+="==== "$ENDVAR" ===="
get_key
echo "$PVAR" | gpg -o "$pwfile" --encrypt --recipient "$USEKEY"
welcome_function
}
remove_section(){
file_opened
echo -n 'Type header of section to remove: '
read VAR
string_exists "==== $VAR ===="
if [ $CHKVAR -eq 0 ]; then
echo $'\n'
backup_function
PVAR=$(sed "/==== $VAR ====/,/$ENDVAR/d" <<< "$PVAR")
get_key
echo "$PVAR" | gpg -o "$pwfile" --encrypt --recipient "$USEKEY"
welcome_function
else
echo $'\n'
echo "Section not found."
welcome_function
fi
}
remove_string(){
file_opened
echo -n 'Type name of string to remove: '
read VAR
string_exists "$VAR"
if [ $CHKVAR -eq 0 ]; then
echo $'\n'
backup_function
PVAR=$(sed -e "s/\<$VAR\>//g" <<< "$PVAR")
get_key
echo "$PVAR" | gpg -o "$pwfile" --encrypt --recipient "$USEKEY"
welcome_function
else
echo $'\n'
echo "String not found."
welcome_function
fi
}
welcome_function