telnet.rb 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. require 'zlib'
  2. require_relative 'telnet/codes'
  3. require_relative 'rfc1143'
  4. require_relative 'monolog'
  5. # This Telnet class implements a subset of the Telnet protocol.
  6. #
  7. class Telnet
  8. include Monolog
  9. include Telnet::Codes
  10. # Allowed telnet state codes
  11. STATES = [:data, :iac, :will, :wont, :do, :dont, :sb, :sb_data, :sb_data_iac]
  12. # Helper structs
  13. Telopt = Struct.new(:telopt, :us, :him)
  14. def initialize(client)
  15. @client = client
  16. @telopts = {} # Telopt support.
  17. @rfc1143 = {} # RFC1143 support.
  18. @buffer = "" # Subrequest buffer
  19. @state = :data # state of telnet protocol parser.
  20. @sb_telopt = nil; # current subnegotiation
  21. @compress = false # compression state
  22. end
  23. # Wait for input from the server
  24. def wait_for_input
  25. return Fiber.yield
  26. end
  27. # Called when client data should be filtered before being passed to the server
  28. def client_to_server(data)
  29. result = ""
  30. data.each_byte do | b |
  31. iac = TELNET_IAC.chr
  32. case @buffer
  33. when /\A#{iac}#{iac}\Z/
  34. # ongoing negotiation
  35. when /\A#{iac}\Z/
  36. return nil
  37. else
  38. end
  39. end
  40. end
  41. # Sends unescaped data to client, possibly compressing it if needed
  42. def send_raw(buf)
  43. if @compress
  44. zbuf = Zlib.deflate(buf)
  45. else
  46. zbuf = buf
  47. end
  48. @client.send_data(zbuf)
  49. end
  50. # Send data to client (escapes IAC bytes)
  51. def send_escaped(buf)
  52. iac = TELNET_IAC.chr
  53. self.send_raw(buf.gsub("#{iac}", "#{iac}#{iac}")
  54. end
  55. # Send negotiation bytes
  56. /* send negotiation bytes */
  57. def send_negotiate(cmd, telopt)
  58. bytes = ""
  59. bytes << TELNET_IAC
  60. bytes << cmd
  61. bytes << telopt
  62. send_raw(bytes)
  63. end
  64. # Check if we support a particular telopt;
  65. def us_support(telopt)
  66. have = @telopts[telopt]
  67. return false unless have
  68. return (have.telopt == telopt) && have.us
  69. end
  70. # Check if the remote supports a telopt
  71. def him_support(telopt)
  72. have = @telopts[telopt]
  73. return false unless have
  74. return (have.telopt == telopt) && have.him
  75. end
  76. # retrieve RFC1143 option state
  77. def rfc1143_get(telopt)
  78. @rfc1143[telopt]
  79. end
  80. # save RFC1143 option state
  81. def rfc1143_set(telopt, us, him)
  82. agree = we_support(telopt)
  83. @rfc1143[telopt] = RFC1143.new(telopt, us, him, agree)
  84. return @rfc1143[telopt]
  85. end
  86. # RFC1143 telnet option negotiation helper
  87. def rfc1143_negotiate_will(rfc1143)
  88. return rfc1143.handle_will
  89. end
  90. # RFC1143 telnet option negotiation helper
  91. def rfc1143_negotiate_wont(rfc1143)
  92. return rfc1143.handle_wont
  93. end
  94. # RFC1143 telnet option negotiation helper
  95. def rfc1143_negotiate_do(rfc1143)
  96. return rfc1143.handle_do
  97. end
  98. # RFC1143 telnet option negotiation helper
  99. def rfc1143_negotiate_dont(rfc1143)
  100. return rfc1143.handle_dont
  101. end
  102. # RFC1143 telnet option negotiation helper
  103. def rfc1143_negotiate(telopt)
  104. q = rfc1143_get(telopt)
  105. return nil, nil unless q
  106. case @state
  107. when :will
  108. return rfc1143_negotiate_will(q)
  109. when :wont
  110. return rfc1143_negotiate_wont(q)
  111. when :do
  112. return rfc1143_negotiate_do(q)
  113. when :dont
  114. return rfc1143_negotiate_dont(q)
  115. end
  116. end
  117. def do_negotiate(telopt)
  118. res, arg = rfc1143_negotiate(telopt)
  119. return unless res
  120. if res == :error
  121. log_error(arg)
  122. else
  123. send_negotiate(res, arg)
  124. end
  125. end
  126. # Called when server data should be filtered before being passed to the client
  127. def server_to_client(data)
  128. end
  129. end