CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/hwbridge/ui/console.rb
Views: 1904
1
# -*- coding: binary -*-
2
require 'rex/post/hwbridge'
3
4
module Rex
5
module Post
6
module HWBridge
7
module Ui
8
9
###
10
#
11
# This class provides a shell driven interface to the hwbridge client API.
12
#
13
###
14
class Console
15
16
include Rex::Ui::Text::DispatcherShell
17
18
# Dispatchers
19
require 'rex/post/hwbridge/ui/console/interactive_channel'
20
require 'rex/post/hwbridge/ui/console/command_dispatcher'
21
require 'rex/post/hwbridge/ui/console/command_dispatcher/core'
22
23
#
24
# Initialize the hardware bridge console.
25
#
26
def initialize(client)
27
if (Rex::Compat.is_windows())
28
super("hwbridge")
29
else
30
super("%undhwbridge%clr")
31
end
32
33
# The hwbridge client context
34
self.client = client
35
36
# Queued commands array
37
self.commands = []
38
39
# Point the input/output handles elsewhere
40
reset_ui
41
42
enstack_dispatcher(Console::CommandDispatcher::Core)
43
44
# Set up logging to whatever logsink 'core' is using
45
if ! $dispatcher['hwbridge']
46
$dispatcher['hwbridge'] = $dispatcher['core']
47
end
48
end
49
50
#
51
# Called when someone wants to interact with the hwbridge client. It's
52
# assumed that init_ui has been called prior.
53
#
54
def interact(&block)
55
# Run queued commands
56
commands.delete_if { |ent|
57
run_single(ent)
58
true
59
}
60
61
# Run the interactive loop
62
run { |line|
63
# Run the command
64
run_single(line)
65
66
# If a block was supplied, call it, otherwise return false
67
if (block)
68
block.call
69
else
70
false
71
end
72
}
73
end
74
75
#
76
# Interacts with the supplied channel.
77
#
78
def interact_with_channel(channel, *_)
79
channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
80
channel.on_command_proc = self.on_command_proc if self.on_command_proc
81
channel.on_print_proc = self.on_print_proc if self.on_print_proc
82
channel.on_log_proc = method(:log_output) if self.respond_to?(:log_output, true)
83
84
channel.interact(input, output)
85
channel.reset_ui
86
end
87
88
#
89
# Queues a command to be run when the interactive loop is entered.
90
#
91
def queue_cmd(cmd)
92
self.commands << cmd
93
end
94
95
#
96
# Runs the specified command wrapper in something to catch hwbridge
97
# exceptions.
98
#
99
def run_command(dispatcher, method, arguments)
100
begin
101
super
102
rescue Timeout::Error
103
log_error("Operation timed out.")
104
rescue RequestError => info
105
log_error(info.to_s)
106
rescue Rex::InvalidDestination => e
107
log_error(e.message)
108
rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
109
self.client.kill
110
rescue ::Exception => e
111
log_error("Error running command #{method}: #{e.class} #{e}")
112
end
113
end
114
115
#
116
# Logs that an error occurred and persists the callstack.
117
#
118
def log_error(msg)
119
print_error(msg)
120
121
elog(msg, 'hwbridge')
122
123
dlog("Call stack:\n#{$@.join("\n")}", 'hwbridge')
124
end
125
126
attr_reader :client # :nodoc:
127
128
protected
129
130
attr_writer :client # :nodoc:
131
attr_accessor :commands # :nodoc:
132
133
end
134
135
end
136
end
137
end
138
end
139
140