channels1.c | channels1.c | |||
---|---|---|---|---|
skipping to change at line 31 | skipping to change at line 31 | |||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |||
* MA 02111-1307, USA. | * MA 02111-1307, USA. | |||
*/ | */ | |||
#include <string.h> | #include <string.h> | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include "libssh/priv.h" | #include "libssh/priv.h" | |||
#include "libssh/ssh1.h" | #include "libssh/ssh1.h" | |||
#include "libssh/buffer.h" | ||||
#include "libssh/packet.h" | ||||
#include "libssh/channels.h" | ||||
#include "libssh/session.h" | ||||
#ifdef WITH_SSH1 | #ifdef WITH_SSH1 | |||
/* | /* | |||
* This is a big hack. In fact, SSH1 doesn't make a clever use of channels. | * This is a big hack. In fact, SSH1 doesn't make a clever use of channels. | |||
* The whole packets concerning shells are sent outside of a channel. | * The whole packets concerning shells are sent outside of a channel. | |||
* Thus, an inside limitation of this behaviour is that you can't only | * Thus, an inside limitation of this behaviour is that you can't only | |||
* request one shell. | * request one shell. | |||
* The question is stil how they managed to imbed two "channel" into one | * The question is stil how they managed to imbed two "channel" into one | |||
* protocol. | * protocol. | |||
*/ | */ | |||
int channel_open_session1(CHANNEL *chan) { | int channel_open_session1(ssh_channel chan) { | |||
/* | /* | |||
* We guess we are requesting an *exec* channel. It can only have one exe c | * We guess we are requesting an *exec* channel. It can only have one exe c | |||
* channel. So we abort with an error if we need more than one. | * channel. So we abort with an error if we need more than one. | |||
*/ | */ | |||
SSH_SESSION *session = chan->session; | ssh_session session = chan->session; | |||
if (session->exec_channel_opened) { | if (session->exec_channel_opened) { | |||
ssh_set_error(session, SSH_REQUEST_DENIED, | ssh_set_error(session, SSH_REQUEST_DENIED, | |||
"SSH1 supports only one execution channel. " | "SSH1 supports only one execution channel. " | |||
"One has already been opened"); | "One has already been opened"); | |||
return -1; | return -1; | |||
} | } | |||
session->exec_channel_opened = 1; | session->exec_channel_opened = 1; | |||
chan->open = 1; | chan->open = 1; | |||
chan->local_maxpacket = 32000; | chan->local_maxpacket = 32000; | |||
chan->local_window = 64000; | chan->local_window = 64000; | |||
skipping to change at line 76 | skipping to change at line 80 | |||
* string TERM environment variable value (e.g. vt100) | * string TERM environment variable value (e.g. vt100) | |||
* 32-bit int terminal height, rows (e.g., 24) | * 32-bit int terminal height, rows (e.g., 24) | |||
* 32-bit int terminal width, columns (e.g., 80) | * 32-bit int terminal width, columns (e.g., 80) | |||
* 32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) | * 32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) | |||
* 32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) | * 32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) | |||
* n bytes tty modes encoded in binary | * n bytes tty modes encoded in binary | |||
* Some day, someone should have a look at that nasty tty encoded. It's | * Some day, someone should have a look at that nasty tty encoded. It's | |||
* much simplier under ssh2. I just hope the defaults values are ok ... | * much simplier under ssh2. I just hope the defaults values are ok ... | |||
*/ | */ | |||
int channel_request_pty_size1(CHANNEL *channel, const char *terminal, int c ol, | int channel_request_pty_size1(ssh_channel channel, const char *terminal, in t col, | |||
int row) { | int row) { | |||
SSH_SESSION *session = channel->session; | ssh_session session = channel->session; | |||
STRING *str = NULL; | ssh_string str = NULL; | |||
str = string_from_char(terminal); | str = string_from_char(terminal); | |||
if (str == NULL) { | if (str == NULL) { | |||
return -1; | return -1; | |||
} | } | |||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 || | if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 || | |||
buffer_add_ssh_string(session->out_buffer, str) < 0) { | buffer_add_ssh_string(session->out_buffer, str) < 0) { | |||
string_free(str); | string_free(str); | |||
return -1; | return -1; | |||
skipping to change at line 129 | skipping to change at line 133 | |||
ssh_log(session, SSH_LOG_RARE, "PTY: error\n"); | ssh_log(session, SSH_LOG_RARE, "PTY: error\n"); | |||
ssh_set_error(session, SSH_FATAL, | ssh_set_error(session, SSH_FATAL, | |||
"Received unexpected packet type %d", | "Received unexpected packet type %d", | |||
session->in_packet.type); | session->in_packet.type); | |||
return -1; | return -1; | |||
} | } | |||
return -1; | return -1; | |||
} | } | |||
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows) { | int channel_change_pty_size1(ssh_channel channel, int cols, int rows) { | |||
SSH_SESSION *session = channel->session; | ssh_session session = channel->session; | |||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 || | if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 || | |||
buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 || | buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 || | |||
buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 || | buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 || | |||
buffer_add_u32(session->out_buffer, 0) < 0 || | buffer_add_u32(session->out_buffer, 0) < 0 || | |||
buffer_add_u32(session->out_buffer, 0) < 0) { | buffer_add_u32(session->out_buffer, 0) < 0) { | |||
return -1; | return -1; | |||
} | } | |||
if (packet_send(session)) { | if (packet_send(session)) { | |||
skipping to change at line 166 | skipping to change at line 170 | |||
ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied"); | ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied"); | |||
return -1; | return -1; | |||
} | } | |||
ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d", | ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d", | |||
session->in_packet.type); | session->in_packet.type); | |||
return -1; | return -1; | |||
} | } | |||
int channel_request_shell1(CHANNEL *channel) { | int channel_request_shell1(ssh_channel channel) { | |||
SSH_SESSION *session = channel->session; | ssh_session session = channel->session; | |||
if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) { | if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) { | |||
return -1; | return -1; | |||
} | } | |||
if (packet_send(session) != SSH_OK) { | if (packet_send(session) != SSH_OK) { | |||
return -1; | return -1; | |||
} | } | |||
ssh_log(session, SSH_LOG_RARE, "Launched a shell"); | ssh_log(session, SSH_LOG_RARE, "Launched a shell"); | |||
return 0; | return 0; | |||
} | } | |||
int channel_request_exec1(CHANNEL *channel, const char *cmd) { | int channel_request_exec1(ssh_channel channel, const char *cmd) { | |||
SSH_SESSION *session = channel->session; | ssh_session session = channel->session; | |||
STRING *command = NULL; | ssh_string command = NULL; | |||
command = string_from_char(cmd); | command = string_from_char(cmd); | |||
if (command == NULL) { | if (command == NULL) { | |||
return -1; | return -1; | |||
} | } | |||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 || | if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 || | |||
buffer_add_ssh_string(session->out_buffer, command) < 0) { | buffer_add_ssh_string(session->out_buffer, command) < 0) { | |||
string_free(command); | string_free(command); | |||
return -1; | return -1; | |||
skipping to change at line 207 | skipping to change at line 211 | |||
if(packet_send(session) != SSH_OK) { | if(packet_send(session) != SSH_OK) { | |||
return -1; | return -1; | |||
} | } | |||
ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd); | ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd); | |||
return 0; | return 0; | |||
} | } | |||
static int channel_rcv_data1(SSH_SESSION *session, int is_stderr) { | static int channel_rcv_data1(ssh_session session, int is_stderr) { | |||
CHANNEL *channel = session->channels; | ssh_channel channel = session->channels; | |||
STRING *str = NULL; | ssh_string str = NULL; | |||
str = buffer_get_ssh_string(session->in_buffer); | str = buffer_get_ssh_string(session->in_buffer); | |||
if (str == NULL) { | if (str == NULL) { | |||
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n"); | ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n"); | |||
return -1; | return -1; | |||
} | } | |||
ssh_log(session, SSH_LOG_RARE, | ssh_log(session, SSH_LOG_RARE, | |||
"Adding %zu bytes data in %d", | "Adding %zu bytes data in %d", | |||
string_len(str), is_stderr); | string_len(str), is_stderr); | |||
if (channel_default_bufferize(channel, str->string, string_len(str), | if (channel_default_bufferize(channel, string_data(str), string_len(str ), | |||
is_stderr) < 0) { | is_stderr) < 0) { | |||
string_free(str); | string_free(str); | |||
return -1; | return -1; | |||
} | } | |||
string_free(str); | string_free(str); | |||
return 0; | return 0; | |||
} | } | |||
static int channel_rcv_close1(SSH_SESSION *session) { | static int channel_rcv_close1(ssh_session session) { | |||
CHANNEL *channel = session->channels; | ssh_channel channel = session->channels; | |||
u32 status; | uint32_t status; | |||
buffer_get_u32(session->in_buffer, &status); | buffer_get_u32(session->in_buffer, &status); | |||
/* | /* | |||
* It's much more than a channel closing. spec says it's the last | * It's much more than a channel closing. spec says it's the last | |||
* message sent by server (strange) | * message sent by server (strange) | |||
*/ | */ | |||
/* actually status is lost somewhere */ | /* actually status is lost somewhere */ | |||
channel->open = 0; | channel->open = 0; | |||
channel->remote_eof = 1; | channel->remote_eof = 1; | |||
skipping to change at line 256 | skipping to change at line 260 | |||
return -1; | return -1; | |||
} | } | |||
if (packet_send(session) != SSH_OK) { | if (packet_send(session) != SSH_OK) { | |||
return -1; | return -1; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
int channel_handle1(SSH_SESSION *session, int type) { | int channel_handle1(ssh_session session, int type) { | |||
ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type); | ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type); | |||
switch (type) { | switch (type) { | |||
case SSH_SMSG_STDOUT_DATA: | case SSH_SMSG_STDOUT_DATA: | |||
if (channel_rcv_data1(session,0) < 0) { | if (channel_rcv_data1(session,0) < 0) { | |||
return -1; | return -1; | |||
} | } | |||
break; | break; | |||
case SSH_SMSG_STDERR_DATA: | ||||
if (channel_rcv_data1(session,1) < 0) { | ||||
return -1; | ||||
} | ||||
break; | ||||
case SSH_SMSG_EXITSTATUS: | case SSH_SMSG_EXITSTATUS: | |||
if (channel_rcv_close1(session) < 0) { | if (channel_rcv_close1(session) < 0) { | |||
return -1; | return -1; | |||
} | } | |||
break; | break; | |||
default: | default: | |||
ssh_log(session, SSH_LOG_FUNCTIONS, "Unexepected message %d", type); | ssh_log(session, SSH_LOG_FUNCTIONS, "Unexepected message %d", type); | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
int channel_write1(CHANNEL *channel, const void *data, int len) { | int channel_write1(ssh_channel channel, const void *data, int len) { | |||
SSH_SESSION *session = channel->session; | ssh_session session = channel->session; | |||
int origlen = len; | int origlen = len; | |||
int effectivelen; | int effectivelen; | |||
const unsigned char *ptr=data; | ||||
while (len > 0) { | while (len > 0) { | |||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) { | if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) { | |||
return -1; | return -1; | |||
} | } | |||
effectivelen = len > 32000 ? 32000 : len; | effectivelen = len > 32000 ? 32000 : len; | |||
if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 || | if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 || | |||
buffer_add_data(session->out_buffer, data, effectivelen) < 0) { | buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) { | |||
return -1; | return -1; | |||
} | } | |||
data += effectivelen; | ptr += effectivelen; | |||
len -= effectivelen; | len -= effectivelen; | |||
if (packet_send(session) != SSH_OK) { | if (packet_send(session) != SSH_OK) { | |||
return -1; | return -1; | |||
} | } | |||
} | } | |||
return origlen; | return origlen; | |||
} | } | |||
End of changes. 17 change blocks. | ||||
25 lines changed or deleted | 34 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |