Skip to main content

Use case examples

This section describes typical NanoSSH Client use cases and explains how to build applicable TrustCore SDK example code:

The NanoSSH Client shell provides a secured communication channel between two networked devices. The typical usage is to log in to a remote machine and execute commands, as shown below.

Figure 1.
nanossh-client-guide-figures_nanossh-client-shell-architecture.png

NanoSSH Client Shell Architecture


Build the shell access example code

  1. Add the NanoSSH client shell example code

    • Add the NanoSSH Client shell example code and supporting software, such as TrustCore SDK code, to the application’s development environment. Ensure to include the sshc_shell_example.c file.

    • Refer to: Adding TrustCore SDK Code to a Development Environment

  2. Port TrustCore SDK code

    • If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.

    • Refer to: Porting TrustCore SDK Code

  3. Configure login credentials

    • In the sshc_shell_example.c example code file, change the following login credential variable values to match the SSH server (such as NanoSSH Server or any other SSH server):

      • sshc_exampleUserName[]

      • sshc_examplePassword[]

      • sshc_exampleIPAddress

  4. Set compilation flags

    • Specify which features to be included in the NanoSSH Client executable by setting the appropriate compilation flags. For the NanoSSH Client shell example code, the basic flags include:

      • __ENABLE_MOCANA_SSH_CLIENT__

      • __ENABLE_MOCANA_EXAMPLES__

      • __ENABLE_MOCANA_SSH_RSA_SUPPORT__

    • The following flag must not be defined:

      • __ENABLE_MOCANA_SSH_FTP_CLIENT__

  5. Build the executable

    • Create the object files and executable using the following commands:

      • make -f make/Makefile.<os> clean

      • make -f make/Makefile.<os> sshc

    • See Building a NanoSSH Client Executable

  6. Verify the NanoSSH Clientexecution

    • Verify that the NanoSSH Client example code executes successfully in the environment.

    • See Verifying Communication between the Client Shell and the NanoSSH Server, Verifying NanoSSH Client Shell Communication with Any SSH Server

  7. Repeat steps 4 to 6 as needed to add features one at a time.

Verify communication between NanoSSH Client shell and NanoSSH Server

After building the NanoSSH code, verify that it executes in the operating environment. Assuming that the NanoSSH client and NanoSSH server (and the example code) have been enabled, the loopback interface may be used to confirm that the client and server are able to communicate within the operating environment.

If using only the NanoSSH client but not the NanoSSH server, see Verifying NanoSSH Client Shell Communication with Any SSH Server.

To verify communication between the client shell and the NanoSSH server:

  1. If necessary, open a command shell on the NanoSSH server (e.g., Cygwin).

  2. Change to the mss directory.

  3. Start the appropriate executable; for example, for NanoSSH Server:

    bin/sshs.exe
    

    Messages are displayed as processes and methods start up and run.

  4. Open a second shell (the client), and enter the following command to request a connection for the admin user:

    ssh admin@127.0.0.1
    

    The system prompts for the corresponding password.

  5. When prompted for the corresponding password, enter the default password, secure.

  6. When prompted to enter a new password, type any password; for example, new.

  7. When prompted to confirm the password, type it again. The client echoes Password changed and Password successfully changed.

  8. In the client window, press any keys. If they are echoed to the client window (i.e., if you can see what you are typing), asynchronous client-server communication is successful.

  9. Perform a graceful shutdown by entering the following command in the client window type:

    Bye!
    

    The client and server sessions end, and both command shells are closed.

Verify NanoSSH Client shell communication with any SSH server

It is recommended to verify basic NanoSSH Client communications with an SSH server before beginning custom code implementations. This process is easily done using the NanoSSH Client shell or SFTP example code, as follows.

The following procedure assumes that Cygwin is used to interface to a UNIX/Linux-like development system. For other environments, modify the commands accordingly.

To verify NanoSSH Client shell communication with any SSH server:

  1. Configure the NanoSSH Client example code:

    1. If the NanoSSH Client executable does not include the NanoSSH Client example code from the sshc_shell_example.c file, modify the makefiles to include this file.

    2. Define the necessary compiler flags in the moptions.h file.

    3. Open the sshc_shell_example.c file for editing and locate the following lines:

      static const char sshc_exampleUserName[] = "admin";
      static const char sshc_examplePassword[] = "secure";
      static const char *sshc_exampleIPAddress = "127.0.0.1";
      static const unsigned short sshc_exampleServerPort = 22;
      
    4. Edit the values so that they match the user’s credentials and system’s IP address, and then save and close the file.

    5. Rebuild the executable, making sure to do a clean build.

  2. Start the SSH server.

  3. Open a command shell and start the NanoSSH Client. The NanoSSH Client example code securely connects (via HTTPS) to the SSH server, dumps debug information to a temporary command prompt window, and then automatically terminates.

  4. Stop the SSH server.

Client shell integration flowchart

The following flowchart shows the NanoSSH Client shell integration. For detailed steps to customizing the NanoSSH Client shell implementation, see Customizing a NanoSSH client implementation.

Figure 2.
nanossh-client-shell-flowchart-01.png

NanoSSH Client shell flowchart


The NanoSSH SFTP Client enables secure writing (PUT) and retrieval (GET) of files to/from a remote machine; for example, to retrieve an updated image file from a server and to write a log file to the server, as shown below.

Figure 3.
nanossh-client-guide-figures_nanossh-client-secure-file-transfer-architecture.png

NanoSSH Client secure file transfer architecture


Build the SFTP example code

  1. Add the NanoSSH SFTP example code and supporting software (such as TrustCore SDK code) to the application development environment.

    • Be sure to include the sshc_example.c file.

  2. If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.

  3. In the sshc_example.c example code file, change the following login credential variable values to match the SSH server, which may be NanoSSH Server or any SSH server:

    • sshc_exampleUserName[]

    • sshc_examplePassword[]

    • sshc_exampleIPAddress

  4. Create the object files and executable. The commands are:

    • make -f make/Makefile.<os> clean

    • make -f make/Makefile.<os> sshc

  5. Verify that the TrustCore SDK NanoSSH SFTP Client example code executes in the environment.

  6. Repeat step 5 and step 6 as needed to add features one at a time.

Verifying NanoSSH Client SFTP communication with any SSH server

Be sure to verify basic NanoSSH SFTP Client communications with the SSH server before beginning custom code implementations. This process is easily done using the NanoSSH Client shell or SFTP example code, as follows:

  1. Open Cygwin and change to the directory where the TrustCore SDK distribution package ZIP file was extracted.

  2. If any source code or makefiles have been modified since the sshc target was last built, rebuild the executable:

    • ./script/nanossh/ssh_client/build_ssh_client_ncrypto.sh

  3. Run the example code executable:

    • ./bin/ssh_client

NanoSSH SFTP Client integration flowchart

The following flowchart shows the NanoSSH SFTP Client integration. For detailed steps to customizing the NanoSSH SFTP Client implementation, see Customize a NanoSSH Client Implementation.

Figure 4.
nanossh-sftp-client-process-flow-01.png

NanoSSH Client Secure File Transfer Protocol (SFTP) flowchart


NanoSSH Client port forwarding encrypts and decrypts TCP/IP traffic. A typical application, as shown in Figure 6 below, is for proprietary applications that are operating on distributed machines to securely communicate over any network or the Internet using TCP/IP.

Figure 5.
nanossh-client-guide-figures_nanossh-client-port-forwarding-architecture.png

NanoSSH Client port forwarding architecture


Building the port forwarding example code

  1. Add the NanoSSH port forwarding example code and supporting software (such as TrustCore SDK code) to the application development environment.

    • Be sure to include the sshc_pf_example.c file.

  2. If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.

  3. In the sshc_pf_example.c example code file, change the following values to match the environment’s:

    • CONNECT_HOST

    • sshc_exampleUserName[]

    • sshc_examplePassword[]

    • sshc_exampleIPAddress

  4. Create the object files and executable. The commands are:

    • make -f make/Makefile.<os> clean

    • make -f make/Makefile.<os> sshc

  5. Verify that the NanoSSH Client example code executes in the environment.

  6. Repeat step 5 and step 6 as needed to add features one at a time.

Client port forwarding integration flowchart

The following flowchart displays the NanoSSH Client port forwarding integration.

Figure 6.
nanossh-client-port-forwarding-process-flowchart-01.png

NanoSSH Client port forwarding process flowchart


SSH reverse port forwarding, also known as reverse tunneling or remote port forwarding, is a method that enables remote devices to initiate a connection with a device that is isolated from incoming connection requests, provided that such devices can make outgoing connections. This block of remotely initiated connections is typical for devices behind a firewall. It is also true for devices on a private network behind a router running NAT, although the underlying technical reasons for the isolation are different.

One way to get around this incoming isolation is for the isolated device to meet the remote devices half way. This meeting is enabled by setting up a half-way point and by connecting the isolated device to that half-way point. To connect the isolated device to the half-way point, set up a reverse-port-forwarding SSH client on the isolated device. To set up the half-way point itself, set up an SSH server configured to support both port-forwarding clients and reverse-port-forwarding clients. Then configure the isolated client to initiate and maintain a session with that SSH server on the publicly accessible machine. When a remote device wants to initiate a connection with the isolated device, the remote device opens a session with the publicly accessible SSH server. This SSH server then provides port forwarding services for the remote device to the isolated device, thus allowing externally initiated communication between the remote device and the isolated device.

So, why is the term reverse applied to this system when the communication is clearly two-way? In this scenario, convention takes the viewpoint of the isolated device. Although the isolated device is participating in a port-forwarding scenario, it did not initiate the tunnel over which the port forwarding takes place. From the viewpoint of the isolated device, the tunnel was requested by the remote device, which is seen as a reversal of the more typical port-forwarding scenario for an isolated device.

However, independent of which device initiates the tunnel, the tunnel is still an SSH-based port-forwarding scenario. Thus, when coding the SSH client for the isolated device, a port-forwarding SSH client is also coded, which means that, for the isolated client, callbacks must be registered for each of the standard port-forwarding SSH client events, in addition to the callbacks that must be registered to handle the reverse port-forwarding events.

Concerning the SSH client on the remote device, from the viewpoint of the remote device, it is involved in a typical port-forwarding use of SSH. Thus, when setting up that client, set it up as a typical port-forwarding SSH client.

Concerning the SSH server that mediates communication between the isolated and remote devices, it is an SSH port-forwarding server with a few extra callbacks to handle events specific to the reverse port-forwarding needs of the isolated device.

Building the Reverse Port Forwarding Example Code

  1. Add the NanoSSH reverse port forwarding example code and supporting software (such as TrustCore SDK code) to the application development environment.

    • Be sure to include the src/examples/sshc_rpf_example.c file.

  2. If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.

  3. In the sshc_rpf_example.c example code file, change the following values to match the environment’s:

    • CONNECT_HOST

    • sshc_exampleUserName[]

    • sshc_examplePassword[]

    • sshc_exampleIPAddress

  4. Use the sshc_rpf_example.c sample code’s implementation as-is or modify it as desired.

  5. Create the object files and executable. The commands are:

    • make -f make/Makefile.<os> clean

    • make -f make/Makefile.<os> sshc

  6. Verify that the NanoSSH Client example code executes in the environment.

  7. Repeat step 4 to step 6 as needed to add features one at a time.

Implementing Reverse Port Forwarding for a NanoSSH Client

  1. (Optional) Set up environment-specific thread support.

    • The example client creates a thread for each channel opened in the port-forwarding tunnel, and the code sets up lpfTable to track information about the open channels. To avoid thread conflicts, a mutex is used for access control.

  2. Initialize the NanoSSH Client’s session manager, internal structures, and NanoSSH Client-specific settings.

  3. Customize and register upcalls (callbacks) for all desired products and features:

    • Replace stub functions with the corresponding custom routines, modeling them after the NanoSSH Client example code.

    • Register the callbacks as required.

  4. Set up management for authentication keys.

  5. Set up a TCP/IP socket connection with the remote SSH server (NanoSSH or any SSH server).

  6. Initialize the SSH session context.

  7. (Optional) Customize the session establishment, such as to override the default choice of the strongest available cipher and specify a particular cipher suite instead.

  8. Set up a secure and authenticated SSH session with the remote server.

  9. If using the NanoSSH SFTP Client, open an SFTP session and negotiate SFTP version support.

  10. Send a remote port forwarding request to the SSH server to establish the client-server link.

    • The tunnel with a remote device is not established yet and not created until after the server uses the established client-server link to forward a connection request from a remote device.

  11. Verify that the client-server link was successfully established.

  12. Allocate the resources that the application needs for receiving data on the connection.

  13. Loop continuously to process messages from the SSH server and from local ports.

  14. Close the connection.

  15. Shut down the NanoSSH Client and reclaim device and NanoSSH Client resources.