version 1.140.2.2, 2002/05/17 00:03:23 |
version 1.140.2.3, 2002/06/22 07:23:17 |
|
|
|
|
#define NUM_SOCKS 10 |
#define NUM_SOCKS 10 |
|
|
/* Name and directory of socket for authentication agent forwarding. */ |
|
static char *auth_sock_name = NULL; |
|
static char *auth_sock_dir = NULL; |
|
|
|
/* AF_UNSPEC or AF_INET or AF_INET6 */ |
/* AF_UNSPEC or AF_INET or AF_INET6 */ |
static int IPv4or6 = AF_UNSPEC; |
static int IPv4or6 = AF_UNSPEC; |
|
|
|
|
FD_SET(c->wfd, writeset); |
FD_SET(c->wfd, writeset); |
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { |
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { |
if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) |
if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) |
debug2("channel %d: obuf_empty delayed efd %d/(%d)", |
debug2("channel %d: obuf_empty delayed efd %d/(%d)", |
c->self, c->efd, buffer_len(&c->extended)); |
c->self, c->efd, buffer_len(&c->extended)); |
else |
else |
chan_obuf_empty(c); |
chan_obuf_empty(c); |
} |
} |
|
|
* hack for extended data: delay EOF if EFD still in use. |
* hack for extended data: delay EOF if EFD still in use. |
*/ |
*/ |
if (CHANNEL_EFD_INPUT_ACTIVE(c)) |
if (CHANNEL_EFD_INPUT_ACTIVE(c)) |
debug2("channel %d: ibuf_empty delayed efd %d/(%d)", |
debug2("channel %d: ibuf_empty delayed efd %d/(%d)", |
c->self, c->efd, buffer_len(&c->extended)); |
c->self, c->efd, buffer_len(&c->extended)); |
else |
else |
chan_ibuf_empty(c); |
chan_ibuf_empty(c); |
} |
} |
|
|
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); |
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); |
packet_send(); |
packet_send(); |
packet_write_wait(); |
packet_write_wait(); |
} |
|
|
|
/* |
|
* Returns the name of the forwarded authentication socket. Returns NULL if |
|
* there is no forwarded authentication socket. The returned value points to |
|
* a static buffer. |
|
*/ |
|
|
|
char * |
|
auth_get_socket_name(void) |
|
{ |
|
return auth_sock_name; |
|
} |
|
|
|
/* removes the agent forwarding socket */ |
|
|
|
void |
|
auth_sock_cleanup_proc(void *_pw) |
|
{ |
|
struct passwd *pw = _pw; |
|
|
|
if (auth_sock_name) { |
|
temporarily_use_uid(pw); |
|
unlink(auth_sock_name); |
|
rmdir(auth_sock_dir); |
|
auth_sock_name = NULL; |
|
restore_uid(); |
|
} |
|
} |
|
|
|
/* |
|
* This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server. |
|
* This starts forwarding authentication requests. |
|
*/ |
|
|
|
int |
|
auth_input_request_forwarding(struct passwd * pw) |
|
{ |
|
Channel *nc; |
|
int sock; |
|
struct sockaddr_un sunaddr; |
|
|
|
if (auth_get_socket_name() != NULL) { |
|
error("authentication forwarding requested twice."); |
|
return 0; |
|
} |
|
|
|
/* Temporarily drop privileged uid for mkdir/bind. */ |
|
temporarily_use_uid(pw); |
|
|
|
/* Allocate a buffer for the socket name, and format the name. */ |
|
auth_sock_name = xmalloc(MAXPATHLEN); |
|
auth_sock_dir = xmalloc(MAXPATHLEN); |
|
strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); |
|
|
|
/* Create private directory for socket */ |
|
if (mkdtemp(auth_sock_dir) == NULL) { |
|
packet_send_debug("Agent forwarding disabled: " |
|
"mkdtemp() failed: %.100s", strerror(errno)); |
|
restore_uid(); |
|
xfree(auth_sock_name); |
|
xfree(auth_sock_dir); |
|
auth_sock_name = NULL; |
|
auth_sock_dir = NULL; |
|
return 0; |
|
} |
|
snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%d", |
|
auth_sock_dir, (int) getpid()); |
|
|
|
/* delete agent socket on fatal() */ |
|
fatal_add_cleanup(auth_sock_cleanup_proc, pw); |
|
|
|
/* Create the socket. */ |
|
sock = socket(AF_UNIX, SOCK_STREAM, 0); |
|
if (sock < 0) |
|
packet_disconnect("socket: %.100s", strerror(errno)); |
|
|
|
/* Bind it to the name. */ |
|
memset(&sunaddr, 0, sizeof(sunaddr)); |
|
sunaddr.sun_family = AF_UNIX; |
|
strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); |
|
|
|
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) |
|
packet_disconnect("bind: %.100s", strerror(errno)); |
|
|
|
/* Restore the privileged uid. */ |
|
restore_uid(); |
|
|
|
/* Start listening on the socket. */ |
|
if (listen(sock, 5) < 0) |
|
packet_disconnect("listen: %.100s", strerror(errno)); |
|
|
|
/* Allocate a channel for the authentication agent socket. */ |
|
nc = channel_new("auth socket", |
|
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, |
|
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, |
|
0, xstrdup("auth socket"), 1); |
|
strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); |
|
return 1; |
|
} |
} |
|
|
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ |
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ |