VirtualBox

Changeset 54953 in vbox


Ignore:
Timestamp:
Mar 25, 2015 5:50:47 PM (10 years ago)
Author:
vboxsync
Message:

FE/Qt: 7676: Runtime UI: Disk Encryption (DE) support: Initial implementation for Machine settings / General page / Encryption tab.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/settings/machine
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp

    r54880 r54953  
    2525# include "QIWidgetValidator.h"
    2626# include "UIMachineSettingsGeneral.h"
     27 #include "UIModalWindowManager.h"
    2728# include "UIMessageCenter.h"
    2829# include "UIConverter.h"
     30/* COM includes: */
     31# include "CMedium.h"
     32# include "CMediumAttachment.h"
    2933#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3034
    3135UIMachineSettingsGeneral::UIMachineSettingsGeneral()
    3236    : m_fHWVirtExEnabled(false)
     37    , m_fEncryptionCipherChanged(false)
     38    , m_fEncryptionPasswordChanged(false)
    3339{
    3440    /* Prepare: */
     
    95101    /* 'Description' tab data: */
    96102    generalData.m_strDescription = m_machine.GetDescription();
     103
     104    /* 'Encryption' tab data: */
     105    QString strCipher;
     106    bool fEncryptionCipherCommon = true;
     107    /* Prepare the map of the encrypted mediums: */
     108    EncryptedMediumMap encryptedMediums;
     109    foreach (const CMediumAttachment &attachment, m_machine.GetMediumAttachments())
     110    {
     111        /* Acquire hard-drive attachments only: */
     112        if (attachment.GetType() == KDeviceType_HardDisk)
     113        {
     114            /* Get the attachment medium base: */
     115            const CMedium medium = attachment.GetMedium();
     116            /* Check medium encryption attributes: */
     117            QString strCurrentCipher;
     118            const QString strCurrentPasswordId = medium.GetEncryptionSettings(strCurrentCipher);
     119            if (medium.isOk())
     120            {
     121                encryptedMediums.insert(strCurrentPasswordId, medium.GetId());
     122                if (strCurrentCipher != strCipher)
     123                {
     124                    if (strCipher.isNull())
     125                        strCipher = strCurrentCipher;
     126                    else
     127                        fEncryptionCipherCommon = false;
     128                }
     129            }
     130        }
     131    }
     132    generalData.m_fEncryptionEnabled = !encryptedMediums.isEmpty();
     133    generalData.m_fEncryptionCipherChanged = false;
     134    generalData.m_fEncryptionPasswordChanged = false;
     135    if (fEncryptionCipherCommon)
     136        generalData.m_iEncryptionCipherIndex = m_encryptionCiphers.indexOf(strCipher);
     137    if (generalData.m_iEncryptionCipherIndex == -1)
     138        generalData.m_iEncryptionCipherIndex = 0;
     139    generalData.m_encryptedMediums = encryptedMediums;
    97140
    98141    /* Cache general data: */
     
    126169    mTeDescription->setPlainText(generalData.m_strDescription);
    127170
     171    /* 'Encryption' tab data: */
     172    AssertPtrReturnVoid(m_pCheckBoxEncryption);
     173    AssertPtrReturnVoid(m_pComboCipher);
     174    m_pCheckBoxEncryption->setChecked(generalData.m_fEncryptionEnabled);
     175    m_pComboCipher->setCurrentIndex(generalData.m_iEncryptionCipherIndex);
     176    m_fEncryptionCipherChanged = generalData.m_fEncryptionCipherChanged;
     177    m_fEncryptionPasswordChanged = generalData.m_fEncryptionPasswordChanged;
     178
    128179    /* Polish page finally: */
    129180    polishPage();
     
    155206    generalData.m_strDescription = mTeDescription->toPlainText().isEmpty() ?
    156207                                   QString::null : mTeDescription->toPlainText();
     208
     209    /* 'Encryption' tab data: */
     210    AssertPtrReturnVoid(m_pCheckBoxEncryption);
     211    AssertPtrReturnVoid(m_pComboCipher);
     212    AssertPtrReturnVoid(m_pEditorEncryptionPassword);
     213    generalData.m_fEncryptionEnabled = m_pCheckBoxEncryption->isChecked();
     214    generalData.m_fEncryptionCipherChanged = m_fEncryptionCipherChanged;
     215    generalData.m_fEncryptionPasswordChanged = m_fEncryptionPasswordChanged;
     216    generalData.m_iEncryptionCipherIndex = m_pComboCipher->currentIndex();
     217    generalData.m_strEncryptionPassword = m_pEditorEncryptionPassword->text();
     218    /* If encryption status, cipher or password is changed: */
     219    if (generalData.m_fEncryptionEnabled != m_cache.base().m_fEncryptionEnabled ||
     220        generalData.m_fEncryptionCipherChanged != m_cache.base().m_fEncryptionCipherChanged ||
     221        generalData.m_fEncryptionPasswordChanged != m_cache.base().m_fEncryptionPasswordChanged)
     222    {
     223        /* Ask for the disk encryption passwords if necessary: */
     224        if (!m_cache.base().m_encryptedMediums.isEmpty())
     225        {
     226            /* Create corresponding dialog: */
     227            QWidget *pDlgParent = windowManager().realParentWindow(window());
     228            QPointer<UIAddDiskEncryptionPasswordDialog> pDlg =
     229                 new UIAddDiskEncryptionPasswordDialog(pDlgParent,
     230                                                       generalData.m_strName,
     231                                                       generalData.m_encryptedMediums);
     232            /* Execute it and acquire the result: */
     233            if (pDlg->exec() == QDialog::Accepted)
     234                generalData.m_encryptionPasswords = pDlg->encryptionPasswords();
     235            /* Delete dialog if still valid: */
     236            if (pDlg)
     237                delete pDlg;
     238        }
     239    }
    157240
    158241    /* Cache general data: */
     
    205288            if (generalData.m_strName != m_cache.base().m_strName)
    206289                m_machine.SetName(generalData.m_strName);
     290
     291            /* Encryption tab data: */
     292            if (generalData.m_fEncryptionEnabled != m_cache.base().m_fEncryptionEnabled ||
     293                generalData.m_fEncryptionCipherChanged != m_cache.base().m_fEncryptionCipherChanged ||
     294                generalData.m_fEncryptionPasswordChanged != m_cache.base().m_fEncryptionPasswordChanged)
     295            {
     296                /* Cipher attribute changed? */
     297                QString strNewCipher;
     298                if (generalData.m_fEncryptionCipherChanged)
     299                {
     300                    strNewCipher = generalData.m_fEncryptionEnabled ?
     301                                   m_encryptionCiphers.at(generalData.m_iEncryptionCipherIndex) : QString();
     302                }
     303                /* Password attribute changed? */
     304                QString strNewPassword;
     305                QString strNewPasswordId;
     306                if (generalData.m_fEncryptionPasswordChanged)
     307                {
     308                    strNewPassword = generalData.m_fEncryptionEnabled ?
     309                                     generalData.m_strEncryptionPassword : QString();
     310                    strNewPasswordId = generalData.m_fEncryptionEnabled ?
     311                                       m_machine.GetName() : QString();
     312                }
     313
     314                /* Get the maps of encrypted mediums and their passwords: */
     315                const EncryptedMediumMap &encryptedMedium = generalData.m_encryptedMediums;
     316                const EncryptionPasswordsMap &encryptionPasswords = generalData.m_encryptionPasswords;
     317                /* Enumerate attachments: */
     318                foreach (const CMediumAttachment &attachment, m_machine.GetMediumAttachments())
     319                {
     320                    /* Enumerate hard-drives only: */
     321                    if (attachment.GetType() == KDeviceType_HardDisk)
     322                    {
     323                        /* Get corresponding medium: */
     324                        CMedium medium = attachment.GetMedium();
     325
     326                        /* Check if old password exists/provided: */
     327                        QString strOldPasswordId = encryptedMedium.key(medium.GetId());
     328                        QString strOldPassword = encryptionPasswords.value(strOldPasswordId);
     329
     330//                        printf(" Medium: %s, old password = %s, new cipher = %s, new password = %s, new password id = %s\n",
     331//                               medium.GetId().toAscii().constData(),
     332//                               strOldPassword.toAscii().constData(),
     333//                               strNewCipher.toAscii().constData(),
     334//                               strNewPassword.toAscii().constData(),
     335//                               strNewPasswordId.toAscii().constData());
     336
     337                        /* Update encryption: */
     338                        CProgress progress = medium.ChangeEncryption(strOldPassword,
     339                                                                     strNewCipher,
     340                                                                     strNewPassword,
     341                                                                     strNewPasswordId);
     342//                        if (!medium.isOk())
     343//                            printf("  Medium API Error, rc = %s\n", msgCenter().formatRC(medium.lastRC()).toAscii().constData());
     344                        progress.WaitForCompletion(-1);
     345//                        if (!progress.isOk())
     346//                            printf("  Progress API Error, rc = %s\n", msgCenter().formatRC(progress.lastRC()).toAscii().constData());
     347//                        if (progress.GetResultCode() != 0)
     348//                            printf("  Progress Processing Error, rc = %s\n", msgCenter().formatRC(progress.GetResultCode()).toAscii().constData());
     349                    }
     350                }
     351            }
    207352        }
    208353    }
     
    219364    /* Prepare message: */
    220365    UIValidationMessage message;
     366
     367    /* 'Basic' tab validations: */
    221368    message.first = VBoxGlobal::removeAccelMark(mTwGeneral->tabText(0));
     369    message.second.clear();
    222370
    223371    /* VM name validation: */
     372    AssertPtrReturn(m_pNameAndSystemEditor, false);
    224373    if (m_pNameAndSystemEditor->name().trimmed().isEmpty())
    225374    {
     
    234383                             "64-bit guest systems require hardware virtualization, "
    235384                             "so this will be enabled automatically if you confirm the changes.");
     385    }
     386
     387    /* Serialize message: */
     388    if (!message.second.isEmpty())
     389        messages << message;
     390
     391    /* 'Encryption' tab validations: */
     392    message.first = VBoxGlobal::removeAccelMark(mTwGeneral->tabText(3));
     393    message.second.clear();
     394
     395    /* Encryption validation: */
     396    AssertPtrReturn(m_pCheckBoxEncryption, false);
     397    if (m_pCheckBoxEncryption->isChecked())
     398    {
     399        /* Cipher should be chosen if once changed: */
     400        AssertPtrReturn(m_pComboCipher, false);
     401        if (!m_cache.base().m_fEncryptionEnabled ||
     402            m_fEncryptionCipherChanged)
     403        {
     404            if (m_pComboCipher->currentIndex() == 0)
     405                message.second << tr("Encryption cipher type is not specified.");
     406        }
     407        /* Password should be entered and confirmed if once changed: */
     408        AssertPtrReturn(m_pEditorEncryptionPassword, false);
     409        AssertPtrReturn(m_pEditorEncryptionPasswordConfirm, false);
     410        if (!m_cache.base().m_fEncryptionEnabled ||
     411            m_fEncryptionPasswordChanged)
     412        {
     413            if (m_pEditorEncryptionPassword->text().isEmpty())
     414                message.second << tr("Encryption password is not entered.");
     415            else
     416            if (m_pEditorEncryptionPasswordConfirm->text().isEmpty())
     417                message.second << tr("Encryption password is not confirmed.");
     418            else
     419            if (m_pEditorEncryptionPassword->text() !=
     420                m_pEditorEncryptionPasswordConfirm->text())
     421                message.second << tr("Entered and confirmed encryption passwords doesn't match.");
     422            fPass = false;
     423        }
    236424    }
    237425
     
    289477    mCbDragAndDrop->setItemText(2, gpConverter->toString(KDnDMode_GuestToHost));
    290478    mCbDragAndDrop->setItemText(3, gpConverter->toString(KDnDMode_Bidirectional));
     479
     480    /* Translate Cipher type combo: */
     481    AssertPtrReturnVoid(m_pComboCipher);
     482    m_pComboCipher->setItemText(0, tr("Leave Unchanged", "cipher type"));
    291483}
    292484
     
    300492    prepareTabAdvanced();
    301493    prepareTabDescription();
     494    prepareTabEncryption();
    302495}
    303496
     
    345538        mTeDescription->setMinimumHeight(150);
    346539#endif /* Q_WS_MAC */
     540    }
     541}
     542
     543void UIMachineSettingsGeneral::prepareTabEncryption()
     544{
     545    /* Encryption check-box was created in the .ui file: */
     546    AssertPtrReturnVoid(m_pCheckBoxEncryption);
     547    {
     548        /* Configure Encryption check-box: */
     549        connect(m_pCheckBoxEncryption, SIGNAL(toggled(bool)),
     550                this, SLOT(revalidate()));
     551    }
     552    /* Encryption Cipher combo was created in the .ui file: */
     553    AssertPtrReturnVoid(m_pComboCipher);
     554    {
     555        /* Configure Encryption Cipher combo: */
     556        m_encryptionCiphers << QString()
     557                            << "AES-XTS256-PLAIN64"
     558                            << "AES-XTS128-PLAIN64";
     559        m_pComboCipher->addItems(m_encryptionCiphers);
     560        connect(m_pComboCipher, SIGNAL(currentIndexChanged(int)),
     561                this, SLOT(sltMarkEncryptionCipherChanged()));
     562        connect(m_pComboCipher, SIGNAL(currentIndexChanged(int)),
     563                this, SLOT(revalidate()));
     564    }
     565    /* Encryption Password editor was created in the .ui file: */
     566    AssertPtrReturnVoid(m_pEditorEncryptionPassword);
     567    {
     568        /* Configure Encryption Password editor: */
     569        m_pEditorEncryptionPassword->setAlignment(Qt::AlignCenter);
     570        m_pEditorEncryptionPassword->setEchoMode(QLineEdit::Password);
     571        connect(m_pEditorEncryptionPassword, SIGNAL(textEdited(const QString&)),
     572                this, SLOT(sltMarkEncryptionPasswordChanged()));
     573        connect(m_pEditorEncryptionPassword, SIGNAL(textEdited(const QString&)),
     574                this, SLOT(revalidate()));
     575    }
     576    /* Encryption Password Confirmation editor was created in the .ui file: */
     577    AssertPtrReturnVoid(m_pEditorEncryptionPasswordConfirm);
     578    {
     579        /* Configure Encryption Password Confirmation editor: */
     580        m_pEditorEncryptionPasswordConfirm->setAlignment(Qt::AlignCenter);
     581        m_pEditorEncryptionPasswordConfirm->setEchoMode(QLineEdit::Password);
     582        connect(m_pEditorEncryptionPasswordConfirm, SIGNAL(textEdited(const QString&)),
     583                this, SLOT(sltMarkEncryptionPasswordChanged()));
     584        connect(m_pEditorEncryptionPasswordConfirm, SIGNAL(textEdited(const QString&)),
     585                this, SLOT(revalidate()));
    347586    }
    348587}
     
    371610    AssertPtrReturnVoid(mTeDescription);
    372611    mTeDescription->setEnabled(isMachineInValidMode());
    373 }
    374 
     612
     613    /* 'Encryption' tab: */
     614    AssertPtrReturnVoid(m_pCheckBoxEncryption);
     615    AssertPtrReturnVoid(m_pWidgetEncryption);
     616    m_pCheckBoxEncryption->setEnabled(isMachineOffline());
     617    m_pWidgetEncryption->setEnabled(isMachineOffline() && m_pCheckBoxEncryption->isChecked());
     618}
     619
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h

    r54880 r54953  
    2121#include "UISettingsPage.h"
    2222#include "UIMachineSettingsGeneral.gen.h"
     23#include "UIAddDiskEncryptionPasswordDialog.h"
    2324
    2425/** Machine settings: General page: Data structure. */
     
    3435        , m_dndMode(KDnDMode_Disabled)
    3536        , m_strDescription(QString())
     37        , m_fEncryptionEnabled(false)
     38        , m_fEncryptionCipherChanged(false)
     39        , m_fEncryptionPasswordChanged(false)
     40        , m_iEncryptionCipherIndex(-1)
     41        , m_strEncryptionPassword(QString())
    3642    {}
    3743
     
    4551               (m_clipboardMode == other.m_clipboardMode) &&
    4652               (m_dndMode == other.m_dndMode) &&
    47                (m_strDescription == other.m_strDescription);
     53               (m_strDescription == other.m_strDescription) &&
     54               (m_fEncryptionEnabled == other.m_fEncryptionEnabled) &&
     55               (m_fEncryptionCipherChanged == other.m_fEncryptionCipherChanged) &&
     56               (m_fEncryptionPasswordChanged == other.m_fEncryptionPasswordChanged);
    4857    }
    4958
     
    6978    /** Holds the VM description. */
    7079    QString m_strDescription;
     80
     81    /** Holds whether the encryption is enabled. */
     82    bool m_fEncryptionEnabled;
     83    /** Holds whether the encryption cipher was changed. */
     84    bool m_fEncryptionCipherChanged;
     85    /** Holds whether the encryption password was changed. */
     86    bool m_fEncryptionPasswordChanged;
     87    /** Holds the encryption cipher index. */
     88    int m_iEncryptionCipherIndex;
     89    /** Holds the encryption password. */
     90    QString m_strEncryptionPassword;
     91    /** Holds the encrypted medium ids. */
     92    EncryptedMediumMap m_encryptedMediums;
     93    /** Holds the encryption passwords. */
     94    EncryptionPasswordsMap m_encryptionPasswords;
    7195};
    7296typedef UISettingsCache<UIDataSettingsMachineGeneral> UICacheSettingsMachineGeneral;
     
    123147    void retranslateUi();
    124148
     149private slots:
     150
     151    /** Marks the encryption cipher as changed. */
     152    void sltMarkEncryptionCipherChanged() { m_fEncryptionCipherChanged = true; }
     153    /** Marks the encryption cipher and password as changed. */
     154    void sltMarkEncryptionPasswordChanged() { m_fEncryptionCipherChanged = true; m_fEncryptionPasswordChanged = true; }
     155
    125156private:
    126157
     
    133164    /** Prepare 'Description' tab routine. */
    134165    void prepareTabDescription();
     166    /** Prepare 'Encryption' tab routine. */
     167    void prepareTabEncryption();
    135168
    136169    /** Polish routine. */
     
    142175    /** Holds whether HW virtualization extension is enabled. */
    143176    bool m_fHWVirtExEnabled;
     177
     178    /** Holds whether the encryption cipher was changed.
     179      * We are holding that argument here because we do not know
     180      * the old <i>cipher</i> for sure to compare the new one with. */
     181    bool m_fEncryptionCipherChanged;
     182    /** Holds whether the encryption password was changed.
     183      * We are holding that argument here because we do not know
     184      * the old <i>password</i> at all to compare the new one with. */
     185    bool m_fEncryptionPasswordChanged;
     186
     187    /** Holds the hard-coded encryption cipher list.
     188      * We are hard-coding it because there is no place we can get it from. */
     189    QStringList m_encryptionCiphers;
    144190};
    145191
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.ui

    r53397 r54953  
    208208      </layout>
    209209     </widget>
     210     <widget class="QWidget" name="m_pTabEncryption">
     211      <attribute name="title">
     212       <string>Enc&amp;ryption</string>
     213      </attribute>
     214      <layout class="QGridLayout" name="m_pLayoutEncryption">
     215       <item row="0" column="0" colspan="2">
     216        <widget class="QCheckBox" name="m_pCheckBoxEncryption">
     217         <property name="whatsThis">
     218          <string>When checked, enables the encryption of this virtual machine.</string>
     219         </property>
     220         <property name="text">
     221          <string>En&amp;able Encryption</string>
     222         </property>
     223        </widget>
     224       </item>
     225       <item row="1" column="0">
     226        <spacer>
     227         <property name="orientation">
     228          <enum>Qt::Horizontal</enum>
     229         </property>
     230         <property name="sizeType">
     231          <enum>QSizePolicy::Fixed</enum>
     232         </property>
     233         <property name="sizeHint">
     234          <size>
     235           <width>20</width>
     236           <height>0</height>
     237          </size>
     238         </property>
     239        </spacer>
     240       </item>
     241       <item row="1" column="1">
     242        <widget class="QWidget" name="m_pWidgetEncryption">
     243         <property name="sizePolicy">
     244          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding">
     245           <horstretch>1</horstretch>
     246           <verstretch>0</verstretch>
     247          </sizepolicy>
     248         </property>
     249         <layout class="QGridLayout" name="m_pLayoutEncryptionSettings">
     250          <property name="leftMargin">
     251           <number>0</number>
     252          </property>
     253          <property name="topMargin">
     254           <number>0</number>
     255          </property>
     256          <property name="rightMargin">
     257           <number>0</number>
     258          </property>
     259          <property name="bottomMargin">
     260           <number>0</number>
     261          </property>
     262          <item row="0" column="0">
     263           <widget class="QLabel" name="m_pLabelCipher">
     264            <property name="text">
     265             <string>Encryption C&amp;ipher:</string>
     266            </property>
     267            <property name="alignment">
     268             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
     269            </property>
     270            <property name="buddy">
     271             <cstring>m_pComboCipher</cstring>
     272            </property>
     273           </widget>
     274          </item>
     275          <item row="0" column="1">
     276           <widget class="QComboBox" name="m_pComboCipher">
     277            <property name="whatsThis" >
     278             <string>Holds the cipher to be used for the virtual machine storage encryption.</string>
     279            </property>
     280           </widget>
     281          </item>
     282          <item row="1" column="0">
     283           <widget class="QLabel" name="m_pLabelPassword1">
     284            <property name="text">
     285             <string>E&amp;nter New Password:</string>
     286            </property>
     287            <property name="alignment">
     288             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
     289            </property>
     290            <property name="buddy">
     291             <cstring>m_pEditorEncryptionPassword</cstring>
     292            </property>
     293           </widget>
     294          </item>
     295          <item row="1" column="1">
     296           <widget class="QLineEdit" name="m_pEditorEncryptionPassword">
     297            <property name="whatsThis" >
     298             <string>Holds the password to be assigned for the virtual machine.</string>
     299            </property>
     300           </widget>
     301          </item>
     302          <item row="2" column="0">
     303           <widget class="QLabel" name="m_pLabelPassword2">
     304            <property name="text">
     305             <string>C&amp;onfirm New Password:</string>
     306            </property>
     307            <property name="alignment">
     308             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
     309            </property>
     310            <property name="buddy">
     311             <cstring>m_pEditorEncryptionPasswordConfirm</cstring>
     312            </property>
     313           </widget>
     314          </item>
     315          <item row="2" column="1">
     316           <widget class="QLineEdit" name="m_pEditorEncryptionPasswordConfirm">
     317            <property name="whatsThis" >
     318             <string>Confirms the password to be assigned for the virtual machine.</string>
     319            </property>
     320           </widget>
     321          </item>
     322         </layout>
     323        </widget>
     324       </item>
     325       <item row="2" column="1">
     326        <spacer>
     327         <property name="orientation">
     328          <enum>Qt::Vertical</enum>
     329         </property>
     330         <property name="sizeType">
     331          <enum>QSizePolicy::Expanding</enum>
     332         </property>
     333         <property name="sizeHint">
     334          <size>
     335           <width>0</width>
     336           <height>0</height>
     337          </size>
     338         </property>
     339        </spacer>
     340       </item>
     341      </layout>
     342     </widget>
    210343    </widget>
    211344   </item>
     
    231364 </customwidgets>
    232365 <resources/>
    233  <connections/>
     366 <connections>
     367  <connection>
     368   <sender>m_pCheckBoxEncryption</sender>
     369   <signal>toggled(bool)</signal>
     370   <receiver>m_pWidgetEncryption</receiver>
     371   <slot>setEnabled(bool)</slot>
     372  </connection>
     373 </connections>
    234374</ui>
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette