[Tickets #2782] Re: S/MIME Sign using browser capabilities

bugs at horde.org bugs at horde.org
Tue Aug 24 05:54:28 UTC 2010


DO NOT REPLY TO THIS MESSAGE. THIS EMAIL ADDRESS IS NOT MONITORED.

Ticket URL: http://bugs.horde.org/ticket/2782
------------------------------------------------------------------------------
  Ticket             | 2782
  Updated By         | blue_eillen03 at yahoo.com
  Summary            | S/MIME Sign using browser capabilities
  Queue              | IMP
  Version            | HEAD
  Type               | Enhancement
  State              | Assigned
  Priority           | 1. Low
  Milestone          |
  Patch              |
  Owners             | Horde Developers, Michael Slusarz
------------------------------------------------------------------------------


blue_eillen03 at yahoo.com (2010-08-24 01:54) wrote:

>>> Wouldn't you consider the AJAX alternative?
>
>> Of course, but why would the help with the splitting of message
>
>> building and sending?
>
>>> I could send you the changes so far as patched.
>
>> Sure, talking about some real code is always easier.
>
> I don't know if you are interested in code details.
>
> So I prepared a Brief and an Extended version,
>
> both for AJAX and Without AJAX.
>
> The extended version helps me to organize myself
>
> (and also document these changes).
>
> Here is the flow control of composing, singning and sending a message
>
> the way I know today.
>
>
>
> Without AJAX:
>
> ~~~~~~~~~~~~~
>
> Brief:
>
> ------
>
> 1) Submit the form as usual.
>
> 2) Build a text/plain MIME for each recipient.
>
> 3) Marshall return values as form hidden inputs.
>
> 4) Render the compose page again.
>
> 5) Hook on onload event to sign text/plain MIMES.
>
> 6) ReSubmit this form.
>
> 7) Unmarshall submitted form hidden inputs to carry on.
>
> 8) Build a multipart/signed for each pair of (text/plain, signature)
>
> 9) Now send all as usual.
>
>
>
> Extended:
>
> ---------
>
> 1) Send the form.
>
>
>
> The page is loaded, the compose form is fulfilled, and submitted
>
> with actionID="send-message'.
>
>
>
> 2) Build a text/plain MIME for each recipient.
>
>
>
> /imp/compose.php is called, the following code is executed
>
>
>
> case 'send_message':
>
> ...
>
> $imp_compose->buildAndSendMessage(...);
>
>
>
> My goal is to split this function in two, because I need to sing
>
> in the browser between "build" and "send".
>
> Right now, the patch I sent "composed" the text/plain part of the MIME
>
> in a Javascript function.
>
> I should leave that to the "build" part of this function.
>
> So, I need 2 new functions:
>
> /imp/lib/Compose.php::buildMessage()
>
> /imp/lib/Compose.php::sendMessage()
>
> The original buildAndSendMessage() is kept for backwards compatibility
>
> and calls these two new ones.
>
> I have done this refactoring and the coupling between these is strong.
>
> Many parameters and array of return values.
>
>
>
>     function buildAndSendMessage(<original parameters>)
>
>     {
>
>         list($messagesToSend, $recipients, $messageToSave) =
>
>                         $this->buildMessage(<original parameters>);
>
>         /**
>
>          * Vars in the list() is the coupling between buildMessage()
>
>          * and sendMessage()
>
>          */
>
>         $sent_saved = $this->sendMessages($messagesToSend, $recipients,
>
>                                  $messageToSave, <original parameters>);
>
>         return $sent_saved;
>
>     }
>
>
>
> Besides, buildMessage() does some work if there are multiple recipients
>
> when signing, so <signing flag> so say "true":
>
>
>
>     if (<signing flag>) {
>
>         /* Must encrypt & send the message one recipient at a time. */
>
>         foreach ($recipientArray as $val) {
>
>             $res = $this->_createMimeMessage(array($val), $body, $encrypt);
>
>             ...
>
>         }
>
>         ...
>
>     }
>
>
>
> Here, buildMessage() calls _createMimeMessage(), one for each recipient.
>
> _createMimeMessage() is exactly the piece of code I want to replace the
>
> Javascript with. However, this function also encrypts, wich I don't  
> need right
>
> now since encryption is carried out later on the browser.
>
> I just want it to compose the text/plain part.
>
>
>
>     function _createMimeMessage($to, $body, $encrypt)
>
>     {
>
>         ...
>
>         <mostly encryption code>
>
>         ...
>
>         /* Add data to MIME_Message object. */
>
>         $mime_message->addPart($body);\
>
>         ...
>
>         return array('recipients' => $to,
>
>                      'to' => implode(', ', $to),
>
>                      'msg' => &$mime_message);
>
>     }
>
>
>
> 3) Marshall return values as form hidden inputs.
>
>
>
> When all this calls return, I have to break the switch statement at
>
> /imp/compose.php.
>
>
>
> Right here I have an array of 3 values returned from buildMessage();
>
>
>
>
>
>     function buildMessage(...)
>
>     {
>
>         ...
>
>         return array($messagesToSend, $recipients, $messageToSave);
>
>     }
>
>
>
>     list($messagesToSend, $recipients, $messageToSave) = buildMessage();
>
>
>
> In the original normal flow of actionID='send_message' these 3 values
>
> are needed by the following lines of code of this switch case.
>
> But now, I must break the flow and show the compose form again
>
> with these 3 values rendered in the form as hidden inputs.
>
> This task is not pretty. For example, $messagesToSend is an array of  
> 3 objects,
>
> one of them is an IMP_MIME wich I have to transform toCanonicalString().
>
> I have not completed this marshalling yet, $recipients and $messageToSave
>
> are missing. Here is a bit of code from /imp/compose.php:
>
>
>
>     /* Prepare the messages in the form to be signed in browser */
>
>     if (isset($messagesToSend)) {
>
>         $canonical_mimes = array();
>
>         foreach ($messagesToSend as $mime_message )
>
>             $canonical_mimes[] = $mime_message['msg']->toCanonicalString();
>
>         $t->set('messagesToSend', $canonical_mimes);
>
>     }
>
>
>
> 4) Render the compose page again.
>
>
>
> This is done in /imp/templates/compose/compose.html:
>
>
>
> <!-- These are the MIMEs to be signed -->
>
> <loop:messagesToSend>
>
> <input type="hidden" name="messagesToSend" value="<tag:messagesToSend />" />
>
> </loop:messagesToSend>
>
>
>
> Wich should write some hmtl code like this:
>
>
>
> <input type="hidden" name="messagesToSend" value="Content-type:  
> text/plain ..." />
>
> <input type="hidden" name="messagesToSend" value="Content-type:  
> text/plain ..." />
>
> <input type="hidden" name="recipients" value="..." />
>
> <input type="hidden" name="messageToSave" value="..." />
>
>
>
> I am missing all code from here. It is not in the patch I attached just now.
>
> 5) Hook on onload event to sign text/plain MIMES.
>
>
>
> With all of this values on the form, I have to hook page onload event
>
> to fire the javascript that takes the text/plain messagesToSend and  
> signs them.
>
>
>
> 6) ReSubmit this form.
>
>
>
> 7) Unmarshall submitted form hidden inputs to carry on.
>
>
>
> The switch structure on /imp/compose.php now looks like this:
>
>
>
> case 'send_message':
>
> case 'compose_mime':
>
>     ...
>
>     if ($actionID == 'compose_mime') {
>
>         $marshall_all_this = $imp_compose->buildMessage(...);
>
>         break;
>
>     }
>
>
>
> case 'send_mime':
>
>
>
>     if ($actionID == 'send_mime') {
>
>         /* We are coming from a form submit */
>
>         $unmarshalled_values = not_implemented_yet(<Util::getFormData()>);
>
>         $sent = $imp_compose->sendMessages($unmarshalled_values);
>
>     } else {
>
>         /* The switch case did not break, so al usual variables are  
> available */
>
>         $sent = $imp_compose->buildAndSendMessage(<usual parameters>);
>
>     }
>
>
>
> 8) Build a multipart/signed for each pair of (text/plain, signature)
>
>
>
> Here's another problem, since now I would need to call buildMessage() again,
>
> so a multipart/signed is composed with every signed text/plain.
>
> Remember, we already called it to compose the text/plain.
>
>
>
> 9) Now send all as usual.
>
>
>
> With the multipart/signed already composed, now I can send the messages
>
> calling the refactored sendMessages().
>
> But before I have to re-construct the parameters we stored as hiddens
>
> in the form to pass them to this functions. Another not pretty task.
>
>
>
> If all this succeeds, the messages are sent as multipart/signed.
>
>
>
> The AJAX way:
>
> ~~~~~~~~~~~~~
>
> Introduction:
>
> -------------
>
> I have written no code at all at this time. I have little experience
>
> with AJAX, so maybe some of this can't be done the way I wished.
>
> This approach should mean very little PHP code changes, plus a better
>
> user experience. I am going to need much advise on how to embed Ajax
>
> in the PHP templates, if this strategy is finally accepted.
>
>
>
> Brief:
>
> ------
>
> 1) Fire the javascript signing function on form submit.
>
> 2) Call imp/lib/Compose.php::IMP_Compose::_createMimeMessage($to,  
> $body, $encrypt)
>
>    via Ajax to compose text/plain MIME(s if multiple recipients).
>
> 3) Sign the text/plain part returned by the Ajax call.
>
> 4) Set the signature(s if multiple recipients) as hidden inputs.
>
> 5) Submit this form with actionID='send_message'.
>
>
>
> Extended:
>
> ---------
>
>
>
> 1) Fire the javascript signing function on form submit.
>
>
>
> This change is already in the first patch. uniqSubmit() function
>
> calls signMessage() if singning has been requested by selecting it
>
> in the drop-down list.
>
>
>
> 2) Call imp/lib/Compose.php::IMP_Compose::_createMimeMessage($to,  
> $body, $encrypt)
>
>    via Ajax to compose text/plain MIME(s if multiple recipients).
>
>
>
> To sign the message we need the message itself as a text/plain MIME.
>
> This is provided by the PHP server side by wrapping the call to
>
> class IMP_Compose. We need to expose _createMimeMessage() method to return
>
> one or multiple text/plain MIMEs depending on how many recipients there are.
>
>
>
> 3) Sign the text/plain part returned by the Ajax call.
>
> & 4) Set the signature(s if multiple recipients) as hidden inputs.
>
>
>
> I sign each text/plain part we retrieved by AJAX, storing each
>
> signature as a form hidden input.
>
>
>
> 5) Submit this form with actionID='send_message'.
>
>
>
> Just go on and submit the form as usual.
>
> Do not encrypt when buildAndSendMessage() calls _createMimeMessage(),
>
> just compose the multipart/signed with the signature provided.
>
> This change is already on the first patch (how do you reference different
>
> patches so not to bring confusion, do you number/timestamp them?).
>
>
>
> Feel free to correct my English. In fact, I would appreciate it.
>
>
>
> Thanks,
>
>
>
> Mariano.
>
>







More information about the bugs mailing list