示例#1
0
文件: blob.c 项目: nsxz/clamav-devel
void
fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg)
{
    UNUSEDPARAM(arg);

    if(fb->b.name)
        return;

    assert(fullname != NULL);

    cli_dbgmsg("fileblobPartialSet: saving to %s\n", fullname);

    fb->fd = open(fullname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_EXCL, 0600);
    if(fb->fd < 0) {
        cli_errmsg("fileblobPartialSet: unable to create file: %s\n",fullname);
        return;
    }
    fb->fp = fdopen(fb->fd, "wb");

    if(fb->fp == NULL) {
        cli_errmsg("fileblobSetFilename: fdopen failed\n");
        close(fb->fd);
        return;
    }
    blobSetFilename(&fb->b, fb->ctx ? fb->ctx->engine->tmpdir : NULL, fullname);
    if(fb->b.data)
        if(fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
            free(fb->b.data);
            fb->b.data = NULL;
            fb->b.len = fb->b.size = 0;
            fb->isNotEmpty = 1;
        }
    fb->fullname = cli_strdup(fullname);
}
示例#2
0
/*
 * Returns the value, or -1 for failure
 */
int
tableInsert(table_t *table, const char *key, int value)
{
	const int v = tableFind(table, key);

	if(v > 0)	/* duplicate key */
		return (v == value) ? value : -1;	/* allow real dups */

	assert(value != -1);	/* that would confuse us */

	if(table->tableHead == NULL)
		table->tableLast = table->tableHead = (tableEntry *)cli_malloc(sizeof(tableEntry));
	else {
		/*
		 * Re-use deleted items
		 */
		if(table->flags&TABLE_HAS_DELETED_ENTRIES) {
			tableEntry *tableItem;

			assert(table->tableHead != NULL);

			for(tableItem = table->tableHead; tableItem; tableItem = tableItem->next)
				if(tableItem->key == NULL) {
					/* This item has been deleted */
					tableItem->key = cli_strdup(key);
					tableItem->value = value;
					return value;
				}

			table->flags &= ~TABLE_HAS_DELETED_ENTRIES;
		}

		table->tableLast = table->tableLast->next =
			(tableEntry *)cli_malloc(sizeof(tableEntry));
	}

	if(table->tableLast == NULL) {
        cli_dbgmsg("tableInsert: Unable to allocate memory for table\n");
		return -1;
    }

	table->tableLast->next = NULL;
	table->tableLast->key = cli_strdup(key);
	table->tableLast->value = value;

	return value;
}
示例#3
0
/*lint -e578*/
static void cli_history_item_init(
        cli_history_item_t * item,
        const cli_int8 * line, 
        cli_uint32 index)
{
    item->line = cli_strdup(line);
    item->index = index; 
}
示例#4
0
/*ARGSUSED*/
void
blobSetFilename(blob *b, const char *dir, const char *filename)
{
	assert(b != NULL);
	assert(b->magic == BLOBCLASS);
	assert(filename != NULL);

	cli_dbgmsg("blobSetFilename: %s\n", filename);

	if(b->name)
		free(b->name);

	b->name = cli_strdup(filename);

	if(b->name)
		sanitiseName(b->name);
}
示例#5
0
文件: cab.c 项目: OPSF/uClinux
static char *cab_readstr(int fd, int *ret)
{
	int i, bread, found = 0;
	char buff[256], *str;
	off_t pos;


    if((pos = lseek(fd, 0, SEEK_CUR)) == -1) {
	*ret = CL_ESEEK;
	return NULL;
    }

    bread = read(fd, buff, sizeof(buff));
    for(i = 0; i < bread; i++) {
	if(!buff[i]) {
	    found = 1;
	    break;
	}
    }

    if(!found) {
	*ret = CL_EFORMAT;
	return NULL;
    }

    if(lseek(fd, (off_t) (pos + i + 1), SEEK_SET) == -1) {
	*ret = CL_EFORMAT; /* most likely a corrupted file */
	return NULL;
    }

    if(!(str = cli_strdup(buff))) {
	*ret = CL_EMEM;
	return NULL;
    }

    *ret = CL_SUCCESS;
    return str;
}
示例#6
0
/* buffer is html-normlike "chunk", if original file is bigger than buffer,
 * we rewind to a space, so we'll know that tokens won't be broken in half at
 * the end of a buffer. All tokens except string-literals of course.
 * So we can assume that after the buffer there is either a space, EOF, or a
 * chunk of text not containing whitespace at all (for which we care only if its
 * a stringliteral)*/
void cli_js_process_buffer(struct parser_state *state, const char *buf, size_t n)
{
	struct scope* current = state->current;
	YYSTYPE val;
	int yv;
	YY_BUFFER_STATE yyb;

	if(!state->global) {
		/* this state has either not been initialized,
		 * or cli_js_parse_done() was already called on it */
		cli_warnmsg(MODULE "invalid state\n");
		return;
	}
	yyb = yy_scan_bytes(buf, n, state->scanner);
	memset(&val, 0, sizeof(val));
	val.vtype = vtype_undefined;
	/* on EOF yylex will return 0 */
	while( (yv=yylex(&val, state->scanner)) != 0)
	{
		const char *text;
		size_t leng;

		val.type = yv;
		switch(yv) {
			case TOK_VAR:
				current->fsm_state = InsideVar;
				break;
			case TOK_IDENTIFIER_NAME:
				text = yyget_text(state->scanner);
				leng = yyget_leng(state->scanner);
				if(current->last_token == TOK_DOT) {
					/* this is a member name, don't normalize
					*/
					TOKEN_SET(&val, string, cli_strdup(text));
					val.type = TOK_UNNORM_IDENTIFIER;
				} else {
					switch(current->fsm_state) {
						case WaitParameterList:
							state->syntax_errors++;
							/* fall through */
						case Base:
						case InsideInitializer:
							TOKEN_SET(&val, cstring, scope_use(current, text, leng));
							break;
						case InsideVar:
						case InsideFunctionDecl:
							TOKEN_SET(&val, cstring, scope_declare(current, text, leng, state));
							current->fsm_state = InsideInitializer;
							current->brackets = 0;
							break;
						case WaitFunctionName:
							TOKEN_SET(&val, cstring, scope_declare(current, text, leng, state));
							current->fsm_state = WaitParameterList;
							break;
					}
				}
				break;
			case TOK_PAR_OPEN:
				switch(current->fsm_state) {
					case WaitFunctionName:
						/* fallthrough */
					case WaitParameterList:
						current->fsm_state = InsideFunctionDecl;
						break;
					default:
						/* noop */
						break;
				}
				break;
			case TOK_PAR_CLOSE:
				switch(current->fsm_state) {
					case WaitFunctionName:
						state->syntax_errors++;
						break;
					case WaitParameterList:
						current->fsm_state = Base;
						break;
					default:
						/* noop */
						break;
				}
				break;
			case TOK_CURLY_BRACE_OPEN:
				switch(current->fsm_state) {
					case WaitFunctionName:
						/* fallthrough */
					case WaitParameterList:
					case InsideFunctionDecl:
						/* in a syntactically correct
						 * file, we would already be in
						 * the Base state when we see a {
						 */
						current->fsm_state = Base;
						/* fall-through */
					case InsideVar:
					case InsideInitializer:
						state->syntax_errors++;
						/* fall-through */
					case Base:
					default:
						current->blocks++;
						break;
				}
				break;
					case TOK_CURLY_BRACE_CLOSE:
				if(current->blocks > 0)
					current->blocks--;
				else
					state->syntax_errors++;
				if(!current->blocks) {
					if(current->parent) {
						/* add dummy FUNCTION token to
						 * mark function end */
						TOKEN_SET(&val, cstring, "}");
						add_token(state, &val);
						TOKEN_SET(&val, scope, NULL);
						val.type = TOK_FUNCTION;

						state->current = current = current->parent;
					} else{
						/* extra } */
						state->syntax_errors++;
				}
				}
				break;
			case TOK_BRACKET_OPEN:
				current->brackets++;
				break;
			case TOK_BRACKET_CLOSE:
				if(current->brackets > 0)
					current->brackets--;
				else
					state->syntax_errors++;
				break;
			case TOK_COMMA:
				if (current->fsm_state == InsideInitializer && current->brackets == 0 && current->blocks == 0) {
					/* initializer ended only if we
					 * encountered a comma, and [] are
					 * balanced.
					 * This avoids switching state on:
					 * var x = [4,y,u];*/
					current->fsm_state = InsideVar;
				}
				break;
			case TOK_SEMICOLON:
				if (current->brackets == 0 && current->blocks == 0) {
					/* avoid switching state on unbalanced []:
					 * var x = [test;testi]; */
					current->fsm_state = Base;
				}
				break;
			case TOK_FUNCTION:
				current = scope_new(state);
				current->fsm_state = WaitFunctionName;
				TOKEN_SET(&val, scope, state->current);
				break;
			case TOK_StringLiteral:
				if(state->tokens.cnt > 1 && state->tokens.data[state->tokens.cnt-1].type == TOK_PLUS) {
					/* see if can fold */
					yystype *prev_string = &state->tokens.data[state->tokens.cnt-2];
					if(prev_string->type == TOK_StringLiteral) {
						char *str = TOKEN_GET(prev_string, string);
						size_t str_len = strlen(str);

						text = yyget_text(state->scanner);
						leng = yyget_leng(state->scanner);


						/* delete TOK_PLUS */
						free_token(&state->tokens.data[--state->tokens.cnt]);

						str = cli_realloc(str, str_len + leng + 1);
						if (!str)
						    break;
						strncpy(str+str_len, text, leng);
						str[str_len + leng] = '\0';
						TOKEN_SET(prev_string, string, str);
						free(val.val.string);
						memset(&val, 0, sizeof(val));
						val.vtype = vtype_undefined;
						continue;
					}
				}
				break;
		}
		if(val.vtype == vtype_undefined) {
			text = yyget_text(state->scanner);
			TOKEN_SET(&val, string, cli_strdup(text));
			abort();
		}
		add_token(state, &val);
		current->last_token = yv;
		memset(&val, 0, sizeof(val));
		val.vtype = vtype_undefined;
	}
}
示例#7
0
char *pdf_finalize_string(struct pdf_struct *pdf, struct pdf_obj *obj, const char *in, size_t len)
{
    char *wrkstr, *output = NULL;
    size_t wrklen = len, outlen;
    unsigned int i, likelyutf = 0;

    if (!in)
        return NULL;

    /* get a working copy */
    wrkstr = cli_calloc(len+1, sizeof(char));
    if (!wrkstr)
        return NULL;
    memcpy(wrkstr, in, len);

    //cli_errmsg("pdf_final: start(%d):   %s\n", wrklen, wrkstr);

    /* convert PDF specific escape sequences, like octal sequences */
    /* TODO: replace the escape sequences directly in the wrkstr   */
    if (strchr(wrkstr, '\\')) {
        output = cli_calloc(wrklen+1, sizeof(char));
        if (!output) {
            free(wrkstr);
            return NULL;
        }

        outlen = 0;
        for (i = 0; i < wrklen; ++i) {
            if ((i+1 < wrklen) && wrkstr[i] == '\\') {
                if ((i+3 < wrklen) &&
                    (isdigit(wrkstr[i+1]) && isdigit(wrkstr[i+2]) && isdigit(wrkstr[i+3]))) {
                    /* octal sequence */
                    char octal[4], *check;
                    unsigned long value;

                    memcpy(octal, &wrkstr[i+1], 3);
                    octal[3] = '\0';

                    value = (char)strtoul(octal, &check, 8);
                    /* check if all characters were converted */
                    if (check == &octal[3])
                        output[outlen++] = value;
                    i += 3; /* 4 with for loop [\ddd] */
                } else {
                    /* other sequences */
                    switch(wrkstr[i+1]) {
                    case 'n':
                        output[outlen++] = 0x0a;
                        break;
                    case 'r':
                        output[outlen++] = 0x0d;
                        break;
                    case 't':
                        output[outlen++] = 0x09;
                        break;
                    case 'b':
                        output[outlen++] = 0x08;
                        break;
                    case 'f':
                        output[outlen++] = 0x0c;
                        break;
                    case '(':
                        output[outlen++] = 0x28;
                        break;
                    case ')':
                        output[outlen++] = 0x29;
                        break;
                    case '\\':
                        output[outlen++] = 0x5c;
                        break;
                    default:
                        /* IGNORE THE REVERSE SOLIDUS - PDF3000-2008 */
                        break;
                    }
                    i += 1; /* 2 with for loop [\c] */
                }
            } else {
                output[outlen++] = wrkstr[i];
            }
        }

        free(wrkstr);
        wrkstr = cli_strdup(output);
        free(output);
        wrklen = outlen;
    }

    //cli_errmsg("pdf_final: escaped(%d): %s\n", wrklen, wrkstr);

    /* check for encryption and decrypt */
    if (pdf->flags & (1 << ENCRYPTED_PDF))
    {
        off_t tmpsz = (off_t)wrklen;
        output = pdf_decrypt_string(pdf, obj, wrkstr, &tmpsz);
        outlen = (size_t)tmpsz;
        free(wrkstr);
        if (output) {
            wrkstr = cli_calloc(outlen+1, sizeof(char));
            if (!wrkstr) {
                free(output);
                return NULL;
            }
            memcpy(wrkstr, output, outlen);
            free(output);
            wrklen = outlen;
        } else {
            return NULL;
        }
    }

    //cli_errmsg("pdf_final: decrypt(%d): %s\n", wrklen, wrkstr);

    /* check for UTF-* and convert to UTF-8 */
    for (i = 0; i < wrklen; ++i) {
        if (((unsigned char)wrkstr[i] > (unsigned char)0x7f) || (wrkstr[i] == '\0')) {
            likelyutf = 1;
            break;
        }
    }

    if (likelyutf) {
        output = pdf_convert_utf(wrkstr, wrklen);
        free(wrkstr);
        wrkstr = output;
    }

    //cli_errmsg("pdf_final: postutf(%d): %s\n", wrklen, wrkstr);

    return wrkstr;
}
示例#8
0
int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int dbtype, const char *filename, unsigned int chkonly)
{
	struct cl_cvd cvd, dupcvd;
	FILE *dupfs;
	int ret;
	time_t s_time;
	int cfd;
	struct cli_dbio dbio;
	struct cli_dbinfo *dbinfo = NULL;
	char *dupname;

    dbio.hashctx = NULL;

    cli_dbgmsg("in cli_cvdload()\n");

    /* verify */
    if((ret = cli_cvdverify(fs, &cvd, dbtype)))
	return ret;

    if(dbtype <= 1) {
	/* check for duplicate db */
	dupname = cli_strdup(filename);
	if(!dupname)
	    return CL_EMEM;
	dupname[strlen(dupname) - 2] = (dbtype == 1 ? 'v' : 'l');
	if(!access(dupname, R_OK) && (dupfs = fopen(dupname, "rb"))) {
	    if((ret = cli_cvdverify(dupfs, &dupcvd, !dbtype))) {
		fclose(dupfs);
		free(dupname);
		return ret;
	    }
	    fclose(dupfs);
	    if(dupcvd.version > cvd.version) {
		cli_warnmsg("Detected duplicate databases %s and %s. The %s database is older and will not be loaded, you should manually remove it from the database directory.\n", filename, dupname, filename);
		free(dupname);
		return CL_SUCCESS;
	    } else if(dupcvd.version == cvd.version && !dbtype) {
		cli_warnmsg("Detected duplicate databases %s and %s, please manually remove one of them\n", filename, dupname);
		free(dupname);
		return CL_SUCCESS;
	    }
	}
	free(dupname);
    }

    if(strstr(filename, "daily.")) {
	time(&s_time);
	if(cvd.stime > s_time) {
	    if(cvd.stime - (unsigned int ) s_time > 3600) {
		cli_warnmsg("******************************************************\n");
		cli_warnmsg("***      Virus database timestamp in the future!   ***\n");
		cli_warnmsg("***  Please check the timezone and clock settings  ***\n");
		cli_warnmsg("******************************************************\n");
	    }
	} else if((unsigned int) s_time - cvd.stime > 604800) {
	    cli_warnmsg("**************************************************\n");
	    cli_warnmsg("***  The virus database is older than 7 days!  ***\n");
	    cli_warnmsg("***   Please update it as soon as possible.    ***\n");
	    cli_warnmsg("**************************************************\n");
	}
	engine->dbversion[0] = cvd.version;
	engine->dbversion[1] = cvd.stime;
    }

    if(cvd.fl > cl_retflevel()) {
	cli_warnmsg("***********************************************************\n");
	cli_warnmsg("***  This version of the ClamAV engine is outdated.     ***\n");
	cli_warnmsg("*** DON'T PANIC! Read http://www.clamav.net/support/faq ***\n");
	cli_warnmsg("***********************************************************\n");
    }

    cfd = fileno(fs);
    dbio.chkonly = 0;
    if(dbtype == 2)
	ret = cli_tgzload(cfd, engine, signo, options | CL_DB_UNSIGNED, &dbio, NULL);
    else
	ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
    if(ret != CL_SUCCESS)
	return ret;

    dbinfo = engine->dbinfo;
    if(!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) {
	cli_errmsg("cli_cvdload: Corrupted CVD header\n");
	return CL_EMALFDB;
    }
    dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL;
    if(!dbinfo) {
	cli_errmsg("cli_cvdload: dbinfo error\n");
	return CL_EMALFDB;
    }

    dbio.chkonly = chkonly;
    if(dbtype == 2)
	options |= CL_DB_UNSIGNED;
    else
	options |= CL_DB_SIGNED | CL_DB_OFFICIAL;

    ret = cli_tgzload(cfd, engine, signo, options, &dbio, dbinfo);

    while(engine->dbinfo) {
	dbinfo = engine->dbinfo;
	engine->dbinfo = dbinfo->next;
	mpool_free(engine->mempool, dbinfo->name);
	mpool_free(engine->mempool, dbinfo->hash);
	if(dbinfo->cvd)
	    cl_cvdfree(dbinfo->cvd);
	mpool_free(engine->mempool, dbinfo);
    }

    return ret;
}
示例#9
0
static void do_phishing_test(const struct rtest *rtest)
{
	char *realurl;
	cli_ctx ctx;
	const char *virname = NULL;
	tag_arguments_t hrefs;
	int rc;

	memset(&ctx, 0, sizeof(ctx));

	realurl = cli_strdup(rtest->realurl);
	fail_unless(!!realurl, "cli_strdup");

	hrefs.count = 1;
	hrefs.value = cli_malloc(sizeof(*hrefs.value));
	fail_unless(!!hrefs.value, "cli_malloc");
	hrefs.value[0] = (unsigned char*)realurl;
	hrefs.contents = cli_malloc(sizeof(*hrefs.contents));
	fail_unless(!!hrefs.contents, "cli_malloc");
	hrefs.tag = cli_malloc(sizeof(*hrefs.tag));
	fail_unless(!!hrefs.tag, "cli_malloc");
	hrefs.tag[0] = (unsigned char*)cli_strdup("href");
	hrefs.contents[0] = (unsigned char*)cli_strdup(rtest->displayurl);

	ctx.engine = engine;
	ctx.virname = &virname;

	rc = phishingScan(&ctx, &hrefs);

	html_tag_arg_free(&hrefs);
	fail_unless(rc == CL_CLEAN,"phishingScan");
	switch(rtest->result) {
		case 0:
			fail_unless_fmt(ctx.found_possibly_unwanted,
					"this should be phishing, realURL: %s, displayURL: %s",
					rtest->realurl, rtest->displayurl);
			break;
		case 1:
			fail_unless_fmt(!ctx.found_possibly_unwanted,
					"this should be whitelisted, realURL: %s, displayURL: %s",
					rtest->realurl, rtest->displayurl);
			break;
		case 2:
			fail_unless_fmt(!ctx.found_possibly_unwanted,
					"this should be clean, realURL: %s, displayURL: %s",
					rtest->realurl, rtest->displayurl);
			break;
		case 3:
			if(!loaded_2)
				fail_unless_fmt(!ctx.found_possibly_unwanted,
					"this should be clean, realURL: %s, displayURL: %s",
					rtest->realurl, rtest->displayurl);
			else {
				fail_unless_fmt(ctx.found_possibly_unwanted,
					"this should be blacklisted, realURL: %s, displayURL: %s",
					rtest->realurl, rtest->displayurl);
				if (*ctx.virname)
				    fail_unless_fmt(!strstr((const char*)*ctx.virname,"Blacklisted"),
						    "should be blacklisted, but is: %s\n", ctx.virname);
			}
			break;
	}
}