Fix zeroconf

This commit is contained in:
kokarare1212 2021-09-14 19:23:10 +09:00
parent dac25540b2
commit c2bfa04c35
No known key found for this signature in database
GPG Key ID: 9FB32C7C7D874F7A
2 changed files with 33 additions and 18 deletions

View File

@ -27,7 +27,6 @@ import os
import random
import requests
import sched
import signal
import socket
import struct
import threading
@ -616,8 +615,6 @@ class Session(Closeable, MessageListener, SubListener):
__user_attributes = {}
def __init__(self, inner: Inner, address: str) -> None:
signal.signal(signal.SIGINT, lambda _1, _2: self.close())
signal.signal(signal.SIGTERM, lambda _1, _2: self.close())
self.__client = Session.create_client(inner.conf)
self.connection = Session.ConnectionHolder.create(address, None)
self.__inner = inner
@ -1108,9 +1105,12 @@ class Session(Closeable, MessageListener, SubListener):
sha1 = SHA1.new()
sha1.update(device_id.encode())
secret = sha1.digest()
base_key = PBKDF2(secret.decode(), username.encode(), 20, 0x100)
aes = AES.new(base_key, AES.MODE_ECB)
decrypted_blob = aes.decrypt(encrypted_blob)
base_key = PBKDF2(secret, username.encode(), 20, 0x100, hmac_hash_module=SHA1)
sha1 = SHA1.new()
sha1.update(base_key)
key = sha1.digest() + b"\x00\x00\x00\x14"
aes = AES.new(key, AES.MODE_ECB)
decrypted_blob = bytearray(aes.decrypt(encrypted_blob))
l = len(decrypted_blob)
for i in range(0, l - 0x10):
decrypted_blob[l - i - 1] ^= decrypted_blob[l - i - 0x11]
@ -1125,8 +1125,9 @@ class Session(Closeable, MessageListener, SubListener):
raise IOError(
TypeError(
"Unknown AuthenticationType: {}".format(type_int)))
le = self.read_blob_int(blob)
auth_data = blob.read(le)
blob.read(1)
l = self.read_blob_int(blob)
auth_data = blob.read(l)
return Authentication.LoginCredentials(
auth_data=auth_data,
typ=type_,

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from Cryptodome.Cipher import AES
from Cryptodome.Hash import HMAC, SHA1
from Cryptodome.Util import Counter
from librespot import util, Version
from librespot.core import Session
from librespot.crypto import DiffieHellman
@ -52,7 +53,7 @@ class ZeroconfServer(Closeable):
__min_port = 1024
__runner: HttpRunner
__service_info: zeroconf.ServiceInfo
__session: typing.Union[Session, None]
__session: typing.Union[Session, None] = None
__session_listeners = []
__zeroconf: zeroconf.Zeroconf
@ -143,7 +144,7 @@ class ZeroconfServer(Closeable):
__socket.send(self.__eol)
__socket.send(self.__eol)
return
aes = AES.new(encryption_key[:16], AES.MODE_CTR, iv)
aes = AES.new(encryption_key[:16], AES.MODE_CTR, counter=Counter.new(128, initial_value=int.from_bytes(iv, "big")))
decrypted = aes.decrypt(encrypted)
with self.__connection_lock:
self.__connecting_username = username
@ -171,7 +172,7 @@ class ZeroconfServer(Closeable):
def handle_get_info(self, __socket: socket.socket,
http_version: str) -> None:
info = copy.deepcopy(self.__default_get_info_fields)
info["device_id"] = self.__inner.device_id
info["deviceID"] = self.__inner.device_id
info["remoteName"] = self.__inner.device_name
info["publicKey"] = base64.b64encode(
self.__keys.public_key_bytes()).decode()
@ -179,7 +180,14 @@ class ZeroconfServer(Closeable):
with self.__connection_lock:
info[
"activeUser"] = self.__connecting_username if self.__connecting_username is not None else self.__session.username(
) if self.has_valid_session() else ""
) if self.has_valid_session() else ""
__socket.send(http_version.encode())
__socket.send(b" 200 OK")
__socket.send(self.__eol)
__socket.send(b"Content-Type: application/json")
__socket.send(self.__eol)
__socket.send(self.__eol)
__socket.send(json.dumps(info).encode())
def has_valid_session(self) -> bool:
valid = self.__session and self.__session.is_valid()
@ -188,10 +196,10 @@ class ZeroconfServer(Closeable):
return valid
def parse_path(self, path: str) -> dict[str, str]:
url = "http://host" + path
url = "https://host" + path
parsed = {}
map = urllib.parse.parse_qs(urllib.parse.urlparse(url).query)
for key, values in map.items():
params = urllib.parse.parse_qs(urllib.parse.urlparse(url).query)
for key, values in params.items():
for value in values:
parsed[key] = value
return parsed
@ -207,6 +215,7 @@ class ZeroconfServer(Closeable):
self.__socket.bind((".".join(["0"] * 4), port))
self.__socket.listen(5)
self.__zeroconf_server = zeroconf_server
logging.info("Zeroconf HTTP server started successfully on port {}!".format(port))
def close(self) -> None:
pass
@ -223,7 +232,7 @@ class ZeroconfServer(Closeable):
def __handle(self, __socket: socket.socket) -> None:
request = io.BytesIO(__socket.recv(1024 * 1024))
request_line = request.readline().split(b" ")
request_line = request.readline().strip().split(b" ")
if len(request_line) != 3:
logging.warning(
"Unexpected request line: {}".format(request_line))
@ -232,7 +241,7 @@ class ZeroconfServer(Closeable):
http_version = request_line[2].decode()
headers = {}
while True:
header = request.readline()
header = request.readline().strip()
if not header:
break
split = header.split(b":")
@ -271,6 +280,11 @@ class ZeroconfServer(Closeable):
if action == "addUser":
if params is None:
raise RuntimeError
self.__zeroconf_server.handle_add_user(__socket, params, http_version)
elif action == "getInfo":
self.__zeroconf_server.handle_get_info(__socket, http_version)
else:
logging.warning("Unknown action: {}".format(action))
class Inner:
conf: typing.Final[Session.Configuration]
@ -285,6 +299,6 @@ class ZeroconfServer(Closeable):
self.conf = conf
self.device_name = device_name
self.device_id = util.random_hex_string(
40).lower() if device_id else device_id
40).lower() if not device_id else device_id
self.device_type = device_type
self.preferred_locale = preferred_locale