when domain matchers, preserve full subdomain(bb #721)

git-svn: trunk@3560
remotes/push_mirror/metadata
Török Edvin 18 years ago
parent 5d40533ed5
commit 75fe12511f
  1. 5
      ChangeLog
  2. 31
      libclamav/phishcheck.c
  3. 36
      libclamav/regex_list.c

@ -1,3 +1,8 @@
Wed Jan 30 20:23:20 EET 2008 (edwin)
------------------------------------
* libclamav/phishcheck.c, regex_list.c: when domain matchers, preserve full
subdomain(bb #721)
Tue Jan 29 17:50:05 GMT 2008 (njh)
----------------------------------
* libclamav/tnef.c: Handle trailing CR and change handling of truncated

@ -242,6 +242,7 @@ static const short int hextable[256] = {
/* Prototypes*/
static void string_init_c(struct string* dest,char* data);
static int string_assign_concatenated(struct string* dest, const char* prefix, const char* begin, const char* end);
static void string_assign_null(struct string* dest);
static char *rfind(char *start, char c, size_t len);
static char hex2int(const unsigned char* src);
@ -298,19 +299,32 @@ static void string_init_c(struct string* dest,char* data)
dest->ref = NULL;
}
/* assigns to @dest the string made from concatenating @prefix with the string between @begin and @end */
static int string_assign_concatenated(struct string* dest, const char* prefix, const char* begin, const char* end)
{
const size_t prefix_len = strlen(prefix);
char* ret = cli_malloc(prefix_len + end - begin + 1);
if(!ret)
return CL_EMEM;
strncpy(ret, prefix, prefix_len);
strncpy(ret+prefix_len, begin, end-begin);
ret[prefix_len+end-begin]='\0';
string_free(dest);
string_init_c(dest, ret);
return CL_SUCCESS;
}
/* make a copy of the string between start -> end*/
static int string_assign_dup(struct string* dest,const char* start,const char* end)
{
char* ret = cli_malloc(end-start+1);
char* ret = cli_malloc(end-start+1);
if(!ret)
return CL_EMEM;
strncpy(ret,start,end-start);
ret[end-start]='\0';
string_free(dest);
dest->data=ret;
dest->refcount=1;
dest->ref=NULL;
string_init_c(dest, ret);
return CL_SUCCESS;
}
@ -745,11 +759,10 @@ cleanupURL(struct string *URL,struct string *pre_URL, int isReal)
}
if(!isReal) {
str_fixup_spaces(&begin,&end);
if (( rc = string_assign_dup(URL,begin,end+1) )) {
if (( rc = string_assign_dup(URL, begin, end+1) )) {
return rc;
}
}
/*cli_dbgmsg("%p::%s\n",URL->data,URL->data);*/
}
return 0;
}
@ -765,6 +778,7 @@ static int found_possibly_unwanted(cli_ctx* ctx)
int phishingScan(message* m,const char* dir,cli_ctx* ctx,tag_arguments_t* hrefs)
{
/* TODO: get_host and then apply regex, etc. */
int i;
struct phishcheck* pchk = (struct phishcheck*) ctx->engine->phishcheck;
/* check for status of whitelist fatal error, etc. */
@ -1003,6 +1017,7 @@ static enum phish_status cleanupURLs(struct url_check* urls)
{
if(urls->flags&CLEANUP_URL) {
cleanupURL(&urls->realLink,NULL,1);
cleanupURL(&urls->displayLink,&urls->pre_fixup.pre_displayLink,0);
if(!urls->displayLink.data || !urls->realLink.data)
return CL_PHISH_NODECISION;
@ -1024,7 +1039,7 @@ static int url_get_host(const struct phishcheck* pchk, struct url_check* url,str
if(!start || !end) {
string_assign_null(host);
}
else if(( rc = string_assign_dup(host,start,end) )) {
else if(( rc = string_assign_concatenated(host, ".", start, end) )) {
return rc;
}
@ -1110,6 +1125,8 @@ static enum phish_status phishingCheck(const struct cl_engine* engine,struct url
return rc < 0 ? rc : CL_PHISH_CLEAN;
}
cli_dbgmsg("Phishcheck:URL after cleanup: %s->%s\n", urls->realLink.data,
urls->displayLink.data);
if(whitelist_check(engine, urls, 0))
return CL_PHISH_CLEAN;/* if url is whitelisted don't perform further checks */

@ -238,7 +238,7 @@ static inline size_t get_char_at_pos_with_skip(const struct pre_fixup_info* info
realpos++;
}
while(str[realpos]==' ') realpos++;
cli_dbgmsg("calc_pos_with_skip:%s\n",str+realpos);
cli_dbgmsg("calc_pos_with_skip:%s\n",str+realpos);
return (pos>0 && !str[realpos]) ? '\0' : str[realpos>0?realpos-1:0];
}
@ -257,6 +257,7 @@ static inline size_t get_char_at_pos_with_skip(const struct pre_fixup_info* info
*/
int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* display_url,const struct pre_fixup_info* pre_fixup,int hostOnly,const char** info,int is_whitelist)
{
char* orig_real_url = real_url;
massert(matcher);
massert(real_url);
massert(display_url);
@ -264,6 +265,9 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di
if(!matcher->list_inited)
return 0;
massert(matcher->list_built);
/* skip initial '.' inserted by get_host */
if(real_url[0] == '.') real_url++;
if(display_url[0] == '.') display_url++;
{
size_t real_len = strlen(real_url);
size_t display_len = strlen(display_url);
@ -280,7 +284,7 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di
buffer[real_len]= (!is_whitelist && hostOnly) ? '\0' : ':';
if(!hostOnly || is_whitelist) {
strncpy(buffer+real_len+1,display_url,display_len);
if(is_whitelist)
if(is_whitelist)
buffer[buffer_len - 1] = '/';
buffer[buffer_len]=0;
}
@ -297,30 +301,40 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di
cli_ac_freedata(&mdata);
if(rc) {
char c;
const char* matched = strchr(*info,':');
const char* matched = strchr(*info,':');
const size_t match_len = matched ? strlen(matched+1) : 0;
if(((c=get_char_at_pos_with_skip(pre_fixup,buffer,buffer_len+1))==' ' || c=='\0' || c=='/' || c=='?') &&
(match_len == buffer_len || /* full match */
(match_len < buffer_len &&
((c=get_char_at_pos_with_skip(pre_fixup,buffer,buffer_len-match_len))=='.' || (c==' ')) )
((c=get_char_at_pos_with_skip(pre_fixup,buffer,buffer_len-match_len))=='.' || (c==' ')) )
/* subdomain matched*/)) {
cli_dbgmsg("Got a match: %s with %s\n",buffer,*info);
cli_dbgmsg("Before inserting .: %s\n",real_url);
cli_dbgmsg("Got a match: %s with %s\n", buffer, *info);
cli_dbgmsg("Before inserting .: %s\n", orig_real_url);
if(real_len >= match_len + 1) {
real_url[real_len-match_len-1]='.';
cli_dbgmsg("After inserting .: %s\n",real_url);
const size_t pos = real_len - match_len - 1;
if(real_url[pos] != '.') {
cli_dbgmsg("No dot here:%s\n",real_url+pos);
/* we need to shift left, and insert a '.'
* we have an extra '.' at the beginning inserted by get_host to have room,
* orig_real_url has to be used here,
* because we want to overwrite that extra '.' */
size_t orig_real_len = strlen(orig_real_url);
real_url = orig_real_url;
memmove(real_url, real_url+1, orig_real_len-match_len-1);
real_url[orig_real_len-match_len-1]='.';
cli_dbgmsg("After inserting .: %s\n", real_url);
}
}
break;
}
cli_dbgmsg("Ignoring false match: %s with %s,%c\n",buffer,*info,c);
cli_dbgmsg("Ignoring false match: %s with %s, mismatched character: %c\n", buffer, *info, c);
rc=0;
}
}
} else
rc = 0;
if(!rc)
if(!rc)
rc = match_node(hostOnly ? matcher->root_regex_hostonly : matcher->root_regex,(unsigned char*)buffer,buffer_len,info) == MATCH_SUCCESS ? CL_VIRUS : CL_SUCCESS;
free(buffer);
if(!rc)

Loading…
Cancel
Save