📄 connections.c
字号:
p->host_pair = NULL; p->hp_next = unoriented_connections; unoriented_connections = p; } else { /* The connection should have vanished, * but the previous connection remains. */ passert(p != *pp); } } else { pp = &p->hp_next; /* advance pp */ } } }}/* adjust orientations of connections to reflect newly added interfaces */voidcheck_orientations(void){ /* try to orient all the unoriented connections */ { struct connection *c = unoriented_connections; unoriented_connections = NULL; while (c != NULL) { struct connection *nxt = c->hp_next; (void)orient(c); connect_to_host_pair(c); c = nxt; } } /* Check that no oriented connection has become double-oriented. * In other words, the far side must not match one of our new interfaces. */ { struct iface_port *i; for (i = interfaces; i != NULL; i = i->next) { if (i->change == IFN_ADD) { struct host_pair *hp; for (hp = host_pairs; hp != NULL; hp = hp->next) { if (sameaddr(&hp->him.addr, &i->ip_addr) && (kern_interface!=NO_KERNEL || hp->him.host_port == pluto_port)) { /* bad news: the whole chain of connections * hanging off this host pair has both sides * matching an interface. * We'll get rid of them, using orient and * connect_to_host_pair. But we'll be lazy * and not ditch the host_pair itself (the * cost of leaving it is slight and cannot * be induced by a foe). */ struct connection *c = hp->connections; hp->connections = NULL; while (c != NULL) { struct connection *nxt = c->hp_next; c->interface = NULL; (void)orient(c); connect_to_host_pair(c); c = nxt; } } } } } }}static err_tdefault_end(struct end *e, ip_address *dflt_nexthop){ err_t ugh = NULL; const struct af_info *afi = aftoinfo(addrtypeof(&e->host_addr)); if (afi == NULL) return "unknown address family in default_end"; /* default ID to IP (but only if not NO_IP -- WildCard) */ if (e->id.kind == ID_NONE && !isanyaddr(&e->host_addr)) { e->id.kind = afi->id_addr; e->id.ip_addr = e->host_addr; e->has_id_wildcards = FALSE; } /* default nexthop to other side */ if (isanyaddr(&e->host_nexthop)) e->host_nexthop = *dflt_nexthop; /* default client to subnet containing only self * XXX This may mean that the client's address family doesn't match * tunnel_addr_family. */ if (!e->has_client) ugh = addrtosubnet(&e->host_addr, &e->client); if(e->sendcert == 0) { e->sendcert = cert_sendifasked; } return ugh;}/* Format the topology of a connection end, leaving out defaults. * Largest left end looks like: client === host : port [ host_id ] --- hop * Note: if that==NULL, skip nexthop * Returns strlen of formated result (length excludes NUL at end). */size_tformat_end(char *buf , size_t buf_len , const struct end *this , const struct end *that , bool is_left , lset_t policy){ char client[SUBNETTOT_BUF]; const char *client_sep = ""; char protoport[sizeof(":255/65535")]; const char *host = NULL; char host_space[ADDRTOT_BUF]; char host_port[sizeof(":65535")]; char host_id[IDTOA_BUF + 2]; char hop[ADDRTOT_BUF]; char endopts[sizeof("MS+MC+XS+XC")+1]; const char *hop_sep = ""; const char *open_brackets = ""; const char *close_brackets = ""; const char *id_obrackets = ""; const char *id_cbrackets = ""; const char *id_comma = ""; memset(endopts, 0, sizeof(endopts)); if (isanyaddr(&this->host_addr)) { switch (policy & (POLICY_GROUP | POLICY_OPPO)) { case POLICY_GROUP: host = "%group"; break; case POLICY_OPPO: host = "%opportunistic"; break; case POLICY_GROUP | POLICY_OPPO: host = "%opportunisticgroup"; break; default: host = "%any"; break; } } client[0] = '\0';#ifdef VIRTUAL_IP if (is_virtual_end(this) && isanyaddr(&this->host_addr)) { host = "%virtual"; }#endif /* [client===] */ if (this->has_client) { ip_address client_net, client_mask; networkof(&this->client, &client_net); maskof(&this->client, &client_mask); client_sep = "==="; /* {client_subnet_wildcard} */ if (this->has_client_wildcard) { open_brackets = "{"; close_brackets = "}"; } if (isanyaddr(&client_net) && isanyaddr(&client_mask) && (policy & (POLICY_GROUP | POLICY_OPPO))) client_sep = ""; /* boring case */ else if (subnetisnone(&this->client)) strcpy(client, "?"); else subnettot(&this->client, 0, client, sizeof(client)); } /* host */ if (host == NULL) { addrtot(&this->host_addr, 0, host_space, sizeof(host_space)); host = host_space; } host_port[0] = '\0'; if (this->host_port_specific) snprintf(host_port, sizeof(host_port), ":%u" , this->host_port); /* payload portocol and port */ protoport[0] = '\0'; if (this->has_port_wildcard) snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol); else if (this->port || this->protocol) snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol , this->port); /* id, if different from host */ host_id[0] = '\0'; if (this->id.kind == ID_MYID) { id_obrackets = "["; id_cbrackets = "]"; strcpy(host_id, "%myid"); } else if (!(this->id.kind == ID_NONE || (id_is_ipaddr(&this->id) && sameaddr(&this->id.ip_addr, &this->host_addr)))) { id_obrackets = "["; id_cbrackets = "]"; idtoa(&this->id, host_id, sizeof(host_id)); } if(this->modecfg_server || this->modecfg_client || this->xauth_server || this->xauth_client || this->sendcert != cert_defaultcertpolicy) { const char *plus = ""; endopts[0]='\0'; if(id_obrackets && id_obrackets[0]=='[') { id_comma=","; } else { id_obrackets = "["; id_cbrackets = "]"; } if(this->modecfg_server) { strncat(endopts, plus, sizeof(endopts)); strncat(endopts, "MS", sizeof(endopts)); plus="+"; } if(this->modecfg_client) { strncat(endopts, plus, sizeof(endopts)); strncat(endopts, "MC", sizeof(endopts)); plus="+"; } if(this->xauth_server) { strncat(endopts, plus, sizeof(endopts)); strncat(endopts, "XS", sizeof(endopts)); plus="+"; } if(this->xauth_client) { strncat(endopts, plus, sizeof(endopts)); strncat(endopts, "XC", sizeof(endopts)); plus="+"; } { const char *send = ""; char s[32]; send=""; switch(this->sendcert) { case cert_neversend: send="S-C"; break; case cert_sendifasked: send="S?C"; break; case cert_alwayssend: send="S=C"; break; case cert_forcedtype: sprintf(s, "S%d", this->cert.type); send=s; break; } strncat(endopts, plus, sizeof(endopts)); strncat(endopts, send, sizeof(endopts)); plus="+"; } } /* [---hop] */ hop[0] = '\0'; hop_sep = ""; if (that != NULL && !sameaddr(&this->host_nexthop, &that->host_addr)) { addrtot(&this->host_nexthop, 0, hop, sizeof(hop)); hop_sep = "---"; } if (is_left) snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" , open_brackets, client, close_brackets , client_sep, host, host_port , id_obrackets, host_id, id_comma, endopts, id_cbrackets , protoport, hop_sep, hop); else snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" , hop, hop_sep, host, host_port , id_obrackets, host_id, id_comma, endopts, id_cbrackets , protoport, client_sep , open_brackets, client, close_brackets); return strlen(buf);}/* format topology of a connection. * Two symmetric ends separated by ... */#define CONNECTION_BUF (2 * (END_BUF - 1) + 4)static size_tformat_connection(char *buf, size_t buf_len , const struct connection *c , struct spd_route *sr){ size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY); w += snprintf(buf + w, buf_len - w, "..."); return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy);}static voidunshare_connection_strings(struct connection *c){ c->name = clone_str(c->name, "connection name"); unshare_id_content(&c->spd.this.id); c->spd.this.updown = clone_str(c->spd.this.updown, "updown");#ifdef SMARTCARD scx_share(c->spd.this.sc);#endif share_cert(c->spd.this.cert); if (c->spd.this.ca.ptr != NULL) clonetochunk(c->spd.this.ca, c->spd.this.ca.ptr, c->spd.this.ca.len, "ca string"); unshare_id_content(&c->spd.that.id); c->spd.that.updown = clone_str(c->spd.that.updown, "updown");#ifdef SMARTCARD scx_share(c->spd.that.sc);#endif share_cert(c->spd.that.cert); if (c->spd.that.ca.ptr != NULL) clonetochunk(c->spd.that.ca, c->spd.that.ca.ptr, c->spd.that.ca.len, "ca string"); /* increment references to algo's, if any */ if(c->alg_info_ike) { alg_info_addref(IKETOINFO(c->alg_info_ike)); } if(c->alg_info_esp) { alg_info_addref(ESPTOINFO(c->alg_info_esp)); }}static voidload_end_certificate(const char *filename, struct end *dst){ time_t valid_until; cert_t cert; bool valid_cert = FALSE; bool cached_cert = FALSE; memset(&dst->cert, 0, sizeof(dst->cert)); /* initialize end certificate */ dst->cert.type = CERT_NONE; /* initialize smartcard info record */ dst->sc = NULL; if (filename != NULL) {#ifdef SMARTCARD if (strncmp(filename, SCX_TOKEN, strlen(SCX_TOKEN)) == 0) { /* we have a smartcard */ smartcard_t *sc = scx_parse_reader_id(filename + strlen(SCX_TOKEN)); dst->sc = scx_add(sc); /* is there a cached smartcard certificate? */ cached_cert = dst->sc->last_cert.type != CERT_NONE && (time(NULL) - dst->sc->last_load) < SCX_CERT_CACHE_INTERVAL; if (cached_cert) { cert = dst->sc->last_cert; valid_cert = TRUE; } else valid_cert = scx_load_cert(dst->sc, &cert); } else#endif { /* load cert from file */ valid_cert = load_host_cert(FALSE, filename, &cert); } } if (valid_cert) { err_t ugh = NULL; switch (cert.type) { case CERT_PGP: select_pgpcert_id(cert.u.pgp, &dst->id); if (cached_cert) dst->cert = cert; else { valid_until = cert.u.pgp->until; add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL); dst->cert.type = cert.type; dst->cert.u.pgp = add_pgpcert(cert.u.pgp); } break; case CERT_X509_SIGNATURE: select_x509cert_id(cert.u.x509, &dst->id); if (!cached_cert) { /* check validity of cert */ valid_until = cert.u.x509->notAfter; ugh = check_validity(cert.u.x509, &valid_until); } if (ugh != NULL) { openswan_log(" %s", ugh); free_x509cert(cert.u.x509); } else { DBG(DBG_CONTROL, DBG_log("certificate is valid") ) if (cached_cert) dst->cert = cert; else { add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL); dst->cert.type = cert.type; dst->cert.u.x509 = add_x509cert(cert.u.x509); } /* if no CA is defined, use issuer as default */ if (dst->ca.ptr == NULL) dst->ca = dst->cert.u.x509->issuer; } break; default: break; } /* cache the certificate that was last retrieved from the smartcard */ if (dst->sc != NULL) { if (!same_cert(&dst->sc->last_cert, &dst->cert)) { release_cert(dst->sc->last_cert); dst->sc->last_cert = dst->cert; share_cert(dst->cert); } time(&dst->sc->last_load); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -