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

📄 kernel.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* figure out which verb suffix applies */    {        const char *hs, *cs;        switch (addrtypeof(&sr->this.host_addr))        {            case AF_INET:                hs = "-host";                cs = "-client";                break;            case AF_INET6:                hs = "-host-v6";                cs = "-client-v6";                break;            default:                loglog(RC_LOG_SERIOUS, "unknown address family");                return FALSE;        }        verb_suffix = subnetisaddr(&sr->this.client, &sr->this.host_addr)            ? hs : cs;    }    /* form the command string */    {        char            nexthop_str[sizeof("PLUTO_NEXT_HOP='' ")+ADDRTOT_BUF],            me_str[ADDRTOT_BUF],            myid_str[IDTOA_BUF],            srcip_str[ADDRTOT_BUF+sizeof("PLUTO_MY_SOURCEIP=")+4],            myclient_str[SUBNETTOT_BUF],            myclientnet_str[ADDRTOT_BUF],            myclientmask_str[ADDRTOT_BUF],            peer_str[ADDRTOT_BUF],            peerid_str[IDTOA_BUF],            peerclient_str[SUBNETTOT_BUF],            peerclientnet_str[ADDRTOT_BUF],            peerclientmask_str[ADDRTOT_BUF],            secure_myid_str[IDTOA_BUF] = "",            secure_peerid_str[IDTOA_BUF] = "",            secure_peerca_str[IDTOA_BUF] = "";	            ip_address ta;	nexthop_str[0]='\0';	if(addrbytesptr(&sr->this.host_nexthop, NULL)	   && !isanyaddr(&sr->this.host_nexthop))	{	    char *n;	    strcpy(nexthop_str, "PLUTO_NEXT_HOP='");	    n = nexthop_str + strlen(nexthop_str);	    addrtot(&sr->this.host_nexthop, 0,		    n, sizeof(nexthop_str)-strlen(nexthop_str));	    strncat(nexthop_str, "' ", sizeof(nexthop_str));	}        addrtot(&sr->this.host_addr, 0, me_str, sizeof(me_str));        idtoa(&sr->this.id, myid_str, sizeof(myid_str));        escape_metachar(myid_str, secure_myid_str, sizeof(secure_myid_str));        subnettot(&sr->this.client, 0, myclient_str, sizeof(myclientnet_str));        networkof(&sr->this.client, &ta);        addrtot(&ta, 0, myclientnet_str, sizeof(myclientnet_str));        maskof(&sr->this.client, &ta);        addrtot(&ta, 0, myclientmask_str, sizeof(myclientmask_str));        addrtot(&sr->that.host_addr, 0, peer_str, sizeof(peer_str));        idtoa(&sr->that.id, peerid_str, sizeof(peerid_str));        escape_metachar(peerid_str, secure_peerid_str, sizeof(secure_peerid_str));        subnettot(&sr->that.client, 0, peerclient_str, sizeof(peerclientnet_str));        networkof(&sr->that.client, &ta);        addrtot(&ta, 0, peerclientnet_str, sizeof(peerclientnet_str));        maskof(&sr->that.client, &ta);        addrtot(&ta, 0, peerclientmask_str, sizeof(peerclientmask_str));        srcip_str[0]='\0';        if(addrbytesptr(&sr->this.host_srcip, NULL) != 0           && !isanyaddr(&sr->this.host_srcip))        {            char *p;            int   l;            strncat(srcip_str, "PLUTO_MY_SOURCEIP=", sizeof(srcip_str));            strncat(srcip_str, "'", sizeof(srcip_str));            l = strlen(srcip_str);            p = srcip_str + l;                        addrtot(&sr->this.host_srcip, 0, p, sizeof(srcip_str));            strncat(srcip_str, "'", sizeof(srcip_str));        }        {            struct pubkey_list *p;            char peerca_str[IDTOA_BUF];            for (p = pubkeys; p != NULL; p = p->next)                {                    struct pubkey *key = p->key;                    int pathlen;                                        if (key->alg == PUBKEY_ALG_RSA && same_id(&sr->that.id, &key->id)                        && trusted_ca(key->issuer, sr->that.ca, &pathlen))                        {                            dntoa_or_null(peerca_str, IDTOA_BUF, key->issuer, "");                            escape_metachar(peerca_str, secure_peerca_str, sizeof(secure_peerca_str));                            break;                        }                }        }        if (-1 == snprintf(cmd, sizeof(cmd)			   , "2>&1 "   /* capture stderr along with stdout */			   "PLUTO_VERSION='1.1' "    /* change VERSION when interface spec changes */			   "PLUTO_VERB='%s%s' "			   "PLUTO_CONNECTION='%s' "			   "%s"      /* possible PLUTO_NEXT_HOP */			   "PLUTO_INTERFACE='%s' "			   "PLUTO_ME='%s' "			   "PLUTO_MY_ID='%s' "			   "PLUTO_MY_CLIENT='%s' "			   "PLUTO_MY_CLIENT_NET='%s' "			   "PLUTO_MY_CLIENT_MASK='%s' "			   "PLUTO_MY_PORT='%u' "			   "PLUTO_MY_PROTOCOL='%u' "			   "PLUTO_PEER='%s' "			   "PLUTO_PEER_ID='%s' "			   "PLUTO_PEER_CLIENT='%s' "			   "PLUTO_PEER_CLIENT_NET='%s' "			   "PLUTO_PEER_CLIENT_MASK='%s' "			   "PLUTO_PEER_PORT='%u' "			   "PLUTO_PEER_PROTOCOL='%u' "			   "PLUTO_PEER_CA='%s' "			   "PLUTO_CONN_POLICY='%s' "			   "%s "       /* PLUTO_MY_SRCIP */                    			   "%s"        /* actual script */			   , verb, verb_suffix			   , c->name			   , nexthop_str			   , c->interface->vname			   , me_str			   , secure_myid_str			   , myclient_str			   , myclientnet_str			   , myclientmask_str			   , sr->this.port			   , sr->this.protocol			   , peer_str			   , secure_peerid_str			   , peerclient_str			   , peerclientnet_str			   , peerclientmask_str			   , sr->that.port			   , sr->that.protocol			   , secure_peerca_str			   , prettypolicy(c->policy)			   , srcip_str			   , sr->this.updown == NULL? DEFAULT_UPDOWN : sr->this.updown))        {            loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb, verb_suffix);            return FALSE;        }    }    DBG(DBG_CONTROL, DBG_log("executing %s%s: %s"        , verb, verb_suffix, cmd));#ifdef KLIPS    if (!no_klips)    {        /* invoke the script, catching stderr and stdout         * It may be of concern that some file descriptors will         * be inherited.  For the ones under our control, we         * have done fcntl(fd, F_SETFD, FD_CLOEXEC) to prevent this.         * Any used by library routines (perhaps the resolver or syslog)         * will remain.         */        FILE *f = popen(cmd, "r");        if (f == NULL)        {            loglog(RC_LOG_SERIOUS, "unable to popen %s%s command", verb, verb_suffix);            return FALSE;        }        /* log any output */        for (;;)        {            /* if response doesn't fit in this buffer, it will be folded */            char resp[256];            if (fgets(resp, sizeof(resp), f) == NULL)            {                if (ferror(f))                {                    log_errno((e, "fgets failed on output of %s%s command"                        , verb, verb_suffix));                    return FALSE;                }                else                {                    passert(feof(f));                    break;                }            }            else            {                char *e = resp + strlen(resp);                if (e > resp && e[-1] == '\n')                    e[-1] = '\0';       /* trim trailing '\n' */                openswan_log("%s%s output: %s", verb, verb_suffix, resp);            }        }        /* report on and react to return code */        {            int r = pclose(f);            if (r == -1)            {                log_errno((e, "pclose failed for %s%s command"                    , verb, verb_suffix));                return FALSE;            }            else if (WIFEXITED(r))            {                if (WEXITSTATUS(r) != 0)                {                    loglog(RC_LOG_SERIOUS, "%s%s command exited with status %d"                        , verb, verb_suffix, WEXITSTATUS(r));                    return FALSE;                }            }            else if (WIFSIGNALED(r))            {                loglog(RC_LOG_SERIOUS, "%s%s command exited with signal %d"                    , verb, verb_suffix, WTERMSIG(r));                return FALSE;            }            else            {                loglog(RC_LOG_SERIOUS, "%s%s command exited with unknown status %d"                    , verb, verb_suffix, r);                return FALSE;            }        }    }#endif /* KLIPS */    return TRUE;}/* Check that we can route (and eroute).  Diagnose if we cannot. */enum routability {    route_impossible = 0,    route_easy = 1,    route_nearconflict = 2,    route_farconflict = 3};static enum routabilitycould_route(struct connection *c){    struct spd_route *esr, *rosr;    struct connection *ero      /* who, if anyone, owns our eroute? */        , *ro = route_owner(c, &rosr, &ero, &esr); /* who owns our route? */    DBG(DBG_CONTROL,        DBG_log("could_route called for %s (kind=%s)"                , c->name                , enum_show(&connection_kind_names, c->kind)));    /* it makes no sense to route a connection that is ISAKMP-only */    if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))    {        loglog(RC_ROUTE, "cannot route an ISAKMP-only connection");        return route_impossible;    }    /* if this is a Road Warrior template, we cannot route.     * Opportunistic template is OK.     */    if (!c->spd.that.has_client	&& c->kind == CK_TEMPLATE	&& !(c->policy & POLICY_OPPO))    {        loglog(RC_ROUTE, "cannot route template policy of %s",               prettypolicy(c->policy));        return route_impossible;    }    /* if we don't know nexthop, we cannot route */    if (isanyaddr(&c->spd.this.host_nexthop))    {        loglog(RC_ROUTE, "cannot route connection without knowing our nexthop");        return route_impossible;    }    /* if routing would affect IKE messages, reject */    if (!no_klips#ifdef NAT_TRAVERSAL    && c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT#endif    && c->spd.this.host_port != IKE_UDP_PORT    && addrinsubnet(&c->spd.that.host_addr, &c->spd.that.client))    {        loglog(RC_LOG_SERIOUS, "cannot install route: peer is within its client");        return route_impossible;    }    /* If there is already a route for peer's client subnet     * and it disagrees about interface or nexthop, we cannot steal it.     * Note: if this connection is already routed (perhaps for another     * state object), the route will agree.     * This is as it should be -- it will arise during rekeying.     */    if (ro != NULL && !routes_agree(ro, c))    {        loglog(RC_LOG_SERIOUS, "cannot route -- route already in use for \"%s\""            , ro->name);        return route_impossible;  /* another connection already                                     using the eroute */    }#ifdef KLIPS    /* if there is an eroute for another connection, there is a problem */    if (ero != NULL && ero != c)    {        struct connection *ero2, *ero_top;        struct connection *inside, *outside;        /*         * note, wavesec (PERMANENT) goes *outside* and         * OE goes *inside* (TEMPLATE)         */        inside = NULL;        outside= NULL;        if (ero->kind == CK_PERMANENT           && c->kind == CK_TEMPLATE)        {            outside = ero;            inside = c;        }        else if (c->kind == CK_PERMANENT                && ero->kind == CK_TEMPLATE)        {            outside = c;            inside = ero;        }        /* okay, check again, with correct order */        if (outside && outside->kind == CK_PERMANENT            && inside && inside->kind == CK_TEMPLATE)        {            char inst[CONN_INST_BUF];            /* this is a co-terminal attempt of the "near" kind. */            /* when chaining, we chain from inside to outside */            /* XXX permit multiple deep connections? */            passert(inside->policy_next == NULL);            inside->policy_next = outside;            /* since we are going to steal the eroute from the secondary             * policy, we need to make sure that it no longer thinks that             * it owns the eroute.             */            outside->spd.eroute_owner = SOS_NOBODY;            outside->spd.routing = RT_UNROUTED_KEYED;            /* set the priority of the new eroute owner to be higher             * than that of the current eroute owner             */            inside->prio = outside->prio + 1;            fmt_conn_instance(inside, inst);            loglog(RC_LOG_SERIOUS                   , "conflict on eroute (%s), switching eroute to %s and linking %s"                   , inst, inside->name, outside->name);            return route_nearconflict;        }        /* look along the chain of policies for one with the same name */        ero_top = ero;        for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)        {            if (ero2->kind == CK_TEMPLATE            && streq(ero2->name, c->name))                break;        }        /* If we fell of the end of the list, then we found no TEMPLATE         * so there must be a conflict that we can't resolve.         * As the names are not equal, then we aren't replacing/rekeying.         */        if (ero2 == NULL)        {            char inst[CONN_INST_BUF];            fmt_conn_instance(ero, inst);            loglog(RC_LOG_SERIOUS                , "cannot install eroute -- it is in use for \"%s\"%s #%lu"                , ero->name, inst, esr->eroute_owner);            return FALSE;       /* another connection already using the eroute */        }

⌨️ 快捷键说明

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