sym 2.4.3 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/README.md +42 -34
- data/bin/sym.completion +39 -48
- data/exe/symit +168 -0
- data/lib/sym/app/cli.rb +32 -70
- data/lib/sym/app/cli_slop.rb +17 -18
- data/lib/sym/application.rb +37 -26
- data/lib/sym/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 919e73e972d6bf773f1dd3d41c5d3ced53769d6e
|
4
|
+
data.tar.gz: 14fea598ef6e71bf34daa3efe958fee42ae15c9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8691a7efbd04c1ff7aa305dcc7b7b9dfbd13ca1e9f7fcf3693b35f5eea54f8fc91b48ecec1d9d9df4c1a8032eb200d4129b9f86fd0c6f8bc376619015287bcee
|
7
|
+
data.tar.gz: f78c6e6fb38dc1c6e9be492b1ebd5d76807b832b4d7ee3b58e0d6bfe8bf878d705966925104900fb1a4f2deb1f67fffbecab8ff8e28388ef11f1545f562360af
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,18 @@
|
|
2
2
|
|
3
3
|
## [HEAD](https://github.com/kigster/sym/tree/HEAD)
|
4
4
|
|
5
|
-
[Changes since the last tag](https://github.com/kigster/sym/compare/v2.
|
5
|
+
[Changes since the last tag](https://github.com/kigster/sym/compare/v2.5.0...HEAD)
|
6
|
+
|
7
|
+
## [v2.5.0](https://github.com/kigster/sym/tree/v2.5.0) (2017-02-28)
|
8
|
+
[Full Changelog](https://github.com/kigster/sym/compare/v2.4.3...v2.5.0)
|
9
|
+
|
10
|
+
* Updated README
|
11
|
+
* Remove `-M` flag; make `SYM_ARGS` environment be only used when `-A` flag is supplied
|
12
|
+
* Change `--bash-completion` to use `-B`
|
13
|
+
* Major fix up for sym.completion
|
14
|
+
* New file `exe/symit` for transparently editing secrets
|
15
|
+
* Reworked `Sym::Application`, removed `--dictionary`, and simplified argument parsing.
|
16
|
+
* Refactored `output_proc` to live in `application`.
|
6
17
|
|
7
18
|
## [v2.4.2](https://github.com/kigster/sym/tree/v2.4.2) (2017-02-28)
|
8
19
|
[Full Changelog](https://github.com/kigster/sym/compare/v2.4.1...v2.4.2)
|
data/README.md
CHANGED
@@ -52,24 +52,26 @@ So how does `sym` substantiate its claim that it *streamlines* the encryption pr
|
|
52
52
|
|
53
53
|
As you can see, we really tried to build a tool that provides good security for application secrets, including password-based encryption, but does not annoyingly ask for password every time. With `--edit` option, and `--negate` options you can treat encrypted files like regular files.
|
54
54
|
|
55
|
-
> Encrypting application secrets had never been easier! –– Socrates.
|
55
|
+
> Encrypting application secrets had never been easier! –– Socrates [LOL, -ed.]
|
56
56
|
|
57
57
|
### How It Works
|
58
58
|
|
59
59
|
1. You generate a new encryption key, that will be used to both encrypt and decrypt the data. The key is 256 bits, or 32 bytes, or 45 bytes when base64-encoded, and can be generated with `sym -g`.
|
60
60
|
* You can optionally password protect the key with `sym -gp`
|
61
|
-
* You can save the key into a file `sym -gpo key-file`
|
62
|
-
* Or you can save it into the OS-X Keychain, with `sym -
|
63
|
-
*
|
61
|
+
* You can save the key into a file with `sym -gpo key-file`
|
62
|
+
* Or you can save it into the OS-X Keychain, with `sym -gpx keychain-name`
|
63
|
+
* You can also cache the password, with `sym -gpcx keychain-name`
|
64
|
+
* Normally, `sym` will also print the resulting key to STDOUT.
|
65
|
+
* You can prevent the key from being printed to STDOUT with `-q/--quiet`.
|
64
66
|
2. You then take a piece of sensitive __data__ that you want to encrypt. This can be a file or a string.
|
65
|
-
3. You can then use the key to encrypt sensitive __data__, with `sym -e [key-
|
67
|
+
3. You can then use the key to encrypt sensitive __data__, with `sym -e [key-spec] [data-spec]`, passing it the key in several accepted ways. Smart flag `-k` automatically interpretes the source of the key, by trying:
|
66
68
|
* a file with a pathname.
|
67
69
|
* or environment variable
|
68
70
|
* or OS-X Keychain password entry
|
69
71
|
* or you can paste the key interactively with `-i`
|
70
72
|
4. Input data can be read from a file with `-f file`, or read from STDIN, or a passed on the command line with `-s string`
|
71
73
|
4. Output is the encrypted data, which is printed to STDOUT by the default, or it can be saved to a file with `-o <file>`
|
72
|
-
5. Encrypted file can be later decrypted with `sym -d [key-
|
74
|
+
5. Encrypted file can be later decrypted with `sym -d [key-spec] [data-spec]`
|
73
75
|
|
74
76
|
Sample session that uses Mac OS-X Keychain to store the password-protected key.
|
75
77
|
|
@@ -178,15 +180,15 @@ Or create a password-protected key (`-p`), and save it to a file (`-o`), cache t
|
|
178
180
|
|
179
181
|
##### Key Sources
|
180
182
|
|
181
|
-
You can subsequently use the private key by passing either:
|
183
|
+
You can subsequently use the private key by passing either of these options to the `-k` flag (*sym attempts to resolve the key automatically, by trying each option and moving to the next until the key is found*):
|
182
184
|
|
183
|
-
1. the `-k
|
184
|
-
* a file
|
185
|
+
1. the `-k value` flag, where the *value* is one of:
|
186
|
+
* a file path
|
185
187
|
* an environment variable name
|
186
|
-
* an actual base64-encoded key
|
188
|
+
* an actual base64-encoded key (not recommended for security reasons)
|
187
189
|
* a keychain name
|
188
190
|
2. pasting or typing the key with the `-i` (interactive) flag
|
189
|
-
3. a default key file, in your home folder, `~/.sym.key`, used only when no other flags passed in.
|
191
|
+
3. a default key file, in your home folder, `~/.sym.key`, used only when no other flags were passed in.
|
190
192
|
|
191
193
|
#### Using KeyChain Access on Mac OS-X
|
192
194
|
|
@@ -197,13 +199,14 @@ Apple had released a `security` command line tool, which this library uses to se
|
|
197
199
|
* The private key won't be lying around your file system unencrypted, so if your Mac is ever stolen, you don't need to worry about the keys running wild.
|
198
200
|
* If you sync your keychain with the iCloud you will have access to it on other machines
|
199
201
|
|
200
|
-
|
202
|
+
As mentioned previously, to add the key to the KeyChain on the Mac, use `-x <key-name>` flag with `-g` flag when generating a key. The `key name` is what you call this particular key, based on how you plan to use it. For example, you may call it `staging`, etc.
|
201
203
|
|
202
204
|
The following command generates the private key and immediately stores it in the KeyChain access under the name provided:
|
203
205
|
|
204
|
-
sym -gx staging
|
206
|
+
sym -gx staging # the key is passwordless
|
207
|
+
sym -gpcx staging # this key is password protected, with the password cached
|
205
208
|
|
206
|
-
|
209
|
+
Next, whenever you need to *use* this key, you can specify the key with `-k staging`.
|
207
210
|
|
208
211
|
Finally, you can delete a key from KeyChain access by running:
|
209
212
|
|
@@ -253,17 +256,17 @@ You can optionally store frequently used flags for `sym` in the `SYM_ARGS` envir
|
|
253
256
|
export SYM_ARGS="-cx production"
|
254
257
|
```
|
255
258
|
|
256
|
-
This will
|
259
|
+
This will be automatically appended to the command line if the `-A/--sym-args` flag is provided, and so to encrypt/decrypt anything with password caching enabled and using that particular key, you would simply type:
|
257
260
|
|
258
261
|
```bash
|
259
262
|
# -cx production are added from SYM_ARGS
|
260
|
-
sym -
|
263
|
+
sym -Aef file -o file.enc
|
261
264
|
|
262
265
|
# And to decrypt:
|
263
|
-
sym -
|
266
|
+
sym -Adf file.enc -o file.original
|
264
267
|
|
265
268
|
# Or edit the encrypted file:
|
266
|
-
sym -
|
269
|
+
sym -Atf file.enc
|
267
270
|
```
|
268
271
|
|
269
272
|
#### Complete CLI Usage
|
@@ -271,34 +274,42 @@ sym -tf file.enc
|
|
271
274
|
This may be a good time to take a look at the full help message for the `sym` tool, shown naturally with a `-h` or `--help` option.
|
272
275
|
|
273
276
|
```
|
274
|
-
Sym (2.
|
277
|
+
Sym (2.5.0) – encrypt/decrypt data with a private key
|
275
278
|
|
276
279
|
Usage:
|
277
280
|
# Generate a new key, optionally password protected, and save it
|
278
281
|
# in one of: keychain, file, or STDOUT (-q turns off STDOUT)
|
279
282
|
sym -g [ -p/--password ] [ -x keychain | -o file | ] [ -q ]
|
280
283
|
|
284
|
+
# To specify encryption key, provide the key as
|
285
|
+
# 1) a string, 2) a file path, 3) an OS-X Keychain, 4) env variable name
|
286
|
+
# 5) use -i to paste/type the key interactively
|
287
|
+
# 6) default key file (if present) at /Users/kig/.sym.key
|
288
|
+
KEY-SPEC = -k/--key [ key | file | keychain | environment_variable ]
|
289
|
+
-i/--interactive
|
281
290
|
|
282
291
|
# Encrypt/Decrypt from STDIN/file/args, to STDOUT/file:
|
283
|
-
sym -e/--encrypt
|
284
|
-
sym -d/--decrypt
|
292
|
+
sym -e/--encrypt KEY-SPEC [-f [file | - ] | -s string ] [-o file]
|
293
|
+
sym -d/--decrypt KEY-SPEC [-f [file | - ] | -s string ] [-o file]
|
294
|
+
|
295
|
+
# Auto-detect mode based on a special file extension ".enc"
|
296
|
+
sym -n/--negate KEY-SPEC file[.enc]
|
285
297
|
|
286
298
|
# Edit an encrypted file in $EDITOR
|
287
|
-
sym -t/--edit
|
299
|
+
sym -t/--edit KEY-SPEC -f file [ -b/--backup ]
|
288
300
|
|
289
|
-
#
|
290
|
-
#
|
301
|
+
# Save commonly used flags in a BASH variable. Below we save the KeyChain
|
302
|
+
# "staging" as the default key name, and enable password caching.
|
291
303
|
export SYM_ARGS="-ck staging"
|
292
|
-
|
293
|
-
|
294
|
-
sym -e -f file
|
295
|
-
# May need to disable SYM_ARGS with -M, eg for help:
|
296
|
-
sym -h -M
|
304
|
+
# Then activate $SYM_ARGS by using -A/--sym-args flag:
|
305
|
+
sym -Aef file
|
297
306
|
|
298
307
|
Modes:
|
299
308
|
-e, --encrypt encrypt mode
|
300
309
|
-d, --decrypt decrypt mode
|
301
310
|
-t, --edit edit encrypted file in an $EDITOR
|
311
|
+
-n, --negate [file] encrypts any regular file into file.enc
|
312
|
+
conversely decrypts file.enc into file.
|
302
313
|
|
303
314
|
Create a new private key:
|
304
315
|
-g, --generate generate a new private key
|
@@ -318,8 +329,6 @@ Data to Encrypt/Decrypt:
|
|
318
329
|
-s, --string [string] specify a string to encrypt/decrypt
|
319
330
|
-f, --file [file] filename to read from
|
320
331
|
-o, --output [file] filename to write to
|
321
|
-
-n, --negate [file] encrypts any regular file into file.enc
|
322
|
-
conversely decrypts file.enc into file.
|
323
332
|
|
324
333
|
Flags:
|
325
334
|
-b, --backup create a backup file in the edit mode
|
@@ -329,15 +338,14 @@ Flags:
|
|
329
338
|
-D, --debug print debugging information
|
330
339
|
-V, --version print library version
|
331
340
|
-N, --no-color disable color output
|
332
|
-
-
|
341
|
+
-A, --sym-args read more CLI arguments from $SYM_ARGS
|
333
342
|
|
334
343
|
Utility:
|
335
|
-
-
|
344
|
+
-B, --bash-completion [file] append shell completion to a file
|
336
345
|
|
337
346
|
Help & Examples:
|
338
347
|
-E, --examples show several examples
|
339
348
|
-h, --help show help
|
340
|
-
|
341
349
|
```
|
342
350
|
|
343
351
|
### CLI Usage Examples
|
data/bin/sym.completion
CHANGED
@@ -5,36 +5,27 @@
|
|
5
5
|
# © 2015-2016, Konstantin Gredeskoul, https://github.com/kigster/sym
|
6
6
|
# MIT LICENSE
|
7
7
|
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# TODO: I have removed a "[ -n $tmp ] &&" before 'printf ..',
|
21
|
-
# and everything works again. If this bug suddenly
|
22
|
-
# appears again (i.e. "cd /b<TAB>" becomes "cd /"),
|
23
|
-
# remember to check for other similar conditionals (here
|
24
|
-
# and _filedir_xspec()). --David
|
25
|
-
printf '%s\n' $tmp
|
26
|
-
done
|
27
|
-
}
|
28
|
-
));
|
29
|
-
if [[ "$1" != -d ]]; then
|
30
|
-
[[ ${BASH_VERSINFO[0]} -ge 4 ]] && xspec=${1:+"!*.@($1|${1^^})"} || xspec=${1:+"!*.@($1|$(printf %s $1 | tr '[:lower:]' '[:upper:]'))"};
|
31
|
-
toks=(${toks[@]-} $( compgen -f -X "$xspec" -- $quoted));
|
32
|
-
fi;
|
33
|
-
[ ${#toks[@]} -ne 0 ] && _compopt_o_filenames;
|
34
|
-
COMPREPLY=("${COMPREPLY[@]}" "${toks[@]}")
|
35
|
-
}
|
8
|
+
|
9
|
+
declare -a bash_completion_locations=(/usr/local/etc/bash_completion /usr/etc/bash_completion /etc/bash_completion)
|
10
|
+
loaded=false
|
11
|
+
for file in ${bash_completion_locations[@]}; do
|
12
|
+
[[ -s $file ]] && {
|
13
|
+
source $file
|
14
|
+
break
|
15
|
+
}
|
16
|
+
done
|
17
|
+
|
18
|
+
_sym_long_opts() {
|
19
|
+
sym -h | grep -- '--' | egrep '^ -' | awk '{print $2}' | sort
|
36
20
|
}
|
37
21
|
|
22
|
+
_sym_short_opts() {
|
23
|
+
sym -h | grep -- '--' | egrep '^ -' | awk '{print $1}' | sed 's/,//g' | sort
|
24
|
+
}
|
25
|
+
|
26
|
+
unset _SYM_COMP_LONG_OPTIONS
|
27
|
+
unset _SYM_COMP_SHORT_OPTIONS
|
28
|
+
|
38
29
|
_sym()
|
39
30
|
{
|
40
31
|
local cur prev shell i path
|
@@ -46,33 +37,33 @@ _sym()
|
|
46
37
|
_expand || return 0
|
47
38
|
|
48
39
|
case "$prev" in
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
40
|
+
--@(key|file|output|negate))
|
41
|
+
_filedir
|
42
|
+
return 0
|
43
|
+
;;
|
44
|
+
-@(f|k|o|n))
|
45
|
+
_filedir
|
46
|
+
return 0
|
47
|
+
;;
|
57
48
|
esac
|
58
49
|
|
59
50
|
case "$cur" in
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
51
|
+
--*)
|
52
|
+
export _SYM_COMP_LONG_OPTIONS=${_SYM_COMP_LONG_OPTIONS:-$(_sym_long_opts)}
|
53
|
+
COMPREPLY=($( compgen -W "$_SYM_COMP_LONG_OPTIONS" -- "$cur" ))
|
54
|
+
;;
|
55
|
+
-*)
|
56
|
+
export _SYM_COMP_SHORT_OPTIONS=${_SYM_COMP_SHORT_OPTIONS:-$(_sym_short_opts)}
|
57
|
+
COMPREPLY=($( compgen -W "$_SYM_COMP_SHORT_OPTIONS" -- "$cur" ))
|
58
|
+
;;
|
59
|
+
*)
|
60
|
+
_filedir
|
61
|
+
;;
|
71
62
|
esac
|
72
63
|
|
73
64
|
return 0
|
74
65
|
} &&
|
75
|
-
complete -F _sym $nospace $filenames sym
|
66
|
+
complete -F _sym $nospace $filenames sym
|
76
67
|
|
77
68
|
# Local variables:
|
78
69
|
# mode: shell-script
|
data/exe/symit
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
#
|
3
|
+
#
|
4
|
+
# (c) 2017 Konstantin Gredeskoul
|
5
|
+
# MIT License, distributed as part of `sym` ruby gem
|
6
|
+
#
|
7
|
+
# https://github.com/kigster/sym
|
8
|
+
#
|
9
|
+
#====================================================================================
|
10
|
+
# Purpuse of this script is to transparently edit application secrets in a Rails app.
|
11
|
+
#
|
12
|
+
# Modify the `default*` variables below and then you can use the script like so:
|
13
|
+
#
|
14
|
+
# bin/secred <production | staging | development> [ key-spec ]
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# SET THE VALUE BELOW WITH THE NAME OF YOUR KEY (actual key, environment variable,
|
18
|
+
# keychain name, etc)
|
19
|
+
|
20
|
+
[[ -n $1 && ${1:0:1} != "-" ]] && {
|
21
|
+
encrypted_file=$1
|
22
|
+
shift
|
23
|
+
}
|
24
|
+
|
25
|
+
symit::init() {
|
26
|
+
symit::install
|
27
|
+
|
28
|
+
export default_key=
|
29
|
+
export default_extension="yml.enc"
|
30
|
+
export default_folder=config/settings/secrets
|
31
|
+
|
32
|
+
export true=1
|
33
|
+
export false=0
|
34
|
+
|
35
|
+
export txtrst='\e[0m' # Text Reset
|
36
|
+
export bldred='\e[1;31m' # Red
|
37
|
+
export bldgrn='\e[1;32m' # Green
|
38
|
+
export bldylw='\e[1;33m' # Yellow
|
39
|
+
export bldblu='\e[1;34m' # Blue
|
40
|
+
|
41
|
+
unset cli__opts
|
42
|
+
declare -A cli__opts=(
|
43
|
+
[verbose]=${true}
|
44
|
+
[key]=${default_key}
|
45
|
+
[extension]=${default_extension}
|
46
|
+
[dry_run]=${false}
|
47
|
+
)
|
48
|
+
}
|
49
|
+
|
50
|
+
symit::usage() {
|
51
|
+
printf "${bldblu}symit: ${txtrst}edit an encrypted file using a pre-defined key\n\n"
|
52
|
+
|
53
|
+
printf " Usage: ${bldgrn}symit ${bldylw}[file-spec] [options]${txtrst}\n\n"
|
54
|
+
|
55
|
+
printf " # To edit an encrypted file config/settings/secrets/development.yml.enc${txtrst}\n"
|
56
|
+
printf " ${bldgrn}symit${bldylw} development${txtrst}\n\n"
|
57
|
+
|
58
|
+
printf "options: \n"
|
59
|
+
printf " -k | --key [key-spec] Pass an alternative key, other than ${default_key}\n"
|
60
|
+
printf " -x | --extension [extension] Pass an alternative default extension, other than ${bldylw}${default_extension}${txtrst}\n"
|
61
|
+
printf " -l | --locations Print locations where [file-spec] is searched\n"
|
62
|
+
printf " -h | --help Show this help message\n"
|
63
|
+
printf " -n | --dry-run Show the generated sym command\n"
|
64
|
+
exit 1
|
65
|
+
}
|
66
|
+
|
67
|
+
symit::error() {
|
68
|
+
printf "${bldred}error: $* ${bldylw}\n"
|
69
|
+
exit 255
|
70
|
+
}
|
71
|
+
|
72
|
+
symit::install() {
|
73
|
+
if [[ -z "${_symit__installed}" ]] ; then
|
74
|
+
[[ -n "$(gem list | grep sym)" ]] || gem install sym
|
75
|
+
[[ -z $(sym -h 2>&1 | grep -- '-k, --key' | grep keychain) ]] && {
|
76
|
+
printf "detected missing or an older version of ${bldgrn}sym${txtrst}... upgrading...\n"
|
77
|
+
echo y | gem uninstall sym -a 2>/dev/null
|
78
|
+
gem install sym --verbose
|
79
|
+
}
|
80
|
+
fi
|
81
|
+
}
|
82
|
+
|
83
|
+
symit::show_locations() {
|
84
|
+
printf "Search path: \n"
|
85
|
+
for loc in ${locations[@]}; do
|
86
|
+
printf " - ${loc}\n"
|
87
|
+
done
|
88
|
+
}
|
89
|
+
|
90
|
+
|
91
|
+
symit::locs() {
|
92
|
+
if [[ -n ${encrypted_file} ]]; then
|
93
|
+
declare -a locations=("${default_folder}/${encrypted_file}.${default_extension}"
|
94
|
+
"${default_folder}/${encrypted_file}"
|
95
|
+
"${encrypted_file}")
|
96
|
+
fi
|
97
|
+
echo -n ${locations[*]}
|
98
|
+
}
|
99
|
+
|
100
|
+
symit::init
|
101
|
+
|
102
|
+
[[ -z ${encrypted_file} && -z $* ]] && symit::usage
|
103
|
+
|
104
|
+
while :; do
|
105
|
+
case $1 in
|
106
|
+
-h|-\?|--help)
|
107
|
+
shift
|
108
|
+
symit::usage
|
109
|
+
;;
|
110
|
+
|
111
|
+
-k|--key)
|
112
|
+
shift
|
113
|
+
[[ -n $1 ]] || symit::error "-k/--key requires an argument"
|
114
|
+
cli__opts[key]=$1
|
115
|
+
;;
|
116
|
+
|
117
|
+
-x|--extension)
|
118
|
+
shift
|
119
|
+
[[ -n $1 ]] || symit::error "-x/--extension requires an argument"
|
120
|
+
cli__opts[extension]=$1
|
121
|
+
;;
|
122
|
+
|
123
|
+
-l|--locations)
|
124
|
+
shift
|
125
|
+
[[ -n ${encrypted_file} ]] || symit::error "-l/--locations requires file-spec to be provided as the 1st argument"
|
126
|
+
declare -a locations=$(symit::locs)
|
127
|
+
symit::show_locations
|
128
|
+
exit 0
|
129
|
+
;;
|
130
|
+
-n|--dry-run)
|
131
|
+
shift
|
132
|
+
cli__opts[dry_run]=${true}
|
133
|
+
;;
|
134
|
+
|
135
|
+
--) # End of all options.
|
136
|
+
shift
|
137
|
+
break
|
138
|
+
;;
|
139
|
+
-?*)
|
140
|
+
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
|
141
|
+
exit 127
|
142
|
+
shift
|
143
|
+
;;
|
144
|
+
*) # Default case: If no more options then break out of the loop.
|
145
|
+
break
|
146
|
+
shift
|
147
|
+
esac
|
148
|
+
done
|
149
|
+
|
150
|
+
declare -a locations=$(symit::locs)
|
151
|
+
|
152
|
+
file=
|
153
|
+
for loc in ${locations[@]}; do
|
154
|
+
if [[ -s "${loc}" ]] ; then
|
155
|
+
file=${loc}
|
156
|
+
break
|
157
|
+
fi
|
158
|
+
done
|
159
|
+
|
160
|
+
[[ -z $file ]] && symit::error "${encrypted_file} could not be found."
|
161
|
+
|
162
|
+
command="sym -ck $cli__opts[key] -tf ${file}"
|
163
|
+
|
164
|
+
${cli_opts[dry_run]} && printf "[dry_run] "
|
165
|
+
|
166
|
+
printf "${bldgrn}${command}${txtrst}\n"
|
167
|
+
|
168
|
+
${cli_opts[dry_run]} || ${command}
|
data/lib/sym/app/cli.rb
CHANGED
@@ -56,48 +56,51 @@ module Sym
|
|
56
56
|
# brings in #parse(Array[String] args)
|
57
57
|
include CLISlop
|
58
58
|
|
59
|
-
attr_accessor :opts, :application, :outputs
|
59
|
+
attr_accessor :opts, :application, :outputs
|
60
60
|
|
61
61
|
def initialize(argv)
|
62
62
|
begin
|
63
|
-
|
64
|
-
|
65
|
-
argv.compact!
|
66
|
-
argv_original = argv.dup
|
67
|
-
# Re-map any leg acy options to the new options
|
68
|
-
argv = CLI.replace_argv(argv)
|
69
|
-
dict = argv.delete('--dictionary')
|
63
|
+
|
64
|
+
# Re-map any legacy options to the new options
|
70
65
|
self.opts = parse(argv)
|
71
|
-
|
66
|
+
if opts[:sym_args]
|
67
|
+
append_sym_args(argv)
|
68
|
+
self.opts = parse(argv)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Disable coloring if requested, or if piping STDOUT
|
72
|
+
if opts[:no_color] || !STDOUT.tty?
|
73
|
+
Colored2.disable! # reparse options without the colors to create new help msg
|
74
|
+
self.opts = parse(argv)
|
75
|
+
end
|
76
|
+
|
72
77
|
rescue StandardError => e
|
78
|
+
log :error, "#{e.message}" if opts
|
73
79
|
error exception: e
|
74
80
|
return
|
75
81
|
end
|
76
82
|
|
77
|
-
# Disable coloring if requested, or if piping STDOUT
|
78
|
-
if opts[:no_color] || !STDOUT.tty?
|
79
|
-
command_no_color(argv_original)
|
80
|
-
end
|
81
|
-
|
82
83
|
self.application = ::Sym::Application.new(opts)
|
83
|
-
select_output_stream
|
84
84
|
end
|
85
85
|
|
86
|
-
def
|
87
|
-
env_args =
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
[]
|
86
|
+
def append_sym_args(argv)
|
87
|
+
if env_args = sym_args
|
88
|
+
argv << env_args.split(' ')
|
89
|
+
argv.flatten!
|
90
|
+
argv.compact!
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
94
|
+
def sym_args
|
95
|
+
ENV[Sym::Constants::ENV_ARGS_VARIABLE_NAME]
|
96
|
+
end
|
97
|
+
|
95
98
|
def execute
|
96
99
|
return Sym::App.exit_code if Sym::App.exit_code != 0
|
97
100
|
result = application.execute
|
98
101
|
case result
|
99
102
|
when Hash
|
100
|
-
self.output_proc
|
103
|
+
self.output_proc ::Sym::App::Args.new({}).output_class
|
101
104
|
error(result)
|
102
105
|
else
|
103
106
|
self.output_proc.call(result)
|
@@ -109,46 +112,21 @@ module Sym
|
|
109
112
|
@command ||= self.application&.command
|
110
113
|
end
|
111
114
|
|
115
|
+
def output_proc(proc = nil)
|
116
|
+
self.application&.output = proc if proc
|
117
|
+
self.application&.output
|
118
|
+
end
|
119
|
+
|
112
120
|
def opts_present
|
113
121
|
o = opts.to_hash
|
114
122
|
o.keys.map { |k| opts[k] ? nil : k }.compact.each { |k| o.delete(k) }
|
115
123
|
o
|
116
124
|
end
|
117
125
|
|
118
|
-
class << self
|
119
|
-
# Re-map any legacy options to the new options
|
120
|
-
ARGV_FLAG_REPLACE_MAP = {
|
121
|
-
'C' => 'c'
|
122
|
-
}
|
123
|
-
|
124
|
-
def replace_regex(from)
|
125
|
-
%r{^-([\w]*)#{from}([\w]*)$}
|
126
|
-
end
|
127
|
-
|
128
|
-
def replace_argv(argv)
|
129
|
-
argv = argv.dup
|
130
|
-
replacements = []
|
131
|
-
ARGV_FLAG_REPLACE_MAP.each_pair do |from, to|
|
132
|
-
argv.map! do |a|
|
133
|
-
match = replace_regex(from).match(a)
|
134
|
-
if match
|
135
|
-
replacements << from
|
136
|
-
"-#{match[1]}#{to}#{match[2]}"
|
137
|
-
else
|
138
|
-
a
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
argv
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
126
|
private
|
147
127
|
|
148
|
-
def
|
149
|
-
|
150
|
-
puts options.map(&:to_s).sort.map { |o| "-#{o[1]}" }.join(' ')
|
151
|
-
exit 0
|
128
|
+
def log(*args)
|
129
|
+
Sym::App.log(*args, **(opts.to_hash))
|
152
130
|
end
|
153
131
|
|
154
132
|
def error(hash)
|
@@ -157,22 +135,6 @@ module Sym
|
|
157
135
|
Sym::App.error(**hash)
|
158
136
|
end
|
159
137
|
|
160
|
-
def select_output_stream
|
161
|
-
output_klass = application.args.output_class
|
162
|
-
unless output_klass && output_klass.is_a?(Class)
|
163
|
-
raise "Can not determine output class from arguments #{opts.to_hash}"
|
164
|
-
end
|
165
|
-
self.output_proc = output_klass.new(application.opts).output_proc
|
166
|
-
end
|
167
|
-
|
168
|
-
def command_no_color(argv)
|
169
|
-
Colored2.disable! # reparse options without the colors to create new help msg
|
170
|
-
self.opts = parse(argv.dup)
|
171
|
-
end
|
172
|
-
|
173
|
-
def key_spec
|
174
|
-
'<key-spec>'.bold.magenta
|
175
|
-
end
|
176
138
|
end
|
177
139
|
end
|
178
140
|
end
|
data/lib/sym/app/cli_slop.rb
CHANGED
@@ -14,11 +14,11 @@ module Sym
|
|
14
14
|
o.separator ' sym -g '.green.bold + '[ -p/--password ] [ -x keychain | -o file | ] [ -q ] '.green
|
15
15
|
o.separator ''
|
16
16
|
o.separator ' # To specify encryption key, provide the key as '.dark
|
17
|
-
o.separator ' # 1) a string, 2) a file path, 3) an OS-X Keychain, 4) env variable
|
18
|
-
o.separator ' # 5) use -i to paste/type the key
|
19
|
-
o.separator '
|
20
|
-
o.separator '
|
21
|
-
|
17
|
+
o.separator ' # 1) a string, 2) a file path, 3) an OS-X Keychain, 4) env variable name '.dark
|
18
|
+
o.separator ' # 5) use -i to paste/type the key interactively'.dark
|
19
|
+
o.separator ' # 6) default key file (if present) at '.dark + Sym.default_key_file.magenta.bold
|
20
|
+
o.separator ' ' + key_spec + ' = -k/--key [ key | file | keychain | environment_variable ]'.green.bold
|
21
|
+
o.separator ' -i/--interactive'.green.bold
|
22
22
|
o.separator ''
|
23
23
|
o.separator ' # Encrypt/Decrypt from STDIN/file/args, to STDOUT/file:'.dark
|
24
24
|
o.separator ' sym -e/--encrypt '.green.bold + key_spec + ' [-f [file | - ] | -s string ] [-o file] '.green
|
@@ -29,23 +29,20 @@ module Sym
|
|
29
29
|
o.separator ' '
|
30
30
|
o.separator ' # Edit an encrypted file in $EDITOR '.dark
|
31
31
|
o.separator ' sym -t/--edit '.green.bold + key_spec + ' -f file [ -b/--backup ]'.green.bold
|
32
|
-
|
33
32
|
o.separator ' '
|
34
|
-
o.separator ' # Save commonly used flags in a BASH variable. Below we save KeyChain '.dark
|
35
|
-
o.separator ' # "staging" as the default key
|
33
|
+
o.separator ' # Save commonly used flags in a BASH variable. Below we save the KeyChain '.dark
|
34
|
+
o.separator ' # "staging" as the default key name, and enable password caching.'.dark
|
36
35
|
o.separator ' export SYM_ARGS="'.green + '-ck staging'.bold.green + '"'.green
|
37
|
-
o.separator ' '
|
38
|
-
o.separator '
|
39
|
-
o.separator ' sym -e '.green.bold '-f file'.green.bold
|
40
|
-
o.separator ' # May need to disable SYM_ARGS with -M, eg for help:'.dark
|
41
|
-
o.separator ' sym -h -M '.green.bold
|
36
|
+
o.separator ' # Then activate $SYM_ARGS by using -A/--sym-args flag:'.dark
|
37
|
+
o.separator ' sym -Aef '.green.bold 'file'.green.bold
|
42
38
|
|
43
39
|
o.separator ' '
|
44
40
|
o.separator 'Modes:'.yellow
|
45
41
|
o.bool '-e', '--encrypt', ' encrypt mode'
|
46
42
|
o.bool '-d', '--decrypt', ' decrypt mode'
|
47
43
|
o.bool '-t', '--edit', ' edit encrypted file in an $EDITOR'
|
48
|
-
|
44
|
+
o.string '-n', '--negate', '[file] '.blue + " encrypts any regular #{'file'.green} into #{'file.enc'.green}" + "\n" +
|
45
|
+
" conversely decrypts #{'file.enc'.green} into #{'file'.green}."
|
49
46
|
o.separator ' '
|
50
47
|
o.separator 'Create a new private key:'.yellow
|
51
48
|
o.bool '-g', '--generate', ' generate a new private key'
|
@@ -70,8 +67,6 @@ module Sym
|
|
70
67
|
o.string '-s', '--string', '[string]'.blue + ' specify a string to encrypt/decrypt'
|
71
68
|
o.string '-f', '--file', '[file] '.blue + ' filename to read from'
|
72
69
|
o.string '-o', '--output', '[file] '.blue + ' filename to write to'
|
73
|
-
o.string '-n', '--negate', '[file] '.blue + " encrypts any regular #{'file'.green} into #{'file.enc'.green}" + "\n" +
|
74
|
-
" conversely decrypts #{'file.enc'.green} into #{'file'.green}."
|
75
70
|
|
76
71
|
o.separator ' '
|
77
72
|
o.separator 'Flags:'.yellow
|
@@ -82,11 +77,11 @@ module Sym
|
|
82
77
|
o.bool '-D', '--debug', ' print debugging information'
|
83
78
|
o.bool '-V', '--version', ' print library version'
|
84
79
|
o.bool '-N', '--no-color', ' disable color output'
|
85
|
-
o.bool '-
|
80
|
+
o.bool '-A', '--sym-args', ' read more CLI arguments from $SYM_ARGS'
|
86
81
|
|
87
82
|
o.separator ' '
|
88
83
|
o.separator 'Utility:'.yellow
|
89
|
-
o.string '-
|
84
|
+
o.string '-B', '--bash-completion', '[file]'.blue + ' append shell completion to a file'
|
90
85
|
|
91
86
|
o.separator ' '
|
92
87
|
o.separator 'Help & Examples:'.yellow
|
@@ -94,6 +89,10 @@ module Sym
|
|
94
89
|
o.bool '-h', '--help', ' show help'
|
95
90
|
end
|
96
91
|
end
|
92
|
+
|
93
|
+
def key_spec
|
94
|
+
'KEY-SPEC'.bold.magenta
|
95
|
+
end
|
97
96
|
end
|
98
97
|
end
|
99
98
|
end
|
data/lib/sym/application.rb
CHANGED
@@ -17,6 +17,7 @@ module Sym
|
|
17
17
|
:key_source,
|
18
18
|
:input_handler,
|
19
19
|
:key_handler,
|
20
|
+
:output,
|
20
21
|
:result,
|
21
22
|
:password_cache
|
22
23
|
|
@@ -25,40 +26,16 @@ module Sym
|
|
25
26
|
self.opts = opts.is_a?(Hash) ? opts : opts.to_hash
|
26
27
|
|
27
28
|
process_negated_option(opts[:negate]) if opts[:negate]
|
29
|
+
|
28
30
|
self.args = ::Sym::App::Args.new(self.provided_options)
|
29
31
|
|
32
|
+
initialize_output_stream
|
30
33
|
initialize_action
|
31
34
|
initialize_data_source
|
32
35
|
initialize_password_cache
|
33
36
|
initialize_input_handler
|
34
37
|
end
|
35
38
|
|
36
|
-
def provided_options
|
37
|
-
provided_opts = self.opts.clone
|
38
|
-
provided_opts.delete_if { |k, v| !v }
|
39
|
-
provided_opts
|
40
|
-
end
|
41
|
-
|
42
|
-
def provided_safe_options
|
43
|
-
provided_options.map do |k, v|
|
44
|
-
k == :key && [44, 45].include?(v.size) ?
|
45
|
-
[k, '[reducted]'] :
|
46
|
-
[k, v]
|
47
|
-
end.to_h
|
48
|
-
end
|
49
|
-
|
50
|
-
def provided_flags
|
51
|
-
provided_flags = provided_options
|
52
|
-
provided_flags.delete_if { |k, v| ![false, true].include?(v) }
|
53
|
-
provided_flags.keys
|
54
|
-
end
|
55
|
-
|
56
|
-
def provided_value_options
|
57
|
-
provided = provided_safe_options
|
58
|
-
provided.delete_if { |k, v| [false, true].include?(v) }
|
59
|
-
provided
|
60
|
-
end
|
61
|
-
|
62
39
|
def execute!
|
63
40
|
initialize_key_source
|
64
41
|
unless command
|
@@ -110,6 +87,32 @@ module Sym
|
|
110
87
|
editors_to_try.find { |editor| File.exist?(editor) }
|
111
88
|
end
|
112
89
|
|
90
|
+
def provided_options
|
91
|
+
provided_opts = self.opts.clone
|
92
|
+
provided_opts.delete_if { |k, v| !v }
|
93
|
+
provided_opts
|
94
|
+
end
|
95
|
+
|
96
|
+
def provided_safe_options
|
97
|
+
provided_options.map do |k, v|
|
98
|
+
k == :key && [44, 45].include?(v.size) ?
|
99
|
+
[k, '[reducted]'] :
|
100
|
+
[k, v]
|
101
|
+
end.to_h
|
102
|
+
end
|
103
|
+
|
104
|
+
def provided_flags
|
105
|
+
provided_flags = provided_options
|
106
|
+
provided_flags.delete_if { |k, v| ![false, true].include?(v) }
|
107
|
+
provided_flags.keys
|
108
|
+
end
|
109
|
+
|
110
|
+
def provided_value_options
|
111
|
+
provided = provided_safe_options
|
112
|
+
provided.delete_if { |k, v| [false, true].include?(v) }
|
113
|
+
provided
|
114
|
+
end
|
115
|
+
|
113
116
|
|
114
117
|
private
|
115
118
|
|
@@ -128,6 +131,14 @@ module Sym
|
|
128
131
|
]
|
129
132
|
end
|
130
133
|
|
134
|
+
def initialize_output_stream
|
135
|
+
output_klass = args.output_class
|
136
|
+
unless output_klass && output_klass.is_a?(Class)
|
137
|
+
raise "Can not determine output type from arguments #{provided_options}"
|
138
|
+
end
|
139
|
+
self.output = output_klass.new(opts).output_proc
|
140
|
+
end
|
141
|
+
|
131
142
|
def initialize_input_handler(handler = ::Sym::App::Input::Handler.new)
|
132
143
|
self.input_handler = handler
|
133
144
|
end
|
data/lib/sym/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sym
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Gredeskoul
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored2
|
@@ -221,6 +221,7 @@ email:
|
|
221
221
|
executables:
|
222
222
|
- keychain
|
223
223
|
- sym
|
224
|
+
- symit
|
224
225
|
extensions: []
|
225
226
|
extra_rdoc_files: []
|
226
227
|
files:
|
@@ -241,6 +242,7 @@ files:
|
|
241
242
|
- bin/sym.completion
|
242
243
|
- exe/keychain
|
243
244
|
- exe/sym
|
245
|
+
- exe/symit
|
244
246
|
- lib/sym.rb
|
245
247
|
- lib/sym/app.rb
|
246
248
|
- lib/sym/app/args.rb
|