Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我如何杀死弹出窗口?_C++_Macos_Libcurl - Fatal编程技术网

C++ 我如何杀死弹出窗口?

C++ 我如何杀死弹出窗口?,c++,macos,libcurl,C++,Macos,Libcurl,如果您编辑以下代码,使其具有有效的证书路径和需要客户端证书的url,然后在OSX上使用clang++-lcurl curl.cpp对其进行编译(我使用的是El-Cap,但我认为Mavericks或更高版本也有相同的行为),并运行可执行文件,则会出现一个弹出窗口(如下所示)从OSX询问是否允许可执行文件在密钥链中使用私钥。这对于知道发生了什么的用户来说是恼人的(OSX上的内部curl使用OSX安全框架来加载客户端证书),但对于不知道发生了什么的用户来说是可怕的,因为他们认为程序试图访问他们钥匙链中

如果您编辑以下代码,使其具有有效的证书路径和需要客户端证书的url,然后在OSX上使用
clang++-lcurl curl.cpp
对其进行编译(我使用的是El-Cap,但我认为Mavericks或更高版本也有相同的行为),并运行可执行文件,则会出现一个弹出窗口(如下所示)从OSX询问是否允许可执行文件在密钥链中使用私钥。这对于知道发生了什么的用户来说是恼人的(OSX上的内部curl使用OSX安全框架来加载客户端证书),但对于不知道发生了什么的用户来说是可怕的,因为他们认为程序试图访问他们钥匙链中的私钥(顺便说一句,这是苹果糟糕的用户体验的一个例子,因为弹出的消息完全是一个骗局)

curl命令行工具不会生成弹出窗口,因此我可以使用较低级别的API,或者是因为可执行文件已签名。我试图添加此功能的实际程序通常作为源代码分发,因此对可执行文件进行签名不是一种理想的方法,因为我无法分发签名密钥,否则它们将被撤销。Doe有人知道如何通过编程防止弹出窗口吗

#包括
#包括
使用名称空间std;
静态大小接收方响应字节(void*缓冲区、大小、大小nmemb、void*用户数据){
字符串*响应数据=(字符串*)用户数据;
responseData->append((const char*)缓冲区,大小*nmemb);
返回大小*nmemb;
}
void prepareCurlPOST(CURL*CURL、string和bodyJsonString、string*responseData、struct CURL\u slist**chunk){
curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1);
curl\u easy\u setopt(curl,CURLOPT\u 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\u slist\u append(NULL,“内容类型:application/json”);
curl\u easy\u setopt(curl,CURLOPT\u 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\u easy\u setopt(curl,CURLOPT\u SSL\u VERIFYPEER,1L);
curl\u easy\u setopt(curl,CURLOPT\u WRITEFUNCTION,receiverresponsebytes);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,responseData);
curl_easy_setopt(curl,CURLOPT_超时,180);
curl_easy_setopt(curl,CURLOPT_CAINFO,“/path/to/ca.crt”);
}
int main(){
CURL*CURL=CURL_easy_init();
struct curl_slist*chunk=NULL;
字符串响应数据;
长响应编码;
字符串bodyJsonString=“{\”版本\“:1}”;
prepareCurlPOST(curl、bodyJsonString、responseData和chunk);
fprintf(stderr,“%s\n”,curl_easy_strerror(curl_easy_perform(curl));
curl\u easy\u getinfo(curl、CURLINFO\u RESPONSE\u CODE和responseCode);
如果(响应代码!=200){
fprintf(stderr,“HTTP%d%s\n”,(int)responseCode,responseData.c_str());
}
卷曲、滑动、自由、全部(块);
旋度\轻松\清洁(旋度);
}

这就是我解决这个问题的方法(感谢Phusion的人让我修补这个问题):

#包括
#包括
#包括
#包括
使用名称空间std;
const char*cert_label=“密钥链访问中显示的证书名称”;
常量字符*域=”https://example.dev/v1/check.json";
const char*ca_path=“/path/to/ca.crt”;
const char*cert_path=“/path/to/client_cert.p12”;
const char*cert_pw=“1234”;
静态OSStatus LookupKeychainItem(常量字符*标签,
SecIdentityRef*out_cert_和_key)
{
OSStatus status=errSecItemNotFound;
if(kSecClassIdentity!=NULL){
CFTypeRef键[4];
CFTypeRef值[4];
CFDictionaryRef查询记录;
CFStringRef标签\u cf=CFStringCreateWithCString(空,标签,
kCFStringEncodingUTF8);
/*设置我们的搜索条件和预期结果:*/
值[0]=kSecClassIdentity;/*我们需要一个证书和一个密钥*/
密钥[0]=kSecClass;
值[1]=kCFBooleanTrue;/*我们需要一个引用*/
键[1]=kSecReturnRef;
值[2]=kSecMatchLimitOne;/*一个就足够了,谢谢*/
键[2]=kSecMatchLimit;
/*身份搜索需要SecPolicyRef才能工作*/
值[3]=SecPolicyCreateSSL(false,label_cf);
密钥[3]=kSecMatchPolicy;
query_dict=CFDictionaryCreate(NULL,(const void**)键,
(const void**)值,4L,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease(值[3]);
CFRelease(标签为cf);
/*我们有火柴吗*/
状态=SecItemCopyMatching(查询指令,(CFTypeRef*)输出证书和密钥);
CFRelease(查询命令);
}
返回状态;
}
SecAccessRef createAccess()
{
SecAccessRef-access=NULL;
if(SecAccessCreate(CFStringCreateWithCString(NULL、证书标签、kCFStringEncodingUTF8)、NULL和access)){
printf(“SecAccessCreate失败\n”);
返回NULL;
}
返回访问;
}
静态OSStatus CopyIdentityFromPKCS12文件(const char*cPath,
常量字符*cPassword,
SecIdentityRef*out_cert_和_key)
{
OSStatus status=errSecItemNotFound;
CFURLRef pkcs_url=CFURLCreateFromFileSystemRepresentation(NULL,
(const UInt8*)加拿大皇家警察,斯特伦(加拿大皇家警察),假;
CFStringRef password=cPassword?CFStringCreateWithCString(空,
cPassword,kCFStringEncodingUTF8):NULL;
CFDataRef pkcs_data=NULL;
如果(CFURLCreateDataAndPropertiesFromResource)(NULL,pkcs_url,&pkcs_数据,
空、空和状态){
SecAccessRef access=createAccess();
常数void*cKeys[]={kSecI
#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);
}
#include <curl/curl.h>
#include <string>

#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>

using namespace std;

const char* cert_label = "Name of the certificate as it appears in keychain access";
const char* domain = "https://example.dev/v1/check.json";
const char* ca_path = "/path/to/ca.crt";
const char* cert_path = "/path/to/client_cert.p12";
const char* cert_pw = "1234";

static OSStatus LookupKeychainItem(const char *label,
                                   SecIdentityRef *out_cert_and_key)
{
  OSStatus status = errSecItemNotFound;

  if(kSecClassIdentity != NULL) {
    CFTypeRef keys[4];
    CFTypeRef values[4];
    CFDictionaryRef query_dict;
    CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
                                                     kCFStringEncodingUTF8);

    /* Set up our search criteria and expected results: */
    values[0] = kSecClassIdentity; /* we want a certificate and a key */
    keys[0] = kSecClass;
    values[1] = kCFBooleanTrue;    /* we need a reference */
    keys[1] = kSecReturnRef;
    values[2] = kSecMatchLimitOne; /* one is enough, thanks */
    keys[2] = kSecMatchLimit;
    /* identity searches need a SecPolicyRef in order to work */
    values[3] = SecPolicyCreateSSL(false, label_cf);
    keys[3] = kSecMatchPolicy;
    query_dict = CFDictionaryCreate(NULL, (const void **)keys,
                                    (const void **)values, 4L,
                                    &kCFCopyStringDictionaryKeyCallBacks,
                                    &kCFTypeDictionaryValueCallBacks);
    CFRelease(values[3]);
    CFRelease(label_cf);

    /* Do we have a match? */
    status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
    CFRelease(query_dict);
  }

  return status;
}

SecAccessRef createAccess()
{
  SecAccessRef access=NULL;
  if (SecAccessCreate(CFStringCreateWithCString(NULL, cert_label, kCFStringEncodingUTF8), NULL, &access)){
    printf("SecAccessCreate failed\n");
    return NULL;
  }
  return access;
}

static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
                                           const char *cPassword,
                                           SecIdentityRef *out_cert_and_key)
{
  OSStatus status = errSecItemNotFound;
  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
                                                              (const UInt8 *)cPath, strlen(cPath), false);
  CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
                                                               cPassword, kCFStringEncodingUTF8) : NULL;
  CFDataRef pkcs_data = NULL;

  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
                                              NULL, NULL, &status)) {
    SecAccessRef access = createAccess();
    const void *cKeys[] = {kSecImportExportPassphrase,kSecImportExportAccess};
    //kSecTrustSettingsKeyUseAny
    const void *cValues[] = {password,access};
    CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
                                                 2L, NULL, NULL);
    CFArrayRef items = NULL;

    /* Here we go: */
    status = SecPKCS12Import(pkcs_data, options, &items);

    if(items)
      CFRelease(items);
    CFRelease(options);
    CFRelease(pkcs_data);
  }

  if(password)
    CFRelease(password);
  CFRelease(pkcs_url);
  return status;
}

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, domain);
  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, cert_label);
  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, ca_path);
}

void killKey(){
    SecIdentityRef id = NULL;
    if (LookupKeychainItem(cert_label,&id) != errSecItemNotFound){

        CFArrayRef itemList = CFArrayCreate(NULL, (const void **)&id, 1, NULL);
        const void *keys2[]   = { kSecClass,  kSecMatchItemList,  kSecMatchLimit };
        const void *values2[] = { kSecClassIdentity, itemList, kSecMatchLimitAll };

        CFDictionaryRef dict = CFDictionaryCreate(NULL, keys2, values2, 3, NULL, NULL);
        OSStatus oserr = SecItemDelete(dict);
        if (oserr) {
            CFStringRef str = SecCopyErrorMessageString(oserr, NULL);
            printf("Removing Passenger Cert from keychain failed: %s Please remove the private key from the certificate labeled %s in your keychain.", CFStringGetCStringPtr(str,kCFStringEncodingUTF8), cert_label);
            CFRelease(str);
        }
        CFRelease(dict);
        CFRelease(itemList);

    }
}

void preAuthKey(){
  SecIdentityRef id = NULL;
  if(LookupKeychainItem(cert_label,&id) == errSecItemNotFound){
    OSStatus status = SecKeychainSetUserInteractionAllowed(false);
    if(status != errSecSuccess){
      printf("%s\n",CFStringGetCStringPtr(SecCopyErrorMessageString(status,NULL),kCFStringEncodingUTF8));
    }
    CopyIdentityFromPKCS12File("/path/to/client_cert.p12","1234",&id);
    status = SecKeychainSetUserInteractionAllowed(true);
    if(status != errSecSuccess){
      printf("%s\n",CFStringGetCStringPtr(SecCopyErrorMessageString(status,NULL),kCFStringEncodingUTF8));
    }
  }
}

int main(){
  preAuthKey();
  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);
  killKey();
}