mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-07 22:02:50 +00:00
Prevent data being truncated over persistent connection socket (#43885)
* Change how data is sent to the persistent connection socket. We can't rely on readline(), so send the size of the data first. We can then read that many bytes from the stream on the recieving end. * Set pty to noncanonical mode before sending * Now that we send data length, we don't need a sentinel anymore * Copy socket changes to persistent, too * Use os.write instead of fdopen()ing and using that. * Follow pickle with sha1sum of pickle * Swap order of vars and init being passed to ansible-connection
This commit is contained in:
@@ -12,6 +12,7 @@ except Exception:
|
||||
pass
|
||||
|
||||
import fcntl
|
||||
import hashlib
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
@@ -36,6 +37,23 @@ from ansible.utils.display import Display
|
||||
from ansible.utils.jsonrpc import JsonRpcServer
|
||||
|
||||
|
||||
def read_stream(byte_stream):
|
||||
size = int(byte_stream.readline().strip())
|
||||
|
||||
data = byte_stream.read(size)
|
||||
if len(data) < size:
|
||||
raise Exception("EOF found before data was complete")
|
||||
|
||||
data_hash = to_text(byte_stream.readline().strip())
|
||||
if data_hash != hashlib.sha1(data).hexdigest():
|
||||
raise Exception("Read {0} bytes, but data did not match checksum".format(size))
|
||||
|
||||
# restore escaped loose \r characters
|
||||
data = data.replace(br'\r', b'\r')
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@contextmanager
|
||||
def file_lock(lock_path):
|
||||
"""
|
||||
@@ -204,25 +222,8 @@ def main():
|
||||
|
||||
try:
|
||||
# read the play context data via stdin, which means depickling it
|
||||
cur_line = stdin.readline()
|
||||
init_data = b''
|
||||
|
||||
while cur_line.strip() != b'#END_INIT#':
|
||||
if cur_line == b'':
|
||||
raise Exception("EOF found before init data was complete")
|
||||
init_data += cur_line
|
||||
cur_line = stdin.readline()
|
||||
|
||||
cur_line = stdin.readline()
|
||||
vars_data = b''
|
||||
|
||||
while cur_line.strip() != b'#END_VARS#':
|
||||
if cur_line == b'':
|
||||
raise Exception("EOF found before vars data was complete")
|
||||
vars_data += cur_line
|
||||
cur_line = stdin.readline()
|
||||
# restore escaped loose \r characters
|
||||
vars_data = vars_data.replace(br'\r', b'\r')
|
||||
vars_data = read_stream(stdin)
|
||||
init_data = read_stream(stdin)
|
||||
|
||||
if PY3:
|
||||
pc_data = cPickle.loads(init_data, encoding='bytes')
|
||||
|
||||
Reference in New Issue
Block a user