1 // carddav.cpp - Main CardDAV Object file.
\r
3 // (c) 2012-2015 Xestia Software Development.
\r
5 // This file is part of Xestia Address Book.
\r
7 // Xestia Address Book is free software: you can redistribute it and/or modify
\r
8 // it under the terms of the GNU General Public License as published by the
\r
9 // Free Software Foundation, version 3 of the license.
\r
11 // Xestia Address Book is distributed in the hope that it will be useful,
\r
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 // GNU General Public License for more details.
\r
16 // You should have received a copy of the GNU General Public License along
\r
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
\r
19 #include "carddav.h"
\r
20 #include "../version.h"
\r
22 #include <wx/tokenzr.h>
\r
23 #include <wx/ffile.h>
\r
24 #include <libxml/parser.h>
\r
25 #include <libxml/tree.h>
\r
28 #include "../vcard/vcard.h"
\r
29 #include "../common/dirs.h"
\r
31 size_t CardDAV::WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){
\r
33 // Writeback function for the CardDAV object.
\r
36 Data = wxString::FromUTF8((char *)ptr);
\r
38 stream->Append(Data);
\r
40 // Get the SSL engine pointer and trust if required on certain operating systems.
\r
42 #if defined(__APPLE__)
\r
44 const struct curl_tlssessioninfo *TLSInfo;
\r
46 CURL *Connection = GetConnectionObject();
\r
47 TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
\r
49 if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
\r
50 SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &SecTrustObject);
\r
53 #elif defined(__WIN32__)
\r
55 const struct curl_tlssessioninfo *TLSInfo;
\r
57 CURL *Connection = GetConnectionObject();
\r
58 TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
\r
60 std::string CertName;
\r
62 if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
\r
64 // Free the previous certificate data.
\r
66 CertFreeCertificateContext(CertificateData);
\r
68 PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
\r
69 SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
\r
75 return size * nmemb;
\r
79 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){
\r
81 // Progress function for the CardDAV object.
\r
85 CardDAV *IncCardDAV = static_cast<CardDAV*>(clientdata);
\r
86 ProgressRet = IncCardDAV->ProgressFuncProc(clientdata, TTDown, NDown, TTUp, NUp);
\r
87 if (ProgressRet != 0){
\r
94 wxString CardDAV::ServerAddress;
\r
95 int CardDAV::ServerPort;
\r
96 wxString CardDAV::ServerUser;
\r
97 wxString CardDAV::ServerPass;
\r
98 wxString CardDAV::ServerPrefix;
\r
99 wxString CardDAV::ServerAccount;
\r
100 bool CardDAV::ServerSSL;
\r
101 bool *CardDAV::ServerResult;
\r
102 bool *CardDAV::ServerMonitor;
\r
103 bool CardDAV::SSLStatus;
\r
104 bool CardDAV::SSLVerified;
\r
105 bool CardDAV::ValidResponse;
\r
106 bool CardDAV::AuthPassed;
\r
107 bool CardDAV::HasCalDAVSupport;
\r
108 bool CardDAV::AbortConnection;
\r
109 wxString CardDAV::ServerResponse;
\r
110 wxString CardDAV::ServerMethod;
\r
111 wxString CardDAV::ServerFilenameLocation;
\r
112 wxString CardDAV::ServerUploadData;
\r
113 wxString CardDAV::ETagData;
\r
114 wxString CardDAV::ETagResult;
\r
115 bool CardDAV::UploadMode;
\r
116 bool CardDAV::EditMode;
\r
117 long CardDAV::ItemIndex;
\r
118 std::map<int, int> *CardDAV::ActivityListPtr;
\r
119 char CardDAV::curlerrbuffer[CURL_ERROR_SIZE];
\r
120 SSLCertCollection CardDAV::SSLCertCol;
\r
121 int CardDAV::SSLErrorCode;
\r
122 int CardDAV::ConnectionErrorCode;
\r
123 wxString CardDAV::PageHeader;
\r
124 wxString CardDAV::PageData;
\r
125 CURLcode CardDAV::claconncode;
\r
126 int CardDAV::HTTPErrorCode;
\r
127 wxString CardDAV::ErrorMessage;
\r
128 SSLCertCollection CardDAV::VerifyCertCollection;
\r
129 bool CardDAV::AllowSelfSign;
\r
130 #if defined(__APPLE__)
\r
131 SSLContext *CardDAV::SSLContextPointer;
\r
132 SecTrustRef CardDAV::SecTrustObject;
\r
134 #if defined(__WIN32__)
\r
135 PCCERT_CONTEXT CardDAV::CertificateData;
\r
137 #if defined(__APPLE__) || defined(__WIN32__)
\r
138 CURL *CardDAV::ConnectionObject;
\r
141 CardDAV::CardDAV(){
\r
143 // Setup the CardDAV object.
\r
147 SSLVerified = FALSE;
\r
148 AuthPassed = FALSE;
\r
149 ValidResponse = FALSE;
\r
150 HasCalDAVSupport = FALSE;
\r
151 SSLCertCol.SuccessCode = 0;
\r
152 AllowSelfSign = FALSE;
\r
154 AbortConnection = FALSE;
\r
155 UploadMode = FALSE;
\r
161 CardDAV::~CardDAV(){
\r
163 // Destroy the CardDAV object.
\r
167 size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata){
\r
170 // Upload function for the CardDAV object.
\r
172 struct UploadDataStruc *UploadPtr = (struct UploadDataStruc *)userdata;
\r
174 if (UploadPtr->sizeleft){
\r
176 //MeepMoop->sizeleft--;
\r
179 UploadPtr->sizeleft--;
\r
182 wxSChar = UploadPtr->readptr->Mid(UploadPtr->seek,1);
\r
184 //*(char *)ptr = (char)wxSChar.mb_str();
\r
186 strncpy((char *)ptr, (const char*)wxSChar.mb_str(wxConvUTF8), 1);
\r
198 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL){
\r
200 // Setup the CardDAV connection without the prefix/account.
\r
202 ServerAddress = SvrAddress;
\r
203 ServerPort = SvrPort;
\r
204 ServerUser = SvrUser;
\r
205 ServerPass = SvrPass;
\r
206 ServerSSL = SvrSSL;
\r
212 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL, wxString SvrPrefix, wxString SvrAccount){
\r
214 // Setup the CardDAV connection with the prefix/account.
\r
216 ServerAddress = SvrAddress;
\r
217 ServerPort = SvrPort;
\r
218 ServerUser = SvrUser;
\r
219 ServerPass = SvrPass;
\r
220 ServerSSL = SvrSSL;
\r
221 ServerPrefix = SvrPrefix;
\r
222 ServerAccount = SvrAccount;
\r
228 bool CardDAV::SetupResultBools(bool *SvrResult, bool *SvrMonitor){
\r
230 // Setup the result booleans.
\r
232 ServerResult = SvrResult;
\r
233 ServerMonitor = SvrMonitor;
\r
239 bool CardDAV::HasValidResponse(){
\r
241 // Check that CardDAV server gave a valid response.
\r
243 return ValidResponse;
\r
247 bool CardDAV::CanDoCardDAV(){
\r
249 // Check that the server has CardDAV support.
\r
251 return HasCalDAVSupport;
\r
255 bool CardDAV::CanDoSSL(){
\r
257 // Check that the server can do SSL.
\r
263 bool CardDAV::SSLVerify(){
\r
265 // Check that the server can verify SSL.
\r
267 return SSLVerified;
\r
271 bool CardDAV::AbleToLogin(){
\r
273 // Check that the user is able to login.
\r
279 bool CardDAV::IsSelfSigned(){
\r
281 // Check that self-signed certificates are allowed.
\r
283 return AllowSelfSign;
\r
287 int CardDAV::ProgressFuncProc(void *clientdata, double TTUp, double NUp, double TTDown, double NDown){
\r
289 // Progress function processing.
\r
291 if (AbortConnection == TRUE){
\r
303 void CardDAV::Abort(){
\r
305 // Abort (close) the connection.
\r
307 AbortConnection = TRUE;
\r
311 SSLCertCollection CardDAV::GetSSLVerifyResults(){
\r
313 // Get the SSL verification results.
\r
315 return VerifyCertCollection;
\r
319 void CardDAV::AllowSelfSignTest(bool AllowSelfSignIn){
\r
321 // Set the value to enable/disable SSL self-signed certificates.
\r
323 AllowSelfSign = AllowSelfSignIn;
\r
326 void CardDAV::GetSSLResults(){
\r
328 // Get the SSL results.
\r
332 void CardDAV::SetServerFilename(wxString Filename){
\r
334 // Set the server filename.
\r
336 ServerFilenameLocation = Filename;
\r
340 wxString CardDAV::GetPageData()
\r
343 // Get the server page data.
\r
349 wxString CardDAV::ETagValueResult(){
\r
351 // Get the ETag Result value.
\r
357 void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){
\r
359 // Setup the data to use with the CardDAV connection.
\r
361 ServerMethod = Method;
\r
362 ServerFilenameLocation = FilenameLocation;
\r
363 ServerUploadData = UploadData;
\r
365 // Check if ServerFilenameLocation has a / at
\r
366 // the start and if not then append it.
\r
368 /*if (ServerFilenameLocation.Left(1) != wxT("/")){
\r
370 // Not there so insert.
\r
372 ServerFilenameLocation = wxT("/") + ServerFilenameLocation;
\r
378 void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){
\r
380 // Setup the variable pointers.
\r
382 ActivityListPtr = actlist;
\r
383 ItemIndex = actindex;
\r
387 wxString CardDAV::GetETagData(){
\r
389 // Get the ETag data.
\r
395 void CardDAV::SetUploadMode(bool IncMode){
\r
397 // Set the upload mode.
\r
399 UploadMode = IncMode;
\r
403 void CardDAV::SetEditMode(bool EditModeInc){
\r
405 // Set the edit mode.
\r
407 EditMode = EditModeInc;
\r
411 int CardDAV::GetResultCode(){
\r
413 // Get the result code.
\r
415 return (int)claconncode;
\r
419 int CardDAV::GetHTTPCode(){
\r
421 // Get the HTTP error code.
\r
423 return HTTPErrorCode;
\r
427 wxString CardDAV::GetErrorBuffer(){
\r
429 // Get the error buffer.
\r
431 wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);
\r
433 return ErrorBuffer;
\r
437 SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){
\r
439 // Build and return the SSL collection.
\r
441 SSLCertCollection SSLCertInfo;
\r
443 // Grab the certificate data.
\r
446 struct curl_slist *certdata;
\r
447 struct curl_certinfo *certinfo;
\r
450 certptr.certdata = NULL;
\r
452 curl_easy_getinfo(conn, CURLINFO_CERTINFO, &certptr.certinfo);
\r
454 wxString CertPropName;
\r
455 wxString CertPropValue;
\r
457 for (int i = 0; i < certptr.certinfo->num_of_certs; i++){
\r
459 struct curl_slist *slist;
\r
460 SSLCertData SSLCertDataInc;
\r
462 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){
\r
464 wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");
\r
466 // Get first token as the property name.
\r
468 CertPropName = CertDataInc.GetNextToken();
\r
470 // Get remaining tokens as the property value.
\r
472 while(CertDataInc.HasMoreTokens()){
\r
474 CertPropValue.Append(CertDataInc.GetNextToken());
\r
478 SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));
\r
479 CertPropName.clear();
\r
480 CertPropValue.clear();
\r
484 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));
\r
488 return SSLCertInfo;
\r
492 SSLCertCollection CardDAV::GetCertificateData(){
\r
494 // Pass on the collected certificate data.
\r
500 wxString CardDAV::GetErrorMessage(){
\r
502 // Get the error message.
\r
504 return ErrorMessage;
\r
508 #if defined(__APPLE__) || defined(__WIN32__)
\r
510 CURL* CardDAV::GetConnectionObject(){
\r
512 // Get the CardDAV connection object.
\r
514 return ConnectionObject;
\r
518 void CardDAV::SetConnectionObject(CURL *ConnectionObjectIn){
\r
520 // Set the connection object.
\r
522 ConnectionObject = ConnectionObjectIn;
\r
528 #if defined(__WIN32__)
\r
530 PCCERT_CONTEXT CardDAV::GetCertificateContextPointer(){
\r
532 // Check that the PCCERT_CONTEXT has an address
\r
533 // other than NULL. Return nullptr if this is the
\r
536 if (CertificateData == NULL){
\r
540 // Get the certificate data.
\r
542 return CertificateData;
\r
546 CERT_CONTEXT CardDAV::GetCertificateContext(){
\r
548 // Check that the PCCERT_CONTEXT has an address
\r
549 // other than NULL. Return nullptr if this is the
\r
552 if (CertificateData == NULL){
\r
553 CERT_CONTEXT EmptyCertificateData = { 0 };
\r
554 return EmptyCertificateData;
\r
557 // Get the certificate data.
\r
559 return *CertificateData;
\r