|
|
|
|
@ -2049,10 +2049,10 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state,
|
|
|
|
|
return (input - initial_input);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserState *pstate,
|
|
|
|
|
const uint8_t *input, uint32_t input_len, const StreamSlice stream_slice)
|
|
|
|
|
static struct SSLDecoderResult SSLv2Decode(uint8_t direction, SSLState *ssl_state,
|
|
|
|
|
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
|
|
|
|
|
const StreamSlice stream_slice)
|
|
|
|
|
{
|
|
|
|
|
int retval = 0;
|
|
|
|
|
const uint8_t *initial_input = input;
|
|
|
|
|
|
|
|
|
|
if (ssl_state->curr_connp->bytes_processed == 0) {
|
|
|
|
|
@ -2075,13 +2075,13 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserSta
|
|
|
|
|
to read the msg_type */
|
|
|
|
|
if (ssl_state->curr_connp->bytes_processed <
|
|
|
|
|
(ssl_state->curr_connp->record_lengths_length + 1)) {
|
|
|
|
|
retval = SSLv2ParseRecord(direction, ssl_state, input, input_len);
|
|
|
|
|
const int retval = SSLv2ParseRecord(direction, ssl_state, input, input_len);
|
|
|
|
|
SCLogDebug("retval %d ssl_state->curr_connp->record_length %u", retval,
|
|
|
|
|
ssl_state->curr_connp->record_length);
|
|
|
|
|
if (retval < 0 || retval > (int)input_len) {
|
|
|
|
|
DEBUG_VALIDATE_BUG_ON(retval > (int)input_len);
|
|
|
|
|
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
|
|
|
|
|
return -1;
|
|
|
|
|
return SSL_DECODER_ERROR(-1);
|
|
|
|
|
}
|
|
|
|
|
// TODO review
|
|
|
|
|
// BUG_ON(ssl_state->curr_connp->record_lengths_length + 1 !=
|
|
|
|
|
@ -2096,22 +2096,32 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserSta
|
|
|
|
|
input_len -= retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if we don't have the full record, we return incomplete */
|
|
|
|
|
if (ssl_state->curr_connp->record_lengths_length + ssl_state->curr_connp->record_length >
|
|
|
|
|
input_len + ssl_state->curr_connp->bytes_processed) {
|
|
|
|
|
uint32_t needed = ssl_state->curr_connp->record_length;
|
|
|
|
|
SCLogDebug("record len %u input_len %u parsed %u: need %u bytes more data",
|
|
|
|
|
ssl_state->curr_connp->record_length, input_len, (uint32_t)(input - initial_input),
|
|
|
|
|
needed);
|
|
|
|
|
return SSL_DECODER_INCOMPLETE((input - initial_input), needed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (input_len == 0) {
|
|
|
|
|
return (input - initial_input);
|
|
|
|
|
return SSL_DECODER_OK((input - initial_input));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* record_length should never be zero */
|
|
|
|
|
if (ssl_state->curr_connp->record_length == 0) {
|
|
|
|
|
SCLogDebug("SSLv2 record length is zero");
|
|
|
|
|
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
|
|
|
|
|
return -1;
|
|
|
|
|
return SSL_DECODER_ERROR(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* record_lengths_length should never be zero */
|
|
|
|
|
if (ssl_state->curr_connp->record_lengths_length == 0) {
|
|
|
|
|
SCLogDebug("SSLv2 record lengths length is zero");
|
|
|
|
|
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
|
|
|
|
|
return -1;
|
|
|
|
|
return SSL_DECODER_ERROR(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (ssl_state->curr_connp->content_type) {
|
|
|
|
|
@ -2325,15 +2335,14 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserSta
|
|
|
|
|
ssl_state->curr_connp->bytes_processed;
|
|
|
|
|
input += diff;
|
|
|
|
|
SSLParserReset(ssl_state);
|
|
|
|
|
return (input - initial_input);
|
|
|
|
|
|
|
|
|
|
/* we still don't have the entire record for the one we are
|
|
|
|
|
currently parsing */
|
|
|
|
|
/* we still don't have the entire record for the one we are
|
|
|
|
|
currently parsing */
|
|
|
|
|
} else {
|
|
|
|
|
input += input_len;
|
|
|
|
|
ssl_state->curr_connp->bytes_processed += input_len;
|
|
|
|
|
return (input - initial_input);
|
|
|
|
|
}
|
|
|
|
|
return SSL_DECODER_OK((input - initial_input));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_state,
|
|
|
|
|
@ -2640,19 +2649,25 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate,
|
|
|
|
|
} else {
|
|
|
|
|
SCLogDebug("Continuing parsing SSLv2 record");
|
|
|
|
|
}
|
|
|
|
|
int retval = SSLv2Decode(direction, ssl_state, pstate, input, input_len, stream_slice);
|
|
|
|
|
if (retval < 0 || retval > input_len) {
|
|
|
|
|
DEBUG_VALIDATE_BUG_ON(retval > input_len);
|
|
|
|
|
struct SSLDecoderResult r =
|
|
|
|
|
SSLv2Decode(direction, ssl_state, pstate, input, input_len, stream_slice);
|
|
|
|
|
if (r.retval < 0 || r.retval > input_len) {
|
|
|
|
|
DEBUG_VALIDATE_BUG_ON(r.retval > input_len);
|
|
|
|
|
SCLogDebug("Error parsing SSLv2. Reseting parser "
|
|
|
|
|
"state. Let's get outta here");
|
|
|
|
|
SSLParserReset(ssl_state);
|
|
|
|
|
SSLSetEvent(ssl_state,
|
|
|
|
|
TLS_DECODER_EVENT_INVALID_SSL_RECORD);
|
|
|
|
|
return APP_LAYER_OK;
|
|
|
|
|
return APP_LAYER_ERROR;
|
|
|
|
|
} else if (r.needed) {
|
|
|
|
|
input += r.retval;
|
|
|
|
|
SCLogDebug("returning consumed %" PRIuMAX " needed %u",
|
|
|
|
|
(uintmax_t)(input - init_input), r.needed);
|
|
|
|
|
SCReturnStruct(APP_LAYER_INCOMPLETE(input - init_input, r.needed));
|
|
|
|
|
}
|
|
|
|
|
input_len -= retval;
|
|
|
|
|
input += retval;
|
|
|
|
|
SCLogDebug("SSLv2 decoder consumed %d bytes: %u left", retval, input_len);
|
|
|
|
|
input_len -= r.retval;
|
|
|
|
|
input += r.retval;
|
|
|
|
|
SCLogDebug("SSLv2 decoder consumed %d bytes: %u left", r.retval, input_len);
|
|
|
|
|
} else {
|
|
|
|
|
if (ssl_state->curr_connp->bytes_processed == 0) {
|
|
|
|
|
SCLogDebug("New TLS record: record_length %u",
|
|
|
|
|
|