safe 0.3 → 0.4

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 CHANGED
@@ -58,6 +58,7 @@ Windows:
58
58
  0.1 -- May 12, 2007
59
59
  0.2 -- August 19, 2007
60
60
  0.3 -- September 7, 2007
61
+ 0.4 -- April 4, 2008
61
62
 
62
63
  See Release-Notes.txt for more information
63
64
 
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ gem_spec = Gem::Specification.new do |spec|
7
7
  spec.summary = 'A command-line password storage program'
8
8
  spec.description = %{safe safely stores all your user IDs and passwords,
9
9
  encrypted by a password of your choosing.}
10
- spec.version = '0.3'
10
+ spec.version = '0.4'
11
11
 
12
12
  # Author information
13
13
  spec.author = 'Rob Warner'
data/Release-Notes.txt CHANGED
@@ -1,8 +1,12 @@
1
1
  Safe Release Notes
2
2
  ------------------
3
+ 0.4 (April 4, 2008)
4
+ -------------------
5
+ [FIXED] Passwords stopped authenticating (change in REXML perhaps?--whitespace returned in salt and hash), so moved salt
6
+ and hash to attributes of root
3
7
 
4
8
  0.3 (September 7, 2007)
5
- ---------------------
9
+ -----------------------
6
10
  [NEW] Added support files to gem
7
11
  [NEW] Specified versions for highline and crypt
8
12
  [NEW] Changed executable from 'safe.rb' to 'safe'
data/lib/safefile.rb CHANGED
@@ -42,12 +42,13 @@ include REXML
42
42
  # The file containing the safe entries
43
43
  ##
44
44
  class SafeFile
45
- attr_accessor :hash, :salt, :password, :filename, :entries
45
+ attr_accessor :filename, :entries, :password
46
46
 
47
47
  def initialize(password, dir, filename = '.safe.xml')
48
- @entries = Hash.new
49
- @filename = "#{dir}/#{filename}"
50
- @password = password
48
+ raise "Password must not be blank" unless password
49
+ self.entries = Hash.new
50
+ self.filename = "#{dir}/#{filename}"
51
+ self.password = password
51
52
  load
52
53
  end
53
54
 
@@ -55,39 +56,30 @@ class SafeFile
55
56
  def load
56
57
  f = File.open(@filename, File::CREAT)
57
58
  begin
58
- if f.lstat.size == 0
59
- create_file(f)
60
- else
61
- decrypt_file(f)
62
- end
63
- rescue
64
- # TODO Determine whether error is can't create file, and print appropriate error
65
- puts $!
66
- ensure
67
- f.close unless f.nil?
59
+ f.lstat.size == 0 ? create_file(f) : decrypt_file(f)
60
+ rescue
61
+ # TODO Determine whether error is can't create file, and print appropriate error
62
+ raise $!
63
+ ensure
64
+ f.close unless f.nil?
68
65
  end
69
66
  end
70
67
 
71
68
  # Decrypts the file
72
69
  def decrypt_file(file)
73
70
  begin
74
- doc = Document.new file
75
- root = doc.root
76
- @hash = root.elements["hash"].text
77
- @salt = root.elements["salt"].text
71
+ root = Document.new(file).root
72
+ @salt = root.attributes["salt"]
73
+ @hash = root.attributes["hash"]
78
74
  if authorized?
79
- crypt_key = Crypt::Blowfish.new(@password)
75
+ crypt_key = Crypt::Blowfish.new(self.password)
80
76
  e_entries = root.elements["entries"]
81
77
  e_entries.elements.each("entry") do |entry|
82
78
  fields = crypt_key.decrypt_string(Base64::decode64(entry.cdatas[0].to_s)).split("\t")
83
- if fields.length == 3
84
- insert(fields[0], fields[1], fields[2])
85
- else
86
- puts "Cannot parse #{fields}, discarding."
87
- end
79
+ fields.length == 3 ? insert(fields[0], fields[1], fields[2]) : puts("Cannot parse #{fields}, discarding.")
88
80
  end
89
81
  else
90
- abort('The password you entered is not valid')
82
+ raise 'The password you entered is not valid'
91
83
  end
92
84
  rescue ParseException
93
85
  puts "Cannot parse #{file.path}"
@@ -97,20 +89,19 @@ class SafeFile
97
89
  # Creates a new file
98
90
  def create_file(file)
99
91
  puts 'Creating new file . . .'
100
- generate_hash_and_salt
92
+ generate_salt_and_hash
101
93
  save
102
94
  end
103
95
 
104
96
  # Saves the file
105
97
  def save
106
- crypt_key = Crypt::Blowfish.new(@password)
107
98
  doc = Document.new
108
99
  root = Element.new "safe"
100
+ root.attributes["salt"] = @salt
101
+ root.attributes["hash"] = @hash
109
102
  doc.add_element root
110
103
 
111
- root.add_element create_element("hash", @hash)
112
- root.add_element create_element("salt", @salt)
113
-
104
+ crypt_key = Crypt::Blowfish.new(self.password)
114
105
  e_entries = Element.new "entries"
115
106
  @entries.each_value do |entry|
116
107
  e = Element.new "entry"
@@ -120,7 +111,7 @@ class SafeFile
120
111
  root.add_element e_entries
121
112
 
122
113
  f = File.new(@filename, 'w')
123
- doc.write f, 0
114
+ doc.write f, 2
124
115
  f.close
125
116
  end
126
117
 
@@ -185,24 +176,24 @@ class SafeFile
185
176
  new_password = SafeUtils::get_password('Enter new password: ')
186
177
  rpt_password = SafeUtils::get_password('Confirm password: ')
187
178
  if new_password == rpt_password
188
- @password = new_password
189
- generate_hash_and_salt
179
+ self.password = new_password
180
+ generate_salt_and_hash
190
181
  save
191
182
  else
192
183
  puts 'Passwords do not match'
193
184
  end
194
185
  end
195
186
 
196
- def generate_hash_and_salt
187
+ def generate_salt_and_hash
197
188
  @salt = [Array.new(20){rand(256).chr}.join].pack('m').chomp
198
- @hash = Digest::SHA256.hexdigest(@password + @salt)
189
+ @hash = Digest::SHA256.hexdigest(self.password + @salt)
199
190
  end
200
191
 
201
192
  # Returns whether the password is authorized
202
193
  def authorized?
203
- Digest::SHA256.hexdigest(@password + @salt) == @hash
194
+ @hash == Digest::SHA256.hexdigest(self.password + @salt)
204
195
  end
205
-
196
+
206
197
  # Helper method to create an XML element with a name and text
207
198
  def create_element(name, text)
208
199
  e = Element.new name
data/test/tc_safefile.rb CHANGED
@@ -42,6 +42,18 @@ class SafeFileTest < Test::Unit::TestCase
42
42
  FileUtils::rm("./.safe.xml")
43
43
  end
44
44
 
45
+ def test_add
46
+ f = SafeFile.new("password", ".")
47
+ f.insert('apple', 'baker', 'charlie')
48
+ f.save
49
+ assert_equal 1, f.count
50
+
51
+ f1 = SafeFile.new("password", ".")
52
+ assert_equal 1, f1.count
53
+
54
+ FileUtils::rm("./.safe.xml")
55
+ end
56
+
45
57
  def test_entry
46
58
  f = SafeFile.new("password", ".")
47
59
  f.insert('apple', 'baker', 'charlie')
metadata CHANGED
@@ -1,60 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: safe
5
3
  version: !ruby/object:Gem::Version
6
- version: "0.3"
7
- date: 2007-09-07 00:00:00 -04:00
8
- summary: A command-line password storage program
9
- require_paths:
10
- - lib
11
- email: rwarner@grailbox.com
12
- homepage: http://safe.rubyforge.org/
13
- rubyforge_project: safe
14
- description: safe safely stores all your user IDs and passwords, encrypted by a password of your choosing.
15
- autorequire:
16
- default_executable: safe
17
- bindir: bin
18
- has_rdoc: false
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: "0.4"
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Rob Warner
31
- files:
32
- - README
33
- - lib/safeentry.rb
34
- - lib/safefile.rb
35
- - lib/safeutils.rb
36
- - index.html
37
- - Rakefile
38
- - Release-Notes.txt
39
- test_files:
40
- - test/tc_safefile.rb
41
- - test/tc_safeentry.rb
42
- - test/tc_safeutils.rb
43
- rdoc_options: []
44
-
45
- extra_rdoc_files: []
46
-
47
- executables:
48
- - safe
49
- extensions: []
50
-
51
- requirements: []
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
52
11
 
12
+ date: 2008-04-04 00:00:00 -04:00
13
+ default_executable: safe
53
14
  dependencies:
54
15
  - !ruby/object:Gem::Dependency
55
16
  name: crypt
56
17
  version_requirement:
57
- version_requirements: !ruby/object:Gem::Version::Requirement
18
+ version_requirements: !ruby/object:Gem::Requirement
58
19
  requirements:
59
20
  - - ">="
60
21
  - !ruby/object:Gem::Version
@@ -63,9 +24,55 @@ dependencies:
63
24
  - !ruby/object:Gem::Dependency
64
25
  name: highline
65
26
  version_requirement:
66
- version_requirements: !ruby/object:Gem::Version::Requirement
27
+ version_requirements: !ruby/object:Gem::Requirement
67
28
  requirements:
68
29
  - - ">="
69
30
  - !ruby/object:Gem::Version
70
31
  version: 1.4.0
71
32
  version:
33
+ description: safe safely stores all your user IDs and passwords, encrypted by a password of your choosing.
34
+ email: rwarner@grailbox.com
35
+ executables:
36
+ - safe
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - README
43
+ - lib/safeentry.rb
44
+ - lib/safefile.rb
45
+ - lib/safeutils.rb
46
+ - index.html
47
+ - Rakefile
48
+ - Release-Notes.txt
49
+ has_rdoc: false
50
+ homepage: http://safe.rubyforge.org/
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: safe
71
+ rubygems_version: 1.0.1
72
+ signing_key:
73
+ specification_version: 2
74
+ summary: A command-line password storage program
75
+ test_files:
76
+ - test/tc_safeentry.rb
77
+ - test/tc_safefile.rb
78
+ - test/tc_safeutils.rb