in VMEncryption/main/handle.py [0:0]
def update_encryption_settings():
hutil.do_parse_context('UpdateEncryptionSettings')
logger.log('Updating encryption settings')
# re-install extra packages like cryptsetup if no longer on system from earlier enable
try:
DistroPatcher.install_extras()
except Exception as e:
message = "Failed to update encryption settings with error: {0}, stack trace: {1}".format(e, traceback.format_exc())
hutil.do_exit(exit_code=CommonVariables.missing_dependency,
operation='UpdateEncryptionSettings',
status=CommonVariables.extension_error_status,
code=str(CommonVariables.missing_dependency),
message=message)
encryption_config = EncryptionConfig(encryption_environment, logger)
config_secret_seq = encryption_config.get_secret_seq_num()
current_secret_seq_num = int(config_secret_seq if config_secret_seq else -1)
update_call_seq_num = hutil.get_current_seq()
logger.log("Current secret was created in operation #{0}".format(current_secret_seq_num))
logger.log("The update call is operation #{0}".format(update_call_seq_num))
executor = CommandExecutor(logger)
executor.Execute("mount /boot")
try:
disk_util = DiskUtil(hutil=hutil, patching=DistroPatcher, logger=logger, encryption_environment=encryption_environment)
bek_util = BekUtil(disk_util, logger)
extension_parameter = ExtensionParameter(hutil, logger, DistroPatcher, encryption_environment, get_protected_settings(), get_public_settings())
existing_passphrase_file = bek_util.get_bek_passphrase_file(encryption_config)
if current_secret_seq_num < update_call_seq_num:
if extension_parameter.passphrase is None or extension_parameter.passphrase == "":
extension_parameter.passphrase = bek_util.generate_passphrase(extension_parameter.KeyEncryptionAlgorithm)
logger.log('Recreating secret to store in the KeyVault')
keyVaultUtil = KeyVaultUtil(logger)
temp_keyfile = tempfile.NamedTemporaryFile(delete=False)
temp_keyfile.write(extension_parameter.passphrase)
temp_keyfile.close()
for crypt_item in disk_util.get_crypt_items():
if not crypt_item:
continue
before_keyslots = disk_util.luks_dump_keyslots(crypt_item.dev_path, crypt_item.luks_header_path)
logger.log("Before key addition, keyslots for {0}: {1}".format(crypt_item.dev_path, before_keyslots))
logger.log("Adding new key for {0}".format(crypt_item.dev_path))
luks_add_result = disk_util.luks_add_key(passphrase_file=existing_passphrase_file,
dev_path=crypt_item.dev_path,
mapper_name=crypt_item.mapper_name,
header_file=crypt_item.luks_header_path,
new_key_path=temp_keyfile.name)
logger.log("luks add result is {0}".format(luks_add_result))
after_keyslots = disk_util.luks_dump_keyslots(crypt_item.dev_path, crypt_item.luks_header_path)
logger.log("After key addition, keyslots for {0}: {1}".format(crypt_item.dev_path, after_keyslots))
new_keyslot = list(map(lambda x: x[0] != x[1], zip(before_keyslots, after_keyslots))).index(True)
logger.log("New key was added in keyslot {0}".format(new_keyslot))
# crypt_item.current_luks_slot = new_keyslot
# disk_util.update_crypt_item(crypt_item)
logger.log("New key successfully added to all encrypted devices")
if DistroPatcher.distro_info[0] == "Ubuntu":
logger.log("Updating initrd image with new osluksheader.")
executor.Execute("update-initramfs -u -k all", True)
if DistroPatcher.distro_info[0] == "redhat" or DistroPatcher.distro_info[0] == "centos":
distro_version = DistroPatcher.distro_info[1]
if distro_version.startswith('7.'):
logger.log("Updating initrd image with new osluksheader.")
executor.ExecuteInBash("/usr/sbin/dracut -f -v --kver `grubby --default-kernel | sed 's|/boot/vmlinuz-||g'`", True)
os.unlink(temp_keyfile.name)
# install Python ADAL support if using client certificate authentication
if extension_parameter.AADClientCertThumbprint:
DistroPatcher.install_adal()
kek_secret_id_created = keyVaultUtil.create_kek_secret(Passphrase=extension_parameter.passphrase,
KeyVaultURL=extension_parameter.KeyVaultURL,
KeyEncryptionKeyURL=extension_parameter.KeyEncryptionKeyURL,
AADClientID=extension_parameter.AADClientID,
AADClientCertThumbprint=extension_parameter.AADClientCertThumbprint,
KeyEncryptionAlgorithm=extension_parameter.KeyEncryptionAlgorithm,
AADClientSecret=extension_parameter.AADClientSecret,
DiskEncryptionKeyFileName=extension_parameter.DiskEncryptionKeyFileName)
if kek_secret_id_created is None:
hutil.do_exit(exit_code=CommonVariables.create_encryption_secret_failed,
operation='UpdateEncryptionSettings',
status=CommonVariables.extension_error_status,
code=str(CommonVariables.create_encryption_secret_failed),
message='UpdateEncryptionSettings failed.')
else:
encryption_config.passphrase_file_name = extension_parameter.DiskEncryptionKeyFileName
encryption_config.secret_id = kek_secret_id_created
encryption_config.secret_seq_num = hutil.get_current_seq()
encryption_config.commit()
shutil.copy(existing_passphrase_file, encryption_environment.bek_backup_path)
logger.log("Backed up BEK at {0}".format(encryption_environment.bek_backup_path))
hutil.do_exit(exit_code=0,
operation='UpdateEncryptionSettings',
status=CommonVariables.extension_success_status,
code=str(CommonVariables.success),
message=str(kek_secret_id_created))
else:
logger.log('Secret has already been updated')
mount_encrypted_disks(disk_util, bek_util, existing_passphrase_file, encryption_config)
disk_util.log_lsblk_output()
hutil.exit_if_same_seq()
# remount bek volume
existing_passphrase_file = bek_util.get_bek_passphrase_file(encryption_config)
if extension_parameter.passphrase and extension_parameter.passphrase != file(existing_passphrase_file).read():
logger.log("The new passphrase has not been placed in BEK volume yet")
logger.log("Skipping removal of old passphrase")
exit_without_status_report()
logger.log('Removing old passphrase')
for crypt_item in disk_util.get_crypt_items():
if not crypt_item:
continue
if filecmp.cmp(existing_passphrase_file, encryption_environment.bek_backup_path):
logger.log('Current BEK and backup are the same, skipping removal')
continue
logger.log('Removing old passphrase from {0}'.format(crypt_item.dev_path))
keyslots = disk_util.luks_dump_keyslots(crypt_item.dev_path, crypt_item.luks_header_path)
logger.log("Keyslots before removal: {0}".format(keyslots))
luks_remove_result = disk_util.luks_remove_key(passphrase_file=encryption_environment.bek_backup_path,
dev_path=crypt_item.dev_path,
header_file=crypt_item.luks_header_path)
logger.log("luks remove result is {0}".format(luks_remove_result))
keyslots = disk_util.luks_dump_keyslots(crypt_item.dev_path, crypt_item.luks_header_path)
logger.log("Keyslots after removal: {0}".format(keyslots))
logger.log("Old key successfully removed from all encrypted devices")
if DistroPatcher.distro_info[0] == "Ubuntu":
logger.log("Updating initrd image with new osluksheader.")
executor.Execute("update-initramfs -u -k all", True)
if DistroPatcher.distro_info[0] == "redhat" or DistroPatcher.distro_info[0] == "centos":
distro_version = DistroPatcher.distro_info[1]
if distro_version.startswith('7.'):
logger.log("Updating initrd image with new osluksheader.")
executor.ExecuteInBash("/usr/sbin/dracut -f -v --kver `grubby --default-kernel | sed 's|/boot/vmlinuz-||g'`", True)
hutil.save_seq()
extension_parameter.commit()
os.unlink(encryption_environment.bek_backup_path)
hutil.do_exit(exit_code=0,
operation='UpdateEncryptionSettings',
status=CommonVariables.extension_success_status,
code=str(CommonVariables.success),
message='Encryption settings updated')
except Exception as e:
message = "Failed to update encryption settings with error: {0}, stack trace: {1}".format(e, traceback.format_exc())
logger.log(msg=message, level=CommonVariables.ErrorLevel)
hutil.do_exit(exit_code=CommonVariables.unknown_error,
operation='UpdateEncryptionSettings',
status=CommonVariables.extension_error_status,
code=str(CommonVariables.unknown_error),
message=message)