mfa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -0
  3. data/Onafile +254 -0
  4. data/bin/mfa +4 -0
  5. metadata +88 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: abc69612ca114cbc9b3735453b8602485cc4f95d8dd5d71ae2f4eb10c3cdc335
4
+ data.tar.gz: b6d3146f3318d006190f2f813b44533519203641b1bdf6b1d790c725f818156f
5
+ SHA512:
6
+ metadata.gz: 766faa173d7b177cbc932638cbcb87fc51cb204a6b6583789afe701abfed32e5420c226896c52d31f067a1d541fc7147c6a7707976ebc776b570b512440bc032
7
+ data.tar.gz: f9d668031f3e571e961be1283e49ded04eb259955c30cbaecd1c540a6d6eea4456dc50597e907a605c41b586a6162cb26fc93633735db96c373563de4c12618e
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'isna', '0.0.4'
4
+ gem 'abstract_command', '0.0.6'
5
+ gem 'ona', '1.0.0'
6
+
data/Onafile ADDED
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'abstract_command'
4
+ require 'isna'
5
+ require 'tmpdir'
6
+ require 'json'
7
+
8
+ module Command
9
+ class GetMfa < AbstractCommand
10
+ def template
11
+ 'security find-generic-password -w -a %<account>s -s %<service>s %<keychain>s'
12
+ end
13
+ end
14
+ class SetMfa < AbstractCommand
15
+ def template
16
+ 'security add-generic-password -a %<account>s -s %<service>s -w %<mfa>s %<keychain>s'
17
+ end
18
+ end
19
+ class RmMfa < AbstractCommand
20
+ def template
21
+ 'security delete-generic-password -a %<account>s -s %<service>s %<keychain>s'
22
+ end
23
+ end
24
+ class CreateKeychain < AbstractCommand
25
+ def template
26
+ 'security create-keychain %<keychain>s'
27
+ end
28
+ end
29
+ class DeleteKeychain < AbstractCommand
30
+ def template
31
+ 'security delete-keychain %<keychain>s'
32
+ end
33
+ end
34
+ class ListMfa < AbstractCommand
35
+ def template
36
+ "security dump-keychain %<keychain>s | awk -F'=' '/0x00000007/ { print $2 }'"
37
+ end
38
+ end
39
+ class ResolveMfa < AbstractCommand
40
+ def template
41
+ 'oathtool -b --totp %<seed>s'
42
+ end
43
+ end
44
+ end
45
+
46
+ KEYCHAIN = 'mfa'
47
+
48
+ Ona.prompt = 'Mfa'
49
+
50
+ Ona.resource(:mfa, [:service])
51
+
52
+ def load_mfa_list
53
+ Command::ListMfa.new(:keychain => KEYCHAIN).backtick.each_line do |line|
54
+ line.chomp!
55
+ next if line == ''
56
+ Ona.register(:mfa) do |mfa|
57
+ mfa.service = line.gsub(/^"|"$/, '')
58
+ end
59
+ end
60
+ end
61
+
62
+ def unload_mfa_list
63
+ Ona.class_eval do
64
+ puts @resources[:mfa][:entries] = []
65
+ end
66
+ end
67
+
68
+ def reset_mfa_list
69
+ unload_mfa_list
70
+ load_mfa_list
71
+ end
72
+
73
+ load_mfa_list
74
+
75
+ def print_command(command)
76
+ puts ''
77
+ puts "# Command: #{command.to_ansi.yellow.to_s}"
78
+ puts "# Executed at: #{Time.now.to_s}"
79
+ puts "# #{('=' * 76).to_ansi.cyan.to_s}"
80
+ puts ''
81
+ end
82
+
83
+ Ona.action(
84
+ :regex => /^create-keychain$/,
85
+ :resource => :mfa,
86
+ :text => 'Create the MFA Keychain.',
87
+ :example => 'create-keychain'
88
+ ) do |mfa, input, regex|
89
+ command = Command::CreateKeychain.new
90
+ command.keychain = KEYCHAIN
91
+ print_command command.to_s
92
+ command.system
93
+ end
94
+
95
+ Ona.action(
96
+ :regex => /^delete-keychain$/,
97
+ :resource => :mfa,
98
+ :text => 'Delete the MFA Keychain.',
99
+ :example => 'delete-keychain'
100
+ ) do |mfa, input, regex|
101
+ command = Command::DeleteKeychain.new
102
+ command.keychain = KEYCHAIN
103
+ print_command command.to_s
104
+ command.system
105
+ reset_mfa_list
106
+ end
107
+
108
+ Ona.action(
109
+ :regex => /(^)(set)(\s)([^ ]+)(\s)(.*)($)/,
110
+ :resource => :mfa,
111
+ :text => 'Add a new MFA entry.',
112
+ :example => 'set [SERVICE] [MFA]',
113
+ ) do |mfa, input, regex|
114
+ command = Command::SetMfa.new
115
+ command.account = KEYCHAIN
116
+ command.service = input.scan(regex)[0][3]
117
+ command.keychain = KEYCHAIN
118
+ command.mfa = input.scan(regex)[0][5]
119
+ print_command command.to_s
120
+ command.system
121
+ reset_mfa_list
122
+ end
123
+
124
+ Ona.action(
125
+ :regex => /(^)(get)(\s)(\d+)($)/,
126
+ :resource => :mfa,
127
+ :text => 'Get mfa from keychain and send to clipboard.',
128
+ :example => 'get [NUMBER]',
129
+ :find => true,
130
+ :token => proc { |scan| scan[0][3] }
131
+ ) do |mfa, id|
132
+ command = Command::GetMfa.new
133
+ command.account = KEYCHAIN
134
+ command.service = mfa.service
135
+ command.keychain = KEYCHAIN
136
+ seed = command.backtick.chomp
137
+ puts " #{id.to_s.to_ansi.cyan.to_s} - #{'service'.to_ansi.green.to_s} : #{mfa.service}"
138
+ command = Command::ResolveMfa.new(:seed => seed)
139
+ secret = command.backtick.chomp
140
+ puts " * Sent to clipboard!".to_ansi.yellow.to_s
141
+ puts " > ".to_ansi.cyan.blink.to_s + "#{secret}"
142
+ Dir.mktmpdir do |dir|
143
+ fname = "#{dir}/file.txt"
144
+ File.open(fname, 'w+') do |file|
145
+ file.print secret.chomp
146
+ end
147
+ system "cat #{fname} | pbcopy"
148
+ end
149
+ end
150
+
151
+ Ona.action(
152
+ :regex => /(^)(dump)(\s)(\d+)($)/,
153
+ :resource => :mfa,
154
+ :text => 'Dump seed, service, and code to STDOUT.',
155
+ :example => 'dump [NUMBER]',
156
+ :find => true,
157
+ :token => proc { |scan| scan[0][3] }
158
+ ) do |mfa, id|
159
+ command = Command::GetMfa.new
160
+ command.account = KEYCHAIN
161
+ command.service = mfa.service
162
+ command.keychain = KEYCHAIN
163
+ puts " #{id.to_s.to_ansi.cyan.to_s} - #{'service'.to_ansi.green.to_s} : #{mfa.service}"
164
+ puts " - mfa : #{command.backtick.chomp}"
165
+ end
166
+
167
+ Ona.action(
168
+ :regex => /(^)(rm)(\s)(\d+)($)/,
169
+ :resource => :mfa,
170
+ :text => 'Remove an existing mfa seed.',
171
+ :example => 'rm [NUMBER]',
172
+ :find => true,
173
+ :token => proc { |scan| scan[0][3] }
174
+ ) do |mfa, id|
175
+ command = Command::RmMfa.new
176
+ command.account = KEYCHAIN
177
+ command.service = mfa.service
178
+ command.keychain = KEYCHAIN
179
+ print_command command.to_s
180
+ command.system
181
+ end
182
+
183
+ Ona.action(
184
+ :regex => /(^)(ls)($)/,
185
+ :resource => :mfa,
186
+ :text => 'List all MFAs.',
187
+ :example => 'ls',
188
+ ) do |mfa, id|
189
+ mfa.each_with_index do |mfa, id|
190
+ puts " #{id.to_s.to_ansi.cyan.to_s} - #{'service'.to_ansi.green.to_s} : #{mfa.service}"
191
+ end
192
+ end
193
+
194
+ Ona.action(
195
+ :regex => /(^)(export)($)/,
196
+ :resource => :mfa,
197
+ :text => 'Export all MFAs.',
198
+ :example => 'export',
199
+ ) do |mfa, id|
200
+ mfa.each_with_index do |mfa, id|
201
+ command = Command::GetMfa.new
202
+ command.account = KEYCHAIN
203
+ command.service = mfa.service
204
+ command.keychain = KEYCHAIN
205
+ seed = command.backtick.chomp
206
+ object = {
207
+ :service => mfa.service,
208
+ :seed => seed
209
+ }
210
+ puts object.to_json
211
+ end
212
+ end
213
+
214
+ Ona.action(
215
+ :regex => /(^)(import)(\s)(.*\.json)($)/,
216
+ :resource => :mfa,
217
+ :text => 'Import MFAs from a json file.',
218
+ :example => 'import [FILE]',
219
+ ) do |mfa, command, regex|
220
+ file = regex.match(command)[4]
221
+ puts "Importing from #{file}"
222
+ unless File.exists?(file)
223
+ puts "File #{file} does not exist."
224
+ next
225
+ end
226
+ File.read(file).each_line do |line|
227
+ object = JSON.parse(line)
228
+ Ona.run("set #{object['service']} #{object['seed']}")
229
+ end
230
+ reset_mfa_list
231
+ puts "Import has completed."
232
+ end
233
+
234
+ Ona.action(
235
+ :regex => /(^)(s)(\s)(.*)($)/,
236
+ :resource => :mfa,
237
+ :text => 'Search by service.',
238
+ :example => 's [STRING]'
239
+ ) do |mfa, command, regex|
240
+ text = command.scan(regex)[0][3]
241
+ r = Regexp.new(text)
242
+ mfa.each_with_index do |mfa, id|
243
+ next unless r.match(mfa.to_s)
244
+ match = " #{id.to_s.to_ansi.cyan.to_s} - #{'service'.to_ansi.green.to_s} : #{mfa.service}"
245
+ puts match.gsub(text, text.to_ansi.red.to_s)
246
+ end
247
+ end
248
+
249
+ if ARGV.size > 0
250
+ Ona.defaults
251
+ Ona.run(ARGV.join(' '))
252
+ exit 0
253
+ end
254
+
data/bin/mfa ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ system "cd #{__dir__}/../ && ona #{ARGV.join(' ')}"
4
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mfa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kazuyoshi Tlacaelel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: isna
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: abstract_command
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.6
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.6
41
+ - !ruby/object:Gem::Dependency
42
+ name: ona
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ description:
56
+ email: kazu.dev@gmail.com
57
+ executables:
58
+ - mfa
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - Gemfile
63
+ - Onafile
64
+ - bin/mfa
65
+ homepage: https://github.com/ktlacaelel/mfa
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubygems_version: 3.3.7
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: mfa - mfa utility tool
88
+ test_files: []