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/