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.
The main problem we face for this using standard SAP is described in note : 795131 – FAQ: SAPFTP cannot perform secure FTP communication.
This subject has also been covered by many blogs. Although these various blogs are good, what is proposed here is a way to do it without any constraints. The great blogs : https://blogs.sap.com/2013/10/03/write-file-on-sftp-server-from-sap/ already describe the solution of this present blog, only it does not give a step by step solution.
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.
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.
- Winscp needs to be installed on the server,
- 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
- 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” :
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) :
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 :
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,
- Variables :
After the execution of “SXPG_COMMAND_EXECUTE”, the variable “exitcode” should be valuated at 0, if not something append (Thanks to Franz Seidl for this info).
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
Winthin a Windows environnement it’s quite difficult to achieve SFTP exchange from SAP. Luckily some freeware, as such as WinSCP, are good enough to give us workaround for this situation.
We cannot be sure whether or not, FTP and SFTP will still be present in the near future but, many actual installation use FTP and will certainly migrate to another technology for security purpose in the next years. For them SFTP seems like a good choice.
If you have encountered similar situation and have faced it with another solution, please share in comments.
Also, if you have any question regarding the implementation of this solution, please submit your interrogations via comments.
Also check the very good blog : https://blogs.sap.com/2013/10/03/write-file-on-sftp-server-from-sap/ which we already talked about. It contains very useful tips about WinScp and the basics for starting using these technology within SAP.
suresh kumar ‘s blog : https://blogs.sap.com/2020/07/10/configuration-and-testing-sftp-and-ftp-in-cpi/ is also a good starter for understanding ftp and sftp.
That’s all for this topic. I hope it’ll help you the next time you face SFTP connection.
Thanks for your time ! If possible, I’ll try to write other blog post on data exchange problematics !
Thank you for this nice post.
Instead of parsing exec_protocol couldn't you use exitcode? By convention it is 0 if a command was successful and <> 0 if there was an error. As far as I quickly investigated WinSCP.exe sets the exitcode.
Thanks for your comment !
It's a good idea, nevertheless during my tests, I discovered that if the problem was only related to SFTP, FM SXPG_COMMAND_EXECUTE will return 0 in sy-subrc.
After reading your comment, I made a test : I try execute a perfectly working command but with a wrong password :
Maybe it is related to the version of SXPG_COMMAND_EXECUTE, mine is from 21.05.2010.
Please let me know what you get with your tests,
did you checked the exporting parameter "exitcode" of SXPG_COMMAND_EXECUTE (not sy-subrc)?
Sorry, I can't test it at my side. But your post was interesting for me, because we also implemented a SFTP interface some years ago. My colleague solved it with a script on our Linux host (I think it is called outside SAP with a crontab).
But I think your solution with an external program/SXPG_COMMAND_EXECUTE is much cleaner.
Indeed the "exitcode" get a value when in Error ! Thanks for your feeback, I'll update the blog.