rubeepass 1.1.2 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 555d0b9b3fed60c5950e2fa38fbd5bfdeb2dc77d
4
- data.tar.gz: 326c1d9ff76b5c0d4bcf6f7f2db37046b21c7d47
3
+ metadata.gz: a497c0ba1c2d89f4be0f1c386c3cba1b692d1452
4
+ data.tar.gz: ff4a9f75e497c6d7c1c06d21fffe40680798d929
5
5
  SHA512:
6
- metadata.gz: 197daacca2a88066501904fb04fd44abc111bfc890a2b9c65a6a0183ee02924dd509d2af388110f59b96c90553fe22916713ca1ab2f96778c77c3003591d88a6
7
- data.tar.gz: 758b32334cc0a1941b876e824ac0dfd9b44480a6224cc5e9e943c5e111a9f538236f6787f1624860826544e283d42902c6d6c75cc8aef97ad57dcdc9e774646e
6
+ metadata.gz: d2141b8e46f3f30be2b0bd08f5159ee71692f1aee5ca923dbf48ffe27a534f7598d47b3e2b28466346bb7a09fa90a39472edee09f207eba583a6981397d0aa48
7
+ data.tar.gz: 1a702fca0863fc0787d6b3034ff71c1b32a00d8f01d0539dc217466b76072915c7c333c37d57e3705c60432c45930dd78646e34e0f64a5dce403a017db64923f
data/bin/rpass CHANGED
@@ -32,13 +32,11 @@ class RubeePassConfig < JSONConfig
32
32
  return kdbx
33
33
  end
34
34
 
35
- def last_keyfile(keyfile = nil)
36
- if (keyfile)
37
- set("last_keyfile", Pathname.new(keyfile).expand_path)
38
- end
39
- keyfile = get("last_keyfile").to_s
40
- return nil if (keyfile.nil? || keyfile.empty?)
41
- return keyfile
35
+ def last_keyfile(kf = nil)
36
+ set("last_keyfile", Pathname.new(kf).expand_path) if (kf)
37
+ kf = get("last_keyfile").to_s
38
+ return nil if (kf.nil? || kf.empty?)
39
+ return kf
42
40
  end
43
41
 
44
42
  def timeout(t = nil)
@@ -0,0 +1,34 @@
1
+ require "base64"
2
+ require "rexml/document"
3
+ require "zlib"
4
+
5
+ class RubeePass::AttachmentDecoder
6
+ def get_attachment(ref)
7
+ @binaries.elements.each("Binary") do |elem|
8
+ if (elem.attributes["ID"] == ref)
9
+ if (elem.attributes["Compressed"].nil?)
10
+ begin
11
+ return Base64.decode64(elem.text)
12
+ rescue
13
+ return elem.text
14
+ end
15
+ end
16
+ return parse_gzip(elem.text)
17
+ end
18
+ end
19
+ end
20
+
21
+ def initialize(binaries)
22
+ @binaries = binaries
23
+ end
24
+
25
+ def parse_gzip(attachment)
26
+ begin
27
+ attachment = Base64.decode64(attachment)
28
+ rescue
29
+ # Do nothing
30
+ end
31
+ return Zlib::GzipReader.new(StringIO.new(attachment)).read
32
+ end
33
+ private :parse_gzip
34
+ end
@@ -24,10 +24,28 @@ class RubeePass::Entry
24
24
 
25
25
  def additional_attributes
26
26
  return attributes.select do |key, value|
27
- key.match(/^(Notes|Password|Title|URL|UserName)$/).nil?
27
+ key.match(/^(notes|password|title|url|username)$/i).nil?
28
28
  end
29
29
  end
30
30
 
31
+ def attachment(name)
32
+ return nil if (@keepass.nil?)
33
+ return nil if (!has_attachment?(name))
34
+ return @keepass.attachment_decoder.get_attachment(
35
+ @attachments[name]
36
+ )
37
+ end
38
+
39
+ def attachments
40
+ attachments = Hash.new
41
+
42
+ @attachments.each do |key, value|
43
+ attachments[key] = attachment(key)
44
+ end
45
+
46
+ return attachments
47
+ end
48
+
31
49
  def attribute(attr)
32
50
  return nil if (@keepass.nil?)
33
51
  return "" if (!has_attribute?(attr))
@@ -53,34 +71,41 @@ class RubeePass::Entry
53
71
  end
54
72
 
55
73
  def details(level = 0, show_passwd = false)
56
- lvl = Array.new(level, " ").join
74
+ lvl = " " * level
57
75
 
58
- ret = Array.new
59
- ret.push(hilight_title("#{lvl}Title : #{@title}"))
60
- # ret.push("#{lvl}UUID : #{@uuid}")
61
- ret.push("#{lvl}Username : #{@username}")
76
+ r = Array.new
77
+ r.push("#{lvl}#{hilight_attr("Title:")} #{@title}")
78
+ # r.push("#{lvl}#{hilight_attr("UUID:")} #{@uuid}")
79
+ r.push("#{lvl}#{hilight_attr("Username:")} #{@username}")
62
80
  if (show_passwd)
63
- ret.push(
64
- hilight_password("#{lvl}Password : #{@password}")
81
+ r.push(
82
+ "#{lvl}#{hilight_password("Password:")} #{@password}"
65
83
  )
66
84
  end
67
- ret.push("#{lvl}Url : #{@url}")
85
+ r.push("#{lvl}#{hilight_attr("URL:")} #{@url}")
68
86
 
69
- first = true
87
+ r.push("#{lvl}#{hilight_attr("Notes:")}") if (!@notes.empty?)
70
88
  @notes.each_line do |line|
71
- if (first)
72
- ret.push("#{lvl}Notes : #{line.strip}")
73
- first = false
74
- else
75
- ret.push("#{lvl} #{line.strip}")
76
- end
89
+ r.push("#{lvl} #{line.strip}")
90
+ end
91
+
92
+ additional_attributes.each do |k, v|
93
+ r.push("#{lvl}#{hilight_attr("#{k}:")} #{v}")
94
+ end
95
+
96
+ if (!@attachments.empty?)
97
+ r.push("#{lvl}#{hilight_attr("Attachments:")}")
98
+ end
99
+ @attachments.keys.each do |name|
100
+ r.push("#{lvl} #{name}")
77
101
  end
78
102
 
79
- return ret.join("\n")
103
+ return r.join("\n")
80
104
  end
81
105
 
82
106
  def self.from_xml(keepass, parent, xml)
83
107
  attrs = Hash.new
108
+ attachs = Hash.new
84
109
 
85
110
  uuid = xml.elements["UUID"].text || ""
86
111
 
@@ -101,7 +126,19 @@ class RubeePass::Entry
101
126
  end
102
127
  end
103
128
 
104
- return RubeePass::Entry.new(parent, keepass, attrs, uuid)
129
+ xml.elements.each("Binary") do |elem|
130
+ key = elem.elements["Key"].text
131
+ value = elem.elements["Value"].attributes["Ref"]
132
+ attachs[key] = value
133
+ end
134
+
135
+ return RubeePass::Entry.new(
136
+ parent,
137
+ keepass,
138
+ attrs,
139
+ attachs,
140
+ uuid
141
+ )
105
142
  end
106
143
 
107
144
  def self.handle_protected(keepass, base64)
@@ -121,26 +158,35 @@ class RubeePass::Entry
121
158
  return keepass.protected_decryptor.add_to_stream(data)
122
159
  end
123
160
 
161
+ def has_attachment?(name)
162
+ return @attachments.any? do |k, v|
163
+ k.downcase == name.downcase
164
+ end
165
+ end
166
+
124
167
  def has_attribute?(attr)
125
- return !@attributes[attr].nil?
168
+ return @attributes.any? do |k, v|
169
+ k.downcase == attr.downcase
170
+ end
126
171
  end
127
172
 
173
+ def hilight_attr(title)
174
+ return title if (!RubeePass.hilight?)
175
+ return title.light_green
176
+ end
177
+ private :hilight_attr
178
+
128
179
  def hilight_password(passwd)
129
180
  return passwd if (!RubeePass.hilight?)
130
181
  return passwd.light_red
131
182
  end
132
183
  private :hilight_password
133
184
 
134
- def hilight_title(title)
135
- return title if (!RubeePass.hilight?)
136
- return title.light_green
137
- end
138
- private :hilight_title
139
-
140
- def initialize(group, keepass, attributes, uuid)
185
+ def initialize(group, keepass, attributes, attachments, uuid)
141
186
  @group = group
142
187
  @keepass = keepass
143
188
  @attributes = attributes
189
+ @attachments = attachments
144
190
 
145
191
  @notes = attribute("Notes")
146
192
  @password = attribute("Password")
@@ -1,5 +1,4 @@
1
- class RubeePass::Error < RuntimeError
2
- end
1
+ class RubeePass::Error < RuntimeError; end
3
2
 
4
3
  require "rubeepass/error/file_not_found"
5
4
  require "rubeepass/error/file_not_readable"
@@ -22,10 +22,10 @@ class RubeePass::Group
22
22
 
23
23
  def details(level = 0, show_passwd = false)
24
24
  out = Array.new
25
- lvl = Array.new(level, " ").join
25
+ lvl = " " * level
26
26
 
27
- group_details = [ hilight_header(@path) ] if (level == 0)
28
- group_details = [ hilight_header(@name) ] if (level != 0)
27
+ group_details = [hilight_header(@path)] if (level == 0)
28
+ group_details = [hilight_header(@name)] if (level != 0)
29
29
 
30
30
  group_details.each do |line|
31
31
  out.push("#{lvl}#{line}")
@@ -35,8 +35,11 @@ class RubeePass::Group
35
35
  out.push(group.details(level + 1, show_passwd))
36
36
  end
37
37
 
38
+ div = "-" * (70 - lvl.length - 2)
39
+ out.push("#{lvl} #{div}") if (!@entries.empty?)
38
40
  @entries.values.each do |entry|
39
41
  out.push(entry.details(level + 1, show_passwd))
42
+ out.push("#{lvl} #{div}")
40
43
  end
41
44
 
42
45
  return out.join("\n")
@@ -67,17 +70,14 @@ class RubeePass::Group
67
70
  end
68
71
 
69
72
  def self.from_xml(keepass, parent, xml)
70
- name = xml.elements["Name"].text if (parent)
71
- name = "" if (name.nil?)
72
- name = "/" if (parent.nil?)
73
+ name = "/"
74
+ name = xml.elements["Name"].text || "" if (parent)
73
75
 
74
- notes = xml.elements["Notes"].text if (parent)
75
- notes = "" if (notes.nil?)
76
- notes = "" if (parent.nil?)
76
+ notes = ""
77
+ notes = xml.elements["Notes"].text || "" if (parent)
77
78
 
78
- uuid = xml.elements["UUID"].text if (parent)
79
- uuid = "" if (uuid.nil?)
80
- uuid = "" if (parent.nil?)
79
+ uuid = ""
80
+ uuid = xml.elements["UUID"].text || "" if (parent)
81
81
 
82
82
  group = RubeePass::Group.new(
83
83
  parent,
@@ -151,22 +151,20 @@ class RubeePass::Group
151
151
  end
152
152
 
153
153
  def has_entry?(title)
154
- entry_titles.each do |entry|
155
- return true if (title.downcase == entry.downcase)
154
+ return entry_titles.any? do |entry|
155
+ entry.downcase == title.downcase
156
156
  end
157
- return false
158
157
  end
159
158
 
160
159
  def has_group?(name)
161
- group_names.each do |group|
162
- return true if (name.downcase == group.downcase)
160
+ return group_names.any? do |group|
161
+ group.downcase == name.downcase
163
162
  end
164
- return false
165
163
  end
166
164
 
167
165
  def hilight_header(header)
168
166
  return header if (!RubeePass.hilight?)
169
- return header.light_blue
167
+ return header.cyan
170
168
  end
171
169
  private :hilight_header
172
170
 
data/lib/rubeepass.rb CHANGED
@@ -26,6 +26,7 @@ class RubeePass
26
26
  @@MAGIC_SIG2 = 0xb54bfb67
27
27
  @@VERSION = 0x00030000
28
28
 
29
+ attr_reader :attachment_decoder
29
30
  attr_reader :db
30
31
  attr_reader :gzip
31
32
  attr_reader :protected_decryptor
@@ -337,6 +338,10 @@ class RubeePass
337
338
  raise Error::InvalidXML.new
338
339
  end
339
340
 
341
+ @attachment_decoder = AttachmentDecoder.new(
342
+ doc.elements["KeePassFile/Meta/Binaries"]
343
+ )
344
+
340
345
  root = doc.elements["KeePassFile/Root"]
341
346
  @db = Group.from_xml(self, nil, root)
342
347
  end
@@ -463,6 +468,7 @@ class RubeePass
463
468
  end
464
469
  end
465
470
 
471
+ require "rubeepass/attachment_decoder"
466
472
  require "rubeepass/entry"
467
473
  require "rubeepass/error"
468
474
  require "rubeepass/group"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubeepass
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Whittaker
@@ -179,6 +179,7 @@ extra_rdoc_files: []
179
179
  files:
180
180
  - bin/rpass
181
181
  - lib/rubeepass.rb
182
+ - lib/rubeepass/attachment_decoder.rb
182
183
  - lib/rubeepass/entry.rb
183
184
  - lib/rubeepass/error.rb
184
185
  - lib/rubeepass/error/file_not_found.rb