Wednesday, 6 July 2022

SAP to SFTP simple Setup with a Windows Host

The aim of this blog is to give an easy way to setup an SFTP connection between a SAP system and an SFTP server.

Main problematic

As Said, SAP does not cover SFTP using SAPFTP. According to note 795131, the best solution is to use a third party software to do it and then call the third party software from SAP (using SM49/69 host command). Still, if the SAP system is running on a Unix Based system, everything is fine, because the syntax offered by Unix allow you to run SFTP command in Oneliner (using | eventually), but if the SAP system is running on a Windows NT based system, problems arise.

The native SFTP command cannot be used as a OneLiner. The impact of this is that you have to find a way to build a script able to connect to SFTP and then do action inside the SFTP native app.

Proposed solution

As describe in the blogs quoted before, one solution will be to use the free-to-use Winscp app. Winscp allow you to connect and to action on a remote SFTP within one line of command.

Prerequisites

1. Winscp needs to be installed on the server,

Step-by-Step Example

◉ Creation of the system command (SM69)

Assuming that Winscp is installed in a “classic” sort of way, here is the command that will allow the system to summon Winscp :

"C:\Program Files (x86)\WinSCP\WinSCP.exe" /command

SAP ABAP Exam Prep, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Certifications, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Preparation, SAP ABAP Learning
SM69 for the creation of System Command (Screenshot from own system)

◉ Building of a simple command “Put”

As described before, the goal is to have a Oneliner. It requests us to put all the arguments in the same time and in the correct order. Below a command example, we’ll detail it later on :

"C:\Program Files (x86)\WinSCP\WinSCP.exe" /command "open sftp://<user>:<password>@<host>:<remote_folder>" "put C:\Users\sapabap\testfile.txt testfile.txt" "exit"

The first part is already known and will be taken into accound by our SM69.

After that, comes the “open” :

"open sftp://<user>:<password>@<host>:<remote_folder>"

It speaks for itself, but to make it work : <user> must be a user with the access rights on the <host>, the password can be gived here. As the communication is done through SSH, we’ll consider it safe.

The remote folder is the SFTP path on which the file must be dropped. (Of course the “<” and “>” are not to be keeped in the final line.) On this step, it is also possible to connect to the root of the SFTP server and the give the location with the next command parameter : “put”.

The “put” :

"put C:\Users\sapabap\testfile.txt testfile.txt"

The first part is the file that is to be transfered and the second the name of file on the SFTP after transfer. It can be replace by “./”, to give the remote file the name of the file in the first paremeter.
Finally, we give a nice “exit” to cut the connection.

With all that, here is a list of command that are suggested to include as well :

"option batch on"
"option confirm off"
/log="E:\usr\sap\DEV\xxxxx\work\log_xfp.txt" /loglevel=0

The two first options comes at the beginning :

◉ Batch : Enables batch mode. In batch mode, any choice prompt is automatically replied and any input prompt is cancelled (after short time interval),
◉ confirm : Toggles confirmations (overwrite, etc.).

The last one is to put at the end of the command and allows you to have a log of each connection. Feel free to name it with time and date so it wont be increased each time, or clear it regularly.

◉ Security Matters

At this point, the command can be successful only if the public key of the SFTP server is known by our system (Windows). To make this public key known, simply connect to the SFTP using the Visual Interface of Winscp (it will create the correct entry in the Registry) :

SAP ABAP Exam Prep, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Certifications, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Preparation, SAP ABAP Learning
WinScp Visual Interface (Screenshot from own system)

Now, let say the public key is subject to changes or it is impossible to access Winscp visual interface. We still have a card up our sleeve, but its a possibility that is definitely not good for the security :

-hostkey=*

This will be used like :

"open sftp://<user>:<password>@<host>:<remote_folder> -hostkey=*"

Meaning any hostkey will be accepted. Another possibility is to give the real hostkey surrunded by quotes and not a “*”.

◉ ABAP Application

    DATA :
          lv_open_cmd TYPE string,
          lv_put_cmd TYPE string,
          lv_log_cmd TYPE string,
          lv_param TYPE sxpgcolist-parameters,
          lv_exitcode TYPE btcxpgexit,
          lt_protocol TYPE TABLE OF btcxpm.

    CONCATENATE '"open sftp://' lv_userid ':' lv_password '@' lv_host ':'
    lv_remote_dir ' -hostkey=*"' INTO lv_open_cmd.

    CONCATENATE '"put' lv_path_file_to_transfer lv_filename INTO lv_put_cmd SEPARATED BY space.
    CONCATENATE lv_put_cmd '"' INTO lv_put_cmd.

    CONCATENATE '/log="\\saprouter\INTERFACE\' sy-sysid 'E:\usr\sap\DEV\xxxxx\work\log_xfp.txt" /loglevel=0' INTO lv_log_cmd.

    CONCATENATE
      '"option batch on"'
      '"option confirm off"'
      lv_open_cmd
      lv_put_cmd
      '"exit"'
      lv_log_cmd
      INTO lv_param SEPARATED BY space.

    CALL FUNCTION 'SXPG_COMMAND_EXECUTE'
      EXPORTING
        commandname                   = 'ZSFTP_WINSCP'
        additional_parameters         = lv_param
      IMPORTING
        exitcode                      = lv_exitcode
      TABLES
        exec_protocol                 = lt_protocol
      EXCEPTIONS
        no_permission                 = 1
        command_not_found             = 2
        parameters_too_long           = 3
        security_risk                 = 4
        wrong_check_call_interface    = 5
        program_start_error           = 6
        program_termination_error     = 7
        x_error                       = 8
        parameter_expected            = 9
        too_many_parameters           = 10
        illegal_command               = 11
        wrong_asynchronous_parameters = 12
        cant_enq_tbtco_entry          = 13
        jobcount_generation_error     = 14
        OTHERS                        = 15.

◉ Variables :
    ◉ lv_userid – username on the SFTP server,
    ◉ lv_password – password on the SFTP server,
    ◉ lv_host – Hostname or IP adress of the SFTP server,
    ◉ lv_remote_dir – The directory on the SFTP server on which the file should be transfered
    ◉ lv_path_file_to_transfer – Complete path of the file on the SAP Server to be transfered,
    ◉ lv_file – The name the file should have on the SFTP server,

After the execution of “SXPG_COMMAND_EXECUTE”, the variable “exitcode” should be valuated at 0, if not something append.

Once, an error is identified, we can use the table “exec_protocol” and we can analyse it with few keywords, but unfortunately Winscp does not give so much information outside of the log.

A way to achieve the analysis of error is maybe to read the log file.

In anycase, if the connection fail, the “exec_protocol” will be filled, here is a sample abap code that check some keywords in it :

FORM ANALYSE_PROTOCOL using p_filename TYPE char20
                                p_serverfilepath TYPE char200
                                p_ftp_dir TYPE char200
                                pt_protocol TYPE LCA_TRACEFILE_TAB
                       changing pv_subrc TYPE sy-subrc.

  DATA: ls_protocol TYPE btcxpm .
  pv_subrc = 9. "Faulty until anything is proved
  LOOP AT pt_protocol INTO ls_protocol.
*Connection error -> rc = 1
*Network error:
*Authentication failed
*Host myhost does not exist
    IF ls_protocol-message CS 'Network error:' OR
       ls_protocol-message CS 'Authentication failed' OR
       ( ls_protocol-message CS 'Host' AND
         ls_protocol-message CS 'does not exist' ).
      pv_subrc = 1.
      EXIT.
    ENDIF.
*cannot access directory ftp / sap
*Error changing directory to
    IF ls_protocol-message CS 'Error changing directory to'.
      IF ls_protocol-message CS p_serverfilepath.
        pv_subrc = 4.
        EXIT.
      ELSEIF ls_protocol-message CS p_ftp_dir.
        pv_subrc = 2.
        EXIT.
      ENDIF.
    ENDIF.
    IF ls_protocol-message CS p_filename.
"There is a line with the filename
      IF ls_protocol CS '100%'. "file 100% transfered
        pv_subrc = 0.
      ELSEIF ls_protocol CS 'No file matching' AND
             ls_protocol CS 'Found'.
*fail to read the file
        pv_subrc = 5.
      ENDIF.
    ENDIF.
  ENDLOOP.

ENDFORM.                    " ANALYSE_PROTOCOL

No comments:

Post a Comment