Class: SimpleTelnetServer::Connection

Inherits:
EventMachine::Connection
  • Object
show all
Defined in:
lib/em-simple_telnet_server.rb

Overview

A basic Telnet server implemented with EventMachine.

Defined Under Namespace

Classes: UnknownCommand

Constant Summary collapse

DEFAULT_OPTIONS =

Returns default values for (telnet) options.

Returns:

  • (Hash<Symbol, Object>)

    default values for (telnet) options

{
  port: 10023,
  command_prompt: "$ ",
  login_prompt: "login: ",
  password_prompt: "password: ",
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#custom_handlerProc, #call

custom handler of buffer content

Returns:

  • (Proc, #call)

    will be passed the content of the buffer



83
84
85
# File 'lib/em-simple_telnet_server.rb', line 83

def custom_handler
  @custom_handler
end

Class Method Details

.commandsHash{String, Regexp => Symbol, Proc}

Returns the Hash of registered commands. If they are not initialized yet (@commands), the one from superclass is used. If we’re TelnetServer itself, an empty Hash is used.

Returns:

  • (Hash{String, Regexp => Symbol, Proc})


60
61
62
63
64
65
66
# File 'lib/em-simple_telnet_server.rb', line 60

def commands
  @commands ||= if top_class?
    {}
  else
    superclass.commands.dup # copy from superclass
  end
end

.has_command(cmd, action = nil, &blk) ⇒ Object

Registers an action for the command cmd (which can be a Regexp, #=== will be used). action can be a Symbol referring to an instance method or an instance of Proc. If action is not specified, the given block is used.

If cmd is a Regexp, all captures (MatchData#captures) will be passed to the block/method call (see #run_command).

Parameters:

  • cmd (String, Regexp)

    fixed command or regular expression that matches a command and its arguments in capture groups

  • action (Symbol) (defaults to: nil)

    the method to call. if given, the block passed is ignored



51
52
53
# File 'lib/em-simple_telnet_server.rb', line 51

def has_command(cmd, action = nil, &blk)
  commands[cmd] = action || blk
end

.has_option(opt, value) ⇒ Object

Sets the option opt to value.

Parameters:

  • opt (Symbol)

    option key

  • value (Object)

    anything



25
26
27
# File 'lib/em-simple_telnet_server.rb', line 25

def has_option(opt, value)
  options[opt] = value
end

.optionsObject

Returns the (telnet) options for this class. If they are not initialized yet, the ones from superclass (or SimpleTelnetServer) are duplicated.



31
32
33
34
35
36
37
# File 'lib/em-simple_telnet_server.rb', line 31

def options
  @options ||= if top_class?
    DEFAULT_OPTIONS
  else
    superclass.options
  end.dup
end

.start_server(addr = 'localhost', port = options[:port]) ⇒ Object

Starts the server on address addr and port port.



18
19
20
# File 'lib/em-simple_telnet_server.rb', line 18

def start_server(addr = 'localhost', port = options[:port])
  EventMachine.start_server(addr, port, self)
end

.top_class?Boolean

Returns whether we’ve reached the top of the relevant hieararchy.

Returns:

  • (Boolean)

    whether we’ve reached the top of the relevant hieararchy



70
71
72
# File 'lib/em-simple_telnet_server.rb', line 70

def top_class?
  self == SimpleTelnetServer::Connection
end

Instance Method Details

#authorized?Boolean

Returns whether the user is logged in.

Returns:

  • (Boolean)

    whether the user is logged in



122
123
124
# File 'lib/em-simple_telnet_server.rb', line 122

def authorized?
  @connection_state == :authorized
end

#command_not_known(command) ⇒ Object

This method is abstract.

Called automatically when a received command is not known (no matching entry in @commands) and sends back an error message.

Parameters:

  • command (String)

    the command that is not known



136
137
138
# File 'lib/em-simple_telnet_server.rb', line 136

def command_not_known(command)
  send_output "Command #{command.inspect} is not known."
end

#commandsObject

Returns the recognized commands for this telnet server.



146
147
148
# File 'lib/em-simple_telnet_server.rb', line 146

def commands
  self.class.commands
end

#needs_authentication?Boolean

This method is abstract.

If authentication is not required, there won’t be a login procedure and any peer is automatically logged in after connecting.

Returns:

  • (Boolean)

    whether this telnet server requires authentication



106
107
108
# File 'lib/em-simple_telnet_server.rb', line 106

def needs_authentication?
  false
end

#optionsObject

Returns the telnet options for this telnet server.



141
142
143
# File 'lib/em-simple_telnet_server.rb', line 141

def options
  self.class.options
end

#post_initObject

Called by EventMachine when a new connection attempt is made to this server (immediately after calling #initialize).

Checks if #needs_authentication?, which returns false if not overridden. If it authentication is needed, it’ll initiate the login procedure (send login prompt, get username, get password, …).

Otherwise, any peer is authorized right away.



93
94
95
96
97
98
99
100
# File 'lib/em-simple_telnet_server.rb', line 93

def post_init
  @buffer = ""
  if needs_authentication?
    initiate_authentication
  else
    authorize # login anybody
  end
end

#receive_data(data) ⇒ Object

Called by EventMachine when new data is received. Appends data to the buffer (@buffer). Calls #process_buffer if @buffer content ends with newline.



113
114
115
116
117
118
119
# File 'lib/em-simple_telnet_server.rb', line 113

def receive_data data
#    warn "Server: <<< #{data.inspect}"
  @buffer << data

  # work only with complete commands (ending with newline)
  process_buffer if @buffer.end_with? "\n"
end

#unbindObject

This method is abstract.

Called by EventMachine after the connection has been closed.



128
129
# File 'lib/em-simple_telnet_server.rb', line 128

def unbind
end