s7 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/ChangeLog +311 -0
  2. data/LICENCE +24 -0
  3. data/README +56 -0
  4. data/Rakefile +128 -0
  5. data/VERSION +1 -0
  6. data/bin/s7cli +27 -0
  7. data/lib/gettext.rb +28 -0
  8. data/lib/s7.rb +12 -0
  9. data/lib/s7/action.rb +7 -0
  10. data/lib/s7/attribute.rb +226 -0
  11. data/lib/s7/cipher.rb +110 -0
  12. data/lib/s7/configuration.rb +41 -0
  13. data/lib/s7/entry.rb +106 -0
  14. data/lib/s7/entry_collection.rb +44 -0
  15. data/lib/s7/entry_template.rb +10 -0
  16. data/lib/s7/exception.rb +116 -0
  17. data/lib/s7/file.rb +77 -0
  18. data/lib/s7/gpass_file.rb +202 -0
  19. data/lib/s7/key.rb +83 -0
  20. data/lib/s7/message_catalog.rb +5 -0
  21. data/lib/s7/s7_file.rb +47 -0
  22. data/lib/s7/s7cli.rb +213 -0
  23. data/lib/s7/s7cli/attribute_command.rb +69 -0
  24. data/lib/s7/s7cli/command.rb +210 -0
  25. data/lib/s7/s7cli/entry_collection_command.rb +63 -0
  26. data/lib/s7/s7cli/entry_command.rb +728 -0
  27. data/lib/s7/s7cli/option.rb +101 -0
  28. data/lib/s7/secret_generator.rb +30 -0
  29. data/lib/s7/undo_stack.rb +7 -0
  30. data/lib/s7/unicode_data.rb +29 -0
  31. data/lib/s7/utils.rb +37 -0
  32. data/lib/s7/world.rb +150 -0
  33. data/setup.rb +1585 -0
  34. data/test/s7/attribute_test.rb +45 -0
  35. data/test/s7/gpass_file_test.rb +169 -0
  36. data/test/s7/gpass_file_test/passwords.gps.empty +1 -0
  37. data/test/s7/gpass_file_test/passwords.gps.one_entry +2 -0
  38. data/test/s7/gpass_file_test/passwords.gps.three_entries +3 -0
  39. data/test/s7/gpass_file_test/passwords.gps.with_folders +0 -0
  40. data/test/s7/secret_generator_test.rb +29 -0
  41. data/test/s7/unicode_data_test.rb +28 -0
  42. data/test/s7/world_test.rb +35 -0
  43. data/test/test_helper.rb +19 -0
  44. metadata +108 -0
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -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:
@@ -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
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # S7 の名前空間を定義。
4
+ module S7
5
+ # バージョン。
6
+ VERSION = "0.0.1"
7
+ end
8
+
9
+ require "s7/world"
10
+ require "s7/s7_file"
11
+ require "s7/exception"
12
+ require "s7/gpass_file"
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module S7
4
+ # 操作を表現する。
5
+ class Action
6
+ end
7
+ end
@@ -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
@@ -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