Example #1
0
    def startup(self):
        super(TaskClient, self).startup()

        self.cc_url = self.cf.get('cc')
        self.ioloop = IOLoop.instance()
        self.xtx = CryptoContext(self.cf)
        self.ccrq = CCReqStream(self.cc_url, self.xtx, self.ioloop)
        self.taskmgr = TaskManager(self.ccrq)
Example #2
0
File: server.py Project: postsql/cc
    def startup(self):
        """Setup sockets and handlers."""

        super(CCServer, self).startup()

        self.log.info("C&C server version %s starting up..", self.__version__)

        self.xtx = CryptoContext(self.cf)
        self.zctx = zmq.Context(self.zmq_nthreads)
        self.ioloop = IOLoop.instance()

        self.local_url = self.cf.get('cc-socket')

        self.cur_role = self.cf.get('cc-role', 'insecure')
        if self.cur_role == 'insecure':
            self.log.warning(
                'CC is running in insecure mode, please add "cc-role = local" or "cc-role = remote" option to config'
            )

        self.stat_level = self.cf.getint('cc-stats', 1)
        if self.stat_level < 1:
            self.log.warning('CC statistics level too low: %d',
                             self.stat_level)

        # initialize local listen socket
        s = self.zctx.socket(zmq.XREP)
        s.setsockopt(zmq.LINGER, self.zmq_linger)
        s.setsockopt(zmq.HWM, self.zmq_hwm)
        if self.zmq_rcvbuf > 0:
            s.setsockopt(zmq.RCVBUF, self.zmq_rcvbuf)
        if self.zmq_sndbuf > 0:
            s.setsockopt(zmq.SNDBUF, self.zmq_sndbuf)
        if self.zmq_tcp_keepalive > 0:
            if getattr(zmq, 'TCP_KEEPALIVE', -1) > 0:
                s.setsockopt(zmq.TCP_KEEPALIVE, self.zmq_tcp_keepalive)
                s.setsockopt(zmq.TCP_KEEPALIVE_INTVL,
                             self.zmq_tcp_keepalive_intvl)
                s.setsockopt(zmq.TCP_KEEPALIVE_IDLE,
                             self.zmq_tcp_keepalive_idle)
                s.setsockopt(zmq.TCP_KEEPALIVE_CNT, self.zmq_tcp_keepalive_cnt)
            else:
                self.log.info("TCP_KEEPALIVE not available")
        s.bind(self.local_url)
        self.local = CCStream(s, self.ioloop, qmaxsize=self.zmq_hwm)
        self.local.on_recv(self.handle_cc_recv)

        self.handlers = {}
        self.routes = {}
        rcf = skytools.Config('routes', self.cf.filename, ignore_defs=True)
        for r, hnames in rcf.cf.items('routes'):
            self.log.info('New route: %s = %s', r, hnames)
            for hname in [hn.strip() for hn in hnames.split(',')]:
                h = self.get_handler(hname)
                self.add_handler(r, h)

        self.stimer = PeriodicCallback(self.send_stats, 30 * 1000, self.ioloop)
        self.stimer.start()
Example #3
0
    def __init__(self, service_type, args):
        # no crypto for logs
        self.logxtx = CryptoContext(None)
        self.xtx = CryptoContext(None)

        super(CCJob, self).__init__(service_type, args)

        self.hostname = socket.gethostname()

        root = skytools.getLogger()
        root.addHandler(CallbackLogger(self.emit_log))

        self.xtx = CryptoContext(self.cf)
Example #4
0
File: jobmgr.py Project: postsql/cc
    def __init__(self, hname, hcf, ccscript):
        super(JobMgr, self).__init__(hname, hcf, ccscript)

        self.cc_config = ccscript.args[0]

        self.local_url = ccscript.local_url
        self.cc_job_name = ccscript.job_name

        self.job_args_extra = []
        if ccscript.options.quiet:
            self.job_args_extra.append("-q")
        if ccscript.options.verbose:
            self.job_args_extra.extend(["-v"] * ccscript.options.verbose)

        self.jobs = {}
        for dname in self.cf.getlist('daemons'):
            defs = make_job_defaults(ccscript.cf, dname)
            self.add_job(dname, defs)

        self.xtx = CryptoContext(None)
Example #5
0
class CCJob(skytools.DBScript):
    zctx = None
    cc = None
    cc_url = None

    zmq_nthreads = 1
    zmq_linger = 500
    zmq_hwm = 100
    zmq_rcvbuf = 0 # means no change
    zmq_sndbuf = 0 # means no change

    def __init__(self, service_type, args):
        # no crypto for logs
        self.logxtx = CryptoContext(None)
        self.xtx = CryptoContext(None)

        super(CCJob, self).__init__(service_type, args)

        self.hostname = socket.gethostname()

        root = skytools.getLogger()
        root.addHandler(CallbackLogger(self.emit_log))

        self.xtx = CryptoContext(self.cf)

    def emit_log(self, rec):
        if not self.cc:
            self.connect_cc()
        if not self.cc:
            return
        msg = LogMessage(
            req = 'log.%s' % rec.levelname.lower(),
            log_level = rec.levelname,
            service_type = self.service_name,
            job_name = self.job_name,
            log_msg = rec.getMessage(),
            log_time = rec.created,
            log_pid = rec.process,
            log_line = rec.lineno,
            log_function = rec.funcName)
        cmsg = self.logxtx.create_cmsg(msg)
        cmsg.send_to (self.cc)

    def ccquery (self, msg, blob = None):
        """Sends query to CC, waits for answer."""
        assert isinstance (msg, BaseMessage)
        if not self.cc: self.connect_cc()

        cmsg = self.xtx.create_cmsg (msg, blob)
        cmsg.send_to (self.cc)

        crep = CCMessage(self.cc.recv_multipart())
        return crep.get_payload(self.xtx)

    def ccpublish (self, msg, blob = None):
        assert isinstance (msg, BaseMessage)
        if not self.cc:
            self.connect_cc()
        cmsg = self.xtx.create_cmsg (msg, blob)
        cmsg.send_to (self.cc)

    def load_config(self):
        """ Load and return skytools.Config instance. """

        cf = skytools.Config('ccserver', self.args[0])
        self.cc_jobname = cf.get('job_name')
        self.cc_url = cf.get('cc-socket')

        if len(self.args) > 1:
            self.service_name = self.args[1]

        self.cf_defaults = make_job_defaults(cf, self.service_name)

        cf = super(CCJob, self).load_config()
        return cf

    def reload (self):
        """ Reload config. """
        super(CCJob, self).reload()

        self.zmq_nthreads = self.cf.getint ('zmq_nthreads', self.zmq_nthreads)
        self.zmq_hwm = self.cf.getint ('zmq_hwm', self.zmq_hwm)
        self.zmq_linger = self.cf.getint ('zmq_linger', self.zmq_linger)
        self.zmq_rcvbuf = hsize_to_bytes (self.cf.get ('zmq_rcvbuf', str(self.zmq_rcvbuf)))
        self.zmq_sndbuf = hsize_to_bytes (self.cf.get ('zmq_sndbuf', str(self.zmq_sndbuf)))

        self.close_cc()

    def _boot_daemon(self):
        # close ZMQ context/thread before forking to background
        self.close_cc()

        super(CCJob, self)._boot_daemon()

    def connect_cc(self):
        if not self.zctx:
            self.zctx = zmq.Context(self.zmq_nthreads)
        if not self.cc:
            self.cc = self.zctx.socket(zmq.XREQ)
            self.cc.setsockopt(zmq.LINGER, self.zmq_linger)
            self.cc.setsockopt(zmq.HWM, self.zmq_hwm)
            if self.zmq_rcvbuf > 0:
                self.cc.setsockopt (zmq.RCVBUF, self.zmq_rcvbuf)
            if self.zmq_sndbuf > 0:
                self.cc.setsockopt (zmq.SNDBUF, self.zmq_sndbuf)
            self.cc.connect (self.cc_url)
        return self.cc

    def close_cc(self):
        if self.cc:
            self.cc.close()
            self.cc = None
        if self.zctx:
            self.zctx.term()
            self.zctx = None
Example #6
0
    def startup(self):
        """Setup sockets and handlers."""

        super(CCServer, self).startup()

        self.log.info("C&C server version %s starting up..", self.__version__)

        self.xtx = CryptoContext(self.cf)
        self.zctx = zmq.Context(self.zmq_nthreads)
        self.ioloop = IOLoop.instance()

        self.local_url = self.cf.get('cc-socket')

        self.cur_role = self.cf.get('cc-role', 'insecure')
        if self.cur_role == 'insecure':
            self.log.warning(
                'CC is running in insecure mode, please add "cc-role = local" or "cc-role = remote" option to config'
            )

        self.stat_level = self.cf.getint('cc-stats', 1)
        if self.stat_level < 1:
            self.log.warning('CC statistics level too low: %d',
                             self.stat_level)

        self.infofile = self.cf.getfile('infofile', '')
        self.infofile_level = self.cf.getint('infofile-level', 2)
        if self.infofile_level >= 3:
            self.stats_deque_bucket = 5  # seconds
            self.stats_deque_cursor = int(time.time() /
                                          self.stats_deque_bucket)
            self.stats_timespans = [1 * 60, 5 * 60, 15 * 60]  # seconds
            assert sum([
                ts % self.stats_deque_bucket for ts in self.stats_timespans
            ]) == 0
            self.stats_deque_window = max(
                self.stats_timespans) / self.stats_deque_bucket + 1
            self.stats_deque = deque([{}
                                      for i in range(self.stats_deque_window)],
                                     maxlen=self.stats_deque_window)
        self.stats_total = {}

        # initialize local listen socket
        s = self.zctx.socket(zmq.XREP)
        s.setsockopt(zmq.LINGER, self.zmq_linger)
        try:
            s.setsockopt(zmq.HWM, self.zmq_hwm)
        except AttributeError:
            s.set_hwm(self.zmq_hwm)
        if self.zmq_rcvbuf > 0:
            s.setsockopt(zmq.RCVBUF, self.zmq_rcvbuf)
        if self.zmq_sndbuf > 0:
            s.setsockopt(zmq.SNDBUF, self.zmq_sndbuf)
        if self.zmq_tcp_keepalive > 0:
            if getattr(zmq, 'TCP_KEEPALIVE', -1) > 0:
                s.setsockopt(zmq.TCP_KEEPALIVE, self.zmq_tcp_keepalive)
                s.setsockopt(zmq.TCP_KEEPALIVE_INTVL,
                             self.zmq_tcp_keepalive_intvl)
                s.setsockopt(zmq.TCP_KEEPALIVE_IDLE,
                             self.zmq_tcp_keepalive_idle)
                s.setsockopt(zmq.TCP_KEEPALIVE_CNT, self.zmq_tcp_keepalive_cnt)
            else:
                self.log.info("TCP_KEEPALIVE not available")
        s.bind(self.local_url)
        self.local = CCStream(s, self.ioloop, qmaxsize=self.zmq_hwm)
        self.local.on_recv(self.handle_cc_recv)

        self.handlers = {}
        self.routes = {}
        rcf = skytools.Config('routes', self.cf.filename, ignore_defs=True)
        for r, hnames in rcf.cf.items('routes'):
            self.log.info('New route: %s = %s', r, hnames)
            for hname in [hn.strip() for hn in hnames.split(',')]:
                h = self.get_handler(hname)
                self.add_handler(r, h)

        self.stats_period = self.cf.getint('stats-period', 30)
        self.stimer = PeriodicCallback(self.send_stats,
                                       self.stats_period * 1000, self.ioloop)
        self.stimer.start()