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
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
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
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()