Start work on remote control passwords
This commit is contained in:
parent
31be4f041e
commit
e64b1ba67c
@ -79,24 +79,27 @@ class ToCmdline:
|
|||||||
self.override_env.update(override)
|
self.override_env.update(override)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __call__(self, x: str) -> List[str]:
|
def __call__(self, x: str, expand: bool = True) -> List[str]:
|
||||||
return list(
|
ans = shlex.split(x)
|
||||||
|
if expand:
|
||||||
|
ans = list(
|
||||||
map(
|
map(
|
||||||
lambda y: expandvars(
|
lambda y: expandvars(
|
||||||
os.path.expanduser(y),
|
os.path.expanduser(y),
|
||||||
os.environ if self.override_env is None else self.override_env,
|
os.environ if self.override_env is None else self.override_env,
|
||||||
fallback_to_os_env=False
|
fallback_to_os_env=False
|
||||||
),
|
),
|
||||||
shlex.split(x)
|
ans
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
to_cmdline_implementation = ToCmdline()
|
to_cmdline_implementation = ToCmdline()
|
||||||
|
|
||||||
|
|
||||||
def to_cmdline(x: str) -> List[str]:
|
def to_cmdline(x: str, expand: bool = True) -> List[str]:
|
||||||
return to_cmdline_implementation(x)
|
return to_cmdline_implementation(x, expand)
|
||||||
|
|
||||||
|
|
||||||
def python_string(text: str) -> str:
|
def python_string(text: str) -> str:
|
||||||
|
|||||||
@ -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',
|
opt('allow_remote_control', 'no',
|
||||||
option_type='allow_remote_control',
|
option_type='allow_remote_control',
|
||||||
long_text='''
|
long_text='''
|
||||||
|
|||||||
15
kitty/options/parse.py
generated
15
kitty/options/parse.py
generated
@ -13,11 +13,11 @@ from kitty.options.utils import (
|
|||||||
deprecated_macos_show_window_title_in_menubar_alias, deprecated_send_text, disable_ligatures,
|
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,
|
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,
|
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,
|
remote_control_password, resize_draw_strategy, scrollback_lines, scrollback_pager_history_size,
|
||||||
store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge, tab_bar_margin_height,
|
shell_integration, store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge,
|
||||||
tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, tab_title_template, titlebar_color,
|
tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator,
|
||||||
to_cursor_shape, to_font_size, to_layout_names, to_modifiers, url_prefixes, url_style,
|
tab_title_template, titlebar_color, to_cursor_shape, to_font_size, to_layout_names, to_modifiers,
|
||||||
visual_window_select_characters, window_border_width, window_size
|
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:
|
def remember_window_size(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['remember_window_size'] = to_bool(val)
|
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:
|
def repaint_delay(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['repaint_delay'] = positive_int(val)
|
ans['repaint_delay'] = positive_int(val)
|
||||||
|
|
||||||
@ -1370,6 +1374,7 @@ def create_result_dict() -> typing.Dict[str, typing.Any]:
|
|||||||
'kitten_alias': {},
|
'kitten_alias': {},
|
||||||
'modify_font': {},
|
'modify_font': {},
|
||||||
'narrow_symbols': {},
|
'narrow_symbols': {},
|
||||||
|
'remote_control_password': {},
|
||||||
'symbol_map': {},
|
'symbol_map': {},
|
||||||
'watcher': {},
|
'watcher': {},
|
||||||
'map': [],
|
'map': [],
|
||||||
|
|||||||
3
kitty/options/types.py
generated
3
kitty/options/types.py
generated
@ -400,6 +400,7 @@ option_names = ( # {{{
|
|||||||
'pointer_shape_when_dragging',
|
'pointer_shape_when_dragging',
|
||||||
'pointer_shape_when_grabbed',
|
'pointer_shape_when_grabbed',
|
||||||
'remember_window_size',
|
'remember_window_size',
|
||||||
|
'remote_control_password',
|
||||||
'repaint_delay',
|
'repaint_delay',
|
||||||
'resize_debounce_time',
|
'resize_debounce_time',
|
||||||
'resize_draw_strategy',
|
'resize_draw_strategy',
|
||||||
@ -609,6 +610,7 @@ class Options:
|
|||||||
kitten_alias: typing.Dict[str, str] = {}
|
kitten_alias: typing.Dict[str, str] = {}
|
||||||
modify_font: typing.Dict[str, kitty.fonts.FontModification] = {}
|
modify_font: typing.Dict[str, kitty.fonts.FontModification] = {}
|
||||||
narrow_symbols: typing.Dict[typing.Tuple[int, int], int] = {}
|
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] = {}
|
symbol_map: typing.Dict[typing.Tuple[int, int], str] = {}
|
||||||
watcher: typing.Dict[str, str] = {}
|
watcher: typing.Dict[str, str] = {}
|
||||||
map: typing.List[kitty.options.utils.KeyDefinition] = []
|
map: typing.List[kitty.options.utils.KeyDefinition] = []
|
||||||
@ -729,6 +731,7 @@ defaults.font_features = {}
|
|||||||
defaults.kitten_alias = {}
|
defaults.kitten_alias = {}
|
||||||
defaults.modify_font = {}
|
defaults.modify_font = {}
|
||||||
defaults.narrow_symbols = {}
|
defaults.narrow_symbols = {}
|
||||||
|
defaults.remote_control_password = {}
|
||||||
defaults.symbol_map = {}
|
defaults.symbol_map = {}
|
||||||
defaults.watcher = {}
|
defaults.watcher = {}
|
||||||
defaults.map = [
|
defaults.map = [
|
||||||
|
|||||||
@ -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)
|
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:
|
def allow_remote_control(x: str) -> str:
|
||||||
if x != 'socket-only':
|
if x != 'socket-only':
|
||||||
x = 'y' if to_bool(x) else 'n'
|
x = 'y' if to_bool(x) else 'n'
|
||||||
|
|||||||
@ -170,7 +170,7 @@ def do_io(to: Optional[str], send: Dict[str, Any], no_response: bool, response_t
|
|||||||
|
|
||||||
cli_msg = (
|
cli_msg = (
|
||||||
'Control {appname} by sending it commands. Set the'
|
'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.'
|
' to work.'
|
||||||
).format(appname=appname)
|
).format(appname=appname)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user