[128050] trunk/dports/security/gpg-agent
ionic at macports.org
ionic at macports.org
Tue Nov 11 18:40:08 PST 2014
Revision: 128050
https://trac.macports.org/changeset/128050
Author: ionic at macports.org
Date: 2014-11-11 18:40:07 -0800 (Tue, 11 Nov 2014)
Log Message:
-----------
gpg-agent: add launchd patchset. #43584
Modified Paths:
--------------
trunk/dports/security/gpg-agent/Portfile
Added Paths:
-----------
trunk/dports/security/gpg-agent/files/gpg-agent.plist.default
trunk/dports/security/gpg-agent/files/patch-agent_gpg-agent.c-launchd.diff
Modified: trunk/dports/security/gpg-agent/Portfile
===================================================================
--- trunk/dports/security/gpg-agent/Portfile 2014-11-12 02:28:03 UTC (rev 128049)
+++ trunk/dports/security/gpg-agent/Portfile 2014-11-12 02:40:07 UTC (rev 128050)
@@ -6,6 +6,7 @@
# When updating gpg-agent, update gnupg2 also if applicable.
name gpg-agent
version 2.0.26
+revision 1
categories security mail
maintainers ionic openmaintainer
license GPL-3+
@@ -25,6 +26,11 @@
checksums rmd160 874040ed8fad12067cbe67c8da222b2ad99a5a96 \
sha256 7758e30dc382ae7a7167ed41b7f936aa50af5ea2d6fccdef663b5b750b65b8e0
+startupitem.location \
+ LaunchAgents
+
+set launchd_dir ${prefix}/etc/${startupitem.location}/${startupitem.uniquename}/
+
configure.args --enable-agent-only \
--with-pinentry-pgm=${prefix}/bin/pinentry
@@ -46,11 +52,88 @@
patchfiles patch-po_Makevars.diff
+# DO NOT USE. Maintainer-only helper for debugging purposes. DO NOT USE.
+#configure.cflags-append -g3 -ggdb3 -gdwarf-2 -O0
+
+platform darwin {
+ patchfiles-append patch-agent_gpg-agent.c-launchd.diff
+ configure.cflags-append -F/System/Library/Frameworks/CoreFoundation.framework \
+ -D__APPLE_LAUNCHD__
+
+ if { [tbool startupitem.install] } {
+ notes-append "
+ A startup item has been installed that will aid in
+ starting ${name} with launchd. It is disabled
+ by default. Execute the following command to launch
+ ${name} at user login:
+
+ launchctl load -w /Library/${startupitem.location}/${startupitem.plist}
+
+ To actually start ${name}, log out and back in.
+ "
+ } else {
+ notes-append "
+ A startup item was not installed for ${name}.
+ Some programs which depend on ${name} might not function properly,
+ most notably eMail clients.
+ Execute the following command to launch ${name} at user login:
+
+ launchctl load -w ${launchd_dir}/${startupitem.plist}
+
+ To actually start ${name}, log out and back in.
+ "
+ }
+}
+
+post-extract {
+ xinstall -m 644 -W ${filespath} gpg-agent.plist.default ${worksrcpath}
+}
+
+post-configure {
+ reinplace -W "${worksrcpath}" "s|@PREFIX@|${prefix}|g" gpg-agent.plist.default
+ reinplace -W "${worksrcpath}" "s|@LABEL@|${startupitem.uniquename}|g" gpg-agent.plist.default
+
+ if {${os.platform} eq "darwin"} {
+ reinplace -W "${worksrcpath}" "s|@SSH_SUPPORT@||g" gpg-agent.plist.default
+ }
+}
+
post-destroot {
# Prevent conflict with gnupg2 port.
delete ${destroot}${prefix}/share/doc/gnupg/README
+
+ if {${os.platform} eq "darwin"} {
+ xinstall -m 755 -d \
+ ${destroot}${launchd_dir}
+ xinstall -m 444 \
+ ${worksrcpath}/gpg-agent.plist.default \
+ ${destroot}${launchd_dir}${startupitem.plist}.default
+ }
}
+post-activate {
+ if {${os.platform} eq "darwin"} {
+ xinstall -m 644 \
+ ${launchd_dir}${startupitem.plist}.default \
+ ${launchd_dir}${startupitem.plist}
+
+ # install the plist, if startupitem.install is set
+ if {[tbool startupitem.install]} {
+ ln -sf "${launchd_dir}${startupitem.plist}" "/Library/${startupitem.location}"
+ }
+ }
+}
+
+post-deactivate {
+ if {${os.platform} eq "darwin"} {
+ delete ${launchd_dir}${startupitem.plist}
+
+ if { [tbool startupitem.install] } {
+ delete "/Library/${startupitem.location}/${startupitem.plist}"
+ }
+ }
+}
+
variant no_pinentry description {Do not use pinentry to handle user input} {
depends_lib-delete port:pinentry
configure.args-delete --with-pinentry-pgm=${prefix}/bin/pinentry
Added: trunk/dports/security/gpg-agent/files/gpg-agent.plist.default
===================================================================
--- trunk/dports/security/gpg-agent/files/gpg-agent.plist.default (rev 0)
+++ trunk/dports/security/gpg-agent/files/gpg-agent.plist.default 2014-11-12 02:40:07 UTC (rev 128050)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Label</key>
+ <string>@LABEL@</string>
+
+ <!-- Please uncomment on 10.4; OnDemand doesn't work properly there. -->
+ <!--
+ <key>OnDemand</key>
+ <false />
+ -->
+
+ <key>ProgramArguments</key>
+ <array>
+ <string>@PREFIX@/bin/gpg-agent</string>
+ <string>--write-env-file</string>
+ <string>--no-use-standard-socket</string>
+ <string>--launchd</string>
+ <!-- at SSH_SUPPORT@
+ <string>--enable-ssh-support</string>
+ @SSH_SUPPORT at -->
+ </array>
+
+ <key>RunAtLoad</key>
+ <true/>
+
+ <!-- Restart the job, should it crash. -->
+ <key>KeepAlive</key>
+ <dict>
+ <key>SuccessfulExit</key>
+ <false />
+ </dict>
+
+ <key>ServiceIPC</key>
+ <true/>
+
+ <key>Sockets</key>
+ <dict>
+ <key>Listeners_agent</key>
+ <dict>
+ <key>SecureSocketWithKey</key>
+ <string>GPG_AGENT_INFO</string>
+ </dict>
+
+ <!-- at SSH_SUPPORT@
+ <key>Listeners_ssh</key>
+ <dict>
+ <key>SecureSocketWithKey</key>
+ <string>SSH_AUTH_SOCK</string>
+ </dict>
+ @SSH_SUPPORT at -->
+ </dict>
+</dict>
+</plist>
Added: trunk/dports/security/gpg-agent/files/patch-agent_gpg-agent.c-launchd.diff
===================================================================
--- trunk/dports/security/gpg-agent/files/patch-agent_gpg-agent.c-launchd.diff (rev 0)
+++ trunk/dports/security/gpg-agent/files/patch-agent_gpg-agent.c-launchd.diff 2014-11-12 02:40:07 UTC (rev 128050)
@@ -0,0 +1,392 @@
+--- agent/gpg-agent.c.old
++++ agent/gpg-agent.c
+@@ -47,6 +47,79 @@
+ #include <unistd.h>
+ #include <signal.h>
+ #include <pth.h>
++#ifdef __APPLE_LAUNCHD__
++# include <launch.h>
++
++extern char **environ;
++
++# define GPG_ENV_SOCKET_AGENT "GPG_AGENT_INFO"
++# define GPG_ENV_SOCKET_SSH "SSH_AUTH_SOCK"
++# define GPG_ENV_PID_SSH "SSH_AGENT_PID"
++# define GPG_SOCKET_NAME_AGENT "Listeners_agent"
++# define GPG_SOCKET_NAME_SSH "Listeners_ssh"
++
++# define PASS_ENV_VAR_TO_LAUNCHD(KEY, VALUE) \
++do \
++ { \
++ launch_data_t resp, msg, tmp, tmp_value; \
++ msg = launch_data_alloc (LAUNCH_DATA_DICTIONARY); \
++ tmp = launch_data_alloc (LAUNCH_DATA_DICTIONARY); \
++ \
++ if (!VALUE || !KEY || (strlen (KEY) == 0)) { \
++ log_error ("invalid key or value given: `" #KEY "', `" #VALUE "'.\n"); \
++ exit (1); \
++ } \
++ \
++ char *value_start = strchr (VALUE, '='); \
++ if (!value_start) \
++ value_start = VALUE; \
++ else \
++ ++value_start; \
++ \
++ tmp_value = launch_data_new_string (value_start); /* Skip variable name \
++ * and equal sign */ \
++ launch_data_dict_insert (tmp, tmp_value, KEY); \
++ launch_data_dict_insert (msg, tmp, "SetUserEnvironment"); \
++ \
++ resp = launch_msg (msg); \
++ \
++ if (!resp) { \
++ log_error ("failed to pass environment variable `" KEY "' to launchd: %s\n", \
++ strerror (errno)); \
++ exit (1); \
++ } \
++ launch_data_free (resp); \
++ launch_data_free (msg); /* Do NOT launch_data_free() neither on tmp, nor tmp_value */ \
++ } \
++while (0)
++
++# define REMOVE_ENV_VAR_FROM_LAUNCHD(ENV_VAR_NAME) \
++do \
++ { \
++ launch_data_t resp, msg, tmp; \
++ msg = launch_data_alloc (LAUNCH_DATA_DICTIONARY); \
++ \
++ if (!ENV_VAR_NAME || (strlen (ENV_VAR_NAME) == 0)) { \
++ log_error ("invalid environment variable name given: `" #ENV_VAR_NAME "'.\n"); \
++ exit (1); \
++ } \
++ \
++ tmp = launch_data_new_string (ENV_VAR_NAME); \
++ launch_data_dict_insert (msg, tmp, "UnsetUserEnvironment"); \
++ \
++ resp = launch_msg (msg); \
++ \
++ if (!resp) { \
++ log_error ("failed to remove environment variable `" ENV_VAR_NAME "' from launchd: %s\n", \
++ strerror (errno)); \
++ } \
++ launch_data_free (resp); \
++ launch_data_free (msg); /* Do NOT launch_data_free() on tmp */ \
++ } \
++while (0)
++
++
++#endif // __APPLE_LAUNCHD__
+
+ #define JNLIB_NEED_LOG_LOGV
+ #define JNLIB_NEED_AFLOCAL
+@@ -85,6 +158,9 @@
+ oLogFile,
+ oServer,
+ oDaemon,
++#ifdef __APPLE_LAUNCHD__
++ oLaunchd,
++#endif
+ oBatch,
+
+ oPinentryProgram,
+@@ -133,6 +209,9 @@
+ { 301, NULL, 0, N_("@Options:\n ") },
+
+ { oDaemon, "daemon", 0, N_("run in daemon mode (background)") },
++#ifdef __APPLE_LAUNCHD__
++ { oLaunchd, "launchd", 0, N_("run controlled by launchd (foreground)") },
++#endif
+ { oServer, "server", 0, N_("run in server mode (foreground)") },
+ { oVerbose, "verbose", 0, N_("verbose") },
+ { oQuiet, "quiet", 0, N_("be somewhat more quiet") },
+@@ -475,6 +554,19 @@
+ {
+ remove_socket (socket_name);
+ remove_socket (socket_name_ssh);
++
++#ifdef __APPLE_LAUNCHD__
++ /* Remove environment variables from launchd. */
++ /* launchd handles this. */
++ /*
++ REMOVE_ENV_VAR_FROM_LAUNCHD (GPG_ENV_SOCKET_AGENT);
++
++ if (opt.ssh_support) {
++ REMOVE_ENV_VAR_FROM_LAUNCHD (GPG_ENV_SOCKET_SSH);
++ REMOVE_ENV_VAR_FROM_LAUNCHD (GPG_ENV_PID_SSH);
++ }
++ */
++#endif // __APPLE_LAUNCHD__
+ }
+
+
+@@ -596,6 +688,9 @@
+ int nogreeting = 0;
+ int pipe_server = 0;
+ int is_daemon = 0;
++#ifdef __APPLE_LAUNCHD__
++ int launchd_child = 0;
++#endif
+ int nodetach = 0;
+ int csh_style = 0;
+ char *logfile = NULL;
+@@ -816,6 +911,9 @@
+ case oSh: csh_style = 0; break;
+ case oServer: pipe_server = 1; break;
+ case oDaemon: is_daemon = 1; break;
++#ifdef __APPLE_LAUNCHD__
++ case oLaunchd: launchd_child = 1; break;
++#endif
+
+ case oDisplay: default_display = xstrdup (pargs.r.ret_str); break;
+ case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break;
+@@ -858,6 +956,19 @@
+ default : pargs.err = configfp? 1:2; break;
+ }
+ }
++
++ /* When running under launchd control, only start for real users ie UID >= 500
++ *
++ * Do this check early to avoid filling logs */
++
++#ifdef __APPLE_LAUNCHD__
++ if (launchd_child && geteuid() < 500)
++ {
++ log_error ("launchd only supported for real users - i.e., UID >= 500\n");
++ exit (1);
++ }
++#endif
++
+ if (configfp)
+ {
+ fclose( configfp );
+@@ -983,7 +1094,11 @@
+ /* If this has been called without any options, we merely check
+ whether an agent is already running. We do this here so that we
+ don't clobber a logfile but print it directly to stderr. */
++#ifdef __APPLE_LAUNCHD__
++ if (!pipe_server && !is_daemon && !launchd_child)
++#else
+ if (!pipe_server && !is_daemon)
++#endif
+ {
+ log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
+ check_for_running_agent (0, 0);
+@@ -1045,6 +1160,217 @@
+ agent_deinit_default_ctrl (ctrl);
+ xfree (ctrl);
+ }
++#ifdef __APPLE_LAUNCHD__
++ else if (launchd_child)
++ { /* launchd-compatible mode */
++ gnupg_fd_t fd, fd_ssh = GNUPG_INVALID_FD;
++ pid_t pid;
++
++ /* Remove the DISPLAY variable so that a pinentry does not
++ * default to a specific display. There is still a default
++ * display when gpg-agent was started using --display or a
++ * client requested this using an OPTION command. Note, that we
++ * don't do this when running in reverse daemon mode (i.e. when
++ * exec the program given as arguments). */
++
++ if (!opt.keep_display && !argc)
++ unsetenv ("DISPLAY");
++
++ fflush (NULL);
++ pid = getpid ();
++
++ /* Disable SSH support for good. */
++ opt.ssh_support = 0;
++
++ /* Quick-check to see if SSH support was requested but another application is
++ * providing an SSH auth socket via launchd. */
++ if (opt.ssh_support) {
++ REMOVE_ENV_VAR_FROM_LAUNCHD (GPG_ENV_SOCKET_SSH);
++
++ if (getenv (GPG_ENV_SOCKET_SSH) != NULL) {
++ log_error ("another program is already providing SSH agent support via launchd. "
++ "disabling SSH agent support in gpg-agent.\n");
++ opt.ssh_support = 0;
++ }
++ }
++
++ /* Fetch socket from launchd. */
++ launch_data_t checkin_request, checkin_response;
++
++ /* EHLO launchd */
++ if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL) {
++ log_error ("unable to create launchd checkin string.\n");
++ exit (1);
++ }
++
++ /* any answer */
++ if ((checkin_response = launch_msg (checkin_request)) == NULL) {
++ log_error ("unable to obtain launchd checkin answer.\n");
++ exit (1);
++ }
++
++ /* not 250 :( */
++ if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response)) {
++ int cur_errno = errno;
++ log_error ("launchd checkin failed: %s\n", strerror (cur_errno));
++ exit (1);
++ }
++
++ /* 250 */
++ launch_data_t socket_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
++ if (socket_dict == NULL) {
++ log_error ("no sockets returned by launchd.\n");
++ exit (1);
++ }
++
++ {
++ size_t need_sockets = 1;
++
++ if (opt.ssh_support)
++ ++need_sockets;
++
++ size_t got_sockets = launch_data_dict_get_count (socket_dict);
++
++ if (got_sockets < need_sockets) {
++ log_error ("launchd returned less seconds than necessary. "
++ "needed: %zu, given: %zu.\n", need_sockets, got_sockets);
++ exit (1);
++ }
++
++ if (got_sockets > need_sockets)
++ log_info ("launchd returned more sockets than needed - ignoring extraneous ones.\n");
++
++ /* Fetch FD array. */
++ launch_data_t data_array_agent, data_array_ssh;
++ if ((data_array_agent = launch_data_dict_lookup (socket_dict, GPG_SOCKET_NAME_AGENT)) == NULL) {
++ log_error ("no agent socket defined in launchd plist file.\n");
++ exit (1);
++ }
++
++ if (opt.ssh_support &&
++ ((data_array_ssh = launch_data_dict_lookup (socket_dict, GPG_SOCKET_NAME_SSH)) == NULL)) {
++ log_error ("no ssh socket defined in launchd plist file.\n");
++ exit (1);
++ }
++
++ size_t fd_count_agent, fd_count_ssh;
++ if ((fd_count_agent = launch_data_array_get_count (data_array_agent)) > 1)
++ log_info ("launchd returned more than one file descriptor for the agent socket - ignoring extraneous ones.\n");
++ else if (fd_count_agent == 0) {
++ log_error ("no file descriptor returned for the agent socket.\n");
++ exit (1);
++ }
++ else {
++ launch_data_t cur = launch_data_array_get_index (data_array_agent, 0);
++ fd = launch_data_get_fd (cur);
++ }
++
++ if (opt.ssh_support && ((fd_count_ssh = launch_data_array_get_count (data_array_ssh)) > 1))
++ log_info ("launchd returned more than one file descriptor for the ssh socket - ignoring extraneous ones.\n");
++ else if (opt.ssh_support && (fd_count_ssh == 0)) {
++ log_error ("no file descriptor returned for the ssh socket.\n");
++ exit (1);
++ }
++ else if (opt.ssh_support) {
++ launch_data_t cur = launch_data_array_get_index (data_array_ssh, 0);
++ fd_ssh = launch_data_get_fd (cur);
++ }
++ }
++
++ char *gpg_socket = getenv (GPG_ENV_SOCKET_AGENT);
++ if (!gpg_socket) {
++ log_error ("no agent socket environment variable defined by launchd.\n");
++ exit (1);
++ }
++
++ char *ssh_socket = getenv (GPG_ENV_SOCKET_SSH);
++ if (opt.ssh_support && !ssh_socket) {
++ log_error ("no ssh socket environment variable defined by launchd.\n");
++ exit (1);
++ }
++
++ socket_name = strndup (gpg_socket, strlen (gpg_socket));
++ if (opt.ssh_support)
++ socket_name_ssh = strndup (ssh_socket, strlen (ssh_socket));
++
++ /* Remove internal environment variables from launchd. */
++ /* launchd handles this. */
++ /*
++ REMOVE_ENV_VAR_FROM_LAUNCHD (GPG_ENV_SOCKET_AGENT);
++ if (opt.ssh_support)
++ REMOVE_ENV_VAR_FROM_LAUNCHD (GPG_ENV_SOCKET_SSH);
++ */
++
++ launch_data_free (checkin_response);
++ launch_data_free (checkin_request);
++
++ char *infostr, *infostr_ssh_sock, *infostr_ssh_pid;
++
++ /* Create the info string: <name>:<pid>:<protocol_version> */
++ if (asprintf (&infostr, GPG_ENV_SOCKET_AGENT "=%s:%lu:1",
++ socket_name, (ulong)pid ) < 0) {
++ log_error ("out of core\n");
++ kill (pid, SIGTERM);
++ exit (1);
++ }
++
++ if (opt.ssh_support) {
++ if (asprintf (&infostr_ssh_sock, GPG_ENV_SOCKET_SSH "=%s",
++ socket_name_ssh) < 0) {
++ log_error ("out of core\n");
++ exit (1);
++ }
++ if (asprintf (&infostr_ssh_pid, GPG_ENV_PID_SSH "=%u",
++ pid) < 0) {
++ log_error ("out of core\n");
++ exit (1);
++ }
++ }
++
++ if (env_file_name) {
++ FILE *fp;
++
++ fp = fopen (env_file_name, "w");
++ if (!fp)
++ log_error (_("error creating `%s': %s\n"),
++ env_file_name, strerror (errno));
++ else {
++ fputs (infostr, fp);
++ putc ('\n', fp);
++
++ if (opt.ssh_support) {
++ fputs (infostr_ssh_sock, fp);
++ putc ('\n', fp);
++ fputs (infostr_ssh_pid, fp);
++ putc ('\n', fp);
++ }
++
++ fclose (fp);
++ }
++ }
++
++ /* Pass environment variables back to launchd. */
++ /* launchd handles this. */
++ /* PASS_ENV_VAR_TO_LAUNCHD (GPG_ENV_SOCKET_AGENT, infostr);
++
++ if (opt.ssh_support) {
++ PASS_ENV_VAR_TO_LAUNCHD (GPG_ENV_SOCKET_SSH, infostr_ssh_sock);
++ PASS_ENV_VAR_TO_LAUNCHD (GPG_ENV_PID_SSH, infostr_ssh_pid);
++ }
++ */
++
++ {
++ struct sigaction sa;
++
++ sa.sa_handler = SIG_IGN;
++ sigemptyset (&sa.sa_mask);
++ sa.sa_flags = 0;
++ sigaction (SIGPIPE, &sa, NULL);
++ }
++
++ handle_connections (fd, fd_ssh);
++ }
++#endif // __APPLE_LAUNCHD__
+ else if (!is_daemon)
+ ; /* NOTREACHED */
+ else
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20141111/0b3c87dc/attachment-0001.html>
More information about the macports-changes
mailing list