1
+ require 'shellwords'
2
+
3
+ module Security
4
+
5
+ class Password
6
+ attr_reader :keychain , :attributes , :password
7
+
8
+ private_class_method :new
9
+
10
+ def initialize ( keychain , attributes , password )
11
+ @keychain = Keychain . new ( keychain )
12
+ @attributes = attributes
13
+ @password = password
14
+ end
15
+
16
+ class << self
17
+ private
18
+
19
+ def password_from_output ( output )
20
+ return nil if output . match? ( /^security: / )
21
+
22
+ keychain = nil
23
+ attributes = { }
24
+ password = nil
25
+ output . split ( /\n / ) . each do |line |
26
+ case line
27
+ when /^keychain: "(.+)"/
28
+ keychain = Regexp . last_match ( 1 )
29
+ when /"(\w {4})".+="(.+)"/
30
+ attributes [ Regexp . last_match ( 1 ) ] = Regexp . last_match ( 2 )
31
+ when /"(\w {4})"<blob>=0x([[:xdigit:]]+)/
32
+ attributes [ Regexp . last_match ( 1 ) ] = decode_hex_blob ( Regexp . last_match ( 2 ) )
33
+ when /^password: "(.+)"/
34
+ password = Regexp . last_match ( 1 )
35
+ when /^password: 0x([[:xdigit:]]+)/
36
+ password = decode_hex_blob ( Regexp . last_match ( 1 ) )
37
+ end
38
+ end
39
+
40
+ new ( keychain , attributes , password )
41
+ end
42
+
43
+ def flags_for_options ( options = { } )
44
+ flags = options . dup
45
+ flags [ :a ] ||= flags . delete ( :account )
46
+ flags [ :c ] ||= flags . delete ( :creator )
47
+ flags [ :C ] ||= flags . delete ( :type )
48
+ flags [ :D ] ||= flags . delete ( :kind )
49
+ flags [ :G ] ||= flags . delete ( :value )
50
+ flags [ :j ] ||= flags . delete ( :comment )
51
+
52
+ flags . delete_if { |_k , v | v . nil? } . collect { |k , v | "-#{ k } #{ v . shellescape } " . strip } . join ( ' ' )
53
+ end
54
+
55
+ def decode_hex_blob ( string )
56
+ [ string ] . pack ( 'H*' ) . force_encoding ( 'UTF-8' )
57
+ end
58
+ end
59
+ end
0 commit comments