From 84b32a91f04b6147d3b9f2badbc248ae548d3ab3 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Thu, 8 Jul 2021 23:20:33 -0400 Subject: [PATCH] Delete some old code related to reencryption We've moved past the point where this code would still be live. --- awx/conf/migrations/_reencrypt.py | 62 ------------------- awx/conf/settings.py | 9 +-- .../migrations/0015_v330_blank_start_args.py | 10 ++- awx/main/migrations/_reencrypt.py | 26 -------- 4 files changed, 5 insertions(+), 102 deletions(-) delete mode 100644 awx/conf/migrations/_reencrypt.py delete mode 100644 awx/main/migrations/_reencrypt.py diff --git a/awx/conf/migrations/_reencrypt.py b/awx/conf/migrations/_reencrypt.py deleted file mode 100644 index b7931464ad..0000000000 --- a/awx/conf/migrations/_reencrypt.py +++ /dev/null @@ -1,62 +0,0 @@ -import base64 -import hashlib - -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives.ciphers import Cipher -from cryptography.hazmat.primitives.ciphers.algorithms import AES -from cryptography.hazmat.primitives.ciphers.modes import ECB - - -__all__ = ['get_encryption_key', 'decrypt_field'] - - -def get_encryption_key(field_name, pk=None): - """ - Generate key for encrypted password based on field name, - ``settings.SECRET_KEY``, and instance pk (if available). - - :param pk: (optional) the primary key of the ``awx.conf.model.Setting``; - can be omitted in situations where you're encrypting a setting - that is not database-persistent (like a read-only setting) - """ - from django.conf import settings - - h = hashlib.sha1() - h.update(settings.SECRET_KEY) - if pk is not None: - h.update(str(pk)) - h.update(field_name) - return h.digest()[:16] - - -def decrypt_value(encryption_key, value): - raw_data = value[len('$encrypted$') :] - # If the encrypted string contains a UTF8 marker, discard it - utf8 = raw_data.startswith('UTF8$') - if utf8: - raw_data = raw_data[len('UTF8$') :] - algo, b64data = raw_data.split('$', 1) - if algo != 'AES': - raise ValueError('unsupported algorithm: %s' % algo) - encrypted = base64.b64decode(b64data) - decryptor = Cipher(AES(encryption_key), ECB(), default_backend()).decryptor() - value = decryptor.update(encrypted) + decryptor.finalize() - value = value.rstrip('\x00') - # If the encrypted string contained a UTF8 marker, decode the data - if utf8: - value = value.decode('utf-8') - return value - - -def decrypt_field(instance, field_name, subfield=None): - """ - Return content of the given instance and field name decrypted. - """ - value = getattr(instance, field_name) - if isinstance(value, dict) and subfield is not None: - value = value[subfield] - if not value or not value.startswith('$encrypted$'): - return value - key = get_encryption_key(field_name, getattr(instance, 'pk', None)) - - return decrypt_value(key, value) diff --git a/awx/conf/settings.py b/awx/conf/settings.py index 7e7abeac54..9aad42010c 100644 --- a/awx/conf/settings.py +++ b/awx/conf/settings.py @@ -25,7 +25,6 @@ from awx.main.utils import encrypt_field, decrypt_field from awx.conf import settings_registry from awx.conf.fields import PrimaryKeyRelatedField from awx.conf.models import Setting -from awx.conf.migrations._reencrypt import decrypt_field as old_decrypt_field # FIXME: Gracefully handle when settings are accessed before the database is # ready (or during migrations). @@ -299,13 +298,7 @@ class SettingsWrapper(UserSettingsHolder): continue if self.registry.is_setting_encrypted(setting.key): setting_ids[setting.key] = setting.id - try: - value = decrypt_field(setting, 'value') - except ValueError as e: - # TODO: Remove in Tower 3.3 - logger.debug('encountered error decrypting field: %s - attempting fallback to old', e) - value = old_decrypt_field(setting, 'value') - + value = decrypt_field(setting, 'value') else: value = setting.value settings_to_cache[setting.key] = get_cache_value(value) diff --git a/awx/main/migrations/0015_v330_blank_start_args.py b/awx/main/migrations/0015_v330_blank_start_args.py index 03cab1df41..5feb52a0d8 100644 --- a/awx/main/migrations/0015_v330_blank_start_args.py +++ b/awx/main/migrations/0015_v330_blank_start_args.py @@ -5,10 +5,6 @@ from __future__ import unicode_literals # Django from django.db import migrations -# AWX -from awx.main.migrations import _migration_utils as migration_utils -from awx.main.migrations._reencrypt import blank_old_start_args - class Migration(migrations.Migration): @@ -17,6 +13,8 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(migration_utils.set_current_apps_for_migrations, migrations.RunPython.noop), - migrations.RunPython(blank_old_start_args, migrations.RunPython.noop), + # This list is intentionally empty. + # Tower 3.3 included several data migrations that are no longer + # necessary (this list is now empty because Tower 3.3 is past EOL and + # cannot be directly upgraded to modern versions) ] diff --git a/awx/main/migrations/_reencrypt.py b/awx/main/migrations/_reencrypt.py deleted file mode 100644 index 1789ee31e3..0000000000 --- a/awx/main/migrations/_reencrypt.py +++ /dev/null @@ -1,26 +0,0 @@ -import logging - -from awx.conf.migrations._reencrypt import ( - decrypt_field, -) - -logger = logging.getLogger('awx.main.migrations') - -__all__ = [] - - -def blank_old_start_args(apps, schema_editor): - UnifiedJob = apps.get_model('main', 'UnifiedJob') - for uj in UnifiedJob.objects.defer('result_stdout_text').exclude(start_args='').iterator(): - if uj.status in ['running', 'pending', 'new', 'waiting']: - continue - try: - args_dict = decrypt_field(uj, 'start_args') - except ValueError: - args_dict = None - if args_dict == {}: - continue - if uj.start_args: - logger.debug('Blanking job args for %s', uj.pk) - uj.start_args = '' - uj.save()