aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorAndreas Schneider <mail@cynapses.org>2009-05-02 20:41:21 +0000
committerAndreas Schneider <mail@cynapses.org>2009-05-02 20:41:21 +0000
commitc31893d24608a0d0903afdc267e2c7517f1ef6fa (patch)
treee421e16bacd8839ce54fad124f161de590f1aed2 /libssh
parentf0b14c7b7a3d7b4192bc03fc8d8e1e72d5b9216f (diff)
downloadlibssh-c31893d24608a0d0903afdc267e2c7517f1ef6fa.tar.gz
libssh-c31893d24608a0d0903afdc267e2c7517f1ef6fa.tar.xz
libssh-c31893d24608a0d0903afdc267e2c7517f1ef6fa.zip
Improve channel_open().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@673 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'libssh')
-rw-r--r--libssh/channels.c199
1 files changed, 109 insertions, 90 deletions
diff --git a/libssh/channels.c b/libssh/channels.c
index e85fb3e..2c2b6ac 100644
--- a/libssh/channels.c
+++ b/libssh/channels.c
@@ -106,109 +106,128 @@ u32 ssh_channel_new_id(SSH_SESSION *session) {
static int channel_open(CHANNEL *channel, const char *type_c, int window,
int maxpacket, BUFFER *payload) {
- SSH_SESSION *session=channel->session;
- STRING *type = NULL;
- u32 foo;
- int err;
- enter_function();
+ SSH_SESSION *session = channel->session;
+ STRING *type = NULL;
+ u32 tmp = 0;
- channel->local_channel=ssh_channel_new_id(session);
- channel->local_maxpacket=maxpacket;
- channel->local_window=window;
- ssh_log(session, SSH_LOG_RARE,
- "creating a channel %d with %d window and %d max packet",
- channel->local_channel, window,maxpacket);
- type = string_from_char(type_c);
- if (type == NULL) {
- goto error;
- }
+ enter_function();
- if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN) < 0) {
- goto error;
- }
- if (buffer_add_ssh_string(session->out_buffer,type) < 0) {
- goto error;
- }
- if (buffer_add_u32(session->out_buffer, htonl(channel->local_channel)) < 0) {
- goto error;
- }
- 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;
- }
+ channel->local_channel = ssh_channel_new_id(session);
+ channel->local_maxpacket = maxpacket;
+ channel->local_window = window;
+
+ ssh_log(session, SSH_LOG_RARE,
+ "Creating a channel %d with %d window and %d max packet",
+ channel->local_channel, window, maxpacket);
+
+ type = string_from_char(type_c);
+ if (type == NULL) {
+ leave_function();
+ return -1;
+ }
+ if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN) < 0 ||
+ buffer_add_ssh_string(session->out_buffer,type) < 0 ||
+ buffer_add_u32(session->out_buffer, htonl(channel->local_channel)) < 0 ||
+ buffer_add_u32(session->out_buffer, htonl(channel->local_window)) < 0 ||
+ buffer_add_u32(session->out_buffer, htonl(channel->local_maxpacket)) < 0) {
string_free(type);
+ leave_function();
+ return -1;
+ }
- if (payload) {
- if (buffer_add_buffer(session->out_buffer, payload) < 0) {
- goto error;
- }
- }
- if (packet_send(session) != SSH_OK) {
+ string_free(type);
+
+ if (payload != NULL) {
+ if (buffer_add_buffer(session->out_buffer, payload) < 0) {
leave_function();
return -1;
}
+ }
- ssh_log(session, SSH_LOG_RARE,
- "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
- type_c, channel->local_channel);
- err=packet_wait(session,SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,1);
- switch(session->in_packet.type){
- 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();
- return -1;
- }
- buffer_get_u32(session->in_buffer,&foo);
- channel->remote_channel=ntohl(foo);
- buffer_get_u32(session->in_buffer,&foo);
- channel->remote_window=ntohl(foo);
- buffer_get_u32(session->in_buffer,&foo);
- channel->remote_maxpacket=ntohl(foo);
- ssh_log(session, SSH_LOG_PROTOCOL,
- "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
- channel->local_channel,
- channel->remote_channel);
- ssh_log(session, SSH_LOG_PROTOCOL,
- "Remote window : %lu, maxpacket : %lu",
- (long unsigned int) channel->remote_window,
- (long unsigned int) channel->remote_maxpacket);
- channel->open=1;
- leave_function();
- return 0;
- case SSH2_MSG_CHANNEL_OPEN_FAILURE:
- {
- u32 code;
- STRING *error_s;
- char *error;
- buffer_get_u32(session->in_buffer,&foo);
- buffer_get_u32(session->in_buffer,&code);
- error_s=buffer_get_ssh_string(session->in_buffer);
- error=string_to_char(error_s);
- ssh_set_error(session,SSH_REQUEST_DENIED,"Channel opening failure : channel %d error (%d) %s",
- channel->local_channel,ntohl(code),error);
- free(error);
- free(error_s);
- leave_function();
- return -1;
- }
- default:
- ssh_set_error(session,SSH_FATAL,"Received unknown packet %d\n",session->in_packet.type);
- leave_function();
- return -1;
- }
+ if (packet_send(session) != SSH_OK) {
+ leave_function();
+ return -1;
+ }
-error:
- buffer_free(session->out_buffer);
- string_free(type);
+ ssh_log(session, SSH_LOG_RARE,
+ "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
+ type_c, channel->local_channel);
+ if (packet_wait(session, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, 1) != SSH_OK) {
leave_function();
return -1;
+ }
+
+ switch(session->in_packet.type) {
+ case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
+ buffer_get_u32(session->in_buffer, &tmp);
+
+ 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,
+ "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
+ channel->local_channel,
+ channel->remote_channel);
+ ssh_log(session, SSH_LOG_PROTOCOL,
+ "Remote window : %lu, maxpacket : %lu",
+ (long unsigned int) channel->remote_window,
+ (long unsigned int) channel->remote_maxpacket);
+
+ channel->open = 1;
+ leave_function();
+ return 0;
+ case SSH2_MSG_CHANNEL_OPEN_FAILURE:
+ {
+ STRING *error_s;
+ char *error;
+ u32 code;
+
+ buffer_get_u32(session->in_buffer, &tmp);
+ buffer_get_u32(session->in_buffer, &code);
+
+ error_s = buffer_get_ssh_string(session->in_buffer);
+ error = string_to_char(error_s);
+ string_free(error_s);
+ if (error == NULL) {
+ leave_function();
+ return -1;
+ }
+
+ ssh_set_error(session, SSH_REQUEST_DENIED,
+ "Channel opening failure: channel %d error (%d) %s",
+ 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();
+ return -1;
}
CHANNEL *ssh_channel_from_local(SSH_SESSION *session,u32 num){