Advertisement
iarmin

rexecutor

May 13th, 2011
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 2.33 KB | None | 0 0
  1. #
  2. #: Filename    : rexecutor.rb
  3. #: Title       : rExecutor
  4. #: Author      : "Iarmin" <[email protected]>
  5. #: Version     : 0.1
  6. #: Description : A little webserver, that accepts JSON input via GET method. Supports authentication code and executes the given command.
  7. #: Gems        : json SystemTimer
  8. #: Installer   :
  9. #
  10.  
  11. require 'socket'
  12. require 'cgi'
  13. require 'rubygems'
  14. require 'json'
  15. require 'open3'
  16. require 'system_timer'
  17.  
  18. $AUTHCODE     = "<CODE>"    # the authentication code
  19. $LISTEN_IP    = "0.0.0.0"   # Bound IP
  20. $LISTEN_PORT  = 9091        # Port to listen
  21. $ALLOWED_CMDS = [ "df", "uname" ]   # allowed commands
  22.  
  23.  
  24. class HttpServer
  25.   def initialize(session, request)
  26.     @session = session
  27.     @request = request
  28.   end
  29.  
  30.   def serve()
  31.     begin
  32.       request = @request.chomp
  33.       raise if ! request.start_with?("GET /")
  34.       request.gsub!(/^GET \//,"").gsub!(/ .*/,"")
  35.       request = CGI::unescape( request )
  36.       request = JSON.parse( request.chomp )
  37.  
  38.       response = '[]'
  39.       begin
  40.         SystemTimer.timeout_after( 6 ) do
  41.         response = process( request )
  42.       end
  43.       rescue Timer::Timeout
  44.         response = { :error => "Timeout" }
  45.       rescue Exception => e
  46.         response = { :error => e.to_s }
  47.       end
  48.       response = response.to_json
  49.  
  50.       contentType = "text/plain"
  51.       @session.print "HTTP/1.1 200/OK\r\nServer: Remote Executor\r\nContent-type: text/plain\r\n\r\n"
  52.       @session.print( "#{response}\n" )
  53.     rescue
  54.       @session.print "HTTP/1.1 400/ERROR\r\nInvalid request\r\n\r\n"
  55.     ensure
  56.       @session.close
  57.     end
  58.   end
  59.  
  60.   def process( request )
  61.     response = {}
  62.     begin
  63.       raise "Invalid auth code" if request["auth"] != $AUTHCODE
  64.       _exec = request["exec"]
  65.       unallowed = true
  66.       $ALLOWED_CMDS.each do |cmd|
  67.         unallowed = false if _exec == cmd
  68.       end
  69.       raise "Restricted command" if unallowed
  70.       stdin, stdout, stderr, wait_thr = Open3.popen3( _exec )
  71.       response = { :stdout => stdout.read, :stderr => stderr.read }
  72.     rescue Exception => e
  73.         response = { :error => s.to_s }
  74.     end
  75.   end
  76. end
  77.  
  78. server = TCPServer.new($LISTEN_IP, $LISTEN_PORT)
  79.  
  80. loop do
  81.   session = server.accept
  82.   request = session.gets
  83.  
  84.   Thread.start(session, request) do |session, request|
  85.     HttpServer.new(session, request).serve()
  86.   end
  87. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement