e8f3ec854c425cc36565a40adbf00d22a2febeec
Marco Ricci Change the author e-mail ad...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py            1) # SPDX-FileCopyrightText: 2024 Marco Ricci <software@the13thletter.info>
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py             2) #
src/ssh_agent_client/__init__.py             3) # SPDX-License-Identifier: MIT
src/ssh_agent_client/__init__.py             4) 
src/ssh_agent_client/__init__.py             5) """A bare-bones SSH agent client supporting signing and key listing."""
src/ssh_agent_client/__init__.py             6) 
src/ssh_agent_client/__init__.py             7) from __future__ import annotations
src/ssh_agent_client/__init__.py             8) 
src/ssh_agent_client/__init__.py             9) import collections
src/ssh_agent_client/__init__.py            10) import errno
src/ssh_agent_client/__init__.py            11) import os
src/ssh_agent_client/__init__.py            12) import socket
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            13) from typing import TYPE_CHECKING
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            14) 
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            15) from typing_extensions import Self
Marco Ricci Support Python 3.10 and PyP...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            16) 
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py  17) from derivepassphrase import _types
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            18) 
src/ssh_agent_client/__init__.py            19) if TYPE_CHECKING:
src/ssh_agent_client/__init__.py            20)     from collections.abc import Sequence
Marco Ricci Fix import from stdlib modu...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            21)     from types import TracebackType
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            22) 
src/ssh_agent_client/__init__.py            23) __all__ = ('SSHAgentClient',)
Marco Ricci Change the author e-mail ad...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py           24) __author__ = 'Marco Ricci <software@the13thletter.info>'
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            25) 
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            26) # In SSH bytestrings, the "length" of the byte string is stored as
src/ssh_agent_client/__init__.py            27) # a 4-byte/32-bit unsigned integer at the beginning.
src/ssh_agent_client/__init__.py            28) HEAD_LEN = 4
src/ssh_agent_client/__init__.py            29) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            30) _socket = socket
src/ssh_agent_client/__init__.py            31) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            32) 
Marco Ricci Introduce TrailingDataError...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py            33) class TrailingDataError(RuntimeError):
src/ssh_agent_client/__init__.py            34)     """The result contained trailing data."""
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            35) 
Marco Ricci Fix typing issues in mypy s...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            36)     def __init__(self) -> None:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            37)         super().__init__('Overlong response from SSH agent')
Marco Ricci Introduce TrailingDataError...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py            38) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            39) 
Marco Ricci Add a specific error class...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py           40) class SSHAgentFailedError(RuntimeError):
src/derivepassphrase/ssh_agent.py           41)     """The SSH agent failed to complete the requested operation."""
src/derivepassphrase/ssh_agent.py           42) 
src/derivepassphrase/ssh_agent.py           43)     def __str__(self) -> str:
src/derivepassphrase/ssh_agent.py           44)         match self.args:
src/derivepassphrase/ssh_agent.py           45)             case (_types.SSH_AGENT.FAILURE.value, b''):  # pragma: no branch
src/derivepassphrase/ssh_agent.py           46)                 return 'The SSH agent failed to complete the request'
src/derivepassphrase/ssh_agent.py           47)             case (_, _msg) if _msg:  # pragma: no cover
src/derivepassphrase/ssh_agent.py           48)                 code = self.args[0]
src/derivepassphrase/ssh_agent.py           49)                 msg = self.args[1].decode('utf-8', 'surrogateescape')
src/derivepassphrase/ssh_agent.py           50)                 return f'[Code {code:d}] {msg:s}'
src/derivepassphrase/ssh_agent.py           51)             case _:  # pragma: no cover
src/derivepassphrase/ssh_agent.py           52)                 return repr(self)
src/derivepassphrase/ssh_agent.py           53) 
src/derivepassphrase/ssh_agent.py           54)     def __repr__(self) -> str:  # pragma: no cover
src/derivepassphrase/ssh_agent.py           55)         return f'{self.__class__.__name__}{self.args!r}'
src/derivepassphrase/ssh_agent.py           56) 
src/derivepassphrase/ssh_agent.py           57) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            58) class SSHAgentClient:
src/ssh_agent_client/__init__.py            59)     """A bare-bones SSH agent client supporting signing and key listing.
src/ssh_agent_client/__init__.py            60) 
src/ssh_agent_client/__init__.py            61)     The main use case is requesting the agent sign some data, after
src/ssh_agent_client/__init__.py            62)     checking that the necessary key is already loaded.
src/ssh_agent_client/__init__.py            63) 
src/ssh_agent_client/__init__.py            64)     The main fleshed out methods are `list_keys` and `sign`, which
src/ssh_agent_client/__init__.py            65)     implement the `REQUEST_IDENTITIES` and `SIGN_REQUEST` requests.  If
src/ssh_agent_client/__init__.py            66)     you *really* wanted to, there is enough infrastructure in place to
src/ssh_agent_client/__init__.py            67)     issue other requests as defined in the protocol---it's merely the
src/ssh_agent_client/__init__.py            68)     wrapper functions and the protocol numbers table that are missing.
src/ssh_agent_client/__init__.py            69) 
src/ssh_agent_client/__init__.py            70)     """
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            71) 
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py            72)     _connection: socket.socket
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py            73) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            74)     def __init__(
src/ssh_agent_client/__init__.py            75)         self, /, *, socket: socket.socket | None = None, timeout: int = 125
src/ssh_agent_client/__init__.py            76)     ) -> None:
src/ssh_agent_client/__init__.py            77)         """Initialize the client.
src/ssh_agent_client/__init__.py            78) 
src/ssh_agent_client/__init__.py            79)         Args:
src/ssh_agent_client/__init__.py            80)             socket:
src/ssh_agent_client/__init__.py            81)                 An optional socket, connected to the SSH agent.  If not
src/ssh_agent_client/__init__.py            82)                 given, we query the `SSH_AUTH_SOCK` environment
src/ssh_agent_client/__init__.py            83)                 variable to auto-discover the correct socket address.
src/ssh_agent_client/__init__.py            84)             timeout:
src/ssh_agent_client/__init__.py            85)                 A connection timeout for the SSH agent.  Only used if
src/ssh_agent_client/__init__.py            86)                 the socket is not yet connected.  The default value
src/ssh_agent_client/__init__.py            87)                 gives ample time for agent connections forwarded via
src/ssh_agent_client/__init__.py            88)                 SSH on high-latency networks (e.g. Tor).
src/ssh_agent_client/__init__.py            89) 
Marco Ricci Distinguish errors when con...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py            90)         Raises:
src/ssh_agent_client/__init__.py            91)             KeyError:
src/ssh_agent_client/__init__.py            92)                 The `SSH_AUTH_SOCK` environment was not found.
src/ssh_agent_client/__init__.py            93)             OSError:
src/ssh_agent_client/__init__.py            94)                 There was an error setting up a socket connection to the
src/ssh_agent_client/__init__.py            95)                 agent.
src/ssh_agent_client/__init__.py            96) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py            97)         """
src/ssh_agent_client/__init__.py            98)         if socket is not None:
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py            99)             self._connection = socket
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           100)         else:
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           101)             self._connection = _socket.socket(family=_socket.AF_UNIX)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           102)         try:
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           103)             # Test whether the socket is connected.
src/ssh_agent_client/__init__.py           104)             self._connection.getpeername()
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           105)         except OSError as e:
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           106)             # This condition is hard to test purposefully, so exclude
src/ssh_agent_client/__init__.py           107)             # from coverage.
src/ssh_agent_client/__init__.py           108)             if e.errno != errno.ENOTCONN:  # pragma: no cover
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           109)                 raise
Marco Ricci Distinguish errors when con...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           110)             if 'SSH_AUTH_SOCK' not in os.environ:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           111)                 msg = 'SSH_AUTH_SOCK environment variable'
src/ssh_agent_client/__init__.py           112)                 raise KeyError(msg) from None
Marco Ricci Distinguish errors when con...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           113)             ssh_auth_sock = os.environ['SSH_AUTH_SOCK']
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           114)             self._connection.settimeout(timeout)
Marco Ricci Distinguish errors when con...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           115)             self._connection.connect(ssh_auth_sock)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           116) 
src/ssh_agent_client/__init__.py           117)     def __enter__(self) -> Self:
Marco Ricci Apply new ruff ruleset to c...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          118)         """Close socket connection upon context manager completion.
src/derivepassphrase/ssh_agent.py          119) 
src/derivepassphrase/ssh_agent.py          120)         Returns:
src/derivepassphrase/ssh_agent.py          121)             Self.
src/derivepassphrase/ssh_agent.py          122) 
src/derivepassphrase/ssh_agent.py          123)         """
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           124)         self._connection.__enter__()
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           125)         return self
src/ssh_agent_client/__init__.py           126) 
src/ssh_agent_client/__init__.py           127)     def __exit__(
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           128)         self,
src/ssh_agent_client/__init__.py           129)         exc_type: type[BaseException] | None,
src/ssh_agent_client/__init__.py           130)         exc_val: BaseException | None,
Marco Ricci Fix import from stdlib modu...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           131)         exc_tb: TracebackType | None,
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           132)     ) -> bool:
Marco Ricci Apply new ruff ruleset to c...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          133)         """Close socket connection upon context manager completion.
src/derivepassphrase/ssh_agent.py          134) 
src/derivepassphrase/ssh_agent.py          135)         Args:
src/derivepassphrase/ssh_agent.py          136)             exc_type: An optional exception type.
src/derivepassphrase/ssh_agent.py          137)             exc_val: An optional exception value.
src/derivepassphrase/ssh_agent.py          138)             exc_tb: An optional exception traceback.
src/derivepassphrase/ssh_agent.py          139) 
src/derivepassphrase/ssh_agent.py          140)         Returns:
src/derivepassphrase/ssh_agent.py          141)             True if the exception was handled, false if it should
src/derivepassphrase/ssh_agent.py          142)             propagate.
src/derivepassphrase/ssh_agent.py          143) 
src/derivepassphrase/ssh_agent.py          144)         """
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           145)         return bool(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           146)             self._connection.__exit__(exc_type, exc_val, exc_tb)  # type: ignore[func-returns-value]
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           147)         )
src/ssh_agent_client/__init__.py           148) 
src/ssh_agent_client/__init__.py           149)     @staticmethod
Marco Ricci Add unit tests, both new an...

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           150)     def uint32(num: int, /) -> bytes:
src/ssh_agent_client/__init__.py           151)         r"""Format the number as a `uint32`, as per the agent protocol.
src/ssh_agent_client/__init__.py           152) 
src/ssh_agent_client/__init__.py           153)         Args:
src/ssh_agent_client/__init__.py           154)             num: A number.
src/ssh_agent_client/__init__.py           155) 
src/ssh_agent_client/__init__.py           156)         Returns:
src/ssh_agent_client/__init__.py           157)             The number in SSH agent wire protocol format, i.e. as
src/ssh_agent_client/__init__.py           158)             a 32-bit big endian number.
src/ssh_agent_client/__init__.py           159) 
src/ssh_agent_client/__init__.py           160)         Raises:
src/ssh_agent_client/__init__.py           161)             OverflowError:
src/ssh_agent_client/__init__.py           162)                 As per [`int.to_bytes`][].
src/ssh_agent_client/__init__.py           163) 
src/ssh_agent_client/__init__.py           164)         Examples:
src/ssh_agent_client/__init__.py           165)             >>> SSHAgentClient.uint32(16777216)
src/ssh_agent_client/__init__.py           166)             b'\x01\x00\x00\x00'
src/ssh_agent_client/__init__.py           167) 
src/ssh_agent_client/__init__.py           168)         """
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           169)         return int.to_bytes(num, 4, 'big', signed=False)
src/ssh_agent_client/__init__.py           170) 
src/ssh_agent_client/__init__.py           171)     @classmethod
src/ssh_agent_client/__init__.py           172)     def string(cls, payload: bytes | bytearray, /) -> bytes | bytearray:
Marco Ricci Add unit tests, both new an...

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           173)         r"""Format the payload as an SSH string, as per the agent protocol.
src/ssh_agent_client/__init__.py           174) 
src/ssh_agent_client/__init__.py           175)         Args:
src/ssh_agent_client/__init__.py           176)             payload: A byte string.
src/ssh_agent_client/__init__.py           177) 
src/ssh_agent_client/__init__.py           178)         Returns:
src/ssh_agent_client/__init__.py           179)             The payload, framed in the SSH agent wire protocol format.
src/ssh_agent_client/__init__.py           180) 
src/ssh_agent_client/__init__.py           181)         Examples:
src/ssh_agent_client/__init__.py           182)             >>> bytes(SSHAgentClient.string(b'ssh-rsa'))
src/ssh_agent_client/__init__.py           183)             b'\x00\x00\x00\x07ssh-rsa'
src/ssh_agent_client/__init__.py           184) 
src/ssh_agent_client/__init__.py           185)         """
Marco Ricci Fix numerous argument type...

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           186)         try:
src/ssh_agent_client/__init__.py           187)             ret = bytearray()
src/ssh_agent_client/__init__.py           188)             ret.extend(cls.uint32(len(payload)))
src/ssh_agent_client/__init__.py           189)             ret.extend(payload)
src/ssh_agent_client/__init__.py           190)         except Exception as e:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           191)             msg = 'invalid payload type'
Marco Ricci Apply new ruff ruleset to c...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          192)             raise TypeError(msg) from e  # noqa: DOC501
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           193)         return ret
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           194) 
src/ssh_agent_client/__init__.py           195)     @classmethod
src/ssh_agent_client/__init__.py           196)     def unstring(cls, bytestring: bytes | bytearray, /) -> bytes | bytearray:
Marco Ricci Add unit tests, both new an...

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           197)         r"""Unpack an SSH string.
src/ssh_agent_client/__init__.py           198) 
src/ssh_agent_client/__init__.py           199)         Args:
src/ssh_agent_client/__init__.py           200)             bytestring: A framed byte string.
src/ssh_agent_client/__init__.py           201) 
src/ssh_agent_client/__init__.py           202)         Returns:
src/ssh_agent_client/__init__.py           203)             The unframed byte string, i.e., the payload.
src/ssh_agent_client/__init__.py           204) 
src/ssh_agent_client/__init__.py           205)         Raises:
src/ssh_agent_client/__init__.py           206)             ValueError:
Marco Ricci Add function for SSH framed...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           207)                 The byte string is not an SSH string.
Marco Ricci Add unit tests, both new an...

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           208) 
src/ssh_agent_client/__init__.py           209)         Examples:
src/ssh_agent_client/__init__.py           210)             >>> bytes(SSHAgentClient.unstring(b'\x00\x00\x00\x07ssh-rsa'))
src/ssh_agent_client/__init__.py           211)             b'ssh-rsa'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           212)             >>> bytes(
src/ssh_agent_client/__init__.py           213)             ...     SSHAgentClient.unstring(SSHAgentClient.string(b'ssh-ed25519'))
src/ssh_agent_client/__init__.py           214)             ... )
Marco Ricci Add unit tests, both new an...

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           215)             b'ssh-ed25519'
src/ssh_agent_client/__init__.py           216) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           217)         """  # noqa: E501
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           218)         n = len(bytestring)
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           219)         msg = 'malformed SSH byte string'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           220)         if n < HEAD_LEN or n != HEAD_LEN + int.from_bytes(
src/ssh_agent_client/__init__.py           221)             bytestring[:HEAD_LEN], 'big', signed=False
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           222)         ):
src/ssh_agent_client/__init__.py           223)             raise ValueError(msg)
src/ssh_agent_client/__init__.py           224)         return bytestring[HEAD_LEN:]
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           225) 
Marco Ricci Add function for SSH framed...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           226)     @classmethod
src/ssh_agent_client/__init__.py           227)     def unstring_prefix(
src/ssh_agent_client/__init__.py           228)         cls, bytestring: bytes | bytearray, /
src/ssh_agent_client/__init__.py           229)     ) -> tuple[bytes | bytearray, bytes | bytearray]:
src/ssh_agent_client/__init__.py           230)         r"""Unpack an SSH string at the beginning of the byte string.
src/ssh_agent_client/__init__.py           231) 
src/ssh_agent_client/__init__.py           232)         Args:
src/ssh_agent_client/__init__.py           233)             bytestring:
src/ssh_agent_client/__init__.py           234)                 A (general) byte string, beginning with a framed/SSH
src/ssh_agent_client/__init__.py           235)                 byte string.
src/ssh_agent_client/__init__.py           236) 
src/ssh_agent_client/__init__.py           237)         Returns:
src/ssh_agent_client/__init__.py           238)             A 2-tuple `(a, b)`, where `a` is the unframed byte
src/ssh_agent_client/__init__.py           239)             string/payload at the beginning of input byte string, and
src/ssh_agent_client/__init__.py           240)             `b` is the remainder of the input byte string.
src/ssh_agent_client/__init__.py           241) 
src/ssh_agent_client/__init__.py           242)         Raises:
src/ssh_agent_client/__init__.py           243)             ValueError:
src/ssh_agent_client/__init__.py           244)                 The byte string does not begin with an SSH string.
src/ssh_agent_client/__init__.py           245) 
src/ssh_agent_client/__init__.py           246)         Examples:
src/ssh_agent_client/__init__.py           247)             >>> a, b = SSHAgentClient.unstring_prefix(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           248)             ...     b'\x00\x00\x00\x07ssh-rsa____trailing data'
src/ssh_agent_client/__init__.py           249)             ... )
Marco Ricci Add function for SSH framed...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           250)             >>> (bytes(a), bytes(b))
src/ssh_agent_client/__init__.py           251)             (b'ssh-rsa', b'____trailing data')
src/ssh_agent_client/__init__.py           252)             >>> a, b = SSHAgentClient.unstring_prefix(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           253)             ...     SSHAgentClient.string(b'ssh-ed25519')
src/ssh_agent_client/__init__.py           254)             ... )
Marco Ricci Add function for SSH framed...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           255)             >>> (bytes(a), bytes(b))
src/ssh_agent_client/__init__.py           256)             (b'ssh-ed25519', b'')
src/ssh_agent_client/__init__.py           257) 
src/ssh_agent_client/__init__.py           258)         """
src/ssh_agent_client/__init__.py           259)         n = len(bytestring)
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           260)         msg = 'malformed SSH byte string'
src/ssh_agent_client/__init__.py           261)         if n < HEAD_LEN:
src/ssh_agent_client/__init__.py           262)             raise ValueError(msg)
src/ssh_agent_client/__init__.py           263)         m = int.from_bytes(bytestring[:HEAD_LEN], 'big', signed=False)
src/ssh_agent_client/__init__.py           264)         if m + HEAD_LEN > n:
src/ssh_agent_client/__init__.py           265)             raise ValueError(msg)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           266)         return (
src/ssh_agent_client/__init__.py           267)             bytestring[HEAD_LEN : m + HEAD_LEN],
src/ssh_agent_client/__init__.py           268)             bytestring[m + HEAD_LEN :],
src/ssh_agent_client/__init__.py           269)         )
Marco Ricci Add function for SSH framed...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           270) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           271)     def request(
src/ssh_agent_client/__init__.py           272)         self, code: int, payload: bytes | bytearray, /
src/ssh_agent_client/__init__.py           273)     ) -> tuple[int, bytes | bytearray]:
src/ssh_agent_client/__init__.py           274)         """Issue a generic request to the SSH agent.
src/ssh_agent_client/__init__.py           275) 
src/ssh_agent_client/__init__.py           276)         Args:
src/ssh_agent_client/__init__.py           277)             code:
src/ssh_agent_client/__init__.py           278)                 The request code.  See the SSH agent protocol for
src/ssh_agent_client/__init__.py           279)                 protocol numbers to use here (and which protocol numbers
src/ssh_agent_client/__init__.py           280)                 to expect in a response).
src/ssh_agent_client/__init__.py           281)             payload:
src/ssh_agent_client/__init__.py           282)                 A byte string containing the payload, or "contents", of
src/ssh_agent_client/__init__.py           283)                 the request.  Request-specific.  `request` will add any
src/ssh_agent_client/__init__.py           284)                 necessary wire framing around the request code and the
src/ssh_agent_client/__init__.py           285)                 payload.
src/ssh_agent_client/__init__.py           286) 
src/ssh_agent_client/__init__.py           287)         Returns:
src/ssh_agent_client/__init__.py           288)             A 2-tuple consisting of the response code and the payload,
src/ssh_agent_client/__init__.py           289)             with all wire framing removed.
src/ssh_agent_client/__init__.py           290) 
src/ssh_agent_client/__init__.py           291)         Raises:
src/ssh_agent_client/__init__.py           292)             EOFError:
src/ssh_agent_client/__init__.py           293)                 The response from the SSH agent is truncated or missing.
src/ssh_agent_client/__init__.py           294) 
src/ssh_agent_client/__init__.py           295)         """
src/ssh_agent_client/__init__.py           296)         request_message = bytearray([code])
src/ssh_agent_client/__init__.py           297)         request_message.extend(payload)
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           298)         self._connection.sendall(self.string(request_message))
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           299)         chunk = self._connection.recv(HEAD_LEN)
src/ssh_agent_client/__init__.py           300)         if len(chunk) < HEAD_LEN:
src/ssh_agent_client/__init__.py           301)             msg = 'cannot read response length'
src/ssh_agent_client/__init__.py           302)             raise EOFError(msg)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           303)         response_length = int.from_bytes(chunk, 'big', signed=False)
Marco Ricci Remove public attributes of...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           304)         response = self._connection.recv(response_length)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           305)         if len(response) < response_length:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           306)             msg = 'truncated response from SSH agent'
src/ssh_agent_client/__init__.py           307)             raise EOFError(msg)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           308)         return response[0], response[1:]
src/ssh_agent_client/__init__.py           309) 
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 310)     def list_keys(self) -> Sequence[_types.KeyCommentPair]:
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           311)         """Request a list of keys known to the SSH agent.
src/ssh_agent_client/__init__.py           312) 
src/ssh_agent_client/__init__.py           313)         Returns:
src/ssh_agent_client/__init__.py           314)             A read-only sequence of key/comment pairs.
src/ssh_agent_client/__init__.py           315) 
src/ssh_agent_client/__init__.py           316)         Raises:
src/ssh_agent_client/__init__.py           317)             EOFError:
src/ssh_agent_client/__init__.py           318)                 The response from the SSH agent is truncated or missing.
Marco Ricci Introduce TrailingDataError...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           319)             TrailingDataError:
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           320)                 The response from the SSH agent is too long.
Marco Ricci Add a specific error class...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          321)             SSHAgentFailedError:
Marco Ricci Introduce TrailingDataError...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           322)                 The agent failed to complete the request.
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           323) 
src/ssh_agent_client/__init__.py           324)         """
src/ssh_agent_client/__init__.py           325)         response_code, response = self.request(
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 326)             _types.SSH_AGENTC.REQUEST_IDENTITIES.value, b''
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           327)         )
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 328)         if response_code != _types.SSH_AGENT.IDENTITIES_ANSWER.value:
Marco Ricci Add a specific error class...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          329)             raise SSHAgentFailedError(response_code, response)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           330)         response_stream = collections.deque(response)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           331) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           332)         def shift(num: int) -> bytes:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           333)             buf = collections.deque(b'')
src/ssh_agent_client/__init__.py           334)             for _ in range(num):
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           335)                 try:
src/ssh_agent_client/__init__.py           336)                     val = response_stream.popleft()
src/ssh_agent_client/__init__.py           337)                 except IndexError:
src/ssh_agent_client/__init__.py           338)                     response_stream.extendleft(reversed(buf))
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           339)                     msg = 'truncated response from SSH agent'
src/ssh_agent_client/__init__.py           340)                     raise EOFError(msg) from None
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           341)                 buf.append(val)
src/ssh_agent_client/__init__.py           342)             return bytes(buf)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           343) 
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           344)         key_count = int.from_bytes(shift(4), 'big')
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 345)         keys: collections.deque[_types.KeyCommentPair]
Marco Ricci Fix Google code style viola...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           346)         keys = collections.deque()
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           347)         for _ in range(key_count):
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           348)             key_size = int.from_bytes(shift(4), 'big')
src/ssh_agent_client/__init__.py           349)             key = shift(key_size)
src/ssh_agent_client/__init__.py           350)             comment_size = int.from_bytes(shift(4), 'big')
src/ssh_agent_client/__init__.py           351)             comment = shift(comment_size)
src/ssh_agent_client/__init__.py           352)             # Both `key` and `comment` are not wrapped as SSH strings.
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 353)             keys.append(_types.KeyCommentPair(key, comment))
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           354)         if response_stream:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           355)             raise TrailingDataError
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           356)         return keys
src/ssh_agent_client/__init__.py           357) 
src/ssh_agent_client/__init__.py           358)     def sign(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           359)         self,
src/ssh_agent_client/__init__.py           360)         /,
src/ssh_agent_client/__init__.py           361)         key: bytes | bytearray,
src/ssh_agent_client/__init__.py           362)         payload: bytes | bytearray,
src/ssh_agent_client/__init__.py           363)         *,
src/ssh_agent_client/__init__.py           364)         flags: int = 0,
src/ssh_agent_client/__init__.py           365)         check_if_key_loaded: bool = False,
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           366)     ) -> bytes | bytearray:
src/ssh_agent_client/__init__.py           367)         """Request the SSH agent sign the payload with the key.
src/ssh_agent_client/__init__.py           368) 
src/ssh_agent_client/__init__.py           369)         Args:
src/ssh_agent_client/__init__.py           370)             key:
src/ssh_agent_client/__init__.py           371)                 The public SSH key to sign the payload with, in the same
src/ssh_agent_client/__init__.py           372)                 format as returned by, e.g., the `list_keys` method.
src/ssh_agent_client/__init__.py           373)                 The corresponding private key must have previously been
src/ssh_agent_client/__init__.py           374)                 loaded into the agent to successfully issue a signature.
src/ssh_agent_client/__init__.py           375)             payload:
src/ssh_agent_client/__init__.py           376)                 A byte string of data to sign.
src/ssh_agent_client/__init__.py           377)             flags:
src/ssh_agent_client/__init__.py           378)                 Optional flags for the signing request.  Currently
src/ssh_agent_client/__init__.py           379)                 passed on as-is to the agent.  In real-world usage, this
src/ssh_agent_client/__init__.py           380)                 could be used, e.g., to request more modern hash
src/ssh_agent_client/__init__.py           381)                 algorithms when signing with RSA keys.  (No such
src/ssh_agent_client/__init__.py           382)                 real-world usage is currently implemented.)
src/ssh_agent_client/__init__.py           383)             check_if_key_loaded:
src/ssh_agent_client/__init__.py           384)                 If true, check beforehand (via `list_keys`) if the
src/ssh_agent_client/__init__.py           385)                 corresponding key has been loaded into the agent.
src/ssh_agent_client/__init__.py           386) 
src/ssh_agent_client/__init__.py           387)         Returns:
src/ssh_agent_client/__init__.py           388)             The binary signature of the payload under the given key.
src/ssh_agent_client/__init__.py           389) 
src/ssh_agent_client/__init__.py           390)         Raises:
src/ssh_agent_client/__init__.py           391)             EOFError:
src/ssh_agent_client/__init__.py           392)                 The response from the SSH agent is truncated or missing.
Marco Ricci Introduce TrailingDataError...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           393)             TrailingDataError:
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           394)                 The response from the SSH agent is too long.
Marco Ricci Add a specific error class...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          395)             SSHAgentFailedError:
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           396)                 The agent failed to complete the request.
Marco Ricci Raise KeyError when signing...

Marco Ricci authored 4 months ago

src/ssh_agent_client/__init__.py           397)             KeyError:
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           398)                 `check_if_key_loaded` is true, and the `key` was not
src/ssh_agent_client/__init__.py           399)                 loaded into the agent.
src/ssh_agent_client/__init__.py           400) 
src/ssh_agent_client/__init__.py           401)         """
src/ssh_agent_client/__init__.py           402)         if check_if_key_loaded:
src/ssh_agent_client/__init__.py           403)             loaded_keys = frozenset({pair.key for pair in self.list_keys()})
src/ssh_agent_client/__init__.py           404)             if bytes(key) not in loaded_keys:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           405)                 msg = 'target SSH key not loaded into agent'
src/ssh_agent_client/__init__.py           406)                 raise KeyError(msg)
Marco Ricci Add prototype implementation

Marco Ricci authored 5 months ago

src/ssh_agent_client/__init__.py           407)         request_data = bytearray(self.string(key))
src/ssh_agent_client/__init__.py           408)         request_data.extend(self.string(payload))
src/ssh_agent_client/__init__.py           409)         request_data.extend(self.uint32(flags))
src/ssh_agent_client/__init__.py           410)         response_code, response = self.request(
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 411)             _types.SSH_AGENTC.SIGN_REQUEST.value, request_data
Marco Ricci Reformat everything with ruff

Marco Ricci authored 3 months ago

src/ssh_agent_client/__init__.py           412)         )
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 3 months ago

src/derivepassphrase/ssh_agent/__init__.py 413)         if response_code != _types.SSH_AGENT.SIGN_RESPONSE.value:
Marco Ricci Add a specific error class...

Marco Ricci authored 2 months ago

src/derivepassphrase/ssh_agent.py          414)             raise SSHAgentFailedError(response_code, response)