Marco Ricci commited on 2024-12-13 14:52:17
              Zeige 2 geänderte Dateien mit 38 Einfügungen und 8 Löschungen.
            
While the configuration and interactive selection of an SSH key is properly guarded against (i.e., any exceptions are wrapped into proper command-line error messages), the calls to `vault.Vault.phrase_from_key` were not similarly guarded. This has now been fixed. The fix also uncovered an incorrectly specified mock function in the test suite, which has been repaired as well.
| ... | ... | 
                      @@ -1703,6 +1703,36 @@ def derivepassphrase_vault( # noqa: C901,PLR0912,PLR0913,PLR0914,PLR0915  | 
                  
| 1703 | 1703 | 
                        logger.error(msg, *args, stacklevel=stacklevel, **kwargs)  | 
                    
| 1704 | 1704 | 
                        ctx.exit(1)  | 
                    
| 1705 | 1705 | 
                         | 
                    
| 1706 | 
                        + def key_to_phrase(key_: str | bytes | bytearray, /) -> bytes | bytearray:  | 
                    |
| 1707 | 
                        + key = base64.standard_b64decode(key_)  | 
                    |
| 1708 | 
                        + try:  | 
                    |
| 1709 | 
                        + with ssh_agent.SSHAgentClient.ensure_agent_subcontext() as client:  | 
                    |
| 1710 | 
                        + try:  | 
                    |
| 1711 | 
                        + return vault.Vault.phrase_from_key(key, conn=client)  | 
                    |
| 1712 | 
                        + except ssh_agent.SSHAgentFailedError as e:  | 
                    |
| 1713 | 
                        + try:  | 
                    |
| 1714 | 
                        + keylist = client.list_keys()  | 
                    |
| 1715 | 
                        + except ssh_agent.SSHAgentFailedError:  | 
                    |
| 1716 | 
                        + pass  | 
                    |
| 1717 | 
                        + except Exception as e2: # noqa: BLE001  | 
                    |
| 1718 | 
                        + e.__context__ = e2  | 
                    |
| 1719 | 
                        + else:  | 
                    |
| 1720 | 
                        + if not any(k == key for k, _ in keylist):  | 
                    |
| 1721 | 
                        + err(  | 
                    |
| 1722 | 
                        + 'The requested SSH key is not loaded '  | 
                    |
| 1723 | 
                        + 'into the agent.'  | 
                    |
| 1724 | 
                        + )  | 
                    |
| 1725 | 
                        + err(e)  | 
                    |
| 1726 | 
                        + except KeyError:  | 
                    |
| 1727 | 
                        +            err('Cannot find running SSH agent; check SSH_AUTH_SOCK')
                       | 
                    |
| 1728 | 
                        + except NotImplementedError:  | 
                    |
| 1729 | 
                        + err(  | 
                    |
| 1730 | 
                        + 'Cannot connect to SSH agent because '  | 
                    |
| 1731 | 
                        + 'this Python version does not support UNIX domain sockets'  | 
                    |
| 1732 | 
                        + )  | 
                    |
| 1733 | 
                        + except OSError as e:  | 
                    |
| 1734 | 
                        +            err('Cannot connect to SSH agent: %s', e.strerror)
                       | 
                    |
| 1735 | 
                        +  | 
                    |
| 1706 | 1736 | 
                        def get_config() -> _types.VaultConfig:  | 
                    
| 1707 | 1737 | 
                        try:  | 
                    
| 1708 | 1738 | 
                        return _load_config()  | 
                    
| ... | ... | 
                      @@ -2047,13 +2077,6 @@ def derivepassphrase_vault( # noqa: C901,PLR0912,PLR0913,PLR0914,PLR0915  | 
                  
| 2047 | 2077 | 
                        if k in service_keys and v is not None  | 
                    
| 2048 | 2078 | 
                        }  | 
                    
| 2049 | 2079 | 
                         | 
                    
| 2050 | 
                        - def key_to_phrase(  | 
                    |
| 2051 | 
                        - key: str | bytes | bytearray,  | 
                    |
| 2052 | 
                        - ) -> bytes | bytearray:  | 
                    |
| 2053 | 
                        - return vault.Vault.phrase_from_key(  | 
                    |
| 2054 | 
                        - base64.standard_b64decode(key)  | 
                    |
| 2055 | 
                        - )  | 
                    |
| 2056 | 
                        -  | 
                    |
| 2057 | 2080 | 
                        if use_phrase:  | 
                    
| 2058 | 2081 | 
                        form = cast(  | 
                    
| 2059 | 2082 | 
                        Literal['NFC', 'NFD', 'NFKC', 'NFKD'],  | 
                    
| ... | ... | 
                      @@ -30,6 +30,7 @@ from derivepassphrase import _types, cli, ssh_agent, vault  | 
                  
| 30 | 30 | 
                        __all__ = ()  | 
                    
| 31 | 31 | 
                         | 
                    
| 32 | 32 | 
                        if TYPE_CHECKING:  | 
                    
| 33 | 
                        + import socket  | 
                    |
| 33 | 34 | 
                        from collections.abc import Callable, Iterator, Mapping, Sequence  | 
                    
| 34 | 35 | 
                         | 
                    
| 35 | 36 | 
                        import click.testing  | 
                    
| ... | ... | 
                      @@ -1412,7 +1413,13 @@ def suitable_ssh_keys(conn: Any) -> Iterator[_types.KeyCommentPair]:  | 
                  
| 1412 | 1413 | 
                        ]  | 
                    
| 1413 | 1414 | 
                         | 
                    
| 1414 | 1415 | 
                         | 
                    
| 1415 | 
                        -def phrase_from_key(key: bytes) -> bytes:  | 
                    |
| 1416 | 
                        +def phrase_from_key(  | 
                    |
| 1417 | 
                        + key: bytes,  | 
                    |
| 1418 | 
                        + /,  | 
                    |
| 1419 | 
                        + *,  | 
                    |
| 1420 | 
                        + conn: ssh_agent.SSHAgentClient | socket.socket | None = None,  | 
                    |
| 1421 | 
                        +) -> bytes:  | 
                    |
| 1422 | 
                        + del conn  | 
                    |
| 1416 | 1423 | 
                        if key == DUMMY_KEY1: # pragma: no branch  | 
                    
| 1417 | 1424 | 
                        return DUMMY_PHRASE_FROM_KEY1  | 
                    
| 1418 | 1425 | 
                        raise KeyError(key) # pragma: no cover  | 
                    
| 1419 | 1426 |