如果编辑以下代码以获得有效的证书路径和需要客户端证书的URL,然后在OS X上使用clang++ -lcurl curl.cpp
进行编译(我使用的是El Cap,但我认为Mavericks或更高版本的行为是以相同的方式),并运行可执行文件,您从OS X获得一个弹出窗口(如下所示),询问您是否要允许可执行文件在您的钥匙串中使用私钥。这对于知道正在发生什么的用户来说很烦人(OS X上的内部卷曲使用OS X安全框架来加载客户端证书)但对于那些不知道发生了什么的用户来说这很可怕,因为他们认为程序正在尝试访问他们的钥匙串中的私钥(除此之外,这是来自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);
}
答案 0 :(得分:1)
这就是我解决这个问题的方法(感谢Phusion人员让我对此进行修改):
array_agg()