patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
217 lines
6.5 KiB
Diff
217 lines
6.5 KiB
Diff
Index: sys/netinet/tcp_syncache.c
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/netinet/tcp_syncache.c,v
|
|
retrieving revision 1.5.2.8
|
|
diff -c -r1.5.2.8 tcp_syncache.c
|
|
*** sys/netinet/tcp_syncache.c 18 Aug 2002 22:04:47 -0000 1.5.2.8
|
|
--- sys/netinet/tcp_syncache.c 23 Feb 2003 14:38:20 -0000
|
|
***************
|
|
*** 1222,1243 ****
|
|
|
|
/*
|
|
* The values below are chosen to minimize the size of the tcp_secret
|
|
! * table, as well as providing roughly a 4 second lifetime for the cookie.
|
|
*/
|
|
|
|
! #define SYNCOOKIE_HASHSHIFT 2 /* log2(# of 32bit words from hash) */
|
|
! #define SYNCOOKIE_WNDBITS 7 /* exposed bits for window indexing */
|
|
! #define SYNCOOKIE_TIMESHIFT 5 /* scale ticks to window time units */
|
|
|
|
- #define SYNCOOKIE_HASHMASK ((1 << SYNCOOKIE_HASHSHIFT) - 1)
|
|
#define SYNCOOKIE_WNDMASK ((1 << SYNCOOKIE_WNDBITS) - 1)
|
|
! #define SYNCOOKIE_NSECRETS (1 << (SYNCOOKIE_WNDBITS - SYNCOOKIE_HASHSHIFT))
|
|
#define SYNCOOKIE_TIMEOUT \
|
|
(hz * (1 << SYNCOOKIE_WNDBITS) / (1 << SYNCOOKIE_TIMESHIFT))
|
|
#define SYNCOOKIE_DATAMASK ((3 << SYNCOOKIE_WNDBITS) | SYNCOOKIE_WNDMASK)
|
|
|
|
static struct {
|
|
! u_int32_t ts_secbits;
|
|
u_int ts_expire;
|
|
} tcp_secret[SYNCOOKIE_NSECRETS];
|
|
|
|
--- 1222,1241 ----
|
|
|
|
/*
|
|
* The values below are chosen to minimize the size of the tcp_secret
|
|
! * table, as well as providing roughly a 16 second lifetime for the cookie.
|
|
*/
|
|
|
|
! #define SYNCOOKIE_WNDBITS 5 /* exposed bits for window indexing */
|
|
! #define SYNCOOKIE_TIMESHIFT 1 /* scale ticks to window time units */
|
|
|
|
#define SYNCOOKIE_WNDMASK ((1 << SYNCOOKIE_WNDBITS) - 1)
|
|
! #define SYNCOOKIE_NSECRETS (1 << SYNCOOKIE_WNDBITS)
|
|
#define SYNCOOKIE_TIMEOUT \
|
|
(hz * (1 << SYNCOOKIE_WNDBITS) / (1 << SYNCOOKIE_TIMESHIFT))
|
|
#define SYNCOOKIE_DATAMASK ((3 << SYNCOOKIE_WNDBITS) | SYNCOOKIE_WNDMASK)
|
|
|
|
static struct {
|
|
! u_int32_t ts_secbits[4];
|
|
u_int ts_expire;
|
|
} tcp_secret[SYNCOOKIE_NSECRETS];
|
|
|
|
***************
|
|
*** 1247,1252 ****
|
|
--- 1245,1260 ----
|
|
|
|
#define MD5Add(v) MD5Update(&syn_ctx, (u_char *)&v, sizeof(v))
|
|
|
|
+ struct md5_add {
|
|
+ u_int32_t laddr, faddr;
|
|
+ u_int32_t secbits[4];
|
|
+ u_int16_t lport, fport;
|
|
+ };
|
|
+
|
|
+ #ifdef CTASSERT
|
|
+ CTASSERT(sizeof(struct md5_add) == 28);
|
|
+ #endif
|
|
+
|
|
/*
|
|
* Consider the problem of a recreated (and retransmitted) cookie. If the
|
|
* original SYN was accepted, the connection is established. The second
|
|
***************
|
|
*** 1262,1296 ****
|
|
{
|
|
u_int32_t md5_buffer[4];
|
|
u_int32_t data;
|
|
! int wnd, idx;
|
|
|
|
! wnd = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK;
|
|
! idx = wnd >> SYNCOOKIE_HASHSHIFT;
|
|
if (tcp_secret[idx].ts_expire < ticks) {
|
|
! tcp_secret[idx].ts_secbits = arc4random();
|
|
tcp_secret[idx].ts_expire = ticks + SYNCOOKIE_TIMEOUT;
|
|
}
|
|
for (data = sizeof(tcp_msstab) / sizeof(int) - 1; data > 0; data--)
|
|
if (tcp_msstab[data] <= sc->sc_peer_mss)
|
|
break;
|
|
! data = (data << SYNCOOKIE_WNDBITS) | wnd;
|
|
data ^= sc->sc_irs; /* peer's iss */
|
|
MD5Init(&syn_ctx);
|
|
#ifdef INET6
|
|
if (sc->sc_inc.inc_isipv6) {
|
|
MD5Add(sc->sc_inc.inc6_laddr);
|
|
MD5Add(sc->sc_inc.inc6_faddr);
|
|
} else
|
|
#endif
|
|
{
|
|
! MD5Add(sc->sc_inc.inc_laddr);
|
|
! MD5Add(sc->sc_inc.inc_faddr);
|
|
}
|
|
! MD5Add(sc->sc_inc.inc_lport);
|
|
! MD5Add(sc->sc_inc.inc_fport);
|
|
! MD5Add(tcp_secret[idx].ts_secbits);
|
|
MD5Final((u_char *)&md5_buffer, &syn_ctx);
|
|
! data ^= (md5_buffer[wnd & SYNCOOKIE_HASHMASK] & ~SYNCOOKIE_WNDMASK);
|
|
return (data);
|
|
}
|
|
|
|
--- 1270,1311 ----
|
|
{
|
|
u_int32_t md5_buffer[4];
|
|
u_int32_t data;
|
|
! int idx, i;
|
|
! struct md5_add add;
|
|
|
|
! idx = ((ticks << SYNCOOKIE_TIMESHIFT) / hz) & SYNCOOKIE_WNDMASK;
|
|
if (tcp_secret[idx].ts_expire < ticks) {
|
|
! for (i = 0; i < 4; i++)
|
|
! tcp_secret[idx].ts_secbits[i] = arc4random();
|
|
tcp_secret[idx].ts_expire = ticks + SYNCOOKIE_TIMEOUT;
|
|
}
|
|
for (data = sizeof(tcp_msstab) / sizeof(int) - 1; data > 0; data--)
|
|
if (tcp_msstab[data] <= sc->sc_peer_mss)
|
|
break;
|
|
! data = (data << SYNCOOKIE_WNDBITS) | idx;
|
|
data ^= sc->sc_irs; /* peer's iss */
|
|
MD5Init(&syn_ctx);
|
|
#ifdef INET6
|
|
if (sc->sc_inc.inc_isipv6) {
|
|
MD5Add(sc->sc_inc.inc6_laddr);
|
|
MD5Add(sc->sc_inc.inc6_faddr);
|
|
+ add.laddr = 0;
|
|
+ add.faddr = 0;
|
|
} else
|
|
#endif
|
|
{
|
|
! add.laddr = sc->sc_inc.inc_laddr.s_addr;
|
|
! add.faddr = sc->sc_inc.inc_faddr.s_addr;
|
|
}
|
|
! add.lport = sc->sc_inc.inc_lport;
|
|
! add.fport = sc->sc_inc.inc_fport;
|
|
! add.secbits[0] = tcp_secret[idx].ts_secbits[0];
|
|
! add.secbits[1] = tcp_secret[idx].ts_secbits[1];
|
|
! add.secbits[2] = tcp_secret[idx].ts_secbits[2];
|
|
! add.secbits[3] = tcp_secret[idx].ts_secbits[3];
|
|
! MD5Add(add);
|
|
MD5Final((u_char *)&md5_buffer, &syn_ctx);
|
|
! data ^= (md5_buffer[0] & ~SYNCOOKIE_WNDMASK);
|
|
return (data);
|
|
}
|
|
|
|
***************
|
|
*** 1304,1313 ****
|
|
struct syncache *sc;
|
|
u_int32_t data;
|
|
int wnd, idx;
|
|
|
|
data = (th->th_ack - 1) ^ (th->th_seq - 1); /* remove ISS */
|
|
! wnd = data & SYNCOOKIE_WNDMASK;
|
|
! idx = wnd >> SYNCOOKIE_HASHSHIFT;
|
|
if (tcp_secret[idx].ts_expire < ticks ||
|
|
sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks)
|
|
return (NULL);
|
|
--- 1319,1328 ----
|
|
struct syncache *sc;
|
|
u_int32_t data;
|
|
int wnd, idx;
|
|
+ struct md5_add add;
|
|
|
|
data = (th->th_ack - 1) ^ (th->th_seq - 1); /* remove ISS */
|
|
! idx = data & SYNCOOKIE_WNDMASK;
|
|
if (tcp_secret[idx].ts_expire < ticks ||
|
|
sototcpcb(so)->ts_recent + SYNCOOKIE_TIMEOUT < ticks)
|
|
return (NULL);
|
|
***************
|
|
*** 1316,1332 ****
|
|
if (inc->inc_isipv6) {
|
|
MD5Add(inc->inc6_laddr);
|
|
MD5Add(inc->inc6_faddr);
|
|
} else
|
|
#endif
|
|
{
|
|
! MD5Add(inc->inc_laddr);
|
|
! MD5Add(inc->inc_faddr);
|
|
}
|
|
! MD5Add(inc->inc_lport);
|
|
! MD5Add(inc->inc_fport);
|
|
! MD5Add(tcp_secret[idx].ts_secbits);
|
|
MD5Final((u_char *)&md5_buffer, &syn_ctx);
|
|
! data ^= md5_buffer[wnd & SYNCOOKIE_HASHMASK];
|
|
if ((data & ~SYNCOOKIE_DATAMASK) != 0)
|
|
return (NULL);
|
|
data = data >> SYNCOOKIE_WNDBITS;
|
|
--- 1331,1353 ----
|
|
if (inc->inc_isipv6) {
|
|
MD5Add(inc->inc6_laddr);
|
|
MD5Add(inc->inc6_faddr);
|
|
+ add.laddr = 0;
|
|
+ add.faddr = 0;
|
|
} else
|
|
#endif
|
|
{
|
|
! add.laddr = inc->inc_laddr.s_addr;
|
|
! add.faddr = inc->inc_faddr.s_addr;
|
|
}
|
|
! add.lport = inc->inc_lport;
|
|
! add.fport = inc->inc_fport;
|
|
! add.secbits[0] = tcp_secret[idx].ts_secbits[0];
|
|
! add.secbits[1] = tcp_secret[idx].ts_secbits[1];
|
|
! add.secbits[2] = tcp_secret[idx].ts_secbits[2];
|
|
! add.secbits[3] = tcp_secret[idx].ts_secbits[3];
|
|
! MD5Add(add);
|
|
MD5Final((u_char *)&md5_buffer, &syn_ctx);
|
|
! data ^= md5_buffer[0];
|
|
if ((data & ~SYNCOOKIE_DATAMASK) != 0)
|
|
return (NULL);
|
|
data = data >> SYNCOOKIE_WNDBITS;
|