const struct sieve_enotify_method *sieve_enotify_method_register
(struct sieve_instance *svinst,
	const struct sieve_enotify_method_def *nmth_def)
{
	const struct sieve_extension *ntfy_ext =
		sieve_extension_get_by_name(svinst, "enotify");

	if ( ntfy_ext != NULL ) {
		struct ext_enotify_context *ectx =
			(struct ext_enotify_context *) ntfy_ext->context;

		return ext_enotify_method_register(svinst, ectx, nmth_def);
	}

	return NULL;
}
static int _read_extensions(struct sieve_binary_block *sblock)
{
	struct sieve_binary *sbin = sblock->sbin;
	sieve_size_t offset = 0;
	unsigned int i, count;
	bool result = 1;

	if ( !sieve_binary_read_unsigned(sblock, &offset, &count) )
		return -1;

	for ( i = 0; result > 0 && i < count; i++ ) {
		T_BEGIN {
			string_t *extension;
			const struct sieve_extension *ext;
			unsigned int version;

			if ( sieve_binary_read_string(sblock, &offset, &extension) ) {
				ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension));

				if ( ext == NULL ) {
					sieve_sys_error(sbin->svinst,
						"binary open: binary %s requires unknown extension `%s'",
						sbin->path, str_sanitize(str_c(extension), 128));
					result = 0;
				} else {
					struct sieve_binary_extension_reg *ereg = NULL;

					(void) sieve_binary_extension_register(sbin, ext, &ereg);
					if ( !sieve_binary_read_unsigned(sblock, &offset, &version) ||
						!sieve_binary_read_unsigned(sblock, &offset, &ereg->block_id) ) {
						result = -1;
					} else if ( !sieve_extension_version_is(ext, version) ) {
						sieve_sys_debug(sbin->svinst,
							"binary open: binary %s was compiled with different version "
							"of the `%s' extension (compiled v%d, expected v%d;"
							"automatically fixed when re-compiled)", sbin->path,
							sieve_extension_name(ext), version, sieve_extension_version(ext));
						result = 0;
					}
				}
			}	else
				result = -1;
		} T_END;
	}

	return result;
}
void sieve_enotify_method_unregister
(const struct sieve_enotify_method *nmth)
{
	struct sieve_instance *svinst = nmth->svinst;
	const struct sieve_extension *ntfy_ext =
		sieve_extension_get_by_name(svinst, "enotify");

	if ( ntfy_ext != NULL ) {
		struct ext_enotify_context *ectx =
			(struct ext_enotify_context *) ntfy_ext->context;
		int nmth_id = nmth->id;

		if ( nmth_id >= 0 && nmth_id < (int)array_count(&ectx->notify_methods) ) {
			struct sieve_enotify_method *nmth_mod =
				array_idx_modifiable(&ectx->notify_methods, nmth_id);

			nmth_mod->def = NULL;
		}
	}
}
Beispiel #4
0
static int cmd_test_config_reload_operation_execute
(const struct sieve_runtime_env *renv, sieve_size_t *address)
{
    const struct sieve_extension *ext;
    int opt_code = 0;
    string_t *extension = NULL;
    int ret;

    /*
     * Read operands
     */

    /* Optional operands */
    for (;;) {
        int opt;

        if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 )
            return SIEVE_EXEC_BIN_CORRUPT;

        if ( opt == 0 ) break;

        switch ( opt_code ) {
        case OPT_EXTENSION:
            ret = sieve_opr_string_read(renv, address, "extension", &extension);
            break;
        default:
            sieve_runtime_trace_error(renv, "unknown optional operand");
            ret = SIEVE_EXEC_BIN_CORRUPT;
        }

        if ( ret <= 0 ) return ret;
    }

    /*
     * Perform operation
     */

    if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
        sieve_runtime_trace(renv, 0,
                            "testsuite: test_config_reload command");
        sieve_runtime_trace_descend(renv);
    }

    if ( extension == NULL ) {
        if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
            sieve_runtime_trace(renv, 0,
                                "reload configuration for sieve engine");
        }

        sieve_settings_load(renv->svinst);

    } else {
        if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
            sieve_runtime_trace(renv, 0,
                                "reload configuration for extension `%s'",
                                str_c(extension));
        }

        ext = sieve_extension_get_by_name(renv->svinst, str_c(extension));
        if ( ext == NULL ) {
            testsuite_test_failf("test_config_reload: "
                                 "unknown extension '%s'", str_c(extension));
            return SIEVE_EXEC_OK;
        }

        sieve_extension_reload(ext);
    }

    return SIEVE_EXEC_OK;
}
Beispiel #5
0
static bool tst_ihave_validate
(struct sieve_validator *valdtr, struct sieve_command *tst)
{
	struct _capability {
		const struct sieve_extension *ext;
		struct sieve_ast_argument *arg;
	};

	struct sieve_ast_argument *arg = tst->first_positional;
	struct sieve_ast_argument *stritem;
	enum sieve_compile_flags cpflags = sieve_validator_compile_flags(valdtr);
	bool no_global = ( (cpflags & SIEVE_COMPILE_FLAG_NOGLOBAL) != 0 );
	ARRAY(struct _capability) capabilities;
	struct _capability capability;
	const struct _capability *caps;
	unsigned int i, count;
	bool all_known = TRUE;

	t_array_init(&capabilities, 64);

	tst->data = (void *) FALSE;

	/* Check stringlist argument */
	if ( !sieve_validate_positional_argument
		(valdtr, tst, arg, "capabilities", 1, SAAT_STRING_LIST) ) {
		return FALSE;
	}

	switch ( sieve_ast_argument_type(arg) ) {
	case SAAT_STRING:
		/* Single string */
		capability.arg = arg;
		capability.ext = sieve_extension_get_by_name
			(tst->ext->svinst, sieve_ast_argument_strc(arg));

		if ( capability.ext == NULL || (no_global && capability.ext->global)) {
			all_known = FALSE;

			ext_ihave_ast_add_missing_extension
				(tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(arg));
		} else {
			array_append(&capabilities, &capability, 1);
		}

		break;

	case SAAT_STRING_LIST:
		/* String list */
		stritem = sieve_ast_strlist_first(arg);

		while ( stritem != NULL ) {
			capability.arg = stritem;
			capability.ext = sieve_extension_get_by_name
				(tst->ext->svinst, sieve_ast_argument_strc(stritem));

			if ( capability.ext == NULL || (no_global && capability.ext->global)) {
				all_known = FALSE;

				ext_ihave_ast_add_missing_extension
					(tst->ext, tst->ast_node->ast, sieve_ast_argument_strc(stritem));
			} else {
				array_append(&capabilities, &capability, 1);
			}

			stritem = sieve_ast_strlist_next(stritem);
		}

		break;
	default:
		i_unreached();
	}

	if ( !all_known )
		return TRUE;

	/* RFC 5463, Section 4, page 4:
	 *
	 * The "ihave" extension is designed to be used with other extensions
	 * that add tests, actions, comparators, or arguments.  Implementations
	 * MUST NOT allow it to be used with extensions that change the
	 * underlying Sieve grammar, or extensions like encoded-character
	 * [RFC5228], or variables [RFC5229] that change how the content of
	 * Sieve scripts are interpreted.  The test MUST fail and the extension
	 * MUST NOT be enabled if such usage is attempted.
	 *
	 * FIXME: current implementation of this restriction is hardcoded and
	 * therefore highly inflexible
	 */
	caps = array_get(&capabilities, &count);
	for ( i = 0; i < count; i++ ) {
		if ( sieve_extension_name_is(caps[i].ext, "variables") ||
			sieve_extension_name_is(caps[i].ext, "encoded-character") )
			return TRUE;
	}

	/* Load all extensions */
	caps = array_get(&capabilities, &count);
	for ( i = 0; i < count; i++ ) {
		if ( !sieve_validator_extension_load
			(valdtr, tst, caps[i].arg, caps[i].ext) )
			return FALSE;
	}

	tst->data = (void *) TRUE;
	return TRUE;
}
		if ( sieve_extension_is(ext, spamtest_extension) ) {
			/* Register validator extension to warn for duplicate */
			sieve_validator_extension_register
				(valdtr, ext, &spamtest_validator_extension, NULL);
		}

		sieve_validator_register_command(valdtr, ext, &spamtest_test);
	}

	return TRUE;
}

static bool ext_spamtest_validator_extension_validate
(const struct sieve_extension *ext, struct sieve_validator *valdtr,
	void *context ATTR_UNUSED, struct sieve_ast_argument *require_arg)
{
	const struct sieve_extension *ext_spamtestplus =
		sieve_extension_get_by_name(ext->svinst, "spamtestplus");

	if ( ext_spamtestplus != NULL &&
		sieve_validator_extension_loaded(valdtr, ext_spamtestplus) ) {
		sieve_argument_validate_warning(valdtr, require_arg,
			"the spamtest and spamtestplus extensions should not be specified "
			"at the same time");
	}

	return TRUE;
}