sym 2.4.3 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|