manageiq-password 1.0.0 → 1.1.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
  SHA256:
3
- metadata.gz: 9a506e65c484778a8b89cc16300e5145922de810e612499fe5046015e8668915
4
- data.tar.gz: 5322663567882ef7b24f4275d9a6f21e1d967bd086de0afe64dcdf45d67e868d
3
+ metadata.gz: 169673824deb748589d388452d71ade309bf678d35a30be8e88493cdfd9058c7
4
+ data.tar.gz: 49c0b253a7ec7a1212ebce03d2e83f3b407b6e6bcad0c49d44cb4889e5968cb2
5
5
  SHA512:
6
- metadata.gz: 3ea27faaef7f610f5f07f67e19c1b27739c43f418f9662cfbf558d6a05168f0002b8697a1ec782b540b29b99e67a9d25996b03e1ad5cf9044d3644b5b3aaa9cb
7
- data.tar.gz: 4b5e896206731cdd5895b1a90165c69af0bbdd789bf86509e2d4e1568a7a3437b794e043094a9183d09612717a67b278b5d32733523e3652698abcb637dd5ad0
6
+ metadata.gz: 0b72cf25be15763836db8d0779da31bb69c45116a44602a61ad4a7bece0083ae57d60c59fe4c295f26c059c4d1b1c01181efce56fb25ad45d2f731095410f77f
7
+ data.tar.gz: ca33b0b6939a2a8671f04905ab00d2ba4c48bcc7b7a48611f968fa3f626a25b08f4b21a8b9e3c285c54410820c3432f44aab0153dd62094bb20da67f881f5ce6
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  language: ruby
3
+ dist: bionic
3
4
  cache: bundler
4
5
  rvm:
5
6
  - 2.6.7
data/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.1.0] - 2021-11-08
8
+ ### Added
9
+ - Add manageiq-password CLI [[#23](https://github.com/ManageIQ/manageiq-password/pull/23)]
10
+
11
+ ### Fixed
12
+ - chmod v2_key on creation [[#22](https://github.com/ManageIQ/manageiq-password/pull/22)]
13
+ - Raise an exception when decrypting plaintext [[#26](https://github.com/ManageIQ/manageiq-password/pull/26)]
14
+ - Fix encrypted? and try_decrypt to work with erb strings [[#28](https://github.com/ManageIQ/manageiq-password/pull/28)]
15
+
7
16
  ## [1.0.0] - 2021-05-05
8
17
  ### Removed
9
18
  - **BREAKING**: Drop support for legacy v0 and v1 keys [[#14](https://github.com/ManageIQ/manageiq-password/pull/14)]
@@ -13,5 +22,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
13
22
  key
14
23
  - **BREAKING**: Drop deprecated methods [[#16](https://github.com/ManageIQ/manageiq-password/pull/16)]
15
24
 
16
- [Unreleased]: https://github.com/ManageIQ/more_core_extensions/compare/v1.0.0...HEAD
25
+ [Unreleased]: https://github.com/ManageIQ/more_core_extensions/compare/v1.1.0...HEAD
26
+ [1.1.0]: https://github.com/ManageIQ/more_core_extensions/compare/v1.1.0...v1.0.0
17
27
  [1.0.0]: https://github.com/ManageIQ/more_core_extensions/compare/v1.0.0...v0.3.0
@@ -0,0 +1,100 @@
1
+ #!/bin/bash
2
+
3
+ while [[ "$#" -gt 0 ]]; do
4
+ case $1 in
5
+ -d|--decrypt)
6
+ mode="decrypt"
7
+ ;;
8
+ -e|--encrypt)
9
+ mode="encrypt"
10
+ ;;
11
+ -k|--key)
12
+ keyfile="$2"
13
+ shift
14
+ ;;
15
+ -h|--help|-?)
16
+ cat <<-EOS >&2
17
+ Usage: $(basename $0) [--encrypt|--decrypt] [--key KEYFILE]
18
+
19
+ Options:
20
+ -d, --decrypt Decrypt the value on STDIN (default mode)
21
+ -e, --encrypt Encrypt the value on STDIN
22
+ -k, --key Path to the key file (default: $(pwd)/certs/v2_key)
23
+
24
+ -h, --help, -? Display help
25
+ EOS
26
+ exit 0
27
+ ;;
28
+ *)
29
+ echo "ERROR: Unknown parameter passed: $1" >&2
30
+ exit 1
31
+ ;;
32
+ esac
33
+ shift
34
+ done
35
+
36
+ mode=${mode:-"decrypt"}
37
+ keyfile=${keyfile:-"$(pwd)/certs/v2_key"}
38
+
39
+ if [ ! -r "$keyfile" ]; then
40
+ echo "ERROR: Cannot read v2 key file: $keyfile" >&2
41
+ exit 1
42
+ fi
43
+
44
+ extractFromKeyfile() {
45
+ grep :$1: "$keyfile" | cut -d ' ' -f 2
46
+ }
47
+
48
+ extractAlgorithm() {
49
+ extractFromKeyfile "algorithm"
50
+ }
51
+
52
+ extractKey() {
53
+ extractFromKeyfile "key" | base64 -d | xxd -p -c256
54
+ }
55
+
56
+ extractIv() {
57
+ iv=$(extractFromKeyfile "iv" | base64 -d | xxd -p -c256)
58
+ echo -n "${iv:-"00000000000000000000000000000000"}"
59
+ }
60
+
61
+ algorithm=$(extractAlgorithm)
62
+ if [ "$algorithm" != "aes-256-cbc" ]; then
63
+ echo "ERROR: Invalid v2 key file: $keyfile" >&2
64
+ exit 1
65
+ fi
66
+
67
+ if [ -n "$DEBUG" ]; then
68
+ cat <<-EOS >&2
69
+ ==============================================================================
70
+ Mode: $mode
71
+ Key File: $keyfile
72
+ Algorithm: $algorithm
73
+ IV (Base64): $(extractFromKeyfile "iv")
74
+ IV (Hex): $(extractIv)
75
+ Key (Base64): $(extractFromKeyfile "key")
76
+ Key (Hex): $(extractKey)
77
+ ==============================================================================
78
+ EOS
79
+ fi
80
+
81
+ case $mode in
82
+ decrypt)
83
+ (
84
+ xargs -L1 echo | \
85
+ sed 's/^.\{4\}//;s/.$//' | \
86
+ openssl enc -d -base64 -$algorithm -iv "$(extractIv)" -K "$(extractKey)"
87
+ ) < /dev/stdin
88
+ ;;
89
+ encrypt)
90
+ (
91
+ xargs -L1 echo -n | \
92
+ openssl enc -base64 -$algorithm -iv "$(extractIv)" -K "$(extractKey)" | \
93
+ sed "s/^/v2:{/;s/$/}/" | \
94
+ xargs -L1 echo -n
95
+ ) < /dev/stdin
96
+ ;;
97
+ *)
98
+ echo "ERROR: Invalid mode: $mode" >&2
99
+ exit 1
100
+ esac
@@ -1,5 +1,5 @@
1
1
  module ManageIQ
2
2
  class Password
3
- VERSION = "1.0.0".freeze
3
+ VERSION = "1.1.0".freeze
4
4
  end
5
5
  end
@@ -22,15 +22,32 @@ module ManageIQ
22
22
  @encStr = encrypt(str)
23
23
  end
24
24
 
25
- def encrypt(str, key = self.class.key)
25
+ def encrypt(*args)
26
+ self.class.encrypt(*args)
27
+ end
28
+
29
+ def decrypt(*args)
30
+ self.class.decrypt(*args)
31
+ end
32
+
33
+ def recrypt(*args)
34
+ self.class.recrypt(*args)
35
+ end
36
+
37
+ def self.encrypt(str, key = self.key)
26
38
  return str if str.nil?
27
39
 
28
40
  enc = key.encrypt64(str).delete("\n") unless str.empty?
29
- self.class.wrap(enc)
41
+ wrap(enc)
30
42
  end
31
43
 
32
- def decrypt(str, key = self.class.key)
33
- enc = self.class.unwrap(str)
44
+ def self.decrypt(str, key = self.key)
45
+ str = remove_erb(str)
46
+ return str if str.nil? || str.empty?
47
+
48
+ raise PasswordError, "cannot decrypt plaintext string" unless wrapped?(str)
49
+
50
+ enc = unwrap(str)
34
51
  return enc if enc.nil? || enc.empty?
35
52
 
36
53
  begin
@@ -40,7 +57,7 @@ module ManageIQ
40
57
  end
41
58
  end
42
59
 
43
- def recrypt(str, prior_key = nil)
60
+ def self.recrypt(str, prior_key = nil)
44
61
  return str if str.nil?
45
62
 
46
63
  decrypted_str = decrypt(str, prior_key) if prior_key rescue nil
@@ -48,21 +65,8 @@ module ManageIQ
48
65
  encrypt(decrypted_str)
49
66
  end
50
67
 
51
- def self.encrypt(*args)
52
- new.encrypt(*args)
53
- end
54
-
55
- def self.decrypt(*args)
56
- new.decrypt(*args)
57
- end
58
-
59
- def self.recrypt(*args)
60
- new.recrypt(*args)
61
- end
62
-
63
68
  def self.encrypted?(str)
64
- return false if str.nil? || str.empty?
65
- !!unwrap(str)
69
+ wrapped?(remove_erb(str))
66
70
  end
67
71
 
68
72
  def self.md5crypt(str)
@@ -83,6 +87,7 @@ module ManageIQ
83
87
  end
84
88
 
85
89
  def self.try_decrypt(str)
90
+ str = remove_erb(str)
86
91
  encrypted?(str) ? decrypt(str) : str
87
92
  end
88
93
 
@@ -124,26 +129,27 @@ module ManageIQ
124
129
  Key.new.tap { |key| store_key_file(filename, key) if filename }
125
130
  end
126
131
 
127
- protected
128
-
129
- def self.wrap(encrypted_str)
132
+ private_class_method def self.wrap(encrypted_str)
130
133
  "v2:{#{encrypted_str}}"
131
134
  end
132
135
 
133
- def self.unwrap(str)
134
- _unwrap(str) || _unwrap(extract_erb_encrypted_value(str))
135
- end
136
-
137
- private_class_method def self._unwrap(str)
136
+ private_class_method def self.unwrap(str)
138
137
  return str if str.nil? || str.empty?
138
+
139
139
  str.match(REGEXP_START_LINE)&.public_send(:[], 1)
140
140
  end
141
141
 
142
- def self.store_key_file(filename, key)
143
- File.write(filename, key.to_h.to_yaml)
142
+ private_class_method def self.wrapped?(str)
143
+ return false if str.nil? || str.empty?
144
+
145
+ str.match?(REGEXP_START_LINE)
146
+ end
147
+
148
+ private_class_method def self.store_key_file(filename, key)
149
+ File.write(filename, key.to_h.to_yaml, :perm => 0440)
144
150
  end
145
151
 
146
- def self.load_key_file(filename)
152
+ private_class_method def self.load_key_file(filename)
147
153
  return filename if filename.respond_to?(:decrypt64)
148
154
 
149
155
  # if it is an absolute path, or relative to pwd, leave as is
@@ -154,8 +160,11 @@ module ManageIQ
154
160
  Key.new(*YAML.load_file(filename).values_at(:algorithm, :key, :iv))
155
161
  end
156
162
 
157
- def self.extract_erb_encrypted_value(value)
158
- return $1 if value =~ /\A<%= (?:MiqPassword|DB_PASSWORD|ManageIQ::Password)\.decrypt\(['"]([^'"]+)['"]\) %>\Z/
163
+ private_class_method def self.remove_erb(str)
164
+ return str if str.nil? || str.empty? || !str.start_with?("<%=")
165
+
166
+ match = str.match(/\A<%= (?:MiqPassword|DB_PASSWORD|ManageIQ::Password)\.decrypt\(['"](.+?)['"]\) %>\Z/m)
167
+ match ? match[1] : str
159
168
  end
160
169
 
161
170
  class Key
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_development_dependency "awesome_spawn"
21
22
  spec.add_development_dependency "bundler"
22
23
  spec.add_development_dependency "manageiq-style"
23
24
  spec.add_development_dependency "rake", ">= 12.3.3"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manageiq-password
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Authors
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-06 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: awesome_spawn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +96,8 @@ dependencies:
82
96
  version: '0'
83
97
  description:
84
98
  email:
85
- executables: []
99
+ executables:
100
+ - manageiq-password
86
101
  extensions: []
87
102
  extra_rdoc_files: []
88
103
  files:
@@ -101,6 +116,7 @@ files:
101
116
  - Rakefile
102
117
  - bin/console
103
118
  - bin/setup
119
+ - exe/manageiq-password
104
120
  - lib/manageiq-password.rb
105
121
  - lib/manageiq/password.rb
106
122
  - lib/manageiq/password/password_mixin.rb
@@ -128,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
144
  - !ruby/object:Gem::Version
129
145
  version: '0'
130
146
  requirements: []
131
- rubygems_version: 3.1.4
147
+ rubygems_version: 3.1.6
132
148
  signing_key:
133
149
  specification_version: 4
134
150
  summary: A simple encryption util for storing passwords in a database.