예제 #1
0
int sieve_match_value
(struct sieve_match_context *mctx, const char *value, size_t value_size,
	struct sieve_stringlist *key_list)
{
	const struct sieve_match_type *mcht = mctx->match_type;
	const struct sieve_runtime_env *renv = mctx->runenv;
	int match, ret;

	if ( mctx->trace ) {
		sieve_runtime_trace(renv, 0,
			"matching value `%s'", str_sanitize(value, 80));
	}

	/* Match to key values */

	sieve_stringlist_reset(key_list);

	if ( mctx->trace )
		sieve_stringlist_set_trace(key_list, TRUE);

	sieve_runtime_trace_descend(renv);

	if ( mcht->def->match_keys != NULL ) {
		/* Call match-type's own key match handler */
		match = mcht->def->match_keys(mctx, value, value_size, key_list);
	} else {
		string_t *key_item = NULL;

		/* Default key match loop */
		match = 0;
		while ( match == 0 &&
			(ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 ) {
			T_BEGIN {
				match = mcht->def->match_key
					(mctx, value, value_size, str_c(key_item), str_len(key_item));

				if ( mctx->trace ) {
					sieve_runtime_trace(renv, 0,
						"with key `%s' => %d", str_sanitize(str_c(key_item), 80),
						match);
				}
			} T_END;
		}

		if ( ret < 0 ) {
			mctx->exec_status = key_list->exec_status;
			match = -1;
		}
	}

	sieve_runtime_trace_ascend(renv);

	if ( mctx->match_status < 0 || match < 0 )
		mctx->match_status = -1;
	else
		mctx->match_status =
			( mctx->match_status > match ? mctx->match_status : match );
	return match;
}
예제 #2
0
static int mcht_count_match
(struct sieve_match_context *mctx, struct sieve_stringlist *value_list,
	struct sieve_stringlist *key_list)
{
	const struct sieve_runtime_env *renv = mctx->runenv;
	bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING);
	int count;
	string_t *key_item;
	int match, ret;

	if ( (count=sieve_stringlist_get_length(value_list)) < 0 ) {
		mctx->exec_status = value_list->exec_status;
		return -1;
	}

	sieve_stringlist_reset(key_list);

	string_t *value = t_str_new(20);
	str_printfa(value, "%d", count);

	if ( trace ) {
		sieve_runtime_trace(renv, 0,
			"matching count value `%s'", str_sanitize(str_c(value), 80));
	}

	sieve_runtime_trace_descend(renv);

  /* Match to all key values */
  key_item = NULL;
	match = 0;
  while ( match == 0 &&
		(ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 )
  {
		match = mcht_value_match_key
			(mctx, str_c(value), str_len(value), str_c(key_item), str_len(key_item));

		if ( trace ) {
			sieve_runtime_trace(renv, 0,
				"with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret);
		}
	}

	sieve_runtime_trace_ascend(renv);

	if ( ret < 0 ) {
		mctx->exec_status = key_list->exec_status;
		match = -1;
	}

	return match;
}
예제 #3
0
int sieve_match_end(struct sieve_match_context **mctx, int *exec_status)
{
	const struct sieve_match_type *mcht = (*mctx)->match_type;
	const struct sieve_runtime_env *renv = (*mctx)->runenv;
	int match = (*mctx)->match_status;

	if ( mcht->def != NULL && mcht->def->match_deinit != NULL )
		mcht->def->match_deinit(*mctx);

	if ( exec_status != NULL )
		*exec_status = (*mctx)->exec_status;

	pool_unref(&(*mctx)->pool);

	sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING,
		"finishing match with result: %s",
		( match > 0 ? "matched" : ( match < 0 ? "error" : "not matched" ) ));
	sieve_runtime_trace_ascend(renv);

	return match;
}
예제 #4
0
static int tst_spamvirustest_operation_execute
(const struct sieve_runtime_env *renv, sieve_size_t *address)
{
	const struct sieve_operation *op = renv->oprtn;
	const struct sieve_extension *this_ext = op->ext;
	int opt_code = 0;
	struct sieve_match_type mcht =
		SIEVE_MATCH_TYPE_DEFAULT(is_match_type);
	struct sieve_comparator cmp =
		SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator);
	bool percent = FALSE;
	struct sieve_stringlist *value_list, *key_list;
	const char *score_value;
	int match, ret;

	/* Read optional operands */
	for (;;) {
		int opt;

		if ( (opt=sieve_match_opr_optional_read
			(renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 )
			return ret;

		if ( opt == 0 ) break;

		switch ( opt_code ) {
		case OPT_SPAMTEST_PERCENT:
			percent = TRUE;
			break;
		default:
			sieve_runtime_trace_error(renv, "unknown optional operand");
			return SIEVE_EXEC_BIN_CORRUPT;
		}
	}

	/* Read value part */
	if ( (ret=sieve_opr_stringlist_read(renv, address, "value", &key_list)) <= 0 )
		return ret;

	/* Perform test */

	if ( sieve_operation_is(op, spamtest_operation) ) {
		sieve_runtime_trace
			(renv, SIEVE_TRLVL_TESTS, "spamtest test [percent=%s]",
				( percent ? "true" : "false" ));
	} else {
		sieve_runtime_trace
			(renv, SIEVE_TRLVL_TESTS, "virustest test");
	}

	/* Get score value */
	sieve_runtime_trace_descend(renv);
	if ( (ret=ext_spamvirustest_get_value
		(renv, this_ext, percent, &score_value)) <= 0 )
		return ret;
	sieve_runtime_trace_ascend(renv);

	/* Construct value list */
	value_list = sieve_single_stringlist_create_cstr(renv, score_value, TRUE);

	/* Perform match */
	if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 )
		return ret;

	/* Set test result for subsequent conditional jump */
	sieve_interpreter_set_test_result(renv->interp, match > 0);
	return SIEVE_EXEC_OK;
}