mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Return binary data from gpg renderer
If we receive binary data, we should respond with binary data.
This commit is contained in:
parent
32aafab79a
commit
604b671ef9
2 changed files with 64 additions and 16 deletions
|
@ -228,7 +228,11 @@ from salt.ext import six
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
GPG_CIPHERTEXT = re.compile(
|
||||
r'-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----', re.DOTALL)
|
||||
salt.utils.stringutils.to_bytes(
|
||||
r'-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----'
|
||||
),
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def _get_gpg_exec():
|
||||
|
@ -281,37 +285,37 @@ def _decrypt_ciphertext(cipher):
|
|||
proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=False)
|
||||
decrypted_data, decrypt_error = proc.communicate(input=cipher)
|
||||
if not decrypted_data:
|
||||
try:
|
||||
cipher = salt.utils.stringutils.to_unicode(cipher)
|
||||
except UnicodeDecodeError:
|
||||
# decrypted data contains undecodable binary data
|
||||
pass
|
||||
log.warning(
|
||||
'Could not decrypt cipher %s, received: %s',
|
||||
'Could not decrypt cipher %r, received: %r',
|
||||
cipher,
|
||||
decrypt_error
|
||||
)
|
||||
return cipher
|
||||
else:
|
||||
try:
|
||||
decrypted_data = salt.utils.stringutils.to_unicode(decrypted_data)
|
||||
except UnicodeDecodeError:
|
||||
# decrypted data contains undecodable binary data
|
||||
pass
|
||||
return decrypted_data
|
||||
|
||||
|
||||
def _decrypt_ciphertexts(cipher, translate_newlines=False):
|
||||
cipher = salt.utils.stringutils.to_bytes(cipher)
|
||||
if translate_newlines:
|
||||
cipher = cipher.replace(r'\n', '\n')
|
||||
ret, num = GPG_CIPHERTEXT.subn(lambda m: _decrypt_ciphertext(m.group()), cipher)
|
||||
cipher = cipher.replace(rb'\n', b'\n')
|
||||
def replace(match):
|
||||
result = salt.utils.stringutils.to_bytes(_decrypt_ciphertext(match.group()))
|
||||
return result
|
||||
ret, num = GPG_CIPHERTEXT.subn(replace, salt.utils.stringutils.to_bytes(cipher))
|
||||
if num > 0:
|
||||
# Remove trailing newlines. Without if crypted value initially specified as a YAML multiline
|
||||
# it will conain unexpected trailing newline.
|
||||
return ret.rstrip('\n')
|
||||
ret = ret.rstrip(b'\n')
|
||||
else:
|
||||
return cipher
|
||||
ret = cipher
|
||||
|
||||
try:
|
||||
ret = salt.utils.stringutils.to_unicode(ret)
|
||||
except UnicodeDecodeError:
|
||||
# decrypted data contains some sort of binary data - not our problem
|
||||
pass
|
||||
return ret
|
||||
|
||||
def _decrypt_object(obj, translate_newlines=False):
|
||||
'''
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
# Import Python Libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.unit import skipIf, TestCase
|
||||
|
@ -100,3 +102,45 @@ class GPGTestCase(TestCase, LoaderModuleMockMixin):
|
|||
with patch('salt.renderers.gpg._get_key_dir', MagicMock(return_value=key_dir)):
|
||||
with patch('salt.renderers.gpg._decrypt_object', MagicMock(return_value=secret)):
|
||||
self.assertEqual(gpg.render(crypted), secret)
|
||||
|
||||
def test_multi_render(self):
|
||||
key_dir = '/etc/salt/gpgkeys'
|
||||
secret = 'Use more salt.'
|
||||
expected = '\n'.join([secret]*3)
|
||||
crypted = dedent('''\
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
!@#$%^&*()_+
|
||||
-----END PGP MESSAGE-----
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
!@#$%^&*()_+
|
||||
-----END PGP MESSAGE-----
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
!@#$%^&*()_+
|
||||
-----END PGP MESSAGE-----
|
||||
''')
|
||||
|
||||
with patch('salt.renderers.gpg._get_gpg_exec', MagicMock(return_value=True)):
|
||||
with patch('salt.renderers.gpg._get_key_dir', MagicMock(return_value=key_dir)):
|
||||
with patch('salt.renderers.gpg._decrypt_ciphertext', MagicMock(return_value=secret)):
|
||||
self.assertEqual(gpg.render(crypted), expected)
|
||||
|
||||
def test_render_with_binary_data_should_return_binary_data(self):
|
||||
key_dir = '/etc/salt/gpgkeys'
|
||||
secret = b'Use\x8b more\x8b salt.'
|
||||
expected = b'\n'.join([secret]*3)
|
||||
crypted = dedent('''\
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
!@#$%^&*()_+
|
||||
-----END PGP MESSAGE-----
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
!@#$%^&*()_+
|
||||
-----END PGP MESSAGE-----
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
!@#$%^&*()_+
|
||||
-----END PGP MESSAGE-----
|
||||
''')
|
||||
|
||||
with patch('salt.renderers.gpg._get_gpg_exec', MagicMock(return_value=True)):
|
||||
with patch('salt.renderers.gpg._get_key_dir', MagicMock(return_value=key_dir)):
|
||||
with patch('salt.renderers.gpg._decrypt_ciphertext', MagicMock(return_value=secret)):
|
||||
self.assertEqual(gpg.render(crypted), expected)
|
Loading…
Add table
Reference in a new issue