s7 0.0.1
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.
- data/ChangeLog +311 -0
- data/LICENCE +24 -0
- data/README +56 -0
- data/Rakefile +128 -0
- data/VERSION +1 -0
- data/bin/s7cli +27 -0
- data/lib/gettext.rb +28 -0
- data/lib/s7.rb +12 -0
- data/lib/s7/action.rb +7 -0
- data/lib/s7/attribute.rb +226 -0
- data/lib/s7/cipher.rb +110 -0
- data/lib/s7/configuration.rb +41 -0
- data/lib/s7/entry.rb +106 -0
- data/lib/s7/entry_collection.rb +44 -0
- data/lib/s7/entry_template.rb +10 -0
- data/lib/s7/exception.rb +116 -0
- data/lib/s7/file.rb +77 -0
- data/lib/s7/gpass_file.rb +202 -0
- data/lib/s7/key.rb +83 -0
- data/lib/s7/message_catalog.rb +5 -0
- data/lib/s7/s7_file.rb +47 -0
- data/lib/s7/s7cli.rb +213 -0
- data/lib/s7/s7cli/attribute_command.rb +69 -0
- data/lib/s7/s7cli/command.rb +210 -0
- data/lib/s7/s7cli/entry_collection_command.rb +63 -0
- data/lib/s7/s7cli/entry_command.rb +728 -0
- data/lib/s7/s7cli/option.rb +101 -0
- data/lib/s7/secret_generator.rb +30 -0
- data/lib/s7/undo_stack.rb +7 -0
- data/lib/s7/unicode_data.rb +29 -0
- data/lib/s7/utils.rb +37 -0
- data/lib/s7/world.rb +150 -0
- data/setup.rb +1585 -0
- data/test/s7/attribute_test.rb +45 -0
- data/test/s7/gpass_file_test.rb +169 -0
- data/test/s7/gpass_file_test/passwords.gps.empty +1 -0
- data/test/s7/gpass_file_test/passwords.gps.one_entry +2 -0
- data/test/s7/gpass_file_test/passwords.gps.three_entries +3 -0
- data/test/s7/gpass_file_test/passwords.gps.with_folders +0 -0
- data/test/s7/secret_generator_test.rb +29 -0
- data/test/s7/unicode_data_test.rb +28 -0
- data/test/s7/world_test.rb +35 -0
- data/test/test_helper.rb +19 -0
- metadata +108 -0
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/s7cli
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/ruby1.9
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Ruby 1.9 で Ruby-GetText-Package を使用するのはまだ時間がかかるようだ。
|
5
|
+
# そのため、LANG=C にして様子を見る。
|
6
|
+
ENV["LANG"] = "C"
|
7
|
+
|
8
|
+
$:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
|
9
|
+
|
10
|
+
require "gettext"
|
11
|
+
|
12
|
+
require "s7"
|
13
|
+
require "s7/s7cli"
|
14
|
+
|
15
|
+
path = File.expand_path("../data/locale/", File.dirname(__FILE__))
|
16
|
+
GetText.bindtextdomain("s7", :path => path)
|
17
|
+
begin
|
18
|
+
S7::S7Cli.run(ARGV)
|
19
|
+
rescue S7::ApplicationError => e
|
20
|
+
puts(e.message)
|
21
|
+
puts("----- back trace -----")
|
22
|
+
raise e
|
23
|
+
end
|
24
|
+
|
25
|
+
# Local Variables:
|
26
|
+
# mode: ruby
|
27
|
+
# End:
|
data/lib/gettext.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# gettext のモック
|
4
|
+
module GetText
|
5
|
+
def self.included(mod)
|
6
|
+
class << mod
|
7
|
+
def _(s)
|
8
|
+
return s
|
9
|
+
end
|
10
|
+
|
11
|
+
def N_(s)
|
12
|
+
return s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def _(s)
|
18
|
+
return s
|
19
|
+
end
|
20
|
+
|
21
|
+
def N_(s)
|
22
|
+
return s
|
23
|
+
end
|
24
|
+
|
25
|
+
def bindtextdomain(*args)
|
26
|
+
end
|
27
|
+
module_function :bindtextdomain
|
28
|
+
end
|
data/lib/s7.rb
ADDED
data/lib/s7/action.rb
ADDED
data/lib/s7/attribute.rb
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "gettext"
|
5
|
+
|
6
|
+
module S7
|
7
|
+
# 属性を表現する。
|
8
|
+
class Attribute
|
9
|
+
include GetText
|
10
|
+
|
11
|
+
# サポートしている属性のクラス。
|
12
|
+
@@attribute_classes = {}
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def create_instance(type, options)
|
16
|
+
return @@attribute_classes[type].new(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# 属性の型名の配列を返す。
|
20
|
+
def types
|
21
|
+
return @@attribute_classes.keys
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def type(name)
|
27
|
+
@@attribute_classes[name] = self
|
28
|
+
self.const_set("TYPE", name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# 名前。
|
33
|
+
attr_accessor :name
|
34
|
+
|
35
|
+
# 機密情報かどうか。true であれば機密情報、false であればそうでない。
|
36
|
+
attr_accessor :secret
|
37
|
+
|
38
|
+
# 値を編集できるかどうか。true であれば編集でき、false であれ
|
39
|
+
# ばそうでない。
|
40
|
+
attr_accessor :editabled
|
41
|
+
|
42
|
+
# 削除できるかどうか。true であれば削除できず、false であれ
|
43
|
+
# ばそうでない。
|
44
|
+
attr_accessor :protected
|
45
|
+
|
46
|
+
def initialize(options)
|
47
|
+
self.name = options["name"]
|
48
|
+
self.value = options["value"]
|
49
|
+
self.secret = options["secret"] ? true : false
|
50
|
+
if options.key?("editabled")
|
51
|
+
self.editabled = options["editabled"] ? true : false
|
52
|
+
else
|
53
|
+
self.editabled = true
|
54
|
+
end
|
55
|
+
self.protected = options["protected"] ? true : false
|
56
|
+
end
|
57
|
+
|
58
|
+
# value を取得する。
|
59
|
+
def value
|
60
|
+
if @value.nil?
|
61
|
+
return nil
|
62
|
+
else
|
63
|
+
return get_value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# value を設定する。
|
68
|
+
def value=(val)
|
69
|
+
if val.nil?
|
70
|
+
@value = val
|
71
|
+
else
|
72
|
+
set_value(val)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# 属性の型を取得する。
|
77
|
+
def type
|
78
|
+
return self.class.const_get("TYPE")
|
79
|
+
end
|
80
|
+
|
81
|
+
# 機密情報かどうかを取得する。
|
82
|
+
# 機密情報の場合、true を返す。そうでなれば false を返す。
|
83
|
+
def secret?
|
84
|
+
return secret ? true : false
|
85
|
+
end
|
86
|
+
|
87
|
+
# ユーザによる値の編集ができるかどうかを取得する。
|
88
|
+
# 編集できる場合、true を返す。そうでなければ true を返す。
|
89
|
+
def editable?
|
90
|
+
return editabled ? true : false
|
91
|
+
end
|
92
|
+
|
93
|
+
# ユーザによる削除ができるかどうかを取得する。
|
94
|
+
# 削除できる場合、true を返す。そうでなければ true を返す。
|
95
|
+
def protected?
|
96
|
+
return protected ? true : false
|
97
|
+
end
|
98
|
+
|
99
|
+
# value を表示するために文字列に変換する。
|
100
|
+
# このとき、 secret が true であれば「*」でマスクする。
|
101
|
+
def display_value(secret = @secret)
|
102
|
+
if secret
|
103
|
+
return "*" * value.to_s.length
|
104
|
+
else
|
105
|
+
return value.to_s
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def get_value
|
112
|
+
return @value
|
113
|
+
end
|
114
|
+
|
115
|
+
def set_value(val)
|
116
|
+
@value = val
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# 文字列の属性を表現する。
|
121
|
+
class TextAttribute < Attribute
|
122
|
+
type("text")
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def get_value
|
127
|
+
return @value.to_s.force_encoding("utf-8")
|
128
|
+
end
|
129
|
+
|
130
|
+
def set_value(val)
|
131
|
+
@value = val.to_s.force_encoding("utf-8")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# 数値の属性を表現する。
|
136
|
+
class NumericAttribute < Attribute
|
137
|
+
type("numeric")
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def get_value
|
142
|
+
return @value.to_i
|
143
|
+
end
|
144
|
+
|
145
|
+
def set_value(val)
|
146
|
+
@value = val.to_i
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# 真偽値の属性を表現する。
|
151
|
+
class BooleanAttribute < Attribute
|
152
|
+
type("boolean")
|
153
|
+
|
154
|
+
# value を表示するために文字列に変換する。
|
155
|
+
# secret が true であれば「*」を返す。
|
156
|
+
# そうでなければ、Yes か No を返す。
|
157
|
+
def display_value(secret = @secret)
|
158
|
+
if secret
|
159
|
+
return "*"
|
160
|
+
else
|
161
|
+
return value ? _("Yes") : _("No")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
private
|
166
|
+
|
167
|
+
def get_value
|
168
|
+
return @value ? true : false
|
169
|
+
end
|
170
|
+
|
171
|
+
def set_value(val)
|
172
|
+
@value = val ? true : false
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# 日時の属性を表現する。
|
177
|
+
class DateTimeAttribute < Attribute
|
178
|
+
type("datetime")
|
179
|
+
|
180
|
+
# value を表示するために文字列に変換する。
|
181
|
+
# secret が true であれば「*」を返す。
|
182
|
+
# そうでなければ、「%Y/%m/%d %H:%M:%S」でフォーマットした文字列を返す。
|
183
|
+
# また、時分秒が全て0の場合は「%Y/%m/%d」でフォーマットする。
|
184
|
+
def display_value(secret = @secret)
|
185
|
+
if secret
|
186
|
+
return "*"
|
187
|
+
else
|
188
|
+
format = "%Y/%m/%d"
|
189
|
+
if value.hour != 0 || value.min != 0 || value.sec != 0
|
190
|
+
format << " %H:%M:%S"
|
191
|
+
end
|
192
|
+
return value.strftime(format)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def get_value
|
199
|
+
return @value.to_datetime
|
200
|
+
end
|
201
|
+
|
202
|
+
def set_value(val)
|
203
|
+
case val
|
204
|
+
when Time, DateTime, Date
|
205
|
+
@value = val.to_datetime
|
206
|
+
else
|
207
|
+
@value = DateTime.parse(val.to_s)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# ファイルの属性を表現する。
|
213
|
+
class FileAttribute < Attribute
|
214
|
+
type("file")
|
215
|
+
end
|
216
|
+
|
217
|
+
# 画像の属性を表現する。
|
218
|
+
class FigureAttribute < FileAttribute
|
219
|
+
type("figure")
|
220
|
+
end
|
221
|
+
|
222
|
+
# 不明な属性を表現する。
|
223
|
+
class UnknownAttribute < Attribute
|
224
|
+
type("unknown")
|
225
|
+
end
|
226
|
+
end
|
data/lib/s7/cipher.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
|
5
|
+
module S7
|
6
|
+
# 秘密鍵暗号化方式を用いた暗号化処理を表現する。
|
7
|
+
class Cipher
|
8
|
+
@@cipher_classes = {}
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def create_instance(type, options)
|
12
|
+
return @@cipher_classes[type].new(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def cipher_type(name)
|
18
|
+
if @@cipher_classes.nil?
|
19
|
+
@@cipher_classes = {}
|
20
|
+
end
|
21
|
+
@@cipher_classes[name] = self
|
22
|
+
self.const_set("CIPHER_TYPE", name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_accessor :options
|
27
|
+
|
28
|
+
def initialize(options)
|
29
|
+
self.options = options
|
30
|
+
end
|
31
|
+
|
32
|
+
# io で指定した IO からデータを読み込み、復号する。
|
33
|
+
def decrypt(io)
|
34
|
+
begin
|
35
|
+
cipher = create_cipher
|
36
|
+
cipher.decrypt
|
37
|
+
parse_options(cipher, options)
|
38
|
+
s = ""
|
39
|
+
while d = io.read(cipher.block_size)
|
40
|
+
s << cipher.update(d)
|
41
|
+
end
|
42
|
+
s << cipher.final
|
43
|
+
rescue OpenSSL::Cipher::CipherError
|
44
|
+
raise InvalidPassphrase
|
45
|
+
end
|
46
|
+
return s
|
47
|
+
end
|
48
|
+
|
49
|
+
# io で指定した IO からデータを読み込み、暗号化する。
|
50
|
+
def encrypt(io)
|
51
|
+
cipher = create_cipher
|
52
|
+
cipher.encrypt
|
53
|
+
parse_options(cipher, options)
|
54
|
+
s = ""
|
55
|
+
while d = io.read(cipher.block_size)
|
56
|
+
s << cipher.update(d)
|
57
|
+
end
|
58
|
+
s << cipher.final
|
59
|
+
return s
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def create_cipher
|
65
|
+
cipher_type = self.class.const_get("CIPHER_TYPE")
|
66
|
+
return OpenSSL::Cipher::Cipher.new(cipher_type)
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_options(cipher, options)
|
70
|
+
if options.key?(:passphrase)
|
71
|
+
cipher.pkcs5_keyivgen(options[:passphrase])
|
72
|
+
elsif options.key?(:key)
|
73
|
+
cipher.key_len = options[:key].length
|
74
|
+
cipher.key = options[:key].key
|
75
|
+
if options.key?(:iv)
|
76
|
+
cipher.iv = options[:iv]
|
77
|
+
end
|
78
|
+
else
|
79
|
+
raise ArgumentError, "too few options: :passphrase or :key"
|
80
|
+
end
|
81
|
+
if options.key?(:padding)
|
82
|
+
cipher.padding = options[:padding]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# 秘密鍵方式の一つ AES を用いて暗号化処理を行うクラスを表現する。
|
88
|
+
class Aes256CbcCipher < Cipher
|
89
|
+
cipher_type "AES-256-CBC"
|
90
|
+
end
|
91
|
+
|
92
|
+
# 秘密鍵方式の一つ Blowfish を用いて暗号化処理を行うクラスを表現する。
|
93
|
+
class BfCbcCipher < Cipher
|
94
|
+
cipher_type "BF-CBC"
|
95
|
+
end
|
96
|
+
|
97
|
+
# Cipher クラスと同じインタフェースを持つが、暗号化しないクラスを表現
|
98
|
+
# する。
|
99
|
+
class PlainCipher < Cipher
|
100
|
+
cipher_type "plain"
|
101
|
+
|
102
|
+
def encrypt(io)
|
103
|
+
return io.read
|
104
|
+
end
|
105
|
+
|
106
|
+
def decrypt(io)
|
107
|
+
return io.read
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module S7
|
6
|
+
# 設定を表現する。
|
7
|
+
class Configuration
|
8
|
+
# デフォルトの秘密鍵暗号方式。
|
9
|
+
DEFAULT_CIPHER_TYPE = "AES-256-CBC"
|
10
|
+
|
11
|
+
# World オブジェクト。
|
12
|
+
attr_accessor :world
|
13
|
+
|
14
|
+
# 秘密鍵暗号方式。
|
15
|
+
attr_accessor :cipher_type
|
16
|
+
|
17
|
+
def initialize(world)
|
18
|
+
@world = world
|
19
|
+
@cipher_type = DEFAULT_CIPHER_TYPE
|
20
|
+
end
|
21
|
+
|
22
|
+
# 設定をファイルに書き出す。
|
23
|
+
def save(path)
|
24
|
+
hash = {
|
25
|
+
"cipher_type" => @cipher_type,
|
26
|
+
}
|
27
|
+
FileUtils.touch(path)
|
28
|
+
File.open(path, "wb") do |f|
|
29
|
+
f.write(hash.to_yaml)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# 設定をファイルから読み込む。
|
34
|
+
def load(path)
|
35
|
+
File.open(path, "rb") do |f|
|
36
|
+
hash = YAML.load(f.read)
|
37
|
+
@cipher_type = hash["cipher_type"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|