version 1.48, 2000/04/14 10:09:14 |
version 1.49, 2000/04/14 10:30:30 |
|
|
/* |
/* |
* |
* |
* channels.c |
* channels.c |
* |
* |
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
* |
* |
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
* All rights reserved |
* All rights reserved |
* |
* |
* Created: Fri Mar 24 16:35:24 1995 ylo |
* Created: Fri Mar 24 16:35:24 1995 ylo |
* |
* |
* This file contains functions for generic socket connection forwarding. |
* This file contains functions for generic socket connection forwarding. |
* There is also code for initiating connection forwarding for X11 connections, |
* There is also code for initiating connection forwarding for X11 connections, |
* arbitrary tcp/ip connections, and the authentication agent connection. |
* arbitrary tcp/ip connections, and the authentication agent connection. |
* |
* |
* SSH2 support added by Markus Friedl. |
* SSH2 support added by Markus Friedl. |
*/ |
*/ |
|
|
|
|
|
|
/* Sets specific protocol options. */ |
/* Sets specific protocol options. */ |
|
|
void |
void |
channel_set_options(int hostname_in_open) |
channel_set_options(int hostname_in_open) |
{ |
{ |
have_hostname_in_open = hostname_in_open; |
have_hostname_in_open = hostname_in_open; |
|
|
* and the server has no way to know but to trust the client anyway. |
* and the server has no way to know but to trust the client anyway. |
*/ |
*/ |
|
|
void |
void |
channel_permit_all_opens() |
channel_permit_all_opens() |
{ |
{ |
all_opens_permitted = 1; |
all_opens_permitted = 1; |
|
|
* remote_name to be freed. |
* remote_name to be freed. |
*/ |
*/ |
|
|
int |
int |
channel_new(char *ctype, int type, int rfd, int wfd, int efd, |
channel_new(char *ctype, int type, int rfd, int wfd, int efd, |
int window, int maxpack, int extended_usage, char *remote_name) |
int window, int maxpack, int extended_usage, char *remote_name) |
{ |
{ |
|
|
debug("channel %d: new [%s]", found, remote_name); |
debug("channel %d: new [%s]", found, remote_name); |
return found; |
return found; |
} |
} |
int |
int |
channel_allocate(int type, int sock, char *remote_name) |
channel_allocate(int type, int sock, char *remote_name) |
{ |
{ |
return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); |
return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name); |
|
|
|
|
/* Free the channel and close its socket. */ |
/* Free the channel and close its socket. */ |
|
|
void |
void |
channel_free(int id) |
channel_free(int id) |
{ |
{ |
Channel *c = channel_lookup(id); |
Channel *c = channel_lookup(id); |
|
|
{ |
{ |
if (buffer_len(&c->output) == 0) |
if (buffer_len(&c->output) == 0) |
channel_free(c->self); |
channel_free(c->self); |
else |
else |
FD_SET(c->sock, writeset); |
FD_SET(c->sock, writeset); |
} |
} |
|
|
|
|
channel_handler_init_15(); |
channel_handler_init_15(); |
} |
} |
|
|
void |
void |
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) |
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) |
{ |
{ |
static int did_init = 0; |
static int did_init = 0; |
|
|
} |
} |
} |
} |
|
|
void |
void |
channel_prepare_select(fd_set * readset, fd_set * writeset) |
channel_prepare_select(fd_set * readset, fd_set * writeset) |
{ |
{ |
channel_handler(channel_pre, readset, writeset); |
channel_handler(channel_pre, readset, writeset); |
} |
} |
|
|
void |
void |
channel_after_select(fd_set * readset, fd_set * writeset) |
channel_after_select(fd_set * readset, fd_set * writeset) |
{ |
{ |
channel_handler(channel_post, readset, writeset); |
channel_handler(channel_post, readset, writeset); |
|
|
|
|
/* If there is data to send to the connection, send some of it now. */ |
/* If there is data to send to the connection, send some of it now. */ |
|
|
void |
void |
channel_output_poll() |
channel_output_poll() |
{ |
{ |
int len, i; |
int len, i; |
|
|
* still there. |
* still there. |
*/ |
*/ |
|
|
void |
void |
channel_input_data(int type, int plen) |
channel_input_data(int type, int plen) |
{ |
{ |
int id; |
int id; |
|
|
buffer_append(&c->output, data, data_len); |
buffer_append(&c->output, data, data_len); |
xfree(data); |
xfree(data); |
} |
} |
void |
void |
channel_input_extended_data(int type, int plen) |
channel_input_extended_data(int type, int plen) |
{ |
{ |
int id; |
int id; |
|
|
* more channel is overfull. |
* more channel is overfull. |
*/ |
*/ |
|
|
int |
int |
channel_not_very_much_buffered_data() |
channel_not_very_much_buffered_data() |
{ |
{ |
unsigned int i; |
unsigned int i; |
|
|
return 1; |
return 1; |
} |
} |
|
|
void |
void |
channel_input_ieof(int type, int plen) |
channel_input_ieof(int type, int plen) |
{ |
{ |
int id; |
int id; |
|
|
chan_rcvd_ieof(c); |
chan_rcvd_ieof(c); |
} |
} |
|
|
void |
void |
channel_input_close(int type, int plen) |
channel_input_close(int type, int plen) |
{ |
{ |
int id; |
int id; |
|
|
} |
} |
|
|
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ |
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ |
void |
void |
channel_input_oclose(int type, int plen) |
channel_input_oclose(int type, int plen) |
{ |
{ |
int id = packet_get_int(); |
int id = packet_get_int(); |
|
|
chan_rcvd_oclose(c); |
chan_rcvd_oclose(c); |
} |
} |
|
|
void |
void |
channel_input_close_confirmation(int type, int plen) |
channel_input_close_confirmation(int type, int plen) |
{ |
{ |
int id = packet_get_int(); |
int id = packet_get_int(); |
|
|
channel_free(c->self); |
channel_free(c->self); |
} |
} |
|
|
void |
void |
channel_input_open_confirmation(int type, int plen) |
channel_input_open_confirmation(int type, int plen) |
{ |
{ |
int id, remote_id; |
int id, remote_id; |
|
|
} |
} |
} |
} |
|
|
void |
void |
channel_input_open_failure(int type, int plen) |
channel_input_open_failure(int type, int plen) |
{ |
{ |
int id; |
int id; |
|
|
} |
} |
} |
} |
|
|
void |
void |
channel_input_window_adjust(int type, int plen) |
channel_input_window_adjust(int type, int plen) |
{ |
{ |
Channel *c; |
Channel *c; |
|
|
* might have. |
* might have. |
*/ |
*/ |
|
|
void |
void |
channel_stop_listening() |
channel_stop_listening() |
{ |
{ |
int i; |
int i; |
|
|
* descriptors after a fork. |
* descriptors after a fork. |
*/ |
*/ |
|
|
void |
void |
channel_close_all() |
channel_close_all() |
{ |
{ |
int i; |
int i; |
|
|
|
|
/* Returns the maximum file descriptor number used by the channels. */ |
/* Returns the maximum file descriptor number used by the channels. */ |
|
|
int |
int |
channel_max_fd() |
channel_max_fd() |
{ |
{ |
return channel_max_fd_value; |
return channel_max_fd_value; |
|
|
|
|
/* Returns true if any channel is still open. */ |
/* Returns true if any channel is still open. */ |
|
|
int |
int |
channel_still_open() |
channel_still_open() |
{ |
{ |
unsigned int i; |
unsigned int i; |
|
|
* channel to host:port from remote side. |
* channel to host:port from remote side. |
*/ |
*/ |
|
|
void |
void |
channel_request_local_forwarding(u_short port, const char *host, |
channel_request_local_forwarding(u_short port, const char *host, |
u_short host_port, int gateway_ports) |
u_short host_port, int gateway_ports) |
{ |
{ |
|
|
* the secure channel to host:port from local side. |
* the secure channel to host:port from local side. |
*/ |
*/ |
|
|
void |
void |
channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, |
channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, |
u_short port_to_connect) |
u_short port_to_connect) |
{ |
{ |
|
|
* message if there was an error). This never returns if there was an error. |
* message if there was an error). This never returns if there was an error. |
*/ |
*/ |
|
|
void |
void |
channel_input_port_forward_request(int is_root) |
channel_input_port_forward_request(int is_root) |
{ |
{ |
u_short port, host_port; |
u_short port, host_port; |
|
|
* or CHANNEL_OPEN_FAILURE. |
* or CHANNEL_OPEN_FAILURE. |
*/ |
*/ |
|
|
void |
void |
channel_input_port_open(int type, int plen) |
channel_input_port_open(int type, int plen) |
{ |
{ |
u_short host_port; |
u_short host_port; |
|
|
* with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. |
* with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. |
*/ |
*/ |
|
|
void |
void |
x11_input_open(int type, int plen) |
x11_input_open(int type, int plen) |
{ |
{ |
int remote_channel, display_number, sock = 0, newch; |
int remote_channel, display_number, sock = 0, newch; |
|
|
} |
} |
freeaddrinfo(aitop); |
freeaddrinfo(aitop); |
if (!ai) { |
if (!ai) { |
error("connect %.100s port %d: %.100s", buf, 6000 + display_number, |
error("connect %.100s port %d: %.100s", buf, 6000 + display_number, |
strerror(errno)); |
strerror(errno)); |
goto fail; |
goto fail; |
} |
} |
|
|
* data, and enables authentication spoofing. |
* data, and enables authentication spoofing. |
*/ |
*/ |
|
|
void |
void |
x11_request_forwarding_with_spoofing(const char *proto, const char *data) |
x11_request_forwarding_with_spoofing(const char *proto, const char *data) |
{ |
{ |
unsigned int data_len = (unsigned int) strlen(data) / 2; |
unsigned int data_len = (unsigned int) strlen(data) / 2; |
|
|
|
|
/* Sends a message to the server to request authentication fd forwarding. */ |
/* Sends a message to the server to request authentication fd forwarding. */ |
|
|
void |
void |
auth_request_forwarding() |
auth_request_forwarding() |
{ |
{ |
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); |
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); |
|
|
|
|
/* removes the agent forwarding socket */ |
/* removes the agent forwarding socket */ |
|
|
void |
void |
cleanup_socket(void) |
cleanup_socket(void) |
{ |
{ |
remove(channel_forwarded_auth_socket_name); |
remove(channel_forwarded_auth_socket_name); |
|
|
* This starts forwarding authentication requests. |
* This starts forwarding authentication requests. |
*/ |
*/ |
|
|
void |
void |
auth_input_request_forwarding(struct passwd * pw) |
auth_input_request_forwarding(struct passwd * pw) |
{ |
{ |
int sock, newch; |
int sock, newch; |
|
|
|
|
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ |
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ |
|
|
void |
void |
auth_input_open_request(int type, int plen) |
auth_input_open_request(int type, int plen) |
{ |
{ |
int remch, sock, newch; |
int remch, sock, newch; |