tome 0.1.0.pre → 0.1.1.pre
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/README.md +9 -3
- data/lib/tome.rb +2 -0
- data/lib/tome/command.rb +31 -203
- data/lib/tome/padding.rb +16 -0
- data/lib/tome/tome.rb +67 -18
- data/lib/tome/usage.rb +193 -0
- data/lib/tome/version.rb +1 -1
- metadata +3 -1
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
## Tome
|
2
2
|
|
3
|
-
Tome is a lightweight password manager with a humane command-line interface.
|
3
|
+
Tome is a lightweight password manager with a humane command-line interface.
|
4
|
+
|
5
|
+
Tome stores your passwords in an encrypted file which you manage with a single master password.
|
6
|
+
You can keep track of multiple complex passwords without having to remember any of them.
|
4
7
|
|
5
8
|
*Disclaimer* I am not a security expert. I've only had limited formal training in security and cryptography.
|
6
9
|
Now that I've scared off all but the bravest, feel free to look [under the hood](#under-the-hood) or
|
@@ -9,13 +12,16 @@ at the security bits in [crypt.rb](https://github.com/schmich/tome/blob/master/l
|
|
9
12
|
## Installation
|
10
13
|
|
11
14
|
* Requires [Ruby 1.9.3](http://www.ruby-lang.org/en/downloads/) or newer.
|
12
|
-
*
|
15
|
+
* `gem install tome --pre`
|
16
|
+
* `tome` is now available on the command-line.
|
13
17
|
|
14
18
|
## Usage
|
15
19
|
|
16
20
|
The first time you run `tome`, you'll be asked to create a master password for your encrypted password database.
|
17
21
|
Any operations involving your password database will require this master password.
|
18
22
|
|
23
|
+
Creating a new password is simple:
|
24
|
+
|
19
25
|
> tome set linkedin.com
|
20
26
|
Creating tome database.
|
21
27
|
Master password:
|
@@ -24,7 +30,7 @@ Any operations involving your password database will require this master passwor
|
|
24
30
|
Password (verify):
|
25
31
|
Created password for linkedin.com.
|
26
32
|
|
27
|
-
Recalling a password is easy:
|
33
|
+
Recalling a password is just as easy:
|
28
34
|
|
29
35
|
> tome get linkedin.com
|
30
36
|
Master password:
|
data/lib/tome.rb
CHANGED
data/lib/tome/command.rb
CHANGED
@@ -29,7 +29,12 @@ module Tome
|
|
29
29
|
begin
|
30
30
|
handle_command(args)
|
31
31
|
rescue CommandError => error
|
32
|
-
@err.puts error.message
|
32
|
+
@err.puts "Error: #{error.message}"
|
33
|
+
return 1
|
34
|
+
rescue FileFormatError => error
|
35
|
+
# Fix file separators for Windows.
|
36
|
+
filename = @tome_filename.gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
|
37
|
+
@err.puts "Error: Cannot read #{filename}: #{error.message}"
|
33
38
|
return 1
|
34
39
|
end
|
35
40
|
|
@@ -53,9 +58,9 @@ module Tome
|
|
53
58
|
commands = {
|
54
59
|
/\A(help|-h|--help)\z/i => :help,
|
55
60
|
/\A(version|ver|-v|--version)\z/i => :version,
|
56
|
-
/\A(set|s)\z/i => :set,
|
61
|
+
/\A(set|s|add)\z/i => :set,
|
57
62
|
/\A(get|g|show)\z/i => :get,
|
58
|
-
/\A(delete|del|
|
63
|
+
/\A(delete|del|rm|remove)\z/i => :delete,
|
59
64
|
/\A(generate|gen)\z/i => :generate,
|
60
65
|
/\A(copy|cp)\z/i => :copy,
|
61
66
|
/\A(rename|ren|rn)\z/i => :rename,
|
@@ -340,12 +345,25 @@ module Tome
|
|
340
345
|
end
|
341
346
|
|
342
347
|
def input_password
|
343
|
-
|
344
|
-
|
345
|
-
|
348
|
+
input = proc { |stdin|
|
349
|
+
raw = stdin.gets
|
350
|
+
return nil if raw.nil?
|
351
|
+
|
352
|
+
password = raw.strip
|
353
|
+
@out.puts
|
346
354
|
|
347
355
|
return password
|
348
356
|
}
|
357
|
+
|
358
|
+
begin
|
359
|
+
@in.noecho { |stdin|
|
360
|
+
input.call stdin
|
361
|
+
}
|
362
|
+
rescue Errno::EBADF
|
363
|
+
# This can happen when stdin refers to a file or pipe.
|
364
|
+
# In this case, we ignore 'no echo' and do normal input.
|
365
|
+
input.call @in
|
366
|
+
end
|
349
367
|
end
|
350
368
|
|
351
369
|
def prompt_confirm(prompt)
|
@@ -381,7 +399,12 @@ module Tome
|
|
381
399
|
tome = Tome.new(@tome_filename, master_password)
|
382
400
|
rescue MasterPasswordError
|
383
401
|
@err.puts 'Incorrect master password.'
|
384
|
-
|
402
|
+
|
403
|
+
if master_password.nil?
|
404
|
+
raise CommandError, 'Authentication failed.'
|
405
|
+
else
|
406
|
+
retry
|
407
|
+
end
|
385
408
|
end
|
386
409
|
|
387
410
|
return tome
|
@@ -397,199 +420,4 @@ module Tome
|
|
397
420
|
end
|
398
421
|
end
|
399
422
|
end
|
400
|
-
|
401
|
-
# TODO: Complete these.
|
402
|
-
$usage = <<END
|
403
|
-
Usage:
|
404
|
-
|
405
|
-
tome set [user@]<domain> [password]
|
406
|
-
|
407
|
-
Create or update the password for an account.
|
408
|
-
Example: tome set foo@gmail.com
|
409
|
-
|
410
|
-
tome generate [user@]<domain>
|
411
|
-
|
412
|
-
Generate a random password for an account.
|
413
|
-
Example: tome generate reddit.com
|
414
|
-
|
415
|
-
tome get <pattern>
|
416
|
-
|
417
|
-
Show the passwords for all accounts matching the pattern.
|
418
|
-
Example: tome get youtube
|
419
|
-
|
420
|
-
tome copy <pattern>
|
421
|
-
|
422
|
-
Copy the password for the account matching the pattern.
|
423
|
-
Example: tome copy news.ycombinator.com
|
424
|
-
|
425
|
-
tome list
|
426
|
-
|
427
|
-
Show all stored accounts and passwords.
|
428
|
-
Example: tome list
|
429
|
-
|
430
|
-
tome delete [user@]<domain>
|
431
|
-
|
432
|
-
Delete the password for an account.
|
433
|
-
Example: tome delete foo@slashdot.org
|
434
|
-
|
435
|
-
tome rename <old> <new>
|
436
|
-
|
437
|
-
Rename the account information stored.
|
438
|
-
Example: tome rename twitter.com foo@twitter.com
|
439
|
-
|
440
|
-
tome help
|
441
|
-
|
442
|
-
Shows help for a specific command.
|
443
|
-
Example: tome help set
|
444
|
-
|
445
|
-
tome version
|
446
|
-
|
447
|
-
Shows the version of tome.
|
448
|
-
Example: tome version
|
449
|
-
END
|
450
|
-
|
451
|
-
$help_usage = <<END
|
452
|
-
tome help
|
453
|
-
|
454
|
-
Shows help for a specific command.
|
455
|
-
|
456
|
-
Usage:
|
457
|
-
|
458
|
-
tome help
|
459
|
-
tome help <command>
|
460
|
-
|
461
|
-
Examples:
|
462
|
-
|
463
|
-
tome help
|
464
|
-
tome help set
|
465
|
-
tome help help (so meta)
|
466
|
-
|
467
|
-
Alias: help, --help, -h
|
468
|
-
END
|
469
|
-
|
470
|
-
$set_usage = <<END
|
471
|
-
tome set
|
472
|
-
|
473
|
-
Create or update the password for an account. The user is optional.
|
474
|
-
If you do not specify a password, you will be prompted for one.
|
475
|
-
|
476
|
-
Usage:
|
477
|
-
|
478
|
-
tome set [user@]<domain> [password]
|
479
|
-
|
480
|
-
Examples:
|
481
|
-
|
482
|
-
tome set gmail.com
|
483
|
-
tome set gmail.com p4ssw0rd
|
484
|
-
tome set foo@gmail.com
|
485
|
-
tome set foo@gmail.com p4ssw0rd
|
486
|
-
|
487
|
-
Alias: set, s
|
488
|
-
END
|
489
|
-
|
490
|
-
$get_usage = <<END
|
491
|
-
tome get
|
492
|
-
|
493
|
-
Show the passwords for all accounts matching the pattern.
|
494
|
-
Matching is done with substring search. Wildcards are not supported.
|
495
|
-
|
496
|
-
Usage:
|
497
|
-
|
498
|
-
tome get <pattern>
|
499
|
-
|
500
|
-
Examples:
|
501
|
-
|
502
|
-
tome get gmail
|
503
|
-
tome get foo@
|
504
|
-
tome get foo@gmail.com
|
505
|
-
|
506
|
-
Alias: get, g, show
|
507
|
-
END
|
508
|
-
|
509
|
-
$delete_usage = <<END
|
510
|
-
tome delete
|
511
|
-
|
512
|
-
Delete the password for an account.
|
513
|
-
|
514
|
-
Usage:
|
515
|
-
|
516
|
-
tome delete [user@]<domain>
|
517
|
-
|
518
|
-
Examples:
|
519
|
-
|
520
|
-
tome delete gmail.com
|
521
|
-
tome delete foo@gmail.com
|
522
|
-
|
523
|
-
Alias: delete, del, d, remove, rm
|
524
|
-
END
|
525
|
-
|
526
|
-
$generate_usage = <<END
|
527
|
-
tome generate
|
528
|
-
|
529
|
-
Generate a random password for an account. The user is optional.
|
530
|
-
|
531
|
-
Usage:
|
532
|
-
|
533
|
-
tome generate [user@]<domain>
|
534
|
-
|
535
|
-
Examples:
|
536
|
-
|
537
|
-
tome generate gmail.com
|
538
|
-
tome generate foo@gmail.com
|
539
|
-
|
540
|
-
Alias: generate, gen
|
541
|
-
END
|
542
|
-
|
543
|
-
$copy_usage = <<END
|
544
|
-
tome copy
|
545
|
-
|
546
|
-
Copy the password for the account matching the pattern.
|
547
|
-
If more than one account matches the pattern, nothing happens.
|
548
|
-
Matching is done with substring search. Wildcards are not supported.
|
549
|
-
|
550
|
-
Usage:
|
551
|
-
|
552
|
-
tome copy <pattern>
|
553
|
-
|
554
|
-
Examples:
|
555
|
-
|
556
|
-
tome copy gmail
|
557
|
-
tome copy foo@
|
558
|
-
tome copy foo@gmail.com
|
559
|
-
|
560
|
-
Alias: copy, cp
|
561
|
-
END
|
562
|
-
|
563
|
-
$list_usage = <<END
|
564
|
-
tome list
|
565
|
-
|
566
|
-
Show all stored accounts and passwords.
|
567
|
-
|
568
|
-
Usage:
|
569
|
-
|
570
|
-
tome list
|
571
|
-
|
572
|
-
Examples:
|
573
|
-
|
574
|
-
tome list
|
575
|
-
|
576
|
-
Alias: list, ls
|
577
|
-
END
|
578
|
-
|
579
|
-
$rename_usage = <<END
|
580
|
-
tome rename
|
581
|
-
|
582
|
-
Rename the account information stored.
|
583
|
-
|
584
|
-
Usage:
|
585
|
-
|
586
|
-
tome rename <old> <new>
|
587
|
-
|
588
|
-
Examples:
|
589
|
-
|
590
|
-
tome rename gmail.com foo@gmail.com
|
591
|
-
tome rename foo@gmail.com bar@gmail.com
|
592
|
-
|
593
|
-
Alias: rename, ren, rn
|
594
|
-
END
|
595
|
-
end
|
423
|
+
end
|
data/lib/tome/padding.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module Tome
|
5
|
+
class Padding
|
6
|
+
def self.pad(value, min_pad, max_pad)
|
7
|
+
padding = Random.rand(min_pad..max_pad)
|
8
|
+
YAML.dump(:value => value, :padding => SecureRandom.random_bytes(padding))
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.unpad(inflated_value)
|
12
|
+
yaml = YAML.load(inflated_value)
|
13
|
+
yaml[:value]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/tome/tome.rb
CHANGED
@@ -5,17 +5,36 @@ module Tome
|
|
5
5
|
class MasterPasswordError < RuntimeError
|
6
6
|
end
|
7
7
|
|
8
|
+
class FileFormatError < RuntimeError
|
9
|
+
end
|
10
|
+
|
8
11
|
class Tome
|
9
12
|
def self.exists?(tome_filename)
|
10
13
|
return !load_tome(tome_filename).nil?
|
11
14
|
end
|
12
15
|
|
13
16
|
def self.create!(tome_filename, master_password, stretch = 100_000)
|
17
|
+
if tome_filename.nil? || tome_filename.empty?
|
18
|
+
raise ArgumentError
|
19
|
+
end
|
20
|
+
|
21
|
+
if master_password.nil? || master_password.empty?
|
22
|
+
raise MasterPasswordError
|
23
|
+
end
|
24
|
+
|
14
25
|
save_tome(tome_filename, new_tome(stretch), {}, master_password)
|
15
26
|
return Tome.new(tome_filename, master_password)
|
16
27
|
end
|
17
28
|
|
18
29
|
def initialize(tome_filename, master_password)
|
30
|
+
if tome_filename.nil? || tome_filename.empty?
|
31
|
+
raise ArgumentError
|
32
|
+
end
|
33
|
+
|
34
|
+
if master_password.nil? || master_password.empty?
|
35
|
+
raise MasterPasswordError
|
36
|
+
end
|
37
|
+
|
19
38
|
@tome_filename = tome_filename
|
20
39
|
@master_password = master_password
|
21
40
|
|
@@ -145,23 +164,53 @@ module Tome
|
|
145
164
|
end
|
146
165
|
|
147
166
|
def self.load_tome(tome_filename)
|
167
|
+
if tome_filename.nil? || tome_filename.empty?
|
168
|
+
raise ArgumentError
|
169
|
+
end
|
170
|
+
|
148
171
|
return nil if !File.exist?(tome_filename)
|
149
172
|
|
150
173
|
contents = File.open(tome_filename, 'rb') { |file| file.read }
|
151
174
|
return nil if contents.length == 0
|
152
175
|
|
153
|
-
|
154
|
-
return nil if !
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
return
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
176
|
+
tome = YAML.load(contents)
|
177
|
+
return nil if !tome
|
178
|
+
|
179
|
+
validate_tome(tome)
|
180
|
+
|
181
|
+
return tome
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.validate_tome(tome)
|
185
|
+
if tome[:version].nil? || tome[:version].class != Fixnum
|
186
|
+
raise FileFormatError, 'The tome database is invalid (missing or invalid version).'
|
187
|
+
end
|
188
|
+
|
189
|
+
if tome[:version] > FILE_VERSION
|
190
|
+
raise FileFormatError, "The tome database comes from a newer version of tome (v#{tome[:version]} > v#{FILE_VERSION}). Try updating tome."
|
191
|
+
end
|
192
|
+
|
193
|
+
if tome[:version] < FILE_VERSION
|
194
|
+
raise FileFormatError, "The tome database is incompatible with this version of tome (v#{tome[:version]} < v#{FILE_VERSION})."
|
195
|
+
end
|
196
|
+
|
197
|
+
# TODO: Check version number, do file format migration if necessary.
|
198
|
+
|
199
|
+
if tome[:salt].nil? || tome[:salt].class != String || tome[:salt].empty?
|
200
|
+
raise FileFormatError, 'The tome database is invalid (missing or invalid salt).'
|
201
|
+
end
|
202
|
+
|
203
|
+
if tome[:iv].nil? || tome[:iv].class != String || tome[:iv].empty?
|
204
|
+
raise FileFormatError, 'The tome database is invalid (missing or invalid IV).'
|
205
|
+
end
|
206
|
+
|
207
|
+
if tome[:stretch].nil? || tome[:stretch].class != Fixnum || tome[:stretch] < 0
|
208
|
+
raise FileFormatError, 'The tome database is invalid (missing or invalid key stretch).'
|
209
|
+
end
|
210
|
+
|
211
|
+
if tome[:store].nil? || tome[:store].class != String || tome[:store].empty?
|
212
|
+
raise FileFormatError, 'The tome database is invalid (missing or invalid store).'
|
213
|
+
end
|
165
214
|
end
|
166
215
|
|
167
216
|
def load_store(tome)
|
@@ -170,20 +219,19 @@ module Tome
|
|
170
219
|
end
|
171
220
|
|
172
221
|
begin
|
173
|
-
|
222
|
+
padded_store_yaml = Crypt.decrypt(
|
174
223
|
:value => tome[:store],
|
175
224
|
:password => @master_password,
|
176
225
|
:stretch => tome[:stretch],
|
177
226
|
:salt => tome[:salt],
|
178
227
|
:iv => tome[:iv]
|
179
228
|
)
|
180
|
-
rescue ArgumentError
|
181
|
-
# TODO: Should probably be raising an error here.
|
182
|
-
return {}
|
183
229
|
rescue OpenSSL::Cipher::CipherError
|
184
230
|
raise MasterPasswordError
|
185
231
|
end
|
186
232
|
|
233
|
+
store_yaml = Padding.unpad(padded_store_yaml)
|
234
|
+
|
187
235
|
store = YAML.load(store_yaml)
|
188
236
|
return store || {}
|
189
237
|
end
|
@@ -194,12 +242,13 @@ module Tome
|
|
194
242
|
end
|
195
243
|
|
196
244
|
store_yaml = YAML.dump(store)
|
245
|
+
padded_store_yaml = Padding.pad(store_yaml, 1024, 4096)
|
197
246
|
|
198
247
|
new_salt = Crypt.new_salt
|
199
248
|
new_iv = Crypt.new_iv
|
200
249
|
|
201
250
|
encrypted_store = Crypt.encrypt(
|
202
|
-
:value =>
|
251
|
+
:value => padded_store_yaml,
|
203
252
|
:password => master_password,
|
204
253
|
:salt => new_salt,
|
205
254
|
:iv => new_iv,
|
@@ -259,6 +308,6 @@ module Tome
|
|
259
308
|
readable_store { }
|
260
309
|
end
|
261
310
|
|
262
|
-
FILE_VERSION =
|
311
|
+
FILE_VERSION = 2
|
263
312
|
end
|
264
313
|
end
|
data/lib/tome/usage.rb
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
$usage = <<END
|
2
|
+
Usage:
|
3
|
+
|
4
|
+
tome set [user@]<domain> [password]
|
5
|
+
|
6
|
+
Create or update the password for an account.
|
7
|
+
Example: tome set foo@gmail.com
|
8
|
+
|
9
|
+
tome generate [user@]<domain>
|
10
|
+
|
11
|
+
Generate a random password for an account.
|
12
|
+
Example: tome generate reddit.com
|
13
|
+
|
14
|
+
tome get <pattern>
|
15
|
+
|
16
|
+
Show the passwords for all accounts matching the pattern.
|
17
|
+
Example: tome get youtube
|
18
|
+
|
19
|
+
tome copy <pattern>
|
20
|
+
|
21
|
+
Copy the password for the account matching the pattern.
|
22
|
+
Example: tome copy news.ycombinator.com
|
23
|
+
|
24
|
+
tome list
|
25
|
+
|
26
|
+
Show all stored accounts and passwords.
|
27
|
+
Example: tome list
|
28
|
+
|
29
|
+
tome delete [user@]<domain>
|
30
|
+
|
31
|
+
Delete the password for an account.
|
32
|
+
Example: tome delete foo@slashdot.org
|
33
|
+
|
34
|
+
tome rename <old> <new>
|
35
|
+
|
36
|
+
Rename the account information stored.
|
37
|
+
Example: tome rename twitter.com foo@twitter.com
|
38
|
+
|
39
|
+
tome help
|
40
|
+
|
41
|
+
Shows help for a specific command.
|
42
|
+
Example: tome help set
|
43
|
+
|
44
|
+
tome version
|
45
|
+
|
46
|
+
Shows the version of tome.
|
47
|
+
Example: tome version
|
48
|
+
END
|
49
|
+
|
50
|
+
$help_usage = <<END
|
51
|
+
tome help
|
52
|
+
|
53
|
+
Shows help for a specific command.
|
54
|
+
|
55
|
+
Usage:
|
56
|
+
|
57
|
+
tome help
|
58
|
+
tome help <command>
|
59
|
+
|
60
|
+
Examples:
|
61
|
+
|
62
|
+
tome help
|
63
|
+
tome help set
|
64
|
+
tome help help (so meta)
|
65
|
+
|
66
|
+
Alias: help, --help, -h
|
67
|
+
END
|
68
|
+
|
69
|
+
$set_usage = <<END
|
70
|
+
tome set
|
71
|
+
|
72
|
+
Create or update the password for an account. The user is optional.
|
73
|
+
If you do not specify a password, you will be prompted for one.
|
74
|
+
|
75
|
+
Usage:
|
76
|
+
|
77
|
+
tome set [user@]<domain> [password]
|
78
|
+
|
79
|
+
Examples:
|
80
|
+
|
81
|
+
tome set gmail.com
|
82
|
+
tome set gmail.com p4ssw0rd
|
83
|
+
tome set foo@gmail.com
|
84
|
+
tome set foo@gmail.com p4ssw0rd
|
85
|
+
|
86
|
+
Alias: set, s, add
|
87
|
+
END
|
88
|
+
|
89
|
+
$get_usage = <<END
|
90
|
+
tome get
|
91
|
+
|
92
|
+
Show the passwords for all accounts matching the pattern.
|
93
|
+
Matching is done with substring search. Wildcards are not supported.
|
94
|
+
|
95
|
+
Usage:
|
96
|
+
|
97
|
+
tome get <pattern>
|
98
|
+
|
99
|
+
Examples:
|
100
|
+
|
101
|
+
tome get gmail
|
102
|
+
tome get foo@
|
103
|
+
tome get foo@gmail.com
|
104
|
+
|
105
|
+
Alias: get, g, show
|
106
|
+
END
|
107
|
+
|
108
|
+
$delete_usage = <<END
|
109
|
+
tome delete
|
110
|
+
|
111
|
+
Delete the password for an account.
|
112
|
+
|
113
|
+
Usage:
|
114
|
+
|
115
|
+
tome delete [user@]<domain>
|
116
|
+
|
117
|
+
Examples:
|
118
|
+
|
119
|
+
tome delete gmail.com
|
120
|
+
tome delete foo@gmail.com
|
121
|
+
|
122
|
+
Alias: delete, del, remove, rm
|
123
|
+
END
|
124
|
+
|
125
|
+
$generate_usage = <<END
|
126
|
+
tome generate
|
127
|
+
|
128
|
+
Generate a random password for an account. The user is optional.
|
129
|
+
|
130
|
+
Usage:
|
131
|
+
|
132
|
+
tome generate [user@]<domain>
|
133
|
+
|
134
|
+
Examples:
|
135
|
+
|
136
|
+
tome generate gmail.com
|
137
|
+
tome generate foo@gmail.com
|
138
|
+
|
139
|
+
Alias: generate, gen
|
140
|
+
END
|
141
|
+
|
142
|
+
$copy_usage = <<END
|
143
|
+
tome copy
|
144
|
+
|
145
|
+
Copy the password for the account matching the pattern.
|
146
|
+
If more than one account matches the pattern, nothing happens.
|
147
|
+
Matching is done with substring search. Wildcards are not supported.
|
148
|
+
|
149
|
+
Usage:
|
150
|
+
|
151
|
+
tome copy <pattern>
|
152
|
+
|
153
|
+
Examples:
|
154
|
+
|
155
|
+
tome copy gmail
|
156
|
+
tome copy foo@
|
157
|
+
tome copy foo@gmail.com
|
158
|
+
|
159
|
+
Alias: copy, cp
|
160
|
+
END
|
161
|
+
|
162
|
+
$list_usage = <<END
|
163
|
+
tome list
|
164
|
+
|
165
|
+
Show all stored accounts and passwords.
|
166
|
+
|
167
|
+
Usage:
|
168
|
+
|
169
|
+
tome list
|
170
|
+
|
171
|
+
Examples:
|
172
|
+
|
173
|
+
tome list
|
174
|
+
|
175
|
+
Alias: list, ls
|
176
|
+
END
|
177
|
+
|
178
|
+
$rename_usage = <<END
|
179
|
+
tome rename
|
180
|
+
|
181
|
+
Rename the account information stored.
|
182
|
+
|
183
|
+
Usage:
|
184
|
+
|
185
|
+
tome rename <old> <new>
|
186
|
+
|
187
|
+
Examples:
|
188
|
+
|
189
|
+
tome rename gmail.com foo@gmail.com
|
190
|
+
tome rename foo@gmail.com bar@gmail.com
|
191
|
+
|
192
|
+
Alias: rename, ren, rn
|
193
|
+
END
|
data/lib/tome/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
$version = '0.1.
|
1
|
+
$version = '0.1.1.pre'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tome
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1.pre
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -69,7 +69,9 @@ extra_rdoc_files: []
|
|
69
69
|
files:
|
70
70
|
- lib/tome/command.rb
|
71
71
|
- lib/tome/crypt.rb
|
72
|
+
- lib/tome/padding.rb
|
72
73
|
- lib/tome/tome.rb
|
74
|
+
- lib/tome/usage.rb
|
73
75
|
- lib/tome/version.rb
|
74
76
|
- lib/tome.rb
|
75
77
|
- bin/tome
|