monkey/infection_monkey/system_singleton.py

113 lines
3.0 KiB
Python
Raw Normal View History

2015-08-30 15:27:35 +08:00
import ctypes
import logging
2017-10-01 22:59:17 +08:00
import sys
2015-08-30 15:27:35 +08:00
from abc import ABCMeta, abstractmethod
2017-10-01 22:59:17 +08:00
2015-08-30 15:27:35 +08:00
from config import WormConfiguration
__author__ = 'itamar'
LOG = logging.getLogger(__name__)
2015-11-30 16:56:20 +08:00
2015-08-30 15:27:35 +08:00
class _SystemSingleton(object):
__metaclass__ = ABCMeta
@property
@abstractmethod
def locked(self):
raise NotImplementedError()
@abstractmethod
def try_lock(self):
raise NotImplementedError()
@abstractmethod
def unlock(self):
raise NotImplementedError()
class WindowsSystemSingleton(_SystemSingleton):
def __init__(self):
2017-10-01 22:59:17 +08:00
self._mutex_name = r"Global\%s" % (WormConfiguration.singleton_mutex_name,)
2015-08-30 15:27:35 +08:00
self._mutex_handle = None
@property
def locked(self):
return self._mutex_handle is not None
def try_lock(self):
assert self._mutex_handle is None, "Singleton already locked"
handle = ctypes.windll.kernel32.CreateMutexA(None,
ctypes.c_bool(True),
ctypes.c_char_p(self._mutex_name))
last_error = ctypes.windll.kernel32.GetLastError()
if not handle:
LOG.error("Cannot acquire system singleton %r, unknown error %d",
2015-11-30 16:56:20 +08:00
self._mutex_name, last_error)
2015-08-30 15:27:35 +08:00
return False
if winerror.ERROR_ALREADY_EXISTS == last_error:
LOG.debug("Cannot acquire system singleton %r, mutex already exist",
self._mutex_name)
return False
2017-10-01 22:59:17 +08:00
2015-08-30 15:27:35 +08:00
self._mutex_handle = handle
LOG.debug("Global singleton mutex %r acquired",
self._mutex_name)
return True
def unlock(self):
assert self._mutex_handle is not None, "Singleton not locked"
ctypes.windll.kernel32.CloseHandle(self._mutex_handle)
self._mutex_handle = None
class LinuxSystemSingleton(_SystemSingleton):
def __init__(self):
self._unix_sock_name = str(WormConfiguration.singleton_mutex_name)
self._sock_handle = None
2015-08-30 15:27:35 +08:00
@property
def locked(self):
return self._sock_handle is not None
2015-08-30 15:27:35 +08:00
def try_lock(self):
assert self._sock_handle is None, "Singleton already locked"
2017-10-01 22:59:17 +08:00
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
2017-10-01 22:59:17 +08:00
try:
sock.bind('\0' + self._unix_sock_name)
2017-10-01 22:59:17 +08:00
except socket.error as e:
LOG.error("Cannot acquire system singleton %r, error code %d, error: %s",
2015-11-30 16:56:20 +08:00
self._unix_sock_name, e.args[0], e.args[1])
return False
2017-10-01 22:59:17 +08:00
self._sock_handle = sock
2015-11-30 16:56:20 +08:00
LOG.debug("Global singleton mutex %r acquired", self._unix_sock_name)
2015-08-30 15:27:35 +08:00
return True
def unlock(self):
assert self._sock_handle is not None, "Singleton not locked"
self._sock_handle.close()
self._sock_handle = None
2015-08-30 15:27:35 +08:00
2017-10-01 22:59:17 +08:00
2015-08-30 15:27:35 +08:00
if sys.platform == "win32":
import winerror
2017-10-01 22:59:17 +08:00
2015-08-30 15:27:35 +08:00
SystemSingleton = WindowsSystemSingleton
else:
import socket
2017-10-01 22:59:17 +08:00
2015-08-30 15:27:35 +08:00
SystemSingleton = LinuxSystemSingleton