summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c116
1 files changed, 45 insertions, 71 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index de71c31..3c6e604 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -118,10 +118,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_offload.h>
#endif
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /*IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
@@ -474,20 +471,6 @@ cc_post_recovery(struct tcpcb *tp, struct tcphdr *th)
tp->t_bytes_acked = 0;
}
-#ifdef TCP_SIGNATURE
-static inline int
-tcp_signature_verify_input(struct mbuf *m, int off0, int tlen, int optlen,
- struct tcpopt *to, struct tcphdr *th, u_int tcpbflag)
-{
- int ret;
-
- tcp_fields_to_net(th);
- ret = tcp_signature_verify(m, off0, tlen, optlen, to, th, tcpbflag);
- tcp_fields_to_host(th);
- return (ret);
-}
-#endif
-
/*
* Indicate whether this ack should be delayed. We can delay the ack if
* following conditions are met:
@@ -598,9 +581,6 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
int drop_hdrlen;
int thflags;
int rstreason = 0; /* For badport_bandlim accounting purposes */
-#ifdef TCP_SIGNATURE
- uint8_t sig_checked = 0;
-#endif
uint8_t iptos;
struct m_tag *fwd_tag = NULL;
#ifdef INET6
@@ -931,15 +911,22 @@ findpcb:
inp->inp_flowid = m->m_pkthdr.flowid;
inp->inp_flowtype = M_HASHTYPE_GET(m);
}
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
#ifdef INET6
- if (isipv6 && ipsec6_in_reject(m, inp)) {
+ if (isipv6 && IPSEC_ENABLED(ipv6) &&
+ IPSEC_CHECK_POLICY(ipv6, m, inp) != 0) {
goto dropunlock;
- } else
+ }
+#ifdef INET
+ else
+#endif
#endif /* INET6 */
- if (ipsec4_in_reject(m, inp) != 0) {
+#ifdef INET
+ if (IPSEC_ENABLED(ipv4) &&
+ IPSEC_CHECK_POLICY(ipv4, m, inp) != 0) {
goto dropunlock;
}
+#endif /* INET */
#endif /* IPSEC */
/*
@@ -1122,7 +1109,16 @@ relocked:
* NB: syncache_expand() doesn't unlock
* inp and tcpinfo locks.
*/
- if (!syncache_expand(&inc, &to, th, &so, m)) {
+ rstreason = syncache_expand(&inc, &to, th, &so, m);
+ if (rstreason < 0) {
+ /*
+ * A failing TCP MD5 signature comparison
+ * must result in the segment being dropped
+ * and must not produce any response back
+ * to the sender.
+ */
+ goto dropunlock;
+ } else if (rstreason == 0) {
/*
* No syncache entry or ACK was not
* for our SYN/ACK. Send a RST.
@@ -1174,26 +1170,6 @@ new_tfo_socket:
tp = intotcpcb(inp);
KASSERT(tp->t_state == TCPS_SYN_RECEIVED,
("%s: ", __func__));
-#ifdef TCP_SIGNATURE
- if (sig_checked == 0) {
- tcp_dooptions(&to, optp, optlen,
- (thflags & TH_SYN) ? TO_SYN : 0);
- if (!tcp_signature_verify_input(m, off0, tlen,
- optlen, &to, th, tp->t_flags)) {
-
- /*
- * In SYN_SENT state if it receives an
- * RST, it is allowed for further
- * processing.
- */
- if ((thflags & TH_RST) == 0 ||
- (tp->t_state == TCPS_SYN_SENT) == 0)
- goto dropunlock;
- }
- sig_checked = 1;
- }
-#endif
-
/*
* Process the segment and the data it
* contains. tcp_do_segment() consumes
@@ -1423,26 +1399,18 @@ new_tfo_socket:
*/
goto dropunlock;
}
-
-#ifdef TCP_SIGNATURE
- if (sig_checked == 0) {
- tcp_dooptions(&to, optp, optlen,
- (thflags & TH_SYN) ? TO_SYN : 0);
- if (!tcp_signature_verify_input(m, off0, tlen, optlen, &to,
- th, tp->t_flags)) {
-
- /*
- * In SYN_SENT state if it receives an RST, it is
- * allowed for further processing.
- */
- if ((thflags & TH_RST) == 0 ||
- (tp->t_state == TCPS_SYN_SENT) == 0)
- goto dropunlock;
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if (tp->t_flags & TF_SIGNATURE) {
+ tcp_dooptions(&to, optp, optlen, thflags);
+ if ((to.to_flags & TOF_SIGNATURE) == 0) {
+ TCPSTAT_INC(tcps_sig_err_nosigopt);
+ goto dropunlock;
}
- sig_checked = 1;
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_INPUT(m, th, to.to_signature) != 0)
+ goto dropunlock;
}
#endif
-
TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th);
/*
@@ -1617,6 +1585,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
(th->th_off << 2) - sizeof(struct tcphdr),
(thflags & TH_SYN) ? TO_SYN : 0);
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if ((tp->t_flags & TF_SIGNATURE) != 0 &&
+ (to.to_flags & TOF_SIGNATURE) == 0) {
+ TCPSTAT_INC(tcps_sig_err_sigopt);
+ /* XXX: should drop? */
+ }
+#endif
/*
* If echoed timestamp is later than the current time,
* fall back to non RFC1323 RTT calculation. Normalize
@@ -3378,20 +3353,19 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
(char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr);
break;
-#ifdef TCP_SIGNATURE
- /*
- * XXX In order to reply to a host which has set the
- * TCP_SIGNATURE option in its initial SYN, we have to
- * record the fact that the option was observed here
- * for the syncache code to perform the correct response.
- */
case TCPOPT_SIGNATURE:
+ /*
+ * In order to reply to a host which has set the
+ * TCP_SIGNATURE option in its initial SYN, we have
+ * to record the fact that the option was observed
+ * here for the syncache code to perform the correct
+ * response.
+ */
if (optlen != TCPOLEN_SIGNATURE)
continue;
to->to_flags |= TOF_SIGNATURE;
to->to_signature = cp + 2;
break;
-#endif
case TCPOPT_SACK_PERMITTED:
if (optlen != TCPOLEN_SACK_PERMITTED)
continue;
OpenPOWER on IntegriCloud