Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Win32 Support: Support for adding a new account on Windows.
[xestiaab/.git] / source / frmNewAccount.cpp
1 // frmNewAccount.cpp - New Account form.
2 //
3 // (c) 2012-2015 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
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.
10 //
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.
15 //
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"
20 #include <thread>
21 #include <cstdlib>
22 #include <wx/filefn.h>
23 #include <wx/fileconf.h>
25 #if defined(__WIN32__)
26 #include <cryptuiapi.h>
27 #endif
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 )
36 :
37 frmNewAccountADT( parent )
38 {
40         // Disable the previous button upon form creation.
42         btnPrevious->Disable();
43         
44 }
46 void frmNewAccount::CheckAccountName( wxCommandEvent& event )
47 {
48     
49         // Check that the account name is valid.
50     
51         wxString CheckAccName = txtAccountName->GetValue();
52     
53         if ((txtAccountName->IsEmpty() && PageSeek == 2) || CheckAccName.Len() < 4){
54         
55                 btnNext->Disable();
56         
57         } else {
58         
59                 btnNext->Enable();
60         
61         }
62     
63 }
65 void frmNewAccount::ProcessPrevious( wxCommandEvent& event )
66 {
68         // Go to the previous page.
70         PageSeek--;
71     
72         if (PageSeek == 0){
73         
74                 // Currently at the Connection test screen.
75         
76                 tabConn->Hide();
77                 tabFinish->Hide();
78                 tabType->Show();
79                 szrNewAccount->RecalcSizes();
80         
81                 btnPrevious->Disable();
82                 btnNext->Enable();
83         
84         } else if (PageSeek == 1){
85         
86                 if (cmbServerType->GetCurrentSelection() == 0){
87             
88                         tabConn->Hide();
89                         tabFinish->Hide();
90                         tabType->Show();
91                         PageSeek = 0;
92                         btnPrevious->Disable();
93                         btnNext->Enable();
94                         btnNext->SetLabel(_("Next >"));
95                         return;
96             
97                 }
98         
99                 // Currently at the Finish screen.
100         
101                 tabType->Hide();
102                 tabConn->Show();
103                 tabFinish->Hide();
104                 szrNewAccount->RecalcSizes();
105         
106                 btnNext->SetLabel(_("Next >"));
107                 btnNext->Enable();
108         
109         }
110     
113 void frmNewAccount::ProcessNext( wxCommandEvent& event )
116         // Go to the next page or setup the new account.
118         PageSeek++;
119     
120         if (PageSeek == 1){
121         
122                 if (cmbServerType->GetCurrentSelection() == 0){
123             
124                         tabType->Hide();
125                         tabConn->Hide();
126                         tabFinish->Show();
127                         PageSeek = 2;
128                         btnPrevious->Enable();
129                         szrNewAccount->RecalcSizes();
130                         btnNext->Disable();
131                         btnNext->SetLabel(_("Finish"));
132                         return;
133             
134                 }
135         
136                 // Check if server address matches against the blacklist.
137                 // Bring up warning message if it does.
138                 
139                 if (CheckBlacklist(txtServerAddress->GetValue())){
140                 
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);
142                 
143                         if (MessageBoxResult == wxNO){
144                                 PageSeek--;
145                                 return;
146                         }
147                         
148                 }
149                 
150                 btnNext->Disable();
151         
152                 bool ServerResult = FALSE;
153                 bool ServerAction = FALSE;
154                 bool UseSSL = TRUE;
155                 wxString ServerMessage;
156         
157                 // Connection test screen.
158         
159                 tabType->Hide();
160                 tabConn->Show();
161                 tabFinish->Hide();
162                 szrNewAccount->RecalcSizes();
163                 btnPrevious->Enable();
164         
165                 // Reset screen.
166         
167                 lblServerConnResult->SetLabel(wxT(""));
168                 lblServerResponse->SetLabel(wxT(""));
169                 lblServerSSLResult->SetLabel(wxT(""));
170                 lblServerSSLValid->SetLabel(wxT(""));
171                 lblAbleToLoginResult->SetLabel(wxT(""));
172                 lblCardDAVSupportResult->SetLabel(wxT(""));
173         
174                 // Spawn a thread and check if server supports CardDAV.
175         
176                 CardDAV CardDAVConn;
177         
178                 lblServerConnResult->SetLabel(_("Testing..."));
179         
180                 UseSSL = chkUseSSL->GetValue();
181                 CardDAVConn.SetupConnection(txtServerAddress->GetValue(),
182                         wxAtoi(txtServerPort->GetValue()),
183                         txtUsername->GetValue(),
184                         txtPassword->GetValue(),
185                         UseSSL);
186                 CardDAVConn.SetupResultBools(&ServerResult, &ServerAction);
187         
188 #if defined(__WIN32__)
190                 BOOL ModifiedCertificateData = FALSE;
192 #endif
194                 // Verify SSL trust first before doing anything.
196                 if (UseSSL == TRUE){
198                         CURLcode sslcode = CardDAVConn.SSLVerifyTest();
200                         if (sslcode == CURLE_OK){
201                                 
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.
211                                 
212                                 int SSLResult;
213                                 
214 #if defined(__APPLE__)
215         
216                                 SSLResult = DisplayTrustPanel(&CardDAVConn);
218                                 if (SSLResult != NSOKButton){
219                                         
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()));
225                                         return;
226                                         
227                                 } else {
228                                         
229                                         // Evalulate the trust object.
230                                         
231                                         SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
232                                         
233                                         switch(EvalResult){
234                                                 case kSecTrustResultProceed:
235                                                         lblServerSSLValid->SetLabel(_("Verified"));
236                                                         break;
237                                                 case kSecTrustResultConfirm:
238                                                         lblServerSSLValid->SetLabel(_("Verified (user)"));
239                                                         break;
240                                                 default:
241                                                         lblServerSSLValid->SetLabel(_("Unable to verify"));
242                                         }
243                                         
244                                         lblServerResponse->SetLabel(_("Not applicable"));
245                                         lblServerSSLResult->SetLabel(_("Used"));
246                                         
247                                         if (EvalResult != kSecTrustResultProceed){
248                                                 return;
249                                         }
250                                         
251                                 }
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"));
259                                 }
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()));
268                                         return;
270                                 }
272 #else
273                         
274                                 frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this);
276                                 frmICPtr->LoadDataNew(CardDAVConn.GetSSLVerifyResults(), txtServerAddress->GetValue());
277                                 frmICPtr->ShowModal();
278                                                                 
279                                 SSLResult = frmICPtr->GetResult();
280                                                         
281                                 // Clean up before processing response.
282                                 
283                                 delete frmICPtr;
284                                 frmICPtr = NULL;
285                                                         
286                                 // Process the response from the user.
287                                                         
288                                 if (SSLResult == 1){
289                                                                 
290                                         // Accept the Certificate.
292                                         CardDAVConn.AllowSelfSignTest(TRUE);
293                                                                 
294                                 } else if (SSLResult == 2){
295                                                                 
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()));
300                                         return;
301                                                                 
302                                 }
303                                 
304 #endif
306                         } else {
308                                 // Something else happened. Stop the process and
309                                 // display an error message instead.
311                                 CURLcode sslcode = CardDAVConn.SSLVerifyTest();
312                                 
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()));
315                                 return;
317                         }
319                 }
321                 std::thread ConnTest(&CardDAV::Connect, &CardDAVConn);
322         
323                 ConnTest.join();
324         
325                 if (ServerResult == FALSE && ModifiedCertificateData == FALSE){
326             
327                         lblServerConnResult->SetLabel(_("Failed"));
328                         lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage());
329                         return;
330                         
331                 } else {
332             
333                         lblServerConnResult->SetLabel(_("Connected"));
334             
335                 }
337                 if (CardDAVConn.CanDoSSL() == TRUE){
339                         lblServerSSLResult->SetLabel(_("Used"));
341                 } else {
342             
343                         lblServerSSLResult->SetLabel(_("Not Used"));
344                         lblServerSSLValid->SetLabel(_("Not Applicable"));
345             
346                 }
347                 
348 #if defined(__APPLE__)
350                 // Evalulate the trust object.
351                 
352                 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
353                 
354                 switch(EvalResult){
355                         case kSecTrustResultProceed:
356                                 lblServerSSLValid->SetLabel(_("Verified"));
357                                 break;
358                         case kSecTrustResultConfirm:
359                                 lblServerSSLValid->SetLabel(_("Verified (user)"));
360                                 break;
361                         default:
362                                 lblServerSSLValid->SetLabel(_("Unable to verify"));
363                 }
365 #elif defined(__WIN32__)
367                 if (ModifiedCertificateData == TRUE){
368                         lblServerSSLValid->SetLabel(_("Verified (user)"));
369                 } else {
370                         lblServerSSLValid->SetLabel(_("Verified"));
371                 }
373 #else
374                 
375                 if (CardDAVConn.SSLVerify() == TRUE && CardDAVConn.CanDoSSL() == TRUE){
376             
377                         lblServerSSLValid->SetLabel(_("Verified"));
378             
379                 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE && CardDAVConn.IsSelfSigned() == TRUE){
380         
381                         lblServerSSLValid->SetLabel(_("Verified (user)"));
382         
383                 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE) {
384             
385                         lblServerSSLValid->SetLabel(_("Unable to verify"));
386             
387                 }
388                 
389 #endif
390                 
391                 if (CardDAVConn.CanDoCardDAV() == TRUE){
392             
393                         lblCardDAVSupportResult->SetLabel(_("Supported"));
394             
395                 } else {
396             
397                         lblCardDAVSupportResult->SetLabel(_("Unsupported"));
398                         SetErrorMessageLabel();
399                         return;
400             
401                 }
402         
403                 if (CardDAVConn.AbleToLogin() == TRUE){
404             
405                         lblAbleToLoginResult->SetLabel(_("Yes"));
406             
407                 } else {
408             
409                         lblAbleToLoginResult->SetLabel(_("No"));
410                         SetErrorMessageLabel();
411                         return;
412             
413                 }
414         
415                 // Get the address to process CardDAV requests.
416         
417                 ServerPrefix = CardDAVConn.GetDefaultAddressBookURL();
418         
419                 if (CardDAVConn.HasValidResponse() == TRUE){
420             
421                         lblServerResponse->SetLabel(_("Yes"));
422             
423                 } else {
424             
425                         lblServerResponse->SetLabel(_("No"));
426                         SetErrorMessageLabel();
427                         return;
428             
429                 }
430         
431                 if (ServerResult == TRUE && CardDAVConn.HasValidResponse() == TRUE &&
433                         CardDAVConn.CanDoCardDAV() == TRUE && CardDAVConn.AbleToLogin() == TRUE){
434             
435                         btnNext->Enable();
436             
437                         lblConnectionResultText->SetLabel(_("Click on Next to set the account name."));
438             
439                 } else {
440             
441                         SetErrorMessageLabel();
442             
443                 }
444         
445         } else if (PageSeek == 2){
446         
447                 // Finish screen.
448         
449                 tabType->Hide();
450                 tabConn->Hide();
451                 tabFinish->Show();
452                 szrNewAccount->RecalcSizes();
453         
454                 btnNext->Disable();
455                 btnNext->SetLabel(_("Finish"));
456         
457                 if (txtAccountName->IsEmpty() && PageSeek == 2){
458         
459                         btnNext->Disable();
460             
461                 } else {
462         
463                         btnNext->Enable();
464             
465                 }
466         
467         } else if (PageSeek == 3){
468         
469                 // Finished.
470         
471                 wxString XestiaABPrefDirectory;
472                 wxString XestiaABDirectory;
473                 wxString AccountSettingsFile;
474                 //wxFile ASFile;
475                 wxString RandomNumberSuffix = wxString::Format(wxT("%i"), rand() % 32767);
476                 bool DirectoryCreated = FALSE;
477         
478 #if defined(__HAIKU__)
479         
480                 //preffilename = wxT("noo");
481         
482 #elif defined(__WIN32__)
483         
484                 XestiaABPrefDirectory = GetUserPrefDir();
485                 XestiaABDirectory = GetUserDir();
486         
487                 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
488         
489                 // Open the file for writing.
490         
491                 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
492         
493                 // Check if account name already exists and return an error message
494                 // if this is the case.
495         
496                 wxString AccountName;
497                 long itemindex = 0;
498                 bool ContinueAcc;
499                 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
500         
501                 while (ContinueAcc){
502             
503                         if (txtAccountName->GetValue() == AccountName){
504                 
505                                 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
506                                 return;
507                 
508                         }
509             
510                         cfgfile->SetPath(wxT("/"));
511                         ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
512             
513                 }
514         
515                 if (cmbServerType->GetCurrentSelection() == 1){
516             
517                         // Create the account directory.
518             
519                         wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
520             
521                         if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
522                 
523                                 DirectoryCreated = TRUE;
524                 
525                         }
526             
527                         if (DirectoryCreated == TRUE){
528                 
529                                 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
530                 
531                         } else {
532                 
533                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
534                                 return;
535                 
536                         }
537             
538                 } else if (cmbServerType->GetCurrentSelection() == 0){
539             
540                         // Create the account directory.
541             
542                         wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
543             
544                         if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".local"), 0740) == TRUE){
545                 
546                                 DirectoryCreated = TRUE;
547                 
548                         }
549             
550                         if (DirectoryCreated == TRUE){
551                 
552                                 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
553                 
554                         } else {
555                 
556                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
557                                 return;
558                 
559                         }
560             
561                 }
562         
563                 delete cfgfile;
564                 cfgfile = NULL;
565         
566                 *ReloadAccountConfig = TRUE;
567         
568 #else
569         
570                 XestiaABPrefDirectory = GetUserPrefDir();
571                 XestiaABDirectory = GetUserDir();
572         
573                 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
574         
575                 // Open the file for writing.
576         
577                 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
578         
579                 // Check if account name already exists and return an error message
580                 // if this is the case.
581         
582                 wxString AccountName;
583                 long itemindex = 0;
584                 bool ContinueAcc;
585                 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
586         
587                 while (ContinueAcc){
588             
589                         if (txtAccountName->GetValue() == AccountName){
590                 
591                                 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
592                                 return;
593                 
594                         }
595             
596                         cfgfile->SetPath(wxT("/"));
597                         ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
598             
599                 }
600         
601                 if (cmbServerType->GetCurrentSelection() == 1){
602             
603                         // Create the account directory.
604             
605                         wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
606             
607                         if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
608                 
609                                 DirectoryCreated = TRUE;
610                 
611                         }
612             
613                         if (DirectoryCreated == TRUE){
614                 
615                                 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
616                 
617                         } else {
618                 
619                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
620                                 return;
621                 
622                         }
623             
624                 } else if (cmbServerType->GetCurrentSelection() == 0){
625             
626                         // Create the account directory.
627             
628                         wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
629             
630                         if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".local"), 0740) == TRUE){
631                 
632                                 DirectoryCreated = TRUE;
633                 
634                         }
635             
636                         if (DirectoryCreated == TRUE){
637                 
638                                 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
639                 
640                         } else {
641                 
642                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
643                                 return;
644                 
645                         }
646             
647                 }
648         
649                 delete cfgfile;
650                 cfgfile = NULL;
651         
652                 *ReloadAccountConfig = TRUE;
653         
654 #endif
655         
656                 this->Close();
657         
658         }
659     
662 void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgfilein, wxString AccountType, wxString DirectoryName){
663     
664         // Write the new account details.
665     
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);
673     
674         if (chkUseSSL->GetValue() == TRUE){
675         
676                 cfgfilein->Write(wxT("ssl"), wxT("true"));
677         
678         } else {
679         
680                 cfgfilein->Write(wxT("ssl"), wxT("false"));
681         
682         }
683     
684         cfgfilein->Write(wxT("refresh"), wxT("1800"));
685         cfgfilein->Write(wxT("type"), AccountType);
686     
689 void frmNewAccount::CloseWindow( wxCommandEvent& event )
692         // Close the window.
694         *ReloadAccountConfig = FALSE;
695         this->Close();
696         
699 void frmNewAccount::UpdateRequirements( wxCommandEvent& event )
701     
702         // Update the options.
703     
704         if (cmbServerType->GetCurrentSelection() == 1){
705         
706                 txtServerAddress->Enable();
707                 txtServerPort->Enable();
708                 txtUsername->Enable();
709                 txtPassword->Enable();
710                 chkUseSSL->Enable();
711         
712         } else if (cmbServerType->GetCurrentSelection() == 0){
713         
714                 txtServerAddress->Disable();
715                 txtServerPort->Disable();
716                 txtUsername->Disable();
717                 txtPassword->Disable();
718                 chkUseSSL->Disable();
719         
720         }
721     
724 void frmNewAccount::SetupPointers(bool *ReloadAccountInc){
726         // Setup the pointers for the new account window.
727    
728         ReloadAccountConfig = ReloadAccountInc;
729     
732 void frmNewAccount::SetErrorMessageLabel(){
733         
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)."));
735         
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy