summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJordan Borean <jborean93@gmail.com>2024-08-18 20:21:24 +0200
committerGitHub <noreply@github.com>2024-08-18 20:21:24 +0200
commit520fa688ba232ed165fc2dbd3b2be2ebde365ba1 (patch)
tree4679fb5e476849aa884f814bbbda871d521cdb90 /lib
parentAdd explicit winrm/psrp tests for HTTP and HTTPS (#83769) (diff)
downloadansible-520fa688ba232ed165fc2dbd3b2be2ebde365ba1.tar.xz
ansible-520fa688ba232ed165fc2dbd3b2be2ebde365ba1.zip
ssh and psrp - Support more complex characters in fetch_file (#83753)
* ssh and psrp - Support more complex chars in fetch_file Fixes the psrp and ssh (with piped) fetch function to work with paths that contains glob like characters in the path. For Windows this was needed when using paths that contain `[]` in the path. For ssh this was a problem with FreeBSD when using the piped transfer method with similar characters. Also tidies up the psrp logic to not inject the paths and buffer size in the script but pass it as an object through an argument/parameter. * Fix sanity check
Diffstat (limited to 'lib')
-rw-r--r--lib/ansible/plugins/connection/psrp.py39
-rw-r--r--lib/ansible/plugins/connection/ssh.py2
2 files changed, 23 insertions, 18 deletions
diff --git a/lib/ansible/plugins/connection/psrp.py b/lib/ansible/plugins/connection/psrp.py
index c9895d4450..abb9788ca1 100644
--- a/lib/ansible/plugins/connection/psrp.py
+++ b/lib/ansible/plugins/connection/psrp.py
@@ -632,39 +632,41 @@ end {
buffer_size = max_b64_size - (max_b64_size % 1024)
# setup the file stream with read only mode
- setup_script = '''$ErrorActionPreference = "Stop"
-$path = '%s'
+ setup_script = '''param([string]$Path)
+$ErrorActionPreference = "Stop"
-if (Test-Path -Path $path -PathType Leaf) {
+if (Test-Path -LiteralPath $path -PathType Leaf) {
$fs = New-Object -TypeName System.IO.FileStream -ArgumentList @(
$path,
[System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read,
[System.IO.FileShare]::Read
)
- $buffer_size = %d
} elseif (Test-Path -Path $path -PathType Container) {
Write-Output -InputObject "[DIR]"
} else {
Write-Error -Message "$path does not exist"
$host.SetShouldExit(1)
-}''' % (self._shell._escape(in_path), buffer_size)
+}'''
# read the file stream at the offset and return the b64 string
- read_script = '''$ErrorActionPreference = "Stop"
-$fs.Seek(%d, [System.IO.SeekOrigin]::Begin) > $null
-$buffer = New-Object -TypeName byte[] -ArgumentList $buffer_size
-$bytes_read = $fs.Read($buffer, 0, $buffer_size)
-
-if ($bytes_read -gt 0) {
- $bytes = $buffer[0..($bytes_read - 1)]
- Write-Output -InputObject ([System.Convert]::ToBase64String($bytes))
+ read_script = '''param([int64]$Offset, [int]$BufferSize)
+$ErrorActionPreference = "Stop"
+$fs.Seek($Offset, [System.IO.SeekOrigin]::Begin) > $null
+$buffer = New-Object -TypeName byte[] -ArgumentList $BufferSize
+$read = $fs.Read($buffer, 0, $buffer.Length)
+
+if ($read -gt 0) {
+ [System.Convert]::ToBase64String($buffer, 0, $read)
}'''
# need to run the setup script outside of the local scope so the
# file stream stays active between fetch operations
- rc, stdout, stderr = self._exec_psrp_script(setup_script,
- use_local_scope=False)
+ rc, stdout, stderr = self._exec_psrp_script(
+ setup_script,
+ use_local_scope=False,
+ arguments=[in_path],
+ )
if rc != 0:
raise AnsibleError("failed to setup file stream for fetch '%s': %s"
% (out_path, to_native(stderr)))
@@ -679,7 +681,10 @@ if ($bytes_read -gt 0) {
while True:
display.vvvvv("PSRP FETCH %s to %s (offset=%d" %
(in_path, out_path, offset), host=self._psrp_host)
- rc, stdout, stderr = self._exec_psrp_script(read_script % offset)
+ rc, stdout, stderr = self._exec_psrp_script(
+ read_script,
+ arguments=[offset, buffer_size],
+ )
if rc != 0:
raise AnsibleError("failed to transfer file to '%s': %s"
% (out_path, to_native(stderr)))
@@ -813,7 +818,7 @@ if ($bytes_read -gt 0) {
script: str,
input_data: bytes | str | t.Iterable | None = None,
use_local_scope: bool = True,
- arguments: t.Iterable[str] | None = None,
+ arguments: t.Iterable[t.Any] | None = None,
) -> tuple[int, bytes, bytes]:
# Check if there's a command on the current pipeline that still needs to be closed.
if self._last_pipeline:
diff --git a/lib/ansible/plugins/connection/ssh.py b/lib/ansible/plugins/connection/ssh.py
index 5c4c28d525..4c58e0d947 100644
--- a/lib/ansible/plugins/connection/ssh.py
+++ b/lib/ansible/plugins/connection/ssh.py
@@ -1250,7 +1250,7 @@ class Connection(ConnectionBase):
if sftp_action == 'get':
# we pass sudoable=False to disable pty allocation, which
# would end up mixing stdout/stderr and screwing with newlines
- (returncode, stdout, stderr) = self.exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE), sudoable=False)
+ (returncode, stdout, stderr) = self.exec_command('dd if=%s bs=%s' % (self._shell.quote(in_path), BUFSIZE), sudoable=False)
with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file:
out_file.write(stdout)
else: