Если вы редактируете следующий код, чтобы иметь допустимые пути сертификатов и URL-адрес, требующий сертификатов клиента, а затем скомпилировать его с помощью clang++ -lcurl curl.cpp
на OS X (я использую El Cap, но, думаю, Mavericks или более поздняя версия ведут себя одинаково) и запустите исполняемый файл, вы получите всплывающее окно (показано ниже) из OS X с просьбой разрешить исполняемому файлу использовать закрытый ключ в вашей цепочке ключей. Это раздражает пользователей, которые знают, что происходит (внутренняя завивка на OS X использует инфраструктуру безопасности OS X для загрузки клиентского сертификата), но это пугает для пользователей, которые не знают, что происходит, потому что они думают, что программа пытается получить доступ закрытый ключ в их брелках (как в стороне это пример ужасного UX от Apple, поскольку всплывающее сообщение - полная красная селедка).Как убить всплывающее окно?
Инструмент командной строки curl не создает всплывающее окно, поэтому можно использовать API нижнего уровня, который я мог бы использовать, или это потому, что исполняемый файл подписан. Реальная программа, к которой я пытаюсь добавить эту функцию, часто распространяется как исходный код, поэтому подписка на исполняемый файл не является идеальным подходом, поскольку я не могу распространять ключи подписи или они будут отменены. Кто-нибудь знает, как я могу предотвратить всплывающее окно программно?
#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);
}