From 3485e8b9dc5b363a40834f8edf280b49bbfe1358 Mon Sep 17 00:00:00 2001 From: Wesley Darlington Date: Wed, 18 Nov 2009 12:21:21 +0000 Subject: [PATCH] Clean build, zero functionality. Doesn't fork subprocesses, doesn't *do* ssh-agent stuff. --- .gitignore | 3 ++ charade.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++------- cmdline.c | 3 ++ 3 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e650198 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.d +*.o +charade.exe diff --git a/charade.c b/charade.c index 63f9685..4bffa4f 100644 --- a/charade.c +++ b/charade.c @@ -5,30 +5,97 @@ * Copyright (c) 2009, Wesley Darlington. All Rights Reserved. */ +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "cmdline.h" +#define LISTEN_BACKLOG 5 + +#define SSH_AUTHSOCKET_ENV_NAME "SSH_AUTH_SOCK" +#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID" + int sock; +char socket_dir[MAXPATHLEN] = ""; +char socket_name[MAXPATHLEN] = ""; + +int remove_socket_at_exit = 1; + +void +remove_socket_dir(void) /* atexit handler */ +{ + if (remove_socket_at_exit) { + int ret = rmdir(socket_dir); + + if (ret) { + fprintf(stderr, "Error removing socket directory '%s': %s.\n", + socket_dir, strerror(errno)); + /* atexit! */ + } + } +} + +void +remove_socket(void) /* atexit handler */ +{ + if (remove_socket_at_exit) { + int ret = unlink(socket_name); + + if (ret) { + fprintf(stderr, "Error removing socket '%s': %s.\n", + socket_name, strerror(errno)); + /* atexit! */ + } + } +} + void create_socket(void) { +#if 0 if (agentsocket == NULL) { - /* Create private directory for agent socket */ - strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir); - if (mkdtemp(socket_dir) == NULL) { - perror("mkdtemp: private socket dir"); - exit(1); - } - snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, - (long)parent_pid); +#endif + + /* Create private directory for agent socket */ + strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir); + if (mkdtemp(socket_dir) == NULL) { + perror("mkdtemp: private socket dir"); + exit(1); + } + + if (atexit(remove_socket_dir)) { + fprintf(stderr, "Can't install atexit handler to delete socket '%s'. " + "Do it yourself!\n", socket_name); + exit(1); + } + + int ret = snprintf(socket_name, sizeof(socket_name), + "%s/agent.%ld", socket_dir, (long)getpid()); + if (ret >= sizeof(socket_name)) { + // Would have liked to print more... + fprintf(stderr, "socket_name too long (%d >= %d).\n", + ret, sizeof(socket_name)); + exit(1); + } + + +#if 0 } else { /* Try to use specified agent socket */ socket_dir[0] = '\0'; strlcpy(socket_name, agentsocket, sizeof socket_name); } +#endif sock = socket(AF_UNIX, SOCK_STREAM, 0); @@ -41,17 +108,23 @@ create_socket(void) memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); - prev_mask = umask(0177); + int prev_mask = umask(0177); if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) { perror("bind"); - *socket_name = '\0'; /* Don't unlink any existing file */ umask(prev_mask); - cleanup_exit(1); + exit(1); + } + + if (atexit(remove_socket)) { + fprintf(stderr, "Can't install atexit handler to delete socket '%s'. " + "Do it yourself!\n", socket_name); + exit(1); } + umask(prev_mask); - if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { + if (listen(sock, LISTEN_BACKLOG) < 0) { perror("listen"); - cleanup_exit(1); + exit(1); } } @@ -69,11 +142,35 @@ kill_old_agent(void) void fork_subprocess(void) { + int pid = fork(); + + if (-1 == pid) { + perror("fork"); + exit(1); + } + + if (pid) { // Parent + printf("%s=%s; export %s\n", SSH_AUTHSOCKET_ENV_NAME, socket_name, + SSH_AUTHSOCKET_ENV_NAME); + printf("%s=%ld; export %s\n", SSH_AGENTPID_ENV_NAME, (long) pid, + SSH_AGENTPID_ENV_NAME); + + // TODO: If argv present, fork and exec it. Only do above if no args. + + remove_socket_at_exit = 0; + exit(0); + } + + // Child + if (setsid() == -1) { + perror("setsid"); + } } void -go(void) +handle_key_requests_forever(void) { + // Select on sockets, etc etc } int @@ -82,20 +179,25 @@ main(int argc, char **argv) /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ // TODO: sanitise_stdfd(); +#if 0 parse_cmdline(argc, argv); if (g_kill_flag) { kill_old_agent(); exit(0); } +#endif create_socket(); +#if 0 if (! g_debug_flag) { - fork_subprocess(); } +#endif + + fork_subprocess(); - go(); + handle_key_requests_forever(); /* NOTREACHED */ diff --git a/cmdline.c b/cmdline.c index def80f0..d23b8f5 100644 --- a/cmdline.c +++ b/cmdline.c @@ -16,6 +16,9 @@ int g_kill_flag = 0; int g_debug_flag = 0; char *g_socket_name = 0; +int g_subprocess_argc; +char **g_subprocess_argv; + static void usage(void) {