~sircmpwn/himitsu

58972fea6dadf87521f0030a296025693059fe07 — Drew DeVault 3 months ago d57dd69
Finish man pages
5 files changed, 370 insertions(+), 208 deletions(-)

M Makefile
A docs/himitsu-ipc.5.scd
A docs/himitsu-prompter.5.scd
A docs/himitsu.ini.5.scd
D docs/prompter.txt
M Makefile => Makefile +19 -9
@@ 27,16 27,16 @@ check:
	hare test

DOCS=\
     himitsu.7 \
     himitsud.1 \
     himitsu-init.1 \
     hiq.1
     hiq.1 \
     himitsu.ini.5 \
     himitsu-ipc.5 \
     himitsu-prompter.5 \
     himitsu.7

docs: $(DOCS)

himitsu.7: docs/himitsu.7.scd
	$(SCDOC) <$< >$@

himitsud.1: docs/himitsud.1.scd
	$(SCDOC) <$< >$@



@@ 46,10 46,17 @@ himitsu-init.1: docs/himitsu-init.1.scd
hiq.1: docs/hiq.1.scd
	$(SCDOC) <$< >$@

# TODO:
# himitsu-ipc(5)
# himitsu-prompter(5)
# himitsu.ini(5)
himitsu.ini.5: docs/himitsu.ini.5.scd
	$(SCDOC) <$< >$@

himitsu-ipc.5: docs/himitsu-ipc.5.scd
	$(SCDOC) <$< >$@

himitsu-prompter.5: docs/himitsu-prompter.5.scd
	$(SCDOC) <$< >$@

himitsu.7: docs/himitsu.7.scd
	$(SCDOC) <$< >$@

clean:
	rm -f himitsud himitsu-init hiq


@@ 67,6 74,9 @@ install:
	install -m644 himitsud.1 $(DESTDIR)$(MANDIR)/man1/himitsud.1
	install -m644 himitsu-init.1 $(DESTDIR)$(MANDIR)/man1/himitsu-init.1
	install -m644 hiq.1 $(DESTDIR)$(MANDIR)/man1/hiq.1
	install -m644 himitsu.ini.5 $(DESTDIR)$(MANDIR)/man5/himitsu.ini.5
	install -m644 himitsu-ipc.5 $(DESTDIR)$(MANDIR)/man5/himitsu-ipc.5
	install -m644 himitsu-prompter.5 $(DESTDIR)$(MANDIR)/man5/himitsu-prompter.5
	install -m644 himitsu.7 $(DESTDIR)$(MANDIR)/man7/himitsu.7

uninstall:

A docs/himitsu-ipc.5.scd => docs/himitsu-ipc.5.scd +101 -0
@@ 0,0 1,101 @@
himitsu-ipc(5)

# NAME

*himitsu-ipc*(5) - IPC protocol implemented by *himitsud*(1)

# DESCRIPTION

The Himitsu IPC protocol is a line-oriented text protocol using the UTF-8
encoding and LF line endings. It is transmitted over a Unix socket which is
located at $XDG_RUNTIME_DIR/himitsu.

Interactions with this interface are command/reply oriented, with commands
initiated by the client and replies sent by the server. Both commands and
replies have the same semantic structure. Each begins with a command word (an
alphanumeric string) which defines the operation requested. There may or may not
be additional arguments provided. If there are no additional arguments the
command word is immediately followed by LF. Otherwise, following the command
word is a space, then a sequence of arbitrary printable UTF-8 characters until
the line terminator is reached. The structure of the argument string depends on
the command word.

This man page assumes knowledge of the *KEY FORMAT* and *QUERY SYNTAX* described
in *himitsu*(7). Note also that commands which accept flags process them in a
manner compatible with *getopt*(3).

All commands are subject to a significant delay before the reply while the user
is prompted to provide consent or to unlock the keyring.

# COMMANDS

The following commands are recognized by the server:

*add* _key_...
	Adds a new _key_ to the key store. The server will send a *key* reply
	echoing the new key (without secrets), followed by an *end* reply.

*del* _query_...
	Removes keys from the key store which match the provided _query_. The
	user will be prompted to consent to this operation. The server will send
	a *key* reply for each deleted key (without secrets), followed by an
	*end* reply.

*query* [-d] _query_...
	Queries the key store for keys matching the provided _query_. Matching
	keys are returned via a series of *key* replies, terminated with an
	*end* reply to signal the end of the list. If the -d option is provided,
	the private values will be decrypted after requesting user consent.

*quit*
	Requests that the daemon terminate itself. This command is only
	recognized if *himitsud*(1) was started with the -D flag. No reply is
	sent.

# REPLIES

The following replies are sent to the client:

*key* _key_...
	Provides a single key store entry to the user.

*end*
	Signals the end of a list of *key* replies.

*error* _message_...
	Indicates that a requested operation resulted in an error. The _message_
	is both human-friendly and consistent, such that it can be displayed to
	the user or matched against an internal database of semantic error
	strings in the client.

# EXAMPLE SESSION

An example session, with *<=* indicating messages from the server to the client,
and *=>* vice-versa. Any of the commands may be separated from their replies by
several seconds while the user interacts with the prompter.

```
=> query proto=web
<= key proto=web host=a.example.org user=jdoe password!
<= key proto=web host=b.example.org user=jdoe password!
<= key proto=web host=c.example.org user=jdoe password!
<= key proto=web host=d.example.org user=jdoe password!
<= end
=> add proto=web host=e.example.org user=jdoe password!=hunter2
<= key proto=web host=e.example.org user=jdoe password!
<= end
=> query -d proto=web host=e.example.org
=> key proto=web host=e.example.org user=jdoe password!=hunter2
<= end
```

# SEE ALSO

*himitsu*(7)

# AUTHORS

Maintained by Drew DeVault <sir@cmpwn.com>, who is assited by other
contributors. Up-to-date source code can be found at
https://git.sr.ht/~sircmpwn/himitsu, and bugs/patches can be submitted by email
to ~sircmpwn/himitsu-devel@lists.sr.ht.

A docs/himitsu-prompter.5.scd => docs/himitsu-prompter.5.scd +206 -0
@@ 0,0 1,206 @@
himitsu-prompter(5)

# NAME

*himitsu-prompter* - Protocol used for the *himitsu*(7) prompter

# DESCRIPTION

*himitsud*(1) will invoke the user-configured prompter program in order to
interactively obtain information from the user, such as the password to unlock
the keyring, or consent to the use of a secret key. The prompter may use
whatever means is appropriate to the host environment to obtain this
information, such as using a system-specific UI toolkit.

The prompter is executed by *himitsud*(1) and communicates with the daemon over
the _stdin_ and _stdout_ file descriptors. The protocol is a series of
line-oriented commands and replies encoded as UTF-8 text with LF terminators.
Commands are sent from the daemon to the prompter via _stdin_ and the prompter
writes replies to _stdout_.

Both commands and replies have the same semantic structure. Each begins with a
command word (an alphanumeric string) which defines the operation requested.
There may or may not be additional arguments provided. If there are no
additional arguments the command word is immediately followed by LF. Otherwise,
following the command word is a space, then a sequence of arbitrary printable
UTF-8 characters until the line terminator is reached. The structure of the
argument string depends on the command word.

In this document, examples are provided with the convention that *=>* indicates
messages from the daemon to the prompter via _stdin_, and *<=* vice-versa via
_stdout_.

## HANDSHAKE

The first message the daemon sends is the version command, which identifies the
protocol version in use by the daemon and requests the protocol version in use
by the client. The version number follows the word "version" in the reply, and
is a series of three integers separated by dots ('.'), indicating respectively
the major, minor, and patch version of the protocol.

```
=> version
<= version 1.0.0
```

The protocol number uses semantic versioning to determine compatibility between
different versions of the daemon and prompter. The daemon will determine at its
discretion if this protocol version is suitable, and if so, proceed to issue
additional commands; if not, it will close stdin and the prompter should exit
with status code 1.

The current protocol number is 0.0.0.

## EXIT STATUS

The prompter's exit status is semantically meaningful. The exit status is
interpreted by the daemon as follows:

|[ 0
:< The user consented to the operation
|  1
:  The user did not consent to the operation
|  2-126
:  Reserved for future use
|  127
:  An internal error occured with the prompter

## COMMANDS

The following commands are sent from the daemon to the prompter via _stdin_.

*key* _key_...
	Provides a key to the prompter which is related to this transaction, in
	the format described by *KEY FORMAT* in *himitsu*(7).

*password* correct|incorrect
	Provides feedback in response to the *password* reply sent from the
	prompter to the daemon. Note that following the *password* reply from
	the prompter, there may be a substantial delay while the password is
	verified. The prompter is encouraged to display some kind of indication
	to the user that this process is underway.

*prompt* disclose|delete
	Sent when the prompter should obtain consent from the user for the
	desired operation, specified by the given parameter. Preceeding this
	command will be one or more *key* commands describing the keys
	implicated in this operation.

	- *disclose*: the specified keys will be disclosed to the client,
	  including secret values.
	- *delete*: the specified keys will be removed from the key store

	Following this command, the daemon will close _stdin_ and will wait for
	the prompter to exit with a meaningful status code as described by *EXIT
	STATUS* above.

*unlock*
	The daemon will send this command when the user must unlock the keyring
	before proceeding. The keyring may be in one of three states:

	- hard locked: all key/value pairs are encrypted
	- soft locked: only secret values are encrypted
	- unlocked: the keyring is fully unlocked

	The keyring is hard locked on startup. In this state, the user cannot
	perform any queries before entering their password. If the prompter
	receives an *unlock* command before any *key* or *prompt* commands are
	sent, the keyring is in this state. The prompter should present the
	unlock UI and send *password* commands until the daemon replies with
	*password correct*. Following this, the keyring will enter the unlocked
	state. If no other operations are required, stdin will be closed after
	*password correct* is sent. However, if a query is pending, the daemon
	will continue normally, sending *key* commands and a *prompt* command to
	complete the desired operation.

	The soft locked mode is entered after the user's configured keyring
	timeout expires. The encryption keys are unloaded from RAM, but the
	decrypted key/value pairs are kept. Queries which do not request
	decryption may proceed normally in this state. However, if decryption of
	secret values is requested, the keyring must be unlocked first. In this
	state, the daemon will send one or more *key* commands, followed by the
	*unlock* command, followed by the *prompt* command. The daemon may
	choose to implement a different unlocking UI in this mode, for instance
	to allow the user to both unlock and consent in a single UI action.

	In either situation, if the user declines to unlock the keyring, the
	prompter should exit with status code 1.

*version*
	See *HANDSHAKE* above.

## REPLIES

The following replies are sent from the prompter to the daemon via _stdout_:

*password* _password_...
	The password reply is sent in response to the *unlock* command after
	the user provides a suitable password. The daemon will send a *password*
	command with feedback on the outcome; see the description of the
	*unlock* command for details. The password itself may contain only
	printable UTF-8 characters.

	Note that the password verification process may require several seconds
	to complete. The prompter implementation is encouraged to provide
	feedback to the user to indicate that the operation is underway.

*version* _major_._minor_._patch_
	See *HANDSHAKE* above.

# EXAMPLES

Scenario 1: the keyring is hard locked and the daemon wishes to unlock it.

```
=> version
<= version 0.0.0
=> unlock
=> prompt unlock
<= password hunter3
=> password incorrect
<= password hunter2
=> password correct
(daemon closes stdin)
(prompter exits with status code 0)
```

Scenario 2: the keyring is unlocked and a client would like to view the user's
secret keys.

```
=> version
<= version 0.0.0
=> key proto=web host=example.org user=jdoe password!
=> key proto=web host=example.com user=jdoe password!
=> prompt disclose
(daemon closes stdin)
```

Scenario 3: the keyring is hard locked and a client would like to view the
user's secret keys.

```
=> version
<= version 0.0.0
=> unlock
<= password hunter1
=> password incorrect
<= password hunter2
=> password correct
=> key proto=web host=example.org user=jdoe password!
=> key proto=web host=example.com user=jdoe password!
=> prompt disclose
(daemon closes stdin)
(prompter exits with status code 0)
```

# SEE ALSO

*himitsu*(7)

# AUTHORS

Maintained by Drew DeVault <sir@cmpwn.com>, who is assited by other
contributors. Up-to-date source code can be found at
https://git.sr.ht/~sircmpwn/himitsu, and bugs/patches can be submitted by email
to ~sircmpwn/himitsu-devel@lists.sr.ht.

A docs/himitsu.ini.5.scd => docs/himitsu.ini.5.scd +44 -0
@@ 0,0 1,44 @@
himitsu.ini(5)

# NAME

*himitsu.ini* - configuration file for *himitsu*(7)

# FILE FORMAT

The Himitsu configuration file is an INI file. Each set of options is grouped
into sections, which are indicated by the section name surrounded by square
brackets (e.g. [himitsud]) on a line. Following each section, a set of key/value
pairs belonging to that section are provided. The keys are separated from the
values by an equal symbol (*=*).

The default configuration file is installed by *himitsu-init*(1).

# APPLICATION USAGE

The set of configuration parameters recognized by the Himitsu distrubtion are
specified below. Third-party software providing Himitsu integrations are
encouraged to configure themselves using this file. Any sections or keys which
are not understood by any particular application will be disregarded.

## HIMITSUD

*himitsud*(1)-related options are placed into the [himitsud] section. The
available options are:

*prompter*
	Configure the path to the prompter executable which will be used to
	interact with the user for consent requests and key store unlock
	operations. See *himitsu-prompter*(5) for a description of the protocol
	which should be implemented by this executable.

# SEE ALSO

*himitsu*(7)

# AUTHORS

Maintained by Drew DeVault <sir@cmpwn.com>, who is assited by other
contributors. Up-to-date source code can be found at
https://git.sr.ht/~sircmpwn/himitsu, and bugs/patches can be submitted by email
to ~sircmpwn/himitsu-devel@lists.sr.ht.

D docs/prompter.txt => docs/prompter.txt +0 -199
@@ 1,199 0,0 @@
			   Himitsu prompter protocol

The prompter is used to interactively prompt the user to provide information or
to consent to a privileged operation. The prompter is an arbitrary command which
is executed by the Himitsu daemon, and the two parties communicate over the
prompter's stdin and stdout file descriptors.

The protocol is a series of line-oriented (LF) commands and replies in UTF-8,
where commands are sent to the prompter via stdin and the prompter sends replies
back via stdout. Each command or reply begins with the name of the message (e.g.
"unlock"), optionally followed by a space and additonal data in a format
specific to each message type.

				  Conventions

In this document, examples of prompter sessions are indented. Commands from the
daemon to the prompter are prefixed with "=> ", and replies from the prompter to
the daemon are prefixed with "<= ".

				   Handshake

The first message the daemon sends is the version command, which identifies the
protocol version in use by the daemon and requests the protocol version in use
by the client. The version number follows the word "version" in the reply, and
is a series of three integers separated by dots ('.'), indicating respectively
the major, minor, and patch version of the protocol.

	=> version
	<= version 1.0.0

The protocol number uses semantic versioning to determine compatibility between
different versions of the daemon and prompter. The daemon will determine at its
discretion if this protocol version is suitable, and if so, proceed to issue
additional commands; if not, it will close stdin and the prompter should exit
with status code 1.

The current protocol number is 0.0.0.

			       Prompting process

The process is as follows:

1. The prompter is executed by the daemon
2. The handshake is performed
3. One or more "informative" commands are sent
4. The "prompt" command is sent
5. The prompter presents itself to the user and sends replies as appropriate
6. The prompter exits with a meaningful status code

The "informative" commands provide details, such as keys being requested, for
the prompter to display to the user. Following this, the "prompt" command causes
the interactive portion of this process to begin. During this process, the
prompter may gather additional information from the user (such as their keyring
password), but in all cases will determine if the user consents or does not
consent to the operation being performed. After gathering any required
information, the prompter shall exit with a status code indicating one of the
following conditions:

	0	The user consented to the operation
	1 	User did not consent to the operation
	2-126	Reserved for future use
	127	An internal error occured with the prompter

The daemon will close stdin when it is done sending commands.

				   Key format

A Himitsu key is made up of one or more key/value pairs. Each pair is separated
by one space ('\x20'). Each pair contains a key, which is a string matching the
POSIX Extended Regular Expression /^[-_A-Za-z]+$/. Optionally, following the key
may be a '!' character, indicating that the key stores a secret value, and '?',
indicating that a value is optional.

Following the key shall be an optional value, consisting of an '=' symbol to
separate it from the key, followed by the value itself. The value may contain
arbitrary printable UTF-8 characters, written according to shell quoting rules,
such that a space may appear in the value if it is surrounded by quotes.

				    Commands

key <key...>

The daemon may provide zero or more keys which are associated with the current
operation via the "key" command. Following the command name shall be a key
represented in the key format above.

password <correct|incorrect>

Provides feedback on the user's password attempt. If "incorrect", the prompter
should ask the user to retry.

version

The daemon sends this command to request protocol version information from the
client.

prompt <params...>

The prompt command indicates that no further informative commands will follow,
and the prompter should present itself to the user and begin sending replies
according to their input. The provided parameters indicate which of several
consequences will occur if the user consents, selected from the following list:

- disclose: the user's encrypted keys will be disclosed to the client if they
  consent to this operation
- delete: the user's keys will be deleted from the store if they consent to this
  operation

unlock

The daemon will send this command when the user must unlock the keyring before
proceeding. The keyring may be in one of three states:

- hard locked: all key/value pairs are encrypted
- soft locked: only secret values are encrypted
- unlocked: the keyring is fully unlocked

The keyring is hard locked on startup. In this state, the user cannot perform
any queries before entering their password. If the prompter receives an "unlock"
command before any "key" or "prompt" commands are sent, the keyring is in this
state. The prompter should present the unlock UI and send "password" commands
until the daemon replies with "password correct". Following this, the keyring
will enter the unlocked state. If no other operations are required, stdin will
be closed after "password correct" is sent. However, if a query is pending, the
daemon will continue normally, sending "key" commands and a "prompt" command to
complete the desired operation.

The soft locked mode is entered after the user's configured keyring timeout
expires. The encryption keys are unloaded from RAM, but the decrypted key/value
pairs are kept. Queries which do not request decryption may proceed normally in
this state. However, if decryption of secret values is requested, the keyring
must be unlocked first. In this state, the daemon will send one or more "key"
commands, followed by the "unlock" command, followed by the "prompt" command.
The daemon may choose to implement a different unlocking UI in this mode, for
instance to allow the user to both unlock and consent in a single UI action.

In either situation, if the user declines to unlock the keyring, the prompter
should exit with status code 1.

				    Replies

password <password...>

The password reply is given in response to the "unlock" command after the user
provides a suitable password. The password will be verified by the daemon, which
may take some time - the prompter should display some kind of progress indicator
while this is being done. Following this, the daemon will either send the
"incorrect-password" message, or will close stdin. The password is appended to
the reply string following "password " and may contain only printable UTF-8
characters.

version <major.minor.patch>

The client replies to the prompter's request for version information with this
reply as described in the "Handshake" section above.

				    Examples

Scenario 1: the keyring is locked, and the daemon wishes to unlock it.

	=> version
	<= version 0.0.0
	=> unlock
	=> prompt unlock
	<= password hunter3
	=> incorrect-password
	<= password hunter2
	=> correct-password
	(daemon closes stdin)
	(prompter exits with status code 0)

Scenario 2: the keyring is unlocked and a client would like to view the user's
secret keys.

	=> version
	<= version 0.0.0
	=> key proto=web host=example.org user=jdoe password! comment?
	=> key proto=web host=example.com user=jdoe password! comment?="business account"
	=> prompt disclose 
	(daemon closes stdin)

The prompter should show the user these keys, explain that the secret keys
(password, in this case) will be disclosed to a third-party application, and
request their consent. If provided, it shall exit with status code 0; if not,
status code 1.

Scenario 3: the keyring is locked and a client would like to view the user's
secret keys.

	=> version
	<= version 0.0.0
	=> key proto=web host=example.org user=jdoe password! comment?
	=> key proto=web host=example.com user=jdoe password! comment?="business account"
	=> unlock
	=> prompt disclose unlock
	<= password hunter2
	=> correct-password
	(daemon closes stdin)
	(prompter exits with status code 0)