Wenn Sie den folgenden Code bearbeiten, um gültige Zertifikatpfade und eine URL zu haben, die Clientzertifikate erfordert und kompilieren Sie sie dann mit clang++ -lcurl curl.cpp
auf OS X (ich benutze El Cap, aber ich denke Mavericks oder später verhalten sich genauso) und Wenn Sie die ausführbare Datei ausführen, erhalten Sie ein Popup (siehe unten) von OS X mit der Frage, ob Sie der ausführbaren Datei erlauben möchten, einen privaten Schlüssel in Ihrem Schlüsselbund zu verwenden. Dies ist ärgerlich für Benutzer, die wissen, was vor sich geht (intern unter OS X benutzt das OS X Sicherheitsframework, um das Client-Zertifikat zu laden), aber es ist erschreckend für Benutzer, die nicht wissen, was passiert, weil sie glauben, dass das Programm versucht, darauf zuzugreifen ein privater Schlüssel in ihrem Schlüsselbund (nebenbei ist dies ein Beispiel für schreckliche UX von Apple, da die Popup-Nachricht ein kompletter Ablenkungsmanöver ist).Wie kann ich das Popup beenden?
Das Befehlszeilenprogramm curl erzeugt kein Popup, also gibt es entweder eine niedrigere API, die ich verwenden könnte, oder die ausführbare Datei ist signiert. Das eigentliche Programm, dem ich diese Funktion hinzufügen möchte, wird oft als Quellcode verteilt. Daher ist das Signieren der ausführbaren Datei kein idealer Ansatz, da ich die Signaturschlüssel nicht verteilen kann oder sie widerrufen werden. Weiß jemand wie ich das Popup programmatisch verhindern kann?
#include <curl/curl.h>
#include <string>
using namespace std;
static size_t receiveResponseBytes(void *buffer, size_t size, size_t nmemb, void *userData) {
string *responseData = (string *) userData;
responseData->append((const char *) buffer, size * nmemb);
return size * nmemb;
}
void prepareCurlPOST(CURL *curl, string &bodyJsonString, string *responseData, struct curl_slist **chunk) {
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_URL, "https://example.dev/v1/check.json");
curl_easy_setopt(curl, CURLOPT_HTTPGET, 0);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, bodyJsonString.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, bodyJsonString.length());
*chunk = curl_slist_append(NULL, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, *chunk);
curl_easy_setopt(curl, CURLOPT_SSLCERT, "/path/to/client_cert.p12");
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "P12");
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, "1234");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveResponseBytes);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, responseData);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180);
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/ca.crt");
}
int main(){
CURL* curl = curl_easy_init();
struct curl_slist *chunk = NULL;
string responseData;
long responseCode;
string bodyJsonString = "{\"version\": 1}";
prepareCurlPOST(curl, bodyJsonString, &responseData, &chunk);
fprintf(stderr,"%s\n",curl_easy_strerror(curl_easy_perform(curl)));
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
if (responseCode != 200) {
fprintf(stderr, "HTTP %d %s\n", (int) responseCode, responseData.c_str());
}
curl_slist_free_all(chunk);
curl_easy_cleanup(curl);
}