Skip to content

Instantly share code, notes, and snippets.

@jryans
Last active October 17, 2015 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jryans/2488ca4ab2bc9b4eeb54 to your computer and use it in GitHub Desktop.
Save jryans/2488ca4ab2bc9b4eeb54 to your computer and use it in GitHub Desktop.
Allow OpenSSH to run as a launch agent
diff --git a/ssh-agent.c b/ssh-agent.c
index a335ea3..594cb8a 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -71,6 +71,9 @@
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
+#ifdef __APPLE__
+# include <launch.h>
+#endif
#include "xmalloc.h"
#include "ssh.h"
@@ -1172,7 +1175,11 @@ usage(void)
int
main(int ac, char **av)
{
+#ifdef __APPLE__
+ int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0, l_flag = 0;
+#else
int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
+#endif
int sock, fd, ch, result, saved_errno;
u_int nalloc;
char *shell, *format, *pidstr, *agentsocket = NULL;
@@ -1207,7 +1214,11 @@ main(int ac, char **av)
__progname = ssh_get_progname(av[0]);
seed_rng();
+#ifdef __APPLE__
+ while ((ch = getopt(ac, av, "cDdklsE:a:t:")) != -1) {
+#else
while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) {
+#endif
switch (ch) {
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1222,6 +1233,11 @@ main(int ac, char **av)
case 'k':
k_flag++;
break;
+#ifdef __APPLE__
+ case 'l':
+ l_flag++;
+ break;
+#endif
case 's':
if (c_flag)
usage();
@@ -1253,7 +1269,11 @@ main(int ac, char **av)
ac -= optind;
av += optind;
+#ifdef __APPLE__
+ if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag || l_flag))
+#else
if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
+#endif
usage();
if (ac == 0 && !c_flag && !s_flag) {
@@ -1309,6 +1329,53 @@ main(int ac, char **av)
* Create socket early so it will exist before command gets run from
* the parent.
*/
+#ifdef __APPLE__
+ if (l_flag) {
+ launch_data_t resp, msg, tmp;
+ size_t listeners_i;
+
+ msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
+
+ resp = launch_msg(msg);
+
+ if (NULL == resp) {
+ perror("launch_msg");
+ exit(1);
+ }
+ launch_data_free(msg);
+ switch (launch_data_get_type(resp)) {
+ case LAUNCH_DATA_ERRNO:
+ errno = launch_data_get_errno(resp);
+ perror("launch_msg response");
+ exit(1);
+ case LAUNCH_DATA_DICTIONARY:
+ break;
+ default:
+ fprintf(stderr, "launch_msg unknown response");
+ exit(1);
+ }
+ tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS);
+
+ if (NULL == tmp) {
+ fprintf(stderr, "no sockets\n");
+ exit(1);
+ }
+
+ tmp = launch_data_dict_lookup(tmp, "Listeners");
+
+ if (NULL == tmp) {
+ fprintf(stderr, "no known listeners\n");
+ exit(1);
+ }
+
+ for (listeners_i = 0; listeners_i < launch_data_array_get_count(tmp); listeners_i++) {
+ launch_data_t obj_at_ind = launch_data_array_get_index(tmp, listeners_i);
+ new_socket(AUTH_SOCKET, launch_data_get_fd(obj_at_ind));
+ }
+
+ launch_data_free(resp);
+ } else {
+#endif
prev_mask = umask(0177);
sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);
if (sock < 0) {
@@ -1318,6 +1385,15 @@ main(int ac, char **av)
}
umask(prev_mask);
+#ifdef __APPLE__
+ }
+#endif
+
+#ifdef __APPLE__
+ if (l_flag)
+ goto skip2;
+#endif
+
/*
* Fork, and have the parent execute the command, if any, or present
* the socket data. The child continues as the authentication agent.
@@ -1393,6 +1469,9 @@ skip:
pkcs11_init(0);
#endif
new_socket(AUTH_SOCKET, sock);
+#ifdef __APPLE__
+skip2:
+#endif
if (ac > 0)
parent_alive_interval = 10;
idtab_init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment