module RubyQA require 'base64' class CommandRunner # Handles creating an interface for running arbitrary commands on a host/target # # To basically provide a unified interface to run commands via different methods (ssh, telnet, etc) # Params: # - ip # - hostname (optional) def initialize (data) @data = data verify_data initialize_runner end def verify_data if @data[:ip].empty? if not @data[:hostname].empty? begin @data[:ip] = Resolv.getaddress(@data[:hostname]) rescue Resolv::ResolvError => error raise "Host: Hostname provided, but did not resolve to IP" end else raise "Host: No hostname or IP provided" end end client_validations end def client_validations # Handles client specific validations (port-connect test, etc) end def exec (command) run_command(command) end def exec_sudo(command) if @data[:password].empty? raise "Password was not provided for host" end encoded_command = Base64.encode(command) sudo_command = < 10, "Prompt" => /[$:#]/ } def initialize_runner begin @client = Net::SSH::Telnet.new( "Host" => @data[:ip], "Username" => @data[:user], "Password" => @data[:password]) # Since this is telnet, it doesn't filter out command sequences, so we have to set the PS1/prompt to something # that is easily matched for filtering purposes @client.cmd({"String" => "PS1=''; PROMPT_COMMANDS='';", "Match" => /filter_line/}) rescue SocketError raise "Failed to make ssh client for #{@data[:hostname]}" end end def run_command(command) output = "" ## Doing intitial command (doesn't send white-space/newline) lines = Array.new filter_regex=/(^|#{command}|^\n$)/ output = @client.cmd({"String" => command, "Waittime" => 100, "Match" => /filter_line/}) # Have to clean output since telnet session will return all output, both stdin & stdout. output = output.split(/\n/).reject do |line| line.match?(/filter_line/) || line.match(/#{command}/) end.join("\n") output end end end