shh 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2009 Mark Ryall
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2009 Mark Ryall
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -1,113 +1,110 @@
1
- = SHH
2
-
3
- Secret Squirrel
4
-
5
- This is a command line utility for managing secure information such as accounts, passwords as individual files so that they can be easily managed in a version control repository.
6
-
7
- You won't be hiding anything from the NSA with this level of encryption so it isn't recommended that you make your repository publicly accessible.
8
-
9
- Now with more tab completion and multi line editing!
10
-
11
- = Usage
12
-
13
- Here you sit expectantly in front of a computer at the command line.
14
-
15
- == Install
16
-
17
- gem install shh
18
-
19
- (you may need to install gemcutter first)
20
-
21
- == Launch
22
-
23
- Open all 'secrets' stored in ~/.secret
24
-
25
- > shh
26
-
27
- Opens all 'secrets' stored in foo/.secret
28
-
29
- > shh foo
30
-
31
- == Authenticate
32
-
33
- Enter your passphrase
34
-
35
- This passphrase will be used to encrypt and decrypt all of your secrets so don't make it too obvious.
36
-
37
- == Listing mode
38
-
39
- This mode allows you to view and edit 'entries' (which are encrypted hashes stored in files)
40
-
41
- > list
42
-
43
- bitbucket (260f34de-6779-4367-af2a-44184dec1cc1)
44
- amazon (291a3e6c-2c7b-4960-a146-1f6635d9a74e)
45
- yahoo (2fe408e7-7f2b-4dc0-854a-c92c21f131ae)
46
- evernote (41ad0a21-eafc-4f70-9b0d-0251be207b9e)
47
- gmail (8b35c1f2-851d-40fc-bd12-c2aad12c370a)
48
- rememberthemilk (a499f612-d034-4e49-82a8-6967d29653a1)
49
-
50
- * list - list entries
51
- * edit <name> - edit or create entry
52
- * view <name> - view entry
53
- * quit
54
-
55
- == Viewing mode
56
-
57
- This mode allows you to view (but not edit) an existing entry
58
-
59
- > view bitbucket
60
- (bitbucket) > list
61
- id,name,password,username
62
- (bitbucket) > view username
63
- markryall
64
-
65
- list keys, show key, copy key or quit? c password
66
-
67
- * list - show entry keys
68
- * view <key> - view entry value on screen
69
- * copy <key> - copy entry value to clipboard
70
- * launch <key> - launch entry value in default browser (available if it starts with http)
71
- * run <key> - execute ruby script (available if it starts with #!/usr/bin/env ruby)
72
- * quit
73
-
74
- == Editing mode
75
-
76
- This mode is viewing mode plus some editing commands
77
-
78
- > edit bitbucket
79
- (bitbucket) > set foo
80
- Enter new value for foo
81
- bar
82
- (bitbucket) > delete foo
83
-
84
- * edit <key> - edit or create key using text editor (notepad or EDITOR)
85
- * set <key> - edit or create key from prompt
86
- * delete <key> - remove a key
87
-
88
- == Quitting mode
89
-
90
- You don't want to be a quitter
91
-
92
- == Scripting
93
-
94
- In a script the following objects are available:
95
-
96
- * splat.clipboard = <text> - allows content to be copied to the clipboard
97
- * splat.browser - a watir compatible browser
98
- * hash - the current selected entry
99
-
100
- Example:
101
-
102
- browser = splat.browser
103
- browser.goto 'http://www.github.com/login'
104
- browser.text_field(:id, 'login_field').set hash['username']
105
- browser.text_field(:id, 'password').set hash['password']
106
- browser.button(:name, 'commit').click
107
-
108
- = Future plans for world domination
109
-
110
- * Add some color
111
- * Add help
112
- * add some source control (hg/git) commands
113
- * add commands for displaying history of entries
1
+ = SHH
2
+
3
+ Secret Squirrel
4
+
5
+ This is a command line utility for managing secure information such as accounts, passwords as individual files so that they can be easily managed in a version control repository.
6
+
7
+ You won't be hiding anything from the NSA with this level of encryption so it isn't recommended that you make your repository publicly accessible.
8
+
9
+ Now with more tab completion and multi line editing!
10
+
11
+ = Usage
12
+
13
+ Here you sit expectantly in front of a computer at the command line.
14
+
15
+ == Install
16
+
17
+ gem install shh
18
+
19
+ == Launch
20
+
21
+ Open all 'secrets' stored in ~/.secret
22
+
23
+ > shh
24
+
25
+ Opens all 'secrets' stored in foo/.secret
26
+
27
+ > shh foo
28
+
29
+ == Authenticate
30
+
31
+ Enter your passphrase
32
+
33
+ This passphrase will be used to encrypt and decrypt all of your secrets so don't make it too obvious.
34
+
35
+ == Listing mode
36
+
37
+ This mode allows you to view and edit 'entries' (which are encrypted hashes stored in files)
38
+
39
+ > list
40
+
41
+ bitbucket (260f34de-6779-4367-af2a-44184dec1cc1)
42
+ amazon (291a3e6c-2c7b-4960-a146-1f6635d9a74e)
43
+ yahoo (2fe408e7-7f2b-4dc0-854a-c92c21f131ae)
44
+ evernote (41ad0a21-eafc-4f70-9b0d-0251be207b9e)
45
+ gmail (8b35c1f2-851d-40fc-bd12-c2aad12c370a)
46
+ rememberthemilk (a499f612-d034-4e49-82a8-6967d29653a1)
47
+
48
+ * list - list entries
49
+ * edit <name> - edit or create entry
50
+ * view <name> - view entry
51
+ * quit
52
+
53
+ == Viewing mode
54
+
55
+ This mode allows you to view (but not edit) an existing entry
56
+
57
+ > view bitbucket
58
+ (bitbucket) > list
59
+ id,name,password,username
60
+ (bitbucket) > view username
61
+ markryall
62
+
63
+ list keys, show key, copy key or quit? c password
64
+
65
+ * list - show entry keys
66
+ * view <key> - view entry value on screen
67
+ * copy <key> - copy entry value to clipboard
68
+ * launch <key> - launch entry value in default browser (available if it starts with http)
69
+ * run <key> - execute ruby script (available if it starts with #!/usr/bin/env ruby)
70
+ * quit
71
+
72
+ == Editing mode
73
+
74
+ This mode is viewing mode plus some editing commands
75
+
76
+ > edit bitbucket
77
+ (bitbucket) > set foo
78
+ Enter new value for foo
79
+ bar
80
+ (bitbucket) > delete foo
81
+
82
+ * edit <key> - edit or create key using text editor (notepad or EDITOR)
83
+ * set <key> - edit or create key from prompt
84
+ * delete <key> - remove a key
85
+
86
+ == Quitting mode
87
+
88
+ You don't want to be a quitter
89
+
90
+ == Scripting
91
+
92
+ In a script the following objects are available:
93
+
94
+ * splat.clipboard = <text> - allows content to be copied to the clipboard
95
+ * splat.browser - a watir compatible browser
96
+ * hash - the current selected entry
97
+
98
+ Example:
99
+
100
+ browser = 'http://www.github.com/login'.to_browser
101
+ browser.text_field(:id, 'login_field').set hash['username']
102
+ browser.text_field(:id, 'password').set hash['password']
103
+ browser.button(:name, 'commit').click
104
+
105
+ = Future plans for world domination
106
+
107
+ * Add some color
108
+ * Add help
109
+ * add some source control (hg/git) commands
110
+ * add commands for displaying history of entries
data/bin/shh CHANGED
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift File.dirname(__FILE__)+'/../lib'
4
- require 'shh/cli'
5
- Shh::Cli.execute(*ARGV)
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__)+'/../lib'
4
+ require 'shh/cli'
5
+ Shh::Cli.execute(*ARGV)
data/lib/shh/cli.rb CHANGED
@@ -1,16 +1,16 @@
1
- require 'rubygems'
2
- require 'shh/repository'
3
- require 'shh/prompt'
4
- require 'shh/entries_menu'
5
-
6
- module Shh
7
- class Cli
8
- def self.execute *args
9
- prompt = Prompt.new
10
- passphrase = prompt.get('Enter your passphrase', :silent => true)
11
- path = args.shift || ('~')
12
-
13
- EntriesMenu.new(prompt, Repository.new(passphrase, path)).main_loop
14
- end
15
- end
16
- end
1
+ require 'rubygems'
2
+ require 'shh/repository'
3
+ require 'shh/prompt'
4
+ require 'shh/entries_menu'
5
+
6
+ module Shh
7
+ class Cli
8
+ def self.execute *args
9
+ prompt = Prompt.new
10
+ passphrase = prompt.ask('Enter your passphrase', :silent => true)
11
+ path = args.shift || ('~')
12
+
13
+ EntriesMenu.new(prompt, Repository.new(passphrase, path)).push
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'shh/commands'
2
+ require 'shh/command/key_command'
3
+ require 'splat'
4
+
5
+ class Shh::Command::CopyKey
6
+ include Shh::Command::KeyCommand
7
+
8
+ def help
9
+ "Copies the value associated with the specified key to the clipboard"
10
+ end
11
+
12
+ def execute key=nil
13
+ (@entry[key] || '').to_clipboard
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'shh/command/key_command'
2
+ require 'splat'
3
+
4
+ class Shh::Command::EditKey
5
+ include Shh::Command::KeyCommand
6
+
7
+ def help
8
+ "Launches an external editor (specified by EDITOR environment variable) to edit the value associated with the specified key"
9
+ end
10
+
11
+ def execute key=nil
12
+ new_value = (@entry[key] || '').to_editor
13
+ @entry[key] = new_value if new_value.length > 0
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'shh/command/key_command'
2
+
3
+ class Shh::Command::ExecuteKey
4
+ include Shh::Command::KeyCommand
5
+
6
+ def help
7
+ "Executes the contents (ruby code) associated with the specified key\nNote that the entire entry is available as a hash called 'entry'"
8
+ end
9
+
10
+ def execute key=nil
11
+ begin
12
+ entry = @entry
13
+ eval @entry[key]
14
+ rescue Exception => e
15
+ @io.say e.message
16
+ e.backtrace.each {|t| @io.say " > #{t}" }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Shh::Command::KeyCommand
2
+ def initialize entry, io
3
+ @entry, @io = entry, io
4
+ end
5
+
6
+ def usage
7
+ "<key name>"
8
+ end
9
+
10
+ def completion text
11
+ @entry.keys.grep(/^#{text}/).sort || []
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'shh/command/key_command'
2
+ require 'splat'
3
+
4
+ class Shh::Command::LaunchKey
5
+ include Shh::Command::KeyCommand
6
+
7
+ def help
8
+ "Launches the value (usually a url) associated with the specified key using default application"
9
+ end
10
+
11
+ def execute key=nil
12
+ (@entry[key] || '').to_launcher
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ class Shh::Command::ListEntries
2
+ attr_reader :usage, :help
3
+
4
+ def initialize repository, io
5
+ @repository, @io = repository, io
6
+ @usage = "(<substring>)"
7
+ @help = "Lists all entries or those with a name including the specified substring"
8
+ end
9
+
10
+ def execute text=nil
11
+ @repository.each do |entry|
12
+ next if text and !(entry['name'] =~ /#{text}/)
13
+ @io.say "#{entry['name']} (#{entry['id']})"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ class Shh::Command::ListKeys
2
+ attr_reader :usage, :help
3
+
4
+ def initialize entry, io
5
+ @entry, @io = entry, io
6
+ @usage = "(<substring>)"
7
+ @help = "Lists all keys for the entry or those including the specified substring"
8
+ end
9
+
10
+ def execute text=nil
11
+ @entry.each_key do |key|
12
+ next if text and !(key =~ /#{text}/)
13
+ @io.say key
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'uuidtools'
2
+ require 'shh/entry_menu'
3
+
4
+ class Shh::Command::OpenEntry
5
+ attr_reader :usage, :help
6
+
7
+ def initialize repository, io
8
+ @repository, @io = repository, io
9
+ @usage = "<entry name>"
10
+ @help = "Enters a subshell for editing the specifed entry"
11
+ end
12
+
13
+ def completion text
14
+ @repository.map{|entry| entry['name']}.grep(/^#{text}/).sort || []
15
+ end
16
+
17
+ def execute name=nil
18
+ entry = @repository.find_by_name(name)
19
+ entry ||= {'name' => name, 'id' => UUIDTools::UUID.random_create.to_s}
20
+ Shh::EntryMenu.new(@io, entry).push
21
+ @repository.persist entry
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require 'shh/command/key_command'
2
+
3
+ class Shh::Command::RemoveKey
4
+ include Shh::Command::KeyCommand
5
+
6
+ def help
7
+ "Removes the specified key from the entry"
8
+ end
9
+
10
+ def execute key=nil
11
+ @entry.delete(key)
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'shh/command/key_command'
2
+
3
+ class Shh::Command::SetKey
4
+ include Shh::Command::KeyCommand
5
+
6
+ def help
7
+ "Prompts for a new value for the specified key\nKeys with a name including 'pass' (eg. password, passphrase) will not echo input"
8
+ end
9
+
10
+ def execute key=nil
11
+ new_value = @io.ask("Enter new value for #{key}", :silent => (key =~ /pass/))
12
+ @entry[key] = new_value if new_value.length > 0
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'shh/command/key_command'
2
+
3
+ class Shh::Command::ShowKey
4
+ include Shh::Command::KeyCommand
5
+
6
+ def help
7
+ "Displays the value associated with the specified key"
8
+ end
9
+
10
+ def execute key=nil
11
+ @io.say @entry[key]
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ require 'active_support/inflector'
2
+
3
+ module Shh
4
+ module Command
5
+ def load_command name, *args
6
+ require "shh/command/#{name}"
7
+ Command.const_get(name.to_s.camelize).new(*args)
8
+ end
9
+ end
10
+ end
data/lib/shh/crypt.rb CHANGED
@@ -1,25 +1,25 @@
1
- require 'crypt/blowfish'
2
-
3
- module Shh
4
- class Crypt
5
- def initialize passphrase
6
- @blowfish = ::Crypt::Blowfish.new(passphrase)
7
- end
8
-
9
- def encrypt text, out_io
10
- in_io = StringIO.new(text)
11
- while l = in_io.read(8) do
12
- while l.size < 8 do l += "\0" end
13
- out_io.print @blowfish.encrypt_block(l)
14
- end
15
- end
16
-
17
- def decrypt in_io
18
- out_io = StringIO.new
19
- while l = in_io.read(8) do
20
- out_io.print @blowfish.decrypt_block(l)
21
- end
22
- out_io.string.gsub("\0",'')
23
- end
24
- end
25
- end
1
+ require 'crypt/blowfish'
2
+
3
+ module Shh
4
+ class Crypt
5
+ def initialize passphrase
6
+ @blowfish = ::Crypt::Blowfish.new(passphrase)
7
+ end
8
+
9
+ def encrypt text, out_io
10
+ in_io = StringIO.new(text)
11
+ while l = in_io.read(8) do
12
+ while l.size < 8 do l += "\0" end
13
+ out_io.print @blowfish.encrypt_block(l)
14
+ end
15
+ end
16
+
17
+ def decrypt in_io
18
+ out_io = StringIO.new
19
+ while l = in_io.read(8) do
20
+ out_io.print @blowfish.decrypt_block(l)
21
+ end
22
+ out_io.string.gsub("\0",'')
23
+ end
24
+ end
25
+ end
@@ -1,64 +1,16 @@
1
- require 'uuidtools'
2
- require 'readline'
3
- require 'shh/entry_menu'
4
-
5
- module Shh
6
- class EntriesMenu
7
- def initialize prompt, repository
8
- @prompt, @repository = prompt, repository
9
- refresh
10
- end
11
-
12
- def main_loop
13
- prompt_text = 'shh > '
14
-
15
- begin
16
- while line = Readline.readline(prompt_text, true)
17
- line.strip!
18
- case line
19
- when 'quit'
20
- return
21
- when 'refresh'
22
- refresh
23
- when 'list'
24
- @entries.sort.each {|entry| say entry }
25
- when /^view (.*)/
26
- view $1
27
- when /^edit (.*)/
28
- edit $1
29
- end
30
- puts
31
- end
32
- rescue Interrupt => e
33
- exit
34
- end
35
- puts
36
- end
37
-
38
- def refresh
39
- commands = ['list', 'refresh', 'quit']
40
- @entries = []
41
- @repository.each_entry do |entry|
42
- @entries << "#{entry['name']} (#{entry['id']})"
43
- commands << "edit #{entry['name']}"
44
- commands << "view #{entry['name']}"
45
- end
46
- Readline.completion_proc = lambda do |text|
47
- commands.grep( /^#{Regexp.escape(text)}/ ).sort
48
- end
49
- Readline.completer_word_break_characters = ''
50
- end
51
-
52
- def edit name
53
- entry = @repository.find_entry(name)
54
- entry ||= {'name' => name, 'id' => UUIDTools::UUID.random_create.to_s}
55
- @repository.persist_entry EntryMenu.new(@prompt, entry).main_loop
56
- refresh
57
- end
58
-
59
- def view name
60
- EntryMenu.new(@prompt, @repository.find_entry(name), true).main_loop
61
- refresh
62
- end
63
- end
64
- end
1
+ require 'shell_shock/context'
2
+ require 'shh/commands'
3
+
4
+ class Shh::EntriesMenu
5
+ include Shh::Command
6
+ include ShellShock::Context
7
+
8
+ def initialize io, repository
9
+ @io, @repository = io, repository
10
+ @prompt_text = 'shh > '
11
+ @commands = {
12
+ 'ls' => load_command(:list_entries, @repository, @io),
13
+ 'cd' => load_command(:open_entry, @repository, @io)
14
+ }
15
+ end
16
+ end
@@ -1,141 +1,25 @@
1
- require 'splat'
2
-
3
- module Shh
4
- class EntryMenu
5
- def initialize prompt, hash, read_only=false
6
- @prompt, @hash, @read_only = prompt, hash, read_only
7
- @splat = Splat.new
8
- refresh
9
- end
10
-
11
- def main_loop
12
- prompt_text = "shh:#{@hash['name']} > "
13
-
14
- begin
15
- while line = Readline.readline(prompt_text, true)
16
- line.strip!
17
- case line
18
- when 'quit'
19
- return @hash
20
- when 'list'
21
- say(@hash.keys.sort.join(','))
22
- when /^set (.*)/
23
- set $1
24
- when /^edit (.*)/
25
- edit $1
26
- when /^copy (.*)/
27
- copy $1
28
- when /^launch (.*)/
29
- launch $1
30
- when /^delete (.*)/
31
- delete $1
32
- when /^view (.*)/
33
- view $1
34
- when /^run (.*)/
35
- run $1
36
- else
37
- puts "I can't imagine what you mean by that"
38
- end
39
- end
40
- rescue Interrupt => e
41
- exit
42
- end
43
-
44
- puts
45
- @hash
46
- end
47
-
48
- private
49
- def can_edit?
50
- !@read_only
51
- end
52
-
53
- def can_launch? key
54
- @splat.supported? and @hash[key] =~ /^http/
55
- end
56
-
57
- def can_run? key
58
- @splat.supported? and @hash[key] =~ /^#!\/usr\/bin\/env ruby/
59
- end
60
-
61
- def view key
62
- say(@hash[key]) if @hash[key]
63
- end
64
-
65
- def copy key
66
- @splat.clipboard = @hash[key]
67
- end
68
-
69
- def run key
70
- begin
71
- hash = @hash
72
- splat = @splat
73
- eval @hash[key]
74
- rescue Exception => e
75
- puts e.message
76
- e.backtrace.each {|t| puts " > #{t}" }
77
- end
78
- end
79
-
80
- def set key
81
- if can_edit?
82
- set_value key
83
- refresh
84
- end
85
- end
86
-
87
- def edit key
88
- if can_edit?
89
- edit_value key
90
- refresh
91
- end
92
- end
93
-
94
- def delete key
95
- if can_edit?
96
- @hash.delete(key)
97
- refresh
98
- end
99
- end
100
-
101
- def launch key
102
- @splat.launch @hash[key] if can_launch?(key)
103
- end
104
-
105
- def refresh
106
- commands = ['list', 'quit']
107
- @hash.keys.each do |key|
108
- commands << "edit #{key}" if can_edit?
109
- commands << "set #{key}" if can_edit?
110
- commands << "delete #{key}" if can_edit?
111
- commands << "view #{key}"
112
- commands << "copy #{key}" if @splat.supported?
113
- commands << "launch #{key}" if can_launch?(key)
114
- commands << "run #{key}" if can_run?(key)
115
- end
116
- Readline.completion_proc = lambda do |text|
117
- commands.grep( /^#{Regexp.escape(text)}/ ).sort
118
- end
119
- Readline.completer_word_break_characters = ''
120
- end
121
-
122
- def set_value key
123
- new_value = @prompt.get("Enter new value for #{key}", :silent => (key =~ /pass/))
124
- @hash[key] = new_value if new_value.length > 0
125
- end
126
-
127
- def edit_value key
128
- tmp_file = Pathname.new("key.tmp")
129
- begin
130
- tmp_file.open('w') { |out| out.print @hash[key] }
131
- editor = ENV["EDITOR"] || "notepad"
132
- system("#{editor} key.tmp")
133
- return unless $?.to_i == 0
134
- new_value = tmp_file.read
135
- @hash[key] = new_value if new_value.length > 0
136
- ensure
137
- tmp_file.unlink
138
- end
139
- end
140
- end
141
- end
1
+ require 'shell_shock/context'
2
+ require 'shh/commands'
3
+
4
+ class Shh::EntryMenu
5
+ include Shh::Command
6
+ include ShellShock::Context
7
+
8
+ def initialize io, entry
9
+ @io, @entry = io, entry
10
+ @commands = {
11
+ 'ls' => load_command(:list_keys, entry, io),
12
+ 'set' => load_command(:set_key, entry, io),
13
+ 'edit' => load_command(:edit_key, entry, io),
14
+ 'cat' => load_command(:show_key, entry, io),
15
+ 'cp' => load_command(:copy_key, entry, io),
16
+ 'launch' => load_command(:launch_key, entry, io),
17
+ 'rm' => load_command(:remove_key, entry, io),
18
+ 'exec' => load_command(:execute_key, entry, io)
19
+ }
20
+ end
21
+
22
+ def refresh_commands
23
+ @prompt_text = "shh:#{@entry['name']} > "
24
+ end
25
+ end
data/lib/shh/prompt.rb CHANGED
@@ -1,11 +1,14 @@
1
- require 'highline/import'
2
-
3
- module Shh
4
- class Prompt
5
- def get text, params={}
6
- return params[:value] if params[:value] and params[:value].size > 0
7
- echo = params[:silent] ? false : true
8
- ask(text) { |q| q.echo = echo }
9
- end
10
- end
11
- end
1
+ require 'highline/import'
2
+
3
+ module Shh
4
+ class Prompt
5
+ def ask text, params={}
6
+ echo = params[:silent] ? false : true
7
+ Kernel.ask(text) { |q| q.echo = echo }
8
+ end
9
+
10
+ def say text=''
11
+ puts text
12
+ end
13
+ end
14
+ end
@@ -1,39 +1,44 @@
1
- require 'yaml'
2
- require 'shh/crypt'
3
- require 'fileutils'
4
-
5
- module Shh
6
- class Repository
7
- attr_reader :folder
8
-
9
- def initialize passphrase, path
10
- @folder = Pathname.new(File.expand_path(path)) + '.secret'
11
- FileUtils.mkdir_p @folder.to_s
12
- @crypt = Crypt.new(passphrase)
13
- end
14
-
15
- def each_entry
16
- @folder.children.each do |child|
17
- entry = load_entry(child)
18
- yield entry if entry
19
- end
20
- end
21
-
22
- def find_entry name
23
- each_entry {|e| return e if e['name'] == name}
24
- nil
25
- end
26
-
27
- def load_entry path
28
- return nil if path.directory?
29
- yaml = path.open('rb') {|io| @crypt.decrypt(io) }
30
- entry = YAML::load(yaml)
31
- return nil unless entry
32
- path.basename.to_s == entry['id'] ? entry : nil
33
- end
34
-
35
- def persist_entry entry
36
- (@folder + entry['id']).open('wb') {|io| @crypt.encrypt(entry.to_yaml, io) }
37
- end
38
- end
39
- end
1
+ require 'yaml'
2
+ require 'shh/crypt'
3
+ require 'fileutils'
4
+
5
+ module Shh
6
+ class Repository
7
+ include Enumerable
8
+
9
+ attr_reader :folder
10
+
11
+ def initialize passphrase, path
12
+ @folder = Pathname.new(File.expand_path(path)) + '.secret'
13
+ @folder.mkpath
14
+ @crypt = Crypt.new(passphrase)
15
+ end
16
+
17
+ def each
18
+ @folder.children.each do |child|
19
+ entry = load(child)
20
+ yield entry if entry
21
+ end
22
+ end
23
+
24
+ def find_by_name name
25
+ each {|e| return e if e['name'] == name}
26
+ nil
27
+ end
28
+
29
+ def load path
30
+ return nil if path.directory?
31
+ yaml = path.open('rb') {|io| @crypt.decrypt(io) }
32
+ entry = YAML::load(yaml)
33
+ unless entry and path.basename.to_s == entry['id']
34
+ $stderr.puts "failed to deserialise #{path}"
35
+ return nil
36
+ end
37
+ entry
38
+ end
39
+
40
+ def persist entry
41
+ (@folder + entry['id']).open('wb') {|io| @crypt.encrypt(entry.to_yaml, io) }
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 6
9
- version: 0.1.6
8
+ - 7
9
+ version: 0.1.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Mark Ryall
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-07 00:00:00 +10:00
17
+ date: 2010-06-15 00:00:00 +10:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,8 +27,8 @@ dependencies:
27
27
  segments:
28
28
  - 1
29
29
  - 5
30
- - 1
31
- version: 1.5.1
30
+ - 2
31
+ version: 1.5.2
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
@@ -68,11 +68,67 @@ dependencies:
68
68
  - !ruby/object:Gem::Version
69
69
  segments:
70
70
  - 0
71
+ - 1
71
72
  - 0
72
- - 2
73
- version: 0.0.2
73
+ version: 0.1.0
74
74
  type: :runtime
75
75
  version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: shell_shock
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ - 0
86
+ - 3
87
+ version: 0.0.3
88
+ type: :runtime
89
+ version_requirements: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ name: rake
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ - 8
100
+ - 7
101
+ version: 0.8.7
102
+ type: :development
103
+ version_requirements: *id006
104
+ - !ruby/object:Gem::Dependency
105
+ name: gemesis
106
+ prerelease: false
107
+ requirement: &id007 !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ segments:
112
+ - 0
113
+ - 0
114
+ - 3
115
+ version: 0.0.3
116
+ type: :development
117
+ version_requirements: *id007
118
+ - !ruby/object:Gem::Dependency
119
+ name: orangutan
120
+ prerelease: false
121
+ requirement: &id008 !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ - 0
128
+ - 7
129
+ version: 0.0.7
130
+ type: :development
131
+ version_requirements: *id008
76
132
  description: |
77
133
  A command line utility that manages accounts and passwords as individual encypted files
78
134
 
@@ -85,6 +141,18 @@ extra_rdoc_files: []
85
141
 
86
142
  files:
87
143
  - lib/shh/cli.rb
144
+ - lib/shh/command/copy_key.rb
145
+ - lib/shh/command/edit_key.rb
146
+ - lib/shh/command/execute_key.rb
147
+ - lib/shh/command/key_command.rb
148
+ - lib/shh/command/launch_key.rb
149
+ - lib/shh/command/list_entries.rb
150
+ - lib/shh/command/list_keys.rb
151
+ - lib/shh/command/open_entry.rb
152
+ - lib/shh/command/remove_key.rb
153
+ - lib/shh/command/set_key.rb
154
+ - lib/shh/command/show_key.rb
155
+ - lib/shh/commands.rb
88
156
  - lib/shh/crypt.rb
89
157
  - lib/shh/entries_menu.rb
90
158
  - lib/shh/entry_menu.rb