New Version 2.6 brings FTPS (TLS/SSL) support.

Discussions related to FTPAPI (An FTP client package for RPG programming.) http://www.scottklement.com/ftpapi/
Post Reply
Scott Klement
Site Admin
Posts: 658
Joined: Sun Jul 04, 2021 5:12 am

New Version 2.6 brings FTPS (TLS/SSL) support.

Post by Scott Klement »

Hi All,

I've been hard at work improving FTPAPI, and am pleased to announce that it now provides support for "secure" FTP, aka FTPS, aka FTP over TLS. (TLS is the security protocol formerly known as "SSL")

Furthermore, FTPAPI source code is now managed via GitHub, making it easier for people to contribute if desired.
https://github.com/ScottKlement/ftpapi

As always, the latest version is available here:
https://www.scottklement.com/ftpapi/
Scott Klement
Site Admin
Posts: 658
Joined: Sun Jul 04, 2021 5:12 am

Re: New Version 2.6 brings FTPS (TLS/SSL) support.

Post by Scott Klement »

The primary difference in coding FTPS is extra parameters to the FTP_open() procedure to tell it to use secure control and data channels. For example:

Code: Select all

      /if defined(*CRTBNDRPG)
        ctl-opt dftactgrp(*no);
      /endif
        ctl-opt BNDDIR('FTPAPI');

      /copy FTPAPI_H

        dcl-s msg char(52);
        dcl-s sess int(10);

        // connect to FTP server. Setting FTPS_TLS will 
        // require the use of TLS (formerly known as "SSL")
        // to encrypt the connection

        sess = FTP_open( 'localhost'
                       : -1
                       : 15
                       : FTPS_TLS
                       : FTPS_PRIVATE
                       : FTPS_PRIVATE );
        if sess = -1;
          msg = ftp_errorMsg(0);
          dsply msg;
          *inlr = *on;
          return;
        endif;

        if FTP_login(sess: 'your userid': 'your password') = -1;
          msg = ftp_errorMsg(0);
          dsply msg;
          FTP_quit(sess);
          *inlr = *on;
          return;
        endif;
         

        FTP_binaryMode(sess: *on);
        FTP_passiveMode(sess: *on);

        if FTP_put( sess
                  : 'EXAMPLE.TXT'
                  : '/tmp/EXAMPLE.TXT') = -1;
          msg = ftp_errorMsg(0);
          dsply msg;
        endif;

        FTP_quit(sess);
        *inlr = *on;
The key part to notice is the FTP_open(), it looks like this:

Code: Select all

        sess = FTP_open( 'localhost'        // host to connect to
                       : -1                 // port number, -1 means "default"
                       : 15                 // timeout after 15 seconds
                       : FTPS_TLS           // Use TLS (FTPS_NONE for regular FTP)
                       : FTPS_PRIVATE       // control channel should be encrypted
                       : FTPS_PRIVATE );    // file transfers should be encrypted
Instead of FTPS_TLS you can alternately specify:
  • FTPS_NONE = (default) means to disable TLS completely -- so a regular FTP transfer.
  • FTPS_TLS = Connect normally and then ask the server to upgrade to TLS with 'AUTH TLS'. Equivalent to SECCNN(*SSL) in the IBM client.
  • FTPS_IMPLICIT = Connect with TLS to start with. Equivalent to SECCNN(*IMPLICIT) in the IBM client.
The 5th and 6th parameters are for the control channel (where commands such as "put" and "get" are sent) and data channels (where file data is transfered) respectively. They can be set to:
  • FTPS_PRIVATE = This channel use TLS encryption.
  • FTPS_CLEAR = This channel is unencrypted.
Note that not all FTP servers support all options. For example, the IBM FTP server does not support using an unencrypted control channel (unless you turn off TLS completely), but there are other servers that do, so FTPAPI offers the option. The 6th parameter works similarly to the IBM DTAPROT(*PRIVATE or *CLEAR) options.

FTP_open also has parameters to control how certificates are used and trusted in conjunction with the IBM Digital Certificate Manager (DCM). When not specified the default system options (in the *SYSTEM certificate store) are used, which is appropriate for most use cases. But parameters are provided for using an application ID so you can configure parameters in the DCM, or using your own custom keyring file.

For example, if you want to use the digital certificate manager to configure your FTP client under the application ID 'ACME_FTPCLIENT' you could do this:

Code: Select all

        sess = FTP_open( 'localhost'
                       : -1
                       : 15
                       : FTPS_TLS
                       : FTPS_PRIVATE
                       : FTPS_PRIVATE 
                       : 'ACME_FTPCLIENT' );
Or if you have your own keyring file with special settings, you could do this:

Code: Select all

        sess = FTP_open( 'localhost'
                       : -1
                       : 15
                       : FTPS_TLS
                       : FTPS_PRIVATE
                       : FTPS_PRIVATE 
                       : *OMIT
                       : '/usr/local/share/tls/EXAMPLE.KDB'
                       : 'monk3ybutt'
                       : 'ftpclient' );
The 8th parameter is the path to the keyring file in the IFS.
The 9th and 10th are the password (monk3ybutt) and label (ftpclient) respectively. The 9th and 10th parameters are optional -- if you don't need a password, you can omit the 9th. If you want to use the default label, you can omit the 10th.

NOTE: Don't use an application ID or custom keyring file unless you need it for a particular reason. More than 95% of use cases don't need them, so there is no need to complicate things.
Post Reply