From 15c33cead65ff0eabb9fd6de6bb9d147f5c6d2ee Mon Sep 17 00:00:00 2001 From: Kiri Date: Sun, 6 Sep 2015 21:21:31 +0100 Subject: [PATCH] Bring up Invalid SSL certificate dialog when creating a new account (still incomplete) --- source/carddav/carddav.cpp | 203 ++++++++++++++++++++++++++++++++++++- source/carddav/carddav.h | 8 ++ 2 files changed, 208 insertions(+), 3 deletions(-) diff --git a/source/carddav/carddav.cpp b/source/carddav/carddav.cpp index 095ab95..4b08fbb 100644 --- a/source/carddav/carddav.cpp +++ b/source/carddav/carddav.cpp @@ -74,6 +74,7 @@ wxString CardDAV::PageData; CURLcode CardDAV::claconncode; int CardDAV::HTTPErrorCode; wxString CardDAV::ErrorMessage; +SSLCertCollection CardDAV::VerifyCertCollection; CardDAV::CardDAV(){ ServerPort = 8080; @@ -224,6 +225,137 @@ void CardDAV::Abort(){ } +CURLcode CardDAV::SSLVerifyTest(){ + + PageData.Clear(); + PageHeader.Clear(); + + SSLStatus = TRUE; + AuthPassed = TRUE; + AbortConnection = FALSE; + + CURL *conn; + CURL *connssldata; + CURLcode conncode; + wxString ServerAddressURL; + wxString ServerAuth; + wxString ServerAddressSSL; + wxString ServerAddressNormal; + + conn = curl_easy_init(); + + /*struct CardDAVCURLPasser { + + CardDAV *Data; + bool HeaderMode = TRUE; + + } CardDAVHeader, CardDAVFooter; + + CardDAVHeader.Data = this; + CardDAVHeader.HeaderMode = TRUE; + + CardDAVFooter.Data = this; + CardDAVFooter.HeaderMode = FALSE;*/ + + wxString Data1; + wxString Data2; + + ServerAddressURL = ServerAddress + wxT(":") + wxString::Format(wxT("%i"), ServerPort) + wxT("/"); + ServerAddressSSL = wxT("https://") + ServerAddressURL; + + if (ServerSSL){ + + union { + struct curl_slist *certdata; + struct curl_certinfo *certinfo; + } ptr; + + ptr.certdata = NULL; + + // Setup two initial connections and attempt to get the certificate data. + + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + curl_easy_setopt(conn, CURLOPT_VERBOSE, 1L); + //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE); + //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, curlerrbuffer); + curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(conn, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(conn, CURLOPT_WRITEHEADER, &PageHeader); + + conncode = (curl_easy_perform(conn)); + + // Check if the SSL certificate is valid or self-signed or some other + // error occured. + + if (conncode == CURLE_OK){ + + // Connection is OK. Do nothing. + + *ServerResult = TRUE; + + } else if (conncode == CURLE_SSL_CACERT || conncode == CURLE_SSL_CONNECT_ERROR){ + + connssldata = curl_easy_init(); + + // Retry but get the certificates without peer/host verification. + + curl_easy_setopt(connssldata, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(connssldata, CURLOPT_CERTINFO, 1); + curl_easy_setopt(connssldata, CURLOPT_VERBOSE, 1L); + //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYPEER, FALSE); + //curl_easy_setopt(conn, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_easy_setopt(connssldata, CURLOPT_ERRORBUFFER, curlerrbuffer); + curl_easy_setopt(connssldata, CURLOPT_WRITEFUNCTION, WritebackFunc); + curl_easy_setopt(connssldata, CURLOPT_WRITEDATA, &PageData); + curl_easy_setopt(connssldata, CURLOPT_WRITEHEADER, &PageHeader); + //curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYPEER, FALSE); + //curl_easy_setopt(connssldata, CURLOPT_SSL_VERIFYHOST, FALSE); + + CURLcode certfetchcode; + + certfetchcode = (curl_easy_perform(connssldata)); + + VerifyCertCollection = BuildSSLCollection(connssldata); + + if (certfetchcode == CURLE_OK){ + + curl_easy_getinfo(connssldata, CURLINFO_CERTINFO, &ptr.certdata); + + VerifyCertCollection = BuildSSLCollection(connssldata); + + } else { + + conncode = certfetchcode; + + } + + *ServerResult = FALSE; + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + + } + + } + + curl_easy_cleanup(conn); + + return conncode; + +} + +SSLCertCollection CardDAV::GetSSLVerifyResults(){ + return VerifyCertCollection; +} + bool CardDAV::Connect(){ PageData.Clear(); @@ -233,15 +365,15 @@ bool CardDAV::Connect(){ AuthPassed = TRUE; AbortConnection = FALSE; - CURL *conn; - CURLcode conncode; + CURL *conn; + CURLcode conncode; wxString ServerAddressURL; wxString ServerAuth; wxString ServerAddressSSL; wxString ServerAddressNormal; conn = curl_easy_init(); - + struct CardDAVCURLPasser { CardDAV *Data; @@ -284,7 +416,47 @@ bool CardDAV::Connect(){ if (ServerSSL){ + union { + struct curl_slist *certdata; + struct curl_certinfo *certinfo; + } ptr; + + ptr.certdata = NULL; + + // Setup two initial connections and attempt to get the certificate data. + curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); + curl_easy_setopt(conn, CURLOPT_CERTINFO, 1); + + conncode = (curl_easy_perform(conn)); + + // Check if the SSL certificate is valid or self-signed or some other + // error occured. + + if (conncode == CURLE_OK){ + + // Connection is OK. Do nothing. + + } else if (conncode == CURLE_SSL_CACERT){ + + // Post message saying SSL certificate is invalid and + + + curl_easy_getinfo(conn, CURLINFO_CERTINFO, &ptr.certdata); + + } else { + + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(conncode)); + + ErrorMessage = wxString::Format(wxT("%s"), curl_easy_strerror(conncode)); + + *ServerResult = FALSE; + return FALSE; + + } + + /*curl_easy_setopt(conn, CURLOPT_URL, (const char*)ServerAddressSSL.mb_str(wxConvUTF8)); curl_easy_setopt(conn, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(conn, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_easy_setopt(conn, CURLOPT_TIMEOUT, 60); @@ -310,6 +482,31 @@ bool CardDAV::Connect(){ if (conncode == CURLE_OK){ + // Process the server header response and look for + // 'addressbook' within the DAV header. + + wxStringTokenizer wxSHeaderLines(PageHeader, wxT("\r\n")); + wxString wxSHeaderLine; + std::map DAVHeaderLines; + + while (wxSHeaderLines.HasMoreTokens()){ + + wxSHeaderLine = wxSHeaderLines.GetNextToken(); + + if (wxSHeaderLine.Mid(0, 4) == wxT("DAV:")){ + + // Look for address book in the line. + + if (wxSHeaderLine.Find(wxT("addressbook")) != wxNOT_FOUND){ + + HasCalDAVSupport = TRUE; + + } + + } + + } + *ServerResult = TRUE; AuthPassed = TRUE; SSLStatus = TRUE; diff --git a/source/carddav/carddav.h b/source/carddav/carddav.h index fd1068a..aff2138 100644 --- a/source/carddav/carddav.h +++ b/source/carddav/carddav.h @@ -79,6 +79,12 @@ class CardDAV static SSLCertCollection BuildSSLCollection(CURL *conn); wxString ETagValueResult(); wxString GetErrorMessage(); + + // SSL Verification tests when connecting. + + static CURLcode SSLVerifyTest(); + static SSLCertCollection GetSSLVerifyResults(); + //size_t WritebackFunc(char *ptr, size_t size, size_t nmemb, FILE *userdata); private: static wxString ServerAddress; @@ -110,6 +116,7 @@ class CardDAV static char curlerrbuffer[CURL_ERROR_SIZE]; static SSLCertCollection SSLCertCol; static wxString ErrorMessage; + static wxString ErrorBufferMessage; protected: static int SSLErrorCode; static int ConnectionErrorCode; @@ -117,6 +124,7 @@ class CardDAV static wxString PageData; static CURLcode claconncode; static int HTTPErrorCode; + static SSLCertCollection VerifyCertCollection; }; -- 2.39.5