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

📄 kernel.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (ugh != NULL)                break;            /* his client */            context = "destination subnet field malformed: ";            ugh = ttosubnet(ff[2].ptr, ff[2].len, AF_INET, &eri.his);            if (ugh != NULL)                break;            /* SAID */            context = "SA ID field malformed: ";            ugh = read_proto(ff[4].ptr, &ff[4].len, &eri.transport_proto);            if (ugh != NULL)                break;            ugh = ttosa(ff[4].ptr, ff[4].len, &eri.said);        } while (FALSE);        if (ugh != NULL)        {            openswan_log("INTERNAL ERROR: %s line %d %s%s"                , procname, lino, context, ugh);            continue;   /* ignore rest of line */        }        /* Now we have decoded eroute, let's consider it.         * For shunt eroutes:         *         * %hold: if not known, add to orphaned_holds list for initiation         *    because ACQUIRE might have been lost.         *         * %pass, %drop, %reject: determine if idle; if so, blast it away.         *    Can occur bare (if DNS provided insufficient information)         *    or with a connection (failure context).         *    Could even be installed by ipsec manual.         *         * %trap: always welcome.         *         * For other eroutes: find state and record count change         */        if (eri.said.proto == SA_INT)        {            /* shunt eroute */            switch (ntohl(eri.said.spi))            {            case SPI_HOLD:                if (bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto) == NULL                && shunt_owner(&eri.ours, &eri.his) == NULL)                {                    int ourport = ntohs(portof(&eri.ours.addr));                    int hisport = ntohs(portof(&eri.his.addr));                    char ourst[SUBNETTOT_BUF];                    char hist[SUBNETTOT_BUF];                    char sat[SATOT_BUF];                    subnettot(&eri.ours, 0, ourst, sizeof(ourst));                    subnettot(&eri.his, 0, hist, sizeof(hist));                    satot(&eri.said, 0, sat, sizeof(sat));                    DBG(DBG_CONTROL,                        DBG_log("add orphaned shunt %s:%d -> %s:%d => %s:%d"                            , ourst, ourport, hist, hisport, sat, eri.transport_proto)                     )                    eri.next = orphaned_holds;                    orphaned_holds = clone_thing(eri, "orphaned %hold");                }                break;            case SPI_PASS:            case SPI_DROP:            case SPI_REJECT:                /* nothing sensible to do if we don't have counts */                if (ff != field)                {                    struct bare_shunt **bs_pp                        = bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto);                    if (bs_pp != NULL)                    {                        struct bare_shunt *bs = *bs_pp;                        if (eri.count != bs->count)                        {                            bs->count = eri.count;                            bs->last_activity = nw;                        }                        else if (nw - bs->last_activity > SHUNT_PATIENCE)                        {                            eri.next = expired;                            expired = clone_thing(eri, "expired %pass");                        }                    }                }                break;            case SPI_TRAP:                break;            default:                bad_case(ntohl(eri.said.spi));            }        }        else        {            /* regular (non-shunt) eroute */            state_eroute_usage(&eri.ours, &eri.his, eri.count, nw);        }    }   /* for each line */    fclose(f);    /* Now that we've finished processing the /proc file,     * it is safe to delete the expired %pass shunts.     */    while (expired != NULL)    {        struct eroute_info *p = expired;        ip_address src, dst;        networkof(&p->ours, &src);        networkof(&p->his, &dst);        (void) replace_bare_shunt(&src, &dst            , BOTTOM_PRIO       /* not used because we are deleting.  This value is a filler */            , SPI_PASS  /* not used because we are deleting.  This value is a filler */            , FALSE, p->transport_proto, "delete expired bare shunts");        expired = p->next;        pfree(p);    }}static booldel_spi(ipsec_spi_t spi, int proto, const ip_address *src, const ip_address *dest){    char text_said[SATOT_BUF];    struct kernel_sa sa;    set_text_said(text_said, dest, spi, proto);    DBG(DBG_KLIPS, DBG_log("delete %s", text_said));    memset(&sa, 0, sizeof(sa));    sa.spi = spi;    sa.proto = proto;    sa.src = src;    sa.dst = dest;    sa.text_said = text_said;    return kernel_ops->del_sa(&sa);}/* * Setup a pair of SAs. * */static boolsetup_half_ipsec_sa(struct state *st, bool inbound){    /* Build an inbound or outbound SA */    struct connection *c = st->st_connection;    ip_subnet src, dst;    ip_subnet src_client, dst_client;    ipsec_spi_t inner_spi;    unsigned int proto, satype;    bool replace;    /* SPIs, saved for spigrouping or undoing, if necessary */    struct kernel_sa        said[EM_MAXRELSPIS],        *said_next = said;    char text_said[SATOT_BUF];    int encapsulation;    replace = inbound && (kernel_ops->get_spi != NULL);    src.maskbits = 0;    dst.maskbits = 0;    if (inbound)    {        src.addr = c->spd.that.host_addr;        dst.addr = c->spd.this.host_addr;        src_client = c->spd.that.client;        dst_client = c->spd.this.client;    }    else    {        src.addr = c->spd.this.host_addr,        dst.addr = c->spd.that.host_addr;        src_client = c->spd.this.client;        dst_client = c->spd.that.client;    }    encapsulation = ENCAPSULATION_MODE_TRANSPORT;    if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL        || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL        || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)    {        encapsulation = ENCAPSULATION_MODE_TUNNEL;    }    memset(said, 0, sizeof(said));    /* If we are tunnelling, set up IP in IP pseudo SA */    if (kernel_ops->inbound_eroute)    {        inner_spi = 256;        proto = SA_IPIP;        satype = SADB_SATYPE_UNSPEC;    }    else if (encapsulation == ENCAPSULATION_MODE_TUNNEL)    {        /* XXX hack alert -- we SHOULD NOT HAVE TO HAVE A DIFFERENT SPI         * XXX FOR IP-in-IP ENCAPSULATION!         */        ipsec_spi_t ipip_spi;        /* Allocate an SPI for the tunnel.         * Since our peer will never see this,         * and it comes from its own number space,         * it is purely a local implementation wart.         */        {            static ipsec_spi_t last_tunnel_spi = IPSEC_DOI_SPI_OUR_MIN;            ipip_spi = htonl(++last_tunnel_spi);            if (inbound)                st->st_tunnel_in_spi = ipip_spi;            else                st->st_tunnel_out_spi = ipip_spi;        }        set_text_said(text_said            , &c->spd.that.host_addr, ipip_spi, SA_IPIP);        said_next->src = &src.addr;        said_next->dst = &dst.addr;        said_next->src_client = &src_client;        said_next->dst_client = &dst_client;        said_next->spi = ipip_spi;        said_next->satype = SADB_X_SATYPE_IPIP;        said_next->text_said = text_said;        if (!kernel_ops->add_sa(said_next, replace))            goto fail;        said_next++;        inner_spi = ipip_spi;        proto = SA_IPIP;        satype = SADB_X_SATYPE_IPIP;    }    /* set up IPCOMP SA, if any */    if (st->st_ipcomp.present)    {        ipsec_spi_t ipcomp_spi = inbound? st->st_ipcomp.our_spi : st->st_ipcomp.attrs.spi;        unsigned compalg;        switch (st->st_ipcomp.attrs.transid)        {            case IPCOMP_DEFLATE:                compalg = SADB_X_CALG_DEFLATE;                break;            default:                loglog(RC_LOG_SERIOUS, "IPCOMP transform %s not implemented"                    , enum_name(&ipcomp_transformid_names, st->st_ipcomp.attrs.transid));                goto fail;        }        set_text_said(text_said, &dst.addr, ipcomp_spi, SA_COMP);        said_next->src = &src.addr;        said_next->dst = &dst.addr;        said_next->src_client = &src_client;        said_next->dst_client = &dst_client;        said_next->spi = ipcomp_spi;        said_next->satype = SADB_X_SATYPE_COMP;        said_next->encalg = compalg;        said_next->encapsulation = encapsulation;        said_next->reqid = c->spd.reqid + 2;        said_next->text_said = text_said;        if (!kernel_ops->add_sa(said_next, replace))            goto fail;        said_next++;        encapsulation = ENCAPSULATION_MODE_TRANSPORT;    }    /* set up ESP SA, if any */    if (st->st_esp.present)    {        ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;        u_char *esp_dst_keymat = inbound? st->st_esp.our_keymat : st->st_esp.peer_keymat;        const struct esp_info *ei;        u_int16_t key_len;        static const struct esp_info esp_info[] = {            { ESP_NULL, AUTH_ALGORITHM_HMAC_MD5,                0, HMAC_MD5_KEY_LEN,                SADB_EALG_NULL, SADB_AALG_MD5HMAC },            { ESP_NULL, AUTH_ALGORITHM_HMAC_SHA1,                0, HMAC_SHA1_KEY_LEN,                SADB_EALG_NULL, SADB_AALG_SHA1HMAC },            { ESP_DES, AUTH_ALGORITHM_NONE,                DES_CBC_BLOCK_SIZE, 0,                SADB_EALG_DESCBC, SADB_AALG_NONE },            { ESP_DES, AUTH_ALGORITHM_HMAC_MD5,                DES_CBC_BLOCK_SIZE, HMAC_MD5_KEY_LEN,                SADB_EALG_DESCBC, SADB_AALG_MD5HMAC },            { ESP_DES, AUTH_ALGORITHM_HMAC_SHA1,                DES_CBC_BLOCK_SIZE,                HMAC_SHA1_KEY_LEN, SADB_EALG_DESCBC, SADB_AALG_SHA1HMAC },            { ESP_3DES, AUTH_ALGORITHM_NONE,                DES_CBC_BLOCK_SIZE * 3, 0,                SADB_EALG_3DESCBC, SADB_AALG_NONE },            { ESP_3DES, AUTH_ALGORITHM_HMAC_MD5,                DES_CBC_BLOCK_SIZE * 3, HMAC_MD5_KEY_LEN,                SADB_EALG_3DESCBC, SADB_AALG_MD5HMAC },            { ESP_3DES, AUTH_ALGORITHM_HMAC_SHA1,                DES_CBC_BLOCK_SIZE * 3, HMAC_SHA1_KEY_LEN,                SADB_EALG_3DESCBC, SADB_AALG_SHA1HMAC },            { ESP_AES, AUTH_ALGORITHM_NONE,                AES_CBC_BLOCK_SIZE, 0,                SADB_X_EALG_AESCBC, SADB_AALG_NONE },            { ESP_AES, AUTH_ALGORITHM_HMAC_MD5,                AES_CBC_BLOCK_SIZE, HMAC_MD5_KEY_LEN,                SADB_X_EALG_AESCBC, SADB_AALG_MD5HMAC },            { ESP_AES, AUTH_ALGORITHM_HMAC_SHA1,                AES_CBC_BLOCK_SIZE, HMAC_SHA1_KEY_LEN,                SADB_X_EALG_AESCBC, SADB_AALG_SHA1HMAC },        };	//static const int esp_max = elemsof(esp_info);	//int esp_count;#ifdef NAT_TRAVERSAL        u_int8_t natt_type = 0;        u_int16_t natt_sport = 0, natt_dport = 0;        ip_address natt_oa;        if (st->nat_traversal & NAT_T_DETECTED) {            natt_type = (st->nat_traversal & NAT_T_WITH_PORT_FLOATING) ?                ESPINUDP_WITH_NON_ESP : ESPINUDP_WITH_NON_IKE;            natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port;            natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;            natt_oa = st->nat_oa;        }#endif        for (ei = esp_info; ; ei++)        {	    	    /* if it is the last key entry, then ask algo */            if (ei == &esp_info[elemsof(esp_info)])            {                /* Check for additional kernel alg */#ifdef KERNEL_ALG                if ((ei=kernel_alg_esp_info(st->st_esp.attrs.transid,                                         st->st_esp.attrs.auth))!=NULL) {                        break;                }#endif                /* note: enum_show may use a static buffer, so two                 * calls in one printf would be a mistake.                 * enum_name does the same job, without a static buffer,                 * assuming the name will be found.                 */                loglog(RC_LOG_SERIOUS, "ESP transform %s / auth %s not implemented yet"                    , enum_name(&esp_transformid_names, st->st_esp.attrs.transid)                    , enum_name(&auth_alg_names, st->st_esp.attrs.auth));                goto fail;            }            if (st->st_esp.attrs.transid == ei->transid		&& st->st_esp.attrs.auth == ei->auth)                break;        }	if (st->st_esp.attrs.transid != ei->transid	    && st->st_esp.attrs.auth != ei->auth) {	    loglog(RC_LOG_SERIOUS, "failed to find key info for %s/%s"		   , enum_name(&esp_transformid_names, st->st_esp.attrs.transid)		   , enum_name(&auth_alg_names, st->st_esp.attrs.auth));	    goto fail;	}        key_len = st->st_esp.attrs.key_len/8;        if (key_len) {                /* XXX: must change to check valid _range_ key_len */                if (key_len > ei->enckeylen) {                        loglog(

⌨️ 快捷键说明

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