systemd 12 and newer support lightweight password agents which can be used to query the user for system-level passwords or passphrases. These are passphrases that are not related to a specific user, but to some kind of hardware or service. Right now this is used exclusively for encrypted hard-disk passphrases but later on this is likely to be used to query passphrases of SSL certificates at Apache startup time as well. The basic idea is that a system component requesting a password entry can simply drop a simple .ini-style file into
/run/systemd/ask-password which multiple different agents may watch via
inotify(), and query the user as necessary. The answer is then sent back to the querier via an
SOCK_DGRAM socket. Multiple agents might be running at the same time in which case they all should query the user and the agent which answers first wins. Right now systemd ships with the following passphrase agents:
wall(1)agent which sends wall messages as soon as a password shall be entered.
systemctl start” (and similar commands) and asks passwords to the user during manual startup of a service
It is easy to write additional agents. The basic algorithm to follow looks like this:
ask.xxxx” shows up, read it. It’s a simple
.inifile that may be parsed with the usual parsers. The
xxxxsuffix is randomized.
.inifile keys in those files, so that we can easily extend the format later on.
Message=field in the
[Ask]section. It is a single-line string in UTF-8, which might be internationalized (by the party that originally asks the question, not by the agent).
Icon=field in the
PID=field in the
[Ask]section (Before asking your question use
kill(PID, 0)and ignore the file if this returns
ESRCH; there’s no need to show the data of this field but if you want to you may)
Echo=specifies whether the input should be obscured. If this field is missing or is
Echo=0, the input should not be shown.
[Ask]section. It is a
SOCK_DGRAMsocket in the file system.
NotAfter=field in the
[Ask]section is in the past. The time is specified in usecs, and refers to the
0, no such check should take place.
ask.xxxxfile is deleted, watch this with inotify. b) the
NotAfter=time elapses, if it is set
/usr/bin/pkexec /lib/systemd/systemd-reply-password 1 /path/to/socket” or “
/usr/bin/pkexec /lib/systemd/systemd-reply-password 0 /path/to/socket” and writing the password to its standard input. Use ‘
1’ as argument if a password was entered by the user, or ‘
0’ if the user canceled the request.
+” or with “
-” depending on whether the password entry was successful or not. You may but don’t have to include a final
NULbyte in your message.
Again, it is essential that you stop showing the password box/notification/status icon if the
ask.xxx file is removed or when
NotAfter= elapses (if it is set
It may happen that multiple password entries are pending at the same time. Your agent needs to be able to deal with that. Depending on your environment you may either choose to show all outstanding passwords at the same time or instead only one and as soon as the user has replied to that one go on to the next one.
You may test this all with manually invoking the “
systemd-ask-password” tool on the command line. Pass
--no-tty to ensure the password is asked via the agent system. Note that only privileged users may use this tool (after all this is intended purely for system-level passwords).
If you write a system level agent a smart way to activate it is using systemd
.path units. This will ensure that systemd will watch the
/run/systemd/ask-password directory and spawn the agent as soon as that directory becomes non-empty. In fact, the console, wall and Plymouth agents are started like this. If systemd is used to maintain user sessions as well you can use a similar scheme to automatically spawn your user password agent as well. (As of this moment we have not switched any DE over to use systemd for session management, however.)