/* TODO: make this function accept a ssh_channel */ ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) { ssh_session session; ssh_channel chan = NULL; enter_function(); if (msg == NULL) { leave_function(); return NULL; } session = msg->session; chan = ssh_channel_new(session); if (chan == NULL) { leave_function(); return NULL; } chan->local_channel = ssh_channel_new_id(session); chan->local_maxpacket = 35000; chan->local_window = 32000; chan->remote_channel = msg->channel_request_open.sender; chan->remote_maxpacket = msg->channel_request_open.packet_size; chan->remote_window = msg->channel_request_open.window; chan->state = SSH_CHANNEL_STATE_OPEN; if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) < 0) { goto error; } if (buffer_add_u32(session->out_buffer, htonl(chan->remote_channel)) < 0) { goto error; } if (buffer_add_u32(session->out_buffer, htonl(chan->local_channel)) < 0) { goto error; } if (buffer_add_u32(session->out_buffer, htonl(chan->local_window)) < 0) { goto error; } if (buffer_add_u32(session->out_buffer, htonl(chan->local_maxpacket)) < 0) { goto error; } ssh_log(session, SSH_LOG_PACKET, "Accepting a channel request_open for chan %d", chan->remote_channel); if (packet_send(session) == SSH_ERROR) { goto error; } leave_function(); return chan; error: ssh_channel_free(chan); leave_function(); return NULL; }
int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan) { ssh_session session; int rc; if (msg == NULL) { return SSH_ERROR; } session = msg->session; chan->local_channel = ssh_channel_new_id(session); chan->local_maxpacket = 35000; chan->local_window = 32000; chan->remote_channel = msg->channel_request_open.sender; chan->remote_maxpacket = msg->channel_request_open.packet_size; chan->remote_window = msg->channel_request_open.window; chan->state = SSH_CHANNEL_STATE_OPEN; rc = buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); if (rc < 0) { return SSH_ERROR; } rc = buffer_add_u32(session->out_buffer, htonl(chan->remote_channel)); if (rc < 0) { return SSH_ERROR; } rc =buffer_add_u32(session->out_buffer, htonl(chan->local_channel)); if (rc < 0) { return SSH_ERROR; } rc = buffer_add_u32(session->out_buffer, htonl(chan->local_window)); if (rc < 0) { return SSH_ERROR; } rc = buffer_add_u32(session->out_buffer, htonl(chan->local_maxpacket)); if (rc < 0) { return SSH_ERROR; } SSH_LOG(SSH_LOG_PACKET, "Accepting a channel request_open for chan %d", chan->remote_channel); rc = packet_send(session); return rc; }
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 tmp = 0; enter_function(); 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; } string_free(type); if (payload != NULL) { if (buffer_add_buffer(session->out_buffer, payload) < 0) { leave_function(); return -1; } } if (packet_send(session) != SSH_OK) { 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); 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 %lu instead of given %u", (long unsigned int) 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 %u error (%lu) %s", channel->local_channel, (long unsigned int) 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; }