Public Access
Support sftp:// and ftps:// URL schemes in host values; fix TLS-flag bug
CAMBS's partner turned out to receive insurance files over SFTP - Melissa pasted "SFTP://sft.polluxsystems.com/" as ftps.host, which the engine fed to WinSCP as a literal FTP hostname. Host values are now parsed: an sftp:// scheme switches the upload to the SFTP protocol (default port 22), ftps:// forces explicit TLS, a bare hostname behaves as before per the tls flag, and the scheme/trailing slash are stripped from the hostname either way. Also fixes a real bug this exposed: GiveUpSecurityAndAcceptAnyTlsHostCertificate was set unconditionally, and WinSCP refuses that combination when FtpSecure is None - exactly the "TlsHostCertificateFingerprint ... is set, but neither FtpSecure nor Secure is enabled" error from her run. The flag is now only set when TLS is actually on.
This commit is contained in:
@@ -110,7 +110,7 @@ leave its login and every other path alone.
|
||||
|---------|-----------|------------|
|
||||
| `workflow` | Yes | `insurance` if no patient files, `insurance+patient` if both |
|
||||
| `insurance_file_type` | No (defaults to `pdf`) | Set to `tif` for an entity whose imaging system exports the daily files as TIFs instead of PDFs (CAMBS, RMI, CONSENSIO, INLAND). Goes at the top level, next to `workflow` — NOT inside `ftps` |
|
||||
| `ftps.host` | Yes | FTP server address |
|
||||
| `ftps.host` | Yes | Server address. A plain name (`ftp.example.com`) uses FTP/FTPS per the `tls` setting. You can also paste a full URL — `sftp://server.com` sends these files over **SFTP** instead (some partners use SFTP for everything), and `ftps://server.com` forces FTPS |
|
||||
| `ftps.port` | No (defaults to 21) | FTP port, only if not 21 |
|
||||
| `ftps.tls` | Yes | `true` for FTPS (secure), `false` for plain FTP |
|
||||
| `ftps.username` | Yes | FTP username (shared across all practices) |
|
||||
|
||||
+29
-7
@@ -168,16 +168,37 @@ function Get-ArchiveDir($parent, $name) {
|
||||
return $path
|
||||
}
|
||||
|
||||
# Host values may be pasted as URLs, e.g. "SFTP://server.com/" - pull out the
|
||||
# scheme (decides the protocol) and the bare hostname.
|
||||
function Get-HostInfo($rawHost) {
|
||||
$h = ([string]$rawHost).Trim()
|
||||
$scheme = $null
|
||||
if ($h -imatch '^(\w+)://') {
|
||||
$scheme = $Matches[1].ToLower()
|
||||
$h = $h -replace '^\w+://', ''
|
||||
}
|
||||
$h = $h.Split('/')[0]
|
||||
return @{ Scheme = $scheme; HostName = $h }
|
||||
}
|
||||
|
||||
# -- Upload via FTPS -----------------------------------------------------------
|
||||
function Invoke-FTPSUpload($ftpConfig, $files, $remotePath, $entity, $practice) {
|
||||
$hostInfo = Get-HostInfo $ftpConfig.host
|
||||
$opts = New-Object WinSCP.SessionOptions
|
||||
$opts.Protocol = [WinSCP.Protocol]::Ftp
|
||||
$opts.FtpSecure = if ($ftpConfig.tls) { [WinSCP.FtpSecure]::Explicit } else { [WinSCP.FtpSecure]::None }
|
||||
$opts.HostName = $ftpConfig.host
|
||||
$opts.PortNumber = if ($ftpConfig.port) { [int]$ftpConfig.port } else { 21 }
|
||||
if ($hostInfo.Scheme -eq "sftp") {
|
||||
$opts.Protocol = [WinSCP.Protocol]::Sftp
|
||||
$opts.PortNumber = if ($ftpConfig.port) { [int]$ftpConfig.port } else { 22 }
|
||||
$opts.GiveUpSecurityAndAcceptAnySshHostKey = $true
|
||||
} else {
|
||||
$useTls = ($ftpConfig.tls -eq $true) -or ($hostInfo.Scheme -eq "ftps")
|
||||
$opts.Protocol = [WinSCP.Protocol]::Ftp
|
||||
$opts.FtpSecure = if ($useTls) { [WinSCP.FtpSecure]::Explicit } else { [WinSCP.FtpSecure]::None }
|
||||
$opts.PortNumber = if ($ftpConfig.port) { [int]$ftpConfig.port } else { 21 }
|
||||
if ($useTls) { $opts.GiveUpSecurityAndAcceptAnyTlsHostCertificate = $true }
|
||||
}
|
||||
$opts.HostName = $hostInfo.HostName
|
||||
$opts.UserName = $ftpConfig.username
|
||||
$opts.Password = $ftpConfig.password
|
||||
$opts.GiveUpSecurityAndAcceptAnyTlsHostCertificate = $true
|
||||
|
||||
$session = New-Object WinSCP.Session
|
||||
if ($logLevel -eq "debug") {
|
||||
@@ -186,7 +207,7 @@ function Invoke-FTPSUpload($ftpConfig, $files, $remotePath, $entity, $practice)
|
||||
|
||||
$ok = 0; $fail = 0
|
||||
try {
|
||||
Write-Debug "FTPS connect: $($ftpConfig.host) user=$($ftpConfig.username) tls=$($ftpConfig.tls)"
|
||||
Write-Debug "Connect: $($opts.Protocol) $($hostInfo.HostName):$($opts.PortNumber) user=$($ftpConfig.username)"
|
||||
$session.Open($opts)
|
||||
foreach ($file in $files) {
|
||||
$remote = $remotePath.TrimEnd("/") + "/" + $file.Name
|
||||
@@ -216,9 +237,10 @@ function Invoke-FTPSUpload($ftpConfig, $files, $remotePath, $entity, $practice)
|
||||
|
||||
# -- Upload via SFTP -----------------------------------------------------------
|
||||
function Invoke-SFTPUpload($sftpConfig, $files, $remotePath, $entity, $practice) {
|
||||
$hostInfo = Get-HostInfo $sftpConfig.host
|
||||
$opts = New-Object WinSCP.SessionOptions
|
||||
$opts.Protocol = [WinSCP.Protocol]::Sftp
|
||||
$opts.HostName = $sftpConfig.host
|
||||
$opts.HostName = $hostInfo.HostName
|
||||
$opts.PortNumber = if ($sftpConfig.port) { [int]$sftpConfig.port } else { 22 }
|
||||
$opts.UserName = $sftpConfig.username
|
||||
$opts.Password = $sftpConfig.password
|
||||
|
||||
Reference in New Issue
Block a user