sym 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dba3a8013e135db50a8294dd619302d1c10b8109
4
- data.tar.gz: 28cc2c0edbff0ecec89e265109c11e3c9c67da01
3
+ metadata.gz: ba48a5359afbfb7ab1dd26e998a8534d6b5a1cd1
4
+ data.tar.gz: 4441338abdc75c4cc94ce8bf62e0cfa124c22290
5
5
  SHA512:
6
- metadata.gz: f78ca029db09962c423fb57e38c86e03b8417977714c6e087a80b31f0b9f6392ec7c6f2f8ebd1c41d9b7d75c82e0755f4ac37fd68393090c2a2eb17a81909d25
7
- data.tar.gz: 1d6c15f15761ceb1187e45455408a27b371a15a798d139a840614427fd52ac0a4574c5475d83a7d483e2b3f4d6e4c321cdc5beddbd89d6e943066f9972d9c984
6
+ metadata.gz: a58d04eee85fe8f9d888c432bd1a076437073448420d1ab83d2439a96f54665f33538cb7212ea9f287af646e369e767c89192af5c46140ce45e85bf9c455784a
7
+ data.tar.gz: 1796761a05b5c3eaa614999bca47bde80ba0967a2c6471d38b349171c49ed601888fcafc028aeedd46df90252063587ef1ab385b026cd4dcbdbedb553a50b5f5
data/.document CHANGED
@@ -1,2 +1,2 @@
1
- lib/ exe/ - README.md MANAGING-KEYS.md LICENSE
1
+ lib/ exe/ - README.md LICENSE sym-3.0-cli.md
2
2
 
data/.yardopts CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  --protected
3
2
  --no-private
4
3
  --embed-mixin ClassMethods
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Sym — Light Weight Symmetric Encryption for Humans
2
2
 
3
+ <hr/>
4
+ [![Gitter](https://img.shields.io/gitter/room/gitterHQ/gitter.svg)](https://gitter.im/kigster/sym)
3
5
  [![Gem Version](https://badge.fury.io/rb/sym.svg)](https://badge.fury.io/rb/sym)
4
6
  [![Downloads](http://ruby-gem-downloads-badge.herokuapp.com/sym?type=total)](https://rubygems.org/gems/sym)
5
7
  [![Documentation](http://inch-ci.org/github/kigster/sym.png)](http://inch-ci.org/github/kigster/sym)
@@ -9,6 +11,8 @@
9
11
  [![Test Coverage](https://codeclimate.com/github/kigster/sym/badges/coverage.svg)](https://codeclimate.com/github/kigster/sym/coverage)
10
12
  [![Issue Count](https://codeclimate.com/github/kigster/sym/badges/issue_count.svg)](https://codeclimate.com/github/kigster/sym)
11
13
 
14
+ <hr/>
15
+
12
16
  ## Description
13
17
 
14
18
  > __sym__ is a command line utility and a Ruby API that makes it _trivial to encrypt and decrypt sensitive data_. Unlike many other existing encryption tools, __sym__ focuses on usability and streamlined interface (CLI), with the goal of making encryption easy and transparent. The result? There is no excuse for keeping your application secrets unencrypted :)
data/Rakefile CHANGED
@@ -2,13 +2,26 @@ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
  require 'yard'
4
4
 
5
+ def shell(*args)
6
+ puts "running: #{args.join(' ')}"
7
+ system(args.join(' '))
8
+ end
9
+
10
+ task :permissions do
11
+ shell("find . -type f -exec chmod o+r,g+r {} \\;")
12
+ shell("find . -type d -exec chmod o+rx,g+rx {} \\;")
13
+ end
14
+
15
+ task :build => :permissions
5
16
 
6
17
  YARD::Rake::YardocTask.new(:doc) do |t|
7
- t.files = %w(lib/**/*.rb exe/*.rb - README.md MANAGING-KEYS.md LICENSE)
8
- t.options.unshift('--title', '"Sym – Symmetric Key Encryption for Your Data"')
18
+ t.files = %w(lib/**/*.rb exe/*.rb - README.md LICENSE sym-3.0-cli.md)
19
+ t.options.unshift('--title','"Sym – Symmetric Key Encryption for Your Data"')
9
20
  t.after = ->() { exec('open doc/index.html') }
10
21
  end
11
22
 
12
23
  RSpec::Core::RakeTask.new(:spec)
13
24
 
14
25
  task :default => :spec
26
+
27
+
data/lib/sym.rb CHANGED
@@ -32,7 +32,9 @@ Sym::Configuration.configure do |config|
32
32
  }
33
33
  end
34
34
 
35
-
35
+ require 'sym/extensions/stdlib'
36
+ require 'sym/extensions/class_methods'
37
+ require 'sym/extensions/instance_methods'
36
38
  #
37
39
  # == Using Sym Library
38
40
  #
@@ -94,22 +96,6 @@ end
94
96
  # Each class including the +Sym+ module would get their own +#private_key#
95
97
  # class-instance variable accessor, and a possible value.
96
98
  #
97
- # For example:
98
- #
99
- #
100
-
101
- module Kernel
102
- def require_dir(___dir)
103
- @___dir ||= File.dirname(__FILE__)
104
- # require files using a consistent order based on the dir/file name.
105
- # this should be OS-neutral
106
- Dir["#{@___dir}/#{___dir}/*.rb"].sort.each do |___file|
107
- require(___file)
108
- end
109
- end
110
- end
111
-
112
- require_dir 'sym/extensions'
113
99
 
114
100
  module Sym
115
101
  def self.included(klass)
@@ -133,7 +119,8 @@ module Sym
133
119
 
134
120
  COMPLETION_FILE = '.sym.completion'.freeze
135
121
  COMPLETION_PATH = "#{ENV['HOME']}/#{COMPLETION_FILE}".freeze
136
- LOGGER = Logger.new(nil).freeze # empty logger
122
+ NIL_LOGGER = Logger.new(nil).freeze # empty logger
123
+ LOGGER = Logger.new(STDOUT).freeze
137
124
  ENV_ARGS_VARIABLE_NAME = 'SYM_ARGS'.freeze
138
125
 
139
126
  BASH_COMPLETION = {
@@ -1,6 +1,6 @@
1
1
  require 'sym'
2
2
  require 'active_support/inflector'
3
-
3
+ require 'colored2'
4
4
  module Sym
5
5
 
6
6
  # The {Sym::App} Module is responsible for handing user input and executing commands.
@@ -25,26 +25,45 @@ module Sym
25
25
  STDERR
26
26
  end
27
27
 
28
- def self.error(
29
- config: {},
28
+ def self.log(level, *args, **opts)
29
+ Sym::LOGGER.send(level, *args) if opts[:debug]
30
+ end
31
+
32
+ def self.error(config: {},
30
33
  exception: nil,
31
34
  type: nil,
32
35
  details: nil,
33
36
  reason: nil,
34
- comments: nil)
35
-
36
- self.out.puts([\
37
- "#{(type || exception.class.name).titleize}:".red.bold.underlined +
38
- (sprintf ' %s', details || exception.message).red.italic,
39
- (reason ? "\n#{reason.blue.bold.italic}" : nil),
40
- (comments ? "\n\n#{comments}" : nil)].compact.join("\n"))
41
- self.out.puts "\n" + exception.backtrace.join("\n").bold.red if exception && config && config[:trace]
37
+ comments: nil,
38
+ command: nil)
39
+
40
+ lines = []
41
+
42
+ error_type = "#{(type || exception.class.name)}"
43
+ error_details = (details || exception.message)
44
+
45
+ if exception && (config && config[:trace] || reason == 'Unknown Error')
46
+ lines << "#{error_type.red.underlined}: #{error_details.white.on.red}\n"
47
+ lines << exception.backtrace.join("\n").red.bold if config[:trace]
48
+ lines << "\n"
49
+ end
50
+
51
+ operation = command ? "to #{command.class.short_name.to_s.humanize.downcase}" : ''
52
+ reason = exception.message if reason.nil? && exception
53
+
54
+ lines << " error #{operation} → ".white.on.red+ " #{reason}".bold.red if reason
55
+ lines << "#{comments}" if comments
56
+
57
+ error_report = lines.compact.join("\n") || 'Undefined error'
58
+
59
+ self.out.puts(error_report) if error_report.present?
42
60
  self.exit_code = 1
43
61
  end
44
62
 
45
63
  def self.is_osx?
46
64
  Gem::Platform.local.os.eql?('darwin')
47
65
  end
66
+
48
67
  def self.this_os
49
68
  Gem::Platform.local.os
50
69
  end
@@ -2,19 +2,20 @@ require 'slop'
2
2
  require 'sym'
3
3
  require 'colored2'
4
4
  require 'yaml'
5
- require 'forwardable'
6
5
  require 'openssl'
6
+ require 'highline'
7
+
7
8
  require 'sym/application'
8
9
  require 'sym/errors'
10
+
9
11
  require 'sym/app/commands'
10
12
  require 'sym/app/keychain'
11
13
  require 'sym/app/private_key/handler'
12
- require 'highline'
13
14
 
14
- require_relative 'output/file'
15
- require_relative 'output/file'
16
- require_relative 'output/stdout'
17
- require_relative 'cli_slop'
15
+ require 'sym/app/output/base'
16
+ require 'sym/app/output/file'
17
+ require 'sym/app/output/stdout'
18
+ require 'sym/app/cli_slop'
18
19
 
19
20
  module Sym
20
21
  module App
@@ -55,9 +56,6 @@ module Sym
55
56
  # brings in #parse(Array[String] args)
56
57
  include CLISlop
57
58
 
58
- extend Forwardable
59
- def_delegators :@application, :command
60
-
61
59
  attr_accessor :opts, :application, :outputs, :output_proc
62
60
 
63
61
  def initialize(argv_original)
@@ -75,23 +73,26 @@ module Sym
75
73
  end
76
74
 
77
75
  command_no_color(argv_original) if opts[:no_color]
78
-
79
76
  self.application = ::Sym::Application.new(opts)
80
-
81
77
  select_output_stream
82
78
  end
83
79
 
84
80
 
85
81
  def execute
86
82
  return Sym::App.exit_code if Sym::App.exit_code != 0
87
-
88
83
  result = application.execute
89
- if result.is_a?(Hash)
90
- self.output_proc = ::Sym::App::Args.new({}).output_class
91
- error(result)
92
- else
93
- self.output_proc.call(result)
84
+ case result
85
+ when Hash
86
+ self.output_proc = ::Sym::App::Args.new({}).output_class
87
+ error(result)
88
+ else
89
+ self.output_proc.call(result)
94
90
  end
91
+ Sym::App.exit_code
92
+ end
93
+
94
+ def command
95
+ @command ||= self.application&.command
95
96
  end
96
97
 
97
98
  private
@@ -103,7 +104,9 @@ module Sym
103
104
  end
104
105
 
105
106
  def error(hash)
106
- Sym::App.error(hash.merge(config: (opts ? opts.to_hash : {})))
107
+ hash.merge!(config: opts.to_hash) if opts
108
+ hash.merge!(command: @command) if @command
109
+ Sym::App.error(**hash)
107
110
  end
108
111
 
109
112
  def select_output_stream
@@ -54,7 +54,8 @@ end
54
54
 
55
55
  require 'sym/app/commands/base_command'
56
56
  require 'sym/app/commands/bash_completion'
57
- require 'sym/app/commands/encrypt_decrypt'
57
+ require 'sym/app/commands/encrypt'
58
+ require 'sym/app/commands/decrypt'
58
59
  require 'sym/app/commands/generate_key'
59
60
  require 'sym/app/commands/keychain_add_key'
60
61
  require 'sym/app/commands/open_editor'
@@ -69,6 +69,10 @@ module Sym
69
69
  raise Sym::Errors::AbstractMethodCalled.new(:run)
70
70
  end
71
71
 
72
+ def content
73
+ @content ||= (opts[:string] || (opts[:file].eql?('-') ? STDIN.read : File.read(opts[:file])))
74
+ end
75
+
72
76
  def to_s
73
77
  "#{self.class.short_name.to_s.bold.yellow}, with options: #{application.args.argv.join(' ').gsub(/--/, '').bold.green}"
74
78
  end
@@ -5,7 +5,7 @@ module Sym
5
5
  class BashCompletion < BaseCommand
6
6
 
7
7
  required_options [:bash_completion]
8
- try_after :generate_key, :open_editor, :encrypt_decrypt
8
+ try_after :generate_key, :open_editor, :encrypt, :decrypt
9
9
 
10
10
  def execute
11
11
  install_completion_file
@@ -2,11 +2,11 @@ require 'sym/app/commands/base_command'
2
2
  module Sym
3
3
  module App
4
4
  module Commands
5
- class EncryptDecrypt < BaseCommand
5
+ class Decrypt < BaseCommand
6
6
  include Sym
7
7
 
8
8
  required_options [ :private_key, :keyfile, :keychain, :interactive ],
9
- [ :encrypt, :decrypt ],
9
+ [ :decrypt ],
10
10
  [ :file, :string ]
11
11
 
12
12
  try_after :generate_key
@@ -14,12 +14,6 @@ module Sym
14
14
  def execute
15
15
  send(application.action, content, application.key)
16
16
  end
17
-
18
- private
19
-
20
- def content
21
- @content ||= (opts[:string] || (opts[:file].eql?('-') ? STDIN.read : File.read(opts[:file])))
22
- end
23
17
  end
24
18
  end
25
19
  end
@@ -0,0 +1,20 @@
1
+ require 'sym/app/commands/base_command'
2
+ module Sym
3
+ module App
4
+ module Commands
5
+ class Encrypt < BaseCommand
6
+ include Sym
7
+
8
+ required_options [ :private_key, :keyfile, :keychain, :interactive ],
9
+ [ :encrypt ],
10
+ [ :file, :string ]
11
+
12
+ try_after :generate_key
13
+
14
+ def execute
15
+ send(application.action, content, application.key)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -7,6 +7,8 @@ module Sym
7
7
 
8
8
  required_options :generate
9
9
 
10
+ try_after :show_help
11
+
10
12
  def execute
11
13
  retries ||= 0
12
14
 
@@ -8,7 +8,7 @@ module Sym
8
8
  required_options [:private_key, :keyfile, :interactive],
9
9
  :keychain
10
10
 
11
- try_after :generate_key, :encrypt_decrypt, :password_protect_key
11
+ try_after :generate_key, :encrypt, :decrypt, :password_protect_key
12
12
 
13
13
  def execute
14
14
  add_to_keychain_if_needed(self.key)
@@ -14,7 +14,7 @@ module Sym
14
14
  :edit,
15
15
  :file
16
16
 
17
- try_after :generate_key, :encrypt_decrypt
17
+ try_after :generate_key, :encrypt, :decrypt
18
18
 
19
19
  attr_accessor :tempfile
20
20
 
@@ -8,7 +8,7 @@ module Sym
8
8
  required_options [:private_key, :keyfile, :keychain, :interactive],
9
9
  :password
10
10
 
11
- try_after :generate_key, :encrypt_decrypt
11
+ try_after :generate_key, :encrypt, :decrypt
12
12
 
13
13
  def execute
14
14
  retries ||= 0
@@ -6,7 +6,7 @@ module Sym
6
6
  class PrintKey < BaseCommand
7
7
  required_options [ :keychain, :keyfile ]
8
8
 
9
- try_after :generate_key, :encrypt_decrypt, :password_protect_key, :keychain_add_key
9
+ try_after :generate_key, :encrypt, :decrypt, :password_protect_key, :keychain_add_key
10
10
 
11
11
  def execute
12
12
  self.key
@@ -36,7 +36,7 @@ module Sym
36
36
  self.enabled = opts[:enabled]
37
37
  self.verbose = opts[:verbose]
38
38
  self.timeout = opts[:timeout] || ::Sym::Configuration.config.password_cache_timeout
39
- self.provider = Providers.provider(opts[:provider])
39
+ self.provider = Providers.provider(opts[:provider], opts[:provider_opts] || {})
40
40
  self.enabled = false unless self.provider
41
41
  self
42
42
  end
@@ -22,8 +22,8 @@ module Sym
22
22
  end
23
23
  end
24
24
 
25
- def provider(p = nil)
26
- provider_from_argument(p) || detect
25
+ def provider(p = nil, **opts, &block)
26
+ provider_from_argument(p, **opts, &block) || detect
27
27
  end
28
28
 
29
29
  private
@@ -32,12 +32,12 @@ module Sym
32
32
  klass.name.gsub(/.*::(\w+)Provider/, '\1').downcase.to_sym
33
33
  end
34
34
 
35
- def provider_from_argument(p)
35
+ def provider_from_argument(p, **opts, &block)
36
36
  case p
37
37
  when String, Symbol
38
38
  provider_class_name = "#{p.to_s.capitalize}Provider"
39
39
  Sym::App::Password::Providers.const_defined?(provider_class_name) ?
40
- Sym::App::Password::Providers.const_get(provider_class_name).new :
40
+ Sym::App::Password::Providers.const_get(provider_class_name).new(**opts, &block) :
41
41
  nil
42
42
  end
43
43
  end
@@ -9,9 +9,11 @@ module Sym
9
9
 
10
10
  attr_accessor :coin
11
11
 
12
- def initialize
13
- Coin.uri = Sym::Configuration.config.password_cache_arguments[:drb][:opts][:uri]
12
+ def initialize(**opts)
13
+ Coin.uri = opts[:uri] || Sym::Configuration.config.password_cache_arguments[:drb][:opts][:uri]
14
14
  self.coin = Coin
15
+ alive?
16
+ self
15
17
  end
16
18
 
17
19
  def alive?
@@ -26,6 +28,10 @@ module Sym
26
28
  def read(*args)
27
29
  coin.send(:read, *args)
28
30
  end
31
+
32
+ def clear
33
+ coin.clear
34
+ end
29
35
  end
30
36
 
31
37
  register DrbProvider
@@ -9,12 +9,12 @@ module Sym
9
9
  class MemcachedProvider
10
10
  attr_accessor :dalli
11
11
 
12
- def initialize
12
+ def initialize(**opts)
13
13
  # disable logging
14
- Dalli.logger = Sym::LOGGER
14
+ Dalli.logger = Sym::NIL_LOGGER
15
15
  self.dalli = ::Dalli::Client.new(
16
16
  * Sym::Configuration.config.password_cache_arguments[:memcached][:args],
17
- ** Sym::Configuration.config.password_cache_arguments[:memcached][:opts]
17
+ ** Sym::Configuration.config.password_cache_arguments[:memcached][:opts].merge!(opts)
18
18
  )
19
19
  end
20
20
 
@@ -33,6 +33,10 @@ module Sym
33
33
  dalli.set(key, value)
34
34
  end
35
35
 
36
+ def clear
37
+ dalli.flush
38
+ end
39
+
36
40
  end
37
41
 
38
42
  register MemcachedProvider
@@ -33,7 +33,7 @@ module Sym
33
33
  if ((retries += 1) < 3)
34
34
  retry
35
35
  else
36
- raise(Sym::Errors::InvalidPasswordPrivateKey.new('Invalid password.'))
36
+ raise(Sym::Errors::InvalidPasswordProvidedForThePrivateKey.new('Invalid password.'))
37
37
  end
38
38
  end
39
39
  else
@@ -1,6 +1,7 @@
1
1
  require 'colored2'
2
2
  require 'sym'
3
3
  require 'sym/app'
4
+ require 'openssl'
4
5
 
5
6
  module Sym
6
7
  class Application
@@ -35,33 +36,46 @@ module Sym
35
36
  end
36
37
 
37
38
  def execute!
38
- if !args.generate_key? &&
39
- (args.require_key? || args.specify_key?)
39
+ if !args.generate_key? && (args.require_key? || args.specify_key?)
40
+ log :debug, 'operation requires a key...'
40
41
  self.key = Sym::App::PrivateKey::Handler.new(opts, input_handler, password_cache).key
41
- raise Sym::Errors::NoPrivateKeyFound.new('Private key is required') unless self.key
42
+ unless self.key
43
+ log :error, 'Unable to determine the key, which appears to be required'
44
+ raise Sym::Errors::NoPrivateKeyFound, 'Private key is required'
45
+ end
42
46
  end
47
+ log :info, "detected command [#{command.class.name}]"
43
48
  unless command
44
- raise Sym::Errors::InsufficientOptionsError.new(
45
- 'Can not determine what to do from the options ' + opts_hash.keys.reject { |k| !opts[k] }.to_s)
49
+ raise Sym::Errors::InsufficientOptionsError, 'Can not determine what to do from the options ' + opts_hash.keys.reject { |k| !opts[k] }.to_s
46
50
  end
47
51
  self.result = command.execute
48
52
  end
49
53
 
54
+ def log(*args)
55
+ Sym::App.log(*args, **opts)
56
+ end
57
+
50
58
  def execute
51
59
  execute!
52
60
 
53
61
  rescue ::OpenSSL::Cipher::CipherError => e
54
- error type: 'Cipher Error',
55
- details: e.message,
56
- reason: 'Perhaps either the secret is invalid, or encrypted data is corrupt.',
57
- exception: e
62
+ { reason: 'Invalid key provided',
63
+ exception: e }
58
64
 
59
65
  rescue Sym::Errors::Error => e
60
- error type: e.class.name.split(/::/)[-1],
61
- details: e.message
66
+ { reason: e.class.name.gsub(/.*::/, '').underscore.humanize.downcase,
67
+ exception: e }
68
+
69
+ rescue TypeError => e
70
+ if e.message =~ /marshal/
71
+ { reason: 'Corrupt source data or invalid/corrupt key provided',
72
+ exception: e }
73
+ else
74
+ { exception: e }
75
+ end
62
76
 
63
77
  rescue StandardError => e
64
- error exception: e
78
+ { exception: e }
65
79
  end
66
80
 
67
81
  def command
@@ -89,10 +103,6 @@ module Sym
89
103
  ]
90
104
  end
91
105
 
92
- def error(hash)
93
- hash
94
- end
95
-
96
106
  def initialize_input_handler(handler = ::Sym::App::Input::Handler.new)
97
107
  self.input_handler = handler
98
108
  end
@@ -8,6 +8,7 @@ module Sym
8
8
  class InsufficientOptionsError < Sym::Errors::Error; end
9
9
 
10
10
  class PasswordError < Sym::Errors::Error; end
11
+ class NoPasswordProvided < Sym::Errors::PasswordError; end
11
12
  class PasswordsDontMatch < Sym::Errors::PasswordError; end
12
13
  class PasswordTooShort < Sym::Errors::PasswordError; end
13
14
 
@@ -19,9 +20,11 @@ module Sym
19
20
 
20
21
  class KeyError < Sym::Errors::Error; end
21
22
  class InvalidEncodingPrivateKey < Sym::Errors::KeyError; end
22
- class InvalidPasswordPrivateKey < Sym::Errors::KeyError; end
23
+ class InvalidPasswordProvidedForThePrivateKey < Sym::Errors::KeyError; end
23
24
  class NoPrivateKeyFound < Sym::Errors::KeyError; end
24
25
 
26
+ class NoDataProvided < Sym::Errors::Error; end
27
+
25
28
  class KeyChainCommandError < Sym::Errors::Error; end
26
29
 
27
30
  # Method was called on an abstract class. Override such methods in
@@ -25,31 +25,37 @@ module Sym
25
25
 
26
26
  # Expects key to be a base64 encoded key
27
27
  def encr(data, key, iv = nil)
28
- raise Sym::Errors::NoPrivateKeyFound if key.nil?
29
- _encr(data, encryption_config.data_cipher, iv) do |cipher_struct|
28
+ raise Sym::Errors::NoPrivateKeyFound unless key.present?
29
+ raise Sym::Errors::NoDataProvided unless data.present?
30
+ encrypt_data(data, encryption_config.data_cipher, iv) do |cipher_struct|
30
31
  cipher_struct.cipher.key = decode_key(key)
31
32
  end
32
33
  end
33
34
 
34
35
  # Expects key to be a base64 encoded key
35
36
  def decr(encrypted_data, key, iv = nil)
36
- raise Sym::Errors::NoPrivateKeyFound if key.nil?
37
- _decr(encrypted_data, encryption_config.data_cipher, iv) do |cipher_struct|
37
+ raise Sym::Errors::NoPrivateKeyFound unless key.present?
38
+ raise Sym::Errors::NoDataProvided unless encrypted_data.present?
39
+ decrypt_data(encrypted_data, encryption_config.data_cipher, iv) do |cipher_struct|
38
40
  cipher_struct.cipher.key = decode_key(key)
39
41
  end
40
42
  end
41
43
 
42
44
  def encr_password(data, password, iv = nil)
43
- _encr(data, encryption_config.password_cipher, iv) do |cipher_struct|
44
- key, salt = _key_from_password(cipher_struct.cipher, password)
45
+ raise Sym::Errors::NoDataProvided unless data.present?
46
+ raise Sym::Errors::NoPasswordProvided unless password.present?
47
+ encrypt_data(data, encryption_config.password_cipher, iv) do |cipher_struct|
48
+ key, salt = make_password_key(cipher_struct.cipher, password)
45
49
  cipher_struct.cipher.key = key
46
50
  cipher_struct.salt = salt
47
51
  end
48
52
  end
49
53
 
50
54
  def decr_password(encrypted_data, password, iv = nil)
51
- _decr(encrypted_data, encryption_config.password_cipher, iv) do |cipher_struct|
52
- key, = _key_from_password(cipher_struct.cipher, password, cipher_struct.salt)
55
+ raise Sym::Errors::NoDataProvided unless encrypted_data.present?
56
+ raise Sym::Errors::NoPasswordProvided unless password.present?
57
+ decrypt_data(encrypted_data, encryption_config.password_cipher, iv) do |cipher_struct|
58
+ key, = make_password_key(cipher_struct.cipher, password, cipher_struct.salt)
53
59
  cipher_struct.cipher.key = key
54
60
  end
55
61
  end
@@ -62,7 +68,7 @@ module Sym
62
68
  encoded_key
63
69
  end
64
70
 
65
- def _key_from_password(cipher, password, salt = nil)
71
+ def make_password_key(cipher, password, salt = nil)
66
72
  key_len = cipher.key_len
67
73
  salt ||= OpenSSL::Random.random_bytes 16
68
74
  iter = 20000
@@ -72,13 +78,13 @@ module Sym
72
78
  end
73
79
 
74
80
  # Expects key to be a base64 encoded key data
75
- def _encr(data, cipher_name, iv = nil, &block)
81
+ def encrypt_data(data, cipher_name, iv = nil, &block)
76
82
  data, compression_enabled = encode_incoming_data(data)
77
83
  cipher_struct = create_cipher(direction: :encrypt,
78
84
  cipher_name: cipher_name,
79
85
  iv: iv)
80
86
 
81
- yield cipher_struct if block_given?
87
+ block.call(cipher_struct) if block
82
88
 
83
89
  encrypted_data = update_cipher(cipher_struct.cipher, data)
84
90
  wrapper_struct = WrapperStruct.new(
@@ -91,13 +97,13 @@ module Sym
91
97
  end
92
98
 
93
99
  # Expects key to be a base64 encoded key data
94
- def _decr(encoded_data, cipher_name, iv = nil, &block)
100
+ def decrypt_data(encoded_data, cipher_name, iv = nil, &block)
95
101
  wrapper_struct = decode(encoded_data)
96
102
  cipher_struct = create_cipher(cipher_name: cipher_name,
97
- iv: wrapper_struct.iv,
103
+ iv: wrapper_struct.iv || iv,
98
104
  direction: :decrypt,
99
105
  salt: wrapper_struct.salt)
100
- yield cipher_struct if block_given?
106
+ block.call(cipher_struct) if block
101
107
  decode(update_cipher(cipher_struct.cipher, wrapper_struct.encrypted_data))
102
108
  end
103
109
 
@@ -0,0 +1,23 @@
1
+
2
+ module Kernel
3
+ def require_dir(___dir)
4
+ @___dir ||= File.dirname(__FILE__)
5
+ # require files using a consistent order based on the dir/file name.
6
+ # this should be OS-neutral
7
+ Dir["#{@___dir}/#{___dir}/*.rb"].sort.each do |___file|
8
+ require(___file)
9
+ end
10
+ end
11
+ end
12
+
13
+ class Object
14
+ unless self.methods.include?(:present?)
15
+ def present?
16
+ return false if self.nil?
17
+ if self.is_a?(String)
18
+ return false if self == ''
19
+ end
20
+ true
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module Sym
2
- VERSION = '2.2.1'
2
+ VERSION = '2.3.0'
3
3
  DESCRIPTION = <<-eof
4
4
  Sym is a command line utility and a Ruby API that makes it trivial to encrypt and decrypt
5
5
  sensitive data. Unlike many other existing encryption tools, sym focuses on usability and
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.2.1
4
+ version: 2.3.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-02-15 00:00:00.000000000 Z
11
+ date: 2017-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colored2
@@ -249,7 +249,8 @@ files:
249
249
  - lib/sym/app/commands.rb
250
250
  - lib/sym/app/commands/base_command.rb
251
251
  - lib/sym/app/commands/bash_completion.rb
252
- - lib/sym/app/commands/encrypt_decrypt.rb
252
+ - lib/sym/app/commands/decrypt.rb
253
+ - lib/sym/app/commands/encrypt.rb
253
254
  - lib/sym/app/commands/generate_key.rb
254
255
  - lib/sym/app/commands/keychain_add_key.rb
255
256
  - lib/sym/app/commands/open_editor.rb
@@ -285,6 +286,7 @@ files:
285
286
  - lib/sym/errors.rb
286
287
  - lib/sym/extensions/class_methods.rb
287
288
  - lib/sym/extensions/instance_methods.rb
289
+ - lib/sym/extensions/stdlib.rb
288
290
  - lib/sym/extensions/with_retry.rb
289
291
  - lib/sym/extensions/with_timeout.rb
290
292
  - lib/sym/version.rb