Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/msf/ui/web/comm.rb
Views: 11783
# -*- coding: binary -*-1module Msf2module Ui3module Web45module Comm67class Channel8def initialize9@id = Comm.next_channel_id10end1112def read13nil14end1516attr_accessor :id17end1819class SessionChannel < Channel20def initialize(session_id, pipe)21super()2223@sid = session_id24@pipe = pipe2526@pipe.create_subscriber(channel.id)27end2829def close30@pipe.remove_subscriber(channel.id)31end3233def write_input(msg)34@pipe.write_input(msg)35end3637def read38@pipe.read_subscriber(channel.id)39end40end4142class SessionEventSubscriber43include Msf::SessionEvent4445def on_session_open(session)46pipe = Comm.create_session_pipe(session)4748session.init_ui(pipe, pipe)49end50end5152@@framework = nil53@@channels = {}54@@channel_id = 055@@read_event = Rex::Sync::Event.new(false, false)56@@session_pipes = {}5758def self.setup(framework)59@framework = framework6061framework.events.add_session_subscriber(SessionEventSubscriber.new)62end6364def self.wakeup65@read_event.set66end6768def self.next_channel_id69@channel_id += 170end7172def self.create_channel(client, request)73create_session_channel(client.qstring['sid'].to_i)74end7576def self.create_session_channel(session_id)77channel = SessionChannel.new(session_id, @session_pipes[session_id])7879@channels[channel.id] = channel8081channel82end8384def self.create_session_pipe(session)85pipe = Rex::Ui::BidirectionalPipe.new8687@session_pipes[session.id] = pipe8889pipe90end9192def self.write_channel(client, request)93channel_id = request.qstring['channel_id']94data = request.qstring['data']95channel = @channels[channel_id]9697if channel.nil? == false98channel.write_input(data)99end100end101102def self.read_channels(client, request)103dlog("read_channels: waiting for event")104105# Wait to see if there's any data available on channels. If there106# isn't, then we send a response immediately. Otherwise, we check107# to see if any of the requested channels were ones that we're108# interested in.109begin110@@read_event.wait(15)111rescue Timeout::Error112client.send_response(Rex::Proto::Http::Response::OK.new)113return114end115116@@read_event.reset117118channels = request.qstring['channels']119120if channels.kind_of?(Array) == false121channels = [channels]122end123124# Walk each channel, checking to see if there is any read data. If125# there is, then we'll include it in the response body.126body = '<channeldatum>'127128channels.each { |cid|129channel = @channels[cid]130131next if channel.nil?132133buf = channel.read134135next if buf.nil?136137body += "<channeldata id=\"#{channel.id}\">#{Base64.encode64(buf)}</channeldata>"138}139140body = '</channeldatum>'141142# Create and send the response143response = Rex::Proto::Http::Response::OK.new144response.body = body145146client.send_response(response)147end148149end150151end152end153end154155156157