mirror of
https://github.com/roundcube/roundcubemail.git
synced 2026-03-03 06:44:03 +01:00
* \n\s+'file' => __FILE__, * \n\s+'line' => __LINE__, * 'line' => __LINE__, 'file' => __FILE__, * 'file' => __FILE__, 'line' => __LINE__, * rest * more * improve cs * more cs * revert rcube_utils::preg_error changes * impl file/line from backtrace * Revert "revert rcube_utils::preg_error changes"
187 lines
5.4 KiB
Bash
Executable File
187 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
/*
|
|
+-----------------------------------------------------------------------+
|
|
| This file is part of the Roundcube Webmail client |
|
|
| |
|
|
| Copyright (C) The Roundcube Dev Team |
|
|
| Copyright (C) Kolab Systems AG |
|
|
| |
|
|
| 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. |
|
|
| |
|
|
| PURPOSE: |
|
|
| Import keys from Enigma's homedir into database for multihost |
|
|
| support. |
|
|
+-----------------------------------------------------------------------+
|
|
| Author: Aleksander Machniak <alec@alec.pl> |
|
|
+-----------------------------------------------------------------------+
|
|
*/
|
|
|
|
define('INSTALL_PATH', realpath(__DIR__ . '/../../../') . '/');
|
|
|
|
require INSTALL_PATH . 'program/include/clisetup.php';
|
|
|
|
$rcmail = rcube::get_instance();
|
|
|
|
// get arguments
|
|
$args = rcube_utils::get_opt([
|
|
'u' => 'user',
|
|
'h' => 'host',
|
|
'd' => 'dir',
|
|
'x' => 'dry-run',
|
|
]);
|
|
|
|
if (!empty($_SERVER['argv'][1]) && $_SERVER['argv'][1] == 'help') {
|
|
print_usage();
|
|
exit;
|
|
}
|
|
|
|
if (empty($args['dir'])) {
|
|
rcube::raise_error('--dir argument is required', true);
|
|
}
|
|
|
|
$host = get_host($args);
|
|
$dirs = [];
|
|
|
|
// Read the homedir and iterate over all subfolders (as users)
|
|
if (empty($args['user'])) {
|
|
if ($dh = opendir($args['dir'])) {
|
|
while (($dir = readdir($dh)) !== false) {
|
|
if ($dir != '.' && $dir != '..') {
|
|
$dirs[$args['dir'] . '/' . $dir] = $dir;
|
|
}
|
|
}
|
|
closedir($dh);
|
|
}
|
|
}
|
|
// a single user
|
|
else {
|
|
$dirs = [$args['dir'] => $args['user']];
|
|
}
|
|
|
|
foreach ($dirs as $dir => $user) {
|
|
echo "Importing keys from {$dir}\n";
|
|
|
|
if ($user_id = get_user_id($user, $host)) {
|
|
reset_state($user_id, !empty($args['dry-run']));
|
|
import_dir($user_id, $dir, !empty($args['dry-run']));
|
|
}
|
|
}
|
|
|
|
function print_usage()
|
|
{
|
|
echo "Usage: import.sh [options]\n";
|
|
echo "Options:\n";
|
|
echo " --user=username User, if not set --dir subfolders will be iterated\n";
|
|
echo " --host=host The IMAP hostname or IP the given user is related to\n";
|
|
echo " --dir=path Location of the gpg homedir\n";
|
|
echo " --dry-run Do nothing, just list found user/files\n";
|
|
}
|
|
|
|
function get_host($args)
|
|
{
|
|
global $rcmail;
|
|
|
|
if (empty($args['host'])) {
|
|
$hosts = $rcmail->config->get('imap_host', '');
|
|
if (is_string($hosts)) {
|
|
$args['host'] = $hosts;
|
|
} elseif (is_array($hosts) && count($hosts) == 1) {
|
|
$args['host'] = reset($hosts);
|
|
} else {
|
|
rcube::raise_error('Specify a host name', true);
|
|
}
|
|
|
|
// host can be a URL like tls://192.168.12.44
|
|
$host_url = parse_url($args['host']);
|
|
if (!empty($host_url['host'])) {
|
|
$args['host'] = $host_url['host'];
|
|
}
|
|
}
|
|
|
|
return $args['host'];
|
|
}
|
|
|
|
function get_user_id($username, $host)
|
|
{
|
|
global $rcmail;
|
|
|
|
$db = $rcmail->get_dbh();
|
|
|
|
// find user in local database
|
|
$user = rcube_user::query($username, $host);
|
|
|
|
if (empty($user)) {
|
|
rcube::raise_error("User does not exist: {$username}");
|
|
}
|
|
|
|
return $user->ID;
|
|
}
|
|
|
|
function reset_state($user_id, $dry_run = false)
|
|
{
|
|
global $rcmail;
|
|
|
|
if ($dry_run) {
|
|
return;
|
|
}
|
|
|
|
$db = $rcmail->get_dbh();
|
|
|
|
$db->query('DELETE FROM ' . $db->table_name('filestore', true)
|
|
. ' WHERE `user_id` = ? AND `context` = ?',
|
|
$user_id, 'enigma');
|
|
}
|
|
|
|
function import_dir($user_id, $dir, $dry_run = false)
|
|
{
|
|
global $rcmail;
|
|
|
|
$db = $rcmail->get_dbh();
|
|
$table = $db->table_name('filestore', true);
|
|
$db_files = ['pubring.gpg', 'secring.gpg', 'pubring.kbx'];
|
|
$maxsize = min($db->get_variable('max_allowed_packet', 1048500), 4 * 1024 * 1024) - 2000;
|
|
|
|
foreach (glob("{$dir}/private-keys-v1.d/*.key") as $file) {
|
|
$db_files[] = substr($file, strlen($dir) + 1);
|
|
}
|
|
|
|
foreach ($db_files as $file) {
|
|
if ($mtime = @filemtime("{$dir}/{$file}")) {
|
|
$data = file_get_contents("{$dir}/{$file}");
|
|
$data = base64_encode($data);
|
|
$datasize = strlen($data);
|
|
|
|
if ($datasize > $maxsize) {
|
|
rcube::raise_error([
|
|
'code' => 605,
|
|
'message' => "Enigma: Failed to save {$file}. Size exceeds max_allowed_packet.",
|
|
], true, false);
|
|
|
|
continue;
|
|
}
|
|
|
|
echo "* {$file}\n";
|
|
|
|
if ($dry_run) {
|
|
continue;
|
|
}
|
|
|
|
$result = $db->query(
|
|
"INSERT INTO {$table} (`user_id`, `context`, `filename`, `mtime`, `data`)"
|
|
. " VALUES(?, 'enigma', ?, ?, ?)",
|
|
$user_id, $file, $mtime, $data);
|
|
|
|
if ($db->is_error($result)) {
|
|
rcube::raise_error([
|
|
'code' => 605,
|
|
'message' => "Enigma: Failed to save {$file} into database.",
|
|
], true, false);
|
|
}
|
|
}
|
|
}
|
|
}
|