// frmNewAccount.cpp - New Account form. // // (c) 2012-2015 Xestia Software Development. // // This file is part of Xestia Address Book. // // Xestia Address Book is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by the // Free Software Foundation, version 3 of the license. // // Xestia Address Book is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with Xestia Address Book. If not, see #include "frmNewAccount.h" #include #include #include #include #if defined(__WIN32__) #include #include "common/win32ssl.h" #endif #include "carddav/carddav.h" #include "common/dirs.h" #include "common/svrblist.h" #include "frmInvalidSSLCertificate.h" frmNewAccount::frmNewAccount( wxWindow* parent ) : frmNewAccountADT( parent ) { // Disable the previous button upon form creation. btnPrevious->Disable(); } void frmNewAccount::CheckAccountName( wxCommandEvent& event ) { // Check that the account name is valid. wxString CheckAccName = txtAccountName->GetValue(); if ((txtAccountName->IsEmpty() && PageSeek == 2) || CheckAccName.Len() < 4){ btnNext->Disable(); } else { btnNext->Enable(); } } void frmNewAccount::ProcessPrevious( wxCommandEvent& event ) { // Go to the previous page. PageSeek--; if (PageSeek == 0){ // Currently at the Connection test screen. tabConn->Hide(); tabFinish->Hide(); tabType->Show(); szrNewAccount->RecalcSizes(); btnPrevious->Disable(); btnNext->Enable(); } else if (PageSeek == 1){ if (cmbServerType->GetCurrentSelection() == 0){ tabConn->Hide(); tabFinish->Hide(); tabType->Show(); PageSeek = 0; btnPrevious->Disable(); btnNext->Enable(); btnNext->SetLabel(_("Next >")); return; } // Currently at the Finish screen. tabType->Hide(); tabConn->Show(); tabFinish->Hide(); szrNewAccount->RecalcSizes(); btnNext->SetLabel(_("Next >")); btnNext->Enable(); } } void frmNewAccount::ProcessNext( wxCommandEvent& event ) { // Go to the next page or setup the new account. PageSeek++; if (PageSeek == 1){ if (cmbServerType->GetCurrentSelection() == 0){ tabType->Hide(); tabConn->Hide(); tabFinish->Show(); PageSeek = 2; btnPrevious->Enable(); szrNewAccount->RecalcSizes(); btnNext->Disable(); btnNext->SetLabel(_("Finish")); return; } // Check if server address matches against the blacklist. // Bring up warning message if it does. if (CheckBlacklist(txtServerAddress->GetValue())){ 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); if (MessageBoxResult == wxNO){ PageSeek--; return; } } btnNext->Disable(); bool ServerResult = FALSE; bool ServerAction = FALSE; bool UseSSL = TRUE; wxString ServerMessage; // Connection test screen. tabType->Hide(); tabConn->Show(); tabFinish->Hide(); szrNewAccount->RecalcSizes(); btnPrevious->Enable(); // Reset screen. lblServerConnResult->SetLabel(wxT("")); lblServerResponse->SetLabel(wxT("")); lblServerSSLResult->SetLabel(wxT("")); lblServerSSLValid->SetLabel(wxT("")); lblAbleToLoginResult->SetLabel(wxT("")); lblCardDAVSupportResult->SetLabel(wxT("")); // Spawn a thread and check if server supports CardDAV. CardDAV CardDAVConn; lblServerConnResult->SetLabel(_("Testing...")); UseSSL = chkUseSSL->GetValue(); CardDAVConn.SetupConnection(txtServerAddress->GetValue(), wxAtoi(txtServerPort->GetValue()), txtUsername->GetValue(), txtPassword->GetValue(), UseSSL); CardDAVConn.SetupResultBools(&ServerResult, &ServerAction); #if defined(__WIN32__) BOOL ModifiedCertificateData = FALSE; #endif // Verify SSL trust first before doing anything. if (UseSSL == TRUE){ CURLcode sslcode = CardDAVConn.SSLVerifyTest(); if (sslcode == CURLE_OK){ } else if (sslcode == CURLE_SSL_CACERT || sslcode == CURLE_SSL_CONNECT_ERROR){ // Certificate is more than likely a self-signed or // expired certificate so display the invalid // SSL certificate message. // Setup the data to be sent in the wxPostEvent command. int SSLResult; #if defined(__APPLE__) SSLResult = DisplayTrustPanel(&CardDAVConn); if (SSLResult != NSOKButton){ lblServerConnResult->SetLabel(_("Failed")); lblServerResponse->SetLabel(_("Not applicable")); lblServerSSLResult->SetLabel(_("Used")); lblServerSSLValid->SetLabel(_("No")); lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str())); return; } else { // Evalulate the trust object. SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn); switch(EvalResult){ case kSecTrustResultProceed: lblServerSSLValid->SetLabel(_("Verified")); break; case kSecTrustResultConfirm: lblServerSSLValid->SetLabel(_("Verified (user)")); break; default: lblServerSSLValid->SetLabel(_("Unable to verify")); } lblServerResponse->SetLabel(_("Not applicable")); lblServerSSLResult->SetLabel(_("Used")); if (EvalResult != kSecTrustResultProceed){ return; } } #elif defined(__WIN32__) CRYPTUI_VIEWCERTIFICATE_STRUCTW CertificateData = BuildCertificateData(&CardDAVConn, (HWND)this->GetHandle()); if (!CryptUIDlgViewCertificate(&CertificateData, &ModifiedCertificateData)){ wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog")); } if (ModifiedCertificateData == FALSE){ lblServerConnResult->SetLabel(_("Failed")); lblServerResponse->SetLabel(_("Not applicable")); lblServerSSLResult->SetLabel(_("Used")); lblServerSSLValid->SetLabel(_("No")); lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str())); return; } #else frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this); frmICPtr->LoadDataNew(CardDAVConn.GetSSLVerifyResults(), txtServerAddress->GetValue()); frmICPtr->ShowModal(); SSLResult = frmICPtr->GetResult(); // Clean up before processing response. delete frmICPtr; frmICPtr = NULL; // Process the response from the user. if (SSLResult == 1){ // Accept the Certificate. CardDAVConn.AllowSelfSignTest(TRUE); } else if (SSLResult == 2){ // Reject the certificate, abort the task and mark as failed. lblServerConnResult->SetLabel(_("Failed")); lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str())); return; } #endif } else { // Something else happened. Stop the process and // display an error message instead. CURLcode sslcode = CardDAVConn.SSLVerifyTest(); lblServerConnResult->SetLabel(_("Failed")); lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str())); return; } } std::thread ConnTest(&CardDAV::Connect, &CardDAVConn); ConnTest.join(); #if defined(__WIN32__) if (ServerResult == FALSE && ModifiedCertificateData == FALSE){ #else if (ServerResult == FALSE){ #endif lblServerConnResult->SetLabel(_("Failed")); lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage()); return; } else { lblServerConnResult->SetLabel(_("Connected")); } if (CardDAVConn.CanDoSSL() == TRUE){ lblServerSSLResult->SetLabel(_("Used")); } else { lblServerSSLResult->SetLabel(_("Not Used")); lblServerSSLValid->SetLabel(_("Not Applicable")); } #if defined(__APPLE__) // Evalulate the trust object. SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn); switch(EvalResult){ case kSecTrustResultProceed: lblServerSSLValid->SetLabel(_("Verified")); break; case kSecTrustResultConfirm: lblServerSSLValid->SetLabel(_("Verified (user)")); break; default: lblServerSSLValid->SetLabel(_("Unable to verify")); } #elif defined(__WIN32__) if (ModifiedCertificateData == TRUE){ lblServerSSLValid->SetLabel(_("Verified (user)")); } else { lblServerSSLValid->SetLabel(_("Verified")); } #else if (CardDAVConn.SSLVerify() == TRUE && CardDAVConn.CanDoSSL() == TRUE){ lblServerSSLValid->SetLabel(_("Verified")); } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE && CardDAVConn.IsSelfSigned() == TRUE){ lblServerSSLValid->SetLabel(_("Verified (user)")); } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE) { lblServerSSLValid->SetLabel(_("Unable to verify")); } #endif if (CardDAVConn.CanDoCardDAV() == TRUE){ lblCardDAVSupportResult->SetLabel(_("Supported")); } else { lblCardDAVSupportResult->SetLabel(_("Unsupported")); SetErrorMessageLabel(); return; } if (CardDAVConn.AbleToLogin() == TRUE){ lblAbleToLoginResult->SetLabel(_("Yes")); } else { lblAbleToLoginResult->SetLabel(_("No")); SetErrorMessageLabel(); return; } // Get the address to process CardDAV requests. ServerPrefix = CardDAVConn.GetDefaultAddressBookURL(); if (CardDAVConn.HasValidResponse() == TRUE){ lblServerResponse->SetLabel(_("Yes")); } else { lblServerResponse->SetLabel(_("No")); SetErrorMessageLabel(); return; } if (ServerResult == TRUE && CardDAVConn.HasValidResponse() == TRUE && CardDAVConn.CanDoCardDAV() == TRUE && CardDAVConn.AbleToLogin() == TRUE){ btnNext->Enable(); lblConnectionResultText->SetLabel(_("Click on Next to set the account name.")); } else { SetErrorMessageLabel(); } } else if (PageSeek == 2){ // Finish screen. tabType->Hide(); tabConn->Hide(); tabFinish->Show(); szrNewAccount->RecalcSizes(); btnNext->Disable(); btnNext->SetLabel(_("Finish")); if (txtAccountName->IsEmpty() && PageSeek == 2){ btnNext->Disable(); } else { btnNext->Enable(); } } else if (PageSeek == 3){ // Finished. wxString XestiaABPrefDirectory; wxString XestiaABDirectory; wxString AccountSettingsFile; //wxFile ASFile; wxString RandomNumberSuffix = wxString::Format(wxT("%i"), rand() % 32767); bool DirectoryCreated = FALSE; #if defined(__HAIKU__) //preffilename = wxT("noo"); #elif defined(__WIN32__) XestiaABPrefDirectory = GetUserPrefDir(); XestiaABDirectory = GetUserDir(); AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts"); // Open the file for writing. wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile); // Check if account name already exists and return an error message // if this is the case. wxString AccountName; long itemindex = 0; bool ContinueAcc; ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex); while (ContinueAcc){ if (txtAccountName->GetValue() == AccountName){ wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR); return; } cfgfile->SetPath(wxT("/")); ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex); } if (cmbServerType->GetCurrentSelection() == 1){ // Create the account directory. wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix; if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".carddav"), 0740) == TRUE){ DirectoryCreated = TRUE; } if (DirectoryCreated == TRUE){ WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName); } else { wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory")); return; } } else if (cmbServerType->GetCurrentSelection() == 0){ // Create the account directory. wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix; if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".local"), 0740) == TRUE){ DirectoryCreated = TRUE; } if (DirectoryCreated == TRUE){ WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName); } else { wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory")); return; } } delete cfgfile; cfgfile = NULL; *ReloadAccountConfig = TRUE; #else XestiaABPrefDirectory = GetUserPrefDir(); XestiaABDirectory = GetUserDir(); AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts"); // Open the file for writing. wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile); // Check if account name already exists and return an error message // if this is the case. wxString AccountName; long itemindex = 0; bool ContinueAcc; ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex); while (ContinueAcc){ if (txtAccountName->GetValue() == AccountName){ wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR); return; } cfgfile->SetPath(wxT("/")); ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex); } if (cmbServerType->GetCurrentSelection() == 1){ // Create the account directory. wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix; if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".carddav"), 0740) == TRUE){ DirectoryCreated = TRUE; } if (DirectoryCreated == TRUE){ WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName); } else { wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory")); return; } } else if (cmbServerType->GetCurrentSelection() == 0){ // Create the account directory. wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix; if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".local"), 0740) == TRUE){ DirectoryCreated = TRUE; } if (DirectoryCreated == TRUE){ WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName); } else { wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory")); return; } } delete cfgfile; cfgfile = NULL; *ReloadAccountConfig = TRUE; #endif this->Close(); } } void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgfilein, wxString AccountType, wxString DirectoryName){ // Write the new account details. cfgfilein->SetPath(txtAccountName->GetValue()); cfgfilein->Write(wxT("address"), txtServerAddress->GetValue()); cfgfilein->Write(wxT("port"), txtServerPort->GetValue()); cfgfilein->Write(wxT("username"), txtUsername->GetValue()); cfgfilein->Write(wxT("password"), txtPassword->GetValue()); cfgfilein->Write(wxT("prefix"), ServerPrefix); cfgfilein->Write(wxT("accountdir"), DirectoryName); if (chkUseSSL->GetValue() == TRUE){ cfgfilein->Write(wxT("ssl"), wxT("true")); } else { cfgfilein->Write(wxT("ssl"), wxT("false")); } cfgfilein->Write(wxT("refresh"), wxT("1800")); cfgfilein->Write(wxT("type"), AccountType); } void frmNewAccount::CloseWindow( wxCommandEvent& event ) { // Close the window. *ReloadAccountConfig = FALSE; this->Close(); } void frmNewAccount::UpdateRequirements( wxCommandEvent& event ) { // Update the options. if (cmbServerType->GetCurrentSelection() == 1){ txtServerAddress->Enable(); txtServerPort->Enable(); txtUsername->Enable(); txtPassword->Enable(); chkUseSSL->Enable(); } else if (cmbServerType->GetCurrentSelection() == 0){ txtServerAddress->Disable(); txtServerPort->Disable(); txtUsername->Disable(); txtPassword->Disable(); chkUseSSL->Disable(); } } void frmNewAccount::SetupPointers(bool *ReloadAccountInc){ // Setup the pointers for the new account window. ReloadAccountConfig = ReloadAccountInc; } void frmNewAccount::SetErrorMessageLabel(){ 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).")); }