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
|
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 27, 2021
|
.Dd January 8, 2022
|
||||||
.Dt TCP 4
|
.Dt TCP 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -339,6 +339,10 @@ This entry can only be specified on a per-host basis at this time.
|
|||||||
.Pp
|
.Pp
|
||||||
If an SADB entry cannot be found for the destination,
|
If an SADB entry cannot be found for the destination,
|
||||||
the system does not send any outgoing segments and drops any inbound segments.
|
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
|
.It Dv TCP_STATS
|
||||||
Manage collection of connection level statistics using the
|
Manage collection of connection level statistics using the
|
||||||
.Xr stats 3
|
.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 defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
|
||||||
/*
|
/*
|
||||||
* If listening socket requested TCP digests, check that received
|
* When the socket is TCP-MD5 enabled check that,
|
||||||
* SYN has signature and it is correct. If signature doesn't match
|
* - a signed packet is valid
|
||||||
* or TCP_SIGNATURE support isn't enabled, drop the packet.
|
* - 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 (ltflags & TF_SIGNATURE) {
|
||||||
if ((to->to_flags & TOF_SIGNATURE) == 0) {
|
if (to->to_flags & TOF_SIGNATURE) {
|
||||||
TCPSTAT_INC(tcps_sig_err_nosigopt);
|
if (!TCPMD5_ENABLED() ||
|
||||||
goto done;
|
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() ||
|
} else if (to->to_flags & TOF_SIGNATURE)
|
||||||
TCPMD5_INPUT(m, th, to->to_signature) != 0)
|
goto done;
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
#endif /* TCP_SIGNATURE */
|
#endif /* TCP_SIGNATURE */
|
||||||
/*
|
/*
|
||||||
* See if we already have an entry for this connection.
|
* 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 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
|
* syncache so that syncache_respond() will do the right thing
|
||||||
* with the SYN+ACK.
|
* with the SYN+ACK.
|
||||||
*/
|
*/
|
||||||
if (ltflags & TF_SIGNATURE)
|
if (to->to_flags & TOF_SIGNATURE)
|
||||||
sc->sc_flags |= SCF_SIGNATURE;
|
sc->sc_flags |= SCF_SIGNATURE;
|
||||||
#endif /* TCP_SIGNATURE */
|
#endif /* TCP_SIGNATURE */
|
||||||
if (to->to_flags & TOF_SACKPERM)
|
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);
|
KMOD_TCPSTAT_INC(tcps_sig_err_buildsig);
|
||||||
return (ENOENT);
|
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
|
* tcp_input() operates with TCP header fields in host
|
||||||
* byte order. We expect them in network byte order.
|
* byte order. We expect them in network byte order.
|
||||||
|
Loading…
Reference in New Issue
Block a user