Remote control: Fix empty password not working

Fixes #7538
This commit is contained in:
Kovid Goyal
2024-06-15 11:15:19 +05:30
parent 68649d78df
commit f4bec5f4ab
4 changed files with 32 additions and 21 deletions

View File

@@ -57,6 +57,8 @@ Detailed list of changes
- A new option, :opt:`cursor_shape_unfocused` to specify the shape of the text cursor in unfocused OS windows (:pull:`7544`) - A new option, :opt:`cursor_shape_unfocused` to specify the shape of the text cursor in unfocused OS windows (:pull:`7544`)
- Remote control: Fix empty password not working (:iss:`7538`)
0.35.1 [2024-05-31] 0.35.1 [2024-05-31]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -794,7 +794,7 @@ def remote_control_password(val: str, current_val: Dict[str, str]) -> Iterable[T
# line of remote_control_password # line of remote_control_password
raise ValueError('Passwords are not allowed to start with hyphens, ignoring this password') raise ValueError('Passwords are not allowed to start with hyphens, ignoring this password')
if len(parts) == 1: if len(parts) == 1:
yield parts[0], tuple() yield "", (parts[0],)
else: else:
yield parts[0], tuple(parts[1:]) yield parts[0], tuple(parts[1:])

View File

@@ -276,7 +276,8 @@ they will only work if this process is run within a kitty window.
--password --password
A password to use when contacting kitty. This will cause kitty to ask the user A password to use when contacting kitty. This will cause kitty to ask the user
for permission to perform the specified action, unless the password has been for permission to perform the specified action, unless the password has been
accepted before or is pre-configured in :file:`kitty.conf`. accepted before or is pre-configured in :file:`kitty.conf`. To use a blank password
specify :option:`kitten @ --use-password` as :code:`always`.
--password-file --password-file
@@ -300,7 +301,7 @@ default=if-available
choices=if-available,never,always choices=if-available,never,always
If no password is available, kitty will usually just send the remote control command If no password is available, kitty will usually just send the remote control command
without a password. This option can be used to force it to :code:`always` or :code:`never` use without a password. This option can be used to force it to :code:`always` or :code:`never` use
the supplied password. the supplied password. If set to always and no password is provided, the blank password is used.
'''.format, appname=appname) '''.format, appname=appname)

View File

@@ -32,10 +32,16 @@ const lowerhex = "0123456789abcdef"
var ProtocolVersion [3]int = [3]int{0, 26, 0} var ProtocolVersion [3]int = [3]int{0, 26, 0}
type password struct {
val string
is_set bool
}
type GlobalOptions struct { type GlobalOptions struct {
to_network, to_address, password string to_network, to_address string
to_address_is_from_env_var bool password password
already_setup bool to_address_is_from_env_var bool
already_setup bool
} }
var global_options GlobalOptions var global_options GlobalOptions
@@ -135,15 +141,15 @@ func simple_serializer(rc *utils.RemoteControlCmd) (ans []byte, err error) {
type serializer_func func(rc *utils.RemoteControlCmd) ([]byte, error) type serializer_func func(rc *utils.RemoteControlCmd) ([]byte, error)
func create_serializer(password string, encoded_pubkey string, io_data *rc_io_data) (err error) { func create_serializer(password password, encoded_pubkey string, io_data *rc_io_data) (err error) {
io_data.serializer = simple_serializer io_data.serializer = simple_serializer
if password != "" { if password.is_set {
encryption_version, pubkey, err := get_pubkey(encoded_pubkey) encryption_version, pubkey, err := get_pubkey(encoded_pubkey)
if err != nil { if err != nil {
return err return err
} }
io_data.serializer = func(rc *utils.RemoteControlCmd) (ans []byte, err error) { io_data.serializer = func(rc *utils.RemoteControlCmd) (ans []byte, err error) {
ec, err := crypto.Encrypt_cmd(rc, global_options.password, pubkey, encryption_version) ec, err := crypto.Encrypt_cmd(rc, global_options.password.val, pubkey, encryption_version)
if err != nil { if err != nil {
return return
} }
@@ -293,25 +299,26 @@ func send_rc_command(io_data *rc_io_data) (err error) {
return return
} }
func get_password(password string, password_file string, password_env string, use_password string) (ans string, err error) { func get_password(password string, password_file string, password_env string, use_password string) (ans password, err error) {
if use_password == "never" { if use_password == "never" {
return return
} }
if password != "" { if password != "" {
ans = password ans.is_set, ans.val = true, password
} }
if ans == "" && password_file != "" { if !ans.is_set && password_file != "" {
if password_file == "-" { if password_file == "-" {
if tty.IsTerminal(os.Stdin.Fd()) { if tty.IsTerminal(os.Stdin.Fd()) {
ans, err = tui.ReadPassword("Password: ", true) p, err := tui.ReadPassword("Password: ", true)
if err != nil { if err != nil {
return return ans, err
} }
ans.is_set, ans.val = true, p
} else { } else {
var q []byte var q []byte
q, err = io.ReadAll(os.Stdin) q, err = io.ReadAll(os.Stdin)
if err == nil { if err == nil {
ans = strings.TrimRight(string(q), " \n\t") ans.is_set, ans.val = true, strings.TrimRight(string(q), " \n\t")
} }
ttyf, err := os.Open(tty.Ctermid()) ttyf, err := os.Open(tty.Ctermid())
if err == nil { if err == nil {
@@ -323,7 +330,7 @@ func get_password(password string, password_file string, password_env string, us
var q []byte var q []byte
q, err = os.ReadFile(password_file) q, err = os.ReadFile(password_file)
if err == nil { if err == nil {
ans = strings.TrimRight(string(q), " \n\t") ans.is_set, ans.val = true, strings.TrimRight(string(q), " \n\t")
} else { } else {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
err = nil err = nil
@@ -334,13 +341,14 @@ func get_password(password string, password_file string, password_env string, us
return return
} }
} }
if ans == "" && password_env != "" { if !ans.is_set && password_env != "" {
ans = os.Getenv(password_env) ans.val, ans.is_set = os.LookupEnv(password_env)
} }
if ans == "" && use_password == "always" { if !ans.is_set && use_password == "always" {
return ans, fmt.Errorf("No password was found") ans.is_set = true
return ans, nil
} }
if len(ans) > 1024 { if len(ans.val) > 1024 {
return ans, fmt.Errorf("Specified password is too long") return ans, fmt.Errorf("Specified password is too long")
} }
return ans, nil return ans, nil