Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F7055360
enigma_ui.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
47 KB
Referenced Files
None
Subscribers
None
enigma_ui.php
View Options
<?php
/**
+-------------------------------------------------------------------------+
| User Interface for the Enigma Plugin |
| |
| Copyright (C) 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
'import-search'
:
$this
->
key_import_search
();
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'
),
'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
();
$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
->
rc
->
output
->
set_env
(
'keyservers'
,
$this
->
rc
->
config
->
keyservers
());
$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'
);
}
$keyid
=
key
(
$data
);
$data
=
array
(
'keyid'
=>
$params
[
'keyid'
]
?:
$keyid
,
'user'
=>
$data
[
$keyid
]
);
// With GnuPG 2.1 user name may not be specified (e.g. on private
// key export), we'll get the key information and set the name appropriately
if
(
$keyid
&&
$params
[
'keyid'
]
&&
strpos
(
$data
[
'user'
],
$keyid
)
!==
false
)
{
$key
=
$this
->
enigma
->
engine
->
get_key
(
$params
[
'keyid'
]);
if
(
$key
&&
$key
->
name
)
{
$data
[
'user'
]
=
$key
->
name
;
}
}
if
(!
empty
(
$params
))
{
$data
=
array_merge
(
$params
,
$data
);
}
if
(
preg_match
(
'/^(send|plugin.enigmaimport|plugin.enigmakeys)$/'
,
$this
->
rc
->
action
))
{
$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 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'
,
'enigma.keyexportprompt'
,
'enigma.withprivkeys'
,
'enigma.onlypubkeys'
,
'enigma.exportkeys'
,
'enigma.importkeys'
,
'enigma.keyimportsearchlabel'
,
'import'
,
'search'
);
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
,
'flags'
=>
$key
->
is_private
()
?
'p'
:
''
));
}
}
$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'
,
html
::
label
(
null
,
$this
->
enigma
->
gettext
(
'keyuserid'
)));
$table
->
add
(
null
,
rcube
::
Q
(
$this
->
data
->
name
));
// Key ID
$table
->
add
(
'title'
,
html
::
label
(
null
,
$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'
,
html
::
label
(
null
,
$this
->
enigma
->
gettext
(
'keytype'
)));
$table
->
add
(
null
,
$type
);
// Key fingerprint
$table
->
add
(
'title'
,
html
::
label
(
null
,
$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
->
set_row_attribs
(
$subkey
->
revoked
||
(
$subkey
->
expires
&&
$subkey
->
expires
<
$now
)
?
'deleted'
:
''
);
$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
));
}
$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
->
set_row_attribs
(
$user
->
revoked
||
!
$user
->
valid
?
'deleted'
:
''
);
$table
->
add
(
'id'
,
rcube
::
Q
(
trim
(
$username
)));
$table
->
add
(
'valid'
,
$this
->
enigma
->
gettext
(
$user
->
valid
?
'valid'
:
'unknown'
));
}
$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
()
{
$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
)
&&
(
$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
)
{
$keyid
=
is_object
(
$key
)
?
$key
->
id
:
$key
;
$status
=
$engine
->
export_key
(
$keyid
,
$fp
,
(
bool
)
$priv
);
if
(
$status
instanceof
enigma_error
)
{
$code
=
$status
->
getCode
();
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
,
'keyid'
=>
$keyid
,
));
fclose
(
$fp
);
$this
->
rc
->
output
->
send
(
'iframe'
);
}
}
}
// send downlaod headers
header
(
'Content-Type: application/pgp-keys'
);
header
(
'Content-Disposition: attachment; filename="'
.
$filename
.
'"'
);
rewind
(
$fp
);
while
(!
feof
(
$fp
))
{
echo
fread
(
$fp
,
1024
*
1024
);
}
fclose
(
$fp
);
}
exit
;
}
/**
* Key import (page) handler
*/
private
function
key_import
()
{
// Import process
if
(
$data
=
rcube_utils
::
get_input_value
(
'_keys'
,
rcube_utils
::
INPUT_POST
))
{
$this
->
enigma
->
load_engine
();
$this
->
enigma
->
engine
->
password_handler
();
$result
=
$this
->
enigma
->
engine
->
import_key
(
$data
);
if
(
is_array
(
$result
))
{
if
(
rcube_utils
::
get_input_value
(
'_generated'
,
rcube_utils
::
INPUT_POST
))
{
$this
->
rc
->
output
->
command
(
'enigma_key_create_success'
);
$this
->
rc
->
output
->
show_message
(
'enigma.keygeneratesuccess'
,
'confirmation'
);
}
else
{
$this
->
rc
->
output
->
show_message
(
'enigma.keysimportsuccess'
,
'confirmation'
,
array
(
'new'
=>
$result
[
'imported'
],
'old'
=>
$result
[
'unchanged'
]));
if
(
$result
[
'imported'
]
&&
!
empty
(
$_POST
[
'_refresh'
]))
{
$this
->
rc
->
output
->
command
(
'enigma_list'
,
1
,
false
);
}
}
}
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
);
}
$this
->
rc
->
output
->
show_message
(
'enigma.keysimportsuccess'
,
'confirmation'
,
array
(
'new'
=>
$result
[
'imported'
],
'old'
=>
$result
[
'unchanged'
]));
$this
->
rc
->
output
->
command
(
'parent.enigma_import_success'
);
}
else
if
(
$result
instanceof
enigma_error
&&
$result
->
getCode
()
==
enigma_error
::
BADPASS
)
{
$this
->
password_prompt
(
$result
);
}
else
{
$this
->
rc
->
output
->
show_message
(
'enigma.keysimportfailed'
,
'error'
);
}
$this
->
rc
->
output
->
send
(
'iframe'
);
}
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
(
rcube_utils
::
max_upload_size
())));
}
else
{
$this
->
rc
->
output
->
show_message
(
'fileuploaderror'
,
'error'
);
}
$this
->
rc
->
output
->
send
(
'iframe'
);
}
$this
->
rc
->
output
->
add_handlers
(
array
(
'importform'
=>
array
(
$this
,
'tpl_key_import_form'
),
));
$this
->
rc
->
output
->
send
(
'enigma.keyimport'
);
}
/**
* Key import-search (page) handler
*/
private
function
key_import_search
()
{
$this
->
rc
->
output
->
add_handlers
(
array
(
'importform'
=>
array
(
$this
,
'tpl_key_import_form'
),
));
$this
->
rc
->
output
->
send
(
'enigma.keysearch'
);
}
/**
* Template object for key import (upload) form
*/
function
tpl_key_import_form
(
$attrib
)
{
$attrib
+=
array
(
'id'
=>
'rcmKeyImportForm'
);
if
(
empty
(
$attrib
[
'part'
])
||
$attrib
[
'part'
]
==
'import'
)
{
$title
=
$this
->
enigma
->
gettext
(
'keyimportlabel'
);
$upload
=
new
html_inputfield
(
array
(
'type'
=>
'file'
,
'name'
=>
'_file'
,
'id'
=>
'rcmimportfile'
,
'size'
=>
30
));
$max_filesize
=
$this
->
rc
->
upload_init
();
$upload_button
=
new
html_button
(
array
(
'class'
=>
'button import'
,
'onclick'
=>
"return rcmail.command('plugin.enigma-import','',this,event)"
,
));
$form
=
html
::
div
(
null
,
html
::
p
(
null
,
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'keyimporttext'
),
'show'
))
.
$upload
->
show
()
.
html
::
div
(
'hint'
,
$this
->
rc
->
gettext
(
array
(
'id'
=>
'importfile'
,
'name'
=>
'maxuploadsize'
,
'vars'
=>
array
(
'size'
=>
$max_filesize
))))
.
(
empty
(
$attrib
[
'part'
])
?
html
::
br
()
.
html
::
br
()
.
$upload_button
->
show
(
$this
->
rc
->
gettext
(
'import'
))
:
''
)
);
if
(
empty
(
$attrib
[
'part'
]))
{
$form
=
html
::
tag
(
'fieldset'
,
''
,
html
::
tag
(
'legend'
,
null
,
$title
)
.
$form
);
}
else
{
$this
->
rc
->
output
->
set_pagetitle
(
$title
);
}
}
if
(
empty
(
$attrib
[
'part'
])
||
$attrib
[
'part'
]
==
'search'
)
{
$title
=
$this
->
enigma
->
gettext
(
'keyimportsearchlabel'
);
$search
=
new
html_inputfield
(
array
(
'type'
=>
'text'
,
'name'
=>
'_search'
,
'id'
=>
'rcmimportsearch'
,
'size'
=>
30
));
$search_button
=
new
html_button
(
array
(
'class'
=>
'button search'
,
'onclick'
=>
"return rcmail.command('plugin.enigma-import-search','',this,event)"
,
));
$form
=
html
::
div
(
null
,
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'keyimportsearchtext'
),
'show'
)
.
html
::
br
()
.
html
::
br
()
.
$search
->
show
()
.
(
empty
(
$attrib
[
'part'
])
?
html
::
br
()
.
html
::
br
()
.
$search_button
->
show
(
$this
->
rc
->
gettext
(
'search'
))
:
''
)
);
if
(
empty
(
$attrib
[
'part'
]))
{
$form
=
html
::
tag
(
'fieldset'
,
''
,
html
::
tag
(
'legend'
,
null
,
$title
)
.
$form
);
}
else
{
$this
->
rc
->
output
->
set_pagetitle
(
$title
);
}
$this
->
rc
->
output
->
include_script
(
'publickey.js'
);
}
$this
->
rc
->
output
->
add_label
(
'selectimportfile'
,
'importwait'
,
'nopubkeyfor'
,
'nopubkeyforsender'
,
'encryptnoattachments'
,
'encryptedsendialog'
,
'searchpubkeyservers'
,
'importpubkeys'
,
'encryptpubkeysfound'
,
'search'
,
'close'
,
'import'
,
'keyid'
,
'keylength'
,
'keyexpired'
,
'keyrevoked'
,
'keyimportsuccess'
,
'keyservererror'
);
$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
()
{
// Crypt_GPG does not support key generation for multiple identities
// It is also very slow (which is problematic because it may exceed
// request time limit) and requires entropy generator
// That's why we use only OpenPGP.js method of key generation
return
;
$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_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
);
$checkbox
=
new
html_checkbox
(
array
(
'name'
=>
'identity[]'
));
$plugin
=
$this
->
rc
->
plugins
->
exec_hook
(
'enigma_user_identities'
,
array
(
'identities'
=>
$identities
));
$identities
=
$plugin
[
'identities'
];
foreach
(
$identities
as
$idx
=>
$ident
)
{
$name
=
empty
(
$ident
[
'name'
])
?
(
$ident
[
'email'
])
:
$ident
[
'ident'
];
$attr
=
array
(
'value'
=>
$idx
,
'data-name'
=>
$ident
[
'name'
],
'data-email'
=>
$ident
[
'email'
]);
$identities
[
$idx
]
=
html
::
tag
(
'li'
,
null
,
html
::
label
(
null
,
$checkbox
->
show
(
$idx
,
$attr
)
.
rcube
::
Q
(
$name
)));
}
$table
->
add
(
'title'
,
html
::
label
(
'key-name'
,
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'newkeyident'
))));
$table
->
add
(
null
,
html
::
tag
(
'ul'
,
'proplist'
,
implode
(
"
\n
"
,
$identities
)));
// 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
,
'autocomplete'
=>
'new-password'
,
'oninput'
=>
"this.type = this.value.length ? 'password' : 'text'"
,
),
'text'
));
$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
,
'autocomplete'
=>
'new-password'
,
'oninput'
=>
"this.type = this.value.length ? 'password' : 'text'"
,
),
'text'
));
$this
->
rc
->
output
->
add_gui_object
(
'keyform'
,
$attrib
[
'id'
]);
$this
->
rc
->
output
->
add_label
(
'enigma.keygenerating'
,
'enigma.formerror'
,
'enigma.passwordsdiffer'
,
'enigma.keygenerateerror'
,
'enigma.noidentselected'
,
'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
();
$this
->
rc
->
output
->
add_label
(
'enigma.sendunencrypted'
);
// Elastic skin (or a skin based on it)
if
(
array_key_exists
(
'elastic'
,
(
array
)
$this
->
rc
->
output
->
skins
))
{
$this
->
enigma
->
api
->
add_content
(
$this
->
compose_ui_options
(),
'composeoptions'
);
}
// other skins
else
{
// 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
,
'aria-owns'
=>
'enigmamenu'
,
'aria-haspopup'
=>
'true'
,
'aria-expanded'
=>
'false'
,
),
'toolbar'
);
// Options menu contents
$this
->
rc
->
output
->
add_footer
(
$this
->
compose_ui_options
(
true
));
}
}
/**
* Init compose UI (add task button and the menu)
*/
private
function
compose_ui_options
(
$wrap
=
false
)
{
$locks
=
(
array
)
$this
->
rc
->
config
->
get
(
'enigma_options_lock'
);
$chbox
=
new
html_checkbox
(
array
(
'value'
=>
1
));
$out
=
html
::
div
(
'form-group form-check row'
,
html
::
label
(
array
(
'for'
=>
'enigmasignopt'
,
'class'
=>
'col-form-label col-6'
),
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'signmsg'
)))
.
html
::
div
(
'form-check col-6'
,
$chbox
->
show
(
$this
->
rc
->
config
->
get
(
'enigma_sign_all'
)
?
1
:
0
,
array
(
'name'
=>
'_enigma_sign'
,
'id'
=>
'enigmasignopt'
,
'class'
=>
'form-check-input'
,
'disabled'
=>
in_array
(
'sign'
,
$locks
),
))));
$out
.=
html
::
div
(
'form-group form-check row'
,
html
::
label
(
array
(
'for'
=>
'enigmaencryptopt'
,
'class'
=>
'col-form-label col-6'
),
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'encryptmsg'
)))
.
html
::
div
(
'form-check col-6'
,
$chbox
->
show
(
$this
->
rc
->
config
->
get
(
'enigma_encrypt_all'
)
?
1
:
0
,
array
(
'name'
=>
'_enigma_encrypt'
,
'id'
=>
'enigmaencryptopt'
,
'class'
=>
'form-check-input'
,
'disabled'
=>
in_array
(
'encrypt'
,
$locks
),
))));
$out
.=
html
::
div
(
'form-group form-check row'
,
html
::
label
(
array
(
'for'
=>
'enigmaattachpubkeyopt'
,
'class'
=>
'col-form-label col-6'
),
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'attachpubkeymsg'
)))
.
html
::
div
(
'form-check col-6'
,
$chbox
->
show
(
$this
->
rc
->
config
->
get
(
'enigma_attach_pubkey'
)
?
1
:
0
,
array
(
'name'
=>
'_enigma_attachpubkey'
,
'id'
=>
'enigmaattachpubkeyopt'
,
'class'
=>
'form-check-input'
,
'disabled'
=>
in_array
(
'pubkey'
,
$locks
),
))));
if
(!
$wrap
)
{
return
$out
;
}
return
html
::
div
(
array
(
'id'
=>
'enigmamenu'
,
'class'
=>
'popupmenu'
),
$out
);
}
/**
* 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
;
$messages
=
array
();
// 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'
]
=
'boxerror enigmaerror encrypted'
;
$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
if
(
$code
==
enigma_error
::
NOMDC
)
{
$msg
=
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'decryptnomdc'
));
}
else
{
$msg
=
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'decrypterror'
));
}
}
else
if
(
$status
===
enigma_engine
::
ENCRYPTED_PARTIALLY
)
{
$attrib
[
'class'
]
=
'boxwarning enigmawarning encrypted'
;
$msg
=
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'decryptpartial'
));
}
else
{
$attrib
[
'class'
]
=
'boxconfirmation enigmanotice encrypted'
;
$msg
=
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'decryptok'
));
}
$attrib
[
'msg'
]
=
$msg
;
$messages
[]
=
$attrib
;
}
// 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
->
get_sender
(
$engine
,
$p
[
'message'
],
$part_id
);
if
(
$sig
->
valid
===
enigma_error
::
UNVERIFIED
)
{
$attrib
[
'class'
]
=
'boxwarning enigmawarning signed'
;
$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
?
'boxwarning enigmawarning'
:
'boxconfirmation enigmanotice'
)
.
' signed'
;
$label
=
'sigvalid'
.
(
$sig
->
partial
?
'partial'
:
''
);
$msg
=
rcube
::
Q
(
str_replace
(
'$sender'
,
$sender
,
$this
->
enigma
->
gettext
(
$label
)));
}
else
{
$attrib
[
'class'
]
=
'boxwarning enigmawarning signed'
;
if
(
$sender
)
{
$msg
=
rcube
::
Q
(
str_replace
(
'$sender'
,
$sender
,
$this
->
enigma
->
gettext
(
'siginvalid'
)));
}
else
{
$msg
=
rcube
::
Q
(
str_replace
(
'$keyid'
,
enigma_key
::
format_id
(
$sig
->
id
),
$this
->
enigma
->
gettext
(
'signokey'
)));
}
}
}
else
if
(
$sig
&&
$sig
->
getCode
()
==
enigma_error
::
KEYNOTFOUND
)
{
$attrib
[
'class'
]
=
'boxwarning enigmawarning signed'
;
$msg
=
rcube
::
Q
(
str_replace
(
'$keyid'
,
enigma_key
::
format_id
(
$sig
->
getData
(
'id'
)),
$this
->
enigma
->
gettext
(
'signokey'
)));
}
else
{
$attrib
[
'class'
]
=
'boxwarning enigmaerror signed'
;
$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>';
$attrib
[
'msg'
]
=
$msg
;
$messages
[]
=
$attrib
;
}
if
(
$count
=
count
(
$messages
))
{
if
(
$count
==
2
&&
$messages
[
0
][
'class'
]
==
$messages
[
1
][
'class'
])
{
$p
[
'prefix'
]
.=
html
::
div
(
$messages
[
0
],
$messages
[
0
][
'msg'
]
.
' '
.
$messages
[
1
][
'msg'
]);
}
else
{
foreach
(
$messages
as
$msg
)
{
$p
[
'prefix'
]
.=
html
::
div
(
$msg
,
$msg
[
'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 above the message body
$p
[
'content'
]
=
html
::
p
(
array
(
'class'
=>
'enigmaattachment boxinformation aligned-buttons'
),
html
::
span
(
null
,
rcube
::
Q
(
$this
->
enigma
->
gettext
(
'keyattfound'
)))
.
html
::
tag
(
'button'
,
array
(
'onclick'
=>
"return "
.
rcmail_output
::
JS_OBJECT_NAME
.
".enigma_import_attachment('"
.
rcube
::
JQ
(
$part
).
"')"
,
'title'
=>
$this
->
enigma
->
gettext
(
'keyattimport'
),
'class'
=>
'import'
,
),
rcube
::
Q
(
$this
->
rc
->
gettext
(
'import'
)))
)
.
$p
[
'content'
];
$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
)
{
// The message might have been already encrypted by Mailvelope
if
(
strpos
(
$p
[
'message'
]->
getParam
(
'ctype'
),
'multipart/encrypted'
)
===
0
)
{
return
$p
;
}
$savedraft
=
!
empty
(
$_POST
[
'_draft'
])
&&
empty
(
$_GET
[
'_saveonly'
]);
$sign_enable
=
(
bool
)
rcube_utils
::
get_input_value
(
'_enigma_sign'
,
rcube_utils
::
INPUT_POST
);
$encrypt_enable
=
(
bool
)
rcube_utils
::
get_input_value
(
'_enigma_encrypt'
,
rcube_utils
::
INPUT_POST
);
$pubkey_enable
=
(
bool
)
rcube_utils
::
get_input_value
(
'_enigma_attachpubkey'
,
rcube_utils
::
INPUT_POST
);
$locks
=
(
array
)
$this
->
rc
->
config
->
get
(
'enigma_options_lock'
);
if
(
in_array
(
'sign'
,
$locks
))
{
$sign_enable
=
(
bool
)
$this
->
rc
->
config
->
get
(
'enigma_sign_all'
);
}
if
(
in_array
(
'encrypt'
,
$locks
))
{
$encrypt_enable
=
(
bool
)
$this
->
rc
->
config
->
get
(
'enigma_encrypt_all'
);
}
if
(
in_array
(
'pubkey'
,
$locks
))
{
$pubkey_enable
=
(
bool
)
$this
->
rc
->
config
->
get
(
'enigma_attach_pubkey'
);
}
if
(!
$savedraft
&&
$pubkey_enable
)
{
$engine
=
$this
->
enigma
->
load_engine
();
$engine
->
attach_public_key
(
$p
[
'message'
]);
}
if
(
$encrypt_enable
)
{
$engine
=
$this
->
enigma
->
load_engine
();
$mode
=
!
$savedraft
&&
$sign_enable
?
enigma_engine
::
ENCRYPT_MODE_SIGN
:
null
;
$status
=
$engine
->
encrypt_message
(
$p
[
'message'
],
$mode
,
$savedraft
);
$mode
=
'encrypt'
;
}
else
if
(!
$savedraft
&&
$sign_enable
)
{
$engine
=
$this
->
enigma
->
load_engine
();
$status
=
$engine
->
sign_message
(
$p
[
'message'
],
enigma_engine
::
SIGN_MODE_MIME
);
$mode
=
'sign'
;
}
if
(
$mode
&&
(
$status
instanceof
enigma_error
))
{
$code
=
$status
->
getCode
();
if
(
$code
==
enigma_error
::
KEYNOTFOUND
)
{
if
(
$email
=
$status
->
getData
(
'missing'
))
{
$vars
=
array
(
'email'
=>
$email
);
$msg
=
'enigma.'
.
$mode
.
'nokey'
;
}
else
{
$msg
=
'enigma.'
.
(
$encrypt_enable
?
'encryptnoprivkey'
:
'signnokey'
);
}
}
else
if
(
$code
==
enigma_error
::
BADPASS
)
{
$this
->
password_prompt
(
$status
);
}
else
{
$msg
=
'enigma.'
.
$mode
.
'error'
;
}
if
(
$msg
)
{
if
(
$vars
&&
$vars
[
'email'
])
{
$this
->
rc
->
output
->
command
(
'enigma_key_not_found'
,
array
(
'email'
=>
$vars
[
'email'
],
'text'
=>
$this
->
rc
->
gettext
(
array
(
'name'
=>
$msg
,
'vars'
=>
$vars
)),
'title'
=>
$this
->
enigma
->
gettext
(
'keynotfound'
),
'button'
=>
$this
->
enigma
->
gettext
(
'findkey'
),
'mode'
=>
$mode
,
));
}
else
{
$this
->
rc
->
output
->
show_message
(
$msg
,
'error'
,
$vars
);
}
}
$this
->
rc
->
output
->
send
(
'iframe'
);
}
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
;
$locks
=
(
array
)
$this
->
rc
->
config
->
get
(
'enigma_options_lock'
);
// 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
if
(!
in_array
(
'encrypt'
,
$locks
))
{
$this
->
rc
->
output
->
set_env
(
'enigma_force_encrypt'
,
!
empty
(
$engine
->
decryptions
));
}
if
(!
in_array
(
'sign'
,
$locks
))
{
$this
->
rc
->
output
->
set_env
(
'enigma_force_sign'
,
!
empty
(
$engine
->
signatures
));
}
return
$p
;
}
/**
* Handler for keys/certs import request action
*/
function
import_file
()
{
$uid
=
rcube_utils
::
get_input_value
(
'_uid'
,
rcube_utils
::
INPUT_POST
);
$mbox
=
rcube_utils
::
get_input_value
(
'_mbox'
,
rcube_utils
::
INPUT_POST
);
$mime_id
=
rcube_utils
::
get_input_value
(
'_part'
,
rcube_utils
::
INPUT_POST
);
$engine
=
$this
->
enigma
->
load_engine
();
if
(
$uid
&&
$mime_id
)
{
// Note: we get the attachment body via rcube_message class
// to support keys inside encrypted messages (#5285)
$message
=
new
rcube_message
(
$uid
,
$mbox
);
// Check if we don't need to ask for password again
foreach
(
$engine
->
decryptions
as
$status
)
{
if
(
$status
instanceof
enigma_error
)
{
if
(
$status
->
getCode
()
==
enigma_error
::
BADPASS
)
{
$this
->
password_prompt
(
$status
,
array
(
'input_uid'
=>
$uid
,
'input_mbox'
=>
$mbox
,
'input_part'
=>
$mime_id
,
'input_task'
=>
'mail'
,
'input_action'
=>
'plugin.enigmaimport'
,
'action'
=>
'?'
,
'iframe'
=>
true
,
));
$this
->
rc
->
output
->
send
(
$this
->
rc
->
output
->
type
==
'html'
?
'iframe'
:
null
);
return
;
}
}
}
if
(
$engine
->
is_keys_part
(
$message
->
mime_parts
[
$mime_id
]))
{
$part
=
$message
->
get_part_body
(
$mime_id
);
}
}
if
(
$part
&&
is_array
(
$result
=
$engine
->
import_key
(
$part
)))
{
$this
->
rc
->
output
->
show_message
(
'enigma.keysimportsuccess'
,
'confirmation'
,
array
(
'new'
=>
$result
[
'imported'
],
'old'
=>
$result
[
'unchanged'
]));
}
else
{
$this
->
rc
->
output
->
show_message
(
'enigma.keysimportfailed'
,
'error'
);
}
$this
->
rc
->
output
->
send
(
$this
->
rc
->
output
->
type
==
'html'
?
'iframe'
:
null
);
}
/**
* 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
;
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Fri, Jun 12, 2:59 AM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
914540
Default Alt Text
enigma_ui.php (47 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment