Beispiel #1
0
 def remove_active_host(self, task, access_path):
     self.acl(task)
     try:
         del self.server_dispatcher.active_count_dict[access_path]
     except KeyError:
         log.warn('access_path "%s" not found in active_count_dict' %
                  access_path)
     return True
Beispiel #2
0
Datei: irc.py Projekt: epsy/hqbot
    def joined(self, channel):
        if channel != self.ircchannel:
            log.warn("Odd, I shouldn't be joining " + channel)
            return

        self.run_cronjobs()

        log.msg("Joined channel")
Beispiel #3
0
Datei: irc.py Projekt: epsy/hqbot
    def joined(self, channel):
        if channel != self.ircchannel:
            log.warn("Odd, I shouldn't be joining " + channel)
            return

        self.run_cronjobs()

        log.msg("Joined channel")
Beispiel #4
0
def validate_team_name(name):
    if len(name) > 9:
        log.warn(
            "Team name's length exceeds 9 character limit. More info: https://git.io/fN2cI"
        )
        # TODO: Once issue #345 is sorted out, we can do a proper validation
        # for now we just warn
        # return False
    return True
	def fetch_feed(self, url):
		feed_type = self.feeds[url].type

		err = None
		try: data = yield self.client.request(url)
		except HTTPClientError as err:
			log.warn('Failed to fetch feed ({}): {}'.format(url, err))
			data = None
		finally: self.schedule_fetch(url, fast=bool(err)) # do faster re-fetch on errors

		if data is None: defer.returnValue(None) # cache hit, not modified, error
		data, headers = data

		if feed_type == 'feed':
			import feedparser
			parser = feedparser.parse(data, response_headers=headers)
			feed, posts = parser.feed, parser.entries
		elif feed_type == 'reddit-json':
			from lya import AttrDict # mandatory dep anyway
			data = json.loads(data)['data']
			posts = list(AttrDict(post['data']) for post in data.pop('children'))
			feed = AttrDict(data)
		else:
			raise ValueError('Unrecognized feed type: {!r}'.format(self.feeds[url].type))

		count = 0
		for post in reversed(posts):
			if feed_type == 'reddit-json':
				# Some reddit-api-specific encoding hacks
				try: title = unescape(post['title'])
				except KeyError: pass
				else: post.title = title

			post_obj = FeedEntryInfo(feed, post, self.conf)

			post_id = list(
				force_bytes(post_obj.get_by_path(attr))
				for attr in self.feeds[url].deduplication )
			if not self.filter_db.add(url, post_id): continue

			first_err = None
			for template in self.feeds[url].template:
				try: event = template.format(**post_obj._asdict())
				except (KeyError, IndexError, AttributeError) as err:
					if not first_err:
						first_err = ValueError(
							'Failed to format template {!r} (data: {}): {}'\
							.format(template, post_obj, err) )
					continue
				event = RelayedEvent(event)
				event.data = post_obj # for any further tricky filtering
				reactor.callLater(0, self.interface.dispatch, event, source=self)
				break
			else: raise first_err # all templates failed

			count += 1
			if self.feeds[url].process_max and count >= self.feeds[url].process_max: break
Beispiel #6
0
    def extReceived(self, dataType, data):
        """
        Called when we receive extended data (usually standard error)

        @param dataType: data type code
        @type dataType: integer
        """
        message = "The command %s returned stderr data (%d) from the device: %s" % (self.command, dataType, data)
        log.warn("%s channel %s %s", self.targetIp, self.conn.localChannelID, message)
        self.stderr += data
Beispiel #7
0
 def retry(self, request, server):
     # servers don't start up *quite* right away, so we give it a
     # moment to be ready to accept connections
     sleep = self.config.get("sleep")
     wait_up_to = self.config.get("wait_up_to")
     for i in range(int(wait_up_to / sleep)):
         try:
             yield self.get_page(request, server)
             return
         except Exception, e:
             log.warn(e)
             yield wait_for(sleep)
	def handle_change(self, stuff, path, mask):
		mask_str = inotify.humanReadableMask(mask)
		log.noise('Event: {} ({})'.format(path, mask_str))

		## Filtering
		path_real = path.realpath()
		if not path_real.isfile():
			log.debug( 'Ignoring event for'
				' non-regular file: {} (realpath: {})'.format(path, path_real) )
			return
		dir_key = path_real.parent().realpath()
		if dir_key not in self.paths_watch:
			log.warn( 'Ignoring event for file outside of watched'
				' set of paths: {} (realpath: {})'.format(path, path_real) )
			return
		for pat in self.paths_watch[dir_key]:
			if fnmatch(bytes(path.basename()), pat): break
		else:
			log.noise( 'Non-matched path in one of'
				' the watched dirs: {} (realpath: {})'.format(path, path_real) )
			return

		## Get last position
		if self.paths_pos.get(path_real) is not None:
			pos, size, data = self.paths_pos[path_real]
			if self.file_end_check(path_real, pos, size=size, data=data):
				log.debug(( 'Event (mask: {}) for unchanged'
					' path, ignoring: {}' ).format(mask_str, path))
				return
			if path_real.getsize() < pos:
				log.debug( 'Detected truncation'
					' of a path, rewinding: {}'.format(path) )
				pos = None
		else: pos = None

		## Actual processing
		line = self.paths_buff.setdefault(path_real, '')
		with path_real.open('rb') as src:
			if pos:
				src.seek(pos)
				pos = None
			while True:
				buff = src.readline()
				if not buff: # eof
					self.paths_pos[path_real] = self.file_end_mark(path_real, data=line)
				line += buff
				if line.endswith('\n'):
					log.noise('New line (source: {}): {!r}'.format(path, line))
					reactor.callLater(0, self.handle_line, line)
					line = self.paths_buff[path_real] = ''
				else:
					line, self.paths_buff[path_real] = None, line
					break
Beispiel #9
0
 def update_world(self):
     last_time = self.last_time
     current_time = reactor.seconds()
     if last_time is not None:
         dt = current_time - last_time
         if dt > 1.0:
             log.warn('high CPU usage detected - %s' % dt)
     self.last_time = current_time
     ServerProtocol.update_world(self)
     time_taken = reactor.seconds() - current_time
     if time_taken > 1.0:
         log.warn('World update iteration took %s, objects: %s' %
                  (time_taken, self.world.objects))
	def name_from_patch_link( self, link,
			_re_path=re.compile(r'\bpackages/[\w\-]+/(?P<name>[\w\-]+)/') ):
		names = set()
		try: page = yield getPage(force_bytes(link), timeout=120)
		except Exception as err:
			log.warn('Failed to download patch: {}'.format(err))
			defer.returnValue(None)
		page = it.imap(op.methodcaller('strip'), page.splitlines())
		for line in page:
			if re.search(r'^\s*(\S+\s+\|\s+\d+\s+[\-+]*\s*$|rename |diff --git |[\-+]{3} )', line):
				line = _re_path.search(line)
				if line: names.add(line.group('name'))
		defer.returnValue(names)
Beispiel #11
0
 def get_available_hosts(self, task):
     self.acl(task)
     records = {}
     for host_id, data in self.server_dispatcher.available_host_dict.items(
     ):
         records[data['access_path']] = (host_id, data)
     for access_path, data in self.server_dispatcher.active_count_dict.items(
     ):
         try:
             records[access_path][1]['count'] = data['count']
         except KeyError:
             log.warn('access_path ignored', access_path)
     return list(records.values())
Beispiel #12
0
 def login_failed(request):
     request.setResponseCode(403)
     user.did_login_failure()
     if user.authentication_failure_count < self.max_failure:
         # diffrent message to hind the failure point (developing)
         log.warn('login failured from ' + client_ip)
         request.write(b'Login failure, try again')
         request.finish()
     else:
         log.warn('login failures over ' + str(self.max_failure) +
                  ' times from ' + client_ip)
         request.write(b'Too many failure, good bye')
         request.finish()
Beispiel #13
0
    def receiveError( self, reasonCode, description ):
        """
        Called when a disconnect error message was received from the device.

        @param reasonCode: error code from SSH connection failure
        @type reasonCode: integer
        @param description: human-readable version of the error code
        @type description: string
        """
        message= 'SSH error from remote device (code %d): %s\n' % \
                 ( reasonCode, str( description ) )
        log.warn( message )
        transport.SSHClientTransport.receiveError(self, reasonCode, description )
Beispiel #14
0
    def remove_username(self, username):
        db = self.presentation_root_folder.db

        p_ids_to_remove = []
        try:
            p_ids = db.user_presentation_dict[username]
        except KeyError:
            pass
        else:
            p_ids_to_remove.extend(p_ids)
        # remove from sbs_name_dict
        try:
            del db.sbs_name_dict[username]
        except KeyError:
            pass

        # remove from binding_dict
        try:
            binding = db.binding_dict[username]
        except KeyError:
            pass
        else:
            if isinstance(binding, str):
                # username is binding to another username
                try:
                    all_bindings = db.binding_dict[binding]
                except KeyError:
                    pass
                else:
                    if username in all_bindings:
                        all_bindings.remove(username)
                        if len(all_bindings) == 0:
                            # remove this item
                            del db.binding_dict[binding]
                        else:
                            # update this item
                            db.binding_dict[binding] = all_bindings
            else:
                #username is been binded by other usernames
                del db.binding_dict[binding]
                for binder in binding:
                    try:
                        binded = db.binding_dict[binder]
                    except KeyError:
                        log.warn('binding db inconsistent type #1')
                    else:
                        if binded == username:
                            del db.binding_dict[binder]
                        else:
                            log.warn('binding db inconsistent type #2')
        return p_ids_to_remove
Beispiel #15
0
 def process_ack(self, uid_conversation, ack=1):
     if uid_conversation in self.factory.waiting_acks:
         log.debug('Processing ack for conversation %s' %
                   (uid_conversation, ))
         data = {'ack': ack, 'uid_conversation': uid_conversation}
         channel = self.factory.waiting_acks[uid_conversation]["channel"]
         channel.sendLine(self.serializer.dumps(data))
         del self.factory.waiting_acks[uid_conversation]
         if uid_conversation in self.factory.conversation_callbacks:
             self.factory.conversation_callbacks[uid_conversation].cancel()
             del self.factory.conversation_callbacks[uid_conversation]
     else:
         log.warn('Tried to process an ack that is not present %s' %
                  (uid_conversation, ))
Beispiel #16
0
 def announce(room_id):
     room_id_wo_R = room_id[1:]
     try:
         count = len(MessageBus.ws_listeners[room_id])
     except KeyError:
         log.warn('announce to unexisted room: %s' % room_id)
     else:
         self.broadcast_by_internal_node(
             room_id_wo_R, {
                 'topic': '_ANNOUNCE_',
                 'data': {
                     'type': 'JOIN',
                     'members_count': count
                 }
             })
Beispiel #17
0
 def _getKey(self):
     keyPath = os.path.expanduser(self.factory.keyPath)
     log.msg("Expanded SSH key path from KeyPath {0} to {1}".format(self.factory.keyPath, keyPath))
     key = None
     if os.path.exists(keyPath):
         try:
             key = Key.fromFile(keyPath)
         except IOError, ex:
             message = "Unable to read the SSH key file because %s" % (str(ex))
             log.warn(message)
             device = "localhost"  # Fallback
             try:
                 device = socket.getfqdn()
             except:
                 pass
Beispiel #18
0
def check_scripts(scripts):
    '''
    Checks if scripts were included multiple times.
    '''
    seen = set()
    dups = []
    for script in scripts:
        if script in seen:
            dups.append(script)
        else:
            seen.add(script)
    if dups:
        log.warn("Scripts included multiple times: {}".format(dups))
        return False
    return True
Beispiel #19
0
 def openFailed(self, reason):
     """
     Called when the open fails.
     """
     from twisted.conch.error import ConchError
     if isinstance(reason, ConchError):
         args = (reason.data, reason.value)
     else:
         args = (reason.code, reason.desc)
     message = 'CommandChannel Open of %s failed (error code %d): %s' % (
             (self.command,) + args)
     log.warn("%s %s", self.targetIp, message)
     channel.SSHChannel.openFailed(self, reason)
     if self.conn is not None:
         self.conn.factory.clientFinished()
Beispiel #20
0
 def data_received(self, peer: Peer, packet: Packet) -> None:
     ip = peer.address.host
     current_time = reactor.seconds()
     try:
         ServerProtocol.data_received(self, peer, packet)
     except (NoDataLeft, ValueError):
         import traceback
         traceback.print_exc()
         log.info(
             'IP %s was hardbanned for invalid data or possibly DDoS.' % ip)
         self.hard_bans.add(ip)
         return
     dt = reactor.seconds() - current_time
     if dt > 1.0:
         log.warn('processing {!r} from {} took {}'.format(
             packet.data, ip, dt))
Beispiel #21
0
	def handle_line(self, line, repo_lock=defer.DeferredLock()):
		try:
			line = line.decode('utf-8', 'ignore').strip()
			match = re.search(r'(^|\s+)!pq\s+(?P<link>\S+)(\s+::\S+|$)', line)
			if not match:
				log.noise('Non-patchbot line, ignoring: {}'.format(line.encode('utf-8', 'ignore')))
				defer.returnValue(None)
			link = match.group('link').encode('ascii')
			if not re.search('https?://', link, re.IGNORECASE):
				log.warn('Incorrect non-http link, skipping: {}'.format(link))
				defer.returnValue(None)
		except UnicodeError as err:
			log.warn('Failed to recode line ({!r}): {}'.format(line, err))
			defer.returnValue(None)

		## Grab the patch
		dst_base = '{}.patch'.format(sha1(link).hexdigest())
		dst_path = self.dst_path.child(dst_base)
		if dst_path.exists():
			log.debug( 'Patch already exists'
				' (file: {}, link: {}), skipping'.format(dst_path, link) )
			defer.returnValue(None)
		# Not via tmpfile to prevent multiple downloads of the same paste
		try: yield downloadPage(link, dst_path.open('wb'), timeout=120)
		except:
			if dst_path.exists(): dst_path.remove()
			raise

		## Commit into repo and push
		yield repo_lock.acquire()
		try:
			for cmd, check in [
					(['add', dst_base], True),
					(['commit', '-m', 'New patch: {}'.format(link)], False),
					(['push'], True) ]:
				out, err, code = yield getProcessOutputAndValue(
					'/usr/bin/git', cmd, path=self.dst_path.path )
				if check and code:
					log.error('\n'.join([
						'Failed to commit/push new patch into repo',
						'Command: {}'.format(cmd), 'Exit code:  {}'.format(code),
						'Stdout:\n  {}'.format('\n  '.join(out.splitlines())),
						'Stderr:\n  {}'.format('\n  '.join(err.splitlines())) ]))
					break
			else: log.debug('Successfully pushed paste: {}'.format(link))
		finally: repo_lock.release()
Beispiel #22
0
    def remove_p_id(self, p_id):
        db = self.presentation_root_folder.db

        try:
            del db.presentation_atime_dict[p_id]
        except KeyError:
            pass

        try:
            p_state = db.presentation_states_dict[p_id]
        except KeyError:
            pass
        else:
            acl_token = p_state['acl_token']
            for token in acl_token.values():
                #if (token is None) or (token == ''): continue
                if not token: continue
                log.debug('removing token %s' % token)
                try:
                    # 此數值 db.token_presentation_dict[token] 應該是p_id
                    # 此處暫時不做一致性檢查
                    del db.token_presentation_dict[token]
                except KeyError:
                    # 應該存在才合理
                    log.warn('token_presentation_dict db inconsistent type #1')

                try:
                    db.delegate_host_dict[token]
                except KeyError:
                    pass

            username = p_state['owner']
            try:
                p_ids = db.user_presentation_dict[username]
            except KeyError:
                pass
            else:
                if p_id in p_ids:
                    p_ids.remove(p_id)
                    # 雖然 p_ids 可能是空的,但還是留著此紀錄,以保留 username之間的binding關係
                    db.user_presentation_dict[username] = p_ids
                else:
                    log.warn('user_presentation_dict db inconsistent type #2')

            del db.presentation_states_dict[p_id]
Beispiel #23
0
    def send(self, message, delay=False):
        '''Attempt to send a message with optional delay'''
        if not self.active:
            log.warn("Attempted to send a message to inactive %s: %s", self.TYPE, self.uid)
            return

        if message is None or message == "":
            log.warn("Attempted to send an empty messsage")
            return

        if type(message) == type(u""):
            message = message.encode('utf-8')

        time = 0.2
        if delay:
            time = 2.5
        log.msg("Sending <{0}>: {1}".format(self.uid, message))
        reactor.callLater(time, self._send, unicode(message, 'utf-8'))
Beispiel #24
0
    def get_external_ip(self, ip_getter: str) -> Iterator[Deferred]:
        log.info(
            'Retrieving external IP from {!r} to generate server identifier.'.
            format(ip_getter))
        try:
            ip = yield self.getPage(ip_getter)
            ip = IPv4Address(ip.strip())
        except AddressValueError as e:
            log.warn('External IP getter service returned invalid data.\n'
                     'Please check the "ip_getter" setting in your config.')
            return
        except Exception as e:
            log.warn("Getting external IP failed: {reason}", reason=e)
            return

        self.ip = ip
        self.identifier = make_server_identifier(ip, self.port)
        log.info('Server public ip address: {}:{}'.format(ip, self.port))
        log.info('Public aos identifier: {}'.format(self.identifier))
Beispiel #25
0
 def _getKey(self):
     keyPath = os.path.expanduser(self.factory.keyPath)
     log.msg('Expanded SSH key path from zKeyPath %s to %s' % (
             self.factory.keyPath, keyPath))
     key = None
     if os.path.exists(keyPath):
         try:
             data = ''.join(open(keyPath).readlines()).strip()
             key = Key.fromString(data)
             #key = Key.fromString(data,
             #               passphrase=self.factory.password)
         except IOError, ex:
             message = "Unable to read the SSH key file because %s" % (
                          str(ex))
             log.warn(message)
             device = 'localhost' # Fallback
             try:
                 device = socket.getfqdn()
             except:
                 pass
Beispiel #26
0
    def send(self, message, delay=False):
        '''Attempt to send a message with optional delay'''
        if not self.active:
            log.warn("Attempted to send a message to inactive %s: %s", self.TYPE, self.uid)
            return

        if message is None or message == "":
            log.warn("Attempted to send an empty messsage")
            return

        if type(message) == type(u""):
            message = message.encode('utf-8')

        time = 0.2
        if type(delay) is int:
            time = delay
        elif delay is True:
            time = 1.5 + random.random() * 2

        log.msg("Sending <{0}>: {1}".format(self.uid, message))
        reactor.callLater(time, self._send, unicode(message, 'utf-8'))
	def update_sid_db( self,
			_ref_line=re.compile( r'^\s*config\s+reference:'
				r'\s+(?P<ref_type>\w+)\s+(?P<ref_url>\S+)\s*$' ) ):
		log.debug('Updating sid-msg.map hash: {}'.format(self.conf.paths.sid_db))

		# Process ref types config (ref_type:url mapping)
		ref_map = dict()
		if self.conf.paths.refs:
			with open(self.conf.paths.refs) as src:
				for line in src:
					match = _ref_line.search(line)
					if not match: continue
					ref_map[match.group('ref_type').lower()] = match.group('ref_url')

		# (Re)build sid:urls db
		try: os.unlink(self.conf.paths.sid_db)
		except OSError: pass
		with open(self.conf.paths.sid_src) as src,\
				closing(anydbm.open(self.conf.paths.sid_db, 'c')) as dst:
			for line in src:
				line = line.strip()
				if not line or line[0] == '#': continue
				try:
					sid, msg, refs = op.itemgetter(0, 1, slice(2, None))\
						(map(op.methodcaller('strip'), line.split(' || ')))
				except IndexError:
					log.warn('Unrecognized sid-msg.map line format, ignoring: {!r}'.format(line))
				if not sid.isdigit():
					log.warn('Detected non-numeric sid: {!r} (line: {!r})'.format(sid, line))
				ref_urls = list()
				for ref in refs:
					if ref_map:
						try:
							ref_type, ref = it.imap(op.methodcaller('strip'), ref.split(',', 1))
							ref = ''.join([ref_map[ref_type.lower()], ref])
						except ValueError:
							log.warn('Unrecognized ref format, ignoring: {!r} (line: {!r})'.format(ref, line))
							continue
						except KeyError:
							log.warn( 'Unrecognized ref type:'
								' {!r} (ref: {!r}, line: {!r})'.format(ref_type, ref, line) )
							ref = ','.join([ref_type, ref])
					ref_urls.append(ref)
				if ref_urls:
					dst[sid] = ' '.join(sorted(set(dst.get(sid, '').split()).union(ref_urls)))
Beispiel #28
0
 def no_ack_timeout(cls, factory, channel, uid_conversation, uid_to):
     if uid_conversation in factory.waiting_acks:
         log.warn('No ack for %s to %s' % (uid_conversation, uid_to))
         data = {'ack': 0, 'error': 'time out, unable to contact'}
         channel.sendLine(factory.serializer.dumps(data))
         clients = factory.waiting_acks[uid_conversation]["clients"]
         for client in clients:
             log.warn('UIDS for this client: %s' % client.uids)
             if len(client.uids) == 1:
                 try:
                     log.warn(
                         'Aborting connection because the only uid it had is not responding %s'
                         % (uid_conversation, ))
                     client.transport.abortConnection()
                 except Exception, e:
                     log.failure("{message!r}", message=e.message)
             client.uids.remove(uid_to)
         del factory.clients[uid_to]
Beispiel #29
0
            clients = factory.waiting_acks[uid_conversation]["clients"]
            for client in clients:
                log.warn('UIDS for this client: %s' % client.uids)
                if len(client.uids) == 1:
                    try:
                        log.warn(
                            'Aborting connection because the only uid it had is not responding %s'
                            % (uid_conversation, ))
                        client.transport.abortConnection()
                    except Exception, e:
                        log.failure("{message!r}", message=e.message)
                client.uids.remove(uid_to)
            del factory.clients[uid_to]
        else:
            log.warn(
                'Callback called but should have not been for conversation %s'
                % (uid_conversation, ))

    def process_ack(self, uid_conversation, ack=1):
        if uid_conversation in self.factory.waiting_acks:
            log.debug('Processing ack for conversation %s' %
                      (uid_conversation, ))
            data = {'ack': ack, 'uid_conversation': uid_conversation}
            channel = self.factory.waiting_acks[uid_conversation]["channel"]
            channel.sendLine(self.serializer.dumps(data))
            del self.factory.waiting_acks[uid_conversation]
            if uid_conversation in self.factory.conversation_callbacks:
                self.factory.conversation_callbacks[uid_conversation].cancel()
                del self.factory.conversation_callbacks[uid_conversation]
        else:
            log.warn('Tried to process an ack that is not present %s' %
Beispiel #30
0
    def __init__(self, interface: bytes, config_dict: Dict[str, Any]) -> None:
        # logfile path relative to config dir if not abs path
        log_filename = logfile.get()
        if log_filename.strip():  # catches empty filename
            if not os.path.isabs(log_filename):
                log_filename = os.path.join(config.config_dir, log_filename)
            ensure_dir_exists(log_filename)
            if logging_rotate_daily.get():
                logging_file = DailyLogFile(log_filename, '.')
            else:
                logging_file = open(log_filename, 'a')
            globalLogPublisher.addObserver(textFileLogObserver(logging_file))
            globalLogPublisher.addObserver(textFileLogObserver(sys.stderr))
            log.info('piqueserver started on %s' % time.strftime('%c'))

        self.config = config_dict
        if random_rotation:
            self.map_rotator_type = random_choice_cycle
        else:
            self.map_rotator_type = itertools.cycle  # pylint: disable=redefined-variable-type
        self.default_time_limit = default_time_limit.get()
        self.default_cap_limit = cap_limit.get()
        self.advance_on_win = int(advance_on_win.get())
        self.win_count = itertools.count(1)
        self.bans = NetworkDict()

        # attempt to load a saved bans list
        try:
            with open(os.path.join(config.config_dir, bans_file.get()),
                      'r') as f:
                self.bans.read_list(json.load(f))
            log.debug("loaded {count} bans", count=len(self.bans))
        except FileNotFoundError:
            log.debug("skip loading bans: file unavailable",
                      count=len(self.bans))
        except IOError as e:
            log.error('Could not read bans.txt: {}'.format(e))
        except ValueError as e:
            log.error('Could not parse bans.txt: {}'.format(e))

        self.hard_bans = set()  # possible DDoS'ers are added here
        self.player_memory = deque(maxlen=100)
        if len(self.name) > MAX_SERVER_NAME_SIZE:
            log.warn('(server name too long; it will be truncated to "%s")' %
                     (self.name[:MAX_SERVER_NAME_SIZE]))
        self.respawn_time = respawn_time_option.get()
        self.respawn_waves = respawn_waves.get()
        if game_mode.get() == 'ctf':
            self.game_mode = CTF_MODE
        elif game_mode.get() == 'tc':
            self.game_mode = TC_MODE
        elif self.game_mode is None:
            raise NotImplementedError('invalid game mode: %s' % game_mode)
        self.game_mode_name = game_mode.get().split('.')[-1]
        self.team1_name = team1_name.get()
        self.team2_name = team2_name.get()
        self.team1_color = tuple(team1_color.get())
        self.team2_color = tuple(team2_color.get())
        self.friendly_fire = friendly_fire.get()
        self.friendly_fire_on_grief = friendly_fire_on_grief.get()
        self.friendly_fire_time = grief_friendly_fire_time.get()
        self.spade_teamkills_on_grief = spade_teamkills_on_grief.get()
        self.fall_damage = fall_damage.get()
        self.teamswitch_interval = teamswitch_interval.get()
        self.teamswitch_allowed = teamswitch_allowed.get()
        self.max_players = max_players.get()
        self.melee_damage = melee_damage.get()
        self.max_connections_per_ip = max_connections_per_ip.get()
        self.passwords = passwords.get()
        self.server_prefix = server_prefix.get()
        self.time_announcements = time_announcements.get()
        self.balanced_teams = balanced_teams.get()
        self.login_retries = login_retries.get()

        # voting configuration
        self.default_ban_time = default_ban_duration.get()

        self.speedhack_detect = speedhack_detect.get()
        if user_blocks_only.get():
            self.user_blocks = set()
        self.set_god_build = set_god_build.get()
        self.debug_log = debug_log_enabled.get()
        if self.debug_log:
            # TODO: make this configurable
            pyspades.debug.open_debug_log(
                os.path.join(config.config_dir, 'debug.log'))
        if ssh_enabled.get():
            from piqueserver.ssh import RemoteConsole
            self.remote_console = RemoteConsole(self)
        irc = irc_options.get()
        if irc.get('enabled', False):
            from piqueserver.irc import IRCRelay
            self.irc_relay = IRCRelay(self, irc)
        if status_server_enabled.get():
            from piqueserver.statusserver import StatusServerFactory
            self.status_server = StatusServerFactory(self)
        if ban_publish.get():
            from piqueserver.banpublish import PublishServer
            self.ban_publish = PublishServer(self, ban_publish_port.get())
        if bans_urls.get():
            from piqueserver import bansubscribe
            self.ban_manager = bansubscribe.BanManager(self)
        self.start_time = reactor.seconds()
        self.end_calls = []
        # TODO: why is this here?
        create_console(self)

        for user_type, func_names in rights.get().items():
            for func_name in func_names:
                commands.add_rights(user_type, func_name)

        port = self.port = port_option.get()
        ServerProtocol.__init__(self, port, interface)
        self.host.intercept = self.receive_callback
        try:
            self.set_map_rotation(self.config['rotation'])
        except MapNotFound as e:
            log.critical('Invalid map in map rotation (%s), exiting.' % e.map)
            raise SystemExit

        self.update_format()
        self.tip_frequency = tip_frequency.get()
        if self.tips is not None and self.tip_frequency > 0:
            reactor.callLater(self.tip_frequency * 60, self.send_tip)

        self.master = register_master_option.get()
        self.set_master()

        self.http_agent = web_client.Agent(reactor)

        ip_getter = ip_getter_option.get()
        if ip_getter:
            self.get_external_ip(ip_getter)
Beispiel #31
0
 def connection_lost(self):
     log.warn("Connection lost")
     self.subscriber = None
     reactor.callLater(self.secs_to_wait, self.suscribe)
Beispiel #32
0
	def connectionLost(self, reason):
		log.warn( 'Detected inotify'
			' connectionLost event, reason: {}'.format(reason) )
		self.errback(reason)
Beispiel #33
0
	def handle_change(self, stuff, path, mask):
		mask_str = inotify.humanReadableMask(mask)
		log.noise('Event: {} ({})'.format(path, mask_str))

		## Filtering
		path_real = path.realpath()
		if not path_real.isfile():
			log.debug( 'Ignoring event for'
				' non-regular file: {} (realpath: {})'.format(path, path_real) )
			return
		dir_key = path_real.parent().realpath()
		if dir_key not in self.paths_watch:
			log.warn( 'Ignoring event for file outside of watched'
				' set of paths: {} (realpath: {})'.format(path, path_real) )
			return
		for pat in self.paths_watch[dir_key]:
			if fnmatch(bytes(path.basename()), pat): break
		else:
			log.noise( 'Non-matched path in one of'
				' the watched dirs: {} (realpath: {})'.format(path, path_real) )
			return
		for pat in self.exclude:
			if pat.search(path.path):
				log.noise( 'Matched path by exclude-pattern'
					' ({}): {} (realpath: {})'.format(pat, path, path_real) )
				return

		## Get last position
		pos = self.paths_pos.get(path_real)
		if not pos: # try restoring it from xattr
			try: pos = pickle.loads(xattr(path_real.path)[self.conf.xattr_name])
			except KeyError:
				log.debug('Failed to restore last log position from xattr for path: {}'.format(path))
			else:
				log.noise(
					'Restored pos from xattr ({}) for path {}: {!r}'\
					.format(self.conf.xattr_name, path_real, pos) )
		if pos:
			pos, size, data_hash = pos
			if self.file_end_check(path_real, pos, size=size, data_hash=data_hash):
				log.noise(( 'Event (mask: {}) for unchanged'
					' path, ignoring: {}' ).format(mask_str, path))
				return
			if path_real.getsize() < pos:
				log.debug( 'Detected truncation'
					' of a path, rewinding: {}'.format(path) )
				pos = None

		## Actual processing
		buff_agg = self.paths_buff.setdefault(path_real, '')
		with path_real.open() as src:
			if pos:
				src.seek(pos)
				pos = None
			while True:
				pos = src.tell()
				try: buff, pos = self.read(src), src.tell()
				except StopIteration:
					buff_agg = ''
					src.seek(pos) # revert back to starting position
					buff, pos = self.read(src), src.tell()
				if not buff: # eof, try to mark the position
					if not buff_agg: # clean eof at the end of the chunk - mark it
						pos = self.file_end_mark(path_real, pos=pos, data=buff_agg)
						self.paths_pos[path_real] = pos
						xattr(path_real.path)[self.conf.xattr_name] = pickle.dumps(pos)
						log.noise( 'Updated xattr ({}) for path {} to: {!r}'\
							.format(self.conf.xattr_name, path_real, pos) )
					break
				buff_agg = self.paths_buff[path_real] = self.process(buff_agg + buff, path)
Beispiel #34
0
def run() -> None:
    """
    runs the server
    """

    # apply scripts

    protocol_class = FeatureProtocol
    connection_class = FeatureConnection

    script_objects = []
    script_names = scripts_option.get()
    script_dir = os.path.join(config.config_dir, 'scripts/')

    for script in script_names[:]:
        try:
            # this finds and loads scripts directly from the script dir
            # no need for messing with sys.path
            f, filename, desc = imp.find_module(script, [script_dir])
            module = imp.load_module('piqueserver_script_namespace_' + script,
                                     f, filename, desc)
            script_objects.append(module)
        except ImportError as e:
            # warning: this also catches import errors from inside the script
            # module it tried to load
            try:
                module = importlib.import_module(script)
                script_objects.append(module)
            except ImportError as e:
                log.error("(script '{}' not found: {!r})".format(script, e))
                script_names.remove(script)

    for script in script_objects:
        protocol_class, connection_class = script.apply_script(
            protocol_class, connection_class, config.get_dict())

    # apply the game_mode script
    if game_mode.get() not in ('ctf', 'tc'):
        # must be a script with this game mode
        module = None
        try:
            game_mode_dir = os.path.join(config.config_dir, 'game_modes/')
            f, filename, desc = imp.find_module(game_mode.get(),
                                                [game_mode_dir])
            module = imp.load_module(
                'piqueserver_gamemode_namespace_' + game_mode.get(), f,
                filename, desc)
        except ImportError as e:
            try:
                module = importlib.import_module(game_mode.get())
            except ImportError as e:
                log.error("(game_mode '%s' not found: %r)" %
                          (game_mode.get(), e))

        if module:
            protocol_class, connection_class = module.apply_script(
                protocol_class, connection_class, config.get_dict())

    protocol_class.connection_class = connection_class

    interface = network_interface.get().encode('utf-8')

    # instantiate the protocol class once. It will set timers and hooks to keep
    # itself running once we start the reactor
    protocol_class(interface, config.get_dict())

    log.debug('Checking for unregistered config items...')
    unused = config.check_unused()
    if unused:
        log.warn('The following config items are not used:')
        pprint(unused)

    log.info('Started server...')

    profile = logging_profile_option.get()
    if profile:
        import cProfile
        cProfile.runctx('reactor.run()', None, globals())
    else:
        reactor.run()
Beispiel #35
0
	def dispatch(self, msg, source, user=None, direct=False):
		if not isinstance(msg, list): msg = [msg]

		channels = dict()
		if direct and user:
			# Direct reply
			log.noise('Dispatching msg from {!r} directly to user: {!r}'.format(source, user))
			channels[user] = msg

		else:
			try: route = self.routes[self.relays.get(source) or source]
			except KeyError:
				log.noise('No routes to dispatch message to, dropping: {!r}'.format(msg))
				return
			# Pull msg through all the pipelines and build dst channels / msgs buffer
			for dst, pipe in route:
				msg_copy = list(msg)
				for name in pipe:
					relay = self.relays[name]
					results = yield defer.DeferredList(list(
						defer.maybeDeferred(relay.dispatch, part) for part in msg_copy ))
					msg_copy = set()
					for chk, result in results:
						if not chk:
							log.error(
								'Detected pipeline failure (src: {}, dst: {}, pipe: {}, relay: {}, msg: {}): {}'\
								.format(source, dst, pipe, name, msg_copy, result) )
						elif isinstance(result, list): msg_copy.update(result)
						else: msg_copy.add(result)
					msg_copy = msg_copy.difference({None})
					if not msg_copy: break
				else:
					if dst in self.relays:
						extra_kwz = dict()
						if isinstance(dst, types.StringTypes): dst = self.relays[dst]
						if user and 'source' in inspect.getargspec(dst.dispatch).args:
							extra_kwz['source'] = user
						log.noise('Delivering msgs to dst relay: {}, extra_kwz: {}'.format(dst, extra_kwz))
						yield defer.DeferredList(list(
							defer.maybeDeferred(dst.dispatch, msg_copy, **extra_kwz)
							for msg_copy in msg_copy ))
					else:
						channels.setdefault(self.channels[dst].name, set()).update(msg_copy)

		# Check whether anything can be delivered to channels at all
		if not self.proto:
			log.warn( 'Failed to deliver message(s)'
				' ({!r}) to the following channels: {}'.format(msg, channels) )
			defer.returnValue(None)

		# Encode and deliver
		for channel, msg in channels.viewitems():
			for msg in msg:
				if not isinstance(msg, types.StringTypes):
					log.warn('Dropping non-string message: {!r}'.format(msg))
					continue
				if isinstance(msg, unicode):
					try: msg = msg.encode(self.irc_enc)
					except UnicodeEncodeError as err:
						log.warn('Failed to encode ({}) unicode msg ({!r}): {}'.format(self.irc_enc, msg, err))
						msg = msg.encode(self.irc_enc, 'replace')
				max_len = min( self.max_line_length,
					self.proto._safeMaximumLineLength('PRIVMSG {} :'.format(channel)) - 2 )
				first_line = True
				for line in irc.split(msg, length=max_len):
					if not first_line: line = '  {}'.format(line)
					if not self.dry_run: self.proto.msg(channel, line)
					else: log.info('IRC line (channel: {}): {}'.format(channel, line))
					first_line = False
Beispiel #36
0
 def sent_err(failure):
     self.transport.lock.release()
     log.warn('send file error:%s' % failure.getErrorMessage())
Beispiel #37
0
    def render_GET(self, request):
        """
        handle requests like
        /login/username<space>password
        /login/username/password
        /login?username=&password=

        /logout
        /logout?next=URL
        """
        paths = unquote(request.path.decode('utf-8')).split('/')

        command = paths[1]

        # only /login, /logout allowed
        assert command in ('login', 'logout')

        user = self.get_user(request)
        client_ip = request.transport.getPeer().host

        if self.allow_cross_origin:
            request.setHeader('Access-Control-Allow-Origin', '*')
            request.setHeader('Access-Control-Allow-Credentials', '*')

        #print 'command = ',command,'user.authenticated',user.authenticated
        __main__.statetree.emit('UserRequestLogin', user.username)

        session = request.getSession()

        if command == 'login' and user.authenticated:
            session.touch()
            log.info('User ' + user.username + ' login from ' + client_ip)
            return self.make_response({
                'retcode':
                0,
                'stdout':
                self.success_login_metadata(user)
            })

        elif command == 'logout':
            if user.authenticated:
                log.debug('user ' + user.username + ' logout from ' +
                          client_ip)
                user.logout()
            next_url = request.args.get(b'next', [None])[0]
            if next_url:
                #http://127.0.0.1:2880/logo?next=http://127.0.0.1:2880/app/whiteboard.html
                assert not next_url.startswith(b'/logout')
                request.setResponseCode(302)
                request.setHeader('Location', next_url.decode())
                return b'bye'
            else:
                return self.make_response({'retcode': 0, 'stdout': 'Good-bye'})

        def login_failed(request):
            request.setResponseCode(403)
            user.did_login_failure()
            if user.authentication_failure_count < self.max_failure:
                # diffrent message to hind the failure point (developing)
                log.warn('login failured from ' + client_ip)
                request.write(b'Login failure, try again')
                request.finish()
            else:
                log.warn('login failures over ' + str(self.max_failure) +
                         ' times from ' + client_ip)
                request.write(b'Too many failure, good bye')
                request.finish()

        # do login starts
        login_type = request.args.get(b'type', [None])[0]
        if login_type:
            # A customized mechanism to do login
            # 1. Register a type-handler in server side
            try:
                ok = self.type_handler[login_type.decode()](user, request)
            except Exception as e:
                log.warn('login failure, type=%s, e=%s' % (login_type, e))
                login_failed(request)
                return NOT_DONE_YET
        else:
            # re-compose command line, accepts following formats
            # /login/username<space>password
            # /login/username/password
            # /login?username=&password=
            message = ''
            username = ''
            password = ''
            if len(paths[2:]):
                line = 'login ' + (' '.join(paths[2:]))
                commands = ObjshCommand.decodeChunks([line])
                # only 1 command supported per request
                command = commands[0]

                #log.msg('line = '+line+'; args=',command.args)
                username = str(
                    command.args[0]) if len(command.args) > 0 else ''
                password = str(
                    command.args[1]) if len(command.args) > 1 else ''

            elif request.args.get(b'username'):
                username = request.args[b'username'][0].decode('utf-8').strip()
                password = request.args.get(b'password',
                                            [b''])[0].decode('utf-8').strip()

            else:
                message = 'access denied!'

            message = 'unauthorized %s' % time.time()

            if not (username and password):
                login_failed(request)
                return NOT_DONE_YET

            # user.login is an inline callback, so the following line is blocking code
            try:
                log.debug('login with', [username, password])
                ok = user.login(username, password)
            except:
                traceback.print_exc()

        if isinstance(ok, defer.Deferred):

            def next(ret, request):
                if user.authenticated:
                    # succeed to login
                    log.info('A user ' + user.username + ' login from ' +
                             client_ip)

                    # enforce to su to another user
                    #if os.environ['USER']=='root':  raise NotImplementedError()
                    self.send_object(
                        request, {
                            'retcode': 0,
                            'stdout': self.success_login_metadata(user)
                        })
                    request.finish()
                else:
                    login_failed(request)

            def err(failure, request):
                errmsg = failure.getErrorMessage()
                if errmsg: log.msg('auth error:%s' % errmsg)
                login_failed(request)

            ok.addCallback(next, request)
            ok.addErrback(err, request)
            return NOT_DONE_YET
        elif user.authenticated:
            log.info('USER ' + user.username + ' login from ' + client_ip)
            return self.make_response({
                'retcode':
                0,
                'stdout':
                self.success_login_metadata(user)
            })
        else:
            login_failed(request)
            return NOT_DONE_YET
	def dispatch(self, msg):
		if not msg.strip(): return

		## Event lines are cached until EOE msg is encountered
		match = self._re_base.search(msg)
		if not match:
			log.warn('Failed to match audit event spec: {!r}'.format(msg))
			return

		node, ev_id, ev_type, msg = (match.group(k) for k in ['node', 'ev_id', 'type', 'msg'])
		ev_key = node, ev_id

		if ev_key not in self._ev_cache:
			self._ev_cache[ev_key] = defaultdict(list)
			self._ev_cache[ev_key].update(ts=time.time(), node=node, ev_id=ev_id)
			self._ev_cache_gc()
		ev = self._ev_cache[ev_key]

		if ev_type != 'EOE': # cache event data
			ev[ev_type].append(msg)
			return
		del self._ev_cache[ev_key]

		## Get "key" value for event, if present
		ev_key = None
		try: syscall, = ev['SYSCALL'] # currently handled events always have it
		except ValueError: pass
		else:
			try: ev_key = self.get_msg_val(syscall, 'key', ur'"(?P<val>[^"]+)"')
			except KeyError as err:
				log.noise('Failed to get ev_key from syscall: {}'.format(err))
		if not ev_key:
			log.noise('Unhandled event: {!r}'.format(ev))
			return

		## Processing

		if ev_key in self.conf.events.watches.ev_keys:
			# Extract all necessary attributes
			ev_vals = dict(node=ev['node'], ev_id=ev['ev_id'], key=ev_key)
			for k in it.imap(''.join, it.product(['', 'e', 's', 'fs'], ['uid', 'gid'])):
				ev_vals[k] = self.get_msg_val(syscall, k)
			for k in 'comm', 'exe':
				ev_vals[k] = self.get_msg_val(syscall, k, ur'"(?P<val>[^"]+)"')
			ev_vals['tty'] = self.get_msg_val(syscall, 'tty', '(?P<val>\S+)')
			paths = ev_vals['paths'] = list()
			for msg in ev['PATH']:
				path = self.get_msg_val(msg, 'name', ur'(?P<val>"[^"]+"|\(null\)|[0-9A-F]+)')
				paths.append(dict( path=path,
					inode=self.get_msg_val(msg, 'inode', fallback='nil'),
					dev=self.get_msg_val(msg, 'dev', '(?P<val>[a-f\d]{2}:[a-f\d]{2})', fallback='nil') ))

			# Formatting
			err, tpl = None, force_unicode(self.conf.events.watches.template_path)
			ev_vals['paths'] = list()
			for val in paths:
				try: ev_vals['paths'].append(tpl.format(**val))
				except self._lookup_error as err: break
			if not err:
				ev_vals['paths'] = ', '.join(ev_vals['paths'])
				tpl, val = force_unicode(self.conf.events.watches.template), ev_vals
				try: event = tpl.format(**val)
				except self._lookup_error as err: pass
				event = RelayedEvent(event)
				event.data = ev_vals
				return event
			raise ValueError( 'Failed to format template {!r} (data: {}): {}'.format(tpl, val, err))