Exemple #1
0
bool cmd_setactive(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct sieve_storage *storage = client->storage;
	const char *scriptname;
	struct sieve_script *script;
	int ret;

	/* <scriptname> */
	if ( !client_read_string_args(cmd, TRUE, 1, &scriptname) )
		return FALSE;

	/* Activate, or .. */
	if ( *scriptname != '\0' ) {
		string_t *errors = NULL;
		const char *errormsg = NULL;
		bool warnings = FALSE;
		bool success = TRUE;

		script = sieve_storage_open_script
			(storage, scriptname, NULL);
		if ( script == NULL ) {
			client_send_storage_error(client, storage);
			return TRUE;
		}

		if ( sieve_script_is_active(script) <= 0 ) {
			/* Script is first being activated; compile it again without the UPLOAD
			 * flag.
			 */
			T_BEGIN {
				struct sieve_error_handler *ehandler;
				enum sieve_compile_flags cpflags =
					SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_ACTIVATED;
				struct sieve_binary *sbin;
				enum sieve_error error;

				/* Prepare error handler */
				errors = str_new(default_pool, 1024);
				ehandler = sieve_strbuf_ehandler_create(client->svinst, errors, TRUE,
					client->set->managesieve_max_compile_errors);

				/* Compile */
				if ( (sbin=sieve_compile_script
					(script, ehandler, cpflags, &error)) == NULL ) {
					if (error != SIEVE_ERROR_NOT_VALID) {
						errormsg = sieve_script_get_last_error(script, &error);
						if ( error == SIEVE_ERROR_NONE )
							errormsg = NULL;
					}
					success = FALSE;
				} else {
					sieve_close(&sbin);
				}

				warnings = ( sieve_get_warnings(ehandler) > 0 );
				sieve_error_handler_unref(&ehandler);
			} T_END;
		}
static int
cmd_sieve_activate_run(struct doveadm_sieve_cmd_context *_ctx)
{
	struct doveadm_sieve_activate_cmd_context *ctx =
		(struct doveadm_sieve_activate_cmd_context *)_ctx;
	struct sieve_storage *storage = _ctx->storage;
	struct sieve_script *script;
	enum sieve_error error;
	int ret = 0;

	script = sieve_storage_open_script
		(storage, ctx->scriptname, NULL);
	if ( script == NULL ) {
		i_error("Failed to activate Sieve script: %s",
			sieve_storage_get_last_error(storage, &error));
		doveadm_sieve_cmd_failed_error(_ctx, error);
		return -1;
	}

	if ( sieve_script_is_active(script) <= 0 ) {
		/* Script is first being activated; compile it again without the UPLOAD
		 * flag.
		 */
		struct sieve_error_handler *ehandler;
		enum sieve_compile_flags cpflags =
			SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_ACTIVATED;
		struct sieve_binary *sbin;
		enum sieve_error error;

		/* Compile */
		ehandler = sieve_master_ehandler_create(ctx->ctx.svinst, NULL, 0);
		if ( (sbin=sieve_compile_script
			(script, ehandler, cpflags, &error)) == NULL ) {
			doveadm_sieve_cmd_failed_error(_ctx, error);
			ret = -1;
		} else {
			sieve_close(&sbin);
		}
		sieve_error_handler_unref(&ehandler);
	}

	/* Activate only when script is valid (or already active) */
	if ( ret == 0 ) {
		/* Refresh activation no matter what; this can also resolve some erroneous
		 * situations.
		 */
		ret = sieve_script_activate(script, (time_t)-1);
		if ( ret < 0 ) {
			i_error("Failed to activate Sieve script: %s",
				sieve_storage_get_last_error(storage, &error));
			doveadm_sieve_cmd_failed_error(_ctx, error);
			ret = -1;
		}
	}

	sieve_script_unref(&script);
	return ret;
}
static bool cmd_putscript_finish_parsing(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_putscript_context *ctx = cmd->context;
	const struct managesieve_arg *args;
	int ret;

	/* if error occurs, the CRLF is already read. */
	client->input_skip_line = FALSE;

	/* <script literal> */
	ret = managesieve_parser_read_args(ctx->save_parser, 0, 0, &args);
	if (ret == -1 || client->output->closed) {
		if (ctx->storage != NULL)
			client_send_command_error(cmd, NULL);
		cmd_putscript_finish(ctx);
		return TRUE;
	}
	if (ret < 0) {
		/* need more data */
		return FALSE;
	}

	if ( MANAGESIEVE_ARG_IS_EOL(&args[0]) ) {
		struct sieve_script *script;
		bool success = TRUE;

		/* Eat away the trailing CRLF */
		client->input_skip_line = TRUE;

		/* Obtain script object for uploaded script */
		script = sieve_storage_save_get_tempscript(ctx->save_ctx);

		/* Check result */
		if ( script == NULL ) {
			client_send_storage_error(client, ctx->storage);
			cmd_putscript_finish(ctx);
			return TRUE;
		}

		/* If quoted string, the size was not known until now */
		if ( ctx->script_size == 0 ) {
			if (sieve_script_get_size(script, &ctx->script_size) < 0) {
				client_send_storage_error(client, ctx->storage);
				cmd_putscript_finish(ctx);
				return TRUE;
			}
			/* Check quota; max size is already checked */
			if ( ctx->scriptname != NULL && !managesieve_quota_check_all
					(client, ctx->scriptname, ctx->script_size) ) {
				cmd_putscript_finish(ctx);
				return TRUE;
			}
		}

		/* Try to compile script */
		T_BEGIN {
			struct sieve_error_handler *ehandler;
			enum sieve_compile_flags cpflags =
				SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_UPLOADED;
			struct sieve_binary *sbin;
			enum sieve_error error;
			string_t *errors;

			/* Mark this as an activation when we are replacing the active script */
			if ( sieve_storage_save_will_activate(ctx->save_ctx) ) {
				cpflags |= SIEVE_COMPILE_FLAG_ACTIVATED;
			}

			/* Prepare error handler */
			errors = str_new(default_pool, 1024);
			ehandler = sieve_strbuf_ehandler_create(client->svinst, errors, TRUE,
				client->set->managesieve_max_compile_errors);

			/* Compile */
			if ( (sbin=sieve_compile_script
				(script, ehandler, cpflags, &error)) == NULL ) {
				if ( error != SIEVE_ERROR_NOT_VALID ) {
					const char *errormsg =
						sieve_script_get_last_error(script, &error);
					if ( error != SIEVE_ERROR_NONE )
						client_send_no(client, errormsg);
					else
						client_send_no(client, str_c(errors));
				} else {
					client_send_no(client, str_c(errors));
				}
				success = FALSE;
			} else {
				sieve_close(&sbin);

				/* Commit to save only when this is a putscript command */
				if ( ctx->scriptname != NULL ) {
					ret = sieve_storage_save_commit(&ctx->save_ctx);

					/* Check commit */
					if (ret < 0) {
						client_send_storage_error(client, ctx->storage);
						success = FALSE;
					}
				}
			}

			/* Finish up */
			cmd_putscript_finish(ctx);

			/* Report result to user */
			if ( success ) {
				if ( ctx->scriptname != NULL ) {
					client->put_count++;
					client->put_bytes += ctx->script_size;
				} else {
					client->check_count++;
					client->check_bytes += ctx->script_size;
				}

				if ( sieve_get_warnings(ehandler) > 0 )
					client_send_okresp(client, "WARNINGS", str_c(errors));
				else {
					if ( ctx->scriptname != NULL )
						client_send_ok(client, "PUTSCRIPT completed.");
					else
						client_send_ok(client, "Script checked successfully.");
				}
			}

			sieve_error_handler_unref(&ehandler);
			str_free(&errors);
		} T_END;

		return TRUE;
	}

	client_send_command_error(cmd, "Too many command arguments.");
	cmd_putscript_finish(ctx);
	return TRUE;
}
Exemple #4
0
int main(int argc, char **argv) 
{
	struct sieve_instance *svinst;
	const char *scriptfile, *dumpfile, *tracefile;
	struct sieve_trace_config tr_config;
	struct sieve_binary *sbin;
	const char *sieve_dir;
	bool log_stdout = FALSE;
	int ret, c;

	sieve_tool = sieve_tool_init
		("testsuite", &argc, &argv, "d:t:T:EDP:", TRUE);

	/* Parse arguments */
	scriptfile = dumpfile = tracefile = NULL;
	memset(&tr_config, 0, sizeof(tr_config));
	tr_config.level = SIEVE_TRLVL_ACTIONS;
	while ((c = sieve_tool_getopt(sieve_tool)) > 0) {
		switch (c) {
		case 'd':
			/* destination address */
			dumpfile = optarg;
			break;
		case 't':
			/* trace file */
			tracefile = optarg;
			break;
		case 'T':
			sieve_tool_parse_trace_option(&tr_config, optarg);
			break;
		case 'E':
			log_stdout = TRUE;
			break;
		default:
			print_help();
			i_fatal_status(EX_USAGE,
				"Unknown argument: %c", c);
			break;
		}
	}

	if ( optind < argc ) {
		scriptfile = t_strdup(argv[optind++]);
	} else {
		print_help();
		i_fatal_status(EX_USAGE, "Missing <scriptfile> argument");
	}
	
	if (optind != argc) {
		print_help();
		i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]);
	}

	/* Initialize mail user */
	sieve_tool_set_homedir(sieve_tool, t_abspath(""));
	
	/* Initialize settings environment */
	testsuite_settings_init();

	/* Currently needed for include (FIXME) */
	sieve_dir = strrchr(scriptfile, '/');
	if ( sieve_dir == NULL )
		sieve_dir= "./";
	else {
		sieve_dir = t_strdup_until(scriptfile, sieve_dir+1);
	}

	testsuite_setting_set
		("sieve_dir", t_strconcat(sieve_dir, "included", NULL));
	testsuite_setting_set
		("sieve_global_dir", t_strconcat(sieve_dir, "included-global", NULL));

	/* Finish testsuite initialization */
	svinst = sieve_tool_init_finish(sieve_tool, FALSE);	
	testsuite_init(svinst, log_stdout);

	printf("Test case: %s:\n\n", scriptfile);

	/* Compile sieve script */
	if ( (sbin = sieve_compile
		(svinst, scriptfile, NULL, testsuite_log_main_ehandler, NULL)) != NULL ) {
		struct ostream *tracestream = NULL;
		struct sieve_script_env scriptenv;

		/* Dump script */
		sieve_tool_dump_binary_to(sbin, dumpfile, FALSE);

		if ( tracefile != NULL )
			tracestream = sieve_tool_open_output_stream(tracefile);

		testsuite_mailstore_init();
		testsuite_message_init();

		memset(&scriptenv, 0, sizeof(scriptenv));
		scriptenv.user = sieve_tool_get_mail_user(sieve_tool);
		scriptenv.default_mailbox = "INBOX";
		scriptenv.hostname = "testsuite.example.com";
		scriptenv.postmaster_address = "*****@*****.**";
		scriptenv.username = sieve_tool_get_username(sieve_tool);
		scriptenv.smtp_open = testsuite_smtp_open;
		scriptenv.smtp_close = testsuite_smtp_close;
		scriptenv.trace_stream = tracestream;
		scriptenv.trace_config = tr_config;

		testsuite_scriptenv = &scriptenv;

		testsuite_result_init();

		/* Run the test */
		ret = testsuite_run
			(sbin, &testsuite_msgdata, &scriptenv, testsuite_log_main_ehandler);

		switch ( ret ) {
		case SIEVE_EXEC_OK:
			break;
		case SIEVE_EXEC_FAILURE:
		case SIEVE_EXEC_KEEP_FAILED:
			testsuite_testcase_fail("test script execution aborted due to error");
			break;
		case SIEVE_EXEC_BIN_CORRUPT:
			testsuite_testcase_fail("compiled test script binary is corrupt");
			break;
		default:
			testsuite_testcase_fail("unknown execution exit code");
		}

		sieve_close(&sbin);

		/* De-initialize message environment */
		testsuite_message_deinit();
		testsuite_mailstore_deinit();
		testsuite_result_deinit();

		if ( tracestream != NULL )
			o_stream_unref(&tracestream);

	} else {
		testsuite_testcase_fail("failed to compile testcase script");
	}

	/* De-initialize testsuite */
	testsuite_deinit();
	testsuite_settings_deinit();

	sieve_tool_deinit(&sieve_tool);

	if ( !testsuite_testcase_result() )
		return EXIT_FAILURE;

	return EXIT_SUCCESS;
}