Exemple #1
0
    def process_handshake(self, line):
        deny = None

        try:
            hs = json.loads(line.decode('ascii'))
        except ValueError as e:
            deny = 'Badly formatted handshake: ' + str(e)
        else:
            try:
                if hs['version'] != 2 and hs['version'] != 3:
                    raise ValueError('Unsupported version in handshake')

                user = str(hs['user'])

                peer_compression_methods = set(hs['compress'])
                self.compress = None
                for c, readmeth, writemeth in self._compression_methods:
                    if c in peer_compression_methods:
                        self.compress = c
                        self.handle_messages = readmeth
                        self.send = writemeth
                        break
                if self.compress is None:
                    raise ValueError('No mutually usable compression type')

                lat = float(hs['lat'])
                if lat < -90 or lat > 90:
                    raise ValueError('invalid latitude, should be -90 .. 90')

                lon = float(hs['lon'])
                if lon < -180 or lon > 360:
                    raise ValueError('invalid longitude, should be -180 .. 360')
                if lon > 180:
                    lon = lon - 180

                alt = float(hs['alt'])
                if alt < -1000 or alt > 10000:
                    raise ValueError('invalid altitude, should be -1000 .. 10000')

                clock_type = str(hs.get('clock_type', 'dump1090'))

                self.use_return_results = bool(hs.get('return_results', False))
                if self.use_return_results:
                    return_result_format = hs.get('return_result_format', 'old')
                    if return_result_format == 'old':
                        self.report_mlat_position = self.report_mlat_position_old
                    elif return_result_format == 'ecef':
                        self.report_mlat_position = self.report_mlat_position_ecef
                    else:
                        raise ValueError('invalid return_result_format, should be one of "old" or "ecef"')
                else:
                    self.report_mlat_position = self.report_mlat_position_discard

                self.use_udp = (self.udp_protocol is not None and hs.get('udp_transport', 0) == 2)

                conn_info = 'v{v} {clock_type} {cversion} {udp} {compress}'.format(
                    v=hs['version'],
                    cversion=hs.get("client_version", "unknown"),
                    udp="udp" if self.use_udp else "tcp",
                    clock_type=clock_type,
                    compress=self.compress)
                self.receiver = self.coordinator.new_receiver(connection=self,
                                                              uuid=user,
                                                              user=user,
                                                              auth=hs.get('auth'),
                                                              clock_type=clock_type,
                                                              position_llh=(lat, lon, alt),
                                                              privacy=bool(hs.get('privacy', False)),
                                                              connection_info=conn_info)

                # disabled until I get to the bottom of the odd timestamps
                if False and self.receiver.clock.epoch == 'gps_midnight':
                    self.process_mlat = self.process_mlat_gps
                else:
                    self.process_mlat = self.process_mlat_nongps

            except KeyError as e:
                deny = 'Missing field in handshake: ' + str(e)

            except ValueError as e:
                deny = 'Bad values in handshake: ' + str(e)

        if deny:
            self.logger.info('Handshake failed: %s', deny)
            self.write_raw(deny=[deny], reconnect_in=util.fuzzy(900))
            return False

        expanded_motd = """

        {motd}

        The multilateration server source code is available under
        the terms of the Affero GPL (v3 or later). You may obtain
        a copy of this server's source code at the following
        location: {agpl_url}
        """.format(agpl_url=config.AGPL_SERVER_CODE_URL,
                   motd=self.motd)

        response = {"compress": self.compress,
                    "reconnect_in": util.fuzzy(15),
                    "selective_traffic": True,
                    "heartbeat": True,
                    "return_results": self.use_return_results,
                    "rate_reports": True,
                    "motd": expanded_motd}

        if self.use_udp:
            self._udp_key = self.udp_protocol.add_client(sync_handler=self.process_sync,
                                                         mlat_handler=self.process_mlat)
            response['udp_transport'] = (self.udp_host,
                                         self.udp_port,
                                         self._udp_key)

        self.write_raw(**response)
        self.logger.info("Handshake successful ({user} {conn_info})'".format(
            user=user,
            conn_info=conn_info))
        self.logger = util.TaggingLogger(glogger, {'tag': '{user}'.format(user=user)})
        return True
    def process_handshake(self, line):
        deny = None

        try:
            hs = json.loads(line.decode('ascii'))
        except ValueError as e:
            deny = 'Badly formatted handshake: ' + str(e)
        else:
            try:
                self.coordinator.handshake_logger.debug(line.decode('ascii'))

                if hs['version'] != 2 and hs['version'] != 3:
                    raise ValueError('Unsupported version in handshake')

                user = str(hs['user'])

                # Newlines wreak havoc on log files, strip them
                user = re.sub("\n|\r", r'\\n', user)
                # replace bad characters with an underscore
                user = re.sub("[^A-Za-z0-9_.-]", r'_', user)
                if len(user) > 400:
                    user = user[:400]
                if len(user) < 5:
                    user = user + '_' + str(random.randrange(10000, 99999))
                # Make sure the user string is sane...
                good_user_regex = '^[A-Za-z0-9_.-]+$'
                user_ok = re.match(good_user_regex, user)
                if user_ok is None:
                    raise ValueError(
                        "Bad username '{user}'.  Please only use alphanum, '_', '-', or '.'"
                        .format(user=user))

                for i in range(5):
                    if user in self.coordinator.receivers:
                        user = user + '_' + str(random.randrange(10, 99))
                    else:
                        break

                peer_compression_methods = set(hs['compress'])
                self.compress = None
                for c, readmeth, writemeth in self._compression_methods:
                    if c in peer_compression_methods:
                        self.compress = c
                        self.handle_messages = readmeth
                        self.send = writemeth
                        break
                if self.compress is None:
                    raise ValueError('No mutually usable compression type')

                lat = float(hs['lat'])
                if lat < -90 or lat > 90:
                    raise ValueError('invalid latitude, should be -90 .. 90')

                lon = float(hs['lon'])
                if lon < -180 or lon > 360:
                    raise ValueError(
                        'invalid longitude, should be -180 .. 360')
                if lon > 180:
                    lon = lon - 180

                alt = float(hs['alt'])
                if alt < -1000 or alt > 10000:
                    raise ValueError(
                        'invalid altitude, should be -1000 .. 10000')

                clock_type = str(hs.get('clock_type', 'dump1090'))

                self.use_return_results = bool(hs.get('return_results', False))
                if self.use_return_results:
                    return_result_format = hs.get('return_result_format',
                                                  'old')
                    if return_result_format == 'old':
                        self.report_mlat_position = self.report_mlat_position_old
                    elif return_result_format == 'ecef':
                        self.report_mlat_position = self.report_mlat_position_ecef
                    else:
                        raise ValueError(
                            'invalid return_result_format, should be one of "old" or "ecef"'
                        )
                else:
                    self.report_mlat_position = self.report_mlat_position_discard

                self.use_udp = (self.udp_protocol is not None
                                and hs.get('udp_transport', 0) == 2)

                conn_info = 'v{v} {clock_type} {cversion} {udp} {compress}'.format(
                    v=hs['version'],
                    cversion=hs.get("client_version", "unknown"),
                    udp="udp" if self.use_udp else "tcp",
                    clock_type=clock_type,
                    compress=self.compress)
                self.receiver = self.coordinator.new_receiver(
                    connection=self,
                    uuid=user,
                    user=user,
                    auth=hs.get('auth'),
                    clock_type=clock_type,
                    position_llh=(lat, lon, alt),
                    privacy=bool(hs.get('privacy', False)),
                    connection_info=conn_info)

                # disabled until I get to the bottom of the odd timestamps
                if False and self.receiver.clock.epoch == 'gps_midnight':
                    self.process_mlat = self.process_mlat_gps
                else:
                    self.process_mlat = self.process_mlat_nongps

            except KeyError as e:
                deny = 'Missing field in handshake: ' + str(e)

            except ValueError as e:
                deny = 'Bad values in handshake: ' + str(e)

        if deny:
            self.logger.warning('Handshake failed: %s', deny)
            self.write_raw(deny=[deny], reconnect_in=util.fuzzy(900))
            return False

        expanded_motd = """

        {motd}

        The multilateration server source code is available under
        the terms of the Affero GPL (v3 or later). You may obtain
        a copy of this server's source code at the following
        location: {agpl_url}
        """.format(agpl_url=config.AGPL_SERVER_CODE_URL, motd=self.motd)

        response = {
            "compress": self.compress,
            "reconnect_in": util.fuzzy(15),
            "selective_traffic": True,
            "heartbeat": True,
            "return_results": self.use_return_results,
            "rate_reports": True,
            "motd": expanded_motd
        }

        if self.use_udp:
            self._udp_key = self.udp_protocol.add_client(
                sync_handler=self.process_sync, mlat_handler=self.process_mlat)
            response['udp_transport'] = (self.udp_host, self.udp_port,
                                         self._udp_key)

        self.write_raw(**response)
        strange = ''
        if clock_type != 'dump1090' and clock_type != 'radarcape_gps':
            strange = 'strange clock: '
        self.logger.warning(
            "{strange}Handshake successful ({user} {conn_info})'".format(
                strange=strange, user=user, conn_info=conn_info))
        self.logger = util.TaggingLogger(glogger,
                                         {'tag': '{user}'.format(user=user)})
        return True
Exemple #3
0
    def process_handshake(self, line):
        deny = None

        try:
            hs = json.loads(line.decode('ascii'))
        except ValueError as e:
            deny = 'Badly formatted handshake: ' + str(e)
        else:
            try:
                if hs['version'] != 2 and hs['version'] != 3:
                    raise ValueError('Unsupported version in handshake')

                user = str(hs['user'])

                peer_compression_methods = set(hs['compress'])
                self.compress = None
                for c, readmeth, writemeth in self._compression_methods:
                    if c in peer_compression_methods:
                        self.compress = c
                        self.handle_messages = readmeth
                        self.send = writemeth
                        break
                if self.compress is None:
                    raise ValueError('No mutually usable compression type')

                lat = float(hs['lat'])
                if lat < -90 or lat > 90:
                    raise ValueError('invalid latitude, should be -90 .. 90')

                lon = float(hs['lon'])
                if lon < -180 or lon > 360:
                    raise ValueError(
                        'invalid longitude, should be -180 .. 360')
                if lon > 180:
                    lon = lon - 180

                alt = float(hs['alt'])
                if alt < -1000 or alt > 10000:
                    raise ValueError(
                        'invalid altitude, should be -1000 .. 10000')

                clock_type = str(hs.get('clock_type', 'dump1090'))

                self.use_return_results = bool(hs.get('return_results', False))
                if self.use_return_results:
                    return_result_format = hs.get('return_result_format',
                                                  'old')
                    if return_result_format == 'old':
                        self.report_mlat_position = self.report_mlat_position_old
                    elif return_result_format == 'ecef':
                        self.report_mlat_position = self.report_mlat_position_ecef
                    else:
                        raise ValueError(
                            'invalid return_result_format, should be one of "old" or "ecef"'
                        )
                else:
                    self.report_mlat_position = self.report_mlat_position_discard

                self.use_udp = (self.udp_protocol is not None
                                and hs.get('udp_transport', 0) == 2)

                conn_info = 'v{v} {clock_type} {cversion} {udp} {compress}'.format(
                    v=hs['version'],
                    cversion=hs.get("client_version", "unknown"),
                    udp="udp" if self.use_udp else "tcp",
                    clock_type=clock_type,
                    compress=self.compress)
                self.receiver = self.coordinator.new_receiver(
                    connection=self,
                    uuid=user,
                    user=user,
                    auth=hs.get('auth'),
                    clock_type=clock_type,
                    position_llh=(lat, lon, alt),
                    privacy=bool(hs.get('privacy', False)),
                    connection_info=conn_info)

                # disabled until I get to the bottom of the odd timestamps
                if False and self.receiver.clock.epoch == 'gps_midnight':
                    self.process_mlat = self.process_mlat_gps
                else:
                    self.process_mlat = self.process_mlat_nongps

            except KeyError as e:
                deny = 'Missing field in handshake: ' + str(e)

            except ValueError as e:
                deny = 'Bad values in handshake: ' + str(e)

        if deny:
            self.logger.info('Handshake failed: %s', deny)
            self.write_raw(deny=[deny], reconnect_in=util.fuzzy(900))
            return False

        expanded_motd = """

        {motd}

        The multilateration server source code is available under
        the terms of the Affero GPL (v3 or later). You may obtain
        a copy of this server's source code at the following
        location: {agpl_url}
        """.format(agpl_url=config.AGPL_SERVER_CODE_URL, motd=self.motd)

        response = {
            "compress": self.compress,
            "reconnect_in": util.fuzzy(15),
            "selective_traffic": True,
            "heartbeat": True,
            "return_results": self.use_return_results,
            "rate_reports": True,
            "motd": expanded_motd
        }

        if self.use_udp:
            self._udp_key = self.udp_protocol.add_client(
                sync_handler=self.process_sync, mlat_handler=self.process_mlat)
            response['udp_transport'] = (self.udp_host, self.udp_port,
                                         self._udp_key)

        self.write_raw(**response)
        self.logger.info("Handshake successful ({user} {conn_info})'".format(
            user=user, conn_info=conn_info))
        self.logger = util.TaggingLogger(glogger,
                                         {'tag': '{user}'.format(user=user)})
        return True