diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 09d6a69bb19c23f334c3dbc9eda261d145e6d558..6c559d6442add6a701fd78437f03a6202e1c5e3e 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -109,7 +109,7 @@ static int cmd_discard_operation_execute "discard action; cancel implicit keep"); if ( sieve_result_add_action - (renv, NULL, &act_discard, NULL, NULL, 0) < 0 ) + (renv, NULL, &act_discard, NULL, NULL, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index bd9482579d6c0a5a51ab9b503148efcad01be0bf..05069739712a86445576f150fe962c5a7ef4f053 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -107,8 +107,6 @@ static int cmd_keep_operation_execute if ( sieve_result_add_keep(renv, slist) < 0 ) return SIEVE_EXEC_FAILURE; - sieve_message_snapshot(renv->msgctx); - return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 6b1e1f35e98c49d4d59b28a028160a1559f9335a..bf3272e4dc8044ad434bb0e5f0676947aee344e4 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -248,11 +248,9 @@ static int cmd_redirect_operation_execute if ( sieve_result_add_action (renv, NULL, &act_redirect, slist, (void *) act, - svinst->max_redirects) < 0 ) + svinst->max_redirects, TRUE) < 0 ) return SIEVE_EXEC_FAILURE; - sieve_message_snapshot(renv->msgctx); - return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index d274ff4e21f3fa235afe5d90f54f6cca7068d74a..6e2fde2fe9227bebd095539dd672567b98c5f481 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -306,7 +306,7 @@ static int ext_reject_operation_execute act->ereject = ( sieve_operation_is(oprtn, ereject_operation) ); if ( sieve_result_add_action - (renv, this_ext, &act_reject, slist, (void *) act, 0) < 0 ) + (renv, this_ext, &act_reject, slist, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/plugins/body/ext-body-common.c b/src/lib-sieve/plugins/body/ext-body-common.c index 92599258c425dd40a01d4a18f73071c61306eef5..3617abf047d872707b7db14f7a893f4c37919971 100644 --- a/src/lib-sieve/plugins/body/ext-body-common.c +++ b/src/lib-sieve/plugins/body/ext-body-common.c @@ -192,9 +192,10 @@ static const char *_parse_content_type(const struct message_header_line *hdr) * Add requested message body parts to the cache that are missing. */ static bool ext_body_parts_add_missing -(const struct sieve_message_data *msgdata, struct ext_body_message_context *ctx, +(struct sieve_message_context *msgctx, struct ext_body_message_context *ctx, const char * const *content_types, bool decode_to_plain) { + struct mail *mail = sieve_message_get_mail(msgctx); struct ext_body_part_cached *body_part = NULL, *header_part = NULL; struct message_parser_ctx *parser; struct message_decoder_context *decoder; @@ -212,9 +213,9 @@ static bool ext_body_parts_add_missing } /* Get the message stream */ - if ( mail_get_stream(msgdata->mail, NULL, NULL, &input) < 0 ) + if ( mail_get_stream(mail, NULL, NULL, &input) < 0 ) return FALSE; - //if (mail_get_parts(msgdata->mail, &parts) < 0) + //if (mail_get_parts(mail, &parts) < 0) // return FALSE; buffer_set_used_size(ctx->tmp_buffer, 0); @@ -395,7 +396,7 @@ static bool ext_body_get_content T_BEGIN { /* Fill the return_body_parts array */ if ( !ext_body_parts_add_missing - (renv->msgdata, ctx, content_types, decode_to_plain != 0) ) + (renv->msgctx, ctx, content_types, decode_to_plain != 0) ) result = FALSE; } T_END; @@ -419,7 +420,7 @@ static bool ext_body_get_raw buffer_t *buf; if ( ctx->raw_body == NULL ) { - struct mail *mail = renv->msgdata->mail; + struct mail *mail = sieve_message_get_mail(renv->msgctx); struct istream *input; struct message_size hdr_size, body_size; const unsigned char *data; diff --git a/src/lib-sieve/plugins/enotify/cmd-notify.c b/src/lib-sieve/plugins/enotify/cmd-notify.c index e68d2f16d6cd20bd243aead99f8364fdb1136b5c..2a5730ccd9de42be84f9998d45d193573528a096 100644 --- a/src/lib-sieve/plugins/enotify/cmd-notify.c +++ b/src/lib-sieve/plugins/enotify/cmd-notify.c @@ -487,7 +487,7 @@ static int cmd_notify_operation_execute act->from = p_strdup(pool, str_c(from)); if ( sieve_result_add_action - (renv, this_ext, &act_notify, slist, (void *) act, 0) < 0 ) + (renv, this_ext, &act_notify, slist, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c index 9c129121fe45b570a453e6143021684d3ff7f453..09bdc8c5666cba7b8e792b1ab67c9d1b71efe9ad 100644 --- a/src/lib-sieve/plugins/notify/cmd-notify.c +++ b/src/lib-sieve/plugins/notify/cmd-notify.c @@ -554,7 +554,7 @@ static int cmd_notify_operation_execute } if ( sieve_result_add_action - (renv, this_ext, &act_notify_old, NULL, (void *) act, 0) < 0 ) + (renv, this_ext, &act_notify_old, NULL, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; } diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 4a81b5cde9848cf1f8af7c334c344b9d03bdb33f..e6115f3ebed74bdb94a321d64570d2840439db67 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -728,7 +728,7 @@ static int ext_vacation_operation_execute } if ( sieve_result_add_action - (renv, this_ext, &act_vacation, slist, (void *) act, 0) < 0 ) + (renv, this_ext, &act_vacation, slist, (void *) act, 0, FALSE) < 0 ) return SIEVE_EXEC_FAILURE; return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index bb610a4e1636f9afab34467e46519bcecdac1af0..452389a7cbd8d7b2326046c6a2d0711d4c1498d9 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -231,8 +231,8 @@ int sieve_act_store_add_to_result act = p_new(pool, struct act_store_context, 1); act->mailbox = p_strdup(pool, mailbox); - return sieve_result_add_action(renv, NULL, &act_store, seffects, - (void *) act, 0); + return sieve_result_add_action + (renv, NULL, &act_store, seffects, (void *)act, 0, TRUE); } void sieve_act_store_add_flags diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c index fe92dfe2a45dc1e3bb8c2adc659123805964d8d3..0d506399b77c3906dd60cf9f4bd4873292bd8f8c 100644 --- a/src/lib-sieve/sieve-message.c +++ b/src/lib-sieve/sieve-message.c @@ -7,7 +7,12 @@ #include "array.h" #include "str.h" #include "str-sanitize.h" +#include "istream.h" #include "mail-storage.h" +#include "mail-user.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "raw-storage.h" #include "edit-mail.h" @@ -39,12 +44,21 @@ const char *sieve_message_get_new_id * Message context */ +struct sieve_message_version { + struct mail *mail; + struct mailbox *box; + struct mailbox_transaction_context *trans; + struct edit_mail *edit_mail; +}; + struct sieve_message_context { pool_t pool; + pool_t context_pool; int refcount; struct sieve_instance *svinst; + struct mail_user *mail_user; const struct sieve_message_data *msgdata; /* Normalized envelope addresses */ @@ -55,9 +69,10 @@ struct sieve_message_context { const struct sieve_address *envelope_orig_recipient; const struct sieve_address *envelope_final_recipient; - /* Edited mail struct */ + /* Message versioning */ - struct edit_mail *edit_mail; + struct mail_user *raw_mail_user; + ARRAY_DEFINE(versions, struct sieve_message_version); /* Context data for extensions */ ARRAY_DEFINE(ext_contexts, void *); @@ -65,18 +80,63 @@ struct sieve_message_context { unsigned int edit_snapshot:1; }; +/* + * Message versions + */ + +static inline struct sieve_message_version *sieve_message_version_new +(struct sieve_message_context *msgctx) +{ + return array_append_space(&msgctx->versions); +} + +static inline struct sieve_message_version *sieve_message_version_get +(struct sieve_message_context *msgctx) +{ + struct sieve_message_version *versions; + unsigned int count; + + versions = array_get_modifiable(&msgctx->versions, &count); + if ( count == 0 ) + return array_append_space(&msgctx->versions); + + return &versions[count-1]; +} + +static inline void sieve_message_version_free +(struct sieve_message_version *version) +{ + if ( version->edit_mail != NULL ) { + edit_mail_unwrap(&version->edit_mail); + version->edit_mail = NULL; + } + + if ( version->mail != NULL ) { + mail_free(&version->mail); + mailbox_transaction_rollback(&version->trans); + mailbox_free(&version->box); + version->mail = NULL; + } +} + +/* + * Message context object + */ + struct sieve_message_context *sieve_message_context_create -(struct sieve_instance *svinst, const struct sieve_message_data *msgdata) +(struct sieve_instance *svinst, struct mail_user *mail_user, + const struct sieve_message_data *msgdata) { struct sieve_message_context *msgctx; - + msgctx = i_new(struct sieve_message_context, 1); msgctx->refcount = 1; msgctx->svinst = svinst; + msgctx->mail_user = mail_user; msgctx->msgdata = msgdata; - sieve_message_context_flush(msgctx); + sieve_message_context_reset(msgctx); return msgctx; } @@ -86,50 +146,69 @@ void sieve_message_context_ref(struct sieve_message_context *msgctx) msgctx->refcount++; } -void sieve_message_context_unref(struct sieve_message_context **msgctx) +static void sieve_message_context_clear(struct sieve_message_context *msgctx) { + struct sieve_message_version *versions; + unsigned int count, i; + + if ( msgctx->pool != NULL ) { + versions = array_get_modifiable(&msgctx->versions, &count); + + for ( i = 0; i < count; i++ ) { + sieve_message_version_free(&versions[i]); + } + + pool_unref(&(msgctx->pool)); + } + + msgctx->envelope_orig_recipient = NULL; + msgctx->envelope_final_recipient = NULL; + msgctx->envelope_sender = NULL; + msgctx->envelope_parsed = FALSE; +} + +void sieve_message_context_unref(struct sieve_message_context **msgctx) +{ i_assert((*msgctx)->refcount > 0); if (--(*msgctx)->refcount != 0) return; - - pool_unref(&((*msgctx)->pool)); - - if ( (*msgctx)->edit_mail != NULL ) - edit_mail_unwrap(&(*msgctx)->edit_mail); + if ( (*msgctx)->raw_mail_user != NULL ) + mail_user_unref(&(*msgctx)->raw_mail_user); + + sieve_message_context_clear(*msgctx); + i_free(*msgctx); *msgctx = NULL; } -void sieve_message_context_flush(struct sieve_message_context *msgctx) +static void sieve_message_context_flush(struct sieve_message_context *msgctx) { - pool_t pool; + if ( msgctx->context_pool != NULL ) + pool_unref(&(msgctx->context_pool)); + + msgctx->context_pool = + pool_alloconly_create("sieve_message_context_data", 1024); - if ( msgctx->pool != NULL ) { - pool_unref(&msgctx->pool); - } + p_array_init(&msgctx->ext_contexts, msgctx->context_pool, + sieve_extensions_get_count(msgctx->svinst)); +} - pool = pool_alloconly_create("sieve_message_context", 1024); - msgctx->pool = pool; +void sieve_message_context_reset(struct sieve_message_context *msgctx) +{ + sieve_message_context_clear(msgctx); - msgctx->envelope_orig_recipient = NULL; - msgctx->envelope_final_recipient = NULL; - msgctx->envelope_sender = NULL; - msgctx->envelope_parsed = FALSE; + msgctx->pool = pool_alloconly_create("sieve_message_context", 1024); - p_array_init(&msgctx->ext_contexts, pool, - sieve_extensions_get_count(msgctx->svinst)); + p_array_init(&msgctx->versions, msgctx->pool, 4); - if ( msgctx->edit_mail != NULL ) { - edit_mail_unwrap(&msgctx->edit_mail); - msgctx->edit_mail = NULL; - } + sieve_message_context_flush(msgctx); } pool_t sieve_message_context_pool(struct sieve_message_context *msgctx) { - return msgctx->pool; + return msgctx->context_pool; } /* Extension support */ @@ -261,29 +340,93 @@ const char *sieve_message_get_sender return sieve_address_to_string(msgctx->envelope_sender); } -/* Mail */ +/* + * Mail + */ + +int sieve_message_substitute +(struct sieve_message_context *msgctx, struct istream *input) +{ + static const char *wanted_headers[] = { + "From", "Message-ID", "Subject", "Return-Path", NULL + }; + struct mail_user *mail_user = msgctx->mail_user; + struct sieve_message_version *version; + struct mailbox_header_lookup_ctx *headers_ctx; + struct mailbox *box = NULL; + int ret; + + if ( msgctx->raw_mail_user == NULL ) { + void **sets = master_service_settings_get_others(master_service); + + msgctx->raw_mail_user = + raw_storage_create_from_set(mail_user->set_info, sets[0]); + } + + i_stream_seek(input, 0); + ret = raw_mailbox_alloc_stream(msgctx->raw_mail_user, input, (time_t)-1, + sieve_message_get_sender(msgctx), &box); + + if ( ret < 0 ) { + sieve_sys_error(msgctx->svinst, "can't open substituted mail as raw: %s", + mailbox_get_last_error(box, NULL)); + return -1; + } + + if ( msgctx->edit_snapshot ) { + version = sieve_message_version_new(msgctx); + } else { + version = sieve_message_version_get(msgctx); + sieve_message_version_free(version); + } + + version->box = box; + version->trans = mailbox_transaction_begin(box, 0); + headers_ctx = mailbox_header_lookup_init(box, wanted_headers); + version->mail = mail_alloc(version->trans, 0, headers_ctx); + mailbox_header_lookup_unref(&headers_ctx); + mail_set_seq(version->mail, 1); + + sieve_message_context_flush(msgctx); + + msgctx->edit_snapshot = FALSE; + + return 1; +} struct mail *sieve_message_get_mail (struct sieve_message_context *msgctx) { - if ( msgctx->edit_mail == NULL ) + const struct sieve_message_version *versions; + unsigned int count; + + versions = array_get(&msgctx->versions, &count); + if ( count == 0 ) return msgctx->msgdata->mail; - return edit_mail_get_mail(msgctx->edit_mail); + if ( versions[count-1].edit_mail != NULL ) + return edit_mail_get_mail(versions[count-1].edit_mail); + + return versions[count-1].mail; } struct edit_mail *sieve_message_edit (struct sieve_message_context *msgctx) { - if ( msgctx->edit_mail == NULL ) { - msgctx->edit_mail = edit_mail_wrap(msgctx->msgdata->mail); + struct sieve_message_version *version; + + version = sieve_message_version_get(msgctx); + + if ( version->edit_mail == NULL ) { + version->edit_mail = edit_mail_wrap + (( version->mail == NULL ? msgctx->msgdata->mail : version->mail )); } else if ( msgctx->edit_snapshot ) { - msgctx->edit_mail = edit_mail_snapshot(msgctx->edit_mail); + version->edit_mail = edit_mail_snapshot(version->edit_mail); } msgctx->edit_snapshot = FALSE; - return msgctx->edit_mail; + return version->edit_mail; } void sieve_message_snapshot diff --git a/src/lib-sieve/sieve-message.h b/src/lib-sieve/sieve-message.h index 5b61b7d963423e58cd1d022eb011d801d0ef58ef..84778ccd0faaf414729132bd2cce16700708a0b3 100644 --- a/src/lib-sieve/sieve-message.h +++ b/src/lib-sieve/sieve-message.h @@ -18,11 +18,12 @@ const char *sieve_message_get_new_id struct sieve_message_context; struct sieve_message_context *sieve_message_context_create - (struct sieve_instance *svinst, const struct sieve_message_data *msgdata); + (struct sieve_instance *svinst, struct mail_user *mail_user, + const struct sieve_message_data *msgdata); void sieve_message_context_ref(struct sieve_message_context *msgctx); void sieve_message_context_unref(struct sieve_message_context **msgctx); -void sieve_message_context_flush(struct sieve_message_context *msgctx); +void sieve_message_context_reset(struct sieve_message_context *msgctx); pool_t sieve_message_context_pool (struct sieve_message_context *msgctx); @@ -58,6 +59,8 @@ const char *sieve_message_get_sender struct mail *sieve_message_get_mail (struct sieve_message_context *msgctx); +int sieve_message_substitute + (struct sieve_message_context *msgctx, struct istream *input); struct edit_mail *sieve_message_edit (struct sieve_message_context *msgctx); void sieve_message_snapshot diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index eb720e3202bcf99f4b3583afc0a786e976e8a308..df7ba121ac230cb265ae36a68bf01043e065efd1 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -117,7 +117,8 @@ struct sieve_result *sieve_result_create result->action_env.result = result; result->action_env.scriptenv = senv; result->action_env.msgdata = msgdata; - result->action_env.msgctx = sieve_message_context_create(svinst, msgdata); + result->action_env.msgctx = sieve_message_context_create + (svinst, senv->user, msgdata); result->keep_action.def = &act_store; result->keep_action.ext = NULL; @@ -448,13 +449,12 @@ static int _sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_extension *ext, const struct sieve_action_def *act_def, struct sieve_side_effects_list *seffects, - void *context, unsigned int instance_limit, bool keep) + void *context, unsigned int instance_limit, bool preserve_mail, bool keep) { int ret = 0; unsigned int instance_count = 0; struct sieve_instance *svinst = renv->svinst; struct sieve_result *result = renv->result; - struct mail *mail = sieve_message_get_mail(renv->msgctx); struct sieve_result_action *raction = NULL, *kaction = NULL; struct sieve_action action; @@ -584,7 +584,6 @@ static int _sieve_result_add_action raction->action.def = act_def; raction->action.ext = ext; raction->action.location = p_strdup(result->pool, action.location); - raction->action.mail = mail; raction->keep = keep; if ( raction->prev == NULL ) { @@ -648,6 +647,13 @@ static int _sieve_result_add_action } } } + + if ( preserve_mail ) { + raction->action.mail = sieve_message_get_mail(renv->msgctx); + sieve_message_snapshot(renv->msgctx); + } else { + raction->action.mail = NULL; + } return 0; } @@ -655,11 +661,11 @@ static int _sieve_result_add_action int sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_extension *ext, const struct sieve_action_def *act_def, - struct sieve_side_effects_list *seffects, - void *context, unsigned int instance_limit) + struct sieve_side_effects_list *seffects, void *context, + unsigned int instance_limit, bool preserve_mail) { - return _sieve_result_add_action - (renv, ext, act_def, seffects, context, instance_limit, FALSE); + return _sieve_result_add_action(renv, ext, act_def, seffects, context, + instance_limit, preserve_mail, FALSE); } int sieve_result_add_keep @@ -667,7 +673,7 @@ int sieve_result_add_keep { return _sieve_result_add_action (renv, renv->result->keep_action.ext, renv->result->keep_action.def, - seffects, NULL, 0, TRUE); + seffects, NULL, 0, TRUE, TRUE); } void sieve_result_set_keep_action diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index 7715c3cb49b3a514fe73c4f4d0bcc8cd69077727..23a0c1b20ba772df50d677c0a12ac42996653512 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -117,8 +117,8 @@ void sieve_result_add_implicit_side_effect int sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_extension *ext, const struct sieve_action_def *act_def, - struct sieve_side_effects_list *seffects, - void *context, unsigned int instance_limit); + struct sieve_side_effects_list *seffects, void *context, + unsigned int instance_limit, bool preserve_mail); int sieve_result_add_keep (const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects); diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c index 176255fc6b4f179961a398467d4e0562453792d5..1a0419c56263d0a2ed8fac5cca1a4e78bf1dde12 100644 --- a/src/testsuite/testsuite-message.c +++ b/src/testsuite/testsuite-message.c @@ -91,7 +91,7 @@ void testsuite_message_init(void) void testsuite_message_set_string (const struct sieve_runtime_env *renv, string_t *message) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); testsuite_mail = sieve_tool_open_data_as_mail(sieve_tool, message); testsuite_message_set_data(testsuite_mail); @@ -100,7 +100,7 @@ void testsuite_message_set_string void testsuite_message_set_file (const struct sieve_runtime_env *renv, const char *file_path) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); testsuite_mail = sieve_tool_open_file_as_mail(sieve_tool, file_path); testsuite_message_set_data(testsuite_mail); @@ -109,7 +109,7 @@ void testsuite_message_set_file void testsuite_message_set_mail (const struct sieve_runtime_env *renv, struct mail *mail) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); testsuite_message_set_data(mail); } @@ -122,7 +122,7 @@ void testsuite_message_deinit(void) void testsuite_envelope_set_sender (const struct sieve_runtime_env *renv, const char *value) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); str_truncate(envelope_from, 0); @@ -135,7 +135,7 @@ void testsuite_envelope_set_sender void testsuite_envelope_set_recipient (const struct sieve_runtime_env *renv, const char *value) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); str_truncate(envelope_to, 0); @@ -149,7 +149,7 @@ void testsuite_envelope_set_recipient void testsuite_envelope_set_orig_recipient (const struct sieve_runtime_env *renv, const char *value) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); str_truncate(envelope_orig_to, 0); @@ -162,7 +162,7 @@ void testsuite_envelope_set_orig_recipient void testsuite_envelope_set_auth_user (const struct sieve_runtime_env *renv, const char *value) { - sieve_message_context_flush(renv->msgctx); + sieve_message_context_reset(renv->msgctx); str_truncate(envelope_auth, 0);