GnuPG 2.1: Support password input on private key export

pull/5498/head
Aleksander Machniak 8 years ago
parent 7829da358d
commit ecefdca21d

@ -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 = $('<form>').attr({target: id, method: 'post', style: 'display:none',
action: '?_action=plugin.enigmakeys&_task=settings&_a=export'}),
iframe = $('<iframe>').attr({name: id, style: 'display:none'})
form.append($('<input>').attr({name: '_token', value: this.env.request_token}));
$.each(data, function(i, v) {
form.append($('<input>').attr({name: i, value: v}));
});
iframe.appendTo(document.body);
form.appendTo(document.body).submit();
};
// Submit key(s) import form
@ -521,7 +539,7 @@ rcube_webmail.prototype.enigma_password_submit = function(data)
return this.enigma_password_compose_submit(data);
}
var lock = this.set_busy(true, 'loading'),
var lock = data.nolock ? null : this.set_busy(true, 'loading'),
form = $('<form>').attr({method: 'post', action: data.action || location.href, style: 'display:none'})
.append($('<input>').attr({type: 'hidden', name: '_keyid', value: data.key}))
.append($('<input>').attr({type: 'hidden', name: '_passwd', value: data.password}))

@ -85,6 +85,8 @@ class enigma extends rcube_plugin
if (empty($_REQUEST['_framed']) || strpos($this->rc->action, 'plugin.enigma') === 0) {
$this->ui->add_css();
}
$this->password_handler();
}
else if ($this->rc->task == 'cli') {
$this->add_hook('user_delete_commit', array($this, 'user_delete'));

@ -90,10 +90,11 @@ abstract class enigma_driver
*
* @param string Key ID
* @param bool Include private key
* @param array Optional key => password map
*
* @return mixed Key content or enigma_error
*/
abstract function export($key, $with_private = false);
abstract function export($key, $with_private = false, $passwords = array());
/**
* Keys listing.

@ -230,15 +230,21 @@ class enigma_driver_gnupg extends enigma_driver
*
* @param string Key ID
* @param bool Include private key
* @param array Optional key => password map
*
* @return mixed Key content or enigma_error
*/
public function export($keyid, $with_private = false)
public function export($keyid, $with_private = false, $passwords = array())
{
try {
$key = $this->gpg->exportPublicKey($keyid, true);
if ($with_private) {
// GnuPG 2.1 requires secret key passphrases on export
foreach ($passwords as $keyid => $pass) {
$this->gpg->addPassphrase($keyid, $pass);
}
$priv = $this->gpg->exportPrivateKey($keyid, true);
$key .= $priv;
}

@ -126,7 +126,7 @@ class enigma_driver_phpssl extends enigma_driver
{
}
public function export($key, $with_private = false)
public function export($key, $with_private = false, $passwords = array())
{
}

@ -1145,7 +1145,7 @@ class enigma_engine
function export_key($key, $fp = null, $include_private = false)
{
$this->load_pgp_driver();
$result = $this->pgp_driver->export($key, $include_private);
$result = $this->pgp_driver->export($key, $include_private, $this->get_passwords());
if ($result instanceof enigma_error) {
rcube::raise_error(array(

@ -161,7 +161,10 @@ class enigma_ui
$data = array_merge($params, $data);
}
if ($this->rc->action == 'send' || $this->rc->action == 'plugin.enigmaimport') {
// @TODO: Get user name/address when keyid == user,
// it may happen on GnuPG 2.1
if (preg_match('/^(send|plugin.enigmaimport|plugin.enigmakeys)$/', $this->rc->action)) {
$this->rc->output->command('enigma_password_request', $data);
}
else {
@ -464,28 +467,51 @@ class enigma_ui
*/
private function key_export()
{
$this->rc->request_security_check(rcube_utils::INPUT_GET);
$keys = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_GPC);
$priv = rcube_utils::get_input_value('_priv', rcube_utils::INPUT_GPC);
$keys = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_POST);
$priv = rcube_utils::get_input_value('_priv', rcube_utils::INPUT_POST);
$engine = $this->enigma->load_engine();
$list = $keys == '*' ? $engine->list_keys() : explode(',', $keys);
if (is_array($list)) {
if (is_array($list) && ($fp = fopen('php://memory', 'rw'))) {
$filename = 'export.pgp';
if (count($list) == 1) {
$filename = (is_object($list[0]) ? $list[0]->id : $list[0]) . '.pgp';
}
$status = null;
foreach ($list as $key) {
$status = $engine->export_key(is_object($key) ? $key->id : $key, $fp, (bool) $priv);
if ($status instanceof enigma_error) {
$code = $status->getCode();
// No/bad passphrase, display error and ask for pass
if ($code == enigma_error::BADPASS) {
$this->password_prompt($status, array(
'input_keys' => $keys,
'input_priv' => 1,
'input_task' => 'settings',
'input_action' => 'plugin.enigmakeys',
'input_a' => 'export',
'action' => '?',
'iframe' => true,
'nolock' => true,
));
fclose($fp);
$this->rc->output->send('iframe');
}
}
}
// send downlaod headers
header('Content-Type: application/pgp-keys');
header('Content-Disposition: attachment; filename="' . $filename . '"');
if ($fp = fopen('php://output', 'w')) {
foreach ($list as $key) {
$engine->export_key(is_object($key) ? $key->id : $key, $fp, (bool) $priv);
}
rewind($fp);
while (!feof($fp)) {
echo fread($fp, 1024 * 1024);
}
fclose($fp);
}
exit;
@ -1075,7 +1101,7 @@ class enigma_ui
));
}
else {
$this->rc->output->show_message($msg, $type ?: 'error', $vars);
$this->rc->output->show_message($msg, 'error', $vars);
}
}

Loading…
Cancel
Save