static void folder_restore_session(struct folder_ref_info * ref_info) { chashiter * iter; mailsession * session; session = ref_info->folder->fld_session; for(iter = chash_begin(ref_info->msg_hash) ; iter != NULL ; iter = chash_next(ref_info->msg_hash, iter)) { chashdatum key; mailmessage * msg; chash_key(iter, &key); memcpy(&msg, key.data, sizeof(msg)); msg->msg_session = session; if (msg->msg_driver == imap_cached_message_driver) { struct imap_cached_session_state_data * imap_cached_data; mailmessage * ancestor_msg; imap_cached_data = ref_info->folder->fld_session->sess_data; ancestor_msg = msg->msg_data; ancestor_msg->msg_session = imap_cached_data->imap_ancestor; } } }
static void storage_debug(struct storage_ref_info * storage_ref_info, FILE * f) { chashiter * iter; fprintf(f, "storage debug -- begin\n"); if (storage_ref_info->storage == NULL) { fprintf(f, "NULL storage\n"); } else { if (storage_ref_info->storage->sto_id != NULL) fprintf(f, "storage %s\n", storage_ref_info->storage->sto_id); else fprintf(f, "storage [no name]\n"); } fprintf(f, "folder count: %i\n", chash_count(storage_ref_info->folder_ref_info)); for(iter = chash_begin(storage_ref_info->folder_ref_info) ; iter != NULL ; iter = chash_next(storage_ref_info->folder_ref_info, iter)) { chashdatum data; struct folder_ref_info * folder_ref_info; chash_value(iter, &data); folder_ref_info = data.data; folder_debug(folder_ref_info, f); } fprintf(f, "storage debug -- end\n"); }
static void storage_disconnect(struct storage_ref_info * ref_info) { chashiter * iter; /* disconnect folders */ while ((iter = chash_begin(ref_info->folder_ref_info)) != NULL) { chashdatum key; struct mailfolder * folder; chash_key(iter, &key); memcpy(&folder, key.data, sizeof(folder)); storage_folder_disconnect(ref_info, folder); } /* disconnect storage */ do_storage_disconnect(ref_info); }
void libetpan_engine_debug(struct mailengine * engine, FILE * f) { chashiter * iter; fprintf(f, "mail engine debug -- begin\n"); for(iter = chash_begin(engine->storage_hash) ; iter != NULL ; iter = chash_next(engine->storage_hash, iter)) { chashdatum data; struct storage_ref_info * storage_ref_info; chash_value(iter, &data); storage_ref_info = data.data; storage_debug(storage_ref_info, f); } fprintf(f, "mail engine debug -- end\n"); }
static void storage_restore_message_session(struct storage_ref_info * ref_info) { chashiter * iter; for(iter = chash_begin(ref_info->folder_ref_info) ; iter != NULL ; iter = chash_next(ref_info->folder_ref_info, iter)) { chashdatum data; struct folder_ref_info * folder_ref_info; chash_value(iter, &data); folder_ref_info = data.data; if (folder_ref_info->lost_session) { if (folder_ref_info->folder->fld_session != NULL) { /* restore folder session */ folder_restore_session(folder_ref_info); folder_ref_info->lost_session = 0; } } } }
static int smime_decrypt(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime ** result) { char smime_filename[PATH_MAX]; char quoted_smime_filename[PATH_MAX]; char description_filename[PATH_MAX]; char decrypted_filename[PATH_MAX]; char command[PATH_MAX]; struct mailmime * description_mime; struct mailmime * decrypted_mime; int r; int res; int sign_ok; struct mailmime * multipart; char * smime_cert; char * smime_key; char quoted_smime_cert[PATH_MAX]; char quoted_smime_key[PATH_MAX]; char * email; chashiter * iter; /* fetch the whole multipart and write it to a file */ r = mailprivacy_fetch_mime_body_to_file(privacy, smime_filename, sizeof(smime_filename), msg, mime); if (r != MAIL_NO_ERROR) { res = r; goto err; } /* we are in a safe directory */ r = mailprivacy_get_tmp_filename(privacy, decrypted_filename, sizeof(decrypted_filename)); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto unlink_smime; } /* description */ r = mailprivacy_get_tmp_filename(privacy, description_filename, sizeof(description_filename)); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto unlink_decrypted; } sign_ok = 0; for(iter = chash_begin(private_keys) ; iter != NULL ; iter = chash_next(private_keys, iter)) { chashdatum key; char email_buf[BUF_SIZE]; chash_key(iter, &key); if (key.len >= sizeof(email_buf)) continue; strncpy(email_buf, key.data, key.len); email_buf[key.len] = '\0'; email = email_buf; /* get encryption key */ smime_key = get_private_key_file(email); smime_cert = get_cert_file(email); if ((smime_cert == NULL) || (smime_key == NULL)) { res = MAIL_ERROR_INVAL; goto unlink_description; } r = mail_quote_filename(quoted_smime_cert, sizeof(quoted_smime_cert), smime_cert); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } r = mail_quote_filename(quoted_smime_key, sizeof(quoted_smime_key), smime_key); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } /* run the command */ r = mail_quote_filename(quoted_smime_filename, sizeof(quoted_smime_filename), smime_filename); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } sign_ok = 0; snprintf(command, sizeof(command), "openssl smime -decrypt -passin fd:0 -in '%s' -inkey '%s' -recip '%s'", quoted_smime_filename, quoted_smime_key, quoted_smime_cert); unlink(description_filename); r = smime_command_passphrase(privacy, msg, command, email, decrypted_filename, description_filename); switch (r) { case NO_ERROR_SMIME: sign_ok = 1; break; case ERROR_SMIME_CHECK: case ERROR_SMIME_NOPASSPHRASE: sign_ok = 0; break; case ERROR_SMIME_COMMAND: res = MAIL_ERROR_COMMAND; goto unlink_description; case ERROR_SMIME_FILE: res = MAIL_ERROR_FILE; goto unlink_description; } if (sign_ok) { break; } } if (!sign_ok) { if (chash_count(private_keys) == 0) { FILE * description_f; description_f = mailprivacy_get_tmp_file(privacy, description_filename, sizeof(description_filename)); if (description_f == NULL) { res = MAIL_ERROR_FILE; goto unlink_decrypted; } fprintf(description_f, SMIME_DECRYPT_FAILED); fclose(description_f); } } else { mailprivacy_smime_encryption_id_list_clear(privacy, msg); } /* building multipart */ r = mailmime_new_with_content("multipart/x-decrypted", NULL, &multipart); if (r != MAILIMF_NO_ERROR) { res = MAIL_ERROR_MEMORY; goto unlink_description; } /* building the description part */ description_mime = mailprivacy_new_file_part(privacy, description_filename, "text/plain", MAILMIME_MECHANISM_8BIT); if (description_mime == NULL) { mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } /* adds the description part */ r = mailmime_smart_add_part(multipart, description_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(description_mime); mailmime_free(description_mime); mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } /* building the decrypted part */ r = mailprivacy_get_part_from_file(privacy, 1, 0, decrypted_filename, &decrypted_mime); if (r == MAIL_NO_ERROR) { /* adds the decrypted part */ r = mailmime_smart_add_part(multipart, decrypted_mime); if (r != MAIL_NO_ERROR) { mailprivacy_mime_clear(decrypted_mime); mailmime_free(decrypted_mime); mailprivacy_mime_clear(multipart); mailmime_free(multipart); res = MAIL_ERROR_MEMORY; goto unlink_description; } } unlink(description_filename); unlink(decrypted_filename); unlink(smime_filename); * result = multipart; return MAIL_NO_ERROR; unlink_description: unlink(description_filename); unlink_decrypted: unlink(decrypted_filename); unlink_smime: unlink(smime_filename); err: return res; }
static int folder_update_msg_list(struct folder_ref_info * ref_info, struct mailmessage_list ** p_new_msg_list, struct mailmessage_list ** p_lost_msg_list) { int r; int res; struct mailmessage_list * new_env_list; unsigned int i; carray * lost_msg_tab; struct mailmessage_list * lost_msg_list; unsigned int free_start_index; chashiter * iter; unsigned int lost_count; r = mailfolder_get_messages_list(ref_info->folder, &new_env_list); if (r != MAIL_NO_ERROR) { res = r; goto err; } for(iter = chash_begin(ref_info->msg_hash) ; iter != NULL ; iter = chash_next(ref_info->msg_hash, iter)) { struct message_ref_elt * msg_ref; chashdatum data; chash_value(iter, &data); msg_ref = data.data; msg_ref->lost = 1; } lost_count = chash_count(ref_info->msg_hash); for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) { mailmessage * msg; mailmessage * old_msg; msg = carray_get(new_env_list->msg_tab, i); if (msg->msg_uid == NULL) continue; old_msg = folder_info_get_msg_by_uid(ref_info, msg->msg_uid); if (old_msg != NULL) { struct message_ref_elt * msg_ref; /* replace old message */ old_msg->msg_index = msg->msg_index; carray_set(new_env_list->msg_tab, i, old_msg); mailmessage_free(msg); msg_ref = folder_info_get_msg_ref(ref_info, old_msg); msg_ref->lost = 0; lost_count --; } else { /* set new message */ r = folder_message_add(ref_info, msg); if (r != MAIL_NO_ERROR) { free_start_index = i; res = r; goto free_remaining; } } } /* build the table of lost messages */ lost_msg_tab = carray_new(lost_count); if (lost_msg_tab == NULL) { res = MAIL_ERROR_MEMORY; goto free_env_list; } carray_set_size(lost_msg_tab, lost_count); i = 0; for(iter = chash_begin(ref_info->msg_hash) ; iter != NULL ; iter = chash_next(ref_info->msg_hash, iter)) { struct message_ref_elt * msg_ref; chashdatum key; chashdatum value; mailmessage * msg; chash_key(iter, &key); memcpy(&msg, key.data, sizeof(msg)); chash_value(iter, &value); msg_ref = value.data; if (msg_ref->lost) { carray_set(lost_msg_tab, i, msg); i ++; } } lost_msg_list = mailmessage_list_new(lost_msg_tab); if (lost_msg_list == NULL) { res = MAIL_ERROR_MEMORY; goto free_lost_msg_tab; } /* reference messages */ for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(new_env_list->msg_tab, i); folder_message_ref(ref_info, msg); } * p_new_msg_list = new_env_list; * p_lost_msg_list = lost_msg_list; return MAIL_NO_ERROR; free_lost_msg_tab: carray_free(lost_msg_tab); free_env_list: for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) { mailmessage * msg; struct message_ref_elt * msg_ref; msg = carray_get(new_env_list->msg_tab, i); msg_ref = folder_info_get_msg_ref(ref_info, msg); if (msg_ref != NULL) { if (msg_ref->ref_count == 0) folder_message_remove(ref_info, msg); } } carray_set_size(new_env_list->msg_tab, 0); mailmessage_list_free(new_env_list); goto err; free_remaining: for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) { mailmessage * msg; struct message_ref_elt * msg_ref; msg = carray_get(new_env_list->msg_tab, i); msg_ref = folder_info_get_msg_ref(ref_info, msg); if (msg_ref != NULL) { if (msg_ref->ref_count == 0) folder_message_remove(ref_info, msg); } } for(i = free_start_index ; i < carray_count(new_env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(new_env_list->msg_tab, i); mailmessage_free(msg); } carray_set_size(new_env_list->msg_tab, 0); mailmessage_list_free(new_env_list); err: return res; }