@@ -13,20 +13,19 @@ while File.symlink?(msfbase)
13
13
msfbase = File . expand_path ( File . readlink ( msfbase ) , File . dirname ( msfbase ) )
14
14
end
15
15
16
-
17
16
class Msfupdate
18
17
attr_reader :stdin
19
18
attr_reader :stdout
20
19
attr_reader :stderr
21
20
22
- def initialize ( msfbase_dir , stdin = $stdin, stdout = $stdout, stderr = $stderr)
21
+ def initialize ( msfbase_dir , stdin = $stdin, stdout = $stdout, stderr = $stderr)
23
22
@msfbase_dir = msfbase_dir
24
23
@stdin = stdin
25
24
@stdout = stdout
26
25
@stderr = stderr
27
26
end
28
27
29
- def usage ( io = stdout )
28
+ def usage ( io = stdout )
30
29
help = "usage: msfupdate [options...]\n "
31
30
help << "Options:\n "
32
31
help << "-h, --help show help\n "
@@ -42,14 +41,14 @@ class Msfupdate
42
41
# Copy args into ARGV, then restore ARGV after GetoptLong
43
42
real_args = ARGV . clone
44
43
ARGV . clear
45
- args . each { |arg | ARGV << arg }
44
+ args . each { |arg | ARGV << arg }
46
45
47
46
require 'getoptlong'
48
47
opts = GetoptLong . new (
49
48
[ '--help' , '-h' , GetoptLong ::NO_ARGUMENT ] ,
50
49
[ '--git-remote' , GetoptLong ::REQUIRED_ARGUMENT ] ,
51
50
[ '--git-branch' , GetoptLong ::REQUIRED_ARGUMENT ] ,
52
- [ '--offline-file' , GetoptLong ::REQUIRED_ARGUMENT ] ,
51
+ [ '--offline-file' , GetoptLong ::REQUIRED_ARGUMENT ]
53
52
)
54
53
55
54
begin
@@ -67,7 +66,7 @@ class Msfupdate
67
66
end
68
67
end
69
68
rescue GetoptLong ::Error
70
- stderr . puts "#{ $0 } : try 'msfupdate --help' for more information"
69
+ stderr . puts "#{ $PROGRAM_NAME } : try 'msfupdate --help' for more information"
71
70
maybe_wait_and_exit 0x20
72
71
end
73
72
@@ -79,7 +78,7 @@ class Msfupdate
79
78
ensure
80
79
# Restore the original ARGV value
81
80
ARGV . clear
82
- real_args . each { |arg | ARGV << arg }
81
+ real_args . each { |arg | ARGV << arg }
83
82
end
84
83
end
85
84
@@ -126,7 +125,7 @@ class Msfupdate
126
125
stderr . puts ""
127
126
128
127
# Bail right away, no waiting around for consoles.
129
- if not ( Process . uid == 0 or File . stat ( @msfbase_dir ) . owned? )
128
+ unless Process . uid . zero? || File . stat ( @msfbase_dir ) . owned?
130
129
stderr . puts "[-] ERROR: User running msfupdate does not own the Metasploit installation"
131
130
stderr . puts "[-] Please run msfupdate as the same user who installed Metasploit."
132
131
maybe_wait_and_exit 0x10
@@ -140,17 +139,47 @@ class Msfupdate
140
139
elsif apt?
141
140
update_apt!
142
141
else
143
- raise RuntimeError , "Cannot determine checkout type: `#{ @msfbase_dir } '"
142
+ raise "Cannot determine checkout type: `#{ @msfbase_dir } '"
144
143
end
145
144
end
146
145
end
147
146
147
+ # We could also do this by running `git config --global user.name` and `git config --global user.email`
148
+ # and check the output of those. (it's a bit quieter)
149
+ def git_globals_okay?
150
+ require 'os'
151
+ output = ''
152
+ begin
153
+ output = `git config --list`
154
+ rescue Errno ::ENOENT
155
+ stderr . puts '[-] ERROR: Failed to check git settings, git not found'
156
+ return false
157
+ end
158
+
159
+ unless output . include? 'user.name'
160
+ stderr . puts '[-] ERROR: user.name is not set in your global git configuration'
161
+ stderr . puts '[-] Set it by running: \'git config --global user.name "NAME HERE"\''
162
+ stderr . puts ''
163
+ return false
164
+ end
165
+
166
+ unless output . include? 'user.email'
167
+ stderr . puts '[-] ERROR: user.email is not set in your global git configuration'
168
+ stderr . puts '[-] Set it by running: \'git config --global user.email "[email protected] "\''
169
+ stderr . puts ''
170
+ return false
171
+ end
172
+
173
+ true
174
+ end
175
+
148
176
def update_git!
149
177
####### Since we're Git, do it all that way #######
150
178
stdout . puts "[*] Checking for updates via git"
151
179
stdout . puts "[*] Note: Updating from bleeding edge"
152
180
out = `git remote show upstream` # Actually need the output for this one.
153
- add_git_upstream unless $?. success? and out =~ %r{(https|git|git@github\. com):(//github\. com/)?(rapid7/metasploit-framework\. git)}
181
+ add_git_upstream unless $?. success? &&
182
+ out =~ %r{(https|git|git@github\. com):(//github\. com/)?(rapid7/metasploit-framework\. git)}
154
183
155
184
remote = @git_remote || "upstream"
156
185
branch = @git_branch || "master"
@@ -163,8 +192,14 @@ class Msfupdate
163
192
# to begin with.
164
193
#
165
194
# Note, this requires at least user.name and user.email
166
- # to be configured in the global git config. Installers should
167
- # take care that this is done. TODO: Enforce this in msfupdate
195
+ # to be configured in the global git config. Installers
196
+ # will be told to set them if they aren't already set.
197
+
198
+ # Checks user.name and user.email
199
+ global_status = git_globals_okay?
200
+ maybe_wait_and_exit ( 1 ) unless global_status
201
+
202
+ # We shouldn't get here if the globals dont check out
168
203
committed = system ( "git" , "diff" , "--quiet" , "HEAD" )
169
204
if committed . nil?
170
205
stderr . puts "[-] ERROR: Failed to run git"
@@ -173,7 +208,7 @@ class Msfupdate
173
208
stderr . puts "[-] /usr/local/bin instead of running this file directly (e.g.: ./msfupdate)"
174
209
stderr . puts "[-] to ensure a proper environment."
175
210
maybe_wait_and_exit 1
176
- elsif not committed
211
+ elsif ! committed
177
212
system ( "git" , "stash" )
178
213
stdout . puts "[*] Stashed local changes to avoid merge conflicts."
179
214
stdout . puts "[*] Run `git stash pop` to reapply local changes."
@@ -203,7 +238,7 @@ class Msfupdate
203
238
product_key = File . expand_path ( File . join ( @msfbase_dir , ".." , "engine" , "license" , "product.key" ) )
204
239
if File . exist? product_key
205
240
if File . readable? product_key
206
- if ( @offline_file )
241
+ if @offline_file
207
242
system ( "ruby" , update_script , @offline_file )
208
243
else
209
244
system ( "ruby" , update_script )
@@ -235,19 +270,13 @@ class Msfupdate
235
270
stdout . puts "[*] Note: expect weekly(ish) updates using this method"
236
271
system ( "apt-get" , "-qq" , "update" )
237
272
238
- packages = [ ]
239
- packages << 'metasploit-framework' if framework_version = apt_upgrade_available ( 'metasploit-framework' )
240
- packages << 'metasploit' if pro_version = apt_upgrade_available ( 'metasploit' )
273
+ framework_version = apt_upgrade_available ( 'metasploit-framework' )
241
274
242
- if packages . empty ?
275
+ if framework_version . blank ?
243
276
stdout . puts "[*] No updates available"
244
277
else
245
- stdout . puts "[*] Updating to version #{ pro_version || framework_version } "
246
- system ( "apt-get" , "install" , "--assume-yes" , *packages )
247
- if packages . include? ( 'metasploit' )
248
- start_cmd = File . expand_path ( File . join ( @msfbase_dir , '..' , '..' , '..' , 'scripts' , 'start.sh' ) )
249
- system ( start_cmd ) if ::File . executable_real? start_cmd
250
- end
278
+ stdout . puts "[*] Updating to version #{ framework_version } "
279
+ system ( "apt-get" , "install" , "--assume-yes" , "metasploit-framework" )
251
280
end
252
281
end
253
282
@@ -262,23 +291,21 @@ class Msfupdate
262
291
263
292
# This only exits if you actually pass a wait option, otherwise
264
293
# just returns nil. This is likely unexpected, revisit this.
265
- def maybe_wait_and_exit ( exit_code = 0 )
294
+ def maybe_wait_and_exit ( exit_code = 0 )
266
295
if @actually_wait
267
296
stdout . puts ""
268
297
stdout . puts "[*] Please hit enter to exit"
269
298
stdout . puts ""
270
299
stdin . readline
271
- exit exit_code
272
- else
273
- exit exit_code
274
300
end
301
+ exit exit_code
275
302
end
276
303
277
304
def apt_upgrade_available ( package )
278
305
require 'open3'
279
306
installed = nil
280
307
upgrade = nil
281
- ::Open3 . popen3 ( { 'LANG' => 'en_US.UTF-8' } , "apt-cache" , "policy" , package ) do |stdin , stdout , stderr |
308
+ ::Open3 . popen3 ( { 'LANG' => 'en_US.UTF-8' } , "apt-cache" , "policy" , package ) do |_stdin , stdout , _stderr |
282
309
stdout . each do |line |
283
310
installed = $1 if line =~ /Installed: ([\w \- +.:~]+)$/
284
311
upgrade = $1 if line =~ /Candidate: ([\w \- +.:~]+)$/
0 commit comments