|
|
@ -164,26 +164,58 @@ MimeDecConfig * MimeDecGetConfig(void) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* \brief Recursively frees a mime entity tree
|
|
|
|
* \brief Follow the 'next' pointers to the leaf
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* \param node The root entity
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* \return Pointer to leaf on 'next' side
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static MimeDecEntity *findLastSibling(MimeDecEntity *node)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (node == NULL)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
while(node->next != NULL)
|
|
|
|
|
|
|
|
node = node->next;
|
|
|
|
|
|
|
|
return node;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* \brief Frees a mime entity tree
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* \param entity The root entity
|
|
|
|
* \param entity The root entity
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* \return none
|
|
|
|
* \return none
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void MimeDecFreeEntity (MimeDecEntity *entity) {
|
|
|
|
void MimeDecFreeEntity (MimeDecEntity *entity)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (entity != NULL) {
|
|
|
|
if (entity == NULL)
|
|
|
|
|
|
|
|
return;
|
|
|
|
MimeDecFreeField(entity->field_list);
|
|
|
|
MimeDecEntity *lastSibling = findLastSibling(entity);
|
|
|
|
MimeDecFreeUrl(entity->url_list);
|
|
|
|
while (entity != NULL)
|
|
|
|
SCFree(entity->filename);
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
/* Use recursion */
|
|
|
|
* Move child to next
|
|
|
|
MimeDecFreeEntity(entity->child);
|
|
|
|
* Transform tree into list
|
|
|
|
MimeDecFreeEntity(entity->next);
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (entity->child != NULL)
|
|
|
|
SCFree(entity);
|
|
|
|
{
|
|
|
|
|
|
|
|
lastSibling->next = entity->child;
|
|
|
|
|
|
|
|
lastSibling = findLastSibling(lastSibling);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Move to next element
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
MimeDecEntity *old = entity;
|
|
|
|
|
|
|
|
entity = entity->next;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MimeDecFreeField(old->field_list);
|
|
|
|
|
|
|
|
MimeDecFreeUrl(old->url_list);
|
|
|
|
|
|
|
|
SCFree(old->filename);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCFree(old);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1085,47 +1117,52 @@ static int ProcessDecodedDataChunk(const uint8_t *chunk, uint32_t len,
|
|
|
|
MimeDecParseState *state) {
|
|
|
|
MimeDecParseState *state) {
|
|
|
|
|
|
|
|
|
|
|
|
int ret = MIME_DEC_OK;
|
|
|
|
int ret = MIME_DEC_OK;
|
|
|
|
MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data;
|
|
|
|
|
|
|
|
char *remainPtr, *tok;
|
|
|
|
char *remainPtr, *tok;
|
|
|
|
uint32_t tokLen;
|
|
|
|
uint32_t tokLen;
|
|
|
|
|
|
|
|
|
|
|
|
MimeDecConfig *mdcfg = MimeDecGetConfig();
|
|
|
|
MimeDecConfig *mdcfg = MimeDecGetConfig();
|
|
|
|
if (mdcfg != NULL && mdcfg->extract_urls) {
|
|
|
|
if (mdcfg != NULL && mdcfg->extract_urls) {
|
|
|
|
/* If plain text or html, then look for URLs */
|
|
|
|
if ((state->stack != NULL) && (state->stack->top != NULL)) {
|
|
|
|
if ((entity->ctnt_flags & CTNT_IS_TEXT) ||
|
|
|
|
MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data;
|
|
|
|
(entity->ctnt_flags & CTNT_IS_HTML)) {
|
|
|
|
/* If plain text or html, then look for URLs */
|
|
|
|
|
|
|
|
if (((entity->ctnt_flags & CTNT_IS_TEXT) ||
|
|
|
|
/* Remainder from previous line */
|
|
|
|
(entity->ctnt_flags & CTNT_IS_HTML)) &&
|
|
|
|
if (state->linerem_len > 0) {
|
|
|
|
((entity->ctnt_flags & CTNT_IS_ATTACHMENT) == 0)) {
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* Remainder from previous line */
|
|
|
|
/* No remainder from previous line */
|
|
|
|
if (state->linerem_len > 0) {
|
|
|
|
/* Parse each line one by one */
|
|
|
|
// TODO
|
|
|
|
remainPtr = (char *) chunk;
|
|
|
|
} else {
|
|
|
|
do {
|
|
|
|
/* No remainder from previous line */
|
|
|
|
tok = GetLine(remainPtr, len - (remainPtr - (char *) chunk),
|
|
|
|
/* Parse each line one by one */
|
|
|
|
&remainPtr, &tokLen);
|
|
|
|
remainPtr = (char *) chunk;
|
|
|
|
if (tok != remainPtr) {
|
|
|
|
do {
|
|
|
|
// DEBUG - ADDED
|
|
|
|
tok = GetLine(remainPtr, len - (remainPtr - (char *) chunk),
|
|
|
|
/* If last token found without CR/LF delimiter, then save
|
|
|
|
&remainPtr, &tokLen);
|
|
|
|
* and reconstruct with next chunk
|
|
|
|
if (tok != remainPtr) {
|
|
|
|
*/
|
|
|
|
// DEBUG - ADDED
|
|
|
|
if (tok + tokLen - (char *) chunk == len) {
|
|
|
|
/* If last token found without CR/LF delimiter, then save
|
|
|
|
PrintChars(SC_LOG_DEBUG, "LAST CHUNK LINE - CUTOFF",
|
|
|
|
* and reconstruct with next chunk
|
|
|
|
tok, tokLen);
|
|
|
|
*/
|
|
|
|
SCLogDebug("\nCHUNK CUTOFF CHARS: %d delim %ld\n", tokLen, len - (tok + tokLen - (char *) chunk));
|
|
|
|
if (tok + tokLen - (char *) chunk == len) {
|
|
|
|
} else {
|
|
|
|
PrintChars(SC_LOG_DEBUG, "LAST CHUNK LINE - CUTOFF",
|
|
|
|
/* Search line for URL */
|
|
|
|
tok, tokLen);
|
|
|
|
ret = FindUrlStrings(tok, tokLen, state);
|
|
|
|
SCLogDebug("\nCHUNK CUTOFF CHARS: %d delim %ld\n", tokLen, len - (tok + tokLen - (char *) chunk));
|
|
|
|
if (ret != MIME_DEC_OK) {
|
|
|
|
} else {
|
|
|
|
SCLogDebug("Error: FindUrlStrings() function"
|
|
|
|
/* Search line for URL */
|
|
|
|
" failed: %d", ret);
|
|
|
|
ret = FindUrlStrings(tok, tokLen, state);
|
|
|
|
break;
|
|
|
|
if (ret != MIME_DEC_OK) {
|
|
|
|
|
|
|
|
SCLogDebug("Error: FindUrlStrings() function"
|
|
|
|
|
|
|
|
" failed: %d", ret);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (tok != remainPtr && remainPtr - (char *) chunk < len);
|
|
|
|
} while (tok != remainPtr && remainPtr - (char *) chunk < len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
SCLogDebug("Error: Stack pointer missing");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|