Delete some old code related to reencryption

We've moved past the point where this code would still be live.
This commit is contained in:
Bill Nottingham 2021-07-08 23:20:33 -04:00
parent adb6661015
commit 84b32a91f0
4 changed files with 5 additions and 102 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)
]

View File

@ -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()