-
Notifications
You must be signed in to change notification settings - Fork 70
Description
Currently users have to store their passwords in the config file as plain text. That makes it difficult to store the config in e.g. git repos, but also storing password in plain text is just not a great idea in general.
In #171 we designed a feature to solve this problem. Basically we allow getting password from external commands. These commands are just strings, except they start with ! (!! is used for escaping the initial !). Commands are allowed in the password fields:
nickserv_identfor NickServ identification passwordpassfor server passwordssasl.passwordfor SASL authentication password
If I have ! pass my_irc_password in a nickserv_ident field, tiny runs pass my_irc_password when the password is needed and uses the output of the command as the password.
(For reading an env variable ! printenv ENV_VAR can be used)
Parking the TUI while running the command (without blocking the thread) can be implemented as we do it for the editor support.
The main difficulties are:
-
What to do in the client while the command is running. The command may ask a master password to the user to unlock the password store, which may take time to enter. Or the user may simply not be in front of the computer when the command is run etc. The client should be handle waiting arbitrarily long while the command is running.
-
How to return the command output to the client.
For (1) I think there are two cases that we need to consider:
-
When
passis a command: to be able to wait arbitrarily long I think we'll have to run the command before actually opening a connection to the server, to avoid timeouts while the server is waiting forPASS. -
When
nickserv_identorsasl.passwordis a command: by the time we need these passwords we already connected to the server. I think we should wait until the command is run and the password is sent to the server before trying to join channels.Note that during this wait the client should run as usual and maintain the connection, by responding to PINGs and sending PINGs to check connectivity, as usual.
(We need to make sure we handle the case where the connection gets lost while waiting for the command output. I think in the design proposed below we don't need to do anything special for this.)
For (2) I propose we add these methods to Client:
pass_value: Provide output of thepasscommand to the client.sasl_pass_value: Same, for SASL passwordnickserv_pass_value: Same, for NickServ password
When pass field is used, when connecting (after a disconnect, or when connecting for the first time) a client will only try to (re)connect when pass_value is called.
When SASL or nickserv_ident is used, after connecting to a server the client will only send JOINs after sasl_pass_value or nickserv_pass_value is called.
(We should probably have some sanity checks in client that makes sure the ..._value methods are called at the right times, e.g. it doesn't make sense to call pass_value if we're already connected, or nickserv_pass_value if we already sent a JOIN message. Those cases are probably bugs that are worth reporting.)
cc @trevarj