The Wildcat! SFTP Server (wcoSFTP.dll) serves the Wildcat! file database over SSH File Transfer Protocol. It is a wcOnline hosting module, loaded the same way as the FTP, TELNET, POP3 and WEB servers.
It shares the FTP file namespace. A trading partner moving from wcFTP to wcSFTP sees the same file groups, the same file areas and the same paths, so existing partner scripts keep working. The same is true of the wcBASIC hooks -- see Hooks below.
libssh.dll must be present beside wcoSFTP.dll. It is shipped as a separate DLL rather than linked in, which is how the LGPL obligation is discharged. Without it the module will not load.
Both files install into the Wildcat! program directory with the AUP.
Run wcConfig | Computers, select the computer, and set:
[X] SFTP Port: 22
Each computer in a multi-machine installation decides for itself whether it runs the SFTP server, exactly as it does for FTP and TELNET. A port of 0 means "not configured here" and the server stays down.
Port 22 is normally owned by the Windows OpenSSH Server optional feature (sshd). If that service is installed and running, wcoSFTP cannot bind and the log will say so. Either disable the Windows service or choose a different SFTP port.
Run wcConfig | SFTP Server | Access and tick the access profiles allowed to use the SFTP server.
On upgrade, every existing access profile is granted SFTP access automatically, matching the way the other protocols ship enabled. A site that wants SFTP closed by default should clear the profiles it does not want, or use wcsetup /vanilla.
wcConfig | SFTP Server has five pages:
General -- namespace, listing and session options.
Key/Auth/Ident -- host key paths and identity strings.
Access -- the access profiles above.
Log Options -- log period, size and session trace.
IP Tracking/Blocking -- the standard IP tracking controls.
The Namespace group on the General page decides the directory paths a client sees:
[X] Show file groups
[X] Use underscore character for directory names
[X] Single file area access automatic change directory
These default to the same values as the FTP server and should normally be left matching it, so a partner using both protocols sees one set of paths. They are separate settings because a site migrating away from FTP may want SFTP shaped differently for a new partner without moving the paths their existing FTP partners already script against. When the two disagree, wcoSFTP says so in its log at startup.
Paths and identity strings are too long for the configuration database, so they live in an ini file.
The existence of this file is what enables the server. No file means SFTP was never turned on for this installation, and the listener stays closed -- so an AUP upgrade never opens a network service nobody asked for. wcConfig creates the file when SFTP is enabled. Until then the module logs:
SFTP server DISABLED -- run wcConfig | SFTP Server to
enable it. Nothing is listening and no host key exists.
[Global]
HostKeyFile = wc:\ssh\ssh_host_ed25519_key ; ED25519 host key
HostKeyFileRSA = ; optional, for RSA-pinned clients
AuthorizedKeys = ; optional key folder; empty = user record
IdentString = ; blank tracks the build version
AuthBanner = ; shown BEFORE login to anyone connecting
AllowPublicKey = ; blank follows wcConfig, 0 off, 1 on
VerboseTrace = 0 ; packet detail in the session trace
SessionTrace = -1 ; -1 follow log options, 0 off, 1 on
An ini key that is present overrides wcConfig. The startup log reports which source won, and says plainly when the ini is overriding:
config: wc:\ssh\wcsftp.ini is present; any key IN IT overrides wcConfig
config: publickey=on [set in wcsftp.ini] authkeydir=(user record only)
All SSH state lives in wc:\ssh\:
wc:\ssh\wcsftp.ini configuration, and the enable gate
wc:\ssh\ssh_host_ed25519_key host key, private half
wc:\ssh\ssh_host_ed25519_key.pub public half, safe to hand out
On first start the server generates an ED25519 host key and writes it there. Every later start reuses it, and the log says which:
host key loaded from wc:\ssh\ssh_host_ed25519_key
host key fingerprint: SHA256:YXVEnqQjiSnV0gbwNWA7CI8pIF3NfP4kSJoKhCmS26o
This file is production state. SFTP clients pin the host key and compare it on every connection. If it is lost or regenerated, every trading partner sees a host key mismatch warning -- which looks exactly like a man-in-the-middle attack and will stop automated transfers until each partner clears their known_hosts entry. Back it up with the rest of the configuration.
Publish the fingerprint. Give it to partners so they can verify the prompt on their FIRST connection, rather than being told to answer yes -- that is the one moment an impostor would be invisible. The server prints both the SHA256 and MD5 forms at startup.
These are wc: paths, not filesystem paths. The SFTP server is a wcRPC client: it cannot know where the server's root is, and the server may be on another machine entirely. A value without a wc: prefix is placed in wc:\ssh\, so a bare filename works and lands in the right folder.
libssh does its own Win32 file I/O and cannot resolve the Wildcat! virtual namespace, so it never sees a filename at all -- the module reads the key over wcRPC and hands libssh the bytes.
The SFTP server runs under wcOnline with no extra steps. To run it as its own NT service instead, the role is installed alongside the others:
cd \wcat\ntservices
installservices
controlled by this line in SetWildcatServices.cmd:
set wconlineService.roles=1
set wconlineService.roles.sftp=1
which installs the service WildcatSFTP ("Wildcat! SFTP Server"). Put site changes in SetWildcatServicesCustom.cmd rather than editing SetWildcatServices.cmd, which the AUP may replace.
Every wcBASIC hook tries the SFTP name first and falls back to the FTP name, so an existing compiled FTP hook runs unchanged under SFTP with no new file to write:
sftpcmd-connect then ftpcmd-connect -- before the SSH handshake; where wcGeoIP and similar rejection logic belongs.
sftploginalias then ftploginalias -- before the user name is looked up.
sftplogon then ftplogon -- after authentication.
sftpscanfile then ftpscanfile -- on upload, before the file is catalogued.
sftpNewFileNotify then NewFileNotify -- after the record exists.
A logon hook sets the user's starting file group and area exactly as it does under FTP, by writing the user's extended record. wcoSFTP reads SFTPDataNodenode first and FTPDataNodenode second, so an existing ftplogon hook works as written, while a hook that wants the two protocols to start in different places can target the SFTP section.
See FTPLOGON Hook Example for the mechanism.
Hook PRINT output is delivered to the client on the SSH channel's standard error stream. Clients display it differently -- the OpenSSH sftp client writes it to the terminal, WinSCP and FileZilla show it in a log pane, and automated clients usually discard it. It is suitable for a greeting or a notice, and should never be the only place something important is said. Hooks that run before the session channel exists (connect and login alias) have nowhere to print, and their output goes to the log only.
A partner may authenticate with an SSH public key instead of a password, which is what an unattended job needs: no password typed, and none written into a script. It is off until enabled on the General page, and the server's system password must be stamped with wcsyspw before wcServer will serve a key login at all.
Keys are held in the user record, up to 16 per user, and are installed by the sysop from the Sysop User Editor's Security page or with wcrun wcsFtpPubkey.
See Wildcat! SFTP Public Key Authentication for the full procedure, both sides, including what to do when it falls back to a password prompt.
With [X] Use FILE_ID.DIZ or MP3 tags for the file description on the General page, an upload is described by its own contents: FILE_ID.DIZ from an archive, or the ID3 tags of an MP3. A scan hook that sets the description overrides it, and "File uploaded via SFTP." is used only when neither produced anything.
IPv4 only. All Wildcat! IP hosting is 32-bit IPv4. A client whose DNS returns an IPv6 address for the server will try it first, fail, and fall back -- which appears as a delay of several seconds before the password prompt, with nothing in the server log. Use an IPv4-only host name, or AddressFamily inet in the client's ssh configuration.
MKDIR and RMDIR are refused. A directory in this namespace is a file group or file area from the catalog, created by a sysop in wcConfig.
RENAME requires file area sysop rights, the same rule the FTP server applies. A partner that uploads to a temporary name and renames it into place needs that right granted on the area. Renaming a file into a different area is refused -- that is a move, not a rename.
Bandwidth throttling does not apply. The FTP bandwidth settings do not affect SFTP sessions.
wcSFTPdate-computer.log -- the module log, including the startup banner reporting which configuration source won.
wcSFTPTracedate-node.computer.log -- the per-node session trace, when enabled on the Log Options page.
activity.node -- the standard activity log, with logins, transfers and hook runs.