secretmgr 0.1.0 → 0.2.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/.rubocop.yml +27 -22
- data/.rubocop_todo.yml +101 -46
- data/Gemfile +25 -14
- data/Gemfile.lock +65 -49
- data/Rakefile +41 -4
- data/SECURITY.md +21 -0
- data/exe/secretmgr +15 -78
- data/lib/secretmgr/cli.rb +171 -0
- data/lib/secretmgr/config.rb +42 -41
- data/lib/secretmgr/globalsetting.rb +49 -0
- data/lib/secretmgr/loggerxs.rb +4 -0
- data/lib/secretmgr/secret.rb +228 -0
- data/lib/secretmgr/secretmgr.rb +247 -200
- data/lib/secretmgr/util.rb +15 -0
- data/lib/secretmgr/version.rb +1 -1
- data/lib/secretmgr.rb +28 -22
- data/rubocoprefine.bat +29 -29
- data/secretmgr.gemspec +49 -49
- metadata +16 -79
data/lib/secretmgr/secretmgr.rb
CHANGED
@@ -1,200 +1,247 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pathname"
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
def
|
100
|
-
|
101
|
-
|
102
|
-
# p "
|
103
|
-
|
104
|
-
p "
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
#
|
112
|
-
|
113
|
-
setting = YAML.safe_load(
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
@
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "debug"
|
5
|
+
|
6
|
+
module Secretmgr
|
7
|
+
# 秘匿情報マネージャ
|
8
|
+
class Secretmgr
|
9
|
+
attr_reader :decrypted_text, :secret
|
10
|
+
|
11
|
+
@log_level = nil
|
12
|
+
@init_count = 0
|
13
|
+
# @setting_file = "setting.yml"
|
14
|
+
JSON_FILE_DIR = "JSON_FILE"
|
15
|
+
SETTING_KEY = "key"
|
16
|
+
SETTING_IV = "iv"
|
17
|
+
FORMAT_JSON = "JSON_FILE"
|
18
|
+
FORMAT_YAML = "YAML"
|
19
|
+
YML = "yml"
|
20
|
+
# @dot_yml = "yml"
|
21
|
+
# @secret_dir = "secret"
|
22
|
+
DEFAULT_PRIVATE_KEYFILE = ".ssh/id_rsa"
|
23
|
+
DEFAULT_PUBLIC_KEYFILE = ".ssh/id_rsa.pub"
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def log_init(log_level)
|
27
|
+
return unless @log_level.nil?
|
28
|
+
|
29
|
+
@log_level = log_level
|
30
|
+
Loggerxs.init("log_", "log.txt", ".", true, log_level) if @init_count.zero?
|
31
|
+
@init_count += 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset_init_count
|
35
|
+
@init_count = 0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(seting, secret_dir_pn, secret_key_dir_pn, ope,
|
40
|
+
public_keyfile_pn: nil, private_keyfile_pn: nil)
|
41
|
+
log_level = :info
|
42
|
+
# log_level = :debug
|
43
|
+
Secretmgr.log_init(log_level)
|
44
|
+
|
45
|
+
@setting = seting
|
46
|
+
home_pn = Pathname.new(Dir.home)
|
47
|
+
secret_dir_pn = Pathname.new(secret_dir_pn) unless secret_dir_pn.instance_of?(Pathname)
|
48
|
+
secret_key_dir_pn = Pathname.new(secret_key_dir_pn) unless secret_key_dir_pn.instance_of?(Pathname)
|
49
|
+
secret_key_dir_pn.mkdir unless secret_key_dir_pn.exist?
|
50
|
+
default_public_keyfile_pn = secret_key_dir_pn + "id_rsa.pub"
|
51
|
+
default_private_keyfile_pn = secret_key_dir_pn + "id_rsa"
|
52
|
+
public_keyfile_pn = Pathname.new(public_keyfile_pn) if public_keyfile_pn
|
53
|
+
private_keyfile_pn = Pathname.new(private_keyfile_pn) if private_keyfile_pn
|
54
|
+
|
55
|
+
@secret = Secret.new(@setting, home_pn, secret_dir_pn, ope,
|
56
|
+
default_public_keyfile_pn,
|
57
|
+
default_private_keyfile_pn,
|
58
|
+
public_keyfile_pn: public_keyfile_pn,
|
59
|
+
private_keyfile_pn: private_keyfile_pn)
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid?
|
63
|
+
@secret.valid
|
64
|
+
# Loggerxs.debug "1 ret=#{ret}"
|
65
|
+
# p "2 ret=#{ret}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def output_public_key(public_keyfile_pn)
|
69
|
+
@secret.output_public_key(public_keyfile_pn)
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_public_key(public_keyfile_pn)
|
73
|
+
@secret.create_public_key(public_keyfile_pn)
|
74
|
+
end
|
75
|
+
|
76
|
+
def output_private_key(private_keyfile_pn)
|
77
|
+
@secret.output_private_key(private_keyfile_pn)
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_private_key(private_keyfile_pn)
|
81
|
+
@secret.create_private_key(private_keyfile_pn)
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_setting_for_plain(plain_setting_file_pn, plain_secret_file_pn)
|
85
|
+
@plain_setting_file_pn = Pathname.new(@plain_setting_file_pn) if @plain_setting_file_pn
|
86
|
+
@plain_setting_file_pn ||= Pathname.new(plain_setting_file_pn)
|
87
|
+
@plain_secret_file_pn = Pathname.new(@plain_secret_file_pn) if @plain_secret_file_pn
|
88
|
+
@plain_secret_file_pn ||= Pathname.new(plain_secret_file_pn)
|
89
|
+
@plain_dir_pn = @plain_setting_file_pn.parent
|
90
|
+
@encrypted_setting_file_pn = @secret.encrypted_setting_file_pn
|
91
|
+
@encrypted_secret_file_pn = @secret.encrypted_secret_file_pn
|
92
|
+
end
|
93
|
+
|
94
|
+
def set_setting_for_encrypted(encrypted_setting_file_pn, encrypted_secret_file_pn)
|
95
|
+
@encrypted_setting_file_pn = Pathname.new(encrypted_setting_file_pn)
|
96
|
+
@encrypted_secret_file_pn = Pathname.new(encrypted_secret_file_pn)
|
97
|
+
end
|
98
|
+
|
99
|
+
def setup
|
100
|
+
# p "###### setup_setting"
|
101
|
+
setup_setting
|
102
|
+
# p "###### setup_secret"
|
103
|
+
setup_secret
|
104
|
+
# p "###### setup_secret_for_json_file"
|
105
|
+
setup_secret_for_json_file
|
106
|
+
end
|
107
|
+
|
108
|
+
def setup_setting
|
109
|
+
content = File.read(@plain_setting_file_pn)
|
110
|
+
# p "setup_setting content.size=#{content.size}"
|
111
|
+
# p "setup_setting content=#{content}"
|
112
|
+
|
113
|
+
@setting = YAML.safe_load(content)
|
114
|
+
# p "setup_setting @setting=#{@setting}"
|
115
|
+
|
116
|
+
Loggerxs.debug @setting
|
117
|
+
# pp "@setting=#{@setting}"
|
118
|
+
# puts "setup_setting @setting=#{@setting}"
|
119
|
+
encrypted_text = @secret.encrypt_with_public_key(content)
|
120
|
+
# puts "setup_setting encrypted_text.size=#{encrypted_text.size}"
|
121
|
+
# puts "setup_setting encrypted_text=#{encrypted_text}"
|
122
|
+
#
|
123
|
+
@secret.decrypt_with_private_key(encrypted_text)
|
124
|
+
# puts "setup_setting decrypted_text=#{decrypted_text}"
|
125
|
+
# puts "setup_setting decrypted_text.size=#{decrypted_text.size}"
|
126
|
+
|
127
|
+
dest_setting_file_pn = @secret.make_pair_file_pn(@plain_setting_file_pn, YML)
|
128
|
+
|
129
|
+
Loggerxs.debug "setup_setting dest_setting_file_pn=#{dest_setting_file_pn}"
|
130
|
+
File.write(dest_setting_file_pn, encrypted_text)
|
131
|
+
# p "dest_setting_file_pn=#{dest_setting_file_pn}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def setup_secret
|
135
|
+
plaintext = File.read(@plain_secret_file_pn)
|
136
|
+
# puts "setup_secret @setting=#{@setting}"
|
137
|
+
encrypted_text = @secret.encrypt_with_common_key(plaintext,
|
138
|
+
@setting[SETTING_KEY],
|
139
|
+
@setting[SETTING_IV])
|
140
|
+
dest_secret_file_pn = @secret.make_pair_file_pn(@plain_secret_file_pn, YML)
|
141
|
+
Loggerxs.debug "setup_secret dest_secret_file_pn=#{dest_secret_file_pn}"
|
142
|
+
File.write(dest_secret_file_pn, encrypted_text)
|
143
|
+
end
|
144
|
+
|
145
|
+
def remove_last_extension(pathn)
|
146
|
+
parent = pathn.parent
|
147
|
+
basename = pathn.basename
|
148
|
+
ext = basename.extname
|
149
|
+
base = basename.basename(ext)
|
150
|
+
parent + base
|
151
|
+
end
|
152
|
+
|
153
|
+
def setup_secret_for_json_file
|
154
|
+
top_pn = @plain_dir_pn + JSON_FILE_DIR
|
155
|
+
top_pn.find do |x|
|
156
|
+
next if x.directory?
|
157
|
+
|
158
|
+
relative_path = x.relative_path_from(@plain_dir_pn)
|
159
|
+
new_relative_path = remove_last_extension(relative_path)
|
160
|
+
Loggerxs.debug("################ relative_path=#{relative_path}")
|
161
|
+
Loggerxs.debug("################ new_relative_path=#{new_relative_path}")
|
162
|
+
@secret.encrypt_and_copy(x, new_relative_path, @setting[SETTING_KEY], @setting[SETTING_IV])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def set_setting_for_query(*dirs)
|
167
|
+
@valid_dirs = dirs.flatten.compact
|
168
|
+
@target, @sub_target, _tmp = @valid_dirs
|
169
|
+
# p "@valid_dirs=#{@valid_dirs}"
|
170
|
+
@file_format = @secret.file_format(@target, @sub_target)
|
171
|
+
Loggerxs.debug "@secret_dir_pn=#{@secret_dir_pn}"
|
172
|
+
Loggerxs.debug "dirs=#{dirs}"
|
173
|
+
Loggerxs.debug "@encrypted_secret_file_pn=#{@encrypted_secret_file_pn}"
|
174
|
+
|
175
|
+
@encrypted_secret_file_pn = @secret.get_file_path(dirs)
|
176
|
+
end
|
177
|
+
|
178
|
+
def load_setting
|
179
|
+
Loggerxs.debug "load_setting @encrypted_setting_file_pn=#{@encrypted_setting_file_pn}"
|
180
|
+
encrypted_text = File.read(@encrypted_setting_file_pn)
|
181
|
+
Loggerxs.debug "load_setting encrypted_text=#{encrypted_text}"
|
182
|
+
decrypted_text = @secret.decrypt_with_private_key(encrypted_text)
|
183
|
+
setting = YAML.safe_load(decrypted_text)
|
184
|
+
@key = setting[SETTING_KEY]
|
185
|
+
Loggerxs.debug "load_setting @key=#{@key}"
|
186
|
+
@iv = setting[SETTING_IV]
|
187
|
+
Loggerxs.debug "load_setting @iv=#{@iv}"
|
188
|
+
end
|
189
|
+
|
190
|
+
def load_and_decrypt
|
191
|
+
Loggerxs.debug("@encrypted_secret_file_pn=#{@encrypted_secret_file_pn}")
|
192
|
+
base64_text = File.read(@encrypted_secret_file_pn)
|
193
|
+
encrypted_content = Base64.decode64(base64_text)
|
194
|
+
begin
|
195
|
+
@decrpyted_content = @secret.decrypt_with_common_key(encrypted_content, @key, @iv)
|
196
|
+
@content = case @file_format
|
197
|
+
when FORMAT_JSON
|
198
|
+
@decrpyted_content
|
199
|
+
when FORMAT_YAML
|
200
|
+
@secret_content = YAML.safe_load(@decrpyted_content)
|
201
|
+
@sub_target ? @secret_content[@target][@sub_target] : @secret_content[@target]
|
202
|
+
else
|
203
|
+
""
|
204
|
+
end
|
205
|
+
rescue StandardError => e
|
206
|
+
Loggerxs.error e
|
207
|
+
Loggerxs.error e.message
|
208
|
+
Loggerxs.error e.backtrace
|
209
|
+
Loggerxs.error "Can't dencrypt #{@encrypted_setting_file_pn}"
|
210
|
+
end
|
211
|
+
@content
|
212
|
+
end
|
213
|
+
|
214
|
+
def load
|
215
|
+
load_setting
|
216
|
+
load_and_decrypt
|
217
|
+
end
|
218
|
+
|
219
|
+
def make(_target, _sub_target)
|
220
|
+
case @file_format
|
221
|
+
when FORMAT_JSON
|
222
|
+
@content
|
223
|
+
when FORMAT_YAML
|
224
|
+
@content.map do |item|
|
225
|
+
%(export #{item[0]}=#{item[1]})
|
226
|
+
end.flatten
|
227
|
+
else
|
228
|
+
""
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def valid_private_keyfile(path, default_path = DEFAULT_PRIVATE_KEYFILE)
|
233
|
+
valid_pathname(path, default_path)
|
234
|
+
end
|
235
|
+
|
236
|
+
def valid_public_keyfile(path, default_path = DEFAULT_PUBLIC_KEYFILE)
|
237
|
+
valid_pathname(path, default_path)
|
238
|
+
end
|
239
|
+
|
240
|
+
def valid_pathname(path, default_path)
|
241
|
+
pathn = path
|
242
|
+
pathn = Pathname.new(Dir.home) + default_path if Util.nil_or_dontexist?(path)
|
243
|
+
pathn = nil if Util.nil_or_dontexist?(pathn)
|
244
|
+
pathn
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
data/lib/secretmgr/version.rb
CHANGED
data/lib/secretmgr.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "openssl"
|
4
|
-
require "base64"
|
5
|
-
require "multi_json"
|
6
|
-
|
7
|
-
require "
|
8
|
-
|
9
|
-
require_relative "secretmgr/
|
10
|
-
require_relative "secretmgr/
|
11
|
-
require_relative "secretmgr/
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
require "base64"
|
5
|
+
require "multi_json"
|
6
|
+
|
7
|
+
require "loggerx"
|
8
|
+
require_relative "secretmgr/version"
|
9
|
+
require_relative "secretmgr/util"
|
10
|
+
require_relative "secretmgr/globalsetting"
|
11
|
+
require_relative "secretmgr/cli"
|
12
|
+
require_relative "secretmgr/secretmgr"
|
13
|
+
require_relative "secretmgr/config"
|
14
|
+
require_relative "secretmgr/secret"
|
15
|
+
require_relative "secretmgr/loggerxs"
|
16
|
+
# require_relative "secretmgr/loggerxs"
|
17
|
+
|
18
|
+
module Secretmgr
|
19
|
+
INSTALLED_APP = "installed"
|
20
|
+
WEB_APP = "web"
|
21
|
+
CLIENT_ID = "client_id"
|
22
|
+
CLIENT_SECRET = "client_secret"
|
23
|
+
CIPHER_NAME = "AES-256-CBC"
|
24
|
+
|
25
|
+
class Error < StandardError; end
|
26
|
+
|
27
|
+
# Your code goes here...
|
28
|
+
end
|
data/rubocoprefine.bat
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
REMM メソッド定義やメソッド呼び出しの()をいい感じに
|
2
|
-
rubocop -a --only Style/DefWithParentheses,\
|
3
|
-
Style/MethodCallParentheses,\
|
4
|
-
Style/MethodDefParentheses
|
5
|
-
|
6
|
-
REM インデント崩れを修正
|
7
|
-
rubocop -a --only Style/IndentationConsistency,\
|
8
|
-
Style/IndentationWidth,\
|
9
|
-
Style/MultilineOperationIndentation
|
10
|
-
|
11
|
-
REM 空行をいい感じに
|
12
|
-
rubocop -a --only Style/EmptyLineBetweenDefs,\
|
13
|
-
Style/EmptyLines,\
|
14
|
-
Style/EmptyLinesAroundAccessModifier,\
|
15
|
-
Style/EmptyLinesAroundBlockBody,\
|
16
|
-
Style/EmptyLinesAroundClassBody,\
|
17
|
-
Style/EmptyLinesAroundMethodBody,\
|
18
|
-
Style/EmptyLinesAroundModuleBody,\
|
19
|
-
Style/TrailingBlankLines
|
20
|
-
|
21
|
-
REM コロンやカンマの前後のスペースをいい感じにする
|
22
|
-
rubocop -a --only Style/SpaceAfterColon,\
|
23
|
-
Style/SpaceAfterComma,\
|
24
|
-
Style/SpaceAfterNot,\
|
25
|
-
Style/SpaceAfterSemicolon,\
|
26
|
-
Style/SpaceAroundEqualsInParameterDefault,\
|
27
|
-
Style/SpaceBeforeSemicolon
|
28
|
-
|
29
|
-
REM 行末のスペース削除
|
1
|
+
REMM メソッド定義やメソッド呼び出しの()をいい感じに
|
2
|
+
rubocop -a --only Style/DefWithParentheses,\
|
3
|
+
Style/MethodCallParentheses,\
|
4
|
+
Style/MethodDefParentheses
|
5
|
+
|
6
|
+
REM インデント崩れを修正
|
7
|
+
rubocop -a --only Style/IndentationConsistency,\
|
8
|
+
Style/IndentationWidth,\
|
9
|
+
Style/MultilineOperationIndentation
|
10
|
+
|
11
|
+
REM 空行をいい感じに
|
12
|
+
rubocop -a --only Style/EmptyLineBetweenDefs,\
|
13
|
+
Style/EmptyLines,\
|
14
|
+
Style/EmptyLinesAroundAccessModifier,\
|
15
|
+
Style/EmptyLinesAroundBlockBody,\
|
16
|
+
Style/EmptyLinesAroundClassBody,\
|
17
|
+
Style/EmptyLinesAroundMethodBody,\
|
18
|
+
Style/EmptyLinesAroundModuleBody,\
|
19
|
+
Style/TrailingBlankLines
|
20
|
+
|
21
|
+
REM コロンやカンマの前後のスペースをいい感じにする
|
22
|
+
rubocop -a --only Style/SpaceAfterColon,\
|
23
|
+
Style/SpaceAfterComma,\
|
24
|
+
Style/SpaceAfterNot,\
|
25
|
+
Style/SpaceAfterSemicolon,\
|
26
|
+
Style/SpaceAroundEqualsInParameterDefault,\
|
27
|
+
Style/SpaceBeforeSemicolon
|
28
|
+
|
29
|
+
REM 行末のスペース削除
|
30
30
|
rubocop -a --only Style/TrailingWhitespace
|