Start work on remote control passwords

This commit is contained in:
Kovid Goyal 2022-08-09 11:30:49 +05:30
parent 31be4f041e
commit e64b1ba67c
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
6 changed files with 65 additions and 18 deletions

View file

@ -79,24 +79,27 @@ def filter_env_vars(self, *a: str, **override: str) -> 'ToCmdline':
self.override_env.update(override)
return self
def __call__(self, x: str) -> List[str]:
return list(
map(
lambda y: expandvars(
os.path.expanduser(y),
os.environ if self.override_env is None else self.override_env,
fallback_to_os_env=False
),
shlex.split(x)
def __call__(self, x: str, expand: bool = True) -> List[str]:
ans = shlex.split(x)
if expand:
ans = list(
map(
lambda y: expandvars(
os.path.expanduser(y),
os.environ if self.override_env is None else self.override_env,
fallback_to_os_env=False
),
ans
)
)
)
return ans
to_cmdline_implementation = ToCmdline()
def to_cmdline(x: str) -> List[str]:
return to_cmdline_implementation(x)
def to_cmdline(x: str, expand: bool = True) -> List[str]:
return to_cmdline_implementation(x, expand)
def python_string(text: str) -> str:

View file

@ -2687,6 +2687,32 @@
'''
)
opt('+remote_control_password', '', option_type='remote_control_password', add_to_default=False,
long_text='''
Allow other programs to control kitty using passwords. This option can be specified multiple
times to add multiple passwords. If no passwords are present kitty will ask the user for
permission if a program tries to use remote control with a password. A password can also
*optionally* be associated with a set of allowed remote control actions. For example::
remote_control_password "my passphrase" get-colors set-colors focus-window focus-tab
Only the specified actions will be allowed when using this password.
Glob patterns can be used too, for example::
remote_control_password "my passphrase" set-tab-* resize-*
To get a list of available actions, run::
kitty @ -h
Finally, the path to a python module can be specified that provides a function :code:`is_cmd_allowed`
that is used to check every remote control command. See :ref:`rc_custom_auth` for details. For example::
remote_control_password "my passphrase" my_rc_command_checker.py
Relative paths are resolved from the kitty configuration directory.
''')
opt('allow_remote_control', 'no',
option_type='allow_remote_control',
long_text='''

15
kitty/options/parse.py generated
View file

@ -13,11 +13,11 @@
deprecated_macos_show_window_title_in_menubar_alias, deprecated_send_text, disable_ligatures,
edge_width, env, font_features, hide_window_decorations, macos_option_as_alt, macos_titlebar_color,
modify_font, narrow_symbols, optional_edge_width, parse_map, parse_mouse_map, paste_actions,
resize_draw_strategy, scrollback_lines, scrollback_pager_history_size, shell_integration,
store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge, tab_bar_margin_height,
tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, tab_title_template, titlebar_color,
to_cursor_shape, to_font_size, to_layout_names, to_modifiers, url_prefixes, url_style,
visual_window_select_characters, window_border_width, window_size
remote_control_password, resize_draw_strategy, scrollback_lines, scrollback_pager_history_size,
shell_integration, store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge,
tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator,
tab_title_template, titlebar_color, to_cursor_shape, to_font_size, to_layout_names, to_modifiers,
url_prefixes, url_style, visual_window_select_characters, window_border_width, window_size
)
@ -1131,6 +1131,10 @@ def pointer_shape_when_grabbed(self, val: str, ans: typing.Dict[str, typing.Any]
def remember_window_size(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['remember_window_size'] = to_bool(val)
def remote_control_password(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
for k, v in remote_control_password(val, ans["remote_control_password"]):
ans["remote_control_password"][k] = v
def repaint_delay(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['repaint_delay'] = positive_int(val)
@ -1370,6 +1374,7 @@ def create_result_dict() -> typing.Dict[str, typing.Any]:
'kitten_alias': {},
'modify_font': {},
'narrow_symbols': {},
'remote_control_password': {},
'symbol_map': {},
'watcher': {},
'map': [],

View file

@ -400,6 +400,7 @@
'pointer_shape_when_dragging',
'pointer_shape_when_grabbed',
'remember_window_size',
'remote_control_password',
'repaint_delay',
'resize_debounce_time',
'resize_draw_strategy',
@ -609,6 +610,7 @@ class Options:
kitten_alias: typing.Dict[str, str] = {}
modify_font: typing.Dict[str, kitty.fonts.FontModification] = {}
narrow_symbols: typing.Dict[typing.Tuple[int, int], int] = {}
remote_control_password: typing.Dict[str, typing.Tuple[str, ...]] = {}
symbol_map: typing.Dict[typing.Tuple[int, int], str] = {}
watcher: typing.Dict[str, str] = {}
map: typing.List[kitty.options.utils.KeyDefinition] = []
@ -729,6 +731,7 @@ def __setattr__(self, key: str, val: typing.Any) -> typing.Any:
defaults.kitten_alias = {}
defaults.modify_font = {}
defaults.narrow_symbols = {}
defaults.remote_control_password = {}
defaults.symbol_map = {}
defaults.watcher = {}
defaults.map = [

View file

@ -675,6 +675,16 @@ def config_or_absolute_path(x: str, env: Optional[Dict[str, str]] = None) -> Opt
return resolve_abs_or_config_path(x, env)
def remote_control_password(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, Tuple[str, ...]]]:
val = val.strip()
if val:
parts = to_cmdline(val, expand=False)
if len(parts) == 1:
yield parts[0], ()
else:
yield parts[0], tuple(parts[1:])
def allow_remote_control(x: str) -> str:
if x != 'socket-only':
x = 'y' if to_bool(x) else 'n'

View file

@ -170,7 +170,7 @@ def send_generator() -> Iterator[bytes]:
cli_msg = (
'Control {appname} by sending it commands. Set the'
' :opt:`allow_remote_control` option to yes in :file:`kitty.conf` for this'
' :opt:`allow_remote_control` option in :file:`kitty.conf` or use a password, for this'
' to work.'
).format(appname=appname)