mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-23 15:09:24 -05:00
Factor out Unix Pageant's socket creation.
The code in Pageant that sets up the Unix socket and its containing directory now lives in a separate file, uxagentsock.c, where it will also be callable from the upcoming new SSH server when it wants to create a similar socket for agent forwarding. While I'm at it, I've also added a feature to create a watchdog subprocess that will try to clean up the socket and directory once Pageant itself terminates, in the hope of leaving less cruft lying around /tmp.
This commit is contained in:
parent
b94c6a7e38
commit
f4db9196da
2
Recipe
2
Recipe
@ -349,7 +349,7 @@ psftp : [U] psftp uxsftp uxcons UXSSH BE_SSH SFTP wildcard UXMISC uxnogtk
|
|||||||
pageant : [X] uxpgnt uxagentc aqsync pageant sshrsa sshpubk sshdes sshbn
|
pageant : [X] uxpgnt uxagentc aqsync pageant sshrsa sshpubk sshdes sshbn
|
||||||
+ sshmd5 version tree234 misc sshaes sshsha sshdss sshsh256 sshsh512
|
+ sshmd5 version tree234 misc sshaes sshsha sshdss sshsh256 sshsh512
|
||||||
+ sshecc CONF uxsignal nocproxy nogss be_none x11fwd ux_x11 uxcons
|
+ sshecc CONF uxsignal nocproxy nogss be_none x11fwd ux_x11 uxcons
|
||||||
+ gtkask gtkmisc nullplug logging UXMISC
|
+ gtkask gtkmisc nullplug logging UXMISC uxagentsock
|
||||||
|
|
||||||
ptermapp : [XT] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
|
ptermapp : [XT] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
|
||||||
+ uxsignal CHARSET uxpterm version time xpmpterm xpmptcfg
|
+ uxsignal CHARSET uxpterm version time xpmpterm xpmptcfg
|
||||||
|
3
ssh.h
3
ssh.h
@ -344,6 +344,9 @@ char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
|||||||
char *hostname, int port, SshChannel *c,
|
char *hostname, int port, SshChannel *c,
|
||||||
int addressfamily);
|
int addressfamily);
|
||||||
|
|
||||||
|
Socket *platform_make_agent_socket(Plug *plug, const char *dirprefix,
|
||||||
|
char **error, char **name);
|
||||||
|
|
||||||
LogContext *ssh_get_logctx(Ssh *ssh);
|
LogContext *ssh_get_logctx(Ssh *ssh);
|
||||||
|
|
||||||
/* Communications back to ssh.c from connection layers */
|
/* Communications back to ssh.c from connection layers */
|
||||||
|
@ -321,9 +321,11 @@ int init_ucs(struct unicode_data *ucsdata, char *line_codepage,
|
|||||||
int utf8_override, int font_charset, int vtmode);
|
int utf8_override, int font_charset, int vtmode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spare function exported directly from uxnet.c.
|
* Spare functions exported directly from uxnet.c.
|
||||||
*/
|
*/
|
||||||
void *sk_getxdmdata(Socket *sock, int *lenp);
|
void *sk_getxdmdata(Socket *sock, int *lenp);
|
||||||
|
SockAddr *unix_sock_addr(const char *path);
|
||||||
|
Socket *new_unix_listener(SockAddr *listenaddr, Plug *plug);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General helpful Unix stuff: more helpful version of the FD_SET
|
* General helpful Unix stuff: more helpful version of the FD_SET
|
||||||
|
85
unix/uxagentsock.c
Normal file
85
unix/uxagentsock.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "putty.h"
|
||||||
|
#include "ssh.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "pageant.h"
|
||||||
|
|
||||||
|
Socket *platform_make_agent_socket(
|
||||||
|
Plug *plug, const char *dirprefix, char **error, char **name)
|
||||||
|
{
|
||||||
|
char *username, *socketdir, *socketname, *errw;
|
||||||
|
const char *errr;
|
||||||
|
Socket *sock;
|
||||||
|
|
||||||
|
*name = NULL;
|
||||||
|
|
||||||
|
username = get_username();
|
||||||
|
socketdir = dupprintf("%s.%s", dirprefix, username);
|
||||||
|
sfree(username);
|
||||||
|
|
||||||
|
assert(*socketdir == '/');
|
||||||
|
if ((errw = make_dir_and_check_ours(socketdir)) != NULL) {
|
||||||
|
*error = dupprintf("%s: %s\n", socketdir, errw);
|
||||||
|
sfree(errw);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
socketname = dupprintf("%s/pageant.%d", socketdir, (int)getpid());
|
||||||
|
sock = new_unix_listener(unix_sock_addr(socketname), plug);
|
||||||
|
if ((errr = sk_socket_error(sock)) != NULL) {
|
||||||
|
*error = dupprintf("%s: %s\n", socketname, errr);
|
||||||
|
sk_close(sock);
|
||||||
|
sfree(socketname);
|
||||||
|
rmdir(socketdir);
|
||||||
|
sfree(socketdir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Spawn a subprocess which will try to reliably delete our socket
|
||||||
|
* and its containing directory when we terminate, in case we die
|
||||||
|
* unexpectedly.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int cleanup_pipe[2];
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
/* Don't worry if pipe or fork fails; it's not _that_ critical. */
|
||||||
|
if (!pipe(cleanup_pipe)) {
|
||||||
|
if ((pid = fork()) == 0) {
|
||||||
|
int buf[1024];
|
||||||
|
/*
|
||||||
|
* Our parent process holds the writing end of
|
||||||
|
* this pipe, and writes nothing to it. Hence,
|
||||||
|
* we expect read() to return EOF as soon as
|
||||||
|
* that process terminates.
|
||||||
|
*/
|
||||||
|
setpgid(0, 0);
|
||||||
|
close(cleanup_pipe[1]);
|
||||||
|
while (read(cleanup_pipe[0], buf, sizeof(buf)) > 0);
|
||||||
|
unlink(socketname);
|
||||||
|
rmdir(socketdir);
|
||||||
|
_exit(0);
|
||||||
|
} else if (pid < 0) {
|
||||||
|
close(cleanup_pipe[0]);
|
||||||
|
close(cleanup_pipe[1]);
|
||||||
|
} else {
|
||||||
|
close(cleanup_pipe[0]);
|
||||||
|
cloexec(cleanup_pipe[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*name = socketname;
|
||||||
|
*error = NULL;
|
||||||
|
sfree(socketdir);
|
||||||
|
return sock;
|
||||||
|
}
|
@ -20,9 +20,6 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "pageant.h"
|
#include "pageant.h"
|
||||||
|
|
||||||
SockAddr *unix_sock_addr(const char *path);
|
|
||||||
Socket *new_unix_listener(SockAddr *listenaddr, Plug *plug);
|
|
||||||
|
|
||||||
void cmdline_error(const char *fmt, ...)
|
void cmdline_error(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -711,7 +708,7 @@ static const PlugVtable X11Connection_plugvt = {
|
|||||||
void run_agent(void)
|
void run_agent(void)
|
||||||
{
|
{
|
||||||
const char *err;
|
const char *err;
|
||||||
char *username, *socketdir;
|
char *errw;
|
||||||
struct pageant_listen_state *pl;
|
struct pageant_listen_state *pl;
|
||||||
Plug *pl_plug;
|
Plug *pl_plug;
|
||||||
Socket *sock;
|
Socket *sock;
|
||||||
@ -743,19 +740,12 @@ void run_agent(void)
|
|||||||
/*
|
/*
|
||||||
* Set up a listening socket and run Pageant on it.
|
* Set up a listening socket and run Pageant on it.
|
||||||
*/
|
*/
|
||||||
username = get_username();
|
|
||||||
socketdir = dupprintf("%s.%s", PAGEANT_DIR_PREFIX, username);
|
|
||||||
sfree(username);
|
|
||||||
assert(*socketdir == '/');
|
|
||||||
if ((err = make_dir_and_check_ours(socketdir)) != NULL) {
|
|
||||||
fprintf(stderr, "pageant: %s: %s\n", socketdir, err);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
socketname = dupprintf("%s/pageant.%d", socketdir, (int)getpid());
|
|
||||||
pl = pageant_listener_new(&pl_plug);
|
pl = pageant_listener_new(&pl_plug);
|
||||||
sock = new_unix_listener(unix_sock_addr(socketname), pl_plug);
|
sock = platform_make_agent_socket(pl_plug, PAGEANT_DIR_PREFIX,
|
||||||
if ((err = sk_socket_error(sock)) != NULL) {
|
&errw, &socketname);
|
||||||
fprintf(stderr, "pageant: %s: %s\n", socketname, err);
|
if (!sock) {
|
||||||
|
fprintf(stderr, "pageant: %s\n", errw);
|
||||||
|
sfree(errw);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
pageant_listener_got_socket(pl, sock);
|
pageant_listener_got_socket(pl, sock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user