static bool pluto_init_nss(char *nssdb) { SECStatus rv; char dbuf[1024]; snprintf(dbuf, sizeof(dbuf), "sql:%s", nssdb); loglog(RC_LOG_SERIOUS, "NSS DB directory: %s", dbuf); rv = NSS_Initialize(dbuf, "", "", SECMOD_DB, NSS_INIT_READONLY); if (rv != SECSuccess) { loglog(RC_LOG_SERIOUS, "NSS readonly initialization (\"%s\") failed (err %d)\n", dbuf, PR_GetError()); return FALSE; } libreswan_log("NSS initialized"); PK11_SetPasswordFunc(getNSSPassword); /* * This exists purely to make the BSI happy. * We do not inflict this on other users */ if (pluto_nss_seedbits != 0) { int seedbytes = BYTES_FOR_BITS(pluto_nss_seedbits); unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix"); get_bsi_random(seedbytes, buf); /* much TLA, very blocking */ rv = PK11_RandomUpdate(buf, seedbytes); libreswan_log("seeded %d bytes into the NSS PRNG", seedbytes); passert(rv == SECSuccess); messupn(buf, seedbytes); pfree(buf); } return TRUE; }
inline double mandelbrot9(double* xList,double* yList,const long max_iter,long& out_i){ const static double M=256; const static double lnln_M=loglog(M); const double& x0=xList[0]; const double& y0=yList[0]; double x_bck=0; double y_bck=0; double x=x0; double y=y0; long i=0; for (;i<max_iter;++i){ if (x*x+y*y>=M) break; x_bck=x; y_bck=y; double tmp=x*x-y*y+x0; y=x*y*2+y0; x=tmp; xList[i+1]=x; yList[i+1]=y; } out_i=i; if (i!=max_iter){ const double lnln_Z=loglog(x*x+y*y); const double lnln_Zbak=loglog(x_bck*x_bck+y_bck*y_bck); return i-2-(lnln_Z-lnln_M)/(lnln_Z-lnln_Zbak); }else return i; }
/* * This function MUST NOT be used for anything else! * It is used to seed the NSS PRNG based on --seedbits pluto argument * or the seedbits= * config setup option in ipsec.conf. * Everything else that needs random MUST use get_rnd_bytes() * This function MUST NOT be changed to use /dev/urandom. */ static void get_bsi_random(size_t nbytes, unsigned char *buf) { size_t ndone; int dev; ssize_t got; const char *device = "/dev/random"; dev = open(device, 0); if (dev < 0) { loglog(RC_LOG_SERIOUS, "could not open %s (%s)\n", device, strerror(errno)); exit_pluto(PLUTO_EXIT_NSS_FAIL); } ndone = 0; DBG(DBG_CONTROL,DBG_log("need %d bits random for extra seeding of the NSS PRNG", (int) nbytes * BITS_PER_BYTE)); while (ndone < nbytes) { got = read(dev, buf + ndone, nbytes - ndone); if (got < 0) { loglog(RC_LOG_SERIOUS,"read error on %s (%s)\n", device, strerror(errno)); exit_pluto(PLUTO_EXIT_NSS_FAIL); } if (got == 0) { loglog(RC_LOG_SERIOUS,"EOF on %s!?!\n", device); exit_pluto(PLUTO_EXIT_NSS_FAIL); } ndone += got; } close(dev); DBG(DBG_CONTROL,DBG_log("read %zu bytes from /dev/random for NSS PRNG", nbytes)); }
static bool pluto_init_nss(char *nssdb) { SECStatus rv; /* little lie, lsw_nss_setup doesn't have logging */ loglog(RC_LOG_SERIOUS, "NSS DB directory: sql:%s", nssdb); lsw_nss_buf_t err; if (!lsw_nss_setup(nssdb, LSW_NSS_READONLY, lsw_nss_get_password, err)) { loglog(RC_LOG_SERIOUS, "%s", err); return FALSE; } libreswan_log("NSS initialized"); /* * This exists purely to make the BSI happy. * We do not inflict this on other users */ if (pluto_nss_seedbits != 0) { int seedbytes = BYTES_FOR_BITS(pluto_nss_seedbits); unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix"); get_bsi_random(seedbytes, buf); /* much TLA, very blocking */ rv = PK11_RandomUpdate(buf, seedbytes); libreswan_log("seeded %d bytes into the NSS PRNG", seedbytes); passert(rv == SECSuccess); messupn(buf, seedbytes); pfree(buf); } return TRUE; }
static void crypto_display_hex (void *ptr, int len, char *msg) { int i; loglog(RC_LOG_SERIOUS,"User Space"); loglog(RC_LOG_SERIOUS,"%s Len=%d", msg, len); for (i = 0; i < len; i=i+8) { loglog(RC_LOG_SERIOUS,"%02x %02x %02x %02x %02x %02x %02x %02x", ((uint8_t *) ptr)[i],((uint8_t *) ptr)[i+1],((uint8_t *) ptr)[i+2],((uint8_t *) ptr)[i+3] , ((uint8_t *) ptr)[i+4],((uint8_t *) ptr)[i+5],((uint8_t *) ptr)[i+6],((uint8_t *) ptr)[i+7]); } }
stf_status dpd_init(struct state *st) { /** * Used to store the 1st state */ struct state *p1st; /* find the related Phase 1 state */ p1st = find_state_ikev1(st->st_icookie, st->st_rcookie, 0); if (p1st == NULL) { loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD"); /* * if the phase 1 state has gone away, it really should have * deleted all of its children. * Why would this happen? because a quick mode SA can take * some time to create (DNS lookups for instance), and the phase 1 * might have been taken down for some reason in the meantime. * We really cannot do anything here --- attempting to invoke * the DPD action would be a good idea, but we really should * do that outside this function. */ return STF_FAIL; } /* if it was enabled, and we haven't turned it on already */ if (p1st->hidden_variables.st_peer_supports_dpd) { DBG(DBG_DPD, DBG_log("Dead Peer Detection (RFC 3706): enabled")); if (st->st_dpd_event == NULL || ev_before(st->st_dpd_event, st->st_connection->dpd_delay)){ if (st->st_dpd_event != NULL) delete_dpd_event(st); event_schedule(EVENT_DPD, deltasecs(st->st_connection->dpd_delay), st); } } else { loglog(RC_LOG_SERIOUS, "Configured DPD (RFC 3706) support not enabled because remote peer did not advertise DPD support"); } if (p1st != st) { /* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */ if (p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD) delete_dpd_event(p1st); } return STF_OK; }
static void pluto_init_nss(char *confddir) { char buf[100]; snprintf(buf, sizeof(buf), "%s",confddir); loglog(RC_LOG_SERIOUS,"nss directory plutomain: %s",buf); SECStatus nss_init_status= NSS_InitReadWrite(buf); if (nss_init_status != SECSuccess) { loglog(RC_LOG_SERIOUS, "NSS initialization failed (err %d)\n", PR_GetError()); exit_pluto(10); } else { libreswan_log("NSS Initialized"); PK11_SetPasswordFunc(getNSSPassword); } }
static void helper_passert_fail(const char *pred_str , const char *file_str , unsigned long line_no) { /* we will get a possibly unplanned prefix. Hope it works */ loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str); if(chdir("helper") == -1) { int e = errno; loglog(RC_LOG_SERIOUS,"pluto: chdir() to 'helper' failed (%d %s)\n", e, strerror(e)); } osw_abort(); }
void pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no) { /* we will get a possibly unplanned prefix. Hope it works */ loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str); }
void passert_fail(const char *pred_str, const char *file_str, unsigned long line_no) { /* we will get a possibly unplanned prefix. Hope it works */ loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str); abort(); /* exiting correctly doesn't always work */ }
/** netlink_policy - * * @param hdr - Data to check * @param enoent_ok - Boolean - OK or not OK. * @param text_said - String * @return boolean */ static bool netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said) { struct { struct nlmsghdr n; struct nlmsgerr e; } rsp; int error; rsp.n.nlmsg_type = NLMSG_ERROR; if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said)) { return FALSE; } error = -rsp.e.error; if (!error) { return TRUE; } if (error == ENOENT && enoent_ok) { return TRUE; } loglog(RC_LOG_SERIOUS , "ERROR: netlink %s response for flow %s included errno %d: %s" , sparse_val_show(xfrm_type_names, hdr->nlmsg_type) , text_said , error , strerror(error)); return FALSE; }
void initiate_connection(const char *name, int whackfd , lset_t moredebug , enum crypto_importance importance) { struct initiate_stuff is; struct connection *c = con_by_name(name, FALSE); int count; is.whackfd = whackfd; is.moredebug = moredebug; is.importance= importance; if (c != NULL) { initiate_a_connection(c, &is); close_any(is.whackfd); return; } loglog(RC_COMMENT, "initiating all conns with alias='%s'\n", name); count = foreach_connection_by_alias(name, initiate_a_connection, &is); if(count == 0) { whack_log(RC_UNKNOWN_NAME , "no connection named \"%s\"", name); } close_any(is.whackfd); }
/* when a X.509 certificate gets revoked, all instances of * the corresponding public key must be removed */ void remove_x509_public_key(/*const*/ x509cert_t *cert) { const cert_t c = {FALSE, CERT_X509_SIGNATURE, {cert}}; struct pubkey_list *p, **pp; struct pubkey *revoked_pk; revoked_pk = allocate_RSA_public_key(c); p = pluto_pubkeys; pp = &pluto_pubkeys; while(p != NULL) { if (same_RSA_public_key(&p->key->u.rsa, &revoked_pk->u.rsa)) { /* remove p from list and free memory */ *pp = free_public_keyentry(p); loglog(RC_LOG_SERIOUS, "invalid RSA public key deleted"); } else { pp = &p->next; } p =*pp; } free_public_key(revoked_pk); }
stf_status build_nonce(struct pluto_crypto_req_cont *cn , struct state *st , enum crypto_importance importance) { struct pluto_crypto_req rd; struct pluto_crypto_req *r = &rd; err_t e; bool toomuch = FALSE; pcr_init(r, pcr_build_nonce, importance); cn->pcrc_serialno = st->st_serialno; e = send_crypto_helper_request(r, cn, &toomuch); if(e != NULL) { loglog(RC_LOG_SERIOUS, "can not start crypto helper: %s", e); if(toomuch) { return STF_TOOMUCHCRYPTO; } else { return STF_FAIL; } } else if(!toomuch) { st->st_calculating = TRUE; delete_event(st); event_schedule(EVENT_CRYPTO_FAILED, EVENT_CRYPTO_FAILED_DELAY, st); return STF_SUSPEND; } else { /* we must have run the continuation directly, so * complete_v1_state_transition already got called. */ return STF_INLINE; } }
stf_status dpd_init(struct state *st) { /** * Used to store the 1st state */ #ifdef HAVE_LABELED_IPSEC if (st->st_connection->loopback) { libreswan_log( "dpd is not required for ipsec connections over loopback"); return STF_OK; } #endif struct state *p1st; /* find the related Phase 1 state */ p1st = find_state_ikev1(st->st_icookie, st->st_rcookie, 0); if (p1st == NULL) { loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD"); /* * if the phase 1 state has gone away, it really should have * deleted all of its children. * Why would this happen? because a quick mode SA can take * some time to create (DNS lookups for instance), and the phase 1 * might have been taken down for some reason in the meantime. * We really can not do anything here --- attempting to invoke * the DPD action would be a good idea, but we really should * do that outside this function. */ return STF_FAIL; } /* if it was enabled, and we haven't turned it on already */ if (p1st->hidden_variables.st_dpd) { time_t n = now(); libreswan_log("Dead Peer Detection (RFC 3706): enabled"); if (st->st_dpd_event == NULL || (st->st_connection->dpd_delay + n) < st->st_dpd_event->ev_time) { if (st->st_dpd_event != NULL) delete_dpd_event(st); event_schedule(EVENT_DPD, st->st_connection->dpd_delay, st); } } else { libreswan_log( "Dead Peer Detection (RFC 3706): not enabled because peer did not advertise it"); } if (p1st != st) { /* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */ if (p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD) delete_dpd_event(p1st); } return STF_OK; }
static void key_add_ugh(const struct id *keyid, err_t ugh) { char name[IDTOA_BUF]; /* longer IDs will be truncated in message */ (void)idtoa(keyid, name, sizeof(name)); loglog(RC_NOKEY, "failure to fetch key for %s from DNS: %s", name, ugh); }
int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds) { /* WIN32: supported since Win2K, but might need some adjustements */ /* UNIX: this should work for any remotely Unix'ish system */ select_info *s = (select_info *)data; /* add only if we had a failed write */ int writefds_add = 0; if (s->send_fail_eagain != 0) { // current_time(): microseconds uint64_t now = current_time(); /* s->sendqueue_length: might be used to guess how long we keep checking */ /* for now, threshold is hardcoded to 500ms, too long for a really really * fast link, but too short for a sloooooow link... */ if (now - s->send_fail_eagain < 500000) writefds_add = 1; } int nfds = 1 + s->sock; /* the FD_ZERO calls might be superfluous */ fd_set readfds; FD_ZERO(&readfds); FD_SET(s->sock, &readfds); fd_set writefds; FD_ZERO(&writefds); if (writefds_add) FD_SET(s->sock, &writefds); fd_set exceptfds; FD_ZERO(&exceptfds); FD_SET(s->sock, &exceptfds); struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = milliseconds * 1000; #ifdef LOGGING errno = 0; #endif /* returns -1 on error, 0 on timeout, the socket on activity */ int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); #ifdef LOGGING sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), FD_ISSET(s->sock, &exceptfds)); loglog(logbuffer); #endif if (FD_ISSET(s->sock, &writefds)) s->send_fail_reset = 1; return res > 0 ? 1 : 0; };
/* Function to receive data * ip and port of sender is put into ip_port. * Packet data is put into data. * Packet length is put into length. * Dump all empty packets. */ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) { struct sockaddr_storage addr; #ifdef WIN32 int addrlen = sizeof(addr); #else socklen_t addrlen = sizeof(addr); #endif *length = 0; int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); if (fail_or_len <= 0) { #ifdef LOGGING if ((fail_or_len < 0) && (errno != EWOULDBLOCK)) { sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); loglog(logbuffer); } #endif return -1; /* Nothing received or empty packet. */ } *length = (uint32_t)fail_or_len; #ifdef TOX_ENABLE_IPV6 if (addr.ss_family == AF_INET) { struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; ip_port->ip.family = addr_in->sin_family; ip_port->ip.ip4.in_addr = addr_in->sin_addr; ip_port->port = addr_in->sin_port; } else if (addr.ss_family == AF_INET6) { struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; ip_port->ip.family = addr_in6->sin6_family; ip_port->ip.ip6.in6_addr = addr_in6->sin6_addr; ip_port->port = addr_in6->sin6_port; } else return -1; #else if (addr.ss_family == AF_INET) { struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; ip_port->ip.in_addr = addr_in->sin_addr; ip_port->port = addr_in->sin_port; } else return -1; #endif #ifdef LOGGING loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length); #endif return 0; }
void get_rnd_bytes(u_char *buffer, int length) { SECStatus rv = PK11_GenerateRandom(buffer, length); if (rv != SECSuccess) { loglog(RC_LOG_SERIOUS, "NSS RNG failed"); abort(); } }
void block_peer_log(const char *msg, block_peer *peer) { char peer_ip_str[IDTOA_BUF]; struct id id; iptoid(&peer->ip, &id); idtoa(&id, peer_ip_str, IDTOA_BUF); loglog(RC_LOG_SERIOUS, msg, peer_ip_str); }
static int nss_err_to_revfail(CERTVerifyLogNode *node) { int ret = VERIFY_RET_FAIL; if (node == NULL || node->cert == NULL) { return ret; } loglog(RC_LOG_SERIOUS, "Certificate %s failed verification", node->cert->subjectName); loglog(RC_LOG_SERIOUS, "ERROR: %s", nss_err_str(node->error)); if (node->error == SEC_ERROR_REVOKED_CERTIFICATE) { ret = VERIFY_RET_REVOKED; } return ret; }
/* * used by responder, for extracting PPK_ID from IKEv2 Notify * PPK_ID Payload, we store PPK_ID and its type in payl */ bool extract_ppk_id(pb_stream *pbs, struct ppk_id_payload *payl) { size_t len = pbs_left(pbs); u_char dst[PPK_ID_MAXLEN]; int idtype; if (len > PPK_ID_MAXLEN) { loglog(RC_LOG_SERIOUS, "PPK ID length is too big"); return FALSE; } if (len <= 1) { loglog(RC_LOG_SERIOUS, "PPK ID data must be at least 1 byte (received %zd bytes including ppk type byte)", len); return FALSE; } if (!in_raw(dst, len, pbs, "Unified PPK_ID Payload")) { loglog(RC_LOG_SERIOUS, "PPK ID data could not be read"); return FALSE; } DBG(DBG_CONTROL, DBG_log("received PPK_ID type: %s", enum_name(&ikev2_ppk_id_type_names, dst[0]))); idtype = (int)dst[0]; switch (idtype) { case PPK_ID_FIXED: DBG(DBG_CONTROL, DBG_log("PPK_ID of type PPK_ID_FIXED.")); break; case PPK_ID_OPAQUE: default: loglog(RC_LOG_SERIOUS, "PPK_ID type %d (%s) not supported", idtype, enum_name(&ikev2_ppk_id_type_names, idtype)); return FALSE; } /* clone ppk id data without ppk id type byte */ clonetochunk(payl->ppk_id, dst + 1, len - 1, "PPK_ID data"); DBG(DBG_CONTROL, DBG_dump_chunk("Extracted PPK_ID", payl->ppk_id)); return TRUE; }
/** Read a subnet (IPv4/IPv6) * read %v4:x.x.x.x/y or %v6:xxxxxxxxx/yy * or %v4:!x.x.x.x/y if dstko not NULL * * @param src String in format (see above) * @param len Length of src string * @param dst IP Subnet Destination * @param dstko IP Subnet * @param isok Boolean * @return bool If the format string is valid. */ static bool _read_subnet(const char *src, size_t len, ip_subnet *dst, ip_subnet *dstko, bool *isok) { bool ok; int af; /* workaround for typo "%4:" instead of "%v4:" introduced in old libreswan release*/ int offset = 0; if ((len > 4) && (strncmp(src, "%v4:", 4) == 0)) { af = AF_INET; } else if ((len > 4) && (strncmp(src, "%v6:", 4) == 0)) { af = AF_INET6; } else if ((len > 4) && (strncmp(src, "%4:", 3) == 0)) { af = AF_INET; offset = -1; loglog(RC_LOG_SERIOUS, "fixup for bad virtual_private entry '%s', please fix your virtual_private line!", src); } else { return FALSE; } ok = (src[4 + offset] == '!') ? FALSE : TRUE; src += ok ? (4 + offset) : (5 + offset); len -= ok ? (4 + offset) : (5 + offset); if (!len) return FALSE; if ((!ok) && (!dstko)) return FALSE; passert( ((ok) ? (dst) : (dstko)) != NULL ); if (ttosubnet(src, len, af, ((ok) ? (dst) : (dstko)))) { loglog(RC_LOG_SERIOUS, "fail in ttosubnet ?"); return FALSE; } if (isok) *isok = ok; return TRUE; }
/* * initialize a ub_ctx for asynchronous calls using libevent from pluto. * only call once */ bool unbound_event_init(struct event_base *eb, bool do_dnssec, const char *rootfile, const char *trusted) { passert(dns_ctx == NULL); /* block re-entry to the function */ dns_ctx = ub_ctx_create_event(eb); if (dns_ctx == NULL) { loglog(RC_LOG_SERIOUS, "Failed to initialize unbound libevent ABI, please recompile libunbound with libevent support or recompile libreswan without USE_DNSSEC"); return FALSE; } unbound_ctx_config(do_dnssec, rootfile, trusted); return TRUE; }
/** ensures we are at a Record (or File) boundary, optionally warning if not * * @param m string * @return bool True if everything is ok */ bool flushline(const char *m) { if (flp->bdry != B_none) { return TRUE; } else { if (m != NULL) loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m); do {} while (shift()); return FALSE; } }
/** is_virtual_net_allowed - * Check if the virtual network the client proposes is acceptable to us * * @param c Connection structure (active) * @param peer_net IP Subnet the peer proposes * @param his_addr Peers IP Address * @return bool True if allowed */ err_t is_virtual_net_allowed(const struct connection *c, const ip_subnet *peer_net, const ip_address *his_addr) { err_t why = NULL; if (!c->spd.that.virt) return NULL; if (c->spd.that.virt->flags & F_VIRTUAL_HOST) { if (!subnetishost(peer_net)) { why = "only virtual host IPs are allowed"; return why; } } if (c->spd.that.virt->flags & F_VIRTUAL_NO) { if (subnetishost(peer_net) && addrinsubnet(his_addr, peer_net)) return NULL; } if (c->spd.that.virt->flags & F_VIRTUAL_PRIVATE) { if (net_in_list(peer_net, private_net_ok, private_net_ok_len) && !net_in_list(peer_net, private_net_ko, private_net_ko_len)) return NULL; why = "a private network virtual IP was required, but the proposed IP did not match our list (virtual_private=)"; } if (c->spd.that.virt->n_net) { if (net_in_list(peer_net, c->spd.that.virt->net, c->spd.that.virt->n_net)) return NULL; why = "a specific network IP was required, but the proposed IP did not match our list (subnet=vhost:list)"; } if (c->spd.that.virt->flags & F_VIRTUAL_ALL) { /* %all must only be used for testing - log it */ loglog(RC_LOG_SERIOUS, "Warning - " "v%s:%%all must only be used for testing", (c->spd.that.virt->flags & F_VIRTUAL_HOST) ? "host" : "net"); return NULL; } return why; }
void passert_fail(const char *pred_str, const char *file_str, unsigned long line_no) { /* we will get a possibly unplanned prefix. Hope it works */ loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str); if (!dying_breath) { dying_breath = TRUE; show_status(); } /* exiting correctly doesn't always work */ libreswan_log_abort(file_str, line_no); }
/** * nat_traversal_natoa_lookup() * * Look for NAT-OA in message */ void nat_traversal_natoa_lookup(struct msg_digest *md) { struct payload_digest *p; struct state *st = md->st; int i; ip_address ip; if (!st || !md->iface) { loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d", __FILE__, __LINE__); return; } /** Count NAT-OA **/ for (p = md->chain[ISAKMP_NEXT_NATOA_R], i=0; p != NULL; p = p->next, i++); #if 0 DBG_log("NAT-Traversal: received %d NAT-OA.", i); #endif if (i==0) { return; } else if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))) { loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. " "ignored because peer is not NATed", i); return; } else if (i>1) { loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. " "using first, ignoring others", i); } /** Take first **/ p = md->chain[ISAKMP_NEXT_NATOA_R]; DBG(DBG_PARSING, DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs)); );
void ikev2_decode_cert(struct msg_digest *md) { struct payload_digest *p; for (p = md->chain[ISAKMP_NEXT_v2CERT]; p != NULL; p = p->next) { struct ikev2_cert *const v2cert = &p->payload.v2cert; chunk_t blob; time_t valid_until; blob.ptr = p->pbs.cur; blob.len = pbs_left(&p->pbs); if (v2cert->isac_enc == CERT_X509_SIGNATURE) { x509cert_t cert2 = empty_x509cert; if (parse_x509cert(blob, 0, &cert2)) { if (verify_x509cert(&cert2, strict_crl_policy, &valid_until)) { DBG(DBG_X509 | DBG_PARSING, DBG_log("Public key validated") ) add_x509_public_key(NULL, &cert2, valid_until, DAL_SIGNED); } else { plog("X.509 certificate rejected"); } free_generalNames(cert2.subjectAltName, FALSE); free_generalNames(cert2.crlDistributionPoints, FALSE); } else plog("Syntax error in X.509 certificate"); } else if (v2cert->isac_enc == CERT_PKCS7_WRAPPED_X509) { x509cert_t *cert2 = NULL; if (parse_pkcs7_cert(blob, &cert2)) store_x509certs(&cert2, strict_crl_policy); else plog("Syntax error in PKCS#7 wrapped X.509 certificates"); } else { loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload", enum_show(&ikev2_cert_type_names, v2cert->isac_enc)); DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob); } } }
/* * clean up after a crypto helper */ static void cleanup_crypto_helper(struct pluto_crypto_worker *w , int status) { if(w->pcw_pipe) { loglog(RC_LOG_SERIOUS, "closing helper(%lu) pid=%lu fd=%d exit=%d" , (unsigned long)w->pcw_helpernum, (unsigned long)w->pcw_pid, w->pcw_pipe, status); close(w->pcw_pipe); } w->pcw_pid = -1; w->pcw_work = 0; /* ?!? */ w->pcw_reaped = FALSE; w->pcw_dead = FALSE; /* marking is not dead lets it live again */ }