1 // frmNewAccount.cpp - New Account form.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
19 #include "frmNewAccount.h"
22 #include <wx/filefn.h>
23 #include <wx/fileconf.h>
25 #if defined(__WIN32__)
26 #include <cryptuiapi.h>
29 #include "carddav/carddav.h"
30 #include "common/dirs.h"
31 #include "common/svrblist.h"
32 #include "common/win32ssl.h"
33 #include "frmInvalidSSLCertificate.h"
35 frmNewAccount::frmNewAccount( wxWindow* parent )
37 frmNewAccountADT( parent )
40 // Disable the previous button upon form creation.
42 btnPrevious->Disable();
46 void frmNewAccount::CheckAccountName( wxCommandEvent& event )
49 // Check that the account name is valid.
51 wxString CheckAccName = txtAccountName->GetValue();
53 if ((txtAccountName->IsEmpty() && PageSeek == 2) || CheckAccName.Len() < 4){
65 void frmNewAccount::ProcessPrevious( wxCommandEvent& event )
68 // Go to the previous page.
74 // Currently at the Connection test screen.
79 szrNewAccount->RecalcSizes();
81 btnPrevious->Disable();
84 } else if (PageSeek == 1){
86 if (cmbServerType->GetCurrentSelection() == 0){
92 btnPrevious->Disable();
94 btnNext->SetLabel(_("Next >"));
99 // Currently at the Finish screen.
104 szrNewAccount->RecalcSizes();
106 btnNext->SetLabel(_("Next >"));
113 void frmNewAccount::ProcessNext( wxCommandEvent& event )
116 // Go to the next page or setup the new account.
122 if (cmbServerType->GetCurrentSelection() == 0){
128 btnPrevious->Enable();
129 szrNewAccount->RecalcSizes();
131 btnNext->SetLabel(_("Finish"));
136 // Check if server address matches against the blacklist.
137 // Bring up warning message if it does.
139 if (CheckBlacklist(txtServerAddress->GetValue())){
141 int MessageBoxResult = wxMessageBox(_("The server with the address given does not support the CardDAV protocol properly and shouldn't be used.\n\nData loss is very likely.\n\nDo you still want to continue using this server?"), _("Server warning"), wxYES_NO, this);
143 if (MessageBoxResult == wxNO){
152 bool ServerResult = FALSE;
153 bool ServerAction = FALSE;
155 wxString ServerMessage;
157 // Connection test screen.
162 szrNewAccount->RecalcSizes();
163 btnPrevious->Enable();
167 lblServerConnResult->SetLabel(wxT(""));
168 lblServerResponse->SetLabel(wxT(""));
169 lblServerSSLResult->SetLabel(wxT(""));
170 lblServerSSLValid->SetLabel(wxT(""));
171 lblAbleToLoginResult->SetLabel(wxT(""));
172 lblCardDAVSupportResult->SetLabel(wxT(""));
174 // Spawn a thread and check if server supports CardDAV.
178 lblServerConnResult->SetLabel(_("Testing..."));
180 UseSSL = chkUseSSL->GetValue();
181 CardDAVConn.SetupConnection(txtServerAddress->GetValue(),
182 wxAtoi(txtServerPort->GetValue()),
183 txtUsername->GetValue(),
184 txtPassword->GetValue(),
186 CardDAVConn.SetupResultBools(&ServerResult, &ServerAction);
188 #if defined(__WIN32__)
190 BOOL ModifiedCertificateData = FALSE;
194 // Verify SSL trust first before doing anything.
198 CURLcode sslcode = CardDAVConn.SSLVerifyTest();
200 if (sslcode == CURLE_OK){
204 } else if (sslcode == CURLE_SSL_CACERT || sslcode == CURLE_SSL_CONNECT_ERROR){
206 // Certificate is more than likely a self-signed or
207 // expired certificate so display the invalid
208 // SSL certificate message.
210 // Setup the data to be sent in the wxPostEvent command.
214 #if defined(__APPLE__)
216 SSLResult = DisplayTrustPanel(&CardDAVConn);
218 if (SSLResult != NSOKButton){
220 lblServerConnResult->SetLabel(_("Failed"));
221 lblServerResponse->SetLabel(_("Not applicable"));
222 lblServerSSLResult->SetLabel(_("Used"));
223 lblServerSSLValid->SetLabel(_("No"));
224 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
229 // Evalulate the trust object.
231 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
234 case kSecTrustResultProceed:
235 lblServerSSLValid->SetLabel(_("Verified"));
237 case kSecTrustResultConfirm:
238 lblServerSSLValid->SetLabel(_("Verified (user)"));
241 lblServerSSLValid->SetLabel(_("Unable to verify"));
244 lblServerResponse->SetLabel(_("Not applicable"));
245 lblServerSSLResult->SetLabel(_("Used"));
247 if (EvalResult != kSecTrustResultProceed){
253 #elif defined(__WIN32__)
255 CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(&CardDAVConn, (HWND)this->GetHandle());
257 if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){
258 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
261 if (ModifiedCertificateData == FALSE){
263 lblServerConnResult->SetLabel(_("Failed"));
264 lblServerResponse->SetLabel(_("Not applicable"));
265 lblServerSSLResult->SetLabel(_("Used"));
266 lblServerSSLValid->SetLabel(_("No"));
267 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
274 frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this);
276 frmICPtr->LoadDataNew(CardDAVConn.GetSSLVerifyResults(), txtServerAddress->GetValue());
277 frmICPtr->ShowModal();
279 SSLResult = frmICPtr->GetResult();
281 // Clean up before processing response.
286 // Process the response from the user.
290 // Accept the Certificate.
292 CardDAVConn.AllowSelfSignTest(TRUE);
294 } else if (SSLResult == 2){
296 // Reject the certificate, abort the task and mark as failed.
298 lblServerConnResult->SetLabel(_("Failed"));
299 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
308 // Something else happened. Stop the process and
309 // display an error message instead.
311 CURLcode sslcode = CardDAVConn.SSLVerifyTest();
313 lblServerConnResult->SetLabel(_("Failed"));
314 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
321 std::thread ConnTest(&CardDAV::Connect, &CardDAVConn);
325 if (ServerResult == FALSE && ModifiedCertificateData == FALSE){
327 lblServerConnResult->SetLabel(_("Failed"));
328 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage());
333 lblServerConnResult->SetLabel(_("Connected"));
337 if (CardDAVConn.CanDoSSL() == TRUE){
339 lblServerSSLResult->SetLabel(_("Used"));
343 lblServerSSLResult->SetLabel(_("Not Used"));
344 lblServerSSLValid->SetLabel(_("Not Applicable"));
348 #if defined(__APPLE__)
350 // Evalulate the trust object.
352 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
355 case kSecTrustResultProceed:
356 lblServerSSLValid->SetLabel(_("Verified"));
358 case kSecTrustResultConfirm:
359 lblServerSSLValid->SetLabel(_("Verified (user)"));
362 lblServerSSLValid->SetLabel(_("Unable to verify"));
365 #elif defined(__WIN32__)
367 if (ModifiedCertificateData == TRUE){
368 lblServerSSLValid->SetLabel(_("Verified (user)"));
370 lblServerSSLValid->SetLabel(_("Verified"));
375 if (CardDAVConn.SSLVerify() == TRUE && CardDAVConn.CanDoSSL() == TRUE){
377 lblServerSSLValid->SetLabel(_("Verified"));
379 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE && CardDAVConn.IsSelfSigned() == TRUE){
381 lblServerSSLValid->SetLabel(_("Verified (user)"));
383 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE) {
385 lblServerSSLValid->SetLabel(_("Unable to verify"));
391 if (CardDAVConn.CanDoCardDAV() == TRUE){
393 lblCardDAVSupportResult->SetLabel(_("Supported"));
397 lblCardDAVSupportResult->SetLabel(_("Unsupported"));
398 SetErrorMessageLabel();
403 if (CardDAVConn.AbleToLogin() == TRUE){
405 lblAbleToLoginResult->SetLabel(_("Yes"));
409 lblAbleToLoginResult->SetLabel(_("No"));
410 SetErrorMessageLabel();
415 // Get the address to process CardDAV requests.
417 ServerPrefix = CardDAVConn.GetDefaultAddressBookURL();
419 if (CardDAVConn.HasValidResponse() == TRUE){
421 lblServerResponse->SetLabel(_("Yes"));
425 lblServerResponse->SetLabel(_("No"));
426 SetErrorMessageLabel();
431 if (ServerResult == TRUE && CardDAVConn.HasValidResponse() == TRUE &&
433 CardDAVConn.CanDoCardDAV() == TRUE && CardDAVConn.AbleToLogin() == TRUE){
437 lblConnectionResultText->SetLabel(_("Click on Next to set the account name."));
441 SetErrorMessageLabel();
445 } else if (PageSeek == 2){
452 szrNewAccount->RecalcSizes();
455 btnNext->SetLabel(_("Finish"));
457 if (txtAccountName->IsEmpty() && PageSeek == 2){
467 } else if (PageSeek == 3){
471 wxString XestiaABPrefDirectory;
472 wxString XestiaABDirectory;
473 wxString AccountSettingsFile;
475 wxString RandomNumberSuffix = wxString::Format(wxT("%i"), rand() % 32767);
476 bool DirectoryCreated = FALSE;
478 #if defined(__HAIKU__)
480 //preffilename = wxT("noo");
482 #elif defined(__WIN32__)
484 XestiaABPrefDirectory = GetUserPrefDir();
485 XestiaABDirectory = GetUserDir();
487 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
489 // Open the file for writing.
491 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
493 // Check if account name already exists and return an error message
494 // if this is the case.
496 wxString AccountName;
499 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
503 if (txtAccountName->GetValue() == AccountName){
505 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
510 cfgfile->SetPath(wxT("/"));
511 ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
515 if (cmbServerType->GetCurrentSelection() == 1){
517 // Create the account directory.
519 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
521 if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
523 DirectoryCreated = TRUE;
527 if (DirectoryCreated == TRUE){
529 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
533 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
538 } else if (cmbServerType->GetCurrentSelection() == 0){
540 // Create the account directory.
542 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
544 if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".local"), 0740) == TRUE){
546 DirectoryCreated = TRUE;
550 if (DirectoryCreated == TRUE){
552 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
556 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
566 *ReloadAccountConfig = TRUE;
570 XestiaABPrefDirectory = GetUserPrefDir();
571 XestiaABDirectory = GetUserDir();
573 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
575 // Open the file for writing.
577 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
579 // Check if account name already exists and return an error message
580 // if this is the case.
582 wxString AccountName;
585 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
589 if (txtAccountName->GetValue() == AccountName){
591 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
596 cfgfile->SetPath(wxT("/"));
597 ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
601 if (cmbServerType->GetCurrentSelection() == 1){
603 // Create the account directory.
605 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
607 if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
609 DirectoryCreated = TRUE;
613 if (DirectoryCreated == TRUE){
615 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
619 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
624 } else if (cmbServerType->GetCurrentSelection() == 0){
626 // Create the account directory.
628 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
630 if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".local"), 0740) == TRUE){
632 DirectoryCreated = TRUE;
636 if (DirectoryCreated == TRUE){
638 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
642 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
652 *ReloadAccountConfig = TRUE;
662 void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgfilein, wxString AccountType, wxString DirectoryName){
664 // Write the new account details.
666 cfgfilein->SetPath(txtAccountName->GetValue());
667 cfgfilein->Write(wxT("address"), txtServerAddress->GetValue());
668 cfgfilein->Write(wxT("port"), txtServerPort->GetValue());
669 cfgfilein->Write(wxT("username"), txtUsername->GetValue());
670 cfgfilein->Write(wxT("password"), txtPassword->GetValue());
671 cfgfilein->Write(wxT("prefix"), ServerPrefix);
672 cfgfilein->Write(wxT("accountdir"), DirectoryName);
674 if (chkUseSSL->GetValue() == TRUE){
676 cfgfilein->Write(wxT("ssl"), wxT("true"));
680 cfgfilein->Write(wxT("ssl"), wxT("false"));
684 cfgfilein->Write(wxT("refresh"), wxT("1800"));
685 cfgfilein->Write(wxT("type"), AccountType);
689 void frmNewAccount::CloseWindow( wxCommandEvent& event )
694 *ReloadAccountConfig = FALSE;
699 void frmNewAccount::UpdateRequirements( wxCommandEvent& event )
702 // Update the options.
704 if (cmbServerType->GetCurrentSelection() == 1){
706 txtServerAddress->Enable();
707 txtServerPort->Enable();
708 txtUsername->Enable();
709 txtPassword->Enable();
712 } else if (cmbServerType->GetCurrentSelection() == 0){
714 txtServerAddress->Disable();
715 txtServerPort->Disable();
716 txtUsername->Disable();
717 txtPassword->Disable();
718 chkUseSSL->Disable();
724 void frmNewAccount::SetupPointers(bool *ReloadAccountInc){
726 // Setup the pointers for the new account window.
728 ReloadAccountConfig = ReloadAccountInc;
732 void frmNewAccount::SetErrorMessageLabel(){
734 lblConnectionResultText->SetLabel(_("A problem has occured whilst connecting to the CardDAV server.\nPlease review the above information and change the server details if needed.\nIf there are still problems, please speak to your system administrator(s)."));