Using sftp or scp from MoneyWorks to transfer files to/from a remote server

SFTP is a nice and easy protocol for secure transfer of files to/from other servers. It's much easier and more secure than FTP. However, the Curl library in MoneyWorks does not include SFTP (which requires the entire OpenSSH library).

However, OpenSSH command line tools are provided by the operating system (standard on Mac; optional install on Windows 10/11)

To use SFTP you can utilise the MoneyWorks External() function to access to the system scp or sftp client.

For security, MWScript is not allowed free access to the command line, so you must first symbolically link any tools you want to access into the MoneyWorks Externals folder.

On Mac

MacOS includes OpenSSH as standard. The scp command is at /usr/bin/scp. To create the symbolic link, in Terminal.app:

mkdir ~/Library/Application\ Support/Cognito/MoneyWorks\ Gold/Externals
ln -s /usr/bin/scp ~/Library/Application\ Support/Cognito/MoneyWorks\ Gold/Externals/

Windows 10/11

OpenSSH is available for Windows, but not installed by default. You can install it from Windows Settings → Add an optional feature. It will install in C:\Windows\System32\OpenSSH. You'll need to link the main client tools into the Externals folder.

At an Administrator command prompt:

mkdir "%HOMEDRIVE%%HOMEPATH%\AppData\Roaming\Cognito\MoneyWorks Gold\Externals"
mklink "%HOMEDRIVE%%HOMEPATH%\AppData\Roaming\Cognito\MoneyWorks Gold\Externals\scp.exe" C:\Windows\System32\OpenSSH\scp.exe
mklink "%HOMEDRIVE%%HOMEPATH%\AppData\Roaming\Cognito\MoneyWorks Gold\Externals\sftp.exe" C:\Windows\System32\OpenSSH\sftp.exe
mklink "%HOMEDRIVE%%HOMEPATH%\AppData\Roaming\Cognito\MoneyWorks Gold\Externals\ssh.exe" C:\Windows\System32\OpenSSH\ssh.exe

Note: Some Windows-hosted non-OpenSSH sftp servers may not work with standard OpenSSH.

Using SCP to upload/download files

You should use SSH keys installed in the user's .ssh folder. See below for a quick tutorial on making SSH keys. These examples assume you have working SSH keys set up, so no credentials parameters are required. Passing passwords to standard scp/sftp is not trivial (requires an additional tool, sshpass). If you really want to use password authenticaiton, you may find it easier to use putty sftp.

In MWScript, to upload the file at sourceFilePath:

External("scp", sourceFilePath, "example.com:~/Documents/")

(use "scp.exe") on Windows.

To download

Be sure to download to a location that you can access from MWScript (e.g. the cache folder)

External(if(Platform = "Mac", "scp" , "scp.exe"), "example.com:~/Documents/remotefile.txt", CacheFolderPath)
let fd = File_Open(CacheFolderPath + "remotefile.txt", "r")
Alert(File_read(fd))
File_Close(fd)

Generating and installing SSH keys

Let's assume your script needs to upload or download files to/from some_server.example.com. You have a login to this server with username Some_user and a password. The script cannot easily use password login (scp/sftp are designed to discourage this). You should instead generate SSH keys to log in with.

  1. Generate the SSH key pair
  2. In terminal, type ssh-keygen (ssh-keygen.exe on Windows) and press return.
    The tool will ask where to save the private key. The default location will be in your ~/.ssh folder.

    % ssh-keygen
    Generating public/private ed25519 key pair.
    Enter file in which to save the key (/Users/username/.ssh/id_ed25519): /Users/username/.ssh/id_ed25519_for_mw_scp
    

    The type of key algorithm you get by default may vary by platform. On Mac ed25519 seems to be the default. On Windows the default is appears to be RSA. If this is the only SSH key you will ever use (and you do not already have a key with that name), you can just accept the default name (id_ed25519 or id_rsa). If you want to use different key pairs for different servers/purposes you should enter a unique name.

    The keygen tool will ask for a passphrase. You can leave it blank. Just hit enter. A passphrase would encrypt the private key and you would need to enter it to use the key.

    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    

    The private key and public key will be generated and placed in your .ssh folder in your home directory.

    Your identification has been saved in /Users/username/.ssh/id_ed25519_for_mw_scp
    Your public key has been saved in /Users/username/.ssh/id_ed25519_for_mw_scp.pub
    The key fingerprint is:
    SHA256:obqtnDWp2laGnyhxfxO6p0LcnSwY9Wo4qfQ8wGavRd8 username@yourhostname
    The key's randomart image is:
    +--[ED25519 256]--+
    |                 |
    |      .          |
    |     . ..        |
    |    .  ...       |
           ...
    | + XoO=+E.       |
    |  o+O*=.+        |
    |  o=B++= .       |
    +----[SHA256]-----+
    
  3. Install the public key on the remote server
  4. The public key generated above needs to be installed on the server that you will be connecting to. We assume that for the time being you have a password login to the server.

    You can just log into the remote server (using password login) and directly edit the .ssh/authorized_keys file and add a line, pasting in the text of your public key. Alternatively, you can use an ssh tool or a one-liner to do that for you...

    On Mac, you can use ssh-copy-id

    This script simply logs into the server using SSH and appends the public key to the authorized_keys file in your .ssh directory on the server.

    ssh-copy-id -i ~/.ssh/id_ed25519_for_mw_scp.pub Some_user@some_server.example.com
    

    You'll see output as below

    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/username/.ssh/id_ed25519_for_mw_scp.pub"
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    Some_user@some_server.example.com's password: 
    

    Enter the SSH login password to log in and complete the upload:

    Number of key(s) added:        1
    
    Now try logging into the machine, with:   "ssh 'Some_user@some_server.example.com'"
    and check to make sure that only the key(s) you wanted were added.
    

    On Windows, use SSH directly because there is no ssh-copy-id

    This one-liner logs into the server using SSH and appends the public key to the authorized_keys file in your .ssh directory on the server (it's formatted on two lines below, but it needs to be entered on one line). This assumes that the server you are connecting to is BSD/GNU-Linux/Mac rather than Windows.

    C:\> type %USERPROFILE%\.ssh\id_ed25519_for_mw_scp.pub | ssh Some_user@some_server.example.com "cat >> .ssh/authorized_keys"
    

    You will need to type your password to complete the login.

    You should then be able to log in with ssh Some_user@some_server.example.com without needing a password.

    Furthermore, your MWScript that runs while you are logged into your computer using MoneyWorks can also automatically log in using your key to SCP files.

Posted in Uncategorized | Comments Off on Using sftp or scp from MoneyWorks to transfer files to/from a remote server