syncache: accept packet with no SA when TCP_MD5SIG is set
When TCP_MD5SIG is set on a socket, all packets are dropped that don't contain an MD5 signature. Relax this behavior to accept a non-signed packet when a security association doesn't exist with the peer. This is useful when a listen socket set with TCP_MD5SIG wants to handle connections protected with and without MD5 signatures. Reviewed by: bz (previous version) Sponsored by: nepustil.net Sponsored by: Klara Inc. Differential Revision: https://reviews.freebsd.org/D33227
This commit is contained in:
parent
91d388119a
commit
eb18708ec8
@ -34,7 +34,7 @@
|
||||
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 27, 2021
|
||||
.Dd January 8, 2022
|
||||
.Dt TCP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -339,6 +339,10 @@ This entry can only be specified on a per-host basis at this time.
|
||||
.Pp
|
||||
If an SADB entry cannot be found for the destination,
|
||||
the system does not send any outgoing segments and drops any inbound segments.
|
||||
However, during connection negotiation, a non-signed segment will be accepted if
|
||||
an SADB entry does not exist between hosts.
|
||||
When a non-signed segment is accepted, the established connection is not
|
||||
protected with MD5 digests.
|
||||
.It Dv TCP_STATS
|
||||
Manage collection of connection level statistics using the
|
||||
.Xr stats 3
|
||||
|
@ -1514,19 +1514,25 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
||||
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
/*
|
||||
* If listening socket requested TCP digests, check that received
|
||||
* SYN has signature and it is correct. If signature doesn't match
|
||||
* or TCP_SIGNATURE support isn't enabled, drop the packet.
|
||||
* When the socket is TCP-MD5 enabled check that,
|
||||
* - a signed packet is valid
|
||||
* - a non-signed packet does not have a security association
|
||||
*
|
||||
* If a signed packet fails validation or a non-signed packet has a
|
||||
* security association, the packet will be dropped.
|
||||
*/
|
||||
if (ltflags & TF_SIGNATURE) {
|
||||
if ((to->to_flags & TOF_SIGNATURE) == 0) {
|
||||
TCPSTAT_INC(tcps_sig_err_nosigopt);
|
||||
goto done;
|
||||
if (to->to_flags & TOF_SIGNATURE) {
|
||||
if (!TCPMD5_ENABLED() ||
|
||||
TCPMD5_INPUT(m, th, to->to_signature) != 0)
|
||||
goto done;
|
||||
} else {
|
||||
if (TCPMD5_ENABLED() &&
|
||||
TCPMD5_INPUT(m, NULL, NULL) != ENOENT)
|
||||
goto done;
|
||||
}
|
||||
if (!TCPMD5_ENABLED() ||
|
||||
TCPMD5_INPUT(m, th, to->to_signature) != 0)
|
||||
goto done;
|
||||
}
|
||||
} else if (to->to_flags & TOF_SIGNATURE)
|
||||
goto done;
|
||||
#endif /* TCP_SIGNATURE */
|
||||
/*
|
||||
* See if we already have an entry for this connection.
|
||||
@ -1724,11 +1730,11 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
||||
}
|
||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||
/*
|
||||
* If listening socket requested TCP digests, flag this in the
|
||||
* If incoming packet has an MD5 signature, flag this in the
|
||||
* syncache so that syncache_respond() will do the right thing
|
||||
* with the SYN+ACK.
|
||||
*/
|
||||
if (ltflags & TF_SIGNATURE)
|
||||
if (to->to_flags & TOF_SIGNATURE)
|
||||
sc->sc_flags |= SCF_SIGNATURE;
|
||||
#endif /* TCP_SIGNATURE */
|
||||
if (to->to_flags & TOF_SACKPERM)
|
||||
|
@ -269,6 +269,11 @@ tcp_ipsec_input(struct mbuf *m, struct tcphdr *th, u_char *buf)
|
||||
KMOD_TCPSTAT_INC(tcps_sig_err_buildsig);
|
||||
return (ENOENT);
|
||||
}
|
||||
if (buf == NULL) {
|
||||
key_freesav(&sav);
|
||||
KMOD_TCPSTAT_INC(tcps_sig_err_nosigopt);
|
||||
return (EACCES);
|
||||
}
|
||||
/*
|
||||
* tcp_input() operates with TCP header fields in host
|
||||
* byte order. We expect them in network byte order.
|
||||
|
Loading…
Reference in New Issue
Block a user