⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connections.c

📁 ipsec vpn
💻 C
📖 第 1 页 / 共 5 页
字号:
static boolextract_end(struct end *dst, const struct whack_end *src, const char *which){    bool same_ca = FALSE;    /* decode id, if any */    if (src->id == NULL)    {	dst->id.kind = ID_NONE;    }    else    {	err_t ugh = atoid(src->id, &dst->id, TRUE);	if (ugh != NULL)	{	    loglog(RC_BADID, "bad %s --id: %s (ignored)", which, ugh);	    dst->id = empty_id;	/* ignore bad one */	}    }    dst->ca = empty_chunk;    /* decode CA distinguished name, if any */    if (src->ca != NULL)    {	if streq(src->ca, "%same")	    same_ca = TRUE;	else if (!streq(src->ca, "%any"))	{	    err_t ugh;	    dst->ca.ptr = temporary_cyclic_buffer();	    ugh = atodn(src->ca, &dst->ca);	    if (ugh != NULL)	    {		openswan_log("bad CA string '%s': %s (ignored)", src->ca, ugh);		dst->ca = empty_chunk;	    }	}    }    if(src->sendcert == cert_forcedtype) {	/* certificate is a blob */	dst->cert.forced = TRUE;	dst->cert.type = src->certtype;	load_cert(TRUE, src->cert, "forced cert", &dst->cert);    } else {	/* load local end certificate and extract ID, if any */	load_end_certificate(src->cert, dst);    }    /* does id has wildcards? */    dst->has_id_wildcards = id_count_wildcards(&dst->id) > 0;    /* decode group attributes, if any */    decode_groups(src->groups, &dst->groups);    /* the rest is simple copying of corresponding fields */    dst->host_addr = src->host_addr;    dst->host_nexthop = src->host_nexthop;    dst->host_srcip = src->host_srcip;    dst->client = src->client;#ifdef MODECFG    dst->modecfg_server = src->modecfg_server;    dst->modecfg_client = src->modecfg_client;#endif#ifdef XAUTH    dst->xauth_server = src->xauth_server;    dst->xauth_client = src->xauth_client;#endif    dst->protocol = src->protocol;    dst->port = src->port;    dst->has_port_wildcard = src->has_port_wildcard;    dst->key_from_DNS_on_demand = src->key_from_DNS_on_demand;    dst->has_client = src->has_client;    dst->has_client_wildcard = src->has_client_wildcard;    dst->updown = src->updown;    dst->host_port = IKE_UDP_PORT;    if(src->host_port != IKE_UDP_PORT) {	dst->host_port = src->host_port;	dst->host_port_specific = TRUE;    }    dst->sendcert =  src->sendcert;        return same_ca;}static boolcheck_connection_end(const struct whack_end *this, const struct whack_end *that, const struct whack_message *wm){    if (wm->addr_family != addrtypeof(&this->host_addr)    || wm->addr_family != addrtypeof(&this->host_nexthop)    || (this->has_client? wm->tunnel_addr_family : wm->addr_family)      != subnettypeof(&this->client)    || subnettypeof(&this->client) != subnettypeof(&that->client))    {	/* this should have been diagnosed by whack, so we need not be clear	 * !!! overloaded use of RC_CLASH	 */	loglog(RC_CLASH, "address family inconsistency in connection");	return FALSE;    }    if (isanyaddr(&that->host_addr))    {	/* other side is wildcard: we must check if other conditions met */	if (isanyaddr(&this->host_addr))	{	    loglog(RC_ORIENT, "connection must specify host IP address for our side");	    return FALSE;	}	else if (!NEVER_NEGOTIATE(wm->policy))	{	    /* check that all main mode RW IKE policies agree because we must	     * implement them before the correct connection is known.	     * We cannot enforce this for other non-RW connections because	     * differentiation is possible when a command specifies which	     * to initiate.	     * aggressive mode IKE policies do not have to agree amongst	     * themselves as the ID is known from the outset.	     */	    const struct connection *c = NULL;	    c = find_host_pair_connections(__FUNCTION__					   , &this->host_addr					   , this->host_port					   , (const ip_address *)NULL					   , that->host_port);	    for (; c != NULL; c = c->hp_next)	    {		if (c->policy & POLICY_AGGRESSIVE)			continue;		if (!NEVER_NEGOTIATE(c->policy)		&& ((c->policy ^ wm->policy) & (POLICY_PSK | POLICY_RSASIG)))		{		    loglog(RC_CLASH			, "authentication method disagrees with \"%s\", which is also for an unspecified peer"			, c->name);		    return FALSE;		}	    }	}    }#ifdef VIRTUAL_IP    if ((this->virt) && (!isanyaddr(&this->host_addr) || this->has_client)) {	loglog(RC_CLASH,	    "virtual IP must only be used with %%any and without client");	return FALSE;    }#endif        return TRUE;	/* happy */}struct connection *find_connection_by_reqid(uint32_t reqid){    struct connection *c;    reqid &= ~3;    for (c = connections; c != NULL; c = c->ac_next)    {	if (c->spd.reqid == reqid)	    return c;    }    return NULL;}static uint32_tgen_reqid(void){    uint32_t start;    static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3;    start = reqid;    do {	reqid += 4;	if (reqid == 0)	    reqid = (IPSEC_MANUAL_REQID_MAX & ~3) + 4;	if (!find_connection_by_reqid(reqid))	    return reqid;    } while (reqid != start);    exit_log("unable to allocate reqid");}voidadd_connection(const struct whack_message *wm){    struct alg_info_ike *alg_info_ike;    const char *ugh;    alg_info_ike = NULL;    if (con_by_name(wm->name, FALSE) != NULL)    {	loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name);    }    else if (wm->right.protocol != wm->left.protocol)    {	/* this should haven been diagnosed by whack	 * !!! overloaded use of RC_CLASH	 */	loglog(RC_CLASH, "the protocol must be the same for leftport and rightport");    }    else if(wm->ike != NULL	    && ((alg_info_ike = alg_info_ike_create_from_str(wm->ike, &ugh))==NULL		|| alg_info_ike->alg_info_cnt==0)) {	if (alg_info_ike!= NULL && alg_info_ike->alg_info_cnt==0) {	    loglog(RC_NOALGO		   , "got 0 transforms for ike=\"%s\""		   , wm->esp);	    return;	} 	loglog(RC_NOALGO	       , "esp string error: %s"	       , ugh? ugh : "Unknown");	return;    }    else if ((wm->ike == NULL || alg_info_ike != NULL)	     && check_connection_end(&wm->right, &wm->left, wm)	     && check_connection_end(&wm->left, &wm->right, wm))    {	bool same_rightca, same_leftca;	struct connection *c = alloc_thing(struct connection, "struct connection");	same_rightca = same_leftca = FALSE;	c->name = wm->name;	c->policy = wm->policy;	DBG(DBG_CONTROL,	    DBG_log("Added new connection %s with policy %s"		    , c->name		    , prettypolicy(c->policy)));    	if ((c->policy & POLICY_COMPRESS) && !can_do_IPcomp)	    loglog(RC_COMMENT		, "ignoring --compress in \"%s\" because KLIPS is not configured to do IPCOMP"		, c->name);	c->alg_info_esp = NULL;#ifdef KERNEL_ALG	if (wm->esp)  	{		DBG(DBG_CONTROL, DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL"));		c->alg_info_esp = alg_info_esp_create_from_str(wm->esp? wm->esp : "", &ugh, FALSE);		DBG(DBG_CRYPT|DBG_CONTROL, 			static char buf[256]="<NULL>";			if (c->alg_info_esp)				alg_info_snprint(buf, sizeof(buf), 						 (struct alg_info *)c->alg_info_esp, TRUE);			DBG_log("esp string values: %s", buf);		);		if (c->alg_info_esp) {			if (c->alg_info_esp->alg_info_cnt==0) {				loglog(RC_NOALGO					, "got 0 transforms for esp=\"%s\""					, wm->esp);				return;			}		} else {			loglog(RC_NOALGO				, "esp string error: %s"				, ugh? ugh : "Unknown");			return;		}		c->alg_esp = clone_str(wm->esp, "esp string");	}#endif		c->alg_info_ike = NULL;#ifdef IKE_ALG	if (wm->ike)	{	    c->alg_info_ike = alg_info_ike;	    DBG(DBG_CONTROL, DBG_log("from whack: got --ike=%s", wm->ike));	    DBG(DBG_CRYPT|DBG_CONTROL, 		char buf[256];		alg_info_snprint(buf, sizeof(buf),				 (struct alg_info *)c->alg_info_ike, TRUE);		DBG_log("ike string values: %s", buf);		);	    if (c->alg_info_ike) {		if (c->alg_info_ike->alg_info_cnt==0) {		    loglog(RC_NOALGO			   , "got 0 transforms for ike=\"%s\""			   , wm->ike);		    return;		}	    } else {		loglog(RC_NOALGO		       , "ike string error: %s"		       , ugh? ugh : "Unknown");		return;	    }	    c->alg_ike = clone_str(wm->ike, "ike string");	}#endif	c->sa_ike_life_seconds = wm->sa_ike_life_seconds;	c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds;	c->sa_rekey_margin = wm->sa_rekey_margin;	c->sa_rekey_fuzz = wm->sa_rekey_fuzz;	c->sa_keying_tries = wm->sa_keying_tries;	/* RFC 3706 DPD */        c->dpd_delay = wm->dpd_delay;        c->dpd_timeout = wm->dpd_timeout;        c->dpd_action = wm->dpd_action;	c->forceencaps = wm->forceencaps;	c->addr_family = wm->addr_family;	c->tunnel_addr_family = wm->tunnel_addr_family;	c->requested_ca = NULL;	same_leftca  = extract_end(&c->spd.this, &wm->left, "left");	same_rightca = extract_end(&c->spd.that, &wm->right, "right");	if (same_rightca)	    c->spd.that.ca = c->spd.this.ca;	else if (same_leftca)	    c->spd.this.ca = c->spd.that.ca;	default_end(&c->spd.this, &c->spd.that.host_addr);	default_end(&c->spd.that, &c->spd.this.host_addr);	/* force any wildcard host IP address, any wildcard subnet	 * or any wildcard ID to that end	 */	if (isanyaddr(&c->spd.this.host_addr) || c->spd.this.has_client_wildcard	|| c->spd.this.has_port_wildcard || c->spd.this.has_id_wildcards)	{	    struct end t = c->spd.this;	    c->spd.this = c->spd.that;	    c->spd.that = t;	}	c->spd.next = NULL;	c->spd.reqid = gen_reqid();	/* set internal fields */	c->instance_serial = 0;	c->ac_next = connections;	connections = c;	c->interface = NULL;	c->spd.routing = RT_UNROUTED;	c->newest_isakmp_sa = SOS_NOBODY;	c->newest_ipsec_sa = SOS_NOBODY;	c->spd.eroute_owner = SOS_NOBODY;	if (c->policy & POLICY_GROUP)	{	    c->kind = CK_GROUP;	    add_group(c);	}	else if ((isanyaddr(&c->spd.that.host_addr) && !NEVER_NEGOTIATE(c->policy))		|| c->spd.that.has_client_wildcard || c->spd.that.has_port_wildcard  		|| ((c->policy & POLICY_SHUNT_MASK) == 0  && c->spd.that.has_id_wildcards ))	{	    DBG(DBG_CONTROL, DBG_log("based upon policy, the connection is a template."));	    /* Opportunistic or Road Warrior or wildcard client subnet	     * or wildcard ID */	    c->kind = CK_TEMPLATE;	}	else	{	    c->kind = CK_PERMANENT;	}	set_policy_prio(c);	/* must be after kind is set */#ifdef DEBUG	c->extra_debugging = wm->debugging;#endif	c->gw_info = NULL;#ifdef VIRTUAL_IP	passert(!(wm->left.virt && wm->right.virt));	if (wm->left.virt || wm->right.virt) {	    passert(isanyaddr(&c->spd.that.host_addr));	    c->spd.that.virt = create_virtual(c,		wm->left.virt ? wm->left.virt : wm->right.virt);	    if (c->spd.that.virt)		c->spd.that.has_client = TRUE;	}#endif	unshare_connection_strings(c);#ifdef KERNEL_ALG	alg_info_addref((struct alg_info *)c->alg_info_esp);#endif#ifdef IKE_ALG	alg_info_addref((struct alg_info *)c->alg_info_ike);#endif	(void)orient(c);	connect_to_host_pair(c);	/* log all about this connection */	openswan_log("added connection description \"%s\"", c->name);	DBG(DBG_CONTROL,	    char topo[CONNECTION_BUF];	    (void) format_connection(topo, sizeof(topo), c, &c->spd);	    DBG_log("%s", topo);	    /* Make sure that address families can be correctly inferred	     * from printed ends.	     */	    passert(c->addr_family == addrtypeof(&c->spd.this.host_addr)		&& c->addr_family == addrtypeof(&c->spd.this.host_nexthop)		&& (c->spd.this.has_client? c->tunnel_addr_family : c->addr_family)		  == subnettypeof(&c->spd.this.client)		&& c->addr_family == addrtypeof(&c->spd.that.host_addr)		&& c->addr_family == addrtypeof(&c->spd.that.host_nexthop)		&& (c->spd.that.has_client? c->tunnel_addr_family : c->addr_family)		  == subnettypeof(&c->spd.that.client));	    DBG_log("ike_life: %lus; ipsec_life: %lus; rekey_margin: %lus;"		" rekey_fuzz: %lu%%; keyingtries: %lu; policy: %s"		, (unsigned long) c->sa_ike_life_seconds		, (unsigned long) c->sa_ipsec_life_seconds		, (unsigned long) c->sa_rekey_margin		, (unsigned long) c->sa_rekey_fuzz		, (unsigned long) c->sa_keying_tries		, prettypolicy(c->policy));	);    } else {	loglog(RC_FATAL, "attempt to load incomplete connection");    }}/* Derive a template connection from a group connection and target. * Similar to instantiate().  Happens at whack --listen. * Returns name of new connection.  May be NULL. * Caller is responsible for pfreeing. */char *add_group_instance(struct connection *group, const ip_subnet *target){    char namebuf[100]	, targetbuf[SUBNETTOT_BUF];    struct connection *t;    char *name = NULL;    passert(group->kind == CK_GROUP);    passert(oriented(*group));    /* manufacture a unique name for this template */    subnettot(target, 0, targetbuf, sizeof(targetbuf));    snprintf(namebuf, sizeof(namebuf), "%s#%s", group->name, targetbuf);    if (con_by_name(namebuf, FALSE) != NULL)    {	loglog(RC_DUPNAME, "group name + target yields duplicate name \"%s\""	    , namebuf);    }    else    {	t = clone_thing(*group, "group instance");	t->name = namebuf;	unshare_connection_strings(t);	name = clone_str(t->name, "group instance name");	t->spd.that.client = *target;	t->policy &= ~(POLICY_GROUP | POLICY_GROUTED);	t->kind = isanyaddr(&t->spd.that.host_addr) && !NEVER_NEGOTIATE(t->policy)	    ? CK_TEMPLATE : CK_INSTANCE;	/* reset log file info */	t->log_file_name = NULL;	t->log_file = NULL;	t->log_file_err = FALSE;	t->spd.reqid = gen_reqid();#ifdef VIRTUAL_IP	if (t->spd.that.virt) {	        DBG_log("virtual_ip not supported in group instance");		t->spd.that.virt = NULL;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -