Add formatters for application/pgp-keys and application/vnd.gnupg.wks body parts
ClosedPublic

Authored by dvratil on Oct 23 2016, 12:27 PM.

Details

Summary

This adds a new body part formatter plugin for application/pgp-keys mime type and application/vnd.gnupg.wks mimetype.

The application/pgp-keys formatter simply prints a message saying that this is an OpenPGP key and explains what that is, as seen below:

User can click the "Show key details" link to get details about the key (uid, creation date, fingerprint), and if the key is available in local keyring there will also be "Open in Kleopatra" link.

The application/vnd.gnupg.wks mimetype formatter handles the WKS Publishing Confirmation request. The request is worded in the terms of "Registration", which might be better for the user, and has a button to "Register".

Once clicked, the formatter silently sends the confirmation response to WKS and deletes both the request and the response.

Test Plan

Tested with locally generated messages. Have not tested actually sending out the response.

Diff Detail

Repository
R81 KDE PIM Addons
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
dvratil updated this revision to Diff 7617.Oct 23 2016, 12:27 PM
dvratil retitled this revision from to Add formatters for application/pgp-keys and application/vnd.gnupg.wks body parts.
dvratil updated this object.
dvratil edited the test plan for this revision. (Show Details)
dvratil added reviewers: aheinecke, bjoernbalazs.
dvratil set the repository for this revision to R81 KDE PIM Addons.
dvratil added a project: KDE PIM.
dvratil added a subscriber: KDE PIM.
Restricted Application added a subscriber: kde-pim. · View Herald TranscriptOct 23 2016, 12:27 PM
mlaurent added inline comments.
plugins/messageviewer/bodypartformatter/gnupgwks/CMakeLists.txt
2

You missed Messages.sh

plugins/messageviewer/bodypartformatter/gnupgwks/gnupgwksmemento.cpp
47 ↗(On Diff #7617)

Perhaps it will good to detect if we have gpg2 in system no ?

205 ↗(On Diff #7617)

Q_NULLPTR

mlaurent requested changes to this revision.Oct 23 2016, 1:41 PM
mlaurent added a reviewer: mlaurent.

you missed to update kdepim-addons.categories

This revision now requires changes to proceed.Oct 23 2016, 1:41 PM
dvratil updated this revision to Diff 7628.Oct 24 2016, 6:12 AM
dvratil edited edge metadata.
dvratil removed R81 KDE PIM Addons as the repository for this revision.
dvratil marked 3 inline comments as done.Oct 24 2016, 6:19 AM
  • added Messages.sh
  • updated kdepim-addons.categories
  • coding style/code clean up
plugins/messageviewer/bodypartformatter/gnupgwks/gnupgwksmemento.cpp
47 ↗(On Diff #7617)

Perhaps it will good to detect if we have gpg2 in system no ?

It's a bit more difficult than that. Some distros have GnuPG2 binaries called "gpg", while some others have GnuPG2 binaries called "gpg2" (and GnuPG1 binaries called "gpg", possibly installed at the same time). We need to use GnuPG2 for this, so we try "gpg2" first, and if we get QProcess::FailedToStart error we try "gpg". If we would get error with "gpg", it means that either there's no "gpg" binary, or it's GnuPG1 binary (which does not understand the arguments).

I think it's easier and simpler to just try, rather than locating the binaries and parsing their "--version" output.

dvratil edited edge metadata.Oct 24 2016, 6:20 AM
dvratil set the repository for this revision to R81 KDE PIM Addons.
aheinecke edited edge metadata.Oct 24 2016, 8:12 AM
aheinecke added a subscriber: emanuel.

Great, I think it's nice to finally have an application/pgp-keys handler. But as written in the inline comments I think that if we have a handler we need to offer the import action.

Regarding the WKS Handler I think the "This key is already published" message / check if the key is already in the WKD is probably wrong, there might be use cases (e.g. after changing the expiry date of a key or adding / removing subkeys) where a user wants to update the published key even if a key with the same fingerprint was already published.
I would have thought we could handle this like invitations. So that after accepting an invitation the actual invitation mail is deleted. (Here after replying to a confirmation request we would delete the request). This would remove the need here problem to check if the key is already published.

Regarding sending, you use SMTPJob. I am concerned that this might be a bit too low level. It looks to me for example that if you are offline when trying to reply the SMTPJob would just error out where I expected that the response stays in the outbox and is sent the next time you are online. Again invitations could be the example how to handle this.

plugins/messageviewer/bodypartformatter/gnupgwks/gnupgwksmemento.cpp
47 ↗(On Diff #7617)

Ultimately I think we need API in gpgme for this. But in the meantime its better to use GpgME engine info:

GpgME::engineInfo(GpgME::GpgEngine).fileName();

There is also GpgME::engineInfo(GpgME::GpgEngine).engineVersion() that you could use for version checks like:

if (!(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.13"))
...

(2.1.13 is the first version that fully supports wkd lookup)

But as written in the general comment I don't think we should do the check here but rather delete the confirmation request mail once we have sent a response.

plugins/messageviewer/bodypartformatter/gnupgwks/pgpkeyformatter.cpp
94

In this case we should offer to import the key. So that we handle the case where someone attaches their PGP key to a message and the recipient imports it. QGpgME::ImportJob

This would also mean to store the raw data in the PgpKeyMessagePart. I think without this we might have a regression because application/pgp-keys was previously associated with kleopatra so you could import an attached public key by "Opening the attachment in Kleopatra".

mlaurent requested changes to this revision.Oct 24 2016, 9:40 AM
mlaurent edited edge metadata.
mlaurent added inline comments.
plugins/messageviewer/bodypartformatter/gnupgwks/gnupgwksmemento.cpp
180 ↗(On Diff #7628)

We need to depend against new kmailtransport (install smtpjob.h)
Did you update kmailtransport version in CMakeLists.txt kdepim-addons toplevel ?

plugins/messageviewer/bodypartformatter/gnupgwks/gnupgwksmemento.h
43 ↗(On Diff #7628)

explicit without argument ?
I think that you can remove explicit here

71 ↗(On Diff #7628)

could you move it in cpp file ? thanks

plugins/messageviewer/bodypartformatter/gnupgwks/pgpkeymemento.h
39

not necessary to add explicit here too

plugins/messageviewer/bodypartformatter/gnupgwks/pgpkeymessagepart.cpp
102

Perhaps we can cache "cols.size()" to avoid to recall this method no ?

This revision now requires changes to proceed.Oct 24 2016, 9:40 AM
knauss added a subscriber: knauss.Oct 24 2016, 12:48 PM
knauss added inline comments.
plugins/messageviewer/bodypartformatter/gnupgwks/gnupgwksformatter.cpp
192

so only one reqest per time is allowed? what happes if user whatto publich multiple keys for different servers, like it happes when you start with kmail and adds all your accounts?

I would say that property("wksPublishingRequest") is a property of the memento.

plugins/messageviewer/bodypartformatter/gnupgwks/pgpkeymessagepart.cpp
82

what? gpgme do not offer any function to scan data is a key?

aheinecke added inline comments.Oct 24 2016, 4:49 PM
plugins/messageviewer/bodypartformatter/gnupgwks/pgpkeymessagepart.cpp
82

Yes,... *blushes for gpgme*

And we need one here. This is fragile and dangerous. We can have multiple keys in a application/pgp-keys file. This would only show the last one. When a user is then offered to import the key (which I suggested in my other comment) he can be tricked into importing multiple keys with different fingerprints / userids. Also without an action gnupg determines by itself what it does with the data. E.g. try to decrypt it. I can't really think of an attack that could utilize this but maybe.

I've written a new gpgme command for this gpgme_op_keylist_from_data which takes a gpgme_data_t and returns a keylistresult. Just need to get it upstream, which is surprisingly a bit difficult as I use "gpg --import-options import-show --dry-run --import" where upstream says that this is not technically a keylisting :-/

In qt this would be a keylistjob that takes a QByteArray.

I'll let you know when we have API for that. (But Packagers will not like us if we depend on unreleased again. So maybe we should then use that with an Ifdef version guard.) :-)

bjoernbalazs edited edge metadata.Oct 25 2016, 9:21 AM

For the wording in the mails I would suggest something like:
"This is an automatically generated email. The purpose of this email is to:" and then add the purpose of the mail, so for the

  • first one (application/pgp-keys):

"send your public key to your email provider. This way other people can easily send you encrypted emails (so no-one except from you and the sender can read the mails)."

  • Second one (application/vnd.gnupg.wks)

"inform you, that your email provider has successfully received your public key. Other people can now easily send you encrypted emails (so no-one except from you and the sender can read the mails)."

For both: "Further action: Nothing required from you."

  • Most problematic is when the key cannot be found in the WKD, because here the user actually needs to take action. A suggestion how to solve this:

"This is an automatically generated email.
The purpose of this email is to inform you that your email provider has not been able to publish your public key. All you can do is to re-send the information:

Further action: [Re-send your public key to your email provider.]"

What do you think?

dvratil marked 4 inline comments as done.Oct 26 2016, 3:49 PM

Thanks Bjoern. The situation has simplified a little with Andre's suggestion to autodelete the email after user action, which means we have to handle much fewer states and thus much fewer messages :-)

For the wording in the mails I would suggest something like:
"This is an automatically generated email. The purpose of this email is to:" and then add the purpose of the mail, so for the

Won't an email starting with "This is an automatically generated email" just make users to shrug and hit the Delete key? That's my biggest concern here....

  • first one (application/pgp-keys): "send your public key to your email provider. This way other people can easily send you encrypted emails (so no-one except from you and the sender can read the mails)."

This one might not be automatically generated in some cases, could just be that someone simply sends you their public key via email, so the text should IMHO be generic enough to explain what it is with an action to allow users to import it into their keychain.

What about:

This is an OpenPGP key from John Smith <john@example.com>. You can use the key to exchange encrypted emails and files with this user and to verify authenticity of their emails.

[ Show key details ] [ Import key ]

"Show key details" just shows a bit more information (creation date, fingerprint, userid), "Import key" obviously imports it.

Since Andre mentioned that pgp-keys can actually contains multiple keys, I'd simply handle it by showing the same "block" one for each key.

  • Second one (application/vnd.gnupg.wks) "inform you, that your email provider has successfully received your public key. Other people can now easily send you encrypted emails (so no-one except from you and the sender can read the mails)."

Right, this mime type can act in two situations:

  1. an email /from/ the provider asking you to confirm publication, so there needs to be an initial action from user: [ Click here to publish ] (which IMO implies having an explanation what this is all about at the top above the button). When clicked this generates and sends an email to provider which then finally publishes the key and there is no further response from the provider and we will delete this email (so no need to handle all the "Sending/Sent/Sent-but-not-yet-published/...") states.
  1. the email that we generated when user clicked the [ Click here to publish ] button in case 1), which means they will only see it if they click the email in their Outbox or Sent folder. Here I think we can say it's an automated email (we generated it after all) just fine:
"This is an automatically generated email sent from KMail to your email provider to publish your key. Other people can now easily send you encrypted emails and verify authenticity of your emails"

For both: "Further action: Nothing required from you."

  • Most problematic is when the key cannot be found in the WKD, because here the user actually needs to take action. A suggestion how to solve this:

    "This is an automatically generated email. The purpose of this email is to inform you that your email provider has not been able to publish your public key. All you can do is to re-send the information:

    Further action: [Re-send your public key to your email provider.]"

This case is now gone, since we delete the email after successfully publishing the key, we don't need to worry about the key already being published or not.

What do you think?

I think we should always start with explaining what this email is about rather than saying it's automatically generated (we can mention that somewhere below), to make sure people don't ignore it and get and can understand the purpose of the email as quickly as possible? That's just my uneducated opinion :)

Ok, I think I get the idea.

We have two workflows:

[1] Uploading your public key

I suggest to create the workflow like this:

  • User does not uncheck the publish public key checkbox during set-up
  • Mail with request to publish the key gets sent to the server and is automatically deleted on the users computer
  • Server responds with am encrypted mail:
    • This is an automatically generated mail needed to securely publish your public key. Please open it with the mail client you used to create your mail encryption keys. Do not delete or answer to this mail.
    • Some cryptic stuff goes here to securely identify everything
      • (This is just needed in case the user opens the mail with some other client.)
  • When KMail opens this mail and can decrypt it, it answers automatically to the mail, deletes both, this mail and the answer.
    • It is important to reduce the needed user interaction as much as possible, because we loose a lot of users with each of these steps!
  • When the server gets the mail it publishes the new public key and sends a mail to the user saying:
    • Thank you for publishing your public key. It is now much easier for other people to confidentially share information with you. Learn more about how to protect your privacy at www....
    • Overview of key and email address
    • This is an automatically generated mail. Please do not answer to it.

DONE :)

[2] Importing public keys

When a mail is viewed that contains a public key, we would like the user to store this key locally. So we need to prompt him to do this, as we cannot do this automatically. Technically the key simply is an attachment and should be handled as such. It might be wise to put some effort into how attachments are displayed to fulfil the additional needs of attached public keys (tbd).
To get the user to update the locally stored keys, I would like to first automatically check if the attached public key equals the public key in Kleo. If it does the user does not need to be informed.
In case there is a difference, I would like to raise a dialogue to point the user to this new key. The reasoning behind this is the fact that it will not happen very often that you get a new public key and at the same time it is important to store / update this key locally asap. This is reason enough to interrupt the user. If we don't do it, it will be very hard to point the user to the needed actions.
This dialogue should offer the possibilities to:

  • replace the key
  • add the new key
  • don't add the new key
  • never add this new key
  • never show this dialogue again (possibly only in the settings)

What do you think?

Regarding Björns comments. For case 1 I agree.

For case 2 I think a dialog / deep check if the key updates the key in the keyring should be out of scope of this patch. I would also dislike a dialog as we already have the messageviewer and are able to display various actions in the messaageviewer.

I would say let's add some functionality for handling pgp-keys and then we can probably improve on that. I don't see much usecases for attaching the public key and in EasyGPG we rather discourage it in favor of Web Key Directories / auto-key-retrieve on signed messages. So I would rather encourage users to publish their key out of bounds.

There is a small rationale for this given on:
https://wiki.gnupg.org/EasyGpg2016/PubkeyDistributionConcept#Attaching_a_pubkey_to_all_emails

plugins/messageviewer/bodypartformatter/gnupgwks/pgpkeymessagepart.cpp
82

Upstream didn't accept my first patch as there are multiple ways to implement it and the best way (imo) is only available with a very recent gnupg version. This needs some discussion but it was pushed back with a "There are more important things at the moment". So this feature will come but not super soon. I have an issue for this: https://bugs.gnupg.org/gnupg/issue2819

In the meantime your hack is probably ok (Although as with the other gnupg process call it would be better to use GpgME::Engine info to figure out which "gpg" to call)

Ok, when saving a local copy of the key is not our intention, then the proposed solution obviously is wrong :)

If we really want to push the WKD in favor of local copies (I hope you have thought about the offline mail composing :) ), I would argue to handle public keys just like other attachments. Usability wise, it would probably make more sense to improve the attachments section in general than to find a public-key specific solution, like it is proposed in this patch.

My main criticism on the proposed patch is that the generated message is shown at the end of a mail - even below signatures and qutotaions - while still looking like being part of the mail. Very many users will fail to notice it.

Let me know if we want to put some effort into the attachments section now. My ideas go into the direction of grouping the attachments by type (can we integrate views from dolphin?) and allowing type specific (bulk) actions. But: "Just" showing the key like current attachments is fine as well. Users, who know what public keys are, can handle them, users who don't should not save them locally anyway and hence do not necessarily need more explanation.

Ok, when saving a local copy of the key is not our intention, then the proposed solution obviously is wrong :)

If we really want to push the WKD in favor of local copies (I hope you have thought about the offline mail composing :) ), I would argue to handle public keys just like other attachments. Usability wise, it would probably make more sense to improve the attachments section in general than to find a public-key specific solution, like it is proposed in this patch.

Just to clarify here, we don't want to get rid of a local keyring in favor of online only key discovery. The WKD is intended to help with initial key discovery, finding a key for your communication partner with some indication (provided by the mail service provider) that this key is the correct one for the owner of this mail address. If gnupg finds a key in the WKD it is imported locally and available for future communications without the need to contact the WKD again.
The key should be refreshed from time to time to handle revocations / key exchange etc. but this is different and can happen through the usual mechanisms.

I did not mean to "get rid of a local keyring". I am just wondering, what we want / expect the user to do in the situation, where a mail with a public key arrives?

  1. Ignore the key unless the user is experienced and knows and cares about managing public keys (because we favour WKD)
  2. Update the key database in case the key is not stored yet
  3. Always take notice that a public key is attached so the user can decide what to do
  4. Get educated about encryption
  5. ???

The design is a result out of this decision. So, what do we want to achieve?

I say case three is the right way to do it. Show the user that someone has sent them a Key but don't import it automatically. That may raise questions like "what is an OpenPGP key" etc.

Also the sender may have ideally accompanied this with a message explaining why he's sending out the key. Like
"Attached you find my OpenPGP key, please call me to confirm the fingerprint and then use this to encrypt the secret data you wanted to send me." Or something like that ;-)

[1] Uploading your public key
=====================
[....]

  • When KMail opens this mail and can decrypt it, it answers automatically to the mail, deletes both, this mail and the answer.

So I thought about this, and although I understand why you want to remove as much user interaction as possible, I think you are pushing this a bit too far.

Consider the following case:

  1. You receive an email
  2. You open it, it says"This email is encrypted, click here do decrypt"
  3. You click the "click here" link
  4. The email disappears
  5. "E-mail sent successfully" notification appears

What I want to point out here is the "awesome" user experience when user clicks the "Click here to decrypt" link, then the view flickers a little and then the email immediately disappears forever, leading to an absolute "WTF moment" on user side and immediate PR shitstorm that KMail deletes your emails. And in two seconds you get "Email was sent successfully" notification, which is a second WTF moment for the user. If this would happen to me, I'd be scared shitless of whom did I accidentally sent something inappropriate, etc., having absolutely NO way of finding out what happened, since KMail permanently deleted both emails (the request and our response).

This is IMO why we need to show the email with a "Yup, do it!" button, transforming the flow to:

  1. You receive an email
  2. You open it, it says "This email is encrypted, click here to decrypt"
  3. You click the "click here" link
  4. An explanation that this is a key publishing request appears, explains you what this is good for, has a big button "Accept" (or whatever) and a small text saying that the email will be deleted afterwards.
  5. You click the "Accept" button
  6. Email disappears
  7. "E-mail sent successfully" notification appears

I know you are the expert, but I'm having hard time believing the the "Fuck yeah!" button would cause users not to finish the "procedure" in such high numbers. After all, we are not trying to sell viagra to them, we are actually explaining what is going on and we show something that is uncommon for most emails: the email has a KMail's blue frame which says "Encrypted yadayadayada" and in the middle is a native-looking button. This will IMO drive enough attention from users to make them at least read the first paragraph and figure out "Oh, I have click this, cool", rather than just instinctively hitting the delete key.

I'm am however convinced that the first case described at the top would lead to users getting really pissed, potentially abandoning KMail and spreading bad PR about us.

[1] Uploading your public key
=====================
[....]

  • When KMail opens this mail and can decrypt it, it answers automatically to the mail, deletes both, this mail and the answer.

Oops sorry, when I read that message I have overlooked this.

I agree with Dan that we need to show that mail. Thats why we want the formatters in this differential.

What we want the user to see is something like the same as registering an account on a website. (Thats why I think Register your Key with your Provider is a good description).

User gets one confirmation mail that needs to be responded.

When the server gets the mail it publishes the new public key and sends a mail to the user saying:

  • Thank you for publishing your public key. It is now much easier for other people to confidentially share information with you. Learn more about how to protect your privacy at www....
  • Overview of key and email address This is an automatically generated mail. Please do not answer to it.

This I also overlooked, I'm really sorry It appears I read that mail with my brain disabled :-/ (I read your message again now). After sending the response we are leaving the specified Protocol. It is not specified that a WKS Provider should send you such a mail. We also would have no control over the contents as it comes from the Provider.

So I thought about this, and although I understand why you want to remove as much user interaction as possible, I think you are pushing this a bit too far.

Consider the following case:

  1. You receive an email
  2. You open it, it says"This email is encrypted, click here do decrypt"

Also at this point a pinentry might pop up asking the user to enter his password.

  1. You click the "click here" link
  2. The email disappears
  3. "E-mail sent successfully" notification appears

    What I want to point out here is the "awesome" user experience when user clicks the "Click here to decrypt" link, then the view flickers a little and then the email immediately disappears forever, leading to an absolute "WTF moment" on user side and immediate PR shitstorm that KMail deletes your emails. And in two seconds you get "Email was sent successfully" notification, which is a second WTF moment for the user. If this would happen to me, I'd be scared shitless of whom did I accidentally sent something inappropriate, etc., having absolutely NO way of finding out what happened, since KMail permanently deleted both emails (the request and our response).

Yes. I also think this is wouldn't be the best solution.

This is IMO why we need to show the email with a "Yup, do it!" button, transforming the flow to:

 You receive an email
You open it, it says "This email is encrypted, click here to decrypt"
You click the "click here" link
 An explanation that this is a key publishing request appears, explains you what this is good for, has a big button "Accept" (or whatever) and a small text saying that the email will be

deleted afterwards.

 You click the "Accept" button
Email disappears
 "E-mail sent successfully" notification appears

Yes this is also the workflow I image and what I want, too.

Thanks.

dvratil marked 4 inline comments as done.Nov 3 2016, 4:48 PM
dvratil updated this revision to Diff 7869.Nov 3 2016, 4:54 PM
dvratil updated this object.
dvratil edited edge metadata.

Change wording a bit (see updated summary), removed dead and unused code

Sorry for the long delay in answering.

Dan, we are both right I guess. So we will loose too many people when we ask them to do too much (in this case anything), esp. as people do not expect to have to confirm anything. On the other hand I can clearly see the WTF moment and the consequences you outlined.

So, how to bring these together?

How about keeping the whole stuff automated, like outlined from me, but - instead of requiring actions from the user - present them a dialogue that basically describes what has happend? Something like:

Upload of your public keys has been successfully finished. KMail automatically confirmed you as the owner of your keys. In the scope of this process the confirmation mail from your provider has been answered and both - your providers mail and your answer - have been deleted. (Obviously a draft in wording)

Does this solve the problem?

We really need to reduce the needed user interactions as much as possible. In an unexpected situation (no user expects that additional step(s)) drop-out rates might go up to something like 70% on any needed interaction (it is hard to predict though for our use-case). Esp. in handling emails everyone learns not to click on any dubious links and to delete suspicious emails.

Concluding: any effort invested in reducing them will be extremely beneficial to reach our project goals.

This revision was automatically updated to reflect the committed changes.