Beispiel #1
0
    def __init__(self, transport, user=None, password=None,
                 cur_player_id=None, debug=False):

        self.transport = transport
        self._debug = debug
        self.user = user
        self.password = password
        if user and password:
            self.log_in()
            print_d("Authenticated with %s!" % self)
        self.players = {}
        self.refresh_status()
        players = list(self.players.values())
        if not players:
            raise SqueezeboxException("Uh-oh. No players found.")
        if not cur_player_id:
            self.cur_player_id = players[0].id
        elif cur_player_id not in self.players:
            print_w("Couldn't find player {id} (found: {all}). "
                    "Check your DEFAULT_PLAYER config.",
                    id=cur_player_id, all=", ".join(list(self.players.keys())))
            self.cur_player_id = players[0].id
        else:
            self.cur_player_id = cur_player_id
        print_d("Current player is now: {}", self.players[self.cur_player_id])
        self.__genres = []
        self.__playlists = []
        self.__favorites = []
Beispiel #2
0
    def _request(self, lines, raw=False, wait=True) -> List[str]:
        """
        Send multiple pipelined requests to the server, if connected,
        and return their responses,
        assuming order is maintained (which seems safe).
        """
        if not (lines and len(lines)):
            return []
        lines = [l.rstrip() for l in lines]

        match = RESPONSE_CMD_REGEX.match(lines[0])
        # If we can't match, then take the first two words (for debugging)
        first_word = (match.group(2)
                      if match else ' '.join(lines[0].split()[:2]))
        if not (self.transport.is_connected or first_word == 'login'):
            try:
                print_w("Transport wasn't connected - trying to restart")
                self.transport.start()
            except Exception:
                raise SqueezeboxException(
                    "Can't do '{cmd}', {transport} is not connected".format(
                        cmd=first_word, transport=self.transport))

        if self._debug:
            print_d("<<<< " + "\n..<< ".join(lines))
        request = "\n".join(lines)
        raw_response = self.transport.communicate(request, wait=wait)
        if not wait:
            return []
        if not raw_response:
            raise SqueezeboxException(
                "No further response from %s. Login problem?" % self)
        raw_response = raw_response.rstrip("\n")
        response = raw_response if raw else self._unquote(raw_response)
        if self._debug:
            print_d(">>>> " + "\n..>> ".join(response.splitlines()))

        def start_point(text):
            if first_word == 'login':
                return 6
            delta = -1 if text.endswith('?') else 1
            return len(self._unquote(text) if raw else text) + delta

        resp_lines = response.splitlines()
        if len(lines) != len(resp_lines):
            print_d("Got mismatched response: {lines} vs {resp_lines}",
                    lines=lines,
                    resp_lines=resp_lines)
            raise Error("Transport response problem: got %d lines, not %d" %
                        (len(resp_lines), len(lines)))
        return [
            resp_line[start_point(line):]
            for line, resp_line in zip(lines, resp_lines)
        ]
Beispiel #3
0
def lambda_handler(event, context):
    """ Route the incoming request based on type (LaunchRequest, IntentRequest,
    etc.) The JSON body of the request is provided in the event parameter.
    """
    sqa = SqueezeAlexa(app_id=APPLICATION_ID)
    try:
        return sqa.handle(event, context)
    except Exception as e:
        if not settings.USE_SPOKEN_ERRORS:
            raise e
        # Work with AWS stack-trace log magic
        print_w(format_exc().replace('\n', '\r'))
        error = str(e.msg if hasattr(e, "msg") else e)
        return speech_response(title=_("All went wrong"),
                               text=_("Oh dear: {type}. {message}").format(
                                   type=type(e).__name__, message=error))
Beispiel #4
0
 def communicate(self, data, wait=True):
     eof = False
     response = ''
     num_lines = data.count("\n")
     try:
         self._ssl_sock.sendall(data.encode('utf-8'))
         if not wait:
             return None
         while not eof:
             response += self._ssl_sock.recv().decode('utf-8')
             eof = response.count("\n") == num_lines or not response
         return response
     except socket.error as e:
         print_d("Couldn't communicate with Squeezebox ({!r})", e)
         self.failures += 1
         if self.failures >= self._MAX_FAILURES:
             print_w("Too many Squeezebox failures. Disconnecting")
             self.is_connected = False
         return None
    def handle(self, event, context=None):
        """The main entry point for Alexa requests"""
        request = event['request']
        req_type = request['type']
        session = self._verified_app_session(event)

        if session and session['new']:
            self.on_session_started(request, session)

        if req_type == Request.LAUNCH:
            return self.on_launch(request, session)
        elif req_type == Request.INTENT:
            return self.on_intent(request, session)
        elif req_type == Request.SESSION_ENDED:
            return self.on_session_ended(request, session)
        elif req_type == Request.EXCEPTION:
            print_w("ERROR callback received (\"%s\"). Full event: %s"
                    % (request['error'].get('message', "?"), event))
        else:
            raise ValueError("Unknown request type %s" % req_type)
Beispiel #6
0
 def test_print_w(self):
     assert "Exception" in print_w("{!r}", Exception("bar"))
Beispiel #7
0
    def __init__(self,
                 hostname,
                 port=9090,
                 ca_file=None,
                 cert_file=None,
                 verify_hostname=False,
                 timeout=5):

        super().__init__()
        self.hostname = hostname
        self.port = port
        self.timeout = timeout
        self.failures = 0
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        self.__harden_context(context)
        try:
            if ca_file:
                context.load_verify_locations(ca_file)
            if cert_file:
                context.verify_mode = ssl.CERT_REQUIRED
                context.check_hostname = verify_hostname
                context.load_cert_chain(cert_file)
        except ssl.SSLError as e:
            raise Error(
                "Problem with Cert / CA (+key) files ({} / {}). "
                "Does it include the private key?".format(cert_file, ca_file),
                e)
        except IOError as e:
            if 'No such file or directory' in e.strerror:
                self._die("Can't find cert '{cert_file}' or CA '{ca_file}'. "
                          "Check CERT_FILE / CA_FILE_PATH in settings".format(
                              ca_file=ca_file, cert_file=cert_file))
            self._die(
                "could be mismatched certificate files, "
                "or wrong hostname in cert."
                "Check CERT_FILE and certs on server too.", e)

        sock = socket.socket()
        sock.settimeout(self.timeout)
        self._ssl_sock = context.wrap_socket(sock, server_hostname=hostname)
        print_d("Connecting to port {port} on {hostname}",
                port=port,
                hostname=hostname or '(localhost)')
        try:
            self._ssl_sock.connect((hostname, port))
        except socket.gaierror as e:
            if "Name or service not know" in e.strerror:
                self._die(
                    "unknown host ({}) - check SERVER_HOSTNAME".format(
                        hostname), e)
            self._die("Couldn't connect to %s with TLS" % (self, ), e)
        except IOError as e:
            err_str = e.strerror or str(e)
            if 'Connection refused' in err_str:
                self._die("nothing listening on {}. "
                          "Check settings, or (re)start server.".format(self))
            elif 'WRONG_VERSION_NUMBER' in err_str:
                self._die(
                    'probably not TLS on port {} - '
                    'wrong SERVER_PORT maybe?'.format(port), e)
            elif 'Connection reset by peer' in err_str:
                self._die("server killed the connection - handshake error? "
                          "Check the SSL tunnel logs")
            elif 'CERTIFICATE_VERIFY_FAILED' in err_str:
                self._die(
                    "Cert not trusted by / from server. "
                    "Is your CA correct? Is the cert expired? "
                    "Is the cert for the right hostname ({})?".format(
                        hostname), e)
            elif 'timed out' in err_str:
                msg = ("Couldn't connect to port {port} on {host} - "
                       "check the server setup and the firewall.").format(
                           host=self.hostname, port=self.port)
                self._die(msg)
            self._die("Connection problem ({}: {})".format(
                type(e).__name__, err_str))

        peer_cert = self._ssl_sock.getpeercert()
        if peer_cert is None:
            self._die("No certificate configured at {}".format(self))
        elif not peer_cert:
            print_w("Unvalidated server cert at {}", self)
        else:
            subject_data = peer_cert['subject']
            try:
                data = {k: v for d in subject_data for k, v in d}
            except Exception:
                data = subject_data
            print_d("Validated cert for {}", data)
        self.is_connected = True
Beispiel #8
0

def connect_cli():
    global telnet
    telnet = telnetlib.Telnet(host=MQTT_SETTINGS.internal_server_hostname,
                              port=LMS_SETTINGS.cli_port,
                              timeout=5)
    print_d("Connected to Squeezeserver CLI")
    return telnet


if __name__ == "__main__":
    try:
        telnet = connect_cli()
    except socket.timeout as e:
        print_w("Couldn't connect to Squeeze CLI using {} ({})", MQTT_SETTINGS,
                e)
        exit(3)
    else:
        client = CustomClient(MQTT_SETTINGS)
        client.on_connect = on_connect
        client.on_subscribe = on_subscribe
        client.on_message = on_message
        client.connect()

        # Continue the network loop
        client.loop_forever(retry_first_connection=True)

    finally:
        if telnet:
            telnet.close()
Beispiel #9
0
    def __init__(self,
                 hostname,
                 port=9090,
                 ca_file=None,
                 cert_file=None,
                 verify_hostname=False):

        self.hostname = hostname
        self.port = port
        self.failures = 0
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        self.__harden_context(context)
        try:
            if ca_file:
                context.load_verify_locations(ca_file)
            if cert_file:
                context.verify_mode = ssl.CERT_REQUIRED
                context.check_hostname = verify_hostname
                context.load_cert_chain(cert_file)
        except ssl.SSLError as e:
            raise Error(
                "Problem with Cert / CA (+key) files (%s / %s). "
                "Does it include the private key?" % (cert_file, ca_file), e)
        except IOError as e:
            if 'No such file or directory' in e.strerror:
                self._die("Can't find '%s'. "
                          "Check CERT_NAME / CERT_PATH in settings" % ca_file)
            self._die(
                "could be mismatched certificate files, "
                "or wrong hostname in cert."
                "Check CERT_FILE and certs on server too.", e)

        self._ssl_sock = context.wrap_socket(socket.socket(),
                                             server_hostname=hostname)
        try:
            self._ssl_sock.connect((hostname, port))
        except socket.gaierror as e:
            if "Name or service not know" in e.strerror:
                self._die(
                    "unknown host (%s) - check SERVER_HOSTNAME" % hostname, e)
            self._die("Couldn't connect to %s with TLS" % (self, ), e)
        except IOError as e:
            if 'Connection refused' in e.strerror:
                self._die("nothing listening on %s"
                          "Check settings, or (re)start server." % self)
            elif 'WRONG_VERSION_NUMBER' in e.strerror:
                self._die(
                    'probably not TLS on port %d - '
                    'wrong SERVER_PORT maybe?' % port, e)
            elif 'Connection reset by peer' in e.strerror:
                self._die("server killed the connection - handshake error? "
                          "Check the SSL tunnel logs")
            elif 'CERTIFICATE_VERIFY_FAILED' in e.strerror:
                self._die(
                    "Cert not trusted by / from server. "
                    "Is your CA correct? Is the cert expired? "
                    "Is the cert for the right hostname (%s)?" % hostname, e)
            self._die("Connection problem (%s)" % e.strerror)

        peer_cert = self._ssl_sock.getpeercert()
        if peer_cert is None:
            self._die("No certificate configured at %s" % self)
        elif not peer_cert:
            print_w("Unvalidated server cert at %s" % self)
        else:
            subject_data = peer_cert['subject']
            try:
                data = {k: v for d in subject_data for k, v in d}
            except Exception:
                data = subject_data
            print_d("Validated cert for %s" % (data, ))
        self.is_connected = True
Beispiel #10
0
    global telnet
    telnet = telnetlib.Telnet(host=MQTT_SETTINGS.internal_server_hostname,
                              port=LMS_SETTINGS.cli_port, timeout=5)
    print_d("Connected to Squeezeserver CLI")
    return telnet


if __name__ == "__main__":

    if not MQTT_SETTINGS.configured:
        print("MQTT transport not configured. Check your settings")
        exit(1)
    try:
        telnet = connect_cli()
    except socket.timeout as e:
        print_w("Couldn't connect to Squeeze CLI using {settings} ({err})",
                settings=MQTT_SETTINGS, err=e)
        exit(3)
    else:
        client = CustomClient(MQTT_SETTINGS)
        client.on_connect = on_connect
        client.on_subscribe = on_subscribe
        client.on_message = on_message
        client.connect()

        # Continue the network loop
        client.loop_forever(retry_first_connection=True)
    finally:
        if telnet:
            telnet.close()