Exemple #1
0
migration management is done from command-line (using socket for communication).

basic commands (see --help for all options):

kopano-msr --list-users -> list users currently being migrated

kopano-msr -u user1 --add --server node14 -> start migrating user

kopano-msr -u user1 ->  check migration status, compare store contents

kopano-msr -u user1 --remove -> finalize migration (metadata, special folders..)

"""

CONFIG = {
    'state_path': Config.path(default='/var/lib/kopano/msr/', check=True),
    'server_bind_name': Config.string(default='file:///var/run/kopano/msr.sock'),
    'ssl_private_key_file': Config.path(default=None, check=False), # XXX don't check when default=None?
    'ssl_certificate_file': Config.path(default=None, check=False),
}

setproctitle.setproctitle('kopano-msr main')

def init_globals(): # late init to survive daemonization
    global LOCK, STORE_STORE, USER_INFO, STORE_FOLDER_QUEUED, STORE_FOLDERS_TODO, USER_SINK

    LOCK = multiprocessing.Lock()

    _mgr = multiprocessing.Manager()

    # TODO persistency
Exemple #2
0
since ICS does not know for deletion changes which store they belong to, we remember ourselves using a berkeleydb file ("serverguid_mapping").

we also maintain folder and server ICS states in a berkeleydb file, for example so we can resume initial indexing ("serverguid_state").
after initial indexing folder states are not updated anymore.

the used search engine is pluggable, but by default we use xapian (plugin_xapian.py).

a tricky bit is that outlook/exchange perform 'prefix' searches by default and we want to be compatible with this, so terms get an
implicit '*' at the end. not every search engine may perform well for this, but we could make this configurable perhaps.

"""

CONFIG = {
    'coredump_enabled':
    Config.ignore(),
    'index_attachments':
    Config.boolean(default=False),
    'index_attachment_extension_filter':
    Config.ignore(),
    'index_attachment_mime_filter':
    Config.ignore(),
    'index_attachment_max_size':
    Config.size(default=2**24),
    'index_attachment_parser':
    Config.ignore(),
    'index_attachment_parser_max_memory':
    Config.ignore(),
    'index_attachment_parser_max_cputime':
    Config.ignore(),
    # 0x007D: PR_TRANSPORT_MESSAGE_HEADERS
Exemple #3
0
kopano-backup -u user1 -f Inbox -> backup 'Inbox' folder for user 'user1' in (new) directory 'user1'

kopano-backup --restore user1 -> restore data from directory 'user1' to account called 'user1'
kopano-backup --restore -u user2 user1 -> same, but restore to account 'user2'

kopano-backup --stats user1 -> summarize contents of backup directory 'user1', in CSV format
kopano-backup --index user1 -> low-level overview of stored items, in CSV format

options can be combined when this makes sense, for example:

kopano-backup --index user1 -f Inbox/subfolder --recursive --period-begin 2014-01-01

"""

CONFIG = {
    'backup_servers': Config.string(multiple=True, default=None),
}

CACHE_SIZE = 64000000 # XXX make configurable

def pickle_dumps(s):
    return pickle.dumps(s, protocol=2)

def pickle_loads(s):
    return pickle.loads(s, encoding='bytes')

def _hex(s):
    return codecs.encode(s, 'hex').upper()

def _unhex(s):
    return codecs.decode(s, 'hex')
# example of using Service class, in the form of an (incomplete) python version of kopano-monitor

# usage: ./kopano-monitor.py

import time
from datetime import timedelta, datetime

import kopano
from kopano import Config
from kopano.utils import bytes_to_human

from MAPI.Tags import PR_EC_QUOTA_MAIL_TIME

CONFIG = {
    'quota_check_interval':
    Config.integer(default=15),
    'mailquota_resend_interval':
    Config.integer(default=1),
    'servers':
    Config.string(default=''),  # XXX
    'userquota_warning_template':
    Config.path(default='/etc/kopano/quotamail/userwarning.mail'),
    'userquota_soft_template':
    Config.path(default='/etc/kopano/quotamail/usersoft.mail'),
    'userquota_hard_template':
    Config.path(default='/etc/kopano/quotamail/userhard.mail'),
    'companyquota_warning_template':
    Config.path(default='/etc/kopano/quotamail/companywarning.mail'),
}
""""
TODO:
Exemple #5
0
import hashlib
import hmac
import json
import os.path
import signal
import sys
sys.path.insert(0, os.path.dirname(__file__))  # XXX for __import__ to work
import time
import threading
import traceback

import kopano
from kopano import log_exc, Config

CONFIG = {
    'data_path': Config.string(default='/var/lib/kopano/presence/'),
    'data_save_interval': Config.integer(default=5),
    'plugins': Config.string(multiple=True, default=['spreed']),
    'run_as_user': Config.string(default="kopano"),
    'run_as_group': Config.string(default="kopano"),
    'server_bind': Config.string(default="127.0.0.1"),
    'server_port': Config.integer(default="1234"),
    'server_auth_user': Config.string(default="presence"),
    'server_auth_password': Config.string(default="presence"),
    'server_secret_key': Config.string(),
    'server_token_expire': Config.integer(default="5"),
    'xmpp_jid': Config.string(default=None),
    'xmpp_password': Config.string(default=None),
    'xmpp_user_id_strip_domain': Config.boolean(default=None),
    'spreed_auto_unavailable': Config.integer(default="2"),
}
Exemple #6
0
from contextlib import closing
import grp
import os
import sys
import time

import bsddb3 as bsddb

import kopano
from kopano import Config, log_exc
"""
kopano-spamd - ICS driven spam learning daemon for Kopano / SpamAssasin
"""

CONFIG = {
    'spam_dir': Config.string(default="/var/lib/kopano/spamd/spam"),
    'ham_dir': Config.string(default="/var/lib/kopano/spamd/ham"),
    'spam_db': Config.string(default="/var/lib/kopano/spamd/spam.db"),
    'sa_group': Config.string(default="amavis"),
    'run_as_user': Config.string(default="kopano"),
    'run_as_group': Config.string(default="kopano"),
    'learn_ham': Config.boolean(default=True),
    'header_tag': Config.string(default="x-spam-flag")
}


class Service(kopano.Service):
    def main(self):
        server = self.server
        state = server.state  # start from current state
        importer = Importer(self)
Exemple #7
0
search queries from outlook/webapp are dealt with by a single instance of class SearchWorker.

since ICS does not know for deletion changes which store they belong to, we remember ourselves using a berkeleydb file ("serverguid_mapping").

we also maintain folder and server ICS states in a berkeleydb file, for example so we can resume initial indexing ("serverguid_state").
after initial indexing folder states are not updated anymore.

the used search engine is pluggable, but by default we use xapian (plugin_xapian.py).

a tricky bit is that outlook/exchange perform 'prefix' searches by default and we want to be compatible with this, so terms get an
implicit '*' at the end. not every search engine may perform well for this, but we could make this configurable perhaps.

"""

CONFIG = {
    'coredump_enabled': Config.ignore(),
    'index_attachments': Config.boolean(default=True),
    'index_attachment_extension_filter': Config.ignore(),
    'index_attachment_mime_filter': Config.ignore(),
    'index_attachment_max_size': Config.size(default=2**24),
    'index_attachment_parser': Config.ignore(),
    'index_attachment_parser_max_memory': Config.ignore(),
    'index_attachment_parser_max_cputime': Config.ignore(),
    # 0x007D: PR_TRANSPORT_MESSAGE_HEADERS
    # 0x0064: PR_SENT_REPRESENTING_ADDRTYPE
    # 0x0C1E: PR_SENDER_ADDRTYPE
    # 0x0075: PR_RECEIVED_BY_ADDRTYPE
    # 0x678E: PR_EC_IMAP_BODY
    # 0x678F: PR_EC_IMAP_BODYSTRUCTURE
    # 0x001A: PR_MESSAGE_CLASS # XXX add to cfg
    'index_exclude_properties': Config.integer(multiple=True, base=16, default=[0x007D, 0x0064, 0x0C1E, 0x0075, 0x678E, 0x678F, 0x001A]),
Exemple #8
0
it under the terms of the GNU Affero General Public License, version 3,
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see http://www.gnu.org/licenses/.


"""

CONFIG = {
    'run_as_user': Config.string(default="kopano"),
    'run_as_group': Config.string(default="kopano"),

    #dspam specific settings:
    'dspam_path': Config.string(default='/var/lib/kopano/dspam/'),
    'process_delay': Config.integer(default=1),

    'header_result': Config.string(default="X-DSPAM-Result"),
    'header_result_spam': Config.string(default="Spam"),

    'header_user': Config.string(default="X-DSPAM-Recipient"),
    'header_id': Config.string(default="X-DSPAM-Signature"),

    'retrain_script': Config.string(default="/etc/kopano/userscripts/kopano-dspam-retrain"),

    #filter dangerous characters before calling shell script
Exemple #9
0
import time
import kopano
import grp
from kopano import Config, log_exc
from contextlib import closing

if sys.hexversion >= 0x03000000:
    import bsddb3 as bsddb
else:
    import bsddb
"""
kopano-spamd - ICS driven spam learning daemon for Kopano / SpamAssasin
"""

CONFIG = {
    'spam_dir': Config.string(default="/var/lib/kopano/spamd/spam"),
    'ham_dir': Config.string(default="/var/lib/kopano/spamd/ham"),
    'spam_db': Config.string(default="/var/lib/kopano/spamd/spam.db"),
    'sa_group': Config.string(default="amavis"),
    'learn_ham': Config.boolean(default=True)
}


class Service(kopano.Service):
    def main(self):
        server = self.server
        state = server.state
        catcher = Checker(self)
        with log_exc(self.log):
            while True:
                try: