Resolve #7959, Automatically login to RPC service after expiration

When the RPC client token expires, it will automatically login
again, and renew the token during the next RPC request.

Resolves #7959
bug/bundler_fix
wchen-r7 2017-02-14 16:41:08 -06:00
parent 082ebe23db
commit 81abbfba46
1 changed files with 45 additions and 15 deletions

View File

@ -28,6 +28,9 @@ class Client
# @option info [String] :token A token used by the client.
# @return [void]
def initialize(info={})
@user = nil
@pass = nil
self.info = {
:host => '127.0.0.1',
:port => 3790,
@ -41,14 +44,16 @@ class Client
end
# Logs in by calling the 'auth.login' API. The authentication token will expire 5 minutes
# after the last request was made.
# Logs in by calling the 'auth.login' API. The authentication token will expire after 5
# minutes, but will automatically be rewnewed when you make a new RPC request.
#
# @param [String] user Username.
# @param [String] pass Password.
# @raise RuntimeError Indicating a failed authentication.
# @return [TrueClass] Indicating a successful login.
def login(user,pass)
@user = user
@pass = pass
res = self.call("auth.login", user, pass)
unless (res && res['result'] == "success")
raise RuntimeError, "authentication failed"
@ -58,6 +63,14 @@ class Client
end
# Attempts to login again with the last known user name and password.
#
# @return [TrueClass] Indicating a successful login.
def re_login
login(@user, @pass)
end
# Calls an API.
#
# @param [String] meth The RPC API to call.
@ -84,6 +97,36 @@ class Client
args.unshift(meth)
begin
send_rpc_request(args)
rescue Msf::RPC::ServerException => e
if e.message =~ /Invalid Authentication Token/i && meth != 'auth.login'
re_login
args[1] = self.token
retry
else
raise e
end
ensure
@cli.close if @cli
end
end
# Closes the client.
#
# @return [void]
def close
if @cli && @cli.conn?
@cli.close
end
@cli = nil
end
private
def send_rpc_request(args)
unless @cli
@cli = Rex::Proto::Http::Client.new(info[:host], info[:port], info[:context], info[:ssl], info[:ssl_version])
@cli.set_config(
@ -101,7 +144,6 @@ class Client
)
res = @cli.send_recv(req)
@cli.close
if res && [200, 401, 403, 500].include?(res.code)
resp = MessagePack.unpack(res.body)
@ -118,18 +160,6 @@ class Client
end
end
# Closes the client.
#
# @return [void]
def close
if @cli && @cli.conn?
@cli.close
end
@cli = nil
end
end
end
end