Kyle Francis
2016-04-01 7ce958ecd987745e545fc40fdc090c6430053b5d
commit | author | age
48e9c1 1 <?php
58c279 2
AM 3 /**
48e9c1 4  +-------------------------------------------------------------------------+
T 5  | Enigma Plugin for Roundcube                                             |
6  |                                                                         |
a99c34 7  | Copyright (C) 2010-2015 The Roundcube Dev Team                          |
48e9c1 8  |                                                                         |
a99c34 9  | Licensed under the GNU General Public License version 3 or              |
AM 10  | any later version with exceptions for skins & plugins.                  |
11  | See the README file for a full license statement.                       |
48e9c1 12  |                                                                         |
T 13  +-------------------------------------------------------------------------+
14  | Author: Aleksander Machniak <alec@alec.pl>                              |
15  +-------------------------------------------------------------------------+
16 */
17
58c279 18 /**
AM 19  * This class contains only hooks and action handlers.
20  * Most plugin logic is placed in enigma_engine and enigma_ui classes.
21  */
48e9c1 22 class enigma extends rcube_plugin
T 23 {
24     public $task = 'mail|settings';
25     public $rc;
26     public $engine;
39f93b 27     public $ui;
48e9c1 28
58c279 29     private $env_loaded = false;
48e9c1 30
T 31
32     /**
33      * Plugin initialization.
34      */
35     function init()
36     {
0878c8 37         $this->rc = rcube::get_instance();
ce89ec 38
48e9c1 39         if ($this->rc->task == 'mail') {
T 40             // message parse/display hooks
0878c8 41             $this->add_hook('message_part_structure', array($this, 'part_structure'));
AM 42             $this->add_hook('message_part_body', array($this, 'part_body'));
48e9c1 43             $this->add_hook('message_body_prefix', array($this, 'status_message'));
T 44
0878c8 45             $this->register_action('plugin.enigmaimport', array($this, 'import_file'));
AM 46
1459f8 47             // load the Enigma plugin configuration
AM 48             $this->load_config();
49
50             $enabled = $this->rc->config->get('enigma_encryption', true);
51
48e9c1 52             // message displaying
392ede 53             if ($this->rc->action == 'show' || $this->rc->action == 'preview' || $this->rc->action == 'print') {
48e9c1 54                 $this->add_hook('message_load', array($this, 'message_load'));
T 55                 $this->add_hook('template_object_messagebody', array($this, 'message_output'));
56             }
57             // message composing
1459f8 58             else if ($enabled && $this->rc->action == 'compose') {
58c279 59                 $this->add_hook('message_compose_body', array($this, 'message_compose'));
AM 60
48e9c1 61                 $this->load_ui();
a99c34 62                 $this->ui->init();
48e9c1 63             }
T 64             // message sending (and draft storing)
1459f8 65             else if ($enabled && $this->rc->action == 'send') {
a99c34 66                 $this->add_hook('message_ready', array($this, 'message_ready'));
48e9c1 67             }
0878c8 68
AM 69             $this->password_handler();
48e9c1 70         }
T 71         else if ($this->rc->task == 'settings') {
72             // add hooks for Enigma settings
0878c8 73             $this->add_hook('settings_actions', array($this, 'settings_actions'));
a99c34 74             $this->add_hook('preferences_sections_list', array($this, 'preferences_sections_list'));
AM 75             $this->add_hook('preferences_list', array($this, 'preferences_list'));
76             $this->add_hook('preferences_save', array($this, 'preferences_save'));
48e9c1 77
T 78             // register handler for keys/certs management
0878c8 79             $this->register_action('plugin.enigmakeys', array($this, 'preferences_ui'));
a99c34 80 //            $this->register_action('plugin.enigmacerts', array($this, 'preferences_ui'));
48e9c1 81
0878c8 82             $this->load_ui();
570f43 83
AM 84             if (empty($_REQUEST['_framed']) || strpos($this->rc->action, 'plugin.enigma') === 0) {
85                 $this->ui->add_css();
86             }
48e9c1 87         }
0878c8 88
AM 89         $this->add_hook('refresh', array($this, 'refresh'));
48e9c1 90     }
T 91
92     /**
93      * Plugin environment initialization.
94      */
95     function load_env()
96     {
0878c8 97         if ($this->env_loaded) {
48e9c1 98             return;
0878c8 99         }
48e9c1 100
T 101         $this->env_loaded = true;
102
103         // Add include path for Enigma classes and drivers
104         $include_path = $this->home . '/lib' . PATH_SEPARATOR;
105         $include_path .= ini_get('include_path');
106         set_include_path($include_path);
107
108         // load the Enigma plugin configuration
109         $this->load_config();
110
111         // include localization (if wasn't included before)
112         $this->add_texts('localization/');
113     }
114
115     /**
116      * Plugin UI initialization.
117      */
0878c8 118     function load_ui($all = false)
48e9c1 119     {
0878c8 120         if (!$this->ui) {
AM 121             // load config/localization
122             $this->load_env();
48e9c1 123
0878c8 124             // Load UI
AM 125             $this->ui = new enigma_ui($this, $this->home);
126         }
48e9c1 127
0878c8 128         if ($all) {
AM 129             $this->ui->add_css();
130             $this->ui->add_js();
131         }
48e9c1 132     }
T 133
134     /**
135      * Plugin engine initialization.
136      */
137     function load_engine()
138     {
0878c8 139         if ($this->engine) {
AM 140             return $this->engine;
141         }
48e9c1 142
T 143         // load config/localization
144         $this->load_env();
145
0878c8 146         return $this->engine = new enigma_engine($this);
48e9c1 147     }
T 148
149     /**
150      * Handler for message_part_structure hook.
151      * Called for every part of the message.
152      *
153      * @param array Original parameters
154      *
155      * @return array Modified parameters
156      */
0878c8 157     function part_structure($p)
48e9c1 158     {
0878c8 159         $this->load_engine();
48e9c1 160
0878c8 161         return $this->engine->part_structure($p);
48e9c1 162     }
T 163
164     /**
0878c8 165      * Handler for message_part_body hook.
AM 166      * Called to get body of a message part.
48e9c1 167      *
T 168      * @param array Original parameters
169      *
170      * @return array Modified parameters
171      */
0878c8 172     function part_body($p)
AM 173     {
174         $this->load_engine();
175
176         return $this->engine->part_body($p);
177     }
178
179     /**
180      * Handler for settings_actions hook.
181      * Adds Enigma settings section into preferences.
182      *
183      * @param array Original parameters
184      *
185      * @return array Modified parameters
186      */
187     function settings_actions($args)
48e9c1 188     {
T 189         // add labels
190         $this->add_texts('localization/');
0878c8 191
AM 192         // register as settings action
193         $args['actions'][] = array(
194             'action' => 'plugin.enigmakeys',
195             'class'  => 'enigma keys',
196             'label'  => 'enigmakeys',
197             'title'  => 'enigmakeys',
198             'domain' => 'enigma',
199         );
3e98f8 200 /*
0878c8 201         $args['actions'][] = array(
AM 202             'action' => 'plugin.enigmacerts',
203             'class'  => 'enigma certs',
204             'label'  => 'enigmacerts',
205             'title'  => 'enigmacerts',
206             'domain' => 'enigma',
48e9c1 207         );
3e98f8 208 */
0878c8 209         return $args;
48e9c1 210     }
T 211
212     /**
a99c34 213      * Handler for preferences_sections_list hook.
AM 214      * Adds Encryption settings section into preferences sections list.
215      *
216      * @param array Original parameters
217      *
218      * @return array Modified parameters
219      */
220     function preferences_sections_list($p)
221     {
222         $p['list']['enigma'] = array(
223             'id' => 'enigma', 'section' => $this->gettext('encryption'),
224         );
225
226         return $p;
227     }
228
229     /**
48e9c1 230      * Handler for preferences_list hook.
T 231      * Adds options blocks into Enigma settings sections in Preferences.
232      *
233      * @param array Original parameters
234      *
235      * @return array Modified parameters
236      */
237     function preferences_list($p)
238     {
a99c34 239         if ($p['section'] != 'enigma') {
AM 240             return $p;
48e9c1 241         }
a99c34 242
AM 243         $no_override = array_flip((array)$this->rc->config->get('dont_override'));
244
245         $p['blocks']['main']['name'] = $this->gettext('mainoptions');
246
1459f8 247         if (!isset($no_override['enigma_encryption'])) {
AM 248             if (!$p['current']) {
249                 $p['blocks']['main']['content'] = true;
250                 return $p;
251             }
252
253             $field_id = 'rcmfd_enigma_encryption';
254             $input    = new html_checkbox(array(
255                     'name'  => '_enigma_encryption',
256                     'id'    => $field_id,
257                     'value' => 1,
258             ));
259
260             $p['blocks']['main']['options']['enigma_encryption'] = array(
261                 'title'   => html::label($field_id, $this->gettext('supportencryption')),
262                 'content' => $input->show(intval($this->rc->config->get('enigma_encryption'))),
263             );
264         }
265
765736 266         if (!isset($no_override['enigma_signatures'])) {
AM 267             if (!$p['current']) {
268                 $p['blocks']['main']['content'] = true;
269                 return $p;
270             }
271
272             $field_id = 'rcmfd_enigma_signatures';
273             $input    = new html_checkbox(array(
274                     'name'  => '_enigma_signatures',
275                     'id'    => $field_id,
276                     'value' => 1,
277             ));
278
279             $p['blocks']['main']['options']['enigma_signatures'] = array(
280                 'title'   => html::label($field_id, $this->gettext('supportsignatures')),
281                 'content' => $input->show(intval($this->rc->config->get('enigma_signatures'))),
282             );
283         }
284
285         if (!isset($no_override['enigma_decryption'])) {
286             if (!$p['current']) {
287                 $p['blocks']['main']['content'] = true;
288                 return $p;
289             }
290
291             $field_id = 'rcmfd_enigma_decryption';
292             $input    = new html_checkbox(array(
293                     'name'  => '_enigma_decryption',
294                     'id'    => $field_id,
295                     'value' => 1,
296             ));
297
298             $p['blocks']['main']['options']['enigma_decryption'] = array(
299                 'title'   => html::label($field_id, $this->gettext('supportdecryption')),
300                 'content' => $input->show(intval($this->rc->config->get('enigma_decryption'))),
301             );
302         }
303
a99c34 304         if (!isset($no_override['enigma_sign_all'])) {
AM 305             if (!$p['current']) {
306                 $p['blocks']['main']['content'] = true;
307                 return $p;
308             }
309
310             $field_id = 'rcmfd_enigma_sign_all';
311             $input    = new html_checkbox(array(
312                     'name'  => '_enigma_sign_all',
313                     'id'    => $field_id,
314                     'value' => 1,
315             ));
316
317             $p['blocks']['main']['options']['enigma_sign_all'] = array(
318                 'title'   => html::label($field_id, $this->gettext('signdefault')),
319                 'content' => $input->show($this->rc->config->get('enigma_sign_all') ? 1 : 0),
320             );
321         }
322
323         if (!isset($no_override['enigma_encrypt_all'])) {
324             if (!$p['current']) {
325                 $p['blocks']['main']['content'] = true;
326                 return $p;
327             }
328
329             $field_id = 'rcmfd_enigma_encrypt_all';
330             $input    = new html_checkbox(array(
331                     'name'  => '_enigma_encrypt_all',
332                     'id'    => $field_id,
333                     'value' => 1,
334             ));
335
336             $p['blocks']['main']['options']['enigma_encrypt_all'] = array(
337                 'title'   => html::label($field_id, $this->gettext('encryptdefault')),
338                 'content' => $input->show($this->rc->config->get('enigma_encrypt_all') ? 1 : 0),
339             );
340         }
341
7ce958 342         if (!isset($no_override['enigma_attach_pubkey'])) {
KF 343             if (!$p['current']) {
344                 $p['blocks']['main']['content'] = true;
345                 return $p;
346             }
347
348             $field_id = 'rcmfd_enigma_attach_pubkey';
349             $input    = new html_checkbox(array(
350                     'name'  => '_enigma_attach_pubkey',
351                     'id'    => $field_id,
352                     'value' => 1,
353             ));
354
355             $p['blocks']['main']['options']['enigma_encrypt_all'] = array(
356                 'title'   => html::label($field_id, $this->gettext('attachpubkeydefault')),
357                 'content' => $input->show($this->rc->config->get('enigma_attach_pubkey') ? 1 : 0),
358             );
359         }
360
765736 361         if (!isset($no_override['enigma_password_time'])) {
AM 362             if (!$p['current']) {
363                 $p['blocks']['main']['content'] = true;
364                 return $p;
365             }
366
367             $field_id = 'rcmfd_enigma_password_time';
368             $select   = new html_select(array('name' => '_enigma_password_time', 'id' => $field_id));
369
370             foreach (array(1, 5, 10, 15, 30) as $m) {
371                 $label = $this->gettext(array('name' => 'nminutes', 'vars' => array('m' => $m)));
372                 $select->add($label, $m);
373             }
374             $select->add($this->gettext('wholesession'), 0);
375
376             $p['blocks']['main']['options']['enigma_password_time'] = array(
377                 'title'   => html::label($field_id, $this->gettext('passwordtime')),
378                 'content' => $select->show(intval($this->rc->config->get('enigma_password_time'))),
379             );
380         }
381
48e9c1 382         return $p;
T 383     }
384
385     /**
386      * Handler for preferences_save hook.
387      * Executed on Enigma settings form submit.
388      *
389      * @param array Original parameters
390      *
391      * @return array Modified parameters
392      */
393     function preferences_save($p)
394     {
a99c34 395         if ($p['section'] == 'enigma') {
AM 396             $p['prefs'] = array(
1459f8 397                 'enigma_signatures'    => (bool) rcube_utils::get_input_value('_enigma_signatures', rcube_utils::INPUT_POST),
AM 398                 'enigma_decryption'    => (bool) rcube_utils::get_input_value('_enigma_decryption', rcube_utils::INPUT_POST),
399                 'enigma_encryption'    => (bool) rcube_utils::get_input_value('_enigma_encryption', rcube_utils::INPUT_POST),
400                 'enigma_sign_all'      => (bool) rcube_utils::get_input_value('_enigma_sign_all', rcube_utils::INPUT_POST),
401                 'enigma_encrypt_all'   => (bool) rcube_utils::get_input_value('_enigma_encrypt_all', rcube_utils::INPUT_POST),
7ce958 402                 'enigma_attach_pubkey' => (bool) rcube_utils::get_input_value('_enigma_attach_pubkey', rcube_utils::INPUT_POST),
765736 403                 'enigma_password_time' => intval(rcube_utils::get_input_value('_enigma_password_time', rcube_utils::INPUT_POST)),
48e9c1 404             );
T 405         }
a99c34 406
48e9c1 407         return $p;
T 408     }
409
410     /**
411      * Handler for keys/certs management UI template.
412      */
413     function preferences_ui()
414     {
415         $this->load_ui();
0878c8 416
48e9c1 417         $this->ui->init();
T 418     }
419
420     /**
421      * Handler for message_body_prefix hook.
422      * Called for every displayed (content) part of the message.
423      * Adds infobox about signature verification and/or decryption
424      * status above the body.
425      *
426      * @param array Original parameters
427      *
428      * @return array Modified parameters
429      */
430     function status_message($p)
431     {
0878c8 432         $this->load_ui();
48e9c1 433
0878c8 434         return $this->ui->status_message($p);
48e9c1 435     }
T 436
437     /**
438      * Handler for message_load hook.
439      * Check message bodies and attachments for keys/certs.
440      */
441     function message_load($p)
442     {
0878c8 443         $this->load_ui();
2193f6 444
0878c8 445         return $this->ui->message_load($p);
48e9c1 446     }
T 447
448     /**
449      * Handler for template_object_messagebody hook.
450      * This callback function adds a box below the message content
451      * if there is a key/cert attachment available
452      */
453     function message_output($p)
454     {
0878c8 455         $this->load_ui();
48e9c1 456
0878c8 457         return $this->ui->message_output($p);
48e9c1 458     }
T 459
460     /**
461      * Handler for attached keys/certs import
462      */
463     function import_file()
464     {
465         $this->load_engine();
0878c8 466
48e9c1 467         $this->engine->import_file();
T 468     }
469
470     /**
0878c8 471      * Handle password submissions
48e9c1 472      */
0878c8 473     function password_handler()
48e9c1 474     {
0878c8 475         $this->load_engine();
a99c34 476
0878c8 477         $this->engine->password_handler();
AM 478     }
479
480     /**
a99c34 481      * Handle message_ready hook (encryption/signing)
AM 482      */
483     function message_ready($p)
484     {
485         $this->load_ui();
486
487         return $this->ui->message_ready($p);
488     }
489
490     /**
58c279 491      * Handle message_compose_body hook
AM 492      */
493     function message_compose($p)
494     {
495         $this->load_ui();
496
497         return $this->ui->message_compose($p);
498     }
499
500     /**
0878c8 501      * Handler for refresh hook.
AM 502      */
503     function refresh($p)
504     {
505         // calling enigma_engine constructor to remove passwords
506         // stored in session after expiration time
507         $this->load_engine();
508
509         return $p;
48e9c1 510     }
T 511 }