From fba3e1ae0c0f4c1d73f55b9f97674c3ed7e695e0 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 25 Sep 2016 08:35:18 +0200 Subject: [PATCH 1/4] GnuPG 2.1: Add option to configure gpgconf binary location --- plugins/enigma/config.inc.php.dist | 4 ++++ plugins/enigma/lib/enigma_driver_gnupg.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/plugins/enigma/config.inc.php.dist b/plugins/enigma/config.inc.php.dist index 581ac8534..aa4280f41 100644 --- a/plugins/enigma/config.inc.php.dist +++ b/plugins/enigma/config.inc.php.dist @@ -24,6 +24,10 @@ $config['enigma_pgp_binary'] = ''; // It's used with GnuPG 2.x. $config['enigma_pgp_agent'] = ''; +// Location of gpgconf binary. By default it will be auto-detected. +// It's used with GnuPG >= 2.1. +$config['enigma_pgp_gpgconf'] = ''; + // Enables signatures verification feature. $config['enigma_signatures'] = true; diff --git a/plugins/enigma/lib/enigma_driver_gnupg.php b/plugins/enigma/lib/enigma_driver_gnupg.php index 3c02f9f43..267af4fd1 100644 --- a/plugins/enigma/lib/enigma_driver_gnupg.php +++ b/plugins/enigma/lib/enigma_driver_gnupg.php @@ -43,6 +43,7 @@ class enigma_driver_gnupg extends enigma_driver $debug = $this->rc->config->get('enigma_debug'); $binary = $this->rc->config->get('enigma_pgp_binary'); $agent = $this->rc->config->get('enigma_pgp_agent'); + $gpgconf = $this->rc->config->get('enigma_pgp_gpgconf'); if (!$homedir) { return new enigma_error(enigma_error::INTERNAL, @@ -88,6 +89,9 @@ class enigma_driver_gnupg extends enigma_driver if ($agent) { $options['agent'] = $agent; } + if ($gpgconf) { + $options['gpgconf'] = $gpgconf; + } // Create Crypt_GPG object try { From 7829da358d80bc0a07b6b86dfc01f52abe7bce2f Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 25 Sep 2016 13:05:21 +0200 Subject: [PATCH 2/4] GnuPG 2.1: Fix importing newly generated (secret) keys using GnuPG 2.1 --- plugins/enigma/enigma.js | 5 +++-- plugins/enigma/lib/enigma_driver.php | 7 ++++--- plugins/enigma/lib/enigma_driver_gnupg.php | 14 ++++++++++---- plugins/enigma/lib/enigma_driver_phpssl.php | 2 +- plugins/enigma/lib/enigma_engine.php | 6 +++--- plugins/enigma/lib/enigma_ui.php | 3 ++- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/plugins/enigma/enigma.js b/plugins/enigma/enigma.js index 081fea21b..3dc3e9a89 100644 --- a/plugins/enigma/enigma.js +++ b/plugins/enigma/enigma.js @@ -99,7 +99,7 @@ rcube_webmail.prototype.enigma_key_create_save = function() size = $('#key-size').val(); $('[name="identity[]"]:checked').each(function() { - users.push(this.value); + users.push(this.value); }); // validate the form @@ -124,7 +124,8 @@ rcube_webmail.prototype.enigma_key_create_save = function() openpgp.generateKeyPair(options).then(function(keypair) { // success - var post = {_a: 'import', _keys: keypair.privateKeyArmored, _generated: 1}; + var post = {_a: 'import', _keys: keypair.privateKeyArmored, _generated: 1, + _passwd: password, _keyid: keypair.key.primaryKey.fingerprint}; // send request to server rcmail.http_post('plugin.enigmakeys', post, lock); diff --git a/plugins/enigma/lib/enigma_driver.php b/plugins/enigma/lib/enigma_driver.php index 1ed5fbc3d..eaa4364b4 100644 --- a/plugins/enigma/lib/enigma_driver.php +++ b/plugins/enigma/lib/enigma_driver.php @@ -77,12 +77,13 @@ abstract class enigma_driver /** * Key/Cert file import. * - * @param string File name or file content - * @param bollean True if first argument is a filename + * @param string File name or file content + * @param bolean True if first argument is a filename + * @param array Optional key => password map * * @return mixed Import status array or enigma_error */ - abstract function import($content, $isfile = false); + abstract function import($content, $isfile = false, $passwords = array()); /** * Key/Cert export. diff --git a/plugins/enigma/lib/enigma_driver_gnupg.php b/plugins/enigma/lib/enigma_driver_gnupg.php index 267af4fd1..b6f87946e 100644 --- a/plugins/enigma/lib/enigma_driver_gnupg.php +++ b/plugins/enigma/lib/enigma_driver_gnupg.php @@ -201,14 +201,20 @@ class enigma_driver_gnupg extends enigma_driver /** * Key file import. * - * @param string File name or file content - * @param bollean True if first argument is a filename + * @param string File name or file content + * @param bolean True if first argument is a filename + * @param array Optional key => password map * * @return mixed Import status array or enigma_error */ - public function import($content, $isfile=false) + public function import($content, $isfile = false, $passwords = array()) { try { + // GnuPG 2.1 requires secret key passphrases on import + foreach ($passwords as $keyid => $pass) { + $this->gpg->addPassphrase($keyid, $pass); + } + if ($isfile) return $this->gpg->importKeyFile($content); else @@ -251,7 +257,7 @@ class enigma_driver_gnupg extends enigma_driver * * @return mixed Array of enigma_key objects or enigma_error */ - public function list_keys($pattern='') + public function list_keys($pattern = '') { try { $keys = $this->gpg->getKeys($pattern); diff --git a/plugins/enigma/lib/enigma_driver_phpssl.php b/plugins/enigma/lib/enigma_driver_phpssl.php index 967811da0..8cffc62f0 100644 --- a/plugins/enigma/lib/enigma_driver_phpssl.php +++ b/plugins/enigma/lib/enigma_driver_phpssl.php @@ -122,7 +122,7 @@ class enigma_driver_phpssl extends enigma_driver return $sig; } - public function import($content, $isfile=false) + public function import($content, $isfile = false, $passwords = array()) { } diff --git a/plugins/enigma/lib/enigma_engine.php b/plugins/enigma/lib/enigma_engine.php index f32367789..f75be3657 100644 --- a/plugins/enigma/lib/enigma_engine.php +++ b/plugins/enigma/lib/enigma_engine.php @@ -1113,10 +1113,10 @@ class enigma_engine * * @return mixed Import status data array or enigma_error */ - function import_key($content, $isfile=false) + function import_key($content, $isfile = false) { $this->load_pgp_driver(); - $result = $this->pgp_driver->import($content, $isfile); + $result = $this->pgp_driver->import($content, $isfile, $this->get_passwords()); if ($result instanceof enigma_error) { rcube::raise_error(array( @@ -1174,7 +1174,7 @@ class enigma_engine $passwd = rcube_utils::get_input_value('_passwd', rcube_utils::INPUT_POST, true); if ($keyid && $passwd !== null && strlen($passwd)) { - $this->save_password($keyid, $passwd); + $this->save_password(strtoupper($keyid), $passwd); } } diff --git a/plugins/enigma/lib/enigma_ui.php b/plugins/enigma/lib/enigma_ui.php index b7fc01161..650ea2166 100644 --- a/plugins/enigma/lib/enigma_ui.php +++ b/plugins/enigma/lib/enigma_ui.php @@ -498,8 +498,9 @@ class enigma_ui { // Import process if ($data = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_POST)) { - // Import from generation form (ajax request) $this->enigma->load_engine(); + $this->enigma->engine->password_handler(); + $result = $this->enigma->engine->import_key($data); if (is_array($result)) { From ecefdca21dba3bce4dc597a48bf93b67931f6c94 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 23 Oct 2016 15:51:28 +0200 Subject: [PATCH 3/4] GnuPG 2.1: Support password input on private key export --- plugins/enigma/enigma.js | 30 ++++++++++--- plugins/enigma/enigma.php | 2 + plugins/enigma/lib/enigma_driver.php | 3 +- plugins/enigma/lib/enigma_driver_gnupg.php | 8 +++- plugins/enigma/lib/enigma_driver_phpssl.php | 2 +- plugins/enigma/lib/enigma_engine.php | 2 +- plugins/enigma/lib/enigma_ui.php | 48 ++++++++++++++++----- 7 files changed, 74 insertions(+), 21 deletions(-) diff --git a/plugins/enigma/enigma.js b/plugins/enigma/enigma.js index 3dc3e9a89..f5ae0e4ac 100644 --- a/plugins/enigma/enigma.js +++ b/plugins/enigma/enigma.js @@ -167,12 +167,12 @@ rcube_webmail.prototype.enigma_export = function(selected) var priv = false, list = this.keys_list, keys = selected ? list.get_selection().join(',') : '*', - args = {_a: 'export', _keys: keys}; + args = {_keys: keys}; if (!keys.length) return; - // find out wether selected keys are private + // find out whether selected keys are private if (keys == '*') priv = true; else @@ -192,7 +192,7 @@ rcube_webmail.prototype.enigma_export = function(selected) [{ text: this.get_label('enigma.onlypubkeys'), click: function(e) { - rcmail.goto_url('plugin.enigmakeys', args, false, true); + rcmail.enigma_export_submit(args); $(this).remove(); } }, @@ -200,14 +200,32 @@ rcube_webmail.prototype.enigma_export = function(selected) text: this.get_label('enigma.withprivkeys'), click: function(e) { args._priv = 1; - rcmail.goto_url('plugin.enigmakeys', args, false, true); + rcmail.enigma_export_submit(args); $(this).remove(); } }], {width: 400} ); - this.goto_url('plugin.enigmakeys', args, false, true); + this.enigma_export_submit(args); +}; + +// Sumbitting request for key(s) export +// Done this way to handle password input +rcube_webmail.prototype.enigma_export_submit = function(data) +{ + var id = 'keyexport-' + new Date().getTime(), + form = $('
').attr({target: id, method: 'post', style: 'display:none', + action: '?_action=plugin.enigmakeys&_task=settings&_a=export'}), + iframe = $('