1 // frmNewAccount.cpp - frmNewAccount form functions
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Calendar 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 Calendar 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 Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "frmNewAccount.h"
21 DEFINE_EVENT_TYPE(UPDATERESULTS);
22 DEFINE_EVENT_TYPE(RUNCALDAVTEST);
24 BEGIN_EVENT_TABLE(frmNewAccount, wxDialog)
25 EVT_COMMAND(wxID_ANY, UPDATERESULTS, frmNewAccount::UpdateResults)
26 EVT_COMMAND(wxID_ANY, RUNCALDAVTEST, frmNewAccount::RunCalDAVTest)
29 frmNewAccount::frmNewAccount( wxWindow* parent )
31 frmNewAccountADT( parent )
34 // Disable the previous button upon form creation.
36 btnPrevious->Disable();
37 txtServerAddress->Disable();
38 txtServerPort->Disable();
39 txtUsername->Disable();
40 txtPassword->Disable();
45 void frmNewAccount::UpdateRequirements( wxCommandEvent& event )
47 // Update the options.
49 if (cmbServerType->GetCurrentSelection() == 1){
51 txtServerAddress->Enable();
52 txtServerPort->Enable();
53 txtUsername->Enable();
54 txtPassword->Enable();
57 } else if (cmbServerType->GetCurrentSelection() == 0){
59 txtServerAddress->Disable();
60 txtServerPort->Disable();
61 txtUsername->Disable();
62 txtPassword->Disable();
68 void frmNewAccount::Navigate( wxCommandEvent& event )
71 if (event.GetId() == wxID_NEXT)
80 btnPrevious->Disable();
86 btnNext->SetLabel(_("Next >"));
88 } else if (pageSeek == 2){
90 if (cmbServerType->GetCurrentSelection() == 0){
95 szrNewAccount->RecalcSizes();
99 btnPrevious->Enable();
100 btnNext->SetLabel(_("Finish"));
105 // Check if server address matches against the blacklist.
106 // Bring up warning message if it does.
108 if (CheckBlacklist(txtServerAddress->GetValue())){
110 int MessageBoxResult = wxMessageBox(_("The server with the address given does not support the CalDAV 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);
112 if (MessageBoxResult == wxNO){
121 bool ServerResult = FALSE;
122 bool ServerAction = FALSE;
124 wxString ServerMessage;
126 // Connection test screen.
131 szrNewAccount->RecalcSizes();
132 btnPrevious->Disable();
136 lblServerConnResult->SetLabel(wxT(""));
137 lblServerResponse->SetLabel(wxT(""));
138 lblServerSSLResult->SetLabel(wxT(""));
139 lblServerSSLValid->SetLabel(wxT(""));
140 lblAbleToLoginResult->SetLabel(wxT(""));
141 lblCalDAVSupportResult->SetLabel(wxT(""));
143 // Depending on account type, run the test.
145 if (cmbServerType->GetCurrentSelection() == 1){
146 wxCommandEvent RunTest(RUNCALDAVTEST);
147 wxPostEvent(this, RunTest);
150 } else if (pageSeek == 3){
157 szrNewAccount->RecalcSizes();
160 btnPrevious->Enable();
161 btnNext->SetLabel(_("Finish"));
163 if (txtAccountName->IsEmpty() && pageSeek == 2){
173 } else if (pageSeek == 4){
177 wxString xestiaCALPrefDirectory;
178 wxString xestiaCALDirectory;
179 wxString accountSettingsFile;
183 int randomNumber = rand() % 32767;
184 wxString randomNumberSuffix = wxString::Format(wxT("%i"), randomNumber);
185 bool directoryCreated = FALSE;
187 #if defined(__HAIKU__)
189 //preffilename = wxT("noo");
191 #elif defined(__WIN32__)
193 xestiaCALPrefDirectory = GetUserPrefDir();
194 xestiaCALDirectory = GetUserDir();
196 accountSettingsFile = xestiaCALPrefDirectory + wxT("accounts");
198 // Open the file for writing.
200 wxFileConfig *cfgFile = new wxFileConfig("", "", accountSettingsFile);
202 // Check if account name already exists and return an error message
203 // if this is the case.
205 wxString accountName;
208 continueAcc = cfgFile->GetFirstGroup(accountName, itemIndex);
212 if (txtAccountName->GetValue() == accountName){
214 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
219 cfgFile->SetPath(wxT("/"));
220 continueAcc = cfgFile->GetNextGroup(accountName, itemIndex);
224 if (cmbServerType->GetCurrentSelection() == 1){
226 // Create the account directory.
228 wxString directoryName = txtAccountName->GetValue().Mid(0, 30) + randomNumberSuffix;
230 if (wxMkdir(xestiaCALDirectory + wxT("\\accounts\\") + directoryName + wxT(".local"), 0740) == TRUE){
232 directoryCreated = TRUE;
236 if (directoryCreated == TRUE){
238 WriteAccountDetails(cfgFile, wxT("Local"), directoryName);
242 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
252 *reloadAccountConfig = TRUE;
256 xestiaCALPrefDirectory = GetUserPrefDir();
257 xestiaCALDirectory = GetUserDir();
259 accountSettingsFile = xestiaCALPrefDirectory + wxT("accounts");
261 // Open the file for writing.
263 wxFileConfig *cfgFile = new wxFileConfig("", "", accountSettingsFile);
265 // Check if account name already exists and return an error message
266 // if this is the case.
268 wxString accountName;
271 continueAcc = cfgFile->GetFirstGroup(accountName, itemIndex);
275 if (txtAccountName->GetValue() == accountName){
277 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
282 cfgFile->SetPath(wxT("/"));
283 continueAcc = cfgFile->GetNextGroup(accountName, itemIndex);
287 if (cmbServerType->GetCurrentSelection() == 1){
289 // Create the account directory.
291 wxString directoryName = txtAccountName->GetValue().Mid(0, 30) + randomNumberSuffix;
293 if (wxMkdir(xestiaCALDirectory + wxT("/accounts/") + directoryName + wxT(".Local"), 0740) == TRUE){
295 directoryCreated = TRUE;
299 if (directoryCreated == TRUE){
301 WriteAccountDetails(cfgFile, wxT("Local"), directoryName);
305 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
315 *reloadAccountConfig = true;
325 void frmNewAccount::CloseWindow( wxCommandEvent& event )
330 *reloadAccountConfig = FALSE;
335 void frmNewAccount::SetupPointers(bool *ReloadAccountInc, CalendarDataStorage *dataStorage){
337 // Setup the pointers for the new account window.
339 reloadAccountConfig = ReloadAccountInc;
343 void frmNewAccount::CheckAccountName( wxCommandEvent& event )
346 // Check that the account name is valid.
348 wxString checkAccName = txtAccountName->GetValue();
350 if ((txtAccountName->IsEmpty() && pageSeek == 2) || checkAccName.Len() < 4){
362 void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgFileIn, wxString accountType, wxString directoryName){
364 // Write the new account details.
366 cfgFileIn->SetPath(txtAccountName->GetValue());
367 cfgFileIn->Write(wxT("address"), txtServerAddress->GetValue());
368 cfgFileIn->Write(wxT("port"), txtServerPort->GetValue());
369 cfgFileIn->Write(wxT("username"), txtUsername->GetValue());
370 cfgFileIn->Write(wxT("password"), txtPassword->GetValue());
371 cfgFileIn->Write(wxT("prefix"), serverPrefix);
372 cfgFileIn->Write(wxT("accountdir"), directoryName);
374 if (chkUseSSL->GetValue() == TRUE){
376 cfgFileIn->Write(wxT("ssl"), wxT("true"));
380 cfgFileIn->Write(wxT("ssl"), wxT("false"));
384 cfgFileIn->Write(wxT("refresh"), wxT("1800"));
385 cfgFileIn->Write(wxT("type"), accountType);
389 void frmNewAccount::UpdateResults( wxCommandEvent &event )
394 void frmNewAccount::RunCalDAVTest( wxCommandEvent &event )
396 NewAccountResult *resultData = new NewAccountResult;
398 lblServerConnResult->SetLabel(_("Testing..."));
399 lblCalDAVSupportResult->SetLabel(wxT(""));
400 lblServerResponse->SetLabel(wxT(""));
401 lblServerSSLResult->SetLabel(wxT(""));
402 lblServerSSLValid->SetLabel(wxT(""));
403 lblAbleToLoginResult->SetLabel(wxT(""));
404 bool usingSSLBypass = false;
406 // Setup a CalDAV connection object for testing.
408 CalDAVConnectionData connData;
409 connData.hostname = txtServerAddress->GetValue().ToStdString();
410 connData.port = wxAtoi(txtServerPort->GetValue());
411 connData.username = txtUsername->GetValue().ToStdString();
412 connData.password = txtPassword->GetValue().ToStdString();
413 connData.useSSL = chkUseSSL->GetValue() ? true : false);
415 CalDAV testConnection;
416 testConnection.SetupConnectionData(&connData);
418 /*CardDAV2 TestConnection(txtServerAddress->GetValue().ToStdString(),
419 wxAtoi(txtServerPort->GetValue()),
420 txtUsername->GetValue().ToStdString(),
421 txtPassword->GetValue().ToStdString(),
422 chkUseSSL->GetValue() ? true : false);*/
424 // Test the connection.
426 testConnection.SetupConnectionObject();
427 CalDAVServerResult testConnectionResult = testConnection.Connect(false);
429 // If server is using SSL, verify that the SSL connection is valid.
431 if (testConnection.SSLVerify() == COSSL_UNABLETOVERIFY){
432 #if defined(__APPLE__)
434 testConnection.BypassSSLVerification(true);
436 CalDAVServerResult testConnection = testConnection.Connect(false);
438 testConnection.BypassSSLVerification(false);
440 int SSLResult = DisplayTrustPanel(&TestConnection);
442 if (SSLResult != NSOKButton){
444 lblServerConnResult->SetLabel(_("Failed"));
445 lblServerResponse->SetLabel(_("Not applicable"));
446 lblServerSSLResult->SetLabel(_("Used"));
447 lblServerSSLValid->SetLabel(_("No"));
448 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + TestConnection.GetErrorMessage());
449 btnPrevious->Enable(true);
454 // Evalulate the trust object.
456 SecTrustResultType evalResult = ProcessResultType(&testConnection);
459 case kSecTrustResultProceed:
460 lblServerSSLValid->SetLabel(_("Verified"));
462 case kSecTrustResultConfirm:
463 lblServerSSLValid->SetLabel(_("Verified (user)"));
466 lblServerSSLValid->SetLabel(_("Unable to verify"));
469 lblServerResponse->SetLabel(_("Not applicable"));
470 lblServerSSLResult->SetLabel(_("Used"));
472 if (evalResult != kSecTrustResultProceed){
478 #elif defined(__WIN32__)
480 testConnection.BypassSSLVerification(true);
482 CalDAVServerResult testConnectionResult = testConnection.Connect(false);
484 testConnection.BypassSSLVerification(false);
486 bool modifiedCertificateData = false;
488 CRYPTUI_VIEWCERTIFICATE_STRUCTW certificateDialogData = BuildCertificateData(&testConnection, (HWND)this->GetHandle());
490 if (!CryptUIDlgViewCertificate(&certificateDialogData, &modifiedCertificateData)){
491 wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
494 if (modifiedCertificateData == false){
496 lblServerConnResult->SetLabel(_("Failed"));
497 lblServerResponse->SetLabel(_("Not applicable"));
498 lblServerSSLResult->SetLabel(_("Used"));
499 lblServerSSLValid->SetLabel(_("No"));
500 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + testConnection.GetErrorMessage());
501 btnPrevious->Enable(true);
508 // Connect again and fetch SSL certificate information.
510 testConnection.BypassSSLVerification(true);
512 CalDAVServerResult testConnectionResult = testConnection.Connect(false);
514 testConnection.BypassSSLVerification(false);
516 SSLCertCollectionString certData = testConnection.BuildSSLCollection();
517 frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this);
519 frmICPtr->LoadDataNew(CertData, txtServerAddress->GetValue().ToStdString());
520 frmICPtr->ShowModal();
522 int sslResult = frmICPtr->GetResult();
524 // Clean up before processing response.
529 // Process the response from the user.
533 // Accept the Certificate.
535 usingSSLBypass = true;
536 testConnection.BypassSSLVerification(true);
538 CalDAVServerResult testConnectionResult = testConnection.Connect(true);
540 testConnection.BypassSSLVerification(false);
542 } else if (sslResult == 2){
544 // Reject the certificate, abort the task and mark as failed.
546 // TODO: Integrate into the code.
548 //lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
555 testConnectionResult = testConnection.Connect(true);
557 // Get the server prefix if the connection was successful.
559 if (testConnectionResult == COCONNECT_OK){
561 if (usingSSLBypass == true){
562 testConnection.BypassSSLVerification(true);
565 std::string receivedServerPrefix;
567 receivedServerPrefix = testConnection.GetUserPrincipal();
568 serverPrefix = receivedServerPrefix;
570 if (usingSSLBypass == true){
571 testConnection.BypassSSLVerification(true);
576 testConnectionResult == COCONNECT_OK ? resultData->Connected = true : resultData->Connected = false;
578 resultData->SSLStatus = TestConnection.CanDoSSL();
579 resultData->SSLVerified = TestConnection.SSLVerify();
580 resultData->ValidResponse = TestConnection.HasValidResponse();
581 resultData->AuthPassed = TestConnection.AbleToLogin();
582 resultData->CanProcess = TestConnection.CanDoProcessing();
583 resultData->ErrorMessage = TestConnection.GetErrorMessage();
585 // Post event back confirming the tests.
587 wxCommandEvent resultsEvent(UPDATERESULTS);
588 resultsEvent.SetClientData(resultData);
589 wxPostEvent(this, resultsEvent);