Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Win32 Support: Add basic SSL verification.
[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                 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
66         }\r
67 \r
68 #endif\r
69         \r
70         return size * nmemb;\r
71 \r
72 }\r
73 \r
74 int ProgressFunc(void *clientdata, double TTDown, double NDown, double TTUp, double NUp){\r
75 \r
76         // Progress function for the CardDAV object.\r
77         \r
78         int ProgressRet;\r
79         \r
80         CardDAV *IncCardDAV = static_cast<CardDAV*>(clientdata);\r
81         ProgressRet = IncCardDAV->ProgressFuncProc(clientdata, TTDown, NDown, TTUp, NUp);\r
82         if (ProgressRet != 0){\r
83                 return 1;\r
84         }\r
85         return 0;\r
86 \r
87 }\r
88 \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
128 #endif\r
129 #if defined(__WIN32__)\r
130 PCCERT_CONTEXT CardDAV::CertificateData;\r
131 #endif\r
132 #if defined(__APPLE__) || defined(__WIN32__)\r
133 CURL *CardDAV::ConnectionObject;\r
134 #endif\r
135 \r
136 CardDAV::CardDAV(){\r
137         \r
138         // Setup the CardDAV object.\r
139         \r
140         ServerPort = 8080;\r
141         SSLStatus = FALSE;\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
148 \r
149         AbortConnection = FALSE;\r
150         UploadMode = FALSE;\r
151         EditMode = FALSE;\r
152         HTTPErrorCode = 0;\r
153         \r
154 }\r
155 \r
156 CardDAV::~CardDAV(){\r
157 \r
158         // Destroy the CardDAV object.\r
159         \r
160 }\r
161 \r
162 size_t UploadReadFunc(void *ptr, size_t size, size_t nmemb, void *userdata){\r
163 \r
164         \r
165         // Upload function for the CardDAV object.\r
166         \r
167         struct UploadDataStruc *UploadPtr = (struct UploadDataStruc *)userdata;\r
168 \r
169         if (UploadPtr->sizeleft){\r
170 \r
171                 //MeepMoop->sizeleft--;\r
172                 //return 1;\r
173 \r
174                 UploadPtr->sizeleft--;\r
175                 wxString wxSChar;\r
176 \r
177                 wxSChar = UploadPtr->readptr->Mid(UploadPtr->seek,1);\r
178 \r
179                 //*(char *)ptr = (char)wxSChar.mb_str();\r
180 \r
181                 strncpy((char *)ptr, (const char*)wxSChar.mb_str(wxConvUTF8), 1);\r
182 \r
183                 UploadPtr->seek++;\r
184 \r
185                 return 1;\r
186 \r
187         }\r
188 \r
189         return 0;\r
190 \r
191 }\r
192 \r
193 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL){\r
194 \r
195         // Setup the CardDAV connection without the prefix/account.\r
196         \r
197         ServerAddress = SvrAddress;\r
198         ServerPort = SvrPort;\r
199         ServerUser = SvrUser;\r
200         ServerPass = SvrPass;\r
201         ServerSSL = SvrSSL;\r
202         \r
203         return TRUE;\r
204 \r
205 }\r
206 \r
207 bool CardDAV::SetupConnection(wxString SvrAddress, int SvrPort, wxString SvrUser, wxString SvrPass, bool SvrSSL, wxString SvrPrefix, wxString SvrAccount){\r
208 \r
209         // Setup the CardDAV connection with the prefix/account.\r
210         \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
218 \r
219         return TRUE;\r
220 \r
221 }\r
222 \r
223 bool CardDAV::SetupResultBools(bool *SvrResult, bool *SvrMonitor){\r
224 \r
225         // Setup the result booleans.\r
226         \r
227         ServerResult = SvrResult;\r
228         ServerMonitor = SvrMonitor;\r
229 \r
230         return TRUE;\r
231 \r
232 }\r
233 \r
234 bool CardDAV::HasValidResponse(){\r
235 \r
236         // Check that CardDAV server gave a valid response.\r
237         \r
238         return ValidResponse;\r
239 \r
240 }\r
241 \r
242 bool CardDAV::CanDoCardDAV(){\r
243 \r
244         // Check that the server has CardDAV support.\r
245         \r
246         return HasCalDAVSupport;\r
247 \r
248 }\r
249 \r
250 bool CardDAV::CanDoSSL(){\r
251 \r
252         // Check that the server can do SSL.\r
253         \r
254         return SSLStatus;\r
255 \r
256 }\r
257 \r
258 bool CardDAV::SSLVerify(){\r
259 \r
260         // Check that the server can verify SSL.\r
261         \r
262         return SSLVerified;\r
263 \r
264 }\r
265 \r
266 bool CardDAV::AbleToLogin(){\r
267 \r
268         // Check that the user is able to login.\r
269         \r
270         return AuthPassed;\r
271 \r
272 }\r
273 \r
274 bool CardDAV::IsSelfSigned(){\r
275 \r
276         // Check that self-signed certificates are allowed.\r
277         \r
278         return AllowSelfSign;\r
279 \r
280 }\r
281 \r
282 int CardDAV::ProgressFuncProc(void *clientdata, double TTUp, double NUp, double TTDown, double NDown){\r
283 \r
284         // Progress function processing.\r
285         \r
286         if (AbortConnection == TRUE){\r
287         \r
288                 return -1;\r
289         \r
290         } else {\r
291         \r
292                 return 0;\r
293         \r
294         }\r
295 \r
296 }\r
297 \r
298 void CardDAV::Abort(){\r
299 \r
300         // Abort (close) the connection.\r
301         \r
302         AbortConnection = TRUE;\r
303 \r
304 }\r
305 \r
306 SSLCertCollection CardDAV::GetSSLVerifyResults(){\r
307         \r
308         // Get the SSL verification results.\r
309         \r
310         return VerifyCertCollection;\r
311         \r
312 }\r
313 \r
314 void CardDAV::AllowSelfSignTest(bool AllowSelfSignIn){\r
315         \r
316         // Set the value to enable/disable SSL self-signed certificates.\r
317         \r
318         AllowSelfSign = AllowSelfSignIn;\r
319 }\r
320 \r
321 void CardDAV::GetSSLResults(){\r
322 \r
323         // Get the SSL results.\r
324 \r
325 }\r
326 \r
327 void CardDAV::SetServerFilename(wxString Filename){\r
328 \r
329         // Set the server filename.\r
330         \r
331         ServerFilenameLocation = Filename;\r
332 \r
333 }\r
334 \r
335 wxString CardDAV::GetPageData()\r
336 {\r
337 \r
338         // Get the server page data.\r
339         \r
340         return PageData;\r
341 \r
342 }\r
343 \r
344 wxString CardDAV::ETagValueResult(){\r
345 \r
346         // Get the ETag Result value.\r
347         \r
348         return ETagResult;\r
349 \r
350 }\r
351 \r
352 void CardDAV::SetupData(wxString Method, wxString FilenameLocation, wxString UploadData){\r
353 \r
354         // Setup the data to use with the CardDAV connection.\r
355         \r
356         ServerMethod = Method;\r
357         ServerFilenameLocation = FilenameLocation;\r
358         ServerUploadData = UploadData;\r
359 \r
360         // Check if ServerFilenameLocation has a / at \r
361         // the start and if not then append it.\r
362         \r
363         /*if (ServerFilenameLocation.Left(1) != wxT("/")){\r
364         \r
365                 // Not there so insert.\r
366                 \r
367                 ServerFilenameLocation = wxT("/") + ServerFilenameLocation;\r
368         \r
369         }*/\r
370 \r
371 }\r
372 \r
373 void CardDAV::SetupVariables(std::map<int, int> *actlist, int actindex){\r
374 \r
375         // Setup the variable pointers.\r
376         \r
377         ActivityListPtr = actlist;\r
378         ItemIndex = actindex;\r
379 \r
380 }\r
381 \r
382 wxString CardDAV::GetETagData(){\r
383 \r
384         // Get the ETag data.\r
385         \r
386         return ETagData;\r
387 \r
388 }\r
389 \r
390 void CardDAV::SetUploadMode(bool IncMode){\r
391 \r
392         // Set the upload mode.\r
393         \r
394         UploadMode = IncMode;\r
395 \r
396 }\r
397 \r
398 void CardDAV::SetEditMode(bool EditModeInc){\r
399 \r
400         // Set the edit mode.\r
401         \r
402         EditMode = EditModeInc;\r
403 \r
404 }\r
405 \r
406 int CardDAV::GetResultCode(){\r
407 \r
408         // Get the result code.\r
409         \r
410         return (int)claconncode;\r
411 \r
412 }\r
413 \r
414 int CardDAV::GetHTTPCode(){\r
415 \r
416         // Get the HTTP error code.\r
417         \r
418         return HTTPErrorCode;\r
419 \r
420 }\r
421 \r
422 wxString CardDAV::GetErrorBuffer(){\r
423 \r
424         // Get the error buffer.\r
425         \r
426         wxString ErrorBuffer = wxString::FromUTF8(curlerrbuffer);\r
427 \r
428         return ErrorBuffer;\r
429 \r
430 }\r
431 \r
432 SSLCertCollection CardDAV::BuildSSLCollection(CURL *conn){\r
433 \r
434         // Build and return the SSL collection.\r
435         \r
436         SSLCertCollection SSLCertInfo;\r
437 \r
438         // Grab the certificate data.\r
439 \r
440         union {\r
441                 struct curl_slist *certdata;\r
442                 struct curl_certinfo *certinfo;\r
443         } certptr;\r
444 \r
445         certptr.certdata = NULL;\r
446         \r
447         curl_easy_getinfo(conn, CURLINFO_CERTINFO, &certptr.certinfo);\r
448 \r
449         wxString CertPropName;\r
450         wxString CertPropValue;\r
451 \r
452         for (int i = 0; i < certptr.certinfo->num_of_certs; i++){\r
453 \r
454                 struct curl_slist *slist;\r
455                 SSLCertData SSLCertDataInc;\r
456                 \r
457                 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){\r
458                         \r
459                         wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");\r
460                         \r
461                         // Get first token as the property name.\r
462                         \r
463                         CertPropName = CertDataInc.GetNextToken();\r
464                         \r
465                         // Get remaining tokens as the property value.\r
466                         \r
467                         while(CertDataInc.HasMoreTokens()){\r
468                         \r
469                                 CertPropValue.Append(CertDataInc.GetNextToken());\r
470                         \r
471                         }\r
472                         \r
473                         SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));\r
474                         CertPropName.clear();\r
475                         CertPropValue.clear();\r
476                         \r
477                 }\r
478         \r
479                 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));\r
480         \r
481         }\r
482         \r
483         return SSLCertInfo;\r
484 \r
485 }\r
486 \r
487 SSLCertCollection CardDAV::GetCertificateData(){\r
488 \r
489         // Pass on the collected certificate data.\r
490 \r
491         return SSLCertCol;\r
492 \r
493 }\r
494 \r
495 wxString CardDAV::GetErrorMessage(){\r
496 \r
497         // Get the error message.\r
498         \r
499         return ErrorMessage;\r
500 \r
501 }\r
502 \r
503 #if defined(__APPLE__) || defined(__WIN32__)\r
504 \r
505 CURL* CardDAV::GetConnectionObject(){\r
506         \r
507         // Get the CardDAV connection object.\r
508         \r
509         return ConnectionObject;\r
510         \r
511 }\r
512 \r
513 void CardDAV::SetConnectionObject(CURL *ConnectionObjectIn){\r
514 \r
515         // Set the connection object.\r
516         \r
517         ConnectionObject = ConnectionObjectIn;\r
518         \r
519 }\r
520 \r
521 #endif\r
522 \r
523 #if defined(__WIN32__)\r
524 \r
525 PCCERT_CONTEXT CardDAV::GetCertificateContextPointer(){\r
526 \r
527         // Get the certificate data.\r
528 \r
529         return CertificateData;\r
530 \r
531 }\r
532 \r
533 CERT_CONTEXT CardDAV::GetCertificateContext(){\r
534 \r
535         // Get the certificate data.\r
536 \r
537         return *CertificateData;\r
538 \r
539 }\r
540 \r
541 #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