diff --git a/go.mod b/go.mod index 7d6c6085..a9b8b09c 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.0 github.com/ProtonMail/gluon v0.17.1-0.20231025125916-5c7941465df8 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a - github.com/ProtonMail/go-proton-api v0.4.1-0.20231106093533-5f248dfc820d + github.com/ProtonMail/go-proton-api v0.4.1-0.20231108105501-fb55d3bd8bd8 github.com/ProtonMail/gopenpgp/v2 v2.7.4-proton github.com/PuerkitoBio/goquery v1.8.1 github.com/abiosoft/ishell v2.0.0+incompatible diff --git a/go.sum b/go.sum index eb7ec5d0..e68bade0 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/ProtonMail/go-message v0.13.1-0.20230526094639-b62c999c85b7 h1:+j+Kd/ github.com/ProtonMail/go-message v0.13.1-0.20230526094639-b62c999c85b7/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= -github.com/ProtonMail/go-proton-api v0.4.1-0.20231106093533-5f248dfc820d h1:LI2kvxBisX19f7lyMh0H6NcAHHg/Y7/x/xZWtxVrXOc= -github.com/ProtonMail/go-proton-api v0.4.1-0.20231106093533-5f248dfc820d/go.mod h1:WEXJqj5DSc2YI77SgXdpMY0nk33Qy92Vu2r4tOEazA8= +github.com/ProtonMail/go-proton-api v0.4.1-0.20231108105501-fb55d3bd8bd8 h1:A89egSM6ODsnxLrb8ChMC/SR5yqZiGIJipEdesPOPhM= +github.com/ProtonMail/go-proton-api v0.4.1-0.20231108105501-fb55d3bd8bd8/go.mod h1:WEXJqj5DSc2YI77SgXdpMY0nk33Qy92Vu2r4tOEazA8= github.com/ProtonMail/go-srp v0.0.7 h1:Sos3Qk+th4tQR64vsxGIxYpN3rdnG9Wf9K4ZloC1JrI= github.com/ProtonMail/go-srp v0.0.7/go.mod h1:giCp+7qRnMIcCvI6V6U3S1lDDXDQYx2ewJ6F/9wdlJk= github.com/ProtonMail/gopenpgp/v2 v2.7.4-proton h1:8tqHYM6IGsdEc6Vxf1TWiwpHNj8yIEQNACPhxsDagrk= diff --git a/internal/services/smtp/smtp.go b/internal/services/smtp/smtp.go index d579e05d..cf509914 100644 --- a/internal/services/smtp/smtp.go +++ b/internal/services/smtp/smtp.go @@ -505,12 +505,15 @@ func (s *Service) getRecipients( return proton.SendPreferences{}, fmt.Errorf("failed to get contact settings for %v: %w", recipient, err) } + s.log.Infof("ContactSettings=%v", contactSettings) + return buildSendPrefs(contactSettings, settings, pubKeys, draft.MIMEType, recType == proton.RecipientTypeInternal) }) if err != nil { return nil, fmt.Errorf("failed to get send preferences: %w", err) } + s.log.Infof("Settings=%v", prefs) recipients := make(recipients) for idx, pref := range prefs { diff --git a/internal/services/smtp/smtp_prefs.go b/internal/services/smtp/smtp_prefs.go index 17de0fa0..4466e493 100644 --- a/internal/services/smtp/smtp_prefs.go +++ b/internal/services/smtp/smtp_prefs.go @@ -34,13 +34,14 @@ const ( ) type contactSettings struct { - Email string - Keys []string - Scheme string - Sign bool - SignIsSet bool - Encrypt bool - MIMEType rfc822.MIMEType + Email string + Keys []string + Scheme string + Sign bool + SignIsSet bool + Encrypt bool + EncryptUntrusted bool + MIMEType rfc822.MIMEType } // newContactSettings converts the API settings into our local settings. @@ -61,6 +62,12 @@ func newContactSettings(settings proton.ContactSettings) *contactSettings { metadata.Encrypt = *settings.Encrypt } + if settings.EncryptUntrusted != nil { + metadata.EncryptUntrusted = *settings.EncryptUntrusted + } else { + metadata.EncryptUntrusted = true + } + if settings.Scheme != nil { switch *settings.Scheme { // nolint:exhaustive case proton.PGPMIMEScheme: @@ -426,9 +433,12 @@ func (b *sendPrefsBuilder) setExternalPGPSettingsWithWKDKeys( return errors.New("an API key is necessary but wasn't provided") } - // We always encrypt and sign external mail if WKD keys are present. - b.withEncrypt(true) - b.withSign(true) + b.withEncrypt(vCardData.EncryptUntrusted) + if vCardData.EncryptUntrusted { + b.withSign(true) + } else if vCardData.SignIsSet { + b.withSign(vCardData.Sign) + } // If the contact has a specific Scheme preference, we set it (otherwise we // leave it unset to allow it to be filled in with the default value later). diff --git a/internal/services/smtp/smtp_prefs_test.go b/internal/services/smtp/smtp_prefs_test.go index dad56bb0..1fdb6955 100644 --- a/internal/services/smtp/smtp_prefs_test.go +++ b/internal/services/smtp/smtp_prefs_test.go @@ -110,7 +110,22 @@ func TestPreferencesBuilder(t *testing.T) { { name: "wkd-external", - contactMeta: &contactSettings{}, + contactMeta: &contactSettings{EncryptUntrusted: true}, + receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, + isInternal: false, + mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, + + wantEncrypt: true, + wantSign: proton.DetachedSignature, + wantScheme: proton.PGPMIMEScheme, + wantMIMEType: "multipart/mixed", + wantPublicKey: testPublicKey, + }, + + { + name: "wkd-external", + + contactMeta: &contactSettings{EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, @@ -125,7 +140,7 @@ func TestPreferencesBuilder(t *testing.T) { { name: "wkd-external with contact-specific email format", - contactMeta: &contactSettings{MIMEType: "text/plain"}, + contactMeta: &contactSettings{MIMEType: "text/plain", EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, @@ -140,7 +155,7 @@ func TestPreferencesBuilder(t *testing.T) { { name: "wkd-external with global pgp-inline scheme", - contactMeta: &contactSettings{}, + contactMeta: &contactSettings{EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPInlineScheme, DraftMIMEType: "text/html"}, @@ -155,7 +170,7 @@ func TestPreferencesBuilder(t *testing.T) { { name: "wkd-external with contact-specific pgp-inline scheme overriding global pgp-mime setting", - contactMeta: &contactSettings{Scheme: pgpInline}, + contactMeta: &contactSettings{Scheme: pgpInline, EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, @@ -170,7 +185,7 @@ func TestPreferencesBuilder(t *testing.T) { { name: "wkd-external with contact-specific pgp-mime scheme overriding global pgp-inline setting", - contactMeta: &contactSettings{Scheme: pgpMIME}, + contactMeta: &contactSettings{Scheme: pgpMIME, EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPInlineScheme, DraftMIMEType: "text/html"}, @@ -185,7 +200,7 @@ func TestPreferencesBuilder(t *testing.T) { { name: "wkd-external with additional pinned contact public key", - contactMeta: &contactSettings{Keys: []string{testContactKey}}, + contactMeta: &contactSettings{Keys: []string{testContactKey}, EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, @@ -201,7 +216,7 @@ func TestPreferencesBuilder(t *testing.T) { // NOTE: Need to figured out how to test that this calls the frontend to check for user confirmation. name: "wkd-external with additional conflicting contact public key", - contactMeta: &contactSettings{Keys: []string{testOtherContactKey}}, + contactMeta: &contactSettings{Keys: []string{testOtherContactKey}, EncryptUntrusted: true}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, isInternal: false, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, @@ -213,6 +228,51 @@ func TestPreferencesBuilder(t *testing.T) { wantPublicKey: testPublicKey, }, + { + name: "wkd-external-with-encrypt-and-sign-disabled", + + contactMeta: &contactSettings{EncryptUntrusted: false}, + receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, + isInternal: false, + mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, + + wantEncrypt: false, + wantSign: proton.NoSignature, + wantScheme: proton.ClearScheme, + wantMIMEType: "text/html", + wantPublicKey: testPublicKey, + }, + + { + name: "wkd-external-with-encrypt-and-sign-disabled-plain-text", + + contactMeta: &contactSettings{EncryptUntrusted: false}, + receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, + isInternal: false, + mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/plain"}, + + wantEncrypt: false, + wantSign: proton.NoSignature, + wantScheme: proton.ClearScheme, + wantMIMEType: "text/plain", + wantPublicKey: testPublicKey, + }, + + { + name: "wkd-external-with-encrypt-disabled-sign-enabled", + + contactMeta: &contactSettings{EncryptUntrusted: false, Sign: true, SignIsSet: true}, + receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}}, + isInternal: false, + mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"}, + + wantEncrypt: false, + wantSign: proton.DetachedSignature, + wantScheme: proton.ClearMIMEScheme, + wantMIMEType: "multipart/mixed", + wantPublicKey: testPublicKey, + }, + { name: "external",