Telnet Daemon

Jump to: navigation, search

Table of Contents >> Application Reference


The TELNETD Application Program Interface allows the user to run a TELNET server. It consists of two parts:

  1. User to TELNET Server Interface:
    The user interface allows the user to start/stop a TELNET server to allow/stop remote TELNET clients to connect and login to the server. It also allows the user to send data to each connected TELNET client.
  2. TELNET Server to User Interface:
    The TELNET server to user interface allows the TELNET server to notify the user of incoming connections. It also allows a TELNET server to hand data received from each connected TELNET client to the user, after NVT conversion has been performed by the TELNET server.

There are two distinct styles of User to TELNET Server API:

  1. Single Server model:
    This is the standard Treck interface that allows the user to run one TELNET server only. The server handle is implied and is omitted from the Single Server API functions.
  2. Multiple Server model:
    This is an enhancement that allows the user to create multiple TELNET servers and control each separately. The user receives a unique server handle for each server created. The user specifies the server handle when calling one of the Multiple Server API functions.

Code Configuration

If you have purchased the Treck TELNET server option, all features described on this page will be available, by default. If, for some reason, you wish to remove the Treck TELNET server code from your application, uncomment the following compile time macro in your trsystem.h module.

#define TM_DISABLE_TELNETD

The following definition specifies the default maximum number of servers. It tells Treck how big the array of TELNET server handles needs to be. By default, Treck supports one server handle (the Single Server model). You can override the default by defining a different value in your trsystem.h module, or by calling tfTeldUserInit() to allocate a new handle array.

#define TM_TELD_DEF_MAX_SERVERS   1

The following definition specifies the periodic interval (in seconds) that the TELNET server will test an idle connection by sending the TELNET Are-You-There (AYT) signal. As long as the TELNET client responds appropriately, it will remain connected. The default interval is 5 minutes (300 seconds). You can increase this value at runtime by calling tfTeldUserIdleTimeout(). If you wish to decrease the interval or change the default behavior, define this macro in your trsystem.h module to suit your needs.

#define TM_TELD_MIN_IDLE_TIMEOUT  300

User to TELNET Server Interface

The following API functions are provided by Treck in the User to TELNET Server Interface. The API is grouped into 3 sections.

The Single Server and Multiple Server models are distinctly different and the API functions cannot be used interchangeably. The two models are discussed in separate sections below. Choose the appropriate section for your needs.

A third section below discusses the TELNET connection API. This part of the API is independent of the server model. The functions provide interaction with TELNET clients.

Single Server API

The Single Server API is described below. It is the default mode of operation for the Treck TELNETD package. The functions are distinguishable from the Multiple Server API in that they don't take a server handle as a parameter. The Single Server handle exists, but is implied in each of the functions below.

  • tfTeldUserStart()
    The user calls tfTeldUserStart() to open a TELNET server socket and start listening for incoming connections. tfTeldUserStart() can be either blocking or non-blocking, as specified by its last parameter.
    Blocking Mode
    In blocking mode, tfTeldUserStart() should be called from a task. tfTeldUserStart() will return only when the user calls tfTeldUserStop() or an error occurs. It will block, wait for incoming connections, and execute the TELNET server code in the context of the calling task. Choose blocking mode if you are using a multitasking RTOS/Kernel.
    Non-Blocking Mode
    In non-blocking mode, tfTeldUserStart() will return immediately after listening for incoming connections. It is the user's responsibility to then call tfTeldUserExecute() periodically to execute the TELNET server code. Choose non-blocking mode if you do not have a multitasking RTOS/Kernel.
  • tfTeldUserIdleTimeout()
    This function allows the user to set a Telnet connection's idle timeout to a value larger than the default (TM_TELD_MIN_IDLE_TIMEOUT). This specifies the rate at which the server will ping the client by sending a TELNET AYT signal. If the client does not respond appropriately, it will be disconnected.
Note Note: The Single Server functions discussed above are not available if you have chosen to use the Multiple Server model (you have set the number of servers greater than 1 via the TM_TELD_DEF_MAX_SERVERS macro or tfTeldUserInit() call).

Multiple Server API

The Multiple Server API is described below. The functions are distinguishable from the Single Server API in that they either return or require a TELNET server handle. You get a unique server handle for each server that you create.

The Multiple Server API has the following differences from the Single Server API:

  1. You can create more than one TELNET server.
  2. The server create, bind and start operations are separate to allow for greater flexibility and server customization.
  3. All server control functions require you to provide the handle returned from the server create function.
  4. You can choose different port, IP address, protocol (IPv4 or IPv6 only) and device bindings for each of your servers.
  5. You can enable SSL for any or all of your servers.
  6. You can adjust the server and socket settings prior to starting the server.
  7. You can have any combination of blocking and non-blocking servers.

The following functions are available if you are using the Multiple Server model:

  • tfTeldUserInit()
    Initialize the Treck TELNET server subsystem and set the maximum number of TELNET servers. This function must be called prior to using any of the Multiple Server functions discussed below.
  • tfTeldUserCreate()
    Create a TELNET server object but do not start it. This function returns a handle to the server object created. The handle can be used with any of the Multiple Server functions discussed below.
  • tfTeldUserExecuteHandle()
    Start or run a TELNET server. For a non-blocking server, the user must call this function periodically. The responsiveness of your TELNET server depends on how frequently you call tfTeldUserExecuteHandle(). A blocking server will tend to be more responsive because the task in which the server runs will be awakened as soon as there is some work to do. The operation of this function depends on how the server was created:
    Blocking Mode
    In blocking mode, tfTeldUserExecuteHandle() should be called from a task. tfTeldUserExecuteHandle() will return only when the user calls tfTeldUserStopHandle() or an error occurs. It will block, wait for incoming connections, and execute the TELNET server code in the context of the calling task.
    Non-Blocking Mode
    In non-blocking mode, tfTeldUserExecuteHandle() must be called periodically to execute the TELNET server code.
  • tfTeldUserStopHandle()
    Stop a server and release all it's resources. This function will close the server socket and kill all existing connections associated with the TELNET server. This call will force a blocking mode tfTeldUserExecuteHandle() call to wake up and return to its caller.
  • tfTeldUserIdleTimeoutHandle()
    Set the connection idle timeout for a server to a value larger than the default (TM_TELD_MIN_IDLE_TIMEOUT). This specifies the rate at which the server will send a TELNET AYT signal to ping its clients. If a client does not respond appropriately, it will be disconnected.
  • tfTeldUserSetOption()
    Set an option or change the default behavior of a TELNET server. For example, you can change the maximum number of connections and maximum connection backlog for a server.
  • tfTeldUserSetSockopt()
    Set an option or change the default behavior of a TELNET server socket. This gives you direct access to the underlying listening socket for a server. For example, you can bind a server to a particular interface by using the same SO_BINDTODEVICE parameters that setsockopt() uses.
Note Note: Some settings cannot be changed after you have called tfTeldUserExecuteHandle() to start the server. Please refer to the detailed function pages for restrictions.

Connection API

The following functions operate the same for Single Server and Multiple Server models. They operate on TELNET connection handles.

  • tfTeldUserSend()
    The user calls tfTeldUserSend() to send data to a specified TELNET client. The TELNET server will perform the NVT conversion before sending the data on the network.
  • tfTeldUserStartSsl()
    Start an SSL server session on a TELNET connection that is currently unsecure. This allows the user's TELNET server application to provide a way of supporting explicit SSL via some agreed upon request and response interaction with the client (e.g. START_SSL command by the client and Okay, going secure reply by the server application). This is not to be confused with the implicit SSL support provided by tfTeldUserSetSsl() above.
  • tfTeldSendQueueBytes()
    Returns the number of bytes currently in the TCP socket send queue for this TELNET session.
  • tfTeldSendQueueSize()
    Returns the total size of the TCP socket send queue for this TELNET session.
  • tfTeldUserStorePointer()
    Associate a user-defined pointer value with a TELNET connection handle. If the user wants to maintain separate state information for each incoming connection, this is a good way to accomplish that goal.
  • tfTeldUserGetPointer()
    Retrieve the user-defined pointer value associated with a TELNET connection handle.

TELNET Server to User Interface

The following API functions must be provided by you. Treck will call the associated function below whenever a TELNET client connects, disconnects or sends application data (the TELNET protocol exchange is transparent to the application).

  • tfTeldIncoming()
    Call provided by the user, and called by the TELNET server. The TELNET server calls tfTeldIncoming() to give data received from a specified TELNET client, to the user. The TELNET server performs the NVT conversion before handing the data to the user.
  • tfTeldClosed()
    Call provided by the user, and called by the TELNET server. The TELNET server calls tfTeldClosed() to inform the user that a specified TELNET client closed the connection.

Using SSL with the Treck TELNET Server

The Treck TELNET Server package supports TELNET over SSL in both implicit and explicit SSL forms.

Implicit SSL suggests that the TELNET client knows that the port it is connecting to is inherently secure. The SSL handshake takes place prior to the initial TELNET protocol interchange between client and server. Treck supports this via the Multiple Server API function tfTeldUserSetSsl(). The standard port for a TELNET over SSL server to listen on is 992.

Explicit SSL occurs sometime after (or maybe during) the initial TELNET protocol interchange between client and server. It requires some form of synchronization between server and client to ensure that all in-flight data has been received and processed by both ends. Various TELNET proposals exist for handling this synchronization: AUTH SSL and START_TLS, for example. Treck does not support explicit SSL at the TELNET protocol level. However, explicit SSL is supported at the application level via function tfTeldUserStartSsl().

The following example demonstrates the calling sequence you might use to create a TELNET over SSL server supporting implicit SSL. For more details, refer to the Treck SSL Programmer's Reference.

    . . .
/* Initialize the TELNET package */
    errorCode = tfTeldUserInit(...);
    . . .
/* Create a TELNET server */
    serverHandle = tfTeldUserCreate(...);
    . . .
/* Bind to the default TELNET address */
    errorCode = tfTeldUserBind(serverHandle, NULL);
    . . .
 
#ifdef TM_USE_SSL_SERVER
/* Enable PKI */
    errorCode = tfUsePki();
    . . .
/* Add CA's certificate */
    errorCode = tfPkiCertificateAdd(...);
    . . .
/* Add TELNET over SSL server's private key and public key pair */
    errorCode = tfPkiOwnKeyPairAdd(...);
    . . .
/* Add TELNET over SSL server's certificate */
    errorCode = tfPkiCertificateAdd(...);
    . . .
/* Enable SSL */
    errorCode = tfUseSsl(...);
    . . .
/* Create the server SSL session id (can be shared by all servers) */
    sslSessionId = tfSslNewSession(...);
    . . .
/* Enable TELNET over SSL. All incoming connections will be secure. */
    errorCode = tfTeldUserSetSsl(serverHandle, sslSessionId);
    . . .
/*
 * optional. User may call tfTeldUserSetSockopt() directly to change
 * SSL option value, such as TM_TCP_SSL_SEND_MIN_SIZE,
 * TM_TCP_SSL_SEND_MAX_SIZE, TM_TCP_SSLSESSION or TM_TCP_SSL_SERVER.
 */
    errorCode = tfTeldUserSetSockopt(...);
#endif /* TM_USE_SSL_SERVER */
 
/* Accept connections */
    errorCode = tfTeldUserExecuteHandle(serverHandle);
    . . .

The following example demonstrates the calling sequence you might use to create a TELNET over SSL server supporting explicit SSL. For more details, refer to the Treck SSL Programmer's Reference.

int myTelnetServer(...)
{
    . . .
/* Initialize the TELNET package */
    errorCode = tfTeldUserInit(...);
    . . .
/* Create a TELNET server */
    serverHandle = tfTeldUserCreate(...);
    . . .
/* Bind to the default TELNET address */
    errorCode = tfTeldUserBind(serverHandle, NULL);
    . . .
/* Accept connections */
    errorCode = tfTeldUserExecuteHandle(serverHandle);
    . . .
}
 
int tfTeldIncoming(ttUserTeldHandle teldHandle, ...)
{
    . . .
 
#ifdef TM_USE_SSL_SERVER
    if (cmdStartSSL)
    {
/* Enable PKI */
        errorCode = tfUsePki();
        . . .
/* Add CA's certificate */
        errorCode = tfPkiCertificateAdd(...);
        . . .
/* Add TELNET over SSL server's private key and public key pair */
        errorCode = tfPkiOwnKeyPairAdd(...);
        . . .
/* Add TELNET over SSL server's certificate */
        errorCode = tfPkiCertificateAdd(...);
        . . .
/* Enable SSL */
        errorCode = tfUseSsl(...);
        . . .
/* Create the server SSL session id */
        sslSessionId = tfSslNewSession(...);
        . . .
/* Tell the peer to start client-side SSL */
        errorCode = tfTeldUserSend(teldHandle, "Okay, going secure now!\r\n", ...);
        . . .
/* Enable TELNET over SSL */
        errorCode = tfTeldUserStartSsl(teldHandle, sslSessionId);
        . . .
/* The next message to the client will be encrypted */
        errorCode = tfTeldUserSend(teldHandle, "Connection is secure.\r\n", ...);
    }
#endif /* TM_USE_SSL_SERVER */
 
    . . .
}

Function Calls


Table of Contents >> Application Reference