From owner-svn-src-projects@freebsd.org Thu Dec 1 12:32:53 2016 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 709A5C5D57A for ; Thu, 1 Dec 2016 12:32:53 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4B33D1EC1; Thu, 1 Dec 2016 12:32:53 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uB1CWqN3017426; Thu, 1 Dec 2016 12:32:52 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB1CWqaj017425; Thu, 1 Dec 2016 12:32:52 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201612011232.uB1CWqaj017425@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Thu, 1 Dec 2016 12:32:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r309359 - projects/ipsec/sys/netipsec X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Dec 2016 12:32:53 -0000 Author: ae Date: Thu Dec 1 12:32:52 2016 New Revision: 309359 URL: https://svnweb.freebsd.org/changeset/base/309359 Log: Add key_allocsa_tcpmd5() to do lookup for SA used to store password for TCP MD5 signature. In key_allocsa() add assert that the functions is used only for ESP/AH/IPcomp. Modified: projects/ipsec/sys/netipsec/key.c Modified: projects/ipsec/sys/netipsec/key.c ============================================================================== --- projects/ipsec/sys/netipsec/key.c Thu Dec 1 11:57:15 2016 (r309358) +++ projects/ipsec/sys/netipsec/key.c Thu Dec 1 12:32:52 2016 (r309359) @@ -753,6 +753,68 @@ key_allocsp(struct secpolicyindex *spidx } /* + * Allocating an SA entry for an *INBOUND* or *OUTBOUND* TCP packet, signed + * or should be signed by MD5 signature. + * We don't use key_allocsa() for such lookups, because we don't know SPI. + * Unlike ESP and AH protocols, SPI isn't transmitted in the TCP header with + * signed packet. We use SADB only as storage for password. + * OUT: positive: corresponding SA for given saidx found. + * NULL: SA not found + */ +struct secasvar * +key_allocsa_tcpmd5(struct secasindex *saidx) +{ + SAHTREE_RLOCK_TRACKER; + struct secashead *sah; + struct secasvar *sav; + + IPSEC_ASSERT(saidx->proto == IPPROTO_TCP, + ("unexpected security protocol %u", saidx->proto)); + IPSEC_ASSERT(saidx->mode == IPSEC_MODE_TCPMD5, + ("unexpected mode %u", saidx->mode)); + + SAHTREE_RLOCK(); + LIST_FOREACH(sah, SAHADDRHASH_HASH(saidx), addrhash) { + KEYDBG(IPSEC_DUMP, + printf("%s: checking SAH\n", __func__); + kdebug_secash(sah, " ")); + if (sah->saidx.proto != IPPROTO_TCP) + continue; + if (sah->saidx.mode != saidx->mode) + continue; + /* + * addrhash uses only IP addresses without ports, but if + * SA contains TCP port, use ports in comparison for exact + * match. + */ + if (!key_sockaddrcmp(&saidx->dst.sa, &sah->saidx.dst.sa, + key_portfromsaddr(&sah->saidx.dst.sa))) + break; + } + if (sah != NULL) { + if (V_key_preferred_oldsa) + sav = TAILQ_LAST(&sah->savtree_alive, secasvar_queue); + else + sav = TAILQ_FIRST(&sah->savtree_alive); + if (sav != NULL) + SAV_ADDREF(sav); + } else + sav = NULL; + SAHTREE_RUNLOCK(); + + if (sav != NULL) { + KEYDBG(IPSEC_STAMP, + printf("%s: return SA(%p)\n", __func__, sav)); + KEYDBG(IPSEC_DATA, kdebug_secasv(sav)); + } else { + KEYDBG(IPSEC_STAMP, + printf("%s: SA not found\n", __func__)); + KEYDBG(IPSEC_DATA, kdebug_secasindex(saidx, NULL)); + } + return (sav); +} + +/* * Allocating an SA entry for an *OUTBOUND* packet. * OUT: positive: corresponding SA for given saidx found. * NULL: SA not found, but will be acquired, check *error @@ -830,11 +892,10 @@ key_allocsa_policy(struct secpolicy *sp, * OUT: positive: pointer to a usable sav (i.e. MATURE or DYING state). * NULL: not found, or error occurred. * - * In the comparison, no source address is used--for RFC2401 conformance. - * To quote, from section 4.1: - * A security association is uniquely identified by a triple consisting - * of a Security Parameter Index (SPI), an IP Destination Address, and a - * security protocol (AH or ESP) identifier. + * According to RFC 2401 SA is uniquely identified by a triple SPI, + * destination address, and security protocol. But according to RFC 4301, + * SPI by itself suffices to specify an SA. + * * Note that, however, we do need to keep source address in IPsec SA. * IKE specification and PF_KEY specification do assume that we * keep source address in IPsec SA. We see a tricky situation here. @@ -846,7 +907,9 @@ key_allocsa(union sockaddr_union *dst, u struct secasvar *sav; int chkport; - IPSEC_ASSERT(dst != NULL, ("null dst address")); + IPSEC_ASSERT(proto == IPPROTO_ESP || proto == IPPROTO_AH || + proto == IPPROTO_IPCOMP, ("unexpected security protocol %u", + proto)); chkport = 0; SAHTREE_RLOCK(); @@ -857,7 +920,6 @@ key_allocsa(union sockaddr_union *dst, u /* * We use single SPI namespace for all protocols, so it is * impossible to have SPI duplicates in the SAVHASH. - * XXXAE: this breaks TCP_SIGNATURE. */ if (sav != NULL) { #ifdef IPSEC_NAT_T