mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-22 03:57:30 +03:00
Start work on SSH askpass implementation
This commit is contained in:
parent
910565aa7c
commit
3b724c8415
@ -701,6 +701,17 @@ def callback_(res: Dict[str, Any], x: int, boss: Boss) -> None:
|
||||
cmd += ['-c', c]
|
||||
self._run_kitten('ask', cmd, window=window, custom_callback=callback_, default_data={'response': ''})
|
||||
|
||||
def get_line(
|
||||
self, msg: str, # can contain newlines and ANSI formatting
|
||||
callback: Callable[..., None], # called with the answer or empty string when aborted
|
||||
window: Optional[Window] = None, # the window associated with the confirmation
|
||||
is_password: bool = False
|
||||
) -> None:
|
||||
def callback_(res: Dict[str, Any], x: int, boss: Boss) -> None:
|
||||
callback(res.get('response') or '')
|
||||
cmd = ['--type', 'password' if is_password else 'line', '--message', msg]
|
||||
self._run_kitten('ask', cmd, window=window, custom_callback=callback_, default_data={'response': ''})
|
||||
|
||||
def confirm_tab_close(self, tab: Tab) -> None:
|
||||
x = get_options().confirm_os_window_close
|
||||
num = tab.number_of_windows_with_running_programs if x < 0 else len(tab)
|
||||
|
@ -1084,6 +1084,7 @@ dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
||||
} else IF_SIMPLE_PREFIX("kitty-print|", screen_handle_print)
|
||||
} else IF_SIMPLE_PREFIX("kitty-echo|", screen_handle_echo)
|
||||
} else IF_SIMPLE_PREFIX("kitty-ssh|", screen_handle_ssh)
|
||||
} else IF_SIMPLE_PREFIX("kitty-askpass|", screen_handle_askpass)
|
||||
#undef IF_SIMPLE_PREFIX
|
||||
} else {
|
||||
REPORT_ERROR("Unrecognized DCS @ code: 0x%x", screen->parser_buf[1]);
|
||||
|
@ -2114,6 +2114,12 @@ screen_handle_ssh(Screen *self, PyObject *msg) {
|
||||
CALLBACK("handle_remote_ssh", "O", msg);
|
||||
}
|
||||
|
||||
void
|
||||
screen_handle_askpass(Screen *self, PyObject *msg) {
|
||||
CALLBACK("handle_remote_askpass", "O", msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
screen_request_capabilities(Screen *self, char c, PyObject *q) {
|
||||
static char buf[128];
|
||||
|
@ -210,6 +210,7 @@ void screen_report_color_stack(Screen *);
|
||||
void screen_handle_print(Screen *, PyObject *cmd);
|
||||
void screen_handle_echo(Screen *, PyObject *cmd);
|
||||
void screen_handle_ssh(Screen *, PyObject *cmd);
|
||||
void screen_handle_askpass(Screen *, PyObject *cmd);
|
||||
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
|
||||
void screen_use_latin1(Screen *, bool);
|
||||
void set_title(Screen *self, PyObject*);
|
||||
|
@ -885,6 +885,35 @@ def handle_remote_ssh(self, msg: str) -> None:
|
||||
for line in get_ssh_data(msg, f'{os.getpid()}-{self.id}'):
|
||||
self.write_to_child(line)
|
||||
|
||||
def handle_remote_askpass(self, msg: str) -> None:
|
||||
from .shm import SharedMemory
|
||||
with SharedMemory(name=msg, readonly=True) as shm:
|
||||
shm.seek(1)
|
||||
data = json.loads(shm.read_data_with_size())
|
||||
|
||||
def callback(ans: Any) -> None:
|
||||
data = json.dumps(ans)
|
||||
with SharedMemory(name=msg) as shm:
|
||||
shm.seek(1)
|
||||
shm.write_data_with_size(data)
|
||||
shm.flush()
|
||||
shm.seek(0)
|
||||
shm.write(b'\x01')
|
||||
|
||||
prompt: str = data['prompt']
|
||||
if data['type'] == 'confirm':
|
||||
get_boss().confirm(
|
||||
prompt, callback, window=self, confirm_on_cancel=bool(data.get('confirm_on_cancel')),
|
||||
confirm_on_accept=bool(data.get('confirm_on_accept')))
|
||||
elif data['type'] == 'choose':
|
||||
get_boss().choose(
|
||||
prompt, callback, *data['choices'], window=self, default=data.get('default', ''))
|
||||
elif data['type'] == 'get_line':
|
||||
get_boss().get_line(
|
||||
prompt, callback, window=self, is_password=bool(data.get('is_password')))
|
||||
else:
|
||||
log_error(f'Ignoring ask request with unknown type: {data["type"]}')
|
||||
|
||||
def handle_remote_print(self, msg: str) -> None:
|
||||
text = process_remote_print(msg)
|
||||
print(text, end='', file=sys.stderr)
|
||||
|
24
shell-integration/ssh/askpass.py
Executable file
24
shell-integration/ssh/askpass.py
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env -S kitty +launch
|
||||
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import json
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from kitty.shm import SharedMemory
|
||||
|
||||
msg = sys.argv[-1]
|
||||
prompt = os.environ.get('SSH_ASKPASS_PROMPT', '')
|
||||
is_confirm = prompt == 'confirm'
|
||||
ask_cmdline = ['-m', msg, '--type', 'yesno' if is_confirm else 'password']
|
||||
if is_confirm:
|
||||
ask_cmdline += ['--default', 'y']
|
||||
data = json.dumps(ask_cmdline).encode('utf-8')
|
||||
sz = struct.pack('>I', len(data))
|
||||
with SharedMemory(size=len(data) + len(sz) + 1, unlink_on_exit=True, prefix=f'askpass-{os.getpid()}-') as shm, open(os.ctermid(), 'wb') as tty:
|
||||
shm.write(b'\0')
|
||||
shm.write(sz)
|
||||
shm.write(data)
|
||||
shm.flush()
|
||||
print(f'\x1bP@kitty-ask|{shm.name}\x1b\\', flush=True)
|
Loading…
Reference in New Issue
Block a user