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
63 PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
\r
64 SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
\r
65 //QueryContextAttributesA(TLSInfo->internals, SECPKG_);
\r
70 return size * nmemb;
\r
74 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){
\r
76 // Progress function for the CardDAV object.
\r
80 CardDAV *IncCardDAV = static_cast<CardDAV*>(clientdata);
\r
81 ProgressRet = IncCardDAV->ProgressFuncProc(clientdata, TTDown, NDown, TTUp, NUp);
\r
82 if (ProgressRet != 0){
\r
89 wxString CardDAV::ServerAddress;
\r
90 int CardDAV::ServerPort;
\r
91 wxString CardDAV::ServerUser;
\r
92 wxString CardDAV::ServerPass;
\r
93 wxString CardDAV::ServerPrefix;
\r
94 wxString CardDAV::ServerAccount;
\r
95 bool CardDAV::ServerSSL;
\r
96 bool *CardDAV::ServerResult;
\r
97 bool *CardDAV::ServerMonitor;
\r
98 bool CardDAV::SSLStatus;
\r
99 bool CardDAV::SSLVerified;
\r
100 bool CardDAV::ValidResponse;
\r
101 bool CardDAV::AuthPassed;
\r
102 bool CardDAV::HasCalDAVSupport;
\r
103 bool CardDAV::AbortConnection;
\r
104 wxString CardDAV::ServerResponse;
\r
105 wxString CardDAV::ServerMethod;
\r
106 wxString CardDAV::ServerFilenameLocation;
\r
107 wxString CardDAV::ServerUploadData;
\r
108 wxString CardDAV::ETagData;
\r
109 wxString CardDAV::ETagResult;
\r
110 bool CardDAV::UploadMode;
\r
111 bool CardDAV::EditMode;
\r
112 long CardDAV::ItemIndex;
\r
113 std::map<int, int> *CardDAV::ActivityListPtr;
\r
114 char CardDAV::curlerrbuffer[CURL_ERROR_SIZE];
\r
115 SSLCertCollection CardDAV::SSLCertCol;
\r
116 int CardDAV::SSLErrorCode;
\r
117 int CardDAV::ConnectionErrorCode;
\r
118 wxString CardDAV::PageHeader;
\r
119 wxString CardDAV::PageData;
\r
120 CURLcode CardDAV::claconncode;
\r
121 int CardDAV::HTTPErrorCode;
\r
122 wxString CardDAV::ErrorMessage;
\r
123 SSLCertCollection CardDAV::VerifyCertCollection;
\r
124 bool CardDAV::AllowSelfSign;
\r
125 #if defined(__APPLE__)
\r
126 SSLContext *CardDAV::SSLContextPointer;
\r
127 SecTrustRef CardDAV::SecTrustObject;
\r
129 #if defined(__WIN32__)
\r
130 PCCERT_CONTEXT CardDAV::CertificateData;
\r
132 #if defined(__APPLE__) || defined(__WIN32__)
\r
133 CURL *CardDAV::ConnectionObject;
\r
136 CardDAV::CardDAV(){
\r
138 // Setup the CardDAV object.
\r
142 SSLVerified = FALSE;
\r
143 AuthPassed = FALSE;
\r
144 ValidResponse = FALSE;
\r
145 HasCalDAVSupport = FALSE;
\r
146 SSLCertCol.SuccessCode = 0;
\r
147 AllowSelfSign = FALSE;
\r
149 AbortConnection = FALSE;
\r
150 UploadMode = FALSE;
\r
156 CardDAV::~CardDAV(){
\r
158 // Destroy the CardDAV object.
\r
162 size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata){
\r
165 // Upload function for the CardDAV object.
\r
167 struct UploadDataStruc *UploadPtr = (struct UploadDataStruc *)userdata;
\r
169 if (UploadPtr->sizeleft){
\r
171 //MeepMoop->sizeleft--;
\r
174 UploadPtr->sizeleft--;
\r
177 wxSChar = UploadPtr->readptr->Mid(UploadPtr->seek,1);
\r
179 //*(char *)ptr = (char)wxSChar.mb_str();
\r
181 strncpy((char *)ptr, (const char*)wxSChar.mb_str(wxConvUTF8), 1);
\r
193 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL){
\r
195 // Setup the CardDAV connection without the prefix/account.
\r
197 ServerAddress = SvrAddress;
\r
198 ServerPort = SvrPort;
\r
199 ServerUser = SvrUser;
\r
200 ServerPass = SvrPass;
\r
201 ServerSSL = SvrSSL;
\r
207 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL, wxString SvrPrefix, wxString SvrAccount){
\r
209 // Setup the CardDAV connection with the prefix/account.
\r
211 ServerAddress = SvrAddress;
\r
212 ServerPort = SvrPort;
\r
213 ServerUser = SvrUser;
\r
214 ServerPass = SvrPass;
\r
215 ServerSSL = SvrSSL;
\r
216 ServerPrefix = SvrPrefix;
\r
217 ServerAccount = SvrAccount;
\r
223 bool CardDAV::SetupResultBools(bool *SvrResult, bool *SvrMonitor){
\r
225 // Setup the result booleans.
\r
227 ServerResult = SvrResult;
\r
228 ServerMonitor = SvrMonitor;
\r
234 bool CardDAV::HasValidResponse(){
\r
236 // Check that CardDAV server gave a valid response.
\r
238 return ValidResponse;
\r
242 bool CardDAV::CanDoCardDAV(){
\r
244 // Check that the server has CardDAV support.
\r
246 return HasCalDAVSupport;
\r
250 bool CardDAV::CanDoSSL(){
\r
252 // Check that the server can do SSL.
\r
258 bool CardDAV::SSLVerify(){
\r
260 // Check that the server can verify SSL.
\r
262 return SSLVerified;
\r
266 bool CardDAV::AbleToLogin(){
\r
268 // Check that the user is able to login.
\r
274 bool CardDAV::IsSelfSigned(){
\r
276 // Check that self-signed certificates are allowed.
\r
278 return AllowSelfSign;
\r
282 int CardDAV::ProgressFuncProc(void *clientdata, double TTUp, double NUp, double TTDown, double NDown){
\r
284 // Progress function processing.
\r
286 if (AbortConnection == TRUE){
\r
298 void CardDAV::Abort(){
\r
300 // Abort (close) the connection.
\r
302 AbortConnection = TRUE;
\r
306 SSLCertCollection CardDAV::GetSSLVerifyResults(){
\r
308 // Get the SSL verification results.
\r
310 return VerifyCertCollection;
\r
314 void CardDAV::AllowSelfSignTest(bool AllowSelfSignIn){
\r
316 // Set the value to enable/disable SSL self-signed certificates.
\r
318 AllowSelfSign = AllowSelfSignIn;
\r
321 void CardDAV::GetSSLResults(){
\r
323 // Get the SSL results.
\r
327 void CardDAV::SetServerFilename(wxString Filename){
\r
329 // Set the server filename.
\r
331 ServerFilenameLocation = Filename;
\r
335 wxString CardDAV::GetPageData()
\r
338 // Get the server page data.
\r
344 wxString CardDAV::ETagValueResult(){
\r
346 // Get the ETag Result value.
\r
352 void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){
\r
354 // Setup the data to use with the CardDAV connection.
\r
356 ServerMethod = Method;
\r
357 ServerFilenameLocation = FilenameLocation;
\r
358 ServerUploadData = UploadData;
\r
360 // Check if ServerFilenameLocation has a / at
\r
361 // the start and if not then append it.
\r
363 /*if (ServerFilenameLocation.Left(1) != wxT("/")){
\r
365 // Not there so insert.
\r
367 ServerFilenameLocation = wxT("/") + ServerFilenameLocation;
\r
373 void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){
\r
375 // Setup the variable pointers.
\r
377 ActivityListPtr = actlist;
\r
378 ItemIndex = actindex;
\r
382 wxString CardDAV::GetETagData(){
\r
384 // Get the ETag data.
\r
390 void CardDAV::SetUploadMode(bool IncMode){
\r
392 // Set the upload mode.
\r
394 UploadMode = IncMode;
\r
398 void CardDAV::SetEditMode(bool EditModeInc){
\r
400 // Set the edit mode.
\r
402 EditMode = EditModeInc;
\r
406 int CardDAV::GetResultCode(){
\r
408 // Get the result code.
\r
410 return (int)claconncode;
\r
414 int CardDAV::GetHTTPCode(){
\r
416 // Get the HTTP error code.
\r
418 return HTTPErrorCode;
\r
422 wxString CardDAV::GetErrorBuffer(){
\r
424 // Get the error buffer.
\r
426 wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);
\r
428 return ErrorBuffer;
\r
432 SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){
\r
434 // Build and return the SSL collection.
\r
436 SSLCertCollection SSLCertInfo;
\r
438 // Grab the certificate data.
\r
441 struct curl_slist *certdata;
\r
442 struct curl_certinfo *certinfo;
\r
445 certptr.certdata = NULL;
\r
447 curl_easy_getinfo(conn, CURLINFO_CERTINFO, &certptr.certinfo);
\r
449 wxString CertPropName;
\r
450 wxString CertPropValue;
\r
452 for (int i = 0; i < certptr.certinfo->num_of_certs; i++){
\r
454 struct curl_slist *slist;
\r
455 SSLCertData SSLCertDataInc;
\r
457 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){
\r
459 wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");
\r
461 // Get first token as the property name.
\r
463 CertPropName = CertDataInc.GetNextToken();
\r
465 // Get remaining tokens as the property value.
\r
467 while(CertDataInc.HasMoreTokens()){
\r
469 CertPropValue.Append(CertDataInc.GetNextToken());
\r
473 SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));
\r
474 CertPropName.clear();
\r
475 CertPropValue.clear();
\r
479 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));
\r
483 return SSLCertInfo;
\r
487 SSLCertCollection CardDAV::GetCertificateData(){
\r
489 // Pass on the collected certificate data.
\r
495 wxString CardDAV::GetErrorMessage(){
\r
497 // Get the error message.
\r
499 return ErrorMessage;
\r
503 #if defined(__APPLE__) || defined(__WIN32__)
\r
505 CURL* CardDAV::GetConnectionObject(){
\r
507 // Get the CardDAV connection object.
\r
509 return ConnectionObject;
\r
513 void CardDAV::SetConnectionObject(CURL *ConnectionObjectIn){
\r
515 // Set the connection object.
\r
517 ConnectionObject = ConnectionObjectIn;
\r
523 #if defined(__WIN32__)
\r
525 PCCERT_CONTEXT CardDAV::GetCertificateContextPointer(){
\r
527 // Get the certificate data.
\r
529 return CertificateData;
\r
533 CERT_CONTEXT CardDAV::GetCertificateContext(){
\r
535 // Get the certificate data.
\r
537 return *CertificateData;
\r