summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2008-02-16 12:22:20 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2008-02-16 12:22:20 +0000
commit465631bad7c17694eefec52b5dc8af5426e3b633 (patch)
tree063815b7259d2801a571dae6c57ef5b8c9832771 /sys
parent837c4ed734b53ded25e7471f95fdf94dc19b9d31 (diff)
switch to RFC 1948 style ISN, too; ok mcbride, dhartmei, henning
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 915ea6e1cd5..772f94f378a 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.565 2007/11/22 02:01:46 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.566 2008/02/16 12:22:19 markus Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -51,6 +51,8 @@
#include <sys/proc.h>
#include <sys/rwlock.h>
+#include <crypto/md5.h>
+
#include <net/if.h>
#include <net/if_types.h>
#include <net/bpf.h>
@@ -110,6 +112,11 @@ u_int32_t ticket_altqs_inactive;
int altqs_inactive_open;
u_int32_t ticket_pabuf;
+MD5_CTX pf_tcp_secret_ctx;
+u_char pf_tcp_secret[16];
+int pf_tcp_secret_init;
+int pf_tcp_iss_off;
+
struct pf_anchor_stackframe {
struct pf_ruleset *rs;
struct pf_rule *r;
@@ -160,6 +167,7 @@ struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
void pf_attach_state(struct pf_state_key *,
struct pf_state *, int);
void pf_detach_state(struct pf_state *, int);
+u_int32_t pf_tcp_iss(struct pf_pdesc *);
int pf_test_rule(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
@@ -2872,6 +2880,34 @@ pf_alloc_state_key(struct pf_state *s)
return (sk);
}
+u_int32_t
+pf_tcp_iss(struct pf_pdesc *pd)
+{
+ MD5_CTX ctx;
+ u_int32_t digest[4];
+
+ if (pf_tcp_secret_init == 0) {
+ arc4random_bytes(pf_tcp_secret, sizeof(pf_tcp_secret));
+ MD5Init(&pf_tcp_secret_ctx);
+ MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret, sizeof(pf_tcp_secret));
+ pf_tcp_secret_init = 1;
+ }
+ ctx = pf_tcp_secret_ctx;
+
+ MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short));
+ MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short));
+ if (pd->af == AF_INET6) {
+ MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr));
+ MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr));
+ } else {
+ MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr));
+ MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr));
+ }
+ MD5Final((u_char *)digest, &ctx);
+ pf_tcp_iss_off += 4096;
+ return (digest[0] + tcp_iss + pf_tcp_iss_off);
+}
+
int
pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
@@ -3339,9 +3375,9 @@ cleanup:
if ((th->th_flags & (TH_SYN|TH_ACK)) ==
TH_SYN && r->keep_state == PF_STATE_MODULATE) {
/* Generate sequence number modulator */
- while ((s->src.seqdiff =
- tcp_rndiss_next() - s->src.seqlo) == 0)
- ;
+ if ((s->src.seqdiff = pf_tcp_iss(pd) -
+ s->src.seqlo) == 0)
+ s->src.seqdiff = 1;
pf_change_a(&th->th_seq, &th->th_sum,
htonl(s->src.seqlo + s->src.seqdiff), 0);
rewrite = 1;
@@ -3786,7 +3822,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
/* Deferred generation of sequence number modulator */
if (dst->seqdiff && !src->seqdiff) {
- while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
+ /* use random iss for the TCP server */
+ while ((src->seqdiff = arc4random() - seq) == 0)
;
ack = ntohl(th->th_ack) - dst->seqdiff;
pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +