safe 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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