Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2534192
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
61 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/plugins/enigma/config.inc.php.dist b/plugins/enigma/config.inc.php.dist
index 17e3265b6..57dfcad81 100644
--- a/plugins/enigma/config.inc.php.dist
+++ b/plugins/enigma/config.inc.php.dist
@@ -1,44 +1,47 @@
<?php
// Enigma Plugin options
// --------------------
// A driver to use for PGP. Default: "gnupg".
$config['enigma_pgp_driver'] = 'gnupg';
// A driver to use for S/MIME. Default: "phpssl".
$config['enigma_smime_driver'] = 'phpssl';
// Keys directory for all users. Default 'enigma/home'.
// Must be writeable by PHP process
$config['enigma_pgp_homedir'] = null;
// Enables signatures verification feature.
$config['enigma_signatures'] = true;
// Enables messages decryption feature.
$config['enigma_decryption'] = true;
// Enables messages encryption and signing feature.
$config['enigma_encryption'] = true;
// Enable signing all messages by default
$config['enigma_sign_all'] = false;
// Enable encrypting all messages by default
$config['enigma_encrypt_all'] = false;
+// Enable signing all messages by default
+$config['enigma_attach_pubkey'] = false;
+
// Default for how long to store private key passwords (in minutes).
// When set to 0 passwords will be stored for the whole session.
$config['enigma_password_time'] = 5;
// Enables server-side keys generation which would be used
// if user browser does not support web-crypto features.
//
// WARNING: Key generation requires true random numbers, and as such can be
// slow. If the operating system runs out of entropy, key generation will
// block until more entropy is available.
//
// To solve that a hardware entropy generator or
// an entropy gathering daemon may be installed (e.g. randomsound).
$config['enigma_keygen_server'] = false;
diff --git a/plugins/enigma/enigma.php b/plugins/enigma/enigma.php
index 8e8ded2a1..c9471acbc 100644
--- a/plugins/enigma/enigma.php
+++ b/plugins/enigma/enigma.php
@@ -1,491 +1,511 @@
<?php
/**
+-------------------------------------------------------------------------+
| Enigma Plugin for Roundcube |
| |
| Copyright (C) 2010-2015 The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
+-------------------------------------------------------------------------+
| Author: Aleksander Machniak <alec@alec.pl> |
+-------------------------------------------------------------------------+
*/
/**
* This class contains only hooks and action handlers.
* Most plugin logic is placed in enigma_engine and enigma_ui classes.
*/
class enigma extends rcube_plugin
{
public $task = 'mail|settings';
public $rc;
public $engine;
public $ui;
private $env_loaded = false;
/**
* Plugin initialization.
*/
function init()
{
$this->rc = rcube::get_instance();
if ($this->rc->task == 'mail') {
// message parse/display hooks
$this->add_hook('message_part_structure', array($this, 'part_structure'));
$this->add_hook('message_part_body', array($this, 'part_body'));
$this->add_hook('message_body_prefix', array($this, 'status_message'));
$this->register_action('plugin.enigmaimport', array($this, 'import_file'));
// load the Enigma plugin configuration
$this->load_config();
$enabled = $this->rc->config->get('enigma_encryption', true);
// message displaying
if ($this->rc->action == 'show' || $this->rc->action == 'preview' || $this->rc->action == 'print') {
$this->add_hook('message_load', array($this, 'message_load'));
$this->add_hook('template_object_messagebody', array($this, 'message_output'));
}
// message composing
else if ($enabled && $this->rc->action == 'compose') {
$this->add_hook('message_compose_body', array($this, 'message_compose'));
$this->load_ui();
$this->ui->init();
}
// message sending (and draft storing)
else if ($enabled && $this->rc->action == 'send') {
$this->add_hook('message_ready', array($this, 'message_ready'));
}
$this->password_handler();
}
else if ($this->rc->task == 'settings') {
// add hooks for Enigma settings
$this->add_hook('settings_actions', array($this, 'settings_actions'));
$this->add_hook('preferences_sections_list', array($this, 'preferences_sections_list'));
$this->add_hook('preferences_list', array($this, 'preferences_list'));
$this->add_hook('preferences_save', array($this, 'preferences_save'));
// register handler for keys/certs management
$this->register_action('plugin.enigmakeys', array($this, 'preferences_ui'));
// $this->register_action('plugin.enigmacerts', array($this, 'preferences_ui'));
$this->load_ui();
if (empty($_REQUEST['_framed']) || strpos($this->rc->action, 'plugin.enigma') === 0) {
$this->ui->add_css();
}
}
$this->add_hook('refresh', array($this, 'refresh'));
}
/**
* Plugin environment initialization.
*/
function load_env()
{
if ($this->env_loaded) {
return;
}
$this->env_loaded = true;
// Add include path for Enigma classes and drivers
$include_path = $this->home . '/lib' . PATH_SEPARATOR;
$include_path .= ini_get('include_path');
set_include_path($include_path);
// load the Enigma plugin configuration
$this->load_config();
// include localization (if wasn't included before)
$this->add_texts('localization/');
}
/**
* Plugin UI initialization.
*/
function load_ui($all = false)
{
if (!$this->ui) {
// load config/localization
$this->load_env();
// Load UI
$this->ui = new enigma_ui($this, $this->home);
}
if ($all) {
$this->ui->add_css();
$this->ui->add_js();
}
}
/**
* Plugin engine initialization.
*/
function load_engine()
{
if ($this->engine) {
return $this->engine;
}
// load config/localization
$this->load_env();
return $this->engine = new enigma_engine($this);
}
/**
* Handler for message_part_structure hook.
* Called for every part of the message.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function part_structure($p)
{
$this->load_engine();
return $this->engine->part_structure($p);
}
/**
* Handler for message_part_body hook.
* Called to get body of a message part.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function part_body($p)
{
$this->load_engine();
return $this->engine->part_body($p);
}
/**
* Handler for settings_actions hook.
* Adds Enigma settings section into preferences.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function settings_actions($args)
{
// add labels
$this->add_texts('localization/');
// register as settings action
$args['actions'][] = array(
'action' => 'plugin.enigmakeys',
'class' => 'enigma keys',
'label' => 'enigmakeys',
'title' => 'enigmakeys',
'domain' => 'enigma',
);
/*
$args['actions'][] = array(
'action' => 'plugin.enigmacerts',
'class' => 'enigma certs',
'label' => 'enigmacerts',
'title' => 'enigmacerts',
'domain' => 'enigma',
);
*/
return $args;
}
/**
* Handler for preferences_sections_list hook.
* Adds Encryption settings section into preferences sections list.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function preferences_sections_list($p)
{
$p['list']['enigma'] = array(
'id' => 'enigma', 'section' => $this->gettext('encryption'),
);
return $p;
}
/**
* Handler for preferences_list hook.
* Adds options blocks into Enigma settings sections in Preferences.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function preferences_list($p)
{
if ($p['section'] != 'enigma') {
return $p;
}
$no_override = array_flip((array)$this->rc->config->get('dont_override'));
$p['blocks']['main']['name'] = $this->gettext('mainoptions');
if (!isset($no_override['enigma_encryption'])) {
if (!$p['current']) {
$p['blocks']['main']['content'] = true;
return $p;
}
$field_id = 'rcmfd_enigma_encryption';
$input = new html_checkbox(array(
'name' => '_enigma_encryption',
'id' => $field_id,
'value' => 1,
));
$p['blocks']['main']['options']['enigma_encryption'] = array(
'title' => html::label($field_id, $this->gettext('supportencryption')),
'content' => $input->show(intval($this->rc->config->get('enigma_encryption'))),
);
}
if (!isset($no_override['enigma_signatures'])) {
if (!$p['current']) {
$p['blocks']['main']['content'] = true;
return $p;
}
$field_id = 'rcmfd_enigma_signatures';
$input = new html_checkbox(array(
'name' => '_enigma_signatures',
'id' => $field_id,
'value' => 1,
));
$p['blocks']['main']['options']['enigma_signatures'] = array(
'title' => html::label($field_id, $this->gettext('supportsignatures')),
'content' => $input->show(intval($this->rc->config->get('enigma_signatures'))),
);
}
if (!isset($no_override['enigma_decryption'])) {
if (!$p['current']) {
$p['blocks']['main']['content'] = true;
return $p;
}
$field_id = 'rcmfd_enigma_decryption';
$input = new html_checkbox(array(
'name' => '_enigma_decryption',
'id' => $field_id,
'value' => 1,
));
$p['blocks']['main']['options']['enigma_decryption'] = array(
'title' => html::label($field_id, $this->gettext('supportdecryption')),
'content' => $input->show(intval($this->rc->config->get('enigma_decryption'))),
);
}
if (!isset($no_override['enigma_sign_all'])) {
if (!$p['current']) {
$p['blocks']['main']['content'] = true;
return $p;
}
$field_id = 'rcmfd_enigma_sign_all';
$input = new html_checkbox(array(
'name' => '_enigma_sign_all',
'id' => $field_id,
'value' => 1,
));
$p['blocks']['main']['options']['enigma_sign_all'] = array(
'title' => html::label($field_id, $this->gettext('signdefault')),
'content' => $input->show($this->rc->config->get('enigma_sign_all') ? 1 : 0),
);
}
if (!isset($no_override['enigma_encrypt_all'])) {
if (!$p['current']) {
$p['blocks']['main']['content'] = true;
return $p;
}
$field_id = 'rcmfd_enigma_encrypt_all';
$input = new html_checkbox(array(
'name' => '_enigma_encrypt_all',
'id' => $field_id,
'value' => 1,
));
$p['blocks']['main']['options']['enigma_encrypt_all'] = array(
'title' => html::label($field_id, $this->gettext('encryptdefault')),
'content' => $input->show($this->rc->config->get('enigma_encrypt_all') ? 1 : 0),
);
}
+ if (!isset($no_override['enigma_attach_pubkey'])) {
+ if (!$p['current']) {
+ $p['blocks']['main']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_enigma_attach_pubkey';
+ $input = new html_checkbox(array(
+ 'name' => '_enigma_attach_pubkey',
+ 'id' => $field_id,
+ 'value' => 1,
+ ));
+
+ $p['blocks']['main']['options']['enigma_encrypt_all'] = array(
+ 'title' => html::label($field_id, $this->gettext('attachpubkeydefault')),
+ 'content' => $input->show($this->rc->config->get('enigma_attach_pubkey') ? 1 : 0),
+ );
+ }
+
if (!isset($no_override['enigma_password_time'])) {
if (!$p['current']) {
$p['blocks']['main']['content'] = true;
return $p;
}
$field_id = 'rcmfd_enigma_password_time';
$select = new html_select(array('name' => '_enigma_password_time', 'id' => $field_id));
foreach (array(1, 5, 10, 15, 30) as $m) {
$label = $this->gettext(array('name' => 'nminutes', 'vars' => array('m' => $m)));
$select->add($label, $m);
}
$select->add($this->gettext('wholesession'), 0);
$p['blocks']['main']['options']['enigma_password_time'] = array(
'title' => html::label($field_id, $this->gettext('passwordtime')),
'content' => $select->show(intval($this->rc->config->get('enigma_password_time'))),
);
}
return $p;
}
/**
* Handler for preferences_save hook.
* Executed on Enigma settings form submit.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function preferences_save($p)
{
if ($p['section'] == 'enigma') {
$p['prefs'] = array(
'enigma_signatures' => (bool) rcube_utils::get_input_value('_enigma_signatures', rcube_utils::INPUT_POST),
'enigma_decryption' => (bool) rcube_utils::get_input_value('_enigma_decryption', rcube_utils::INPUT_POST),
'enigma_encryption' => (bool) rcube_utils::get_input_value('_enigma_encryption', rcube_utils::INPUT_POST),
'enigma_sign_all' => (bool) rcube_utils::get_input_value('_enigma_sign_all', rcube_utils::INPUT_POST),
'enigma_encrypt_all' => (bool) rcube_utils::get_input_value('_enigma_encrypt_all', rcube_utils::INPUT_POST),
+ 'enigma_attach_pubkey' => (bool) rcube_utils::get_input_value('_enigma_attach_pubkey', rcube_utils::INPUT_POST),
'enigma_password_time' => intval(rcube_utils::get_input_value('_enigma_password_time', rcube_utils::INPUT_POST)),
);
}
return $p;
}
/**
* Handler for keys/certs management UI template.
*/
function preferences_ui()
{
$this->load_ui();
$this->ui->init();
}
/**
* Handler for message_body_prefix hook.
* Called for every displayed (content) part of the message.
* Adds infobox about signature verification and/or decryption
* status above the body.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function status_message($p)
{
$this->load_ui();
return $this->ui->status_message($p);
}
/**
* Handler for message_load hook.
* Check message bodies and attachments for keys/certs.
*/
function message_load($p)
{
$this->load_ui();
return $this->ui->message_load($p);
}
/**
* Handler for template_object_messagebody hook.
* This callback function adds a box below the message content
* if there is a key/cert attachment available
*/
function message_output($p)
{
$this->load_ui();
return $this->ui->message_output($p);
}
/**
* Handler for attached keys/certs import
*/
function import_file()
{
$this->load_engine();
$this->engine->import_file();
}
/**
* Handle password submissions
*/
function password_handler()
{
$this->load_engine();
$this->engine->password_handler();
}
/**
* Handle message_ready hook (encryption/signing)
*/
function message_ready($p)
{
$this->load_ui();
return $this->ui->message_ready($p);
}
/**
* Handle message_compose_body hook
*/
function message_compose($p)
{
$this->load_ui();
return $this->ui->message_compose($p);
}
/**
* Handler for refresh hook.
*/
function refresh($p)
{
// calling enigma_engine constructor to remove passwords
// stored in session after expiration time
$this->load_engine();
return $p;
}
}
diff --git a/plugins/enigma/lib/enigma_ui.php b/plugins/enigma/lib/enigma_ui.php
index f0963dca6..3ccacd45e 100644
--- a/plugins/enigma/lib/enigma_ui.php
+++ b/plugins/enigma/lib/enigma_ui.php
@@ -1,1058 +1,1063 @@
<?php
/**
+-------------------------------------------------------------------------+
| User Interface for the Enigma Plugin |
| |
| Copyright (C) 2010-2015 The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
+-------------------------------------------------------------------------+
| Author: Aleksander Machniak <alec@alec.pl> |
+-------------------------------------------------------------------------+
*/
class enigma_ui
{
private $rc;
private $enigma;
private $home;
private $css_loaded;
private $js_loaded;
private $data;
private $keys_parts = array();
private $keys_bodies = array();
function __construct($enigma_plugin, $home='')
{
$this->enigma = $enigma_plugin;
$this->rc = $enigma_plugin->rc;
$this->home = $home; // we cannot use $enigma_plugin->home here
}
/**
* UI initialization and requests handlers.
*
* @param string Preferences section
*/
function init()
{
$this->add_js();
$action = rcube_utils::get_input_value('_a', rcube_utils::INPUT_GPC);
if ($this->rc->action == 'plugin.enigmakeys') {
switch ($action) {
case 'delete':
$this->key_delete();
break;
/*
case 'edit':
$this->key_edit();
break;
*/
case 'import':
$this->key_import();
break;
case 'export':
$this->key_export();
break;
case 'generate':
$this->key_generate();
break;
case 'create':
$this->key_create();
break;
case 'search':
case 'list':
$this->key_list();
break;
case 'info':
$this->key_info();
break;
}
$this->rc->output->add_handlers(array(
'keyslist' => array($this, 'tpl_keys_list'),
'keyframe' => array($this, 'tpl_key_frame'),
'countdisplay' => array($this, 'tpl_keys_rowcount'),
'searchform' => array($this->rc->output, 'search_form'),
));
$this->rc->output->set_pagetitle($this->enigma->gettext('enigmakeys'));
$this->rc->output->send('enigma.keys');
}
/*
// Preferences UI
else if ($this->rc->action == 'plugin.enigmacerts') {
$this->rc->output->add_handlers(array(
'keyslist' => array($this, 'tpl_certs_list'),
'keyframe' => array($this, 'tpl_cert_frame'),
'countdisplay' => array($this, 'tpl_certs_rowcount'),
'searchform' => array($this->rc->output, 'search_form'),
));
$this->rc->output->set_pagetitle($this->enigma->gettext('enigmacerts'));
$this->rc->output->send('enigma.certs');
}
*/
// Message composing UI
else if ($this->rc->action == 'compose') {
$this->compose_ui();
}
}
/**
* Adds CSS style file to the page header.
*/
function add_css()
{
if ($this->css_loaded)
return;
$skin_path = $this->enigma->local_skin_path();
if (is_file($this->home . "/$skin_path/enigma.css")) {
$this->enigma->include_stylesheet("$skin_path/enigma.css");
}
$this->css_loaded = true;
}
/**
* Adds javascript file to the page header.
*/
function add_js()
{
if ($this->js_loaded) {
return;
}
$this->enigma->include_script('enigma.js');
$this->js_loaded = true;
}
/**
* Initializes key password prompt
*
* @param enigma_error $status Error object with key info
* @param array $params Optional prompt parameters
*/
function password_prompt($status, $params = array())
{
$data = $status->getData('missing');
if (empty($data)) {
$data = $status->getData('bad');
}
$data = array('keyid' => key($data), 'user' => $data[key($data)]);
if (!empty($params)) {
$data = array_merge($params, $data);
}
if ($this->rc->action == 'send') {
$this->rc->output->command('enigma_password_request', $data);
}
else {
$this->rc->output->set_env('enigma_password_request', $data);
}
// add some labels to client
$this->rc->output->add_label('enigma.enterkeypasstitle', 'enigma.enterkeypass',
'save', 'cancel');
$this->add_css();
$this->add_js();
}
/**
* Template object for key info/edit frame.
*
* @param array Object attributes
*
* @return string HTML output
*/
function tpl_key_frame($attrib)
{
if (!$attrib['id']) {
$attrib['id'] = 'rcmkeysframe';
}
$attrib['name'] = $attrib['id'];
$this->rc->output->set_env('contentframe', $attrib['name']);
$this->rc->output->set_env('blankpage', $attrib['src'] ?
$this->rc->output->abs_url($attrib['src']) : 'program/resources/blank.gif');
return $this->rc->output->frame($attrib);
}
/**
* Template object for list of keys.
*
* @param array Object attributes
*
* @return string HTML content
*/
function tpl_keys_list($attrib)
{
// add id to message list table if not specified
if (!strlen($attrib['id'])) {
$attrib['id'] = 'rcmenigmakeyslist';
}
// define list of cols to be displayed
$a_show_cols = array('name');
// create XHTML table
$out = $this->rc->table_output($attrib, array(), $a_show_cols, 'id');
// set client env
$this->rc->output->add_gui_object('keyslist', $attrib['id']);
$this->rc->output->include_script('list.js');
// add some labels to client
$this->rc->output->add_label('enigma.keyremoveconfirm', 'enigma.keyremoving');
return $out;
}
/**
* Key listing (and searching) request handler
*/
private function key_list()
{
$this->enigma->load_engine();
$pagesize = $this->rc->config->get('pagesize', 100);
$page = max(intval(rcube_utils::get_input_value('_p', rcube_utils::INPUT_GPC)), 1);
$search = rcube_utils::get_input_value('_q', rcube_utils::INPUT_GPC);
// Get the list
$list = $this->enigma->engine->list_keys($search);
if ($list && ($list instanceof enigma_error))
$this->rc->output->show_message('enigma.keylisterror', 'error');
else if (empty($list))
$this->rc->output->show_message('enigma.nokeysfound', 'notice');
else if (is_array($list)) {
// Save the size
$listsize = count($list);
// Sort the list by key (user) name
usort($list, array('enigma_key', 'cmp'));
// Slice current page
$list = array_slice($list, ($page - 1) * $pagesize, $pagesize);
$size = count($list);
// Add rows
foreach ($list as $key) {
$this->rc->output->command('enigma_add_list_row',
array('name' => rcube::Q($key->name), 'id' => $key->id));
}
}
$this->rc->output->set_env('rowcount', $size);
$this->rc->output->set_env('search_request', $search);
$this->rc->output->set_env('pagecount', ceil($listsize/$pagesize));
$this->rc->output->set_env('current_page', $page);
$this->rc->output->command('set_rowcount',
$this->get_rowcount_text($listsize, $size, $page));
$this->rc->output->send();
}
/**
* Template object for list records counter.
*
* @param array Object attributes
*
* @return string HTML output
*/
function tpl_keys_rowcount($attrib)
{
if (!$attrib['id'])
$attrib['id'] = 'rcmcountdisplay';
$this->rc->output->add_gui_object('countdisplay', $attrib['id']);
return html::span($attrib, $this->get_rowcount_text());
}
/**
* Returns text representation of list records counter
*/
private function get_rowcount_text($all=0, $curr_count=0, $page=1)
{
if (!$curr_count) {
$out = $this->enigma->gettext('nokeysfound');
}
else {
$pagesize = $this->rc->config->get('pagesize', 100);
$first = ($page - 1) * $pagesize;
$out = $this->enigma->gettext(array(
'name' => 'keysfromto',
'vars' => array(
'from' => $first + 1,
'to' => $first + $curr_count,
'count' => $all)
));
}
return $out;
}
/**
* Key information page handler
*/
private function key_info()
{
$this->enigma->load_engine();
$id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GET);
$res = $this->enigma->engine->get_key($id);
if ($res instanceof enigma_key) {
$this->data = $res;
}
else { // error
$this->rc->output->show_message('enigma.keyopenerror', 'error');
$this->rc->output->command('parent.enigma_loadframe');
$this->rc->output->send('iframe');
}
$this->rc->output->add_handlers(array(
'keyname' => array($this, 'tpl_key_name'),
'keydata' => array($this, 'tpl_key_data'),
));
$this->rc->output->set_pagetitle($this->enigma->gettext('keyinfo'));
$this->rc->output->send('enigma.keyinfo');
}
/**
* Template object for key name
*/
function tpl_key_name($attrib)
{
return rcube::Q($this->data->name);
}
/**
* Template object for key information page content
*/
function tpl_key_data($attrib)
{
$out = '';
$table = new html_table(array('cols' => 2));
// Key user ID
$table->add('title', $this->enigma->gettext('keyuserid'));
$table->add(null, rcube::Q($this->data->name));
// Key ID
$table->add('title', $this->enigma->gettext('keyid'));
$table->add(null, $this->data->subkeys[0]->get_short_id());
// Key type
$keytype = $this->data->get_type();
if ($keytype == enigma_key::TYPE_KEYPAIR) {
$type = $this->enigma->gettext('typekeypair');
}
else if ($keytype == enigma_key::TYPE_PUBLIC) {
$type = $this->enigma->gettext('typepublickey');
}
$table->add('title', $this->enigma->gettext('keytype'));
$table->add(null, $type);
// Key fingerprint
$table->add('title', $this->enigma->gettext('fingerprint'));
$table->add(null, $this->data->subkeys[0]->get_fingerprint());
$out .= html::tag('fieldset', null,
html::tag('legend', null,
$this->enigma->gettext('basicinfo')) . $table->show($attrib));
// Subkeys
$table = new html_table(array('cols' => 5, 'id' => 'enigmasubkeytable', 'class' => 'records-table'));
$table->add_header('id', $this->enigma->gettext('subkeyid'));
$table->add_header('algo', $this->enigma->gettext('subkeyalgo'));
$table->add_header('created', $this->enigma->gettext('subkeycreated'));
$table->add_header('expires', $this->enigma->gettext('subkeyexpires'));
$table->add_header('usage', $this->enigma->gettext('subkeyusage'));
$now = time();
$date_format = $this->rc->config->get('date_format', 'Y-m-d');
$usage_map = array(
enigma_key::CAN_ENCRYPT => $this->enigma->gettext('typeencrypt'),
enigma_key::CAN_SIGN => $this->enigma->gettext('typesign'),
enigma_key::CAN_CERTIFY => $this->enigma->gettext('typecert'),
enigma_key::CAN_AUTHENTICATE => $this->enigma->gettext('typeauth'),
);
foreach ($this->data->subkeys as $subkey) {
$algo = $subkey->get_algorithm();
if ($algo && $subkey->length) {
$algo .= ' (' . $subkey->length . ')';
}
$usage = array();
foreach ($usage_map as $key => $text) {
if ($subkey->usage & $key) {
$usage[] = $text;
}
}
$table->add('id', $subkey->get_short_id());
$table->add('algo', $algo);
$table->add('created', $subkey->created ? $this->rc->format_date($subkey->created, $date_format, false) : '');
$table->add('expires', $subkey->expires ? $this->rc->format_date($subkey->expires, $date_format, false) : $this->enigma->gettext('expiresnever'));
$table->add('usage', implode(',', $usage));
$table->set_row_attribs($subkey->revoked || ($subkey->expires && $subkey->expires < $now) ? 'deleted' : '');
}
$out .= html::tag('fieldset', null,
html::tag('legend', null,
$this->enigma->gettext('subkeys')) . $table->show());
// Additional user IDs
$table = new html_table(array('cols' => 2, 'id' => 'enigmausertable', 'class' => 'records-table'));
$table->add_header('id', $this->enigma->gettext('userid'));
$table->add_header('valid', $this->enigma->gettext('uservalid'));
foreach ($this->data->users as $user) {
$username = $user->name;
if ($user->comment) {
$username .= ' (' . $user->comment . ')';
}
$username .= ' <' . $user->email . '>';
$table->add('id', rcube::Q(trim($username)));
$table->add('valid', $this->enigma->gettext($user->valid ? 'valid' : 'unknown'));
$table->set_row_attribs($user->revoked || !$user->valid ? 'deleted' : '');
}
$out .= html::tag('fieldset', null,
html::tag('legend', null,
$this->enigma->gettext('userids')) . $table->show());
return $out;
}
/**
* Key(s) export handler
*/
private function key_export()
{
$this->rc->request_security_check(rcube_utils::INPUT_GET);
$keys = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_GPC);
$engine = $this->enigma->load_engine();
$list = $keys == '*' ? $engine->list_keys() : explode(',', $keys);
if (is_array($list)) {
$filename = 'export.pgp';
if (count($list) == 1) {
$filename = (is_object($list[0]) ? $list[0]->id : $list[0]) . '.pgp';
}
// 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);
}
}
}
exit;
}
/**
* Key import (page) handler
*/
private function key_import()
{
// Import process
if ($data = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_POST)) {
// Import from generation form (ajax request)
$this->enigma->load_engine();
$result = $this->enigma->engine->import_key($data);
if (is_array($result)) {
$this->rc->output->command('enigma_key_create_success');
$this->rc->output->show_message('enigma.keygeneratesuccess', 'confirmation');
}
else {
$this->rc->output->show_message('enigma.keysimportfailed', 'error');
}
$this->rc->output->send();
}
else if ($_FILES['_file']['tmp_name'] && is_uploaded_file($_FILES['_file']['tmp_name'])) {
$this->enigma->load_engine();
$result = $this->enigma->engine->import_key($_FILES['_file']['tmp_name'], true);
if (is_array($result)) {
// reload list if any keys has been added
if ($result['imported']) {
$this->rc->output->command('parent.enigma_list', 1);
}
else {
$this->rc->output->command('parent.enigma_loadframe');
}
$this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
array('new' => $result['imported'], 'old' => $result['unchanged']));
$this->rc->output->send('iframe');
}
else {
$this->rc->output->show_message('enigma.keysimportfailed', 'error');
}
}
else if ($err = $_FILES['_file']['error']) {
if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
$this->rc->output->show_message('filesizeerror', 'error',
array('size' => $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize')))));
} else {
$this->rc->output->show_message('fileuploaderror', 'error');
}
}
$this->rc->output->add_handlers(array(
'importform' => array($this, 'tpl_key_import_form'),
));
$this->rc->output->set_pagetitle($this->enigma->gettext('keyimport'));
$this->rc->output->send('enigma.keyimport');
}
/**
* Template object for key import (upload) form
*/
function tpl_key_import_form($attrib)
{
$attrib += array('id' => 'rcmKeyImportForm');
$upload = new html_inputfield(array('type' => 'file', 'name' => '_file',
'id' => 'rcmimportfile', 'size' => 30));
$form = html::p(null,
rcube::Q($this->enigma->gettext('keyimporttext'), 'show')
. html::br() . html::br() . $upload->show()
);
$this->rc->output->add_label('selectimportfile', 'importwait');
$this->rc->output->add_gui_object('importform', $attrib['id']);
$out = $this->rc->output->form_tag(array(
'action' => $this->rc->url(array('action' => $this->rc->action, 'a' => 'import')),
'method' => 'post',
'enctype' => 'multipart/form-data') + $attrib,
$form);
return $out;
}
/**
* Server-side key pair generation handler
*/
private function key_generate()
{
$user = rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST, true);
$pass = rcube_utils::get_input_value('_password', rcube_utils::INPUT_POST, true);
$size = (int) rcube_utils::get_input_value('_size', rcube_utils::INPUT_POST);
if ($size > 4096) {
$size = 4096;
}
$ident = rcube_mime::decode_address_list($user, 1, false);
if (empty($ident)) {
$this->rc->output->show_message('enigma.keygenerateerror', 'error');
$this->rc->output->send();
}
$this->enigma->load_engine();
$result = $this->enigma->engine->generate_key(array(
'user' => $ident[1]['name'],
'email' => $ident[1]['mailto'],
'password' => $pass,
'size' => $size,
));
if ($result instanceof enigma_key) {
$this->rc->output->command('enigma_key_create_success');
$this->rc->output->show_message('enigma.keygeneratesuccess', 'confirmation');
}
else {
$this->rc->output->show_message('enigma.keygenerateerror', 'error');
}
$this->rc->output->send();
}
/**
* Key generation page handler
*/
private function key_create()
{
$this->enigma->include_script('openpgp.min.js');
$this->rc->output->add_handlers(array(
'keyform' => array($this, 'tpl_key_create_form'),
));
$this->rc->output->set_env('enigma_keygen_server', $this->rc->config->get('enigma_keygen_server'));
$this->rc->output->set_pagetitle($this->enigma->gettext('keygenerate'));
$this->rc->output->send('enigma.keycreate');
}
/**
* Template object for key generation form
*/
function tpl_key_create_form($attrib)
{
$attrib += array('id' => 'rcmKeyCreateForm');
$table = new html_table(array('cols' => 2));
// get user's identities
$identities = $this->rc->user->list_identities(null, true);
// Identity
$select = new html_select(array('name' => 'identity', 'id' => 'key-ident'));
foreach ((array) $identities as $idx => $ident) {
$name = empty($ident['name']) ? ('<' . $ident['email'] . '>') : $ident['ident'];
$select->add($name, $idx);
}
$table->add('title', html::label('key-name', rcube::Q($this->enigma->gettext('newkeyident'))));
$table->add(null, $select->show(0));
// Key size
$select = new html_select(array('name' => 'size', 'id' => 'key-size'));
$select->add($this->enigma->gettext('key2048'), '2048');
$select->add($this->enigma->gettext('key4096'), '4096');
$table->add('title', html::label('key-size', rcube::Q($this->enigma->gettext('newkeysize'))));
$table->add(null, $select->show());
// Password and confirm password
$table->add('title', html::label('key-pass', rcube::Q($this->enigma->gettext('newkeypass'))));
$table->add(null, rcube_output::get_edit_field('password', '',
array('id' => 'key-pass', 'size' => $attrib['size'], 'required' => true), 'password'));
$table->add('title', html::label('key-pass-confirm', rcube::Q($this->enigma->gettext('newkeypassconfirm'))));
$table->add(null, rcube_output::get_edit_field('password-confirm', '',
array('id' => 'key-pass-confirm', 'size' => $attrib['size'], 'required' => true), 'password'));
$this->rc->output->add_gui_object('keyform', $attrib['id']);
$this->rc->output->add_label('enigma.keygenerating', 'enigma.formerror',
'enigma.passwordsdiffer', 'enigma.keygenerateerror', 'enigma.nonameident',
'enigma.keygennosupport');
return $this->rc->output->form_tag(array(), $table->show($attrib));
}
/**
* Key deleting
*/
private function key_delete()
{
$keys = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_POST);
$engine = $this->enigma->load_engine();
foreach ((array)$keys as $key) {
$res = $engine->delete_key($key);
if ($res !== true) {
$this->rc->output->show_message('enigma.keyremoveerror', 'error');
$this->rc->output->command('enigma_list');
$this->rc->output->send();
}
}
$this->rc->output->command('enigma_list');
$this->rc->output->show_message('enigma.keyremovesuccess', 'confirmation');
$this->rc->output->send();
}
/**
* Init compose UI (add task button and the menu)
*/
private function compose_ui()
{
$this->add_css();
// Options menu button
$this->enigma->add_button(array(
'type' => 'link',
'command' => 'plugin.enigma',
'onclick' => "rcmail.command('menu-open', 'enigmamenu', event.target, event)",
'class' => 'button enigma',
'title' => 'encryptionoptions',
'label' => 'encryption',
'domain' => $this->enigma->ID,
'width' => 32,
'height' => 32
), 'toolbar');
$menu = new html_table(array('cols' => 2));
$chbox = new html_checkbox(array('value' => 1));
$menu->add(null, html::label(array('for' => 'enigmasignopt'),
rcube::Q($this->enigma->gettext('signmsg'))));
$menu->add(null, $chbox->show($this->rc->config->get('enigma_sign_all') ? 1 : 0,
array('name' => '_enigma_sign', 'id' => 'enigmasignopt')));
$menu->add(null, html::label(array('for' => 'enigmaencryptopt'),
rcube::Q($this->enigma->gettext('encryptmsg'))));
$menu->add(null, $chbox->show($this->rc->config->get('enigma_encrypt_all') ? 1 : 0,
array('name' => '_enigma_encrypt', 'id' => 'enigmaencryptopt')));
+ $menu->add(null, html::label(array('for' => 'enigmaattachpubkeyopt'),
+ rcube::Q($this->enigma->gettext('attachpubkeymsg'))));
+ $menu->add(null, $chbox->show($this->rc->config->get('enigma_attach_pubkey') ? 1 : 0,
+ array('name' => '_enigma_attachpubkey', 'id' => 'enigmaattachpubkeyopt')));
+
$menu = html::div(array('id' => 'enigmamenu', 'class' => 'popupmenu'), $menu->show());
// Options menu contents
$this->rc->output->add_footer($menu);
}
/**
* Handler for message_body_prefix hook.
* Called for every displayed (content) part of the message.
* Adds infobox about signature verification and/or decryption
* status above the body.
*
* @param array Original parameters
*
* @return array Modified parameters
*/
function status_message($p)
{
// skip: not a message part
if ($p['part'] instanceof rcube_message) {
return $p;
}
// skip: message has no signed/encoded content
if (!$this->enigma->engine) {
return $p;
}
$engine = $this->enigma->engine;
$part_id = $p['part']->mime_id;
// Decryption status
if (($found = $this->find_part_id($part_id, $engine->decryptions)) !== null
&& ($status = $engine->decryptions[$found])
) {
$attach_scripts = true;
// show the message only once
unset($engine->decryptions[$found]);
// display status info
$attrib['id'] = 'enigma-message';
if ($status instanceof enigma_error) {
$attrib['class'] = 'enigmaerror';
$code = $status->getCode();
if ($code == enigma_error::KEYNOTFOUND) {
$msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($status->getData('id')),
$this->enigma->gettext('decryptnokey')));
}
else if ($code == enigma_error::BADPASS) {
$missing = $status->getData('missing');
$label = 'decrypt' . (!empty($missing) ? 'no' : 'bad') . 'pass';
$msg = rcube::Q($this->enigma->gettext($label));
$this->password_prompt($status);
}
else {
$msg = rcube::Q($this->enigma->gettext('decrypterror'));
}
}
else if ($status === enigma_engine::ENCRYPTED_PARTIALLY) {
$attrib['class'] = 'enigmawarning';
$msg = rcube::Q($this->enigma->gettext('decryptpartial'));
}
else {
$attrib['class'] = 'enigmanotice';
$msg = rcube::Q($this->enigma->gettext('decryptok'));
}
$p['prefix'] .= html::div($attrib, $msg);
}
// Signature verification status
if (($found = $this->find_part_id($part_id, $engine->signatures)) !== null
&& ($sig = $engine->signatures[$found])
) {
$attach_scripts = true;
// show the message only once
unset($engine->signatures[$found]);
// display status info
$attrib['id'] = 'enigma-message';
if ($sig instanceof enigma_signature) {
$sender = ($sig->name ? $sig->name . ' ' : '') . '<' . $sig->email . '>';
if ($sig->valid === enigma_error::UNVERIFIED) {
$attrib['class'] = 'enigmawarning';
$msg = str_replace('$sender', $sender, $this->enigma->gettext('sigunverified'));
$msg = str_replace('$keyid', $sig->id, $msg);
$msg = rcube::Q($msg);
}
else if ($sig->valid) {
$attrib['class'] = $sig->partial ? 'enigmawarning' : 'enigmanotice';
$label = 'sigvalid' . ($sig->partial ? 'partial' : '');
$msg = rcube::Q(str_replace('$sender', $sender, $this->enigma->gettext($label)));
}
else {
$attrib['class'] = 'enigmawarning';
$msg = rcube::Q(str_replace('$sender', $sender, $this->enigma->gettext('siginvalid')));
}
}
else if ($sig && $sig->getCode() == enigma_error::KEYNOTFOUND) {
$attrib['class'] = 'enigmawarning';
$msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($sig->getData('id')),
$this->enigma->gettext('signokey')));
}
else {
$attrib['class'] = 'enigmaerror';
$msg = rcube::Q($this->enigma->gettext('sigerror'));
}
/*
$msg .= ' ' . html::a(array('href' => "#sigdetails",
'onclick' => rcmail_output::JS_OBJECT_NAME.".command('enigma-sig-details')"),
rcube::Q($this->enigma->gettext('showdetails')));
*/
// test
// $msg .= '<br /><pre>'.$sig->body.'</pre>';
$p['prefix'] .= html::div($attrib, $msg);
}
if ($attach_scripts) {
// add css and js script
$this->add_css();
$this->add_js();
}
return $p;
}
/**
* Handler for message_load hook.
* Check message bodies and attachments for keys/certs.
*/
function message_load($p)
{
$engine = $this->enigma->load_engine();
// handle keys/certs in attachments
foreach ((array) $p['object']->attachments as $attachment) {
if ($engine->is_keys_part($attachment)) {
$this->keys_parts[] = $attachment->mime_id;
}
}
// the same with message bodies
foreach ((array) $p['object']->parts as $part) {
if ($engine->is_keys_part($part)) {
$this->keys_parts[] = $part->mime_id;
$this->keys_bodies[] = $part->mime_id;
}
}
// @TODO: inline PGP keys
if ($this->keys_parts) {
$this->enigma->add_texts('localization');
}
return $p;
}
/**
* Handler for template_object_messagebody hook.
* This callback function adds a box below the message content
* if there is a key/cert attachment available
*/
function message_output($p)
{
foreach ($this->keys_parts as $part) {
// remove part's body
if (in_array($part, $this->keys_bodies)) {
$p['content'] = '';
}
// add box below message body
$p['content'] .= html::p(array('class' => 'enigmaattachment'),
html::a(array(
'href' => "#",
'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".enigma_import_attachment('".rcube::JQ($part)."')",
'title' => $this->enigma->gettext('keyattimport')),
html::span(null, $this->enigma->gettext('keyattfound'))));
$attach_scripts = true;
}
if ($attach_scripts) {
// add css and js script
$this->add_css();
$this->add_js();
}
return $p;
}
/**
* Handle message_ready hook (encryption/signing/attach public key)
*/
function message_ready($p)
{
$savedraft = !empty($_POST['_draft']) && empty($_GET['_saveonly']);
if (!$savedraft && rcube_utils::get_input_value('_enigma_attachpubkey', rcube_utils::INPUT_POST)) {
$p = $this->attach_public($p);
}
if (!$savedraft && rcube_utils::get_input_value('_enigma_sign', rcube_utils::INPUT_POST)) {
$this->enigma->load_engine();
$status = $this->enigma->engine->sign_message($p['message']);
$mode = 'sign';
}
if ((!$status instanceof enigma_error) && rcube_utils::get_input_value('_enigma_encrypt', rcube_utils::INPUT_POST)) {
$this->enigma->load_engine();
$status = $this->enigma->engine->encrypt_message($p['message'], null, $savedraft);
$mode = 'encrypt';
}
if ($mode && ($status instanceof enigma_error)) {
$code = $status->getCode();
if ($code == enigma_error::KEYNOTFOUND) {
$vars = array('email' => $status->getData('missing'));
$msg = 'enigma.' . $mode . 'nokey';
}
else if ($code == enigma_error::BADPASS) {
$this->password_prompt($status);
}
else {
$msg = 'enigma.' . $mode . 'error';
}
if ($msg) {
$this->rc->output->show_message($msg, $type ?: 'error', $vars);
}
$this->rc->output->send('iframe');
}
return $p;
}
/**
* Add sender's public key (PGP).
*/
function attach_public($p)
{
// get sender's PGP pubkey for attachment
$this->enigma->load_engine();
$key = $this->enigma->engine->list_keys($p['message']->headers()['From']);
$keyID = $key[0]->subkeys[0]->get_short_id();
$pubkey_armor = $this->enigma->engine->get_gpg_pubkey_for_attach($p['message']->headers()['From']);
if(!$pubkey_armor instanceof enigma_error) {
$p['message']->addAttachment($pubkey_armor, 'application/pgp-keys', "0x$keyID.asc", false);
}
return $p;
}
/**
* Handler for message_compose_body hook
* Display error when the message cannot be encrypted
* and provide a way to try again with a password.
*/
function message_compose($p)
{
$engine = $this->enigma->load_engine();
// skip: message has no signed/encoded content
if (!$this->enigma->engine) {
return $p;
}
$engine = $this->enigma->engine;
// Decryption status
foreach ($engine->decryptions as $status) {
if ($status instanceof enigma_error) {
$code = $status->getCode();
if ($code == enigma_error::KEYNOTFOUND) {
$msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($status->getData('id')),
$this->enigma->gettext('decryptnokey')));
}
else if ($code == enigma_error::BADPASS) {
$this->password_prompt($status, array('compose-init' => true));
return $p;
}
else {
$msg = rcube::Q($this->enigma->gettext('decrypterror'));
}
}
}
if ($msg) {
$this->rc->output->show_message($msg, 'error');
}
// Check sign/ecrypt options for signed/encrypted drafts
$this->rc->output->set_env('enigma_force_encrypt', !empty($engine->decryptions));
$this->rc->output->set_env('enigma_force_sign', !empty($engine->signatures));
return $p;
}
/**
* Check if the part or its parent exists in the array
* of decryptions/signatures. Returns found ID.
*/
private function find_part_id($part_id, $data)
{
$ids = explode('.', $part_id);
$i = 0;
$count = count($ids);
while ($i < $count && strlen($part = implode('.', array_slice($ids, 0, ++$i)))) {
if (array_key_exists($part, $data)) {
return $part;
}
}
}
}
diff --git a/plugins/enigma/localization/en_US.inc b/plugins/enigma/localization/en_US.inc
index 0e4d2b43d..5224ca556 100644
--- a/plugins/enigma/localization/en_US.inc
+++ b/plugins/enigma/localization/en_US.inc
@@ -1,123 +1,125 @@
<?php
/**
+-----------------------------------------------------------------------+
| plugins/enigma/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail ACL plugin |
| Copyright (C) 2012-2015, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
+-----------------------------------------------------------------------+
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/enigma/
*/
$labels = array();
$labels['encryption'] = 'Encryption';
$labels['enigmacerts'] = 'S/MIME Certificates';
$labels['enigmakeys'] = 'PGP Keys';
$labels['keysfromto'] = 'Keys $from to $to of $count';
$labels['keyname'] = 'Name';
$labels['keyid'] = 'Key ID';
$labels['keyuserid'] = 'User ID';
$labels['keytype'] = 'Key type';
$labels['fingerprint'] = 'Fingerprint';
$labels['subkeys'] = 'Subkeys';
$labels['basicinfo'] = 'Basic Information';
$labels['userids'] = 'Additional Users';
$labels['typepublickey'] = 'public key';
$labels['typekeypair'] = 'key pair';
$labels['keyattfound'] = 'This message contains attached PGP key(s).';
$labels['keyattimport'] = 'Import key(s)';
$labels['typesign'] = 'Sign';
$labels['typeencrypt'] = 'Encrypt';
$labels['typecert'] = 'Certify';
$labels['typeauth'] = 'Authentication';
$labels['subkeyid'] = 'ID';
$labels['subkeyalgo'] = 'Algorithm';
$labels['subkeycreated'] = 'Created';
$labels['subkeyexpires'] = 'Expires';
$labels['subkeyusage'] = 'Usage';
$labels['expiresnever'] = 'never';
$labels['unknown'] = 'unknown';
$labels['uservalid'] = 'Valid';
$labels['userid'] = 'ID';
$labels['valid'] = 'valid';
$labels['supportencryption'] = 'Enable message encryption and signing';
$labels['supportsignatures'] = 'Enable message signatures verification';
$labels['supportdecryption'] = 'Enable message decryption';
$labels['signdefault'] = 'Sign all messages by default';
$labels['encryptdefault'] = 'Encrypt all messages by default';
+$labels['attachpubkeydefault'] = 'Attach my public PGP key by default';
$labels['passwordtime'] = 'Keep private key passwords for';
$labels['nminutes'] = '$m minute(s)';
$labels['wholesession'] = 'the whole session';
$labels['createkeys'] = 'Create a new key pair';
$labels['importkeys'] = 'Import key(s)';
$labels['exportkeys'] = 'Export key(s)';
$labels['keyactions'] = 'Key actions...';
$labels['keyremove'] = 'Remove';
$labels['keydisable'] = 'Disable';
$labels['keyrevoke'] = 'Revoke';
$labels['keysend'] = 'Send public key in a message';
$labels['keychpass'] = 'Change password';
$labels['newkeyident'] = 'Identity:';
$labels['newkeypass'] = 'Password:';
$labels['newkeypassconfirm'] = 'Confirm password:';
$labels['newkeysize'] = 'Key size:';
$labels['key2048'] = '2048 bits - default';
$labels['key4096'] = '4096 bits - more secure';
$labels['keygenerating'] = 'Generating keys...';
$labels['encryptionoptions'] = 'Encryption options...';
$labels['encryptmsg'] = 'Encrypt this message';
$labels['signmsg'] = 'Digitally sign this message';
$labels['enterkeypasstitle'] = 'Enter key passphrase';
$labels['enterkeypass'] = 'A passphrase is needed to unlock the secret key ($keyid) for user: $user.';
$labels['arialabelkeyexportoptions'] = 'Keys export options';
+$labels['attachpubkeymsg'] = 'Attach my public key';
$messages = array();
$messages['sigvalid'] = 'Verified signature from $sender.';
$messages['sigvalidpartial'] = 'Verified signature from $sender, but part of the body was not signed.';
$messages['siginvalid'] = 'Invalid signature from $sender.';
$messages['sigunverified'] = 'Unverified signature. Certificate not verified. Certificate ID: $keyid.';
$messages['signokey'] = 'Unverified signature. Public key not found. Key ID: $keyid.';
$messages['sigerror'] = 'Unverified signature. Internal error.';
$messages['decryptok'] = 'Message decrypted.';
$messages['decrypterror'] = 'Decryption failed.';
$messages['decryptnokey'] = 'Decryption failed. Private key not found. Key ID: $keyid.';
$messages['decryptbadpass'] = 'Decryption failed. Bad password.';
$messages['decryptnopass'] = 'Decryption failed. Key password required.';
$messages['decryptpartial'] = 'Message decrypted, but part of the body was not encrypted.';
$messages['signerror'] = 'Signing failed.';
$messages['signnokey'] = 'Signing failed. Private key not found.';
$messages['signbadpass'] = 'Signing failed. Bad password.';
$messages['signnopass'] = 'Signing failed. Key password required.';
$messages['encrypterror'] = 'Encryption failed.';
$messages['encryptnokey'] = 'Encryption failed. Public key not found for $email.';
$messages['nokeysfound'] = 'No keys found';
$messages['keyopenerror'] = 'Unable to get key information! Internal error.';
$messages['keylisterror'] = 'Unable to list keys! Internal error.';
$messages['keysimportfailed'] = 'Unable to import key(s)! Internal error.';
$messages['keysimportsuccess'] = 'Key(s) imported successfully. Imported: $new, unchanged: $old.';
$messages['keyremoving'] = 'Removing key(s)...';
$messages['keyremoveconfirm'] = 'Are you sure, you want to delete selected key(s)?';
$messages['keyremovesuccess'] = 'Key(s) deleted successfully';
$messages['keyremoveerror'] = 'Unable to delete selected key(s).';
$messages['keyimporttext'] = 'You can import private and public key(s) or revocation signatures in ASCII-Armor format.';
$messages['formerror'] = 'Please, fill the form. All fields are required!';
$messages['passwordsdiffer'] = 'Passwords do not match!';
$messages['nonameident'] = 'Identity must have a user name defined!';
$messages['keygenerateerror'] = 'Failed to generate a key pair';
$messages['keygeneratesuccess'] = 'A key pair generated and imported successfully.';
$messages['keygennosupport'] = 'Your web browser does not support cryptography. Unable to generate a key pair!';
?>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Feb 6, 8:34 AM (3 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
428181
Default Alt Text
(61 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment