Plan a NanoSSH Server example implementation
Before beginning to build the TrustCore SDK NanoSSH server or even selecting which example code to build for evaluation and testing, decide which features are needed:
Select between the synchronous or asynchronous SSH server (see Q1: Synchronous or Asynchronous?).
For synchronous implementations, see the following sections:
Architecture
Figure 1 below shows a typical setup for using NanoSSH server to implement a secure CLI.
Synchronous vs asynchronous
TrustCore SDK NanoSSH server supports both synchronous and asynchronous message handling. If a system is socket-based (e.g., using TCP/IP), the synchronous methods should be used. For everything else (e.g., TCB, event-driven, callback-based, and asynchronous stacks), use the asynchronous methods.
The first decision to make is whether to use the synchronous or asynchronous version of TrustCore SDK NanoSSH server.
Begin by assuming that the synchronous version is used because it is generally easier to integrate; however, if any of the following conditions apply, the asynchronous version must be used instead:
The existing system is event-driven or callback-based.
The existing TCP/IP stack is TCB-based or similar asynchronous stack.
Multiple user sessions per thread are required.
A thread shortage is expected.
A threadless operation required.
Additional considerations include:
The synchronous version’s initial negotiation locks the thread until negotiation is complete; asynchronous version does not.
The asynchronous version is more efficient than synchronous version.
Synchronous receive method
If using the synchronous NanoSSH server functions, decide whether to stream the message data (enabling receipt and buffering of partial messages) or receive messages in their entirety.
Receive streamed message data: Recommended for easier integration.
Use the SSH_recv function, available in NanoSSH server release 2.02 and later.
Requires the
__ENABLE_MOCANA_SSH_STREAM_API__
flag to be defined.
Receive entire messages: Provided to support custom streaming implementations.
Use the SSH_recvMessage function, available in all NanoSSH server releases.
The
__ENABLE_MOCANA_SSH_STREAM_API__
flag must not be defined.
TrustCore SDK SSH functions vs pipes vs sockets
When using the synchronous version of NanoSSH server, there are several options for making communication calls from the CLI application’s code:
Call only TrustCore SDK SSH API functions
Create and manage sockets
Create and manage pipes
For the lightest system load, TrustCore SDK recommends calling the NanoSSH API functions, which are socket-like. Depending on the operating system, NanoSSH functions may use only half as many threads as a pipe or socket solution. For example code, refer to examples/ssh_example.c.
If the CLI application is legacy code that contains many send and receive calls, is relatively unstructured, or is difficult to modify, NanoSSH integration may be easier if the CLI application is treated as a black box by using either of the following techniques:
Replace existing CLI communication calls with TrustCore SDK macros that wrap the NanoSSH API (socket-like) functions; see Using Socket-Wrapper Macros.
Implement the NanoSSH server as a proxy using pipes to communicate with the CLI application; see Using Pipes.
Use socket-wrapper macros
The easiest approach to using sockets is to replace the legacy code’s function calls to accept(), send(), recv(), and close() with their corresponding TrustCore SDK macros, ACCEPT(), SEND(), RECV(), and CLOSE(). For example code, refer to ssh_wrapper.c in the examples directory.
Using pipes
Although pipes increase the system load and may be used only for intra-process communication, they are necessary if any of the following are used:
Generic debug shell (such as VxWorks debug shell)
Code directs output to stdin, stdout, and stderr
Binary shell (such as Telnet)
For example code that shows how to create and manage pipes, refer to examples/ssh_pipe.c.
To integrate the TrustCore SDK pipe code, be sure to modify the NanoSSH server as follows:
Disable authentication. The NanoSSH client, functioning as a proxy in this scenario, prompts the user for authentication credentials.
Listen only on the loopback interface (127.0.0.1) to prevent a security hole that would allow an intruder to bypass the login procedure.