compose/pgp: add encrypt_for_self flag

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/490/head
Manos Pitsidianakis 4 weeks ago
parent c82341f3af
commit 23395491db
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -42,5 +42,5 @@ use crate::conf::{*, data_types::*};
# [derive (Debug , Serialize , Deserialize , Clone)] # [serde (deny_unknown_fields)] pub struct TagsSettingsOverride { # [serde (deserialize_with = "tag_color_de")] # [serde (default)] pub colors : Option < IndexMap < TagHash , Color > > , # [serde (deserialize_with = "tag_set_de" , alias = "ignore-tags")] # [serde (default)] pub ignore_tags : Option < IndexSet < TagHash > > } impl Default for TagsSettingsOverride { fn default () -> Self { Self { colors : None , ignore_tags : None } } }
# [derive (Debug , Serialize , Deserialize , Clone)] # [serde (deny_unknown_fields)] pub struct PGPSettingsOverride { # [doc = " auto verify signed e-mail according to RFC3156"] # [doc = " Default: true"] # [serde (alias = "auto-verify-signatures")] # [serde (default)] pub auto_verify_signatures : Option < ActionFlag > , # [doc = " auto decrypt encrypted e-mail"] # [doc = " Default: true"] # [serde (alias = "auto-decrypt")] # [serde (default)] pub auto_decrypt : Option < ActionFlag > , # [doc = " always sign sent e-mail"] # [doc = " Default: false"] # [serde (alias = "auto-sign")] # [serde (default)] pub auto_sign : Option < ActionFlag > , # [doc = " Auto encrypt sent e-mail"] # [doc = " Default: false"] # [serde (alias = "auto-encrypt")] # [serde (default)] pub auto_encrypt : Option < ActionFlag > , # [doc = " Default: None"] # [serde (alias = "sign-key")] # [serde (default)] pub sign_key : Option < Option < String > > , # [doc = " Default: None"] # [serde (alias = "decrypt-key")] # [serde (default)] pub decrypt_key : Option < Option < String > > , # [doc = " Default: None"] # [serde (alias = "encrypt-key")] # [serde (default)] pub encrypt_key : Option < Option < String > > , # [doc = " Allow remote lookups"] # [doc = " Default: False"] # [serde (alias = "allow-remote-lookups")] # [serde (default)] pub allow_remote_lookup : Option < ActionFlag > , # [doc = " Remote lookup mechanisms."] # [doc = " Default: \"local,wkd\""] # [cfg_attr (feature = "gpgme" , serde (alias = "remote-lookup-mechanisms"))] # [cfg (feature = "gpgme")] # [serde (default)] pub remote_lookup_mechanisms : Option < melib :: gpgme :: LocateKey > , # [cfg (not (feature = "gpgme"))] # [cfg_attr (not (feature = "gpgme") , serde (alias = "remote-lookup-mechanisms"))] # [serde (default)] pub remote_lookup_mechanisms : Option < String > } impl Default for PGPSettingsOverride { fn default () -> Self { Self { auto_verify_signatures : None , auto_decrypt : None , auto_sign : None , auto_encrypt : None , sign_key : None , decrypt_key : None , encrypt_key : None , allow_remote_lookup : None , remote_lookup_mechanisms : None } } }
# [derive (Debug , Serialize , Deserialize , Clone)] # [serde (deny_unknown_fields)] pub struct PGPSettingsOverride { # [doc = " auto verify signed e-mail according to RFC3156"] # [doc = " Default: true"] # [serde (alias = "auto-verify-signatures")] # [serde (default)] pub auto_verify_signatures : Option < ActionFlag > , # [doc = " auto decrypt encrypted e-mail"] # [doc = " Default: true"] # [serde (alias = "auto-decrypt")] # [serde (default)] pub auto_decrypt : Option < ActionFlag > , # [doc = " always sign sent e-mail"] # [doc = " Default: false"] # [serde (alias = "auto-sign")] # [serde (default)] pub auto_sign : Option < ActionFlag > , # [doc = " Auto encrypt sent e-mail"] # [doc = " Default: false"] # [serde (alias = "auto-encrypt")] # [serde (default)] pub auto_encrypt : Option < ActionFlag > , # [doc = " Default: None"] # [serde (alias = "sign-key")] # [serde (default)] pub sign_key : Option < Option < String > > , # [doc = " Default: None"] # [serde (alias = "decrypt-key")] # [serde (default)] pub decrypt_key : Option < Option < String > > , # [doc = " Default: None"] # [serde (alias = "encrypt-key")] # [serde (default)] pub encrypt_key : Option < Option < String > > , # [doc = " Default: true"] # [serde (alias = "encrypt-for-self")] # [serde (default)] pub encrypt_for_self : Option < bool > , # [doc = " Allow remote lookups"] # [doc = " Default: False"] # [serde (alias = "allow-remote-lookups")] # [serde (default)] pub allow_remote_lookup : Option < ActionFlag > , # [doc = " Remote lookup mechanisms."] # [doc = " Default: \"local,wkd\""] # [cfg_attr (feature = "gpgme" , serde (alias = "remote-lookup-mechanisms"))] # [cfg (feature = "gpgme")] # [serde (default)] pub remote_lookup_mechanisms : Option < melib :: gpgme :: LocateKey > , # [cfg (not (feature = "gpgme"))] # [cfg_attr (not (feature = "gpgme") , serde (alias = "remote-lookup-mechanisms"))] # [serde (default)] pub remote_lookup_mechanisms : Option < String > } impl Default for PGPSettingsOverride { fn default () -> Self { Self { auto_verify_signatures : None , auto_decrypt : None , auto_sign : None , auto_encrypt : None , sign_key : None , decrypt_key : None , encrypt_key : None , encrypt_for_self : None , allow_remote_lookup : None , remote_lookup_mechanisms : None } } }

@ -60,6 +60,10 @@ pub struct PGPSettings {
#[serde(default = "none", alias = "encrypt-key")]
pub encrypt_key: Option<String>,
/// Default: true
#[serde(default = "true_val", alias = "encrypt-for-self")]
pub encrypt_for_self: bool,
/// Allow remote lookups
/// Default: False
#[serde(
@ -99,6 +103,7 @@ impl Default for PGPSettings {
auto_decrypt: true.into(),
auto_sign: false.into(),
auto_encrypt: false.into(),
encrypt_for_self: true,
sign_key: None,
decrypt_key: None,
encrypt_key: None,

@ -21,18 +21,21 @@
//! Entities that handle Mail specific functions.
use std::{future::Future, pin::Pin};
use indexmap::IndexMap;
use melib::{
backends::{AccountHash, Mailbox, MailboxHash},
email::{attachment_types::*, attachments::*},
text::{TextProcessing, Truncate},
thread::ThreadNodeHash,
};
use uuid::Uuid;
use super::*;
use crate::{
melib::text::{TextProcessing, Truncate},
uuid::Uuid,
};
pub type AttachmentBoxFuture = Pin<Box<dyn Future<Output = Result<AttachmentBuilder>> + Send>>;
pub type AttachmentFilterBox = Box<dyn FnOnce(AttachmentBuilder) -> AttachmentBoxFuture + Send>;
pub mod listing;
pub use crate::listing::*;

@ -888,6 +888,8 @@ impl Component for Composer {
self.gpg_state.sign_mail =
Some(*account_settings!(context[self.account_hash].pgp.auto_sign));
}
self.gpg_state.encrypt_for_self =
*account_settings!(context[self.account_hash].pgp.encrypt_for_self);
if !self.draft.headers().contains_key(HeaderName::FROM)
|| self.draft.headers()[HeaderName::FROM].is_empty()
{
@ -2564,16 +2566,7 @@ pub fn send_draft_async(
let format_flowed = *account_settings!(context[account_hash].composing.format_flowed);
let event_sender = context.main_loop_handler.sender.clone();
#[cfg(feature = "gpgme")]
#[allow(clippy::type_complexity)]
let mut filters_stack: Vec<
Box<
dyn FnOnce(
AttachmentBuilder,
)
-> Pin<Box<dyn Future<Output = Result<AttachmentBuilder>> + Send>>
+ Send,
>,
> = vec![];
let mut filters_stack: Vec<AttachmentFilterBox> = vec![];
#[cfg(feature = "gpgme")]
if gpg_state.sign_mail.unwrap_or(ActionFlag::False).is_true()
&& !gpg_state
@ -2623,14 +2616,15 @@ pub fn send_draft_async(
let send_mail = account_settings!(context[account_hash].send_mail).clone();
let send_cb = context.accounts[&account_hash].send_async(send_mail);
let mut content_type = ContentType::default();
if format_flowed {
if let ContentType::Text {
if let (
true,
ContentType::Text {
ref mut parameters, ..
} = content_type
},
) = (format_flowed, &mut content_type)
{
parameters.push((b"format".to_vec(), b"flowed".to_vec()));
}
}
let mut body: AttachmentBuilder = Attachment::new(
content_type,
Default::default(),

@ -23,7 +23,6 @@ use std::{
collections::{hash_map::DefaultHasher, BTreeMap},
future::Future,
hash::{Hash, Hasher},
pin::Pin,
sync::{Arc, Mutex},
};
@ -38,6 +37,8 @@ use melib::{
parser::BytesExt,
};
use super::AttachmentBoxFuture;
pub async fn decrypt(raw: Vec<u8>) -> Result<(melib_pgp::DecryptionMetadata, Vec<u8>)> {
let mut ctx = Context::new()?;
let cipher = ctx.new_data_mem(&raw)?;
@ -87,6 +88,23 @@ pub fn sign_filter(
Ok(move |a: AttachmentBuilder| -> AttachmentBoxFuture {
Box::pin(async move {
if let Some(default_key) = default_key {
let mut ctx = Context::new()?;
ctx.set_auto_key_locate(LocateKey::LOCAL)?;
let keys = ctx.keylist(false, Some(default_key.clone()))?.await?;
if keys.is_empty() {
return Err(Error::new(format!(
"Could not locate sign key with ID `{}`",
default_key
)));
}
sign_keys.extend(keys);
}
if sign_keys.is_empty() {
return Err(Error::new(
"No key was selected for signing; please select one.",
));
}
let a: Attachment = a.into();
let mut ctx = Context::new()?;
let data = ctx.new_data_mem(&melib_pgp::convert_attachment_to_rfc_spec(
a.into_raw().as_bytes(),
@ -111,8 +129,7 @@ pub fn sign_filter(
)
.into())
})
},
)
})
}
pub fn encrypt_filter(
@ -166,24 +183,50 @@ pub fn encrypt_filter(
}
if let Some(encrypt_for_self) = encrypt_for_self {
let mut ctx = Context::new()?;
let data = ctx.new_data_mem(
a.into_raw().as_bytes()
)?;
ctx.set_auto_key_locate(LocateKey::LOCAL)?;
let keys = ctx
.keylist(false, Some(encrypt_for_self.to_string()))?
.await?;
if keys.is_empty() {
return Err(Error::new(format!(
"Could not locate personal encryption key for address `{}`",
encrypt_for_self
)));
}
for key in keys {
if !encrypt_keys.contains(&key) {
encrypt_keys.push(key);
}
}
}
let a: Attachment = a.into();
log::trace!(
"main attachment is {:?} sign_keys = {:?} encrypt_keys = {:?}",
&a,
&sign_keys,
&encrypt_keys
);
let mut ctx = Context::new()?;
let data = ctx.new_data_mem(a.into_raw().as_bytes())?;
let sig_attachment = {
let enc_attachment = {
let mut a = Attachment::new(
ContentType::OctetStream { name: None, parameters: vec![] },
ContentType::OctetStream {
name: None,
parameters: vec![],
},
Default::default(),
ctx.encrypt(sign_keys, encrypt_keys, data)?.await?,
);
a.content_disposition = ContentDisposition::from(br#"attachment; filename="msg.asc""#);
a.content_disposition =
ContentDisposition::from(br#"attachment; filename="msg.asc""#);
a
};
let mut a: AttachmentBuilder = AttachmentBuilder::new(b"Version: 1\n");
a.set_content_type_from_bytes(b"application/pgp-encrypted");
a.set_content_disposition(ContentDisposition::from(b"attachment"));
let parts = vec![a, sig_attachment.into()];
let parts = vec![a, enc_attachment.into()];
let boundary = ContentType::make_boundary(&parts);
Ok(Attachment::new(
ContentType::Multipart {
@ -197,6 +240,5 @@ pub fn encrypt_filter(
)
.into())
})
},
)
})
}

Loading…
Cancel
Save