"Fossies" - the Fresh Open Source Software Archive

Member "src/Main/Forms/VolumePasswordPanel.cpp" (10 Oct 2018, 14898 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "VolumePasswordPanel.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2  Derived from source code of TrueCrypt 7.1a, which is
    3  Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
    4  by the TrueCrypt License 3.0.
    5 
    6  Modifications and additions to the original source code (contained in this file)
    7  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
    8  and are governed by the Apache License 2.0 the full text of which is
    9  contained in the file License.txt included in VeraCrypt binary and source
   10  code distribution packages.
   11 */
   12 
   13 #include "System.h"
   14 #include "Main/GraphicUserInterface.h"
   15 #include "KeyfilesDialog.h"
   16 #include "VolumePasswordPanel.h"
   17 #include "SecurityTokenKeyfilesDialog.h"
   18 
   19 namespace VeraCrypt
   20 {
   21     VolumePasswordPanel::VolumePasswordPanel (wxWindow* parent, MountOptions* options, shared_ptr <VolumePassword> password, bool disableTruecryptMode, shared_ptr <KeyfileList> keyfiles, bool enableCache, bool enablePassword, bool enableKeyfiles, bool enableConfirmation, bool enablePkcs5Prf, bool isMountPassword, const wxString &passwordLabel)
   22         : VolumePasswordPanelBase (parent), Keyfiles (new KeyfileList), EnablePimEntry (true)
   23     {
   24         if (keyfiles)
   25         {
   26             *Keyfiles = *keyfiles;
   27             UseKeyfilesCheckBox->SetValue (!Keyfiles->empty());
   28         }
   29         else
   30         {
   31             *Keyfiles = Gui->GetPreferences().DefaultKeyfiles;
   32             UseKeyfilesCheckBox->SetValue (Gui->GetPreferences().UseKeyfiles && !Keyfiles->empty());
   33         }
   34 
   35         PasswordTextCtrl->SetMaxLength (VolumePassword::MaxSize);
   36         ConfirmPasswordTextCtrl->SetMaxLength (VolumePassword::MaxSize);
   37 
   38         if (!passwordLabel.empty())
   39         {
   40             PasswordStaticText->SetLabel (passwordLabel);
   41             GridBagSizer->Detach (PasswordStaticText);
   42             GridBagSizer->Add (PasswordStaticText, wxGBPosition (0, 1), wxGBSpan (1, 1), wxALIGN_CENTER_VERTICAL | wxBOTTOM, Gui->GetDefaultBorderSize());
   43         }
   44 
   45         CacheCheckBox->Show (enableCache);
   46 
   47         if (!enablePassword && enableKeyfiles)
   48         {
   49             Layout();
   50             Fit();
   51             PasswordPlaceholderSizer->SetMinSize (wxSize (PasswordTextCtrl->GetSize().GetWidth(), -1));
   52         }
   53         else if (!enablePkcs5Prf)
   54         {
   55             GridBagSizer->Remove (PasswordPlaceholderSizer);
   56         }
   57 
   58         PasswordStaticText->Show (enablePassword);
   59         PasswordTextCtrl->Show (enablePassword);
   60         DisplayPasswordCheckBox->Show (enablePassword);
   61 
   62 
   63         EnablePimEntry = enablePassword && (!enableConfirmation || (enablePkcs5Prf && !isMountPassword));
   64         PimCheckBox->Show (EnablePimEntry);
   65         VolumePimStaticText->Show (false);
   66         VolumePimTextCtrl->SetMaxLength (MAX_PIM_DIGITS);
   67         VolumePimTextCtrl->Show (false);
   68         VolumePimHelpStaticText->Show (false);
   69 
   70         SetPimValidator ();
   71 
   72         ConfirmPasswordStaticText->Show (enableConfirmation);
   73         ConfirmPasswordTextCtrl->Show (enableConfirmation);
   74 
   75         UseKeyfilesCheckBox->Show (enableKeyfiles);
   76         KeyfilesButton->Show (enableKeyfiles);
   77 
   78         Pkcs5PrfStaticText->Show (enablePkcs5Prf);
   79         Pkcs5PrfChoice->Show (enablePkcs5Prf);
   80         TrueCryptModeCheckBox->Show (!disableTruecryptMode);
   81         HeaderWipeCountText->Show (enablePkcs5Prf && !isMountPassword);
   82         HeaderWipeCount->Show (enablePkcs5Prf && !isMountPassword);
   83 
   84         if (options && !disableTruecryptMode)
   85         {
   86             TrueCryptModeCheckBox->SetValue (options->TrueCryptMode);
   87             if (options->TrueCryptMode)
   88             {
   89                 PimCheckBox->Enable (false);
   90                 VolumePimStaticText->Enable (false);
   91                 VolumePimTextCtrl->Enable (false);
   92                 VolumePimHelpStaticText->Enable (false);
   93             }
   94         }
   95 
   96         if (EnablePimEntry && options && options->Pim > 0)
   97         {
   98             PimCheckBox->SetValue (true);
   99             PimCheckBox->Show (false);
  100             VolumePimStaticText->Show (true);
  101             VolumePimTextCtrl->Show (true);
  102             VolumePimHelpStaticText->Show (true);
  103             SetVolumePim (options->Pim);
  104         }
  105 
  106         if (enablePkcs5Prf)
  107         {
  108             int index, prfInitialIndex = 0;
  109             if (isMountPassword)
  110             {
  111                 // case of password for mounting
  112                 Pkcs5PrfChoice->Delete (0);
  113                 Pkcs5PrfChoice->Append (LangString["AUTODETECTION"]);
  114             }
  115             foreach_ref (const Pkcs5Kdf &kdf, Pkcs5Kdf::GetAvailableAlgorithms(false))
  116             {
  117                 if (!kdf.IsDeprecated() || isMountPassword)
  118                 {
  119                     index = Pkcs5PrfChoice->Append (kdf.GetName());
  120                     if (isMountPassword && options && options->Kdf
  121                         && (options->Kdf->GetName() == kdf.GetName())
  122                        )
  123                     {
  124                         prfInitialIndex = index;
  125                     }
  126                 }
  127             }
  128             Pkcs5PrfChoice->Select (prfInitialIndex);
  129         }
  130 
  131         if (!enablePkcs5Prf || (!enablePassword && !enableKeyfiles))
  132         {
  133             GridBagSizer->Remove (Pkcs5PrfSizer);
  134         }
  135 
  136         // Keyfiles drag & drop
  137         class FileDropTarget : public wxFileDropTarget
  138         {
  139         public:
  140             FileDropTarget (VolumePasswordPanel *panel) : Panel (panel) { }
  141 
  142             wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def)
  143             {
  144                 return wxDragLink;
  145             }
  146 
  147             bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames)
  148             {
  149                 foreach (const wxString &f, filenames)
  150                     Panel->AddKeyfile (make_shared <Keyfile> (wstring (f)));
  151 
  152                 return true;
  153             }
  154 
  155         protected:
  156             VolumePasswordPanel *Panel;
  157         };
  158 
  159         if (enableKeyfiles)
  160         {
  161             SetDropTarget (new FileDropTarget (this));
  162 #ifdef TC_MACOSX
  163             foreach (wxWindow *c, GetChildren())
  164                 c->SetDropTarget (new FileDropTarget (this));
  165 #endif
  166         }
  167 
  168         Layout();
  169         Fit();
  170     }
  171 
  172     VolumePasswordPanel::~VolumePasswordPanel ()
  173     {
  174         WipeTextCtrl (PasswordTextCtrl);
  175         WipeTextCtrl (ConfirmPasswordTextCtrl);
  176     }
  177 
  178     void VolumePasswordPanel::AddKeyfile (shared_ptr <Keyfile> keyfile)
  179     {
  180         if (!Keyfiles)
  181             Keyfiles.reset (new KeyfileList);
  182 
  183         Keyfiles->push_back (keyfile);
  184         UseKeyfilesCheckBox->SetValue (true);
  185     }
  186 
  187     void VolumePasswordPanel::SetPimValidator ()
  188     {
  189         wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST);  // wxFILTER_NUMERIC does not exclude - . , etc.
  190         const wxChar *valArr[] = { L"0", L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9" };
  191         validator.SetIncludes (wxArrayString (array_capacity (valArr), (const wxChar **) &valArr));
  192         VolumePimTextCtrl->SetValidator (validator);
  193     }
  194 
  195     void VolumePasswordPanel::DisplayPassword (bool display, wxTextCtrl **textCtrl, int row)
  196     {
  197         FreezeScope freeze (this);
  198         bool isPim = (*textCtrl == VolumePimTextCtrl);
  199         int colspan = isPim? 1 : 2;
  200 
  201         wxTextCtrl *newTextCtrl = new wxTextCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, display ? 0 : wxTE_PASSWORD);
  202         newTextCtrl->SetMaxLength (isPim? MAX_PIM_DIGITS : VolumePassword::MaxSize);
  203         newTextCtrl->SetValue ((*textCtrl)->GetValue());
  204         newTextCtrl->SetMinSize ((*textCtrl)->GetSize());
  205 
  206         GridBagSizer->Detach ((*textCtrl));
  207         GridBagSizer->Add (newTextCtrl, wxGBPosition (row, 1), wxGBSpan (1, colspan), wxEXPAND|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 5);
  208         (*textCtrl)->Show (false);
  209         WipeTextCtrl (*textCtrl);
  210 
  211         Fit();
  212         Layout();
  213         newTextCtrl->SetMinSize ((*textCtrl)->GetMinSize());
  214 
  215         newTextCtrl->Connect (wxEVT_COMMAND_TEXT_UPDATED, isPim? wxCommandEventHandler (VolumePasswordPanel::OnPimChanged): wxCommandEventHandler (VolumePasswordPanel::OnTextChanged), nullptr, this);
  216         delete *textCtrl;
  217         *textCtrl = newTextCtrl;
  218         if (isPim)
  219             SetPimValidator ();
  220     }
  221 
  222     shared_ptr <VolumePassword> VolumePasswordPanel::GetPassword () const
  223     {
  224         return GetPassword (PasswordTextCtrl);
  225     }
  226 
  227     shared_ptr <VolumePassword> VolumePasswordPanel::GetPassword (wxTextCtrl *textCtrl) const
  228     {
  229         shared_ptr <VolumePassword> password;
  230         wchar_t passwordBuf[VolumePassword::MaxSize + 1];
  231         finally_do_arg (BufferPtr, BufferPtr (reinterpret_cast <byte *> (passwordBuf), sizeof (passwordBuf)), { finally_arg.Erase(); });
  232 
  233 #ifdef TC_WINDOWS
  234         int len = GetWindowText (static_cast <HWND> (textCtrl->GetHandle()), passwordBuf, VolumePassword::MaxSize + 1);
  235         password = ToUTF8Password (passwordBuf, len);
  236 #else
  237         wxString passwordStr (textCtrl->GetValue());    // A copy of the password is created here by wxWidgets, which cannot be erased
  238         for (size_t i = 0; i < passwordStr.size() && i < VolumePassword::MaxSize; ++i)
  239         {
  240             passwordBuf[i] = (wchar_t) passwordStr[i];
  241             passwordStr[i] = L'X';
  242         }
  243         password = ToUTF8Password (passwordBuf, passwordStr.size() <= VolumePassword::MaxSize ? passwordStr.size() : VolumePassword::MaxSize);
  244 #endif
  245         return password;
  246     }
  247 
  248     shared_ptr <Pkcs5Kdf> VolumePasswordPanel::GetPkcs5Kdf (bool &bUnsupportedKdf) const
  249     {
  250         return GetPkcs5Kdf (GetTrueCryptMode(), bUnsupportedKdf);
  251     }
  252 
  253     shared_ptr <Pkcs5Kdf> VolumePasswordPanel::GetPkcs5Kdf (bool bTrueCryptMode, bool &bUnsupportedKdf) const
  254     {
  255         bUnsupportedKdf = false;
  256         try
  257         {
  258             int index = Pkcs5PrfChoice->GetSelection ();
  259             if ((wxNOT_FOUND == index) || (0 == index))
  260             {
  261                 // auto-detection
  262                 return shared_ptr <Pkcs5Kdf> ();
  263             }
  264             else
  265                 return Pkcs5Kdf::GetAlgorithm (wstring (Pkcs5PrfChoice->GetStringSelection()), bTrueCryptMode);
  266         }
  267         catch (ParameterIncorrect&)
  268         {
  269             bUnsupportedKdf = true;
  270             return shared_ptr <Pkcs5Kdf> ();
  271         }
  272     }
  273 
  274     int VolumePasswordPanel::GetVolumePim () const
  275     {
  276         if (VolumePimTextCtrl->IsEnabled () && VolumePimTextCtrl->IsShown ())
  277         {
  278             wxString pimStr (VolumePimTextCtrl->GetValue());
  279             long pim = 0;
  280             if (pimStr.IsEmpty())
  281                 return 0;
  282             if (((size_t) wxNOT_FOUND == pimStr.find_first_not_of (wxT("0123456789")))
  283                 && pimStr.ToLong (&pim)
  284                 && pim <= MAX_PIM_VALUE)
  285                 return (int) pim;
  286             else
  287                 return -1;
  288         }
  289         else
  290             return 0;
  291     }
  292 
  293     void VolumePasswordPanel::SetVolumePim (int pim)
  294     {
  295         if (pim > 0)
  296         {
  297             VolumePimTextCtrl->SetValue (StringConverter::FromNumber (pim));
  298         }
  299         else
  300         {
  301             VolumePimTextCtrl->SetValue (wxT(""));
  302         }
  303     }
  304 
  305     bool VolumePasswordPanel::GetTrueCryptMode () const
  306     {
  307         return TrueCryptModeCheckBox->GetValue ();
  308     }
  309     
  310     void VolumePasswordPanel::SetTrueCryptMode (bool trueCryptMode)
  311     {
  312         bool bEnablePIM = !trueCryptMode;
  313         TrueCryptModeCheckBox->SetValue (trueCryptMode);
  314         PimCheckBox->Enable (bEnablePIM);
  315         VolumePimStaticText->Enable (bEnablePIM);
  316         VolumePimTextCtrl->Enable (bEnablePIM);
  317         VolumePimHelpStaticText->Enable (bEnablePIM);
  318     }
  319 
  320     int VolumePasswordPanel::GetHeaderWipeCount () const
  321     {
  322         try
  323         {
  324             long wipeCount;
  325             wxString wipeCountStrDesc = HeaderWipeCount->GetStringSelection();
  326             wxString wipeCountStr = wipeCountStrDesc.BeforeFirst(wxT('-'));
  327             if (!wipeCountStr.ToLong(&wipeCount))
  328                 wipeCount = PRAND_HEADER_WIPE_PASSES;
  329             return (int) wipeCount;
  330         }
  331         catch (ParameterIncorrect&)
  332         {
  333             return PRAND_HEADER_WIPE_PASSES;
  334         }
  335     }
  336 
  337     void VolumePasswordPanel::OnAddKeyfileDirMenuItemSelected (wxCommandEvent& event)
  338     {
  339         try
  340         {
  341             DirectoryPath dir = Gui->SelectDirectory (this, LangString["SELECT_KEYFILE_PATH"]);
  342 
  343             if (!dir.IsEmpty())
  344             {
  345                 Keyfiles->push_back (make_shared <Keyfile> (dir));
  346 
  347                 UseKeyfilesCheckBox->SetValue (!Keyfiles->empty());
  348                 OnUpdate();
  349             }
  350         }
  351         catch (exception &e)
  352         {
  353             Gui->ShowError (e);
  354         }
  355     }
  356 
  357     void VolumePasswordPanel::OnAddKeyfilesMenuItemSelected (wxCommandEvent& event)
  358     {
  359         try
  360         {
  361             FilePathList files = Gui->SelectFiles (this, LangString["SELECT_KEYFILES"], false, true);
  362 
  363             if (!files.empty())
  364             {
  365                 foreach_ref (const FilePath &f, files)
  366                     Keyfiles->push_back (make_shared <Keyfile> (f));
  367 
  368                 UseKeyfilesCheckBox->SetValue (!Keyfiles->empty());
  369                 OnUpdate();
  370             }
  371         }
  372         catch (exception &e)
  373         {
  374             Gui->ShowError (e);
  375         }
  376     }
  377 
  378     void VolumePasswordPanel::OnAddSecurityTokenSignatureMenuItemSelected (wxCommandEvent& event)
  379     {
  380         try
  381         {
  382             SecurityTokenKeyfilesDialog dialog (this);
  383             if (dialog.ShowModal() == wxID_OK)
  384             {
  385                 foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths())
  386                 {
  387                     Keyfiles->push_back (make_shared <Keyfile> (wstring (path)));
  388                 }
  389 
  390                 if (!dialog.GetSelectedSecurityTokenKeyfilePaths().empty())
  391                 {
  392                     UseKeyfilesCheckBox->SetValue (!Keyfiles->empty());
  393                     OnUpdate();
  394                 }
  395             }
  396         }
  397         catch (exception &e)
  398         {
  399             Gui->ShowError (e);
  400         }
  401     }
  402 
  403     void VolumePasswordPanel::OnDisplayPasswordCheckBoxClick (wxCommandEvent& event)
  404     {
  405         DisplayPassword (event.IsChecked(), &PasswordTextCtrl, 1);
  406 
  407         if (ConfirmPasswordTextCtrl->IsShown())
  408             DisplayPassword (event.IsChecked(), &ConfirmPasswordTextCtrl, 2);
  409 
  410         if (VolumePimTextCtrl->IsShown())
  411             DisplayPassword (event.IsChecked(), &VolumePimTextCtrl, 3);
  412 
  413         OnUpdate();
  414     }
  415 
  416     void VolumePasswordPanel::OnKeyfilesButtonClick (wxCommandEvent& event)
  417     {
  418         KeyfilesDialog dialog (GetParent(), Keyfiles);
  419 
  420         if (dialog.ShowModal() == wxID_OK)
  421         {
  422             Keyfiles = dialog.GetKeyfiles();
  423 
  424             UseKeyfilesCheckBox->SetValue (!Keyfiles->empty());
  425             OnUpdate();
  426         }
  427     }
  428 
  429     void VolumePasswordPanel::OnKeyfilesButtonRightClick (wxMouseEvent& event)
  430     {
  431         wxMenu popup;
  432         Gui->AppendToMenu (popup, LangString["IDC_KEYADD"], this, wxCommandEventHandler (VolumePasswordPanel::OnAddKeyfilesMenuItemSelected));
  433         Gui->AppendToMenu (popup, LangString["IDC_ADD_KEYFILE_PATH"], this, wxCommandEventHandler (VolumePasswordPanel::OnAddKeyfileDirMenuItemSelected));
  434         Gui->AppendToMenu (popup, LangString["IDC_TOKEN_FILES_ADD"], this, wxCommandEventHandler (VolumePasswordPanel::OnAddSecurityTokenSignatureMenuItemSelected));
  435 
  436         PopupMenu (&popup, KeyfilesButton->GetPosition().x + 2, KeyfilesButton->GetPosition().y + 2);
  437     }
  438 
  439     void VolumePasswordPanel::OnKeyfilesButtonRightDown (wxMouseEvent& event)
  440     {
  441 #ifndef TC_MACOSX
  442         event.Skip();
  443 #endif
  444     }
  445 
  446     bool VolumePasswordPanel::PasswordsMatch () const
  447     {
  448         assert (ConfirmPasswordStaticText->IsShown());
  449         try
  450         {
  451             return *GetPassword (PasswordTextCtrl) == *GetPassword (ConfirmPasswordTextCtrl);
  452         }
  453         catch (PasswordException&)
  454         {
  455             return false;
  456         }
  457     }
  458 
  459     void VolumePasswordPanel::WipeTextCtrl (wxTextCtrl *textCtrl)
  460     {
  461         textCtrl->SetValue (wxString (L'X', textCtrl->GetLineLength(0)));
  462         GetPassword (textCtrl);
  463     }
  464 
  465     bool VolumePasswordPanel::UpdatePimHelpText (bool pimChanged)
  466     {
  467         bool guiUpdated = false;
  468         if (pimChanged && VolumePimHelpStaticText->GetForegroundColour() != *wxRED)
  469         {
  470             VolumePimHelpStaticText->SetForegroundColour(*wxRED);
  471             VolumePimHelpStaticText->SetLabel(LangString["PIM_CHANGE_WARNING"]);
  472             guiUpdated = true;
  473         }
  474         if (!pimChanged && VolumePimHelpStaticText->GetForegroundColour() != *wxBLACK)
  475         {
  476             VolumePimHelpStaticText->SetForegroundColour(*wxBLACK);
  477             VolumePimHelpStaticText->SetLabel(LangString["IDC_PIM_HELP"]);
  478             guiUpdated = true;
  479         }
  480 
  481         if (guiUpdated)
  482         {
  483             Layout();
  484             Fit();
  485             GetParent()->Layout();
  486             GetParent()->Fit();
  487         }
  488         return guiUpdated;
  489     }
  490 
  491     void VolumePasswordPanel::OnUsePimCheckBoxClick( wxCommandEvent& event )
  492     {
  493         if (EnablePimEntry)
  494         {
  495             PimCheckBox->Show (false);
  496             VolumePimStaticText->Show (true);
  497             VolumePimTextCtrl->Show (true);
  498             VolumePimHelpStaticText->Show (true);
  499 
  500             if (DisplayPasswordCheckBox->IsChecked ())
  501                 DisplayPassword (true, &VolumePimTextCtrl, 3);
  502             else
  503             {
  504                 Layout();
  505                 Fit();
  506             }
  507 
  508             GetParent()->Layout();
  509             GetParent()->Fit();
  510         }
  511     }
  512 
  513     void VolumePasswordPanel::OnTrueCryptModeChecked( wxCommandEvent& event )
  514     {
  515         bool bEnablePIM = !GetTrueCryptMode ();
  516         PimCheckBox->Enable (bEnablePIM);
  517         VolumePimStaticText->Enable (bEnablePIM);
  518         VolumePimTextCtrl->Enable (bEnablePIM);
  519         VolumePimHelpStaticText->Enable (bEnablePIM);
  520     }
  521 }