agent-socket.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <assert.h>
  5. #include <signal.h>
  6. #include <ctype.h>
  7. #include <unistd.h>
  8. #include "putty.h"
  9. #include "ssh.h"
  10. #include "misc.h"
  11. #include "pageant.h"
  12. Socket *platform_make_agent_socket(
  13. Plug *plug, const char *dirprefix, char **error, char **name)
  14. {
  15. char *username, *socketdir, *socketname, *errw;
  16. const char *err;
  17. Socket *sock;
  18. *name = NULL;
  19. username = get_username();
  20. socketdir = dupprintf("%s.%s", dirprefix, username);
  21. sfree(username);
  22. assert(*socketdir == '/');
  23. if ((errw = make_dir_and_check_ours(socketdir)) != NULL) {
  24. *error = dupprintf("%s: %s\n", socketdir, errw);
  25. sfree(errw);
  26. sfree(socketdir);
  27. return NULL;
  28. }
  29. socketname = dupprintf("%s/pageant.%d", socketdir, (int)getpid());
  30. sock = new_unix_listener(unix_sock_addr(socketname), plug);
  31. if ((err = sk_socket_error(sock)) != NULL) {
  32. *error = dupprintf("%s: %s\n", socketname, err);
  33. sk_close(sock);
  34. sfree(socketname);
  35. rmdir(socketdir);
  36. sfree(socketdir);
  37. return NULL;
  38. }
  39. /*
  40. * Spawn a subprocess which will try to reliably delete our socket
  41. * and its containing directory when we terminate, in case we die
  42. * unexpectedly.
  43. */
  44. {
  45. int cleanup_pipe[2];
  46. pid_t pid;
  47. /* Don't worry if pipe or fork fails; it's not _that_ critical. */
  48. if (!pipe(cleanup_pipe)) {
  49. if ((pid = fork()) == 0) {
  50. int buf[1024];
  51. /*
  52. * Our parent process holds the writing end of
  53. * this pipe, and writes nothing to it. Hence,
  54. * we expect read() to return EOF as soon as
  55. * that process terminates.
  56. */
  57. close(0);
  58. close(1);
  59. close(2);
  60. setpgid(0, 0);
  61. close(cleanup_pipe[1]);
  62. while (read(cleanup_pipe[0], buf, sizeof(buf)) > 0);
  63. unlink(socketname);
  64. rmdir(socketdir);
  65. _exit(0);
  66. } else if (pid < 0) {
  67. close(cleanup_pipe[0]);
  68. close(cleanup_pipe[1]);
  69. } else {
  70. close(cleanup_pipe[0]);
  71. cloexec(cleanup_pipe[1]);
  72. }
  73. }
  74. }
  75. *name = socketname;
  76. *error = NULL;
  77. sfree(socketdir);
  78. return sock;
  79. }