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 @@ class 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 @@ their stdout/stderr/stdin no longer work.
'''
)
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 @@ from kitty.options.utils import (
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 @@ class Parser:
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 @@ option_names = ( # {{{
'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 @@ defaults.font_features = {}
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 do_io(to: Optional[str], send: Dict[str, Any], no_response: bool, response_t
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)