Git Product home page Git Product logo

telnetsrvlib's Introduction

telnetsrvlib

Telnet server using gevent or threading.

Copied from http://pytelnetsrvlib.sourceforge.net/ and modified to support gevent and eventlet, better input handling, clean asynchronous messages and much more. Licensed under the LGPL, as per the SourceForge notes.

This library allows you to easily create a Telnet or SSH server powered by your Python code. The library negotiates with a Telnet client, parses commands, provides an automated help command, optionally provides login queries, then allows you to define your own commands. An optional SSH handler is provided to wrap the defined Telnet handler into an SSH handler.

You use the library to create your own handler, then pass that handler to a StreamServer or TCPServer to perform the actual connection tasks.

This library includes two flavors of the server handler, one uses separate threads, the other uses greenlets (green pseudo-threads) via gevent or eventlet.

The threaded version uses a separate thread to process the input buffer and semaphores reading and writing. The provided test server only handles a single connection at a time.

The green version moves the input buffer processing into a greenlet to allow cooperative multi-processing. This results in significantly less memory usage and nearly no idle processing. The provided test server handles a large number of connections.

Install

telnetsrv is available through the Cheeseshop. You can use easy_install or pip to perform the installation.

easy_install telnetsrv

or

pip install telnetsrv

Note that there are no dependancies defined, but if you want to use the green version, you must also install gevent or eventlet. If you wish to use the SSH server, you must also install paramiko.

To Use

Import the TelnetHandler base class and command function decorator from either the green class, evtlet class or threaded class, then subclass TelnetHandler to add your own commands which are methods decorated with @command.

Threaded

Green

Eventlet

Adding Commands

Commands can be defined by using the command function decorator.

Old Style

Commands can also be defined by prefixing any method with "cmd". For example, this also creates an echo command:

This method is less flexible and may not be supported in future versions.

Command Parameters

Any command parameters will be passed to this function automatically. The parameters are contained in a list. The user input is parsed similar to the way Bash parses text: space delimited, quoted parameters are kept together and default behavior can be modified with the \ character. If you need to access the raw text input, inspect the self.input.raw variable.

Telnet Server> echo 1  "2    3"
Telnet Server> echo 1 \
... 2 "3
... 4"  "5\
... 6"
Telnet Server> echo 1\ 2

Command Help Text

The command's docstring is used for generating the console help information, and must be formatted with at least 3 lines:

  • Line 0: Command parameter(s) if any. (Can be blank line)
  • Line 1: Short descriptive text. (Mandatory)
  • Line 2+: Long descriptive text. (Can be blank line)

If there is no line 2, line 1 will be used for the long description as well.

Telnet Server> help
? [<command>] - Display help
BYE - Exit the command shell
ECHO <text to echo> - Echo text back to the console.
...


Telnet Server> help echo
ECHO <text to echo>

This command simply echos the provided text
back to the console.
Telnet Server>

Command Aliases

To create an alias for the new command, set the method's name to a list:

The decorator may be stacked, which adds each list to the aliases:

Hidden Commands

To hide the command (and any alias for that command) from the help text output, pass in hidden=True to the decorator:

The command will not show when the user invokes help by itself, but the detailed help text will show if the user invokes help echo.

When stacking decorators, any one of the stack may define the hidden parameter to hide the command.

Console Information

These will be provided for inspection.

TERM

String ID describing the currently connected terminal

WIDTH

Integer describing the width of the terminal at connection time.

HEIGHT

Integer describing the height of the terminal at connection time.

username

Set after authentication succeeds, name of the logged in user. If no authentication was requested, will be None.

history

List containing the command history. This can be manipulated directly.

Console Communication

Send Text to the Client

Lower level functions:

self.writeline( TEXT )

self.write( TEXT )

Higher level functions:

self.writemessage( TEXT ) - for clean, asynchronous writing. Any interrupted input is rebuilt.

self.writeresponse( TEXT ) - to emit a line of expected output

self.writeerror( TEXT ) - to emit error messages

The writemessage method is intended to send messages to the console without interrupting any current input. If the user has entered text at the prompt, the prompt and text will be seamlessly regenerated following the message. It is ideal for asynchronous messages that aren't generated from the direct user input.

Receive Text from the Client

self.readline( prompt=TEXT )

Setting the prompt is important to recreate the user input following a writemessage interruption.

When requesting sensitive information from the user (such as requesting a new password) the input should not be shown nor should the input line be written to the command history. readline accepts two optional parameters to control this, echo and use_history.

self.readline( prompt=TEXT, echo=False, use_history=False )

When echo is set to False, the input will not echo back to the user. When use_history is set to False, the user will not have access to the command history (up arrow) nor will the entered data be stored in the command history.

Handler Options

Override these class members to change the handler's behavior.

PROMPT

Default: "Telnet Server> "

CONTINUE_PROMPT

Default: "... "

WELCOME

Displayed after a successful connection, after the username/password is accepted, if configured.

Default: "You have connected to the telnet server."

session_start(self)

Called after the WELCOME text is displayed.

Default: pass

session_end(self)

Called after the console is disconnected.

Default: pass

authCallback(self, username, password)

Reference to authentication function. If this is not defined, no username or password is requested. Should raise an exception if authentication fails

Default: None

authNeedUser

Should a username be requested?

Default: False

authNeedPass

Should a password be requested?

Default: False

Handler Display Modification

If you want to change how the output is displayed, override one or all of the write classes. Make sure you call back to the base class when doing so. This is a good way to provide color to your console by using ANSI color commands. See http://en.wikipedia.org/wiki/ANSI_escape_code

  • writemessage( TEXT )
  • writeresponse( TEXT )
  • writeerror( TEXT )

Serving the Handler

Now you have a shiny new handler class, but it doesn't serve itself - it must be called from an appropriate server. The server will create an instance of the TelnetHandler class for each new connection. The handler class will work with either a gevent StreamServer instance (for the green version) or with a SocketServer.TCPServer instance (for the threaded version).

Threaded

Green

The TelnetHandler class includes a streamserver_handle class method to translate the required fields from a StreamServer, allowing use with the gevent StreamServer (and possibly others).

Short Example

SSH

If the paramiko library is installed, the TelnetHanlder can be used via an SSH server for significantly improved security. paramiko_ssh contains SSHHandler and getRsaKeyFile to make setting up the server trivial. Since the authentication is done prior to invoking the TelnetHandler, any authCallback defined in the TelnetHandler is ignored.

Green

If using the green version of the TelnetHandler, you must use Gevent's monkey patch_all prior to importing from paramiko_ssh.

Eventlet

If using the eventlet version of the TelnetHandler, you must use Eventlet's monkey patch_all prior to importing from paramiko_ssh.

Operation Overview

The SocketServer/StreamServer sets up the socket then passes that to an SSHHandler class which authenticates then starts the SSH transport. Within the SSH transport, the client requests a PTY channel (and possibly other channel types, which are denied) and the SSHHandler sets up a TelnetHandler class as the PTY for the channel. If the client never requests a PTY channel, the transport will disconnect after a timeout.

SSH Host Key

To thwart man-in-the-middle attacks, every SSH server provides an RSA key as a unique fingerprint. This unique key should never change, and should be stored in a local file or a database. The getRsaKeyFile makes this easy by reading the given key file if it exists, or creating the key if it does not. The result should be read once and set in the class definition.

Easy way:

host_key = getRsaKeyFile( FILENAME )

If the FILENAME can be read, the RSA key is read in and returned as an RSAKey object. If the file can't be read, it generates a new RSA key and stores it in that file.

Long way:

SSH Authentication

Users can authenticate with just a username, a username/publickey or a username/password. Up to three callbacks can be defined, and if all three are defined, all three will be tried before denying the authentication attempt. An SSH client will always provide a username. If no authCallbackXX is defined, the SSH authentication will be set to "none" and any username will be able to log in.

authCallbackUsername(self, username)

Reference to username-only authentication function. Define this function to permit specific usernames to log in without any futher authentication. Raise any exception to deny this authentication attempt.

If defined, this is always tried first.

Default: None

authCallbackKey(self, username, key)

Reference to username/key authentication function. If this is defined, users can log in the SSH client automatically with a key. Raise any exception to deny this authentication attempt.

Default: None

authCallback(self, username, password)

Reference to username/password authentication function. If this is defined, a password is requested. Raise any exception to deny this authentication attempt.

If defined, this is always tried last.

Default: None

SSHHandler uses Paramiko's ServerInterface as one of its base classes. If you are familiar with Paramiko, feel free to instead override the authentication callbacks as needed.

Short SSH Example

Longer Example

See https://github.com/ianepperson/telnetsrvlib/blob/master/test.py

telnetsrvlib's People

Contributors

gooseyard avatar ianepperson avatar kjoconnor avatar yakxxx avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.