This repository presents a single script which is intended to aid in setting the pin entry program correctly on both Linux and macOS.
The idea for this script was stimulated by the discussion at Dr Duh YubiKey-Guide: Issue 504.
If the script is running on macOS and the user selects the pinentry-mac program, the script also installs both a run-at-load LaunchAgent and a complementary delegate (shell script) which performs basic error checking before taking any possibly destructive actions. The delegate also maintains a log of its activities so that the user has somewhere to start if it detects problems.
The launch agent and delegate replace the functionality of the pair of launch agents described at:
-
Clone this repository from GitHub:
$ git clone https://github.com/Paraphraser/set-gpg-pinentry-program.git -
Make the clone your working directory
$ cd set-gpg-pinentry-program
When you run the script without any arguments, it displays a list of pinentry programs that are available on your system. Example:
$ ./set-gpg-pinentry-program.sh
Usage: set-gpg-pinentry-program.sh { curses | gnome3 | mac | tty | x11 }When you run the script with a valid target, it activates the associated pinentry- program. Example:
$ ./set-gpg-pinentry-program.sh curses
Activated pinentry-program /usr/bin/pinentry-cursesThe script edits ~/.gnupg/gpg-agent.conf as follows:
- Disables (comments-out) any pre-existing
pinentry-programdirectives which were active; then - Searches for and activates any inactive (ie commented-out) form of the
pinentry-programyou wish to activate; but - If step 2 was unsuccessful (ie the search failed because
gpg-agent.confdid not contain an inactive form), appends an appropriatepinentry-programdirective to the file.
Changes to ~/.gnupg/gpg-agent.conf are propagated by invoking:
$ gpgconf --reload gpg-agentTesting suggests this is more reliable than
gpg-connect-agent reloadagent /bye.
You can use grep to confirm the active choice. For example:
$ grep '^pinentry-program' ~/.gnupg/gpg-agent.conf
pinentry-program /usr/bin/pinentry-cursesWhen running on macOS:
-
The script checks whether the following "launch agents" are installed:
~/Library/LaunchAgents/gnupg.gpg-agent.plist ~/Library/LaunchAgents/gnupg.gpg-agent-symlink.plistIf found, the agents are deactivated and removed.
Those property lists are mentioned at SSH in the Dr Duh YubiKey-Guide.
-
If
pinentry-macis being made active, the script:-
Installs a "delegate" (shell script) at the path:
~/.gnupg/gnupg.gpg-agent-pinentry-mac-delegate.sh -
Installs a "launch agent" (property list) at the path:
~/Library/LaunchAgents/gnupg.gpg-agent-pinentry-mac.plist
The launch agent runs each time you login to your macOS desktop (ie not via SSH). The agent executes the delegate which performs some sanity-checking, after which it creates the "glue" so that the
pinentry-macprogram can run successfully.The combination of launch agent and delegate has the same overall effect as the older launch agent pairing of
gnupg.gpg-agent.plistwithgnupg.gpg-agent-symlink.plistbut is generally safer and more robust. -
If the delegate encounters any problems, it writes log entries to the path:
~/.gnupg/gnupg.gpg-agent-pinentry-mac-delegate.sh.log
You should check that log if pinentry-mac does not seem to be working. The possible messages are:
-
SSH_AUTH_SOCK is undefined (symbolic link can't be created)During a reboot, the environment variable
SSH_AUTH_SOCKis normally initialised with a value like the following, which is a path to a socket:/private/tmp/com.apple.launchd.«randomValue»/ListenersIf something prevents that socket from being created,
SSH_AUTH_SOCKwill be undefined and, accordingly, it will not be available to the delegate. Restarting your Mac should cure this problem.Note:
-
You can check
SSH_AUTH_SOCKyourself like this:$ echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"This command must be executed in a Terminal session running directly on the Mac. You can't run this command remotely via SSH (you will always get a null answer).
-
-
/Users/«user»/.gnupg/S.gpg-agent.ssh exists but is not a socketThe file
~/.gnupg/S.gpg-agent.sshis expected to exist and be a socket when the delegate runs. This error indicates that the file exists but is not of the expected type. You can confirm this by running:$ ls -l ~/.gnupg/S.gpg-agent.ssh srwx------ 1 moi staff 0 Jun 12 11:44 ~/.gnupg/S.gpg-agent.ssh
The leading
sinsrwxindicates that a file is a socket. It is an error if that first character is anything other thans, such as-(regular file) orl(symbolic link). Although the error message refers to a single file, it is often indicative of a wider problem. It is better to re-initialise the sub-system by removing all sockets and then re-run the delegate by hand, like this:$ cd ~/.gnupg/ $ rm S.gpg-agent* $ ./gnupg.gpg-agent-pinentry-mac-delegate.sh $
In this situation, the delegate writes errors to the console rather than the log file so "silence" means "success".
-
/Users/«user»/.gnupg/S.gpg-agent.ssh does not existThe most likely cause of this problem is that one of the other socket files exists but is not actually a socket. An error with any one of the sockets seems to prevent the creation of the full cohort of sockets. The solution here is the same as for the previous error: remove all the socket files and re-run the delegate. A system restart may also be helpful.
Although it is not strictly necessary the delegate is code-signed. You can think of this as "future proofing" against the day when GateKeeper becomes even more restrictive about what you can run on your own Mac.
The default is to use a so-called "ad-hoc" signature, which means it will be marked as "from an unidentified developer" in:
If you have the necessary certificate in your keychain, you can use your own code-signing identity instead. To see if you have any valid identities, run:
$ security find-identity -v -p codesigningIdentities are displayed as a list with a «sequence») «hexID» "«name»" format, like this:
1) 0123456789ABCDEF0123456789ABCDEF01234567 "certificate 1 name"
2) 76543210FEDCBA9876543210FEDCBA9876543210 "certificate 2 name"
...
You can use any of those fields to indicate which identity to use. In the following example, all three commands refer to the same certificate:
$ CODESIGN="1" ./set-gpg-pinentry-program.sh mac
$ CODESIGN="0123456789ABCDEF0123456789ABCDEF01234567" ./set-gpg-pinentry-program.sh mac
$ CODESIGN="certificate 1 name" ./set-gpg-pinentry-program.sh macWhen signed with your own certificate, System Settings groups the delegate together with any other items signed by the same certificate.
| Command Line Interface | Graphical User Interface |
|---|---|
| pinentry-tty | pinentry-mac |
![]() |
![]() |
| pinentry-curses | pinentry-gnome3 |
![]() |
![]() |




