version 1.12, 1999/10/05 22:18:52 |
version 1.13, 1999/10/14 18:17:42 |
|
|
#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ |
#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ |
#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ |
#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */ |
#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ |
#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ |
#define SSH_CHANNEL_AUTH_FD 6 /* authentication fd */ |
/* SSH_CHANNEL_AUTH_FD 6 authentication fd */ |
#define SSH_CHANNEL_AUTH_SOCKET 7 /* authentication socket */ |
#define SSH_CHANNEL_AUTH_SOCKET 7 /* authentication socket */ |
#define SSH_CHANNEL_AUTH_SOCKET_FD 8 /* connection to auth socket */ |
/* SSH_CHANNEL_AUTH_SOCKET_FD 8 connection to auth socket */ |
#define SSH_CHANNEL_X11_OPEN 9 /* reading first X11 packet */ |
#define SSH_CHANNEL_X11_OPEN 9 /* reading first X11 packet */ |
#define SSH_CHANNEL_INPUT_DRAINING 10 /* sending remaining data to conn */ |
#define SSH_CHANNEL_INPUT_DRAINING 10 /* sending remaining data to conn */ |
#define SSH_CHANNEL_OUTPUT_DRAINING 11 /* sending remaining data to app */ |
#define SSH_CHANNEL_OUTPUT_DRAINING 11 /* sending remaining data to app */ |
|
|
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET_FD: |
|
case SSH_CHANNEL_AUTH_FD: |
|
FD_SET(ch->sock, readset); |
FD_SET(ch->sock, readset); |
break; |
break; |
|
|
|
|
void channel_after_select(fd_set *readset, fd_set *writeset) |
void channel_after_select(fd_set *readset, fd_set *writeset) |
{ |
{ |
struct sockaddr addr; |
struct sockaddr addr; |
int addrlen, newsock, i, newch, len, port; |
int addrlen, newsock, i, newch, len; |
Channel *ch; |
Channel *ch; |
char buf[16384], *remote_hostname; |
char buf[16384], *remote_hostname; |
|
|
|
|
} |
} |
break; |
break; |
|
|
case SSH_CHANNEL_AUTH_FD: |
|
/* This is the authentication agent file descriptor. It is used to |
|
obtain the real connection to the agent. */ |
|
case SSH_CHANNEL_AUTH_SOCKET_FD: |
|
/* This is the temporary connection obtained by connecting the |
|
authentication agent socket. */ |
|
if (FD_ISSET(ch->sock, readset)) |
|
{ |
|
len = recv(ch->sock, buf, sizeof(buf), 0); |
|
if (len <= 0) |
|
{ |
|
channel_free(i); |
|
break; |
|
} |
|
if (len != 3 || (unsigned char)buf[0] != SSH_AUTHFD_CONNECT) |
|
break; /* Ignore any messages of wrong length or type. */ |
|
port = 256 * (unsigned char)buf[1] + (unsigned char)buf[2]; |
|
packet_start(SSH_SMSG_AGENT_OPEN); |
|
packet_put_int(port); |
|
packet_send(); |
|
} |
|
break; |
|
|
|
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET: |
/* This is the authentication agent socket listening for connections |
/* This is the authentication agent socket listening for connections |
from clients. */ |
from clients. */ |
if (FD_ISSET(ch->sock, readset)) |
if (FD_ISSET(ch->sock, readset)) |
{ |
{ |
|
int nchan; |
len = sizeof(addr); |
len = sizeof(addr); |
newsock = accept(ch->sock, &addr, &len); |
newsock = accept(ch->sock, &addr, &len); |
if (newsock < 0) |
if (newsock < 0) |
error("Accept from authentication socket failed"); |
{ |
(void)channel_allocate(SSH_CHANNEL_AUTH_SOCKET_FD, newsock, |
error("accept from auth socket: %.100s", strerror(errno)); |
|
break; |
|
} |
|
|
|
nchan = channel_allocate(SSH_CHANNEL_OPENING, newsock, |
xstrdup("accepted auth socket")); |
xstrdup("accepted auth socket")); |
|
packet_start(SSH_SMSG_AGENT_OPEN); |
|
packet_put_int(nchan); |
|
packet_send(); |
} |
} |
break; |
break; |
|
|
|
|
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET_FD: |
|
case SSH_CHANNEL_AUTH_FD: |
|
continue; |
continue; |
case SSH_CHANNEL_OPEN: |
case SSH_CHANNEL_OPEN: |
if (buffer_len(&ch->input) > 32768) |
if (buffer_len(&ch->input) > 32768) |
|
|
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_CLOSED: |
case SSH_CHANNEL_CLOSED: |
case SSH_CHANNEL_AUTH_FD: |
|
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET_FD: |
|
continue; |
continue; |
case SSH_CHANNEL_OPENING: |
case SSH_CHANNEL_OPENING: |
case SSH_CHANNEL_OPEN: |
case SSH_CHANNEL_OPEN: |
|
|
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_X11_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_PORT_LISTENER: |
case SSH_CHANNEL_CLOSED: |
case SSH_CHANNEL_CLOSED: |
case SSH_CHANNEL_AUTH_FD: |
|
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET: |
case SSH_CHANNEL_AUTH_SOCKET_FD: |
|
continue; |
continue; |
case SSH_CHANNEL_OPENING: |
case SSH_CHANNEL_OPENING: |
case SSH_CHANNEL_OPEN: |
case SSH_CHANNEL_OPEN: |
|
|
|
|
void auth_input_open_request() |
void auth_input_open_request() |
{ |
{ |
int port, sock, newch; |
int remch, sock, newch; |
char *dummyname; |
char *dummyname; |
|
|
/* Read the port number from the message. */ |
/* Read the remote channel number from the message. */ |
port = packet_get_int(); |
remch = packet_get_int(); |
|
|
/* Get a connection to the local authentication agent (this may again get |
/* Get a connection to the local authentication agent (this may again get |
forwarded). */ |
forwarded). */ |
sock = ssh_get_authentication_connection_fd(); |
sock = ssh_get_authentication_socket(); |
|
|
/* If we could not connect the agent, just return. This will cause the |
/* If we could not connect the agent, send an error message back to |
client to timeout and fail. This should never happen unless the agent |
the server. This should never happen unless the agent |
dies, because authentication forwarding is only enabled if we have an |
dies, because authentication forwarding is only enabled if we have an |
agent. */ |
agent. */ |
if (sock < 0) |
if (sock < 0){ |
|
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
|
packet_put_int(remch); |
|
packet_send(); |
return; |
return; |
|
} |
|
|
debug("Forwarding authentication connection."); |
debug("Forwarding authentication connection."); |
|
|
|
|
yet be freed at that point. */ |
yet be freed at that point. */ |
dummyname = xstrdup("authentication agent connection"); |
dummyname = xstrdup("authentication agent connection"); |
|
|
/* Allocate a channel for the new connection. */ |
newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname); |
newch = channel_allocate(SSH_CHANNEL_OPENING, sock, dummyname); |
channels[newch].remote_id = remch; |
|
|
/* Fake a forwarding request. */ |
/* Send a confirmation to the remote host. */ |
packet_start(SSH_MSG_PORT_OPEN); |
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |
|
packet_put_int(remch); |
packet_put_int(newch); |
packet_put_int(newch); |
packet_put_string("localhost", strlen("localhost")); |
|
packet_put_int(port); |
|
if (have_hostname_in_open) |
|
packet_put_string(dummyname, strlen(dummyname)); |
|
packet_send(); |
packet_send(); |
} |
} |