2
2
3
3
module Security
4
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' )
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 ) )
57
37
end
58
38
end
59
- 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
60
+
61
+ class GenericPassword < Password
62
+ class << self
63
+ def add ( service , account , password , options = { } )
64
+ options [ :a ] = account
65
+ options [ :s ] = service
66
+ options [ :w ] = password
67
+
68
+ system "security add-generic-password #{ flags_for_options ( options ) } "
69
+ end
70
+
71
+ def find ( options )
72
+ password_from_output ( `security 2>&1 find-generic-password -g #{ flags_for_options ( options ) } ` )
73
+ end
74
+
75
+ def delete ( options )
76
+ system "security delete-generic-password #{ flags_for_options ( options ) } "
77
+ end
78
+
79
+ private
80
+
81
+ def flags_for_options ( options = { } )
82
+ options [ :s ] ||= options . delete ( :service )
83
+ super ( options )
84
+ end
85
+ end
86
+ end
87
+
88
+ class InternetPassword < Password
89
+ class << self
90
+ def add ( server , account , password , options = { } )
91
+ options [ :a ] = account
92
+ options [ :s ] = server
93
+ options [ :w ] = password
94
+
95
+ system "security add-internet-password #{ flags_for_options ( options ) } "
96
+ end
97
+
98
+ def find ( options )
99
+ password_from_output ( `security 2>&1 find-internet-password -g #{ flags_for_options ( options ) } ` )
100
+ end
101
+
102
+ def delete ( options )
103
+ system "security delete-internet-password #{ flags_for_options ( options ) } "
104
+ end
105
+
106
+ private
107
+
108
+ def flags_for_options ( options = { } )
109
+ options [ :s ] ||= options . delete ( :server )
110
+ options [ :p ] ||= options . delete ( :path )
111
+ options [ :P ] ||= options . delete ( :port )
112
+ options [ :r ] ||= options . delete ( :protocol )
113
+ super ( options )
114
+ end
115
+ end
116
+ end
117
+ end
0 commit comments