#!/usr/bin/python3
from gi.repository import GLib
from pydbus import SystemBus
import isodumper.raw_write as raw_write
import threading
import gettext
import logging
import time
DEAMON_ORG = 'org.mageia.Magiback'
DEAMON_INTERFACE = DEAMON_ORG
ISODUMPER_INTERFACE = DEAMON_ORG + ".Isodumper"
# Keep the authorization during KEEPER (in seconds)
KEEPER = 3600
auth = False
last_auth = 0
logging.basicConfig(filename="/var/log/magiback.log",
format='%(asctime)s %(levelname)-8s %(message)s',
level=logging.DEBUG)
class Isodumper(raw_write.Dumper):
"""
"""
def __init__(self):
super().__init__()
APP = "isodumper"
DIR = "/usr/share/locale"
# Call translation catalog
gettext.install(APP, localedir=DIR,)
self.finished = threading.Event()
# finished is cleared at start of operation, and set at the end
self.finished.clear()
self._progress = 0
self.loop = GLib.MainLoop()
self.return_state = False
self.return_message = ""
self.authorized_sender_read = set()
self.authorized_sender_write = set()
self.sum_check = ""
self.sum_check_searched = False
self.signature_checked = False
self.writing_perm = False
self.writing_target = ""
self.backup_mode = False
self.uid = 0
self.gid = 0
self.last_auth = time.perf_counter()
def do_write(self, source, target, size, dbus_context):
self.finished.clear()
if check_permission('org.mageia.Magiback.Isodumper.write', dbus_context):
self.thread = threading.Thread(target=self._do_write, args=(source, target, size, self.backup_mode, self.uid, self.gid))
self.thread.start()
logging.info("Writing thread started")
self.writing_perm = True
self.writing_target = target
else:
self.return_message = "Writing: Access denied"
self.return_state = False
logging.debug(self.return_message)
self.finished.set()
def do_persistence(self, target, label, key, fs_type):
self.finished.clear()
if self.writing_perm and self.writing_target == target:
self.thread = threading.Thread(target=self._do_persistence, args=(target, label, key, fs_type))
self.thread.start()
logging.info("Persistence thread started")
else:
self.return_message = "Persistence: Access denied"
logging.info(self.return_message)
self.finished.set()
self.writing_perm = False
self.writing_target = ""
@property
def done(self):
return self.finished.wait(1)
@property
def message(self):
return self.return_message
@property
def state(self):
return self.return_state
def end(self):
if hasattr(self, 'thread'):
self.thread.join()
self._progress = 0
self.finished.clear()
return self.return_state, self.return_message
def close(self):
logging.info("Closing")
# Close the loop from the main function
loop.quit()
@property
def progress(self):
return self._progress
def check_write(self, target, source):
if hasattr(self, 'key_thread'):
self.key_thread.join()
self.thread = threading.Thread(target=self._check_write, args=(target, source,))
self.thread.start()
def set_backup_mode(self, uid, gid):
logging.info("Set in backup mode")
self.backup_mode = True
self.uid = uid
self.gid = gid
def unset_backup_mode(self):
logging.info("Unset the backup mode")
self.backup_mode = False
self.uid = 0
self.gid = 0
def run(self):
self.loop.run()
def check_permission(action, dbus_context):
""" Check permission
"""
global auth
global last_auth
cur = time.perf_counter()
if cur - last_auth > KEEPER or not auth:
auth = dbus_context.is_authorized(action, {'polkit.icon_name': 'isodumper.png', }, interactive=True)
if auth:
last_auth = cur
return auth
else:
return True
class ConfFile(object):
"""
"""
def __init__(self):
super().__init__()
def setName(self, file_name):
self.file_name = file_name
def getFile(self):
with open(self.file_name, 'r') as tcf:
# read the file
content=""
while 1:
line = tcf.readline()
if not line:
break
content += line
return content
def saveFile(self, tc, dbus_context):
if check_permission('org.mageia.Magiback.write', dbus_context):
try:
with open(self.file_name, 'w') as tcf:
tcf.write(tc)
except:
return False
return True
class Logging(object):
"""
"""
def __init__(self):
super().__init__()
def debug(self, message):
logging.debug(message)
def info(self, message):
logging.info(message)
def warning(self, message):
logging.warning(message)
def error(self, message):
logging.error(message)
if __name__ == '__main__':
print("Running Magiback service.")
bus = SystemBus()
conf_file = ConfFile()
log = Logging()
bus.publish(DEAMON_ORG, conf_file, ("Isodumper", Isodumper()), ('Logging', Logging()))
loop = GLib.MainLoop()
loop.run()
logging.shutdown()