diff options
Diffstat (limited to 'custom_components/patch_asyncssh/__init__.py')
-rw-r--r-- | custom_components/patch_asyncssh/__init__.py | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/custom_components/patch_asyncssh/__init__.py b/custom_components/patch_asyncssh/__init__.py new file mode 100644 index 0000000..cdcb095 --- /dev/null +++ b/custom_components/patch_asyncssh/__init__.py @@ -0,0 +1,49 @@ +# /config/custom_components/patch_asyncssh/__init__.py +from __future__ import annotations +import logging + +_LOGGER = logging.getLogger(__name__) + +async def async_setup(hass, config): + """Patch asyncssh at HA startup, then return True to finish setup.""" + try: + import asyncssh + + # Re-expose ReadHostKeysPolicy at top-level for libs that expect it + try: + from asyncssh.hostkeys import ReadHostKeysPolicy + asyncssh.ReadHostKeysPolicy = ReadHostKeysPolicy # type: ignore[attr-defined] + except Exception: + pass + + # Patch only once + if not getattr(asyncssh, "_ha_patched_connect", False): + _real_connect = asyncssh.connect + + def _patched_connect(*args, **kwargs): + # Expand allowed *server* host key algorithms to match Dropbear + algs = list( + kwargs.get("server_host_key_algs") + or kwargs.get("host_key_algs") + or [] + ) + wanted = ["ssh-ed25519", "ecdsa-sha2-nistp256", "rsa-sha2-256"] + for a in wanted: + if a not in algs: + algs.append(a) + kwargs["server_host_key_algs"] = algs or wanted + + return _real_connect(*args, **kwargs) + + asyncssh.connect = _patched_connect # type: ignore[assignment] + asyncssh._ha_patched_connect = True # type: ignore[attr-defined] + _LOGGER.info( + "patch_asyncssh: asyncssh.connect patched (added algs %s)", + ["ssh-ed25519", "ecdsa-sha2-nistp256", "rsa-sha2-256"], + ) + else: + _LOGGER.debug("patch_asyncssh: asyncssh.connect already patched") + except Exception: + _LOGGER.exception("patch_asyncssh: failed to patch asyncssh") + + return True |