📄 fetch.c
字号:
{ err_t ugh = NULL; if (url.len >= 4 && strncasecmp(url.ptr, "ldap", 4) == 0) { ugh = fetch_ldap_url(url, blob); } else { ugh = fetch_curl(url, blob); } if (ugh != NULL) return ugh; if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" fetched blob coded in DER format") ) } else { bool pgp = FALSE; ugh = pemtobin(blob, NULL, "", &pgp); if (ugh == NULL) { if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" fetched blob coded in PEM format") ) } else { ugh = "Blob coded in unknown format"; pfree(blob->ptr); } } else { pfree(blob->ptr); } } return ugh;}/* * try to fetch the crls defined by the fetch requests */static voidfetch_crls(void){ fetch_req_t *req; fetch_req_t **reqp; lock_crl_fetch_list("fetch_crls"); req = crl_fetch_reqs; reqp = &crl_fetch_reqs; while (req != NULL) { bool valid_crl = FALSE; chunk_t blob = empty_chunk; generalName_t *gn = req->distributionPoints; while (gn != NULL) { err_t ugh = fetch_asn1_blob(gn->name, &blob); if (ugh != NULL) { plog("fetch failed: %s", ugh); } else { chunk_t crl_uri; clonetochunk(crl_uri, gn->name.ptr, gn->name.len, "crl uri"); if (insert_crl(blob, crl_uri)) { DBG(DBG_CONTROL, DBG_log("we have a valid crl") ) valid_crl = TRUE; break; } } gn = gn->next; } if (valid_crl) { /* delete fetch request */ fetch_req_t *req_free = req; req = req->next; *reqp = req; free_fetch_request(req_free); } else { /* try again next time */ req->trials++; reqp = &req->next; req = req->next; } } unlock_crl_fetch_list("fetch_crls");}static voidfetch_ocsp_status(ocsp_location_t* location LIBCURL_UNUSED){#ifdef LIBCURL chunk_t request; chunk_t response = empty_chunk; CURL* curl; CURLcode res; request = build_ocsp_request(location); DBG(DBG_CONTROL, DBG_log("sending ocsp request to location '%.*s'" , (int)location->uri.len, location->uri.ptr) ) DBG(DBG_RAW, DBG_dump_chunk("OCSP request", request) ) /* send via http post using libcurl */ curl = curl_easy_init(); if (curl != NULL) { char errorbuffer[CURL_ERROR_SIZE]; struct curl_slist *headers = NULL; char* uri = alloc_bytes(location->uri.len+1, "ocsp uri"); /* we need a null terminated string for curl */ memcpy(uri, location->uri.ptr, location->uri.len); *(uri + location->uri.len) = '\0'; /* set content type header */ headers = curl_slist_append(headers, "Content-Type: application/ocsp-request"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_URL, uri); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer); curl_easy_setopt(curl, CURLOPT_FILE, (void *)&response); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.ptr); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, request.len); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errorbuffer); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT); res = curl_easy_perform(curl); if (res == CURLE_OK) { DBG(DBG_CONTROL, DBG_log("received ocsp response") ) DBG(DBG_RAW, DBG_dump_chunk("OCSP response", response) ) parse_ocsp(location, response); } else { plog("failed to fetch ocsp status (%s): %s", uri, errorbuffer); } curl_slist_free_all(headers); curl_easy_cleanup(curl); pfree(uri); /* not using freeanychunk because of realloc (no leak detective) */ free(response.ptr); } freeanychunk(location->nonce); freeanychunk(request); /* increment the trial counter of the unresolved fetch requests */ { ocsp_certinfo_t *certinfo = location->certinfo; while (certinfo != NULL) { certinfo->trials++; certinfo = certinfo->next; } } return;#else plog("ocsp error: pluto wasn't compiled with libcurl support");#endif}/* * try to fetch the necessary ocsp information */static voidfetch_ocsp(void){ ocsp_location_t *location; lock_ocsp_fetch_list("fetch_ocsp"); location = ocsp_fetch_reqs; /* fetch the ocps status for all locations */ while (location != NULL) { if (location->certinfo != NULL) fetch_ocsp_status(location); location = location->next; } unlock_ocsp_fetch_list("fetch_ocsp");}static void*fetch_thread(void *arg UNUSED){ struct timespec wait_interval; DBG(DBG_CONTROL, DBG_log("fetch thread started") )#ifdef HAVE_THREADS pthread_mutex_lock(&fetch_wake_mutex);#endif while(1) { int status; wait_interval.tv_nsec = 0; wait_interval.tv_sec = time(NULL) + crl_check_interval; DBG(DBG_CONTROL, DBG_log("next regular crl check in %ld seconds", crl_check_interval) ) status = pthread_cond_timedwait(&fetch_wake_cond, &fetch_wake_mutex , &wait_interval); if (status == ETIMEDOUT) { DBG(DBG_CONTROL, DBG_log(" "); DBG_log("*time to check crls and the ocsp cache") ) check_ocsp(); check_crls(); } else { DBG(DBG_CONTROL, DBG_log("fetch thread was woken up") ) } fetch_ocsp(); fetch_crls(); }}/* * initializes curl and starts the fetching thread */voidinit_fetch(void){ int status; if (crl_check_interval > 0) {#ifdef LIBCURL /* init curl */ status = curl_global_init(CURL_GLOBAL_NOTHING); if (status != 0) { plog("libcurl could not be initialized, status = %d", status); }#endif status = pthread_create( &thread, NULL, fetch_thread, NULL); if (status != 0) { plog("fetching thread could not be started, status = %d", status); } }}voidfree_crl_fetch(void){ lock_crl_fetch_list("free_crl_fetch"); while (crl_fetch_reqs != NULL) { fetch_req_t *req = crl_fetch_reqs; crl_fetch_reqs = req->next; free_fetch_request(req); } unlock_crl_fetch_list("free_crl_fetch");#ifdef LIBCURL if (crl_check_interval > 0) { /* cleanup curl */ curl_global_cleanup(); }#endif}/* * free the chained list of ocsp requests */voidfree_ocsp_fetch(void){ lock_ocsp_fetch_list("free_ocsp_fetch"); free_ocsp_locations(&ocsp_fetch_reqs); unlock_ocsp_fetch_list("free_ocsp_fetch");}/* * add additional distribution points */voidadd_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints){ while (newPoints != NULL) { bool add = TRUE; generalName_t *gn = *distributionPoints; while (gn != NULL) { if (gn->kind == newPoints->kind && gn->name.len == newPoints->name.len && memcmp(gn->name.ptr, newPoints->name.ptr, gn->name.len) == 0) { /* distribution point already present, skip to next entry */ add = FALSE; break; } gn = gn->next; } if (add) { /* clone additional distribution point */ gn = clone_thing(*newPoints, "generalName"); clonetochunk(gn->name, newPoints->name.ptr, newPoints->name.len , "crl uri"); /* insert additional CRL distribution point */ gn->next = *distributionPoints; *distributionPoints = gn; } newPoints = newPoints->next; }}/* * add a crl fetch request to the chained list */voidadd_crl_fetch_request(chunk_t issuer, const generalName_t *gn){ fetch_req_t *req; lock_crl_fetch_list("add_crl_fetch_request"); req = crl_fetch_reqs; while (req != NULL) { if (same_dn(issuer, req->issuer)) { /* there is already a fetch request */ DBG(DBG_CONTROL, DBG_log("crl fetch request already exists") ) /* there might be new distribution points */ add_distribution_points(gn, &req->distributionPoints); unlock_crl_fetch_list("add_crl_fetch_request"); return; } req = req->next; } /* create a new fetch request */ req = alloc_thing(fetch_req_t, "fetch request"); *req = empty_fetch_req; /* note current time */ req->installed = time(NULL); /* clone issuer */ clonetochunk(req->issuer, issuer.ptr, issuer.len, "issuer dn"); /* copy distribution points */ add_distribution_points(gn, &req->distributionPoints); /* insert new fetch request at the head of the queue */ req->next = crl_fetch_reqs; crl_fetch_reqs = req; DBG(DBG_CONTROL, DBG_log("crl fetch request added") ) unlock_crl_fetch_list("add_crl_fetch_request");}/* * add an ocsp fetch request to the chained list */voidadd_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber){ ocsp_certinfo_t certinfo; certinfo.serialNumber = serialNumber; lock_ocsp_fetch_list("add_ocsp_fetch_request"); add_certinfo(location, &certinfo, &ocsp_fetch_reqs, TRUE); unlock_ocsp_fetch_list("add_ocsp_fetch_request");}/* * list all distribution points */voidlist_distribution_points(const generalName_t *gn){ bool first_gn = TRUE; while (gn != NULL) { whack_log(RC_COMMENT, " %s '%.*s'", (first_gn)? "distPts:" : " ", (int)gn->name.len, gn->name.ptr); first_gn = FALSE; gn = gn->next; }}/* * list all fetch requests in the chained list */voidlist_crl_fetch_requests(bool utc){ fetch_req_t *req; lock_crl_fetch_list("list_crl_fetch_requests"); req = crl_fetch_reqs; if (req != NULL) { whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, "List of CRL fetch requests:"); whack_log(RC_COMMENT, " "); } while (req != NULL) { u_char buf[BUF_LEN]; char tbuf2[TIMETOA_BUF]; whack_log(RC_COMMENT, "%s, trials: %d" , timetoa(&req->installed, utc, tbuf2, sizeof(tbuf2)) , req->trials); dntoa(buf, BUF_LEN, req->issuer); whack_log(RC_COMMENT, " issuer: '%s'", buf); list_distribution_points(req->distributionPoints); req = req->next; } unlock_crl_fetch_list("list_crl_fetch_requests");}voidlist_ocsp_fetch_requests(bool utc){ lock_ocsp_fetch_list("list_ocsp_fetch_requests"); list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE); unlock_ocsp_fetch_list("list_ocsp_fetch_requests");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -