Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Check for NULL pointers for CertificateData in the GetCertificateContextPointer and...
[xestiaab/.git] / source / carddav / carddav.cpp
1 // carddav.cpp - Main CardDAV Object file.\r
2 //\r
3 // (c) 2012-2015 Xestia Software Development.\r
4 //\r
5 // This file is part of Xestia Address Book.\r
6 //\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
10 //\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
15 //\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
18 \r
19 #include "carddav.h"\r
20 #include "../version.h"\r
21 #include <wx/wx.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
26 #include <map>\r
27 #include <thread>\r
28 #include "../vcard/vcard.h"\r
29 #include "../common/dirs.h"\r
30 \r
31 size_t CardDAV::WritebackFunc(char *ptr, size_t size, size_t nmemb, wxString *stream){\r
32         \r
33         // Writeback function for the CardDAV object.\r
34         \r
35         wxString Data;\r
36         Data = wxString::FromUTF8((char *)ptr);\r
37         \r
38         stream->Append(Data);\r
39         \r
40         // Get the SSL engine pointer and trust if required on certain operating systems.\r
41         \r
42 #if defined(__APPLE__)\r
43         \r
44         const struct curl_tlssessioninfo *TLSInfo;\r
45         CURLcode TLSCode;\r
46         CURL *Connection = GetConnectionObject();\r
47         TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);\r
48         \r
49         if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){\r
50                 SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &SecTrustObject);\r
51         }\r
52         \r
53 #elif defined(__WIN32__)\r
54 \r
55         const struct curl_tlssessioninfo *TLSInfo;\r
56         CURLcode TLSCode;\r
57         CURL *Connection = GetConnectionObject();\r
58         TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);\r
59 \r
60         std::string CertName;\r
61 \r
62         if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){\r
63 \r
64                 // Free the previous certificate data.\r
65 \r
66                 CertFreeCertificateContext(CertificateData);\r
67 \r
68                 PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;\r
69                 SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);\r
70 \r
71         }\r
72 \r
73 #endif\r
74         \r
75         return size * nmemb;\r
76 \r
77 }\r
78 \r
79 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){\r
80 \r
81         // Progress function for the CardDAV object.\r
82         \r
83         int ProgressRet;\r
84         \r
85         CardDAV *IncCardDAV = static_cast<CardDAV*>(clientdata);\r
86         ProgressRet = IncCardDAV->ProgressFuncProc(clientdata, TTDown, NDown, TTUp, NUp);\r
87         if (ProgressRet != 0){\r
88                 return 1;\r
89         }\r
90         return 0;\r
91 \r
92 }\r
93 \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
133 #endif\r
134 #if defined(__WIN32__)\r
135 PCCERT_CONTEXT CardDAV::CertificateData;\r
136 #endif\r
137 #if defined(__APPLE__) || defined(__WIN32__)\r
138 CURL *CardDAV::ConnectionObject;\r
139 #endif\r
140 \r
141 CardDAV::CardDAV(){\r
142         \r
143         // Setup the CardDAV object.\r
144         \r
145         ServerPort = 8080;\r
146         SSLStatus = FALSE;\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
153 \r
154         AbortConnection = FALSE;\r
155         UploadMode = FALSE;\r
156         EditMode = FALSE;\r
157         HTTPErrorCode = 0;\r
158         \r
159 }\r
160 \r
161 CardDAV::~CardDAV(){\r
162 \r
163         // Destroy the CardDAV object.\r
164         \r
165 }\r
166 \r
167 size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata){\r
168 \r
169         \r
170         // Upload function for the CardDAV object.\r
171         \r
172         struct UploadDataStruc *UploadPtr = (struct UploadDataStruc *)userdata;\r
173 \r
174         if (UploadPtr->sizeleft){\r
175 \r
176                 //MeepMoop->sizeleft--;\r
177                 //return 1;\r
178 \r
179                 UploadPtr->sizeleft--;\r
180                 wxString wxSChar;\r
181 \r
182                 wxSChar = UploadPtr->readptr->Mid(UploadPtr->seek,1);\r
183 \r
184                 //*(char *)ptr = (char)wxSChar.mb_str();\r
185 \r
186                 strncpy((char *)ptr, (const char*)wxSChar.mb_str(wxConvUTF8), 1);\r
187 \r
188                 UploadPtr->seek++;\r
189 \r
190                 return 1;\r
191 \r
192         }\r
193 \r
194         return 0;\r
195 \r
196 }\r
197 \r
198 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL){\r
199 \r
200         // Setup the CardDAV connection without the prefix/account.\r
201         \r
202         ServerAddress = SvrAddress;\r
203         ServerPort = SvrPort;\r
204         ServerUser = SvrUser;\r
205         ServerPass = SvrPass;\r
206         ServerSSL = SvrSSL;\r
207         \r
208         return TRUE;\r
209 \r
210 }\r
211 \r
212 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL, wxString SvrPrefix, wxString SvrAccount){\r
213 \r
214         // Setup the CardDAV connection with the prefix/account.\r
215         \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
223 \r
224         return TRUE;\r
225 \r
226 }\r
227 \r
228 bool CardDAV::SetupResultBools(bool *SvrResult, bool *SvrMonitor){\r
229 \r
230         // Setup the result booleans.\r
231         \r
232         ServerResult = SvrResult;\r
233         ServerMonitor = SvrMonitor;\r
234 \r
235         return TRUE;\r
236 \r
237 }\r
238 \r
239 bool CardDAV::HasValidResponse(){\r
240 \r
241         // Check that CardDAV server gave a valid response.\r
242         \r
243         return ValidResponse;\r
244 \r
245 }\r
246 \r
247 bool CardDAV::CanDoCardDAV(){\r
248 \r
249         // Check that the server has CardDAV support.\r
250         \r
251         return HasCalDAVSupport;\r
252 \r
253 }\r
254 \r
255 bool CardDAV::CanDoSSL(){\r
256 \r
257         // Check that the server can do SSL.\r
258         \r
259         return SSLStatus;\r
260 \r
261 }\r
262 \r
263 bool CardDAV::SSLVerify(){\r
264 \r
265         // Check that the server can verify SSL.\r
266         \r
267         return SSLVerified;\r
268 \r
269 }\r
270 \r
271 bool CardDAV::AbleToLogin(){\r
272 \r
273         // Check that the user is able to login.\r
274         \r
275         return AuthPassed;\r
276 \r
277 }\r
278 \r
279 bool CardDAV::IsSelfSigned(){\r
280 \r
281         // Check that self-signed certificates are allowed.\r
282         \r
283         return AllowSelfSign;\r
284 \r
285 }\r
286 \r
287 int CardDAV::ProgressFuncProc(void *clientdata, double TTUp, double NUp, double TTDown, double NDown){\r
288 \r
289         // Progress function processing.\r
290         \r
291         if (AbortConnection == TRUE){\r
292         \r
293                 return -1;\r
294         \r
295         } else {\r
296         \r
297                 return 0;\r
298         \r
299         }\r
300 \r
301 }\r
302 \r
303 void CardDAV::Abort(){\r
304 \r
305         // Abort (close) the connection.\r
306         \r
307         AbortConnection = TRUE;\r
308 \r
309 }\r
310 \r
311 SSLCertCollection CardDAV::GetSSLVerifyResults(){\r
312         \r
313         // Get the SSL verification results.\r
314         \r
315         return VerifyCertCollection;\r
316         \r
317 }\r
318 \r
319 void CardDAV::AllowSelfSignTest(bool AllowSelfSignIn){\r
320         \r
321         // Set the value to enable/disable SSL self-signed certificates.\r
322         \r
323         AllowSelfSign = AllowSelfSignIn;\r
324 }\r
325 \r
326 void CardDAV::GetSSLResults(){\r
327 \r
328         // Get the SSL results.\r
329 \r
330 }\r
331 \r
332 void CardDAV::SetServerFilename(wxString Filename){\r
333 \r
334         // Set the server filename.\r
335         \r
336         ServerFilenameLocation = Filename;\r
337 \r
338 }\r
339 \r
340 wxString CardDAV::GetPageData()\r
341 {\r
342 \r
343         // Get the server page data.\r
344         \r
345         return PageData;\r
346 \r
347 }\r
348 \r
349 wxString CardDAV::ETagValueResult(){\r
350 \r
351         // Get the ETag Result value.\r
352         \r
353         return ETagResult;\r
354 \r
355 }\r
356 \r
357 void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){\r
358 \r
359         // Setup the data to use with the CardDAV connection.\r
360         \r
361         ServerMethod = Method;\r
362         ServerFilenameLocation = FilenameLocation;\r
363         ServerUploadData = UploadData;\r
364 \r
365         // Check if ServerFilenameLocation has a / at \r
366         // the start and if not then append it.\r
367         \r
368         /*if (ServerFilenameLocation.Left(1) != wxT("/")){\r
369         \r
370                 // Not there so insert.\r
371                 \r
372                 ServerFilenameLocation = wxT("/") + ServerFilenameLocation;\r
373         \r
374         }*/\r
375 \r
376 }\r
377 \r
378 void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){\r
379 \r
380         // Setup the variable pointers.\r
381         \r
382         ActivityListPtr = actlist;\r
383         ItemIndex = actindex;\r
384 \r
385 }\r
386 \r
387 wxString CardDAV::GetETagData(){\r
388 \r
389         // Get the ETag data.\r
390         \r
391         return ETagData;\r
392 \r
393 }\r
394 \r
395 void CardDAV::SetUploadMode(bool IncMode){\r
396 \r
397         // Set the upload mode.\r
398         \r
399         UploadMode = IncMode;\r
400 \r
401 }\r
402 \r
403 void CardDAV::SetEditMode(bool EditModeInc){\r
404 \r
405         // Set the edit mode.\r
406         \r
407         EditMode = EditModeInc;\r
408 \r
409 }\r
410 \r
411 int CardDAV::GetResultCode(){\r
412 \r
413         // Get the result code.\r
414         \r
415         return (int)claconncode;\r
416 \r
417 }\r
418 \r
419 int CardDAV::GetHTTPCode(){\r
420 \r
421         // Get the HTTP error code.\r
422         \r
423         return HTTPErrorCode;\r
424 \r
425 }\r
426 \r
427 wxString CardDAV::GetErrorBuffer(){\r
428 \r
429         // Get the error buffer.\r
430         \r
431         wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);\r
432 \r
433         return ErrorBuffer;\r
434 \r
435 }\r
436 \r
437 SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){\r
438 \r
439         // Build and return the SSL collection.\r
440         \r
441         SSLCertCollection SSLCertInfo;\r
442 \r
443         // Grab the certificate data.\r
444 \r
445         union {\r
446                 struct curl_slist *certdata;\r
447                 struct curl_certinfo *certinfo;\r
448         } certptr;\r
449 \r
450         certptr.certdata = NULL;\r
451         \r
452         curl_easy_getinfo(conn, CURLINFO_CERTINFO, &certptr.certinfo);\r
453 \r
454         wxString CertPropName;\r
455         wxString CertPropValue;\r
456 \r
457         for (int i = 0; i < certptr.certinfo->num_of_certs; i++){\r
458 \r
459                 struct curl_slist *slist;\r
460                 SSLCertData SSLCertDataInc;\r
461                 \r
462                 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){\r
463                         \r
464                         wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");\r
465                         \r
466                         // Get first token as the property name.\r
467                         \r
468                         CertPropName = CertDataInc.GetNextToken();\r
469                         \r
470                         // Get remaining tokens as the property value.\r
471                         \r
472                         while(CertDataInc.HasMoreTokens()){\r
473                         \r
474                                 CertPropValue.Append(CertDataInc.GetNextToken());\r
475                         \r
476                         }\r
477                         \r
478                         SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));\r
479                         CertPropName.clear();\r
480                         CertPropValue.clear();\r
481                         \r
482                 }\r
483         \r
484                 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));\r
485         \r
486         }\r
487         \r
488         return SSLCertInfo;\r
489 \r
490 }\r
491 \r
492 SSLCertCollection CardDAV::GetCertificateData(){\r
493 \r
494         // Pass on the collected certificate data.\r
495 \r
496         return SSLCertCol;\r
497 \r
498 }\r
499 \r
500 wxString CardDAV::GetErrorMessage(){\r
501 \r
502         // Get the error message.\r
503         \r
504         return ErrorMessage;\r
505 \r
506 }\r
507 \r
508 #if defined(__APPLE__) || defined(__WIN32__)\r
509 \r
510 CURL* CardDAV::GetConnectionObject(){\r
511         \r
512         // Get the CardDAV connection object.\r
513         \r
514         return ConnectionObject;\r
515         \r
516 }\r
517 \r
518 void CardDAV::SetConnectionObject(CURL *ConnectionObjectIn){\r
519 \r
520         // Set the connection object.\r
521         \r
522         ConnectionObject = ConnectionObjectIn;\r
523         \r
524 }\r
525 \r
526 #endif\r
527 \r
528 #if defined(__WIN32__)\r
529 \r
530 PCCERT_CONTEXT CardDAV::GetCertificateContextPointer(){\r
531 \r
532         // Check that the PCCERT_CONTEXT has an address\r
533         // other than NULL. Return nullptr if this is the\r
534         // case.\r
535 \r
536         if (CertificateData == NULL){\r
537                 return NULL;\r
538         }\r
539 \r
540         // Get the certificate data.\r
541 \r
542         return CertificateData;\r
543 \r
544 }\r
545 \r
546 CERT_CONTEXT CardDAV::GetCertificateContext(){\r
547 \r
548         // Check that the PCCERT_CONTEXT has an address\r
549         // other than NULL. Return nullptr if this is the\r
550         // case.\r
551 \r
552         if (CertificateData == NULL){\r
553                 CERT_CONTEXT EmptyCertificateData = { 0 };\r
554                 return EmptyCertificateData;\r
555         }\r
556 \r
557         // Get the certificate data.\r
558 \r
559         return *CertificateData;\r
560 \r
561 }\r
562 \r
563 #endif
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