Sniffer Chain Buffers

1. Fixed an issue when a TLS record is split across two chain buffers.
The second buffer was being treated as a new record.
2. Fixed an issue with STARTTLS_ALLOWED where the input buffer isn't
getting cleared and the skipped data just builds up blocking TLS
records.
This commit is contained in:
John Safranek
2019-08-29 12:45:01 -07:00
parent 53c7f864b2
commit 3256fef7f9

View File

@@ -3606,8 +3606,7 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
/* if current partial data, add to end of partial */ /* if current partial data, add to end of partial */
/* if skipping, the data is already at the end of partial */ /* if skipping, the data is already at the end of partial */
if ( !skipPartial && !vChain && if ( !skipPartial && (length = ssl->buffers.inputBuffer.length) ) {
(length = ssl->buffers.inputBuffer.length) ) {
Trace(PARTIAL_ADD_STR); Trace(PARTIAL_ADD_STR);
if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) { if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
@@ -3616,49 +3615,54 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
return -1; return -1;
} }
} }
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length], *sslFrame, *sslBytes); if (vChain == NULL) {
*sslBytes += length; XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
ssl->buffers.inputBuffer.length = *sslBytes; *sslFrame, *sslBytes);
*sslFrame = ssl->buffers.inputBuffer.buffer; *sslBytes += length;
*end = *sslFrame + *sslBytes; ssl->buffers.inputBuffer.length = *sslBytes;
*sslFrame = ssl->buffers.inputBuffer.buffer;
*end = *sslFrame + *sslBytes;
}
} }
if (vChain != NULL) { if (vChain != NULL) {
#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT #ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
struct iovec* chain = (struct iovec*)vChain; struct iovec* chain = (struct iovec*)vChain;
word32 i, offset, headerOffset, qty; word32 i, offset, headerSz, qty, remainder;
Trace(CHAIN_INPUT_STR); Trace(CHAIN_INPUT_STR);
headerOffset = (word32)*sslFrame - (word32)chain[0].iov_base; headerSz = (word32)*sslFrame - (word32)chain[0].iov_base;
length = *sslBytes + headerOffset; remainder = *sslBytes;
if (length > ssl->buffers.inputBuffer.bufferSize) {
if (GrowInputBuffer(ssl, length, 0) < 0) { if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE); SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
return -1; return -1;
} }
} }
offset = 0; qty = min(*sslBytes, (word32)chain[0].iov_len - headerSz);
for (i = 0; i < chainSz; i++) { XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
/* In case there is extra data in the chain that isn't covered (byte*)chain[0].iov_base + headerSz, qty);
* by the sizes in the TCP headers, don't copy too much. This offset = length;
* case has been seen where there are 4 extra bytes in the for (i = 1; i < chainSz; i++) {
* packet capture than the TCP header indicates. */ offset += qty;
if (offset + chain[i].iov_len > length) remainder -= qty;
qty = length - offset;
if (chain[i].iov_len > remainder)
qty = remainder;
else else
qty = (word32)chain[i].iov_len; qty = (word32)chain[i].iov_len;
XMEMCPY(ssl->buffers.inputBuffer.buffer + offset, XMEMCPY(ssl->buffers.inputBuffer.buffer + offset,
chain[i].iov_base, qty); chain[i].iov_base, qty);
offset += qty;
} }
ssl->buffers.inputBuffer.length = length; *sslBytes += length;
*sslFrame = ssl->buffers.inputBuffer.buffer + headerOffset; ssl->buffers.inputBuffer.length = *sslBytes;
*sslFrame = ssl->buffers.inputBuffer.buffer;
*end = *sslFrame + *sslBytes; *end = *sslFrame + *sslBytes;
#else
(void)chainSz;
#endif #endif
(void)chainSz;
} }
if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) { if ((*session)->flags.clientHello == 0 && **sslFrame != handshake) {
@@ -3677,8 +3681,10 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
} }
else { else {
#ifdef STARTTLS_ALLOWED #ifdef STARTTLS_ALLOWED
if (ssl->buffers.inputBuffer.dynamicFlag) if (ssl->buffers.inputBuffer.dynamicFlag) {
ssl->buffers.inputBuffer.length = 0;
ShrinkInputBuffer(ssl, NO_FORCED_FREE); ShrinkInputBuffer(ssl, NO_FORCED_FREE);
}
return 1; return 1;
#endif #endif
} }