Integrates the PGP support with the web interface.
authorx2003bruneau <x2003bruneau@9869982d-c50d-0410-be91-f2a2ec7c7c7b>
Tue, 12 Jun 2007 20:03:09 +0000 (20:03 +0000)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Fri, 4 Jan 2008 23:35:47 +0000 (00:35 +0100)
Some bugfixes and improvements

 Changelog                               |    4 ++++
 banana/banana.inc.php.in                |    4 ++++
 banana/message.inc.php                  |   21 +++++++++++++++++++++
 banana/mimepart.inc.php                 |   19 +++++++++++++++----
 banana/templates/banana-message.inc.tpl |   27 ++++++++++++++++++++++++++-
 5 files changed, 70 insertions(+), 5 deletions(-)

git-svn-id: svn+ssh://murphy/home/svn/banana/trunk@266 9869982d-c50d-0410-be91-f2a2ec7c7c7b

Changelog
banana/banana.inc.php.in
banana/message.inc.php
banana/mimepart.inc.php
banana/templates/banana-message.inc.tpl
img/accept.gif [new file with mode: 0644]
img/error.gif [new file with mode: 0644]
img/exclamation.gif [new file with mode: 0644]

index 15f1094..c2c85ff 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,7 @@
+Tue, 12 Jun 2007                                       Florent Bruneau <florent.bruneau@m4x.org>
+
+       * PGP signature check
+
 Wed, 30 May 2007                                       Florent Bruneau <florent.bruneau@m4x.org>
 
        * Bugfix: references compliance
index 34ae838..386e4c1 100644 (file)
@@ -56,6 +56,10 @@ class Banana
     static public $msgshow_withthread = true;
     static public $msgshow_javascript = true;
 
+    static public $msgshow_pgpcheck   = true;
+    static public $msgshow_pgppath    = 'gpg';
+    static public $msgshow_pgpoptions = '';
+
     /** Match an url
      * Should be included in a regexp delimited using /, !, , or @ (eg: "/$url_regexp/ui")
      * If it matches, return 3 main parts :
index 5caa802..ed733d1 100644 (file)
@@ -310,6 +310,27 @@ final class BananaMessage extends BananaMimePart
     {
         return Banana::$protocole->canSend();
     }
+
+    public function getSignature()
+    {
+        $email = $this->getHeaderValue('from');
+        if (preg_match('/<?([^ <]+@[^ >]+)>?/', $email, $matches)) {
+            $email = $matches[1];
+        }
+        $signature = BananaMimePart::getSignature();
+        if (empty($signature)) {
+            return $signature;
+        } else {
+            foreach ($signature['identity'] as $ident) {
+                if (strpos($ident, "<$email>") !== false) {
+                    return $signature;
+                }
+            }
+            $signature['certified'] = false;
+            $signature['certification_error'] = 'mauvaise identité';
+        }
+        return $signature;
+    }
 }
 
 // vim:set et sw=4 sts=4 ts=4 enc=utf-8:
index ef549c6..0446640 100644 (file)
@@ -179,7 +179,7 @@ class BananaMimePart
             if (empty($filename)) {
                 $filename = $this->getHeader('content-type', '/name="?([^"]+)"?/');
             }
-        } 
+        }
         list($type, $subtype) = explode('/', $content_type);
         switch ($type) {
           case 'text': case 'message':
@@ -221,7 +221,7 @@ class BananaMimePart
             $newpart = new BananaMimePart($part);
             if (!is_null($newpart->content_type)) {
                 if ($signed && $newpart->content_type == $this->signature['protocole']) { 
-                    $signature = $newpart->body; 
+                    $signature = $newpart->body;
                 } elseif ($signed) { 
                     $signed_message = $part; 
                 } 
@@ -643,15 +643,20 @@ class BananaMimePart
 
     private function checkPGPSignature($signature, $message = null)
     {
+        if (!Banana::$msgshow_pgpcheck) {
+            return true;
+        }
         $signname = tempnam(Banana::$spool_root, 'banana_pgp_');
+        $gpg = 'LC_ALL="en_US" ' . Banana::$msgshow_pgppath . ' ' . Banana::$msgshow_pgpoptions . ' --verify '
+                .  $signname . '.asc ';
         file_put_contents($signname. '.asc', $signature);
         $gpg_check = array();
         if (!is_null($message)) {
             file_put_contents($signname, str_replace(array("\r\n", "\n"), array("\n", "\r\n"), $message));
-            exec('LC_ALL="en_US" gpg --verify ' . $signname . '.asc ' . $signname . ' 2>&1', $gpg_check, $result);
+            exec($gpg . $signname . ' 2>&1', $gpg_check, $result);
             unlink($signname);
         } else {
-            exec('LC_ALL="en_US" gpg --verify ' . $signname . '.asc 2&>1', $gpg_check, $result);
+            exec($gpg . '2&>1', $gpg_check, $result);
         }
         unlink("$signname.asc");
         if (preg_match('/Signature made (.+) using (.+) key ID (.+)/', array_shift($gpg_check), $matches)) {
@@ -665,9 +670,11 @@ class BananaMimePart
         if (preg_match('/Good signature from "(.+)"/', $signature, $matches)) {
             $this->signature['verify'] = true;
             $this->signature['identity'] = array($matches[1]);
+            $this->signature['certified'] = true;
         } elseif (preg_match('/BAD signature from "(.+)"/', $signature, $matches)) {
             $this->signature['verify'] = false;
             $this->signature['identity'] = array($matches[1]);
+            $this->signature['certified'] = false;
         } else {
             return false;
         }
@@ -675,6 +682,10 @@ class BananaMimePart
             if (preg_match('/aka "(.+)"/', $aka, $matches)) {
                 $this->signature['identity'][] = $matches[1];
             }
+            if (preg_match('/This key is not certified with a trusted signature!/', $aka)) {
+                $this->signature['certified'] = false;
+                $this->signature['certification_error'] = _b_("identité non confirmée");
+            }
         }
         return true;
     }
index b55bc3e..8a07445 100644 (file)
@@ -43,7 +43,7 @@
   {assign var=files value=$message->getAttachments()}
   {if $files|@count}
   <tr class="pair">
-    <td class="hdr">Fichiers joints</td>
+    <td class="hdr">{"Fichiers joints"|b}</td>
     <td colspan="2">
       {foreach from=$files item=file name=attachs}
       {imglink img=save alt="Enregistrer"|b group=$group artid=$artid part=$file->getFilename() text=$file->getFilename()}{if !$smarty.foreach.attachs.last}, {/if}
     </td>
   </tr>
   {/if}
+  {assign var=signature value=$message->getSignature()}
+  {if $signature|@count}
+  <tr class="pair">
+    <td class="hdr">{"Signature"|b}</td>
+    <td colspan="2">
+      {if $signature.verify && $signature.certified}
+      {img img=accept alt="Signature valide par une clé de confiance"|b}
+      {elseif $signature.verify}
+      {img img=error alt="Signature valide par une clé non vérifiée"|b}
+      {else}
+      {img img=exclamation alt="Signature non valide"|b}
+      {/if}
+      <strong>
+        {if $signature.verify}<span class="ok">{"Valide"|b}...</span>
+        {else}<span class="erreur">{"Non valide"|b}...</span>{/if}
+      </strong>&nbsp;
+      {"Message signé par la clé"|b} {$signature.key.format}:{$signature.key.id}
+      {if $signature.certified}
+        (<span class="ok">{"identité vérifiée"|b}</span>)
+      {else}
+        (<span class="erreur">{"non vérifiée"|b}</span>&nbsp;: {$signature.certification_error})
+      {/if}
+    </td>
+  </tr>
+  {/if}
   {assign var=alter value=$message->getAlternatives()}
   {if $alter|@count}
   <tr class="pair">
diff --git a/img/accept.gif b/img/accept.gif
new file mode 100644 (file)
index 0000000..95af123
Binary files /dev/null and b/img/accept.gif differ
diff --git a/img/error.gif b/img/error.gif
new file mode 100644 (file)
index 0000000..ce65ef2
Binary files /dev/null and b/img/error.gif differ
diff --git a/img/exclamation.gif b/img/exclamation.gif
new file mode 100644 (file)
index 0000000..289be43
Binary files /dev/null and b/img/exclamation.gif differ