void mailprivacy_prepare_mime(struct mailmime * mime) { clistiter * cur; switch (mime->mm_type) { case MAILMIME_SINGLE: if (mime->mm_data.mm_single != NULL) { prepare_mime_single(mime); } break; case MAILMIME_MULTIPLE: for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { struct mailmime * child; child = clist_content(cur); mailprivacy_prepare_mime(child); } break; case MAILMIME_MESSAGE: if (mime->mm_data.mm_message.mm_msg_mime) { mailprivacy_prepare_mime(mime->mm_data.mm_message.mm_msg_mime); } break; } }
static int smime_encrypt(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime ** result) { char encrypted_filename[PATH_MAX]; int res; int r; int col; char description_filename[PATH_MAX]; char decrypted_filename[PATH_MAX]; FILE * decrypted_f; char command[PATH_MAX]; char quoted_decrypted_filename[PATH_MAX]; struct mailmime * encrypted_mime; struct mailmime * root; struct mailimf_fields * fields; char recipient[PATH_MAX]; root = mime; while (root->mm_parent != NULL) root = root->mm_parent; fields = NULL; if (root->mm_type == MAILMIME_MESSAGE) fields = root->mm_data.mm_message.mm_fields; /* recipient */ r = collect_smime_cert(recipient, sizeof(recipient), fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } /* part to encrypt */ /* encode quoted printable all text parts */ mailprivacy_prepare_mime(mime); decrypted_f = mailprivacy_get_tmp_file(privacy, decrypted_filename, sizeof(decrypted_filename)); if (decrypted_f == NULL) { res = MAIL_ERROR_FILE; goto err; } col = 0; r = mailmime_write(decrypted_f, &col, mime); if (r != MAILIMF_NO_ERROR) { fclose(decrypted_f); res = MAIL_ERROR_FILE; goto unlink_decrypted; } fclose(decrypted_f); /* prepare destination file for encryption */ r = mailprivacy_get_tmp_filename(privacy, encrypted_filename, sizeof(encrypted_filename)); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto unlink_decrypted; } r = mailprivacy_get_tmp_filename(privacy, description_filename, sizeof(description_filename)); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto unlink_encrypted; } r = mail_quote_filename(quoted_decrypted_filename, sizeof(quoted_decrypted_filename), decrypted_filename); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } snprintf(command, sizeof(command), "openssl smime -encrypt -in '%s' %s", quoted_decrypted_filename, recipient); r = smime_command_passphrase(privacy, msg, command, NULL, encrypted_filename, description_filename); switch (r) { case NO_ERROR_SMIME: break; case ERROR_SMIME_NOPASSPHRASE: case ERROR_SMIME_CHECK: res = MAIL_ERROR_COMMAND; goto unlink_description; break; case ERROR_SMIME_COMMAND: res = MAIL_ERROR_COMMAND; goto unlink_encrypted; case ERROR_SMIME_FILE: res = MAIL_ERROR_FILE; goto unlink_description; } /* encrypted part */ r = mailprivacy_get_part_from_file(privacy, 0, 0, encrypted_filename, &encrypted_mime); if (r != MAIL_NO_ERROR) { res = r; goto unlink_description; } strip_mime_headers(encrypted_mime); unlink(description_filename); unlink(encrypted_filename); unlink(decrypted_filename); * result = encrypted_mime; return MAIL_NO_ERROR; unlink_description: unlink(description_filename); unlink_encrypted: unlink(encrypted_filename); unlink_decrypted: unlink(decrypted_filename); err: return res; }
static int smime_sign(struct mailprivacy * privacy, mailmessage * msg, struct mailmime * mime, struct mailmime ** result) { char signed_filename[PATH_MAX]; FILE * signed_f; int res; int r; int col; char description_filename[PATH_MAX]; char signature_filename[PATH_MAX]; char command[PATH_MAX]; char quoted_signed_filename[PATH_MAX]; struct mailmime * signed_mime; char * smime_cert; char * smime_key; char quoted_smime_cert[PATH_MAX]; char quoted_smime_key[PATH_MAX]; char * email; /* get signing key */ email = get_first_from_addr(mime); if (email == NULL) { res = MAIL_ERROR_INVAL; goto err; } 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 err; } /* part to sign */ /* encode quoted printable all text parts */ mailprivacy_prepare_mime(mime); signed_f = mailprivacy_get_tmp_file(privacy, signed_filename, sizeof(signed_filename)); if (signed_f == NULL) { res = MAIL_ERROR_FILE; goto err; } col = 0; r = mailmime_write(signed_f, &col, mime); if (r != MAILIMF_NO_ERROR) { fclose(signed_f); res = MAIL_ERROR_FILE; goto unlink_signed; } fclose(signed_f); /* prepare destination file for signature */ r = mailprivacy_get_tmp_filename(privacy, signature_filename, sizeof(signature_filename)); if (r != MAIL_NO_ERROR) { res = r; goto unlink_signed; } r = mailprivacy_get_tmp_filename(privacy, description_filename, sizeof(description_filename)); if (r != MAIL_NO_ERROR) { res = r; goto unlink_signature; } r = mail_quote_filename(quoted_signed_filename, sizeof(quoted_signed_filename), signed_filename); 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; } r = mail_quote_filename(quoted_smime_cert, sizeof(quoted_smime_cert), smime_cert); if (r < 0) { res = MAIL_ERROR_MEMORY; goto unlink_description; } snprintf(command, sizeof(command), "openssl smime -sign -passin fd:0 -in '%s' -signer '%s' -inkey '%s'", quoted_signed_filename, quoted_smime_cert, quoted_smime_key); r = smime_command_passphrase(privacy, msg, command, email, signature_filename, description_filename); switch (r) { case NO_ERROR_SMIME: break; case ERROR_SMIME_NOPASSPHRASE: case ERROR_SMIME_CHECK: res = MAIL_ERROR_COMMAND; goto unlink_description; break; case ERROR_SMIME_COMMAND: res = MAIL_ERROR_COMMAND; goto unlink_description; case ERROR_SMIME_FILE: res = MAIL_ERROR_FILE; goto unlink_description; } /* signature part */ r = mailprivacy_get_part_from_file(privacy, 0, 0, signature_filename, &signed_mime); if (r != MAIL_NO_ERROR) { res = r; goto unlink_description; } strip_mime_headers(signed_mime); unlink(description_filename); /* unlink(signature_filename); */ /* unlink(signed_filename); */ * result = signed_mime; return MAIL_NO_ERROR; unlink_description: unlink(description_filename); unlink_signature: unlink(signature_filename); unlink_signed: unlink(signed_filename); err: return res; }