pwkeep 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,6 +8,24 @@ module PWKeep
8
8
  def initialize
9
9
  @opts = { :home => ENV['PWKEEP_HOME'] || '~/.pwkeep' } # required value
10
10
  end
11
+
12
+ def keypair_load
13
+ counter = 0
14
+ while true
15
+ begin
16
+ pw = ask("Enter your password:") { |q| q.echo = false }
17
+ @storage.keypair_load pw
18
+ rescue OpenSSL::PKey::RSAError => e
19
+ say "<%= color('Invalid password', RED) %>"
20
+ counter = counter + 1
21
+ if (counter>2)
22
+ raise e
23
+ end
24
+ next
25
+ end
26
+ break
27
+ end
28
+ end
11
29
 
12
30
  def setup
13
31
  @opts = Trollop::options do
@@ -31,6 +49,7 @@ EOS
31
49
  opt :list, "List all known systems", :short => '-l'
32
50
  opt :help, "Show usage", :short => '-h'
33
51
  opt :home, "Home directory", :short => '-H', :type => :string, :default => ( ENV['PWKEEP_HOME'] || '~/.pwkeep' )
52
+ opt :migrate, "Migrate from old storage format(s)"
34
53
  opt :version, "Show version", :short => '-V'
35
54
  end
36
55
 
@@ -44,7 +63,7 @@ EOS
44
63
  Trollop::die :initialize, "can only have one mode of operation" if opts[:initialize] and (opts[:edit] or opts[:view] or opts[:delete] or opts[:create] or opts[:search] or opts[:list])
45
64
  Trollop::die :list, "can only have one mode of operation" if opts[:list] and (opts[:edit] or opts[:view] or opts[:delete] or opts[:create] or opts[:search] or opts[:initialize])
46
65
 
47
- Trollop::die "You must choose one mode of operation" unless opts[:create] or opts[:edit] or opts[:view] or opts[:delete] or opts[:search] or opts[:initialize] or opts[:list]
66
+ Trollop::die "You must choose one mode of operation" unless opts[:create] or opts[:edit] or opts[:view] or opts[:delete] or opts[:search] or opts[:initialize] or opts[:list] or opts[:migrate]
48
67
  end
49
68
 
50
69
  def self.run
@@ -92,8 +111,7 @@ EOS
92
111
  raise "Storage not initialized (run with --initialize)" unless @storage.valid?
93
112
 
94
113
  if opts[:view]
95
- pw = ask("Enter your password:") { |q| q.echo = false }
96
- @storage.keypair_load pw
114
+ keypair_load
97
115
 
98
116
  data = @storage.load_system opts[:system]
99
117
 
@@ -111,16 +129,14 @@ EOS
111
129
  raise PWKeep::Exception, "Not modified"
112
130
  end
113
131
 
114
- pw = ask("Enter your password:") { |q| q.echo = false }
115
- @storage.keypair_load pw
132
+ keypair_load
116
133
  @storage.save_system opts[:system], result[1]
117
134
  say("<%= color('Changes stored', GREEN)%>")
118
135
  return
119
136
  end
120
137
 
121
138
  if opts[:edit]
122
- pw = ask("Enter your password:") { |q| q.echo = false }
123
- @storage.keypair_load pw
139
+ keypair_load
124
140
  data = @storage.load_system opts[:system]
125
141
  result = PWKeep.run_editor(data[:data], {})
126
142
  unless result[0]
@@ -132,8 +148,7 @@ EOS
132
148
  end
133
149
 
134
150
  if opts[:delete]
135
- pw = ask("Enter your password:") { |q| q.echo = false }
136
- @storage.keypair_load pw
151
+ keypair_load
137
152
  data = @storage.load_system opts[:system]
138
153
  # just to be sure
139
154
  unless agree("Are you <%=color('SURE',BOLD)%> you want to delete #{data[:system]}?")
@@ -144,8 +159,7 @@ EOS
144
159
  end
145
160
 
146
161
  if opts[:search]
147
- pw = ask("Enter your password:") { |q| q.echo = false }
148
- @storage.keypair_load pw
162
+ keypair_load
149
163
  say("All matching systems\n")
150
164
  @storage.list_all_systems.sort.each do |system|
151
165
  if system.match opts[:search]
@@ -156,18 +170,27 @@ EOS
156
170
  end
157
171
 
158
172
  if opts[:list]
159
- pw = ask("Enter your password:") { |q| q.echo = false }
160
- @storage.keypair_load pw
173
+ keypair_load
161
174
  say("All known systems\n")
162
175
  @storage.list_all_systems.sort.each do |system|
163
176
  say(" - #{system}")
164
177
  end
165
178
  return
166
179
  end
180
+
181
+ if opts[:migrate]
182
+ keypair_load
183
+ say("Migrating systems...\n")
184
+ count = @storage.migrate
185
+ say("Migrated #{count} systems\n")
186
+ return
187
+ end
167
188
  rescue PWKeep::Exception => e1
168
189
  PWKeep::logger.error e1.message.colorize(:red)
169
190
  rescue OpenSSL::PKey::RSAError => e2
170
191
  PWKeep::logger.error "Cannot load private key".colorize(:red)
192
+ rescue SystemExit,Interrupt
193
+ # ignore
171
194
  end
172
195
  end
173
196
  end
@@ -50,23 +50,17 @@ class Storage
50
50
  @key = OpenSSL::PKey::RSA.new key_pem, password
51
51
  end
52
52
 
53
- def master_key_load
54
- unless @key
55
- raise PWKeep::Exception, "RSA private key required"
56
- end
57
-
58
- # load the key
59
- @master_key = @key.private_decrypt(path.join('master.key').open('rb') { |io| io.read },4)
60
- end
61
-
62
53
  def system_to_hash(system)
63
54
  d = Digest.const_get(@options[:digest].upcase).new
64
55
 
65
- system_h = system.downcase
56
+ # hash with public key to prevent dictionary attacks
57
+ system_h = system.downcase + @key.public_key.to_der
58
+
66
59
  (0..@options[:iterations]).each do
67
60
  system_h = d.update(system_h).digest
68
61
  d.reset
69
62
  end
63
+
70
64
  "system-#{Base64.urlsafe_encode64(system_h)}"
71
65
  end
72
66
 
@@ -167,11 +161,27 @@ class Storage
167
161
  def list_all_systems
168
162
  systems = []
169
163
  path.entries.each do |s|
170
- next unless s.fnmatch? "system-*"
171
- systems << JSON.load(decrypt_system(path.join(s)))["system"]
164
+ next unless s.fnmatch? "system-*"
165
+ systems << JSON.load(decrypt_system(path.join(s)))["system"]
172
166
  end
173
167
  systems
174
168
  end
169
+
170
+ def migrate
171
+ count = 0
172
+ path.entries.each do |s|
173
+ next unless s.fnmatch? "system-*"
174
+ # check whether name matches the system name
175
+ system = JSON.load(decrypt_system(path.join(s)))["system"]
176
+ system_h = system_to_hash system
177
+
178
+ if s.to_s != system_h
179
+ count = count + 1
180
+ File.rename path.join(s), path.join(system_h)
181
+ end
182
+ end
183
+ count
184
+ end
175
185
  end
176
186
 
177
187
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'pwkeep'
3
- s.version = '0.0.3'
3
+ s.version = '0.0.4'
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = [ 'Aki Tuomi']
6
6
  s.email = %w( aki.tuomi@g-works.fi )
@@ -17,6 +17,6 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency 'trollop'
18
18
  s.add_dependency 'lockfile'
19
19
  s.add_dependency 'hashr'
20
- s.add_dependency 'ruco'
21
20
  s.add_dependency 'keepass-password-generator'
21
+ s.add_dependency 'yard'
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwkeep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-09 00:00:00.000000000 Z
12
+ date: 2014-05-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: ruco
111
+ name: keepass-password-generator
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -124,7 +124,7 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: keepass-password-generator
127
+ name: yard
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
@@ -154,6 +154,28 @@ files:
154
154
  - README.md
155
155
  - Rakefile
156
156
  - bin/pwkeep
157
+ - doc/PWKeep.html
158
+ - doc/PWKeep/Config.html
159
+ - doc/PWKeep/Editor.html
160
+ - doc/PWKeep/EditorApplication.html
161
+ - doc/PWKeep/Exception.html
162
+ - doc/PWKeep/Main.html
163
+ - doc/PWKeep/StatusBar.html
164
+ - doc/PWKeep/Storage.html
165
+ - doc/_index.html
166
+ - doc/class_list.html
167
+ - doc/css/common.css
168
+ - doc/css/full_list.css
169
+ - doc/css/style.css
170
+ - doc/file.README.html
171
+ - doc/file_list.html
172
+ - doc/frames.html
173
+ - doc/index.html
174
+ - doc/js/app.js
175
+ - doc/js/full_list.js
176
+ - doc/js/jquery.js
177
+ - doc/method_list.html
178
+ - doc/top-level-namespace.html
157
179
  - lib/pwkeep.rb
158
180
  - lib/pwkeep/config.rb
159
181
  - lib/pwkeep/editor.rb