2 #include "../version.h"
4 #include <wx/tokenzr.h>
6 #include <libxml/parser.h>
7 #include <libxml/tree.h>
10 #include "../vcard/vcard.h"
11 #include "../common/dirs.h"
13 bool CardDAV::Connect(){
20 AbortConnection = FALSE;
24 wxString ServerAddressURL;
26 wxString ServerAddressSSL;
27 wxString ServerAddressNormal;
29 conn = curl_easy_init();
31 struct CardDAVCURLPasser {
34 bool HeaderMode = TRUE;
36 } CardDAVHeader, CardDAVFooter;
38 CardDAVHeader.Data = this;
39 CardDAVHeader.HeaderMode = TRUE;
41 CardDAVFooter.Data = this;
42 CardDAVFooter.HeaderMode = FALSE;
47 ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
48 ServerAddressSSL = wxT("https://") + ServerAddressURL;
49 ServerAddressNormal = wxT("http://") + ServerAddressURL;
51 ServerAuth = ServerUser + wxT(":") + ServerPass;
57 char *ServerAdrSSLChar = new char[(ServerAddressSSL.Length() - 1)];
58 //memset(ServerAdrSSLChar, 0, ServerAddressSSL.Length());
59 strncpy(ServerAdrSSLChar, (const char*)ServerAddressSSL.mb_str(wxConvUTF8), (ServerAddressSSL.Length() - 1));
61 char *ServerAdrNorChar = new char[(ServerAddressNormal.Length() - 1)];
62 //memset(ServerAdrNorChar, 0, ServerAddressSSL.Length());
63 strncpy(ServerAdrNorChar, (const char*)ServerAddressNormal.mb_str(wxConvUTF8), (ServerAddressNormal.Length() - 1));
65 char *ServerAuthChar = new char[(ServerAuth.Length() - 1)];
66 //memset(ServerAuthChar, 0, ServerAddressSSL.Length());
67 strncpy(ServerAuthChar, (const char*)ServerAuth.mb_str(wxConvUTF8), (ServerAuth.Length() - 1));
74 struct curl_slist *certdata;
75 struct curl_certinfo *certinfo;
80 // Setup two initial connections and attempt to get the certificate data.
82 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
83 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
85 conncode = (curl_easy_perform(conn));
87 // Check if the SSL certificate is valid or self-signed or some other
90 if (conncode == CURLE_OK){
92 // Connection is OK. Do nothing.
94 } else if (conncode == CURLE_SSL_CACERT){
96 // Post message saying SSL certificate is invalid.
98 curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);
102 fprintf(stderr, "curl_easy_perform() failed: %s\n",
103 curl_easy_strerror(conncode));
105 ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
107 *ServerResult = FALSE;
112 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
113 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
114 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
115 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
116 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
117 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
118 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
119 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
120 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
121 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
122 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
123 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
125 if (AllowSelfSign == TRUE){
126 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 0L);
127 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 0L);
130 conncode = (curl_easy_perform(conn));
134 curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata);
136 if (conncode == CURLE_OK){
138 // Process the server header response and look for
139 // 'addressbook' within the DAV header.
141 wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
142 wxString wxSHeaderLine;
143 std::map<int, wxString> DAVHeaderLines;
145 while (wxSHeaderLines.HasMoreTokens()){
147 wxSHeaderLine = wxSHeaderLines.GetNextToken();
149 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
151 // Look for address book in the line.
153 if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
155 HasCalDAVSupport = TRUE;
163 *ServerResult = TRUE;
164 ValidResponse = TRUE;
169 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
171 fprintf(stderr, "curl_easy_perform() failed: %s\n",
172 curl_easy_strerror(conncode));
174 ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
176 *ServerResult = TRUE;
177 ValidResponse = FALSE;
184 fprintf(stderr, "curl_easy_perform() failed: %s\n",
185 curl_easy_strerror(conncode));
187 ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
189 *ServerResult = FALSE;
198 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressNormal.mb_str(wxConvUTF8));
199 curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L);
200 curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
201 curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60);
202 curl_easy_setopt(conn, CURLOPT_FAILONERROR, TRUE);
203 curl_easy_setopt(conn, CURLOPT_USERAGENT, XSDAB_USERAGENT);
204 curl_easy_setopt(conn, CURLOPT_USERPWD, (const char*)ServerAuth.mb_str(wxConvUTF8));
205 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
206 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
207 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
208 curl_easy_setopt(conn, CURLOPT_NOSIGNAL, 1);
210 conncode = (curl_easy_perform(conn));
212 if (conncode == CURLE_OK){
214 // Process the server header response and look for
215 // 'addressbook' within the DAV header.
217 wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n"));
218 wxString wxSHeaderLine;
219 std::map<int, wxString> DAVHeaderLines;
221 while (wxSHeaderLines.HasMoreTokens()){
223 wxSHeaderLine = wxSHeaderLines.GetNextToken();
225 if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){
227 // Look for address book in the line.
229 if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){
231 HasCalDAVSupport = TRUE;
239 *ServerResult = TRUE;
240 ValidResponse = TRUE;
245 } else if (conncode == CURLE_HTTP_RETURNED_ERROR){
247 fprintf(stderr, "curl_easy_perform() failed: %s\n",
248 curl_easy_strerror(conncode));
250 *ServerResult = TRUE;
251 ValidResponse = FALSE;
258 fprintf(stderr, "curl_easy_perform() failed: %s\n",
259 curl_easy_strerror(conncode));
261 *ServerResult = FALSE;
266 // TODO: Double check and make sure HTTP Authentication is possible.
270 *ServerResult = TRUE;