1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-02 01:17:52 +03:00

Improve channel_open().

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@673 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
Andreas Schneider
2009-05-02 20:41:21 +00:00
parent f0b14c7b7a
commit c31893d246

View File

@@ -106,46 +106,45 @@ u32 ssh_channel_new_id(SSH_SESSION *session) {
static int channel_open(CHANNEL *channel, const char *type_c, int window, static int channel_open(CHANNEL *channel, const char *type_c, int window,
int maxpacket, BUFFER *payload) { int maxpacket, BUFFER *payload) {
SSH_SESSION *session=channel->session; SSH_SESSION *session = channel->session;
STRING *type = NULL; STRING *type = NULL;
u32 foo; u32 tmp = 0;
int err;
enter_function(); enter_function();
channel->local_channel=ssh_channel_new_id(session); channel->local_channel = ssh_channel_new_id(session);
channel->local_maxpacket=maxpacket; channel->local_maxpacket = maxpacket;
channel->local_window=window; channel->local_window = window;
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_RARE,
"creating a channel %d with %d window and %d max packet", "Creating a channel %d with %d window and %d max packet",
channel->local_channel, window,maxpacket); channel->local_channel, window, maxpacket);
type = string_from_char(type_c); type = string_from_char(type_c);
if (type == NULL) { if (type == NULL) {
goto error; leave_function();
return -1;
} }
if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN) < 0) { if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN) < 0 ||
goto error; buffer_add_ssh_string(session->out_buffer,type) < 0 ||
} buffer_add_u32(session->out_buffer, htonl(channel->local_channel)) < 0 ||
if (buffer_add_ssh_string(session->out_buffer,type) < 0) { buffer_add_u32(session->out_buffer, htonl(channel->local_window)) < 0 ||
goto error; buffer_add_u32(session->out_buffer, htonl(channel->local_maxpacket)) < 0) {
} string_free(type);
if (buffer_add_u32(session->out_buffer, htonl(channel->local_channel)) < 0) { leave_function();
goto error; return -1;
}
if (buffer_add_u32(session->out_buffer, htonl(channel->local_window)) < 0) {
goto error;
}
if (buffer_add_u32(session->out_buffer, htonl(channel->local_maxpacket)) < 0) {
goto error;
} }
string_free(type); string_free(type);
if (payload) { if (payload != NULL) {
if (buffer_add_buffer(session->out_buffer, payload) < 0) { if (buffer_add_buffer(session->out_buffer, payload) < 0) {
goto error; leave_function();
return -1;
} }
} }
if (packet_send(session) != SSH_OK) { if (packet_send(session) != SSH_OK) {
leave_function(); leave_function();
return -1; return -1;
@@ -154,22 +153,33 @@ static int channel_open(CHANNEL *channel, const char *type_c, int window,
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_RARE,
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d", "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
type_c, channel->local_channel); type_c, channel->local_channel);
err=packet_wait(session,SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,1);
switch(session->in_packet.type){ if (packet_wait(session, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, 1) != SSH_OK) {
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
buffer_get_u32(session->in_buffer,&foo);
if(channel->local_channel!=ntohl(foo)){
ssh_set_error(session,SSH_FATAL,"server answered with sender chan num %d instead of given %d",
ntohl(foo),channel->local_channel);
leave_function(); leave_function();
return -1; return -1;
} }
buffer_get_u32(session->in_buffer,&foo);
channel->remote_channel=ntohl(foo); switch(session->in_packet.type) {
buffer_get_u32(session->in_buffer,&foo); case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
channel->remote_window=ntohl(foo); buffer_get_u32(session->in_buffer, &tmp);
buffer_get_u32(session->in_buffer,&foo);
channel->remote_maxpacket=ntohl(foo); if (channel->local_channel != ntohl(tmp)) {
ssh_set_error(session, SSH_FATAL,
"Server answered with sender channel number %d instead of given %d",
ntohl(tmp),
channel->local_channel);
leave_function();
return -1;
}
buffer_get_u32(session->in_buffer, &tmp);
channel->remote_channel = ntohl(tmp);
buffer_get_u32(session->in_buffer, &tmp);
channel->remote_window = ntohl(tmp);
buffer_get_u32(session->in_buffer,&tmp);
channel->remote_maxpacket=ntohl(tmp);
ssh_log(session, SSH_LOG_PROTOCOL, ssh_log(session, SSH_LOG_PROTOCOL,
"Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d", "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
channel->local_channel, channel->local_channel,
@@ -178,34 +188,43 @@ static int channel_open(CHANNEL *channel, const char *type_c, int window,
"Remote window : %lu, maxpacket : %lu", "Remote window : %lu, maxpacket : %lu",
(long unsigned int) channel->remote_window, (long unsigned int) channel->remote_window,
(long unsigned int) channel->remote_maxpacket); (long unsigned int) channel->remote_maxpacket);
channel->open=1;
channel->open = 1;
leave_function(); leave_function();
return 0; return 0;
case SSH2_MSG_CHANNEL_OPEN_FAILURE: case SSH2_MSG_CHANNEL_OPEN_FAILURE:
{ {
u32 code;
STRING *error_s; STRING *error_s;
char *error; char *error;
buffer_get_u32(session->in_buffer,&foo); u32 code;
buffer_get_u32(session->in_buffer,&code);
error_s=buffer_get_ssh_string(session->in_buffer); buffer_get_u32(session->in_buffer, &tmp);
error=string_to_char(error_s); buffer_get_u32(session->in_buffer, &code);
ssh_set_error(session,SSH_REQUEST_DENIED,"Channel opening failure : channel %d error (%d) %s",
channel->local_channel,ntohl(code),error); error_s = buffer_get_ssh_string(session->in_buffer);
free(error); error = string_to_char(error_s);
free(error_s); string_free(error_s);
leave_function(); if (error == NULL) {
return -1;
}
default:
ssh_set_error(session,SSH_FATAL,"Received unknown packet %d\n",session->in_packet.type);
leave_function(); leave_function();
return -1; return -1;
} }
error: ssh_set_error(session, SSH_REQUEST_DENIED,
buffer_free(session->out_buffer); "Channel opening failure: channel %d error (%d) %s",
string_free(type); channel->local_channel,
ntohl(code),
error);
SAFE_FREE(error);
leave_function();
return -1;
}
default:
ssh_set_error(session, SSH_FATAL,
"Received unknown packet %d\n", session->in_packet.type);
leave_function();
return -1;
}
leave_function(); leave_function();
return -1; return -1;