diff --git a/kittens/transfer/main.py b/kittens/transfer/main.py index 6369cdb71..bdd62692f 100644 --- a/kittens/transfer/main.py +++ b/kittens/transfer/main.py @@ -30,9 +30,9 @@ receiving computer. In :code:`normal` mode the last argument is assumed to be a destination path on the receiving computer. ---permissions-password -p +--permissions-bypass -p The password to use to skip the transfer confirmation popup in kitty. Must match the -password set for the :opt:`file_transfer_password` option in kitty.conf. Note that +password set for the :opt:`file_transfer_confirmation_bypass` option in kitty.conf. Note that leading and trailing whitespace is removed from the password. A password starting with ., / or ~ characters is assumed to be a file name to read the password from. A value of - means read the password from STDIN. A password that is purely a number less than 256 @@ -71,8 +71,8 @@ def read_password(loc: str) -> str: def main(args: List[str]) -> None: cli_opts, items = parse_transfer_args(args) - if cli_opts.permissions_password: - cli_opts.permissions_password = read_password(cli_opts.permissions_password).strip() + if cli_opts.permissions_bypass: + cli_opts.permissions_bypass = read_password(cli_opts.permissions_bypass).strip() if not items: raise SystemExit('Usage: kitty +kitten transfer file_or_directory ...') diff --git a/kittens/transfer/send.py b/kittens/transfer/send.py index 5bd8cd9a0..f719a61b6 100644 --- a/kittens/transfer/send.py +++ b/kittens/transfer/send.py @@ -18,7 +18,7 @@ from kitty.cli_stub import TransferCLIOptions from kitty.fast_data_types import FILE_TRANSFER_CODE, wcswidth from kitty.file_transmission import ( Action, Compression, FileTransmissionCommand, FileType, NameReprEnum, - TransmissionType, encode_password + TransmissionType, encode_bypass ) from kitty.typing import KeyEventType from kitty.utils import sanitize_control_codes @@ -257,9 +257,9 @@ class ProgressTracker: class SendManager: - def __init__(self, request_id: str, files: Tuple[File, ...], pw: Optional[str] = None, file_done: Callable[[File], None] = lambda f: None): + def __init__(self, request_id: str, files: Tuple[File, ...], bypass: Optional[str] = None, file_done: Callable[[File], None] = lambda f: None): self.files = files - self.password = encode_password(request_id, pw) if pw else '' + self.bypass = encode_bypass(request_id, bypass) if bypass else '' self.fid_map = {f.file_id: f for f in self.files} self.request_id = request_id self.state = SendState.waiting_for_permission @@ -306,7 +306,7 @@ class SendManager: self.all_started = not found_not_started def start_transfer(self) -> str: - return FileTransmissionCommand(action=Action.send, password=self.password).serialize() + return FileTransmissionCommand(action=Action.send, bypass=self.bypass).serialize() def next_chunks(self) -> Iterator[str]: if self.active_file is None: @@ -368,7 +368,7 @@ class Send(Handler): def __init__(self, cli_opts: TransferCLIOptions, files: Tuple[File, ...]): Handler.__init__(self) - self.manager = SendManager(random_id(), files, cli_opts.permissions_password, self.on_file_done) + self.manager = SendManager(random_id(), files, cli_opts.permissions_bypass, self.on_file_done) self.cli_opts = cli_opts self.transmit_started = False self.file_metadata_sent = False @@ -504,8 +504,8 @@ class Send(Handler): def initialize(self) -> None: self.send_payload(self.manager.start_transfer()) - if self.cli_opts.permissions_password: - # dont wait for permission, not needed with a password and + if self.cli_opts.permissions_bypass: + # dont wait for permission, not needed with a bypass and # avoids a roundtrip self.send_file_metadata() self.cmd.set_cursor_visible(False) diff --git a/kitty/file_transmission.py b/kitty/file_transmission.py index f14bea890..973bf3d2a 100644 --- a/kitty/file_transmission.py +++ b/kitty/file_transmission.py @@ -26,7 +26,7 @@ EXPIRE_TIME = 10 # minutes MAX_ACTIVE_RECEIVES = 10 -def encode_password(request_id: str, pw: str) -> str: +def encode_bypass(request_id: str, pw: str) -> str: import hashlib q = request_id + ';' + pw return 'sha256:' + hashlib.sha256(q.encode('utf-8', 'replace')).hexdigest() @@ -114,7 +114,7 @@ class FileTransmissionCommand: ttype: TransmissionType = TransmissionType.simple id: str = '' file_id: str = '' - password: str = field(default='', metadata={'base64': True}) + bypass: str = field(default='', metadata={'base64': True}) quiet: int = 0 mtime: int = -1 permissions: int = -1 @@ -341,12 +341,12 @@ class ActiveReceive: files: Dict[str, DestFile] accepted: bool = False - def __init__(self, request_id: str, quiet: int, password: str) -> None: + def __init__(self, request_id: str, quiet: int, bypass: str) -> None: self.id = request_id - self.password_ok: Optional[bool] = None - pw = get_options().file_transfer_password - if pw and password: - self.password_ok = encode_password(request_id, pw) == password + self.bypass_ok: Optional[bool] = None + byp = get_options().file_transfer_confirmation_bypass + if byp and bypass: + self.bypass_ok = encode_bypass(request_id, byp) == byp self.files = {} self.last_activity_at = monotonic() self.send_acknowledgements = quiet < 1 @@ -477,7 +477,7 @@ class FileTransmission: if len(self.active_receives) >= MAX_ACTIVE_RECEIVES: log_error('New File transmission send with too many active receives, ignoring') return - ar = self.active_receives[cmd.id] = ActiveReceive(cmd.id, cmd.quiet, cmd.password) + ar = self.active_receives[cmd.id] = ActiveReceive(cmd.id, cmd.quiet, cmd.bypass) self.start_receive(ar.id) return @@ -568,8 +568,8 @@ class FileTransmission: def start_receive(self, ar_id: str) -> None: ar = self.active_receives[ar_id] - if ar.password_ok is not None: - self.handle_send_confirmation(ar_id, {'response': 'y' if ar.password_ok else 'n'}) + if ar.bypass_ok is not None: + self.handle_send_confirmation(ar_id, {'response': 'y' if ar.bypass_ok else 'n'}) return boss = get_boss() window = boss.window_id_map.get(self.window_id) diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 47fe0801a..608800ba8 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -2566,11 +2566,12 @@ stored for writing to the system clipboard. See also :opt:`clipboard_control`. A value of zero means no size limit is applied. ''') -opt('file_transfer_password', '', long_text=''' -A password, that can be supplied to the file transfer kitten to skip -the transfer confirmation dialog. This should only be used -when initiating transfers from trusted computers, over trusted networks -or encrypted transports. +opt('file_transfer_confirmation_bypass', '', long_text=''' +A password, that can be supplied to the file transfer kitten to skip the +transfer confirmation prompt. This should only be used when initiating +transfers from trusted computers, over trusted networks or encrypted +transports, as it allows programs running on the remote machine to read/write +to the local filesystem, without permission. ''') opt('allow_hyperlinks', 'yes', diff --git a/kitty/options/parse.py b/kitty/options/parse.py index b6b1a1c22..55ba1837b 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -942,8 +942,8 @@ class Parser: for k, v in env(val, ans["env"]): ans["env"][k] = v - def file_transfer_password(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: - ans['file_transfer_password'] = str(val) + def file_transfer_confirmation_bypass(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['file_transfer_confirmation_bypass'] = str(val) def focus_follows_mouse(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['focus_follows_mouse'] = to_bool(val) diff --git a/kitty/options/types.py b/kitty/options/types.py index 19a5de570..129a8c701 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -345,7 +345,7 @@ option_names = ( # {{{ 'enable_audio_bell', 'enabled_layouts', 'env', - 'file_transfer_password', + 'file_transfer_confirmation_bypass', 'focus_follows_mouse', 'font_family', 'font_features', @@ -485,7 +485,7 @@ class Options: editor: str = '.' enable_audio_bell: bool = True enabled_layouts: typing.List[str] = ['fat', 'grid', 'horizontal', 'splits', 'stack', 'tall', 'vertical'] - file_transfer_password: str = '' + file_transfer_confirmation_bypass: str = '' focus_follows_mouse: bool = False font_family: str = 'monospace' font_size: float = 11.0