1 // carddav-sslverify.cpp - CardDAV Object - SSL verification subroutines.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
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.
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.
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/>
20 #include "../version.h"
22 #include <wx/tokenzr.h>
24 #include <libxml/parser.h>
25 #include <libxml/tree.h>
28 #include "../vcard/vcard.h"
29 #include "../common/dirs.h"
31 CURLcode CardDAV::SSLVerifyTest(){
33 // Verify the SSL information.
40 AbortConnection = FALSE;
44 CURLcode conncode = CURLE_OK;
45 wxString ServerAddressURL;
47 wxString ServerAddressSSL;
48 wxString ServerAddressNormal;
50 conn = curl_easy_init();
55 ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/");
56 ServerAddressSSL = wxT("https://") + ServerAddressURL;
61 struct curl_slist *certdata;
62 struct curl_certinfo *certinfo;
67 // Setup two initial connections and attempt to get the certificate data.
69 curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
70 curl_easy_setopt(conn, CURLOPT_CERTINFO, 1);
71 curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L);
72 curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer);
73 curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc);
74 curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData);
75 curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader);
77 #if defined(__APPLE__) || defined(__WIN32__)
79 SetConnectionObject(conn);
83 if (ServerAccount != ""){
85 wxString ServerCertFilename = GetAccountDir(ServerAccount, TRUE);
87 if (wxFile::Exists(ServerCertFilename) == TRUE){
89 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, 1);
90 curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, 2);
91 curl_easy_setopt(conn, CURLOPT_CAINFO, (const char*)ServerCertFilename.mb_str(wxConvUTF8));
99 conncode = (curl_easy_perform(conn));
101 // Check if the SSL certificate is valid or self-signed or some other
104 if (conncode == CURLE_OK){
106 // Connection is OK. Do nothing.
108 *ServerResult = TRUE;
110 #if !defined(__APPLE__) && !defined(__WIN32__)
112 VerifyCertCollection = BuildSSLCollection(conn);
116 } else if (conncode == CURLE_SSL_CACERT ||
117 conncode == CURLE_SSL_CONNECT_ERROR ||
118 conncode == CURLE_PEER_FAILED_VERIFICATION){
120 connssldata = curl_easy_init();
122 // Retry but get the certificates without peer/host verification.
124 curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8));
125 curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1);
126 curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L);
127 curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer);
128 curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc);
129 curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData);
130 curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader);
131 curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, 0L);
132 curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, 0L);
134 #if defined(__APPLE__) || defined(__WIN32__)
136 SetConnectionObject(connssldata);
140 CURLcode certfetchcode;
142 certfetchcode = (curl_easy_perform(connssldata));
144 #if !defined(__APPLE__) && !defined(__WIN32__)
146 VerifyCertCollection = BuildSSLCollection(connssldata);
148 if (certfetchcode == CURLE_OK){
150 curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata);
152 VerifyCertCollection = BuildSSLCollection(connssldata);
156 conncode = certfetchcode;
162 *ServerResult = FALSE;
166 fprintf(stderr, "curl_easy_perform() failed: %s\n",
167 curl_easy_strerror(conncode));
169 ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode));
171 *ServerResult = FALSE;
177 curl_easy_cleanup(conn);