Esempio n. 1
0
 def actorResult(
     result: typing.Any = None,
     error: typing.Optional[str] = None
 ) -> typing.MutableMapping[str, typing.Any]:
     result = result or ''
     res = {'result': result, 'stamp': getSqlDatetimeAsUnix()}
     if error:
         res['error'] = error
     return res
Esempio n. 2
0
    def addEvent(self, owner_type: int, owner_id: int, eventType: int,
                 **kwargs):
        """
        Adds a new event stat to database.

        stamp=None, fld1=None, fld2=None, fld3=None
        Args:

            toWhat: if of the counter
            stamp: if not None, this will be used as date for cuounter, else current date/time will be get
                   (this has a granurality of seconds)

        Returns:

            Nothing
        """
        logger.debug('Adding event stat')
        stamp = kwargs.get('stamp')
        if stamp is None:
            stamp = getSqlDatetimeAsUnix()
        else:
            # To Unix epoch
            stamp = int(time.mktime(stamp.timetuple()))  # pylint: disable=maybe-no-member

        try:

            # Replaces nulls for ''
            def noneToEmpty(value):
                return str(value) if value else ''

            fld1 = noneToEmpty(
                kwargs.get('fld1',
                           kwargs.get('username', kwargs.get('platform', ''))))
            fld2 = noneToEmpty(
                kwargs.get('fld2',
                           kwargs.get('srcip', kwargs.get('browser', ''))))
            fld3 = noneToEmpty(
                kwargs.get('fld3',
                           kwargs.get('dstip', kwargs.get('version', ''))))
            fld4 = noneToEmpty(kwargs.get('fld4', kwargs.get('uniqueid', '')))

            StatsEvents.objects.create(owner_type=owner_type,
                                       owner_id=owner_id,
                                       event_type=eventType,
                                       stamp=stamp,
                                       fld1=fld1,
                                       fld2=fld2,
                                       fld3=fld3,
                                       fld4=fld4)
            return True
        except Exception:
            logger.exception(
                'Exception handling event stats saving (maybe database is full?)'
            )
        return False
Esempio n. 3
0
 def getUnassignedMachine(self) -> typing.Optional[str]:
     # Search first unassigned machine
     try:
         now = getSqlDatetimeAsUnix()
         consideredFreeTime = now - config.GlobalConfig.SESSION_EXPIRE_TIME.getInt(
             force=False) * 3600
         for ip in self._ips:
             theIP = IPServiceBase.getIp(ip)
             theMAC = IPServiceBase.getMac(ip)
             locked = self.storage.getPickle(theIP)
             if not locked or locked < consideredFreeTime:
                 if self._port > 0 and self._skipTimeOnFailure > 0 and self.cache.get(
                         'port{}'.format(theIP)):
                     continue  # The check failed not so long ago, skip it...
                 self.storage.putPickle(theIP, now)
                 # Is WOL enabled?
                 wolENABLED = bool(self.parent().wolURL(theIP, theMAC))
                 # Now, check if it is available on port, if required...
                 if self._port > 0 and not wolENABLED:  # If configured WOL, check is a nonsense
                     if (connection.testServer(
                             theIP, self._port, timeOut=0.5) is False):
                         # Log into logs of provider, so it can be "shown" on services logs
                         self.parent().doLog(
                             log.WARN,
                             'Host {} not accesible on port {}'.format(
                                 theIP, self._port),
                         )
                         logger.warning(
                             'Static Machine check on %s:%s failed. Will be ignored for %s minutes.',
                             theIP,
                             self._port,
                             self._skipTimeOnFailure,
                         )
                         self.storage.remove(
                             theIP)  # Return Machine to pool
                         if self._skipTimeOnFailure > 0:
                             self.cache.put(
                                 'port{}'.format(theIP),
                                 '1',
                                 validity=self._skipTimeOnFailure * 60,
                             )
                         continue
                 if theMAC:
                     return theIP + ';' + theMAC
                 return theIP
         return None
     except Exception:
         logger.exception("Exception at getUnassignedMachine")
         return None
Esempio n. 4
0
    def get(self) -> typing.MutableMapping[str, typing.Any]:
        """
        Processes get requests, currently none
        """
        logger.debug(
            'Tunnel parameters for GET: %s (%s) from %s', self._args, self._params, self._request.ip
        )

        if (
            not isTrustedSource(self._request.ip)
            or len(self._args) != 2
            or len(self._args[0]) != 48
        ):
            # Invalid requests
            raise AccessDenied()

        # Try to get ticket from DB
        try:
            user, userService, host, port, extra = models.TicketStore.get_for_tunnel(
                self._args[0]
            )
            data = {}
            if self._args[1][:4] == 'stop':
                sent, recv = self._params['sent'], self._params['recv']
                # Ensures extra exists...
                extra = extra or {}
                now = models.getSqlDatetimeAsUnix()
                totalTime = now - extra.get('b', now-1)               
                msg = f'User {user.name} stopped tunnel {extra.get("t", "")[:8]}... to {host}:{port}: u:{sent}/d:{recv}/t:{totalTime}.'
                log.doLog(user.manager, log.INFO, msg)
                log.doLog(userService, log.INFO, msg)
            else:
                if net.ipToLong(self._args[1][:32]) == 0:
                    raise Exception('Invalid from IP')
                events.addEvent(
                    userService.deployed_service,
                    events.ET_TUNNEL_ACCESS,
                    username=user.pretty_name,
                    srcip=self._args[1],
                    dstip=host,
                    uniqueid=userService.unique_id,
                )
                msg = f'User {user.name} started tunnel {self._args[0][:8]}... to {host}:{port} from {self._args[1]}.'
                log.doLog(user.manager, log.INFO, msg)
                log.doLog(userService, log.INFO, msg)
                # Generate new, notify only, ticket
                rstr = managers.cryptoManager().randomString(length=8)
                notifyTicket = models.TicketStore.create_for_tunnel(
                    userService=userService,
                    port=port,
                    host=host,
                    extra={'t': self._args[0], 'b': models.getSqlDatetimeAsUnix()},
                    validity=MAX_SESSION_LENGTH)
                data = {
                    'host': host,
                    'port': port,
                    'notify': notifyTicket
                }

            return data
        except Exception as e:
            logger.info('Ticket ignored: %s', e)
            raise AccessDenied()