Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Altered CardDAV object to accommodate for SSL support for OS X (and other OSes in...
[xestiaab/.git] / source / carddav / carddav-connect.cpp
1 // carddav-connect.cpp - CardDAV Object - Connect subroutines.
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 "carddav.h"
20 #include "../version.h"
21 #include <wx/wx.h>
22 #include <wx/tokenzr.h>
23 #include <wx/ffile.h>
24 #include <libxml/parser.h>
25 #include <libxml/tree.h>
26 #include <map>
27 #include <thread>
28 #include "../vcard/vcard.h"
29 #include "../common/dirs.h"
31 bool CardDAV::Connect(){
33         // Connect to the CardDAV server.
34         
35         PageData.Clear();
36         PageHeader.Clear();
38         SSLStatus = TRUE;
39         AuthPassed = TRUE;
40         AbortConnection = FALSE;
42         CURL *conn;
43         CURLcode conncode;
44         wxString ServerAddressURL;
45         wxString ServerAuth;
46         wxString ServerAddressSSL;
47         wxString ServerAddressNormal;   
49         conn = curl_easy_init();
51         struct CardDAVCURLPasser {
52         
53                 CardDAV *Data;
54                 bool HeaderMode = TRUE;
55         
56         } CardDAVHeader, CardDAVFooter;
58         CardDAVHeader.Data = this;
59         CardDAVHeader.HeaderMode = TRUE;
60         
61         CardDAVFooter.Data = this;
62         CardDAVFooter.HeaderMode = FALSE;
64         wxString Data1;
65         wxString Data2;
66         
67         ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
68         ServerAddressSSL = wxT("https://") + ServerAddressURL;
69         ServerAddressNormal = wxT("http://") + ServerAddressURL;
70         
71         ServerAuth = ServerUser + wxT(":") + ServerPass;
72         
73         // Try SSL first.
75         if (ServerSSL){
77                 union {
78                         struct curl_slist       *certdata;
79                         struct curl_certinfo    *certinfo;
80                 } ptr;
82                 ptr.certdata = NULL;
84                 // Setup two initial connections and attempt to get the certificate data.
86                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
87                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
89                 conncode = (curl_easy_perform(conn));
91                 // Check if the SSL certificate is valid or self-signed or some other
92                 // error occured.
94                 if (conncode == CURLE_OK){
96                         // Connection is OK. Do nothing.
98                 } else if (conncode == CURLE_SSL_CACERT){
100                         // Post message saying SSL certificate is invalid. 
102                         curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);
104                 } else {
106                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
107                                 curl_easy_strerror(conncode));
109                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
111                         *ServerResult = FALSE;
112                         return FALSE;
114                 }
116                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
117                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
118                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
119                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
120                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
121                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);             
122                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
123                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
124                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
125                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
126                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
127                 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
128                 
129                 if (AllowSelfSign == TRUE){
130                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
131                         curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
132                 }
134                 SetConnectionObject(conn);
135         
136                 conncode = (curl_easy_perform(conn));
137                 
138                 ptr.certdata = NULL;
140                 curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);
141                 
142                 if (conncode == CURLE_OK){
144                         // Process the server header response and look for
145                         // 'addressbook' within the DAV header.
147                         wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
148                         wxString wxSHeaderLine;
149                         std::map<int, wxString> DAVHeaderLines;
151                         while (wxSHeaderLines.HasMoreTokens()){
153                                 wxSHeaderLine = wxSHeaderLines.GetNextToken();
155                                 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
157                                         // Look for address book in the line.
159                                         if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
161                                                 HasCalDAVSupport = TRUE;
163                                         }
165                                 }
167                         }
169                         *ServerResult = TRUE;
170                         ValidResponse = TRUE;
171                         AuthPassed = TRUE;
172                         SSLStatus = TRUE;
173                         return TRUE;
175                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
176                 
177                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
178                                         curl_easy_strerror(conncode));
179                                 
180                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
182                         *ServerResult = TRUE;
183                         ValidResponse = FALSE;
184                         AuthPassed = FALSE;
185                         SSLStatus = TRUE;
186                         return TRUE;
187                 
188                 } else {
190                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
191                                         curl_easy_strerror(conncode));
193                         ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
195                         *ServerResult = FALSE;
196                         return FALSE;                                   
198                 }
200         } else {
201         
202         // No SSL.
203                 
204                 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
205                 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
206                 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
207                 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);    
208                 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
209                 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
210                 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
211                 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
212                 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
213                 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
214                 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
216                 conncode = (curl_easy_perform(conn));
218                 if (conncode == CURLE_OK){
220                         // Process the server header response and look for
221                         // 'addressbook' within the DAV header.
222                         
223                         wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
224                         wxString wxSHeaderLine;
225                         std::map<int, wxString> DAVHeaderLines;
226                         
227                         while (wxSHeaderLines.HasMoreTokens()){
228                         
229                                 wxSHeaderLine = wxSHeaderLines.GetNextToken();
230                                 
231                                 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
232                                 
233                                         // Look for address book in the line.
234                                         
235                                         if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
236                                         
237                                                 HasCalDAVSupport = TRUE;
238                                         
239                                         }
240                                 
241                                 }
242                         
243                         }
245                         *ServerResult = TRUE;
246                         ValidResponse = TRUE;                   
247                         AuthPassed = TRUE;
248                         SSLStatus = FALSE;
249                         return TRUE;
251                 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
252                 
253                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
254                                         curl_easy_strerror(conncode));
255                                         
256                         *ServerResult = TRUE;
257                         ValidResponse = FALSE;
258                         AuthPassed = FALSE;
259                         SSLStatus = FALSE;
260                         return TRUE;
261                 
262                 } else {
264                         fprintf(stderr, "curl_easy_perform() failed: %s\n",
265                                         curl_easy_strerror(conncode));
266                                 
267                         *ServerResult = FALSE;
268                         return FALSE;
270                 }
271                 
272                 // TODO: Double check and make sure HTTP Authentication is possible.
273                 
274         }               
275                 
276         *ServerResult = TRUE;
277         return TRUE;    
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