diff options
-rw-r--r-- | include/libssh/libssh.h | 1 | ||||
-rw-r--r-- | include/libssh/messages.h | 3 | ||||
-rw-r--r-- | libssh/channels.c | 12 | ||||
-rw-r--r-- | libssh/messages.c | 211 |
4 files changed, 60 insertions, 167 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 350113c..39a1a0c 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -375,7 +375,6 @@ LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg); LIBSSH_API void ssh_message_free(ssh_message msg); LIBSSH_API ssh_message ssh_message_get(ssh_session session); -LIBSSH_API ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype); LIBSSH_API int ssh_message_subtype(ssh_message msg); LIBSSH_API int ssh_message_type(ssh_message msg); LIBSSH_API int ssh_mkdir (const char *pathname, mode_t mode); diff --git a/include/libssh/messages.h b/include/libssh/messages.h index 5d2e5e8..87fb5d7 100644 --- a/include/libssh/messages.h +++ b/include/libssh/messages.h @@ -81,7 +81,8 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open); SSH_PACKET_CALLBACK(ssh_packet_service_request); SSH_PACKET_CALLBACK(ssh_packet_userauth_request); -//void message_handle(ssh_session session, uint32_t type); +int message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet, + const char *request, uint8_t want_reply); int ssh_execute_message_callbacks(ssh_session session); void message_queue(ssh_session session, ssh_message message); diff --git a/libssh/channels.c b/libssh/channels.c index 0108f63..af20bde 100644 --- a/libssh/channels.c +++ b/libssh/channels.c @@ -534,7 +534,6 @@ SSH_PACKET_CALLBACK(channel_rcv_request) { ssh_string request_s; char *request; uint32_t status; - uint32_t startpos = session->in_buffer->pos; (void)user; (void)type; @@ -608,13 +607,12 @@ SSH_PACKET_CALLBACK(channel_rcv_request) { return SSH_PACKET_USED; } - /* TODO call message_handle since it handles channel requests as messages */ - /* *but* reset buffer before !! */ - - session->in_buffer->pos = startpos; - message_handle(session, NULL, SSH2_MSG_CHANNEL_REQUEST, session->in_buffer); + /* If we are here, that means we have a request that is not in the understood + * client requests. That means we need to create a ssh message to be passed + * to the user code handling ssh messages + */ + message_handle_channel_request(session,channel,packet,request,status); - ssh_log(session, SSH_LOG_PACKET, "Unknown request %s", request); SAFE_FREE(request); leave_function(); diff --git a/libssh/messages.c b/libssh/messages.c index 307fd06..7df52be 100644 --- a/libssh/messages.c +++ b/libssh/messages.c @@ -96,18 +96,6 @@ error: return SSH_PACKET_USED; } -static int handle_unimplemented(ssh_session session) { - if (buffer_add_u32(session->out_buffer, htonl(session->recv_seq - 1)) < 0) { - return -1; - } - - if (packet_send(session) != SSH_OK) { - return -1; - } - - return 0; -} - /** @internal * @brief Handle a SSH_MSG_MSG_USERAUTH_REQUEST packet and queue a * SSH Message @@ -513,57 +501,38 @@ error: return NULL; } -static ssh_message handle_channel_request(ssh_session session) { +/** @internal + * @brief This function parses the last end of a channel request packet, + * which is normally converted to a SSH message and placed on the queue. + * @param session SSH session. + * @param channel Channel the request is made on. + * @param packet rest of the packet to be parsed. + * @param request type of request. + * @param want_reply want_reply field from the request + * @returns SSH_OK or SSH_ERROR. + */ +int message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet, + const char *request, uint8_t want_reply) { ssh_message msg = NULL; - ssh_string type = NULL; - char *type_c = NULL; - uint32_t channel; - uint8_t want_reply; - enter_function(); - msg = message_new(session); if (msg == NULL) { ssh_set_error_oom(session); - return NULL; - } - - buffer_get_u32(session->in_buffer, &channel); - channel = ntohl(channel); - - type = buffer_get_ssh_string(session->in_buffer); - if (type == NULL) { - ssh_set_error_oom(session); goto error; } - type_c = string_to_char(type); - if (type_c == NULL) { - ssh_set_error_oom(session); - goto error; - } - string_free(type); - - buffer_get_u8(session->in_buffer,&want_reply); ssh_log(session, SSH_LOG_PACKET, - "Received a %s channel_request for channel %d (want_reply=%hhd)", - type_c, channel, want_reply); + "Received a %s channel_request for channel (%d:%d) (want_reply=%hhd)", + request, channel->local_channel, channel->remote_channel, want_reply); msg->type = SSH_REQUEST_CHANNEL; - msg->channel_request.channel = ssh_channel_from_local(session, channel); - if (msg->channel_request.channel == NULL) { - ssh_set_error(session, SSH_FATAL, "There are no channels with the id %u.", - channel); - goto error; - } + msg->channel_request.channel = channel; msg->channel_request.want_reply = want_reply; - if (strcmp(type_c, "pty-req") == 0) { + if (strcmp(request, "pty-req") == 0) { ssh_string term = NULL; char *term_c = NULL; - SAFE_FREE(type_c); - - term = buffer_get_ssh_string(session->in_buffer); + term = buffer_get_ssh_string(packet); if (term == NULL) { ssh_set_error_oom(session); goto error; @@ -579,51 +548,43 @@ static ssh_message handle_channel_request(ssh_session session) { msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY; msg->channel_request.TERM = term_c; - buffer_get_u32(session->in_buffer, &msg->channel_request.width); - buffer_get_u32(session->in_buffer, &msg->channel_request.height); - buffer_get_u32(session->in_buffer, &msg->channel_request.pxwidth); - buffer_get_u32(session->in_buffer, &msg->channel_request.pxheight); + buffer_get_u32(packet, &msg->channel_request.width); + buffer_get_u32(packet, &msg->channel_request.height); + buffer_get_u32(packet, &msg->channel_request.pxwidth); + buffer_get_u32(packet, &msg->channel_request.pxheight); msg->channel_request.width = ntohl(msg->channel_request.width); msg->channel_request.height = ntohl(msg->channel_request.height); msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth); msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight); - msg->channel_request.modes = buffer_get_ssh_string(session->in_buffer); + msg->channel_request.modes = buffer_get_ssh_string(packet); if (msg->channel_request.modes == NULL) { SAFE_FREE(term_c); goto error; } - - leave_function(); - return msg; + goto end; } - if (strcmp(type_c, "window-change") == 0) { - SAFE_FREE(type_c); - + if (strcmp(request, "window-change") == 0) { msg->channel_request.type = SSH_CHANNEL_REQUEST_WINDOW_CHANGE; - buffer_get_u32(session->in_buffer, &msg->channel_request.width); - buffer_get_u32(session->in_buffer, &msg->channel_request.height); - buffer_get_u32(session->in_buffer, &msg->channel_request.pxwidth); - buffer_get_u32(session->in_buffer, &msg->channel_request.pxheight); + buffer_get_u32(packet, &msg->channel_request.width); + buffer_get_u32(packet, &msg->channel_request.height); + buffer_get_u32(packet, &msg->channel_request.pxwidth); + buffer_get_u32(packet, &msg->channel_request.pxheight); msg->channel_request.width = ntohl(msg->channel_request.width); msg->channel_request.height = ntohl(msg->channel_request.height); msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth); msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight); - leave_function(); - return msg; + goto end; } - if (strcmp(type_c, "subsystem") == 0) { + if (strcmp(request, "subsystem") == 0) { ssh_string subsys = NULL; char *subsys_c = NULL; - - SAFE_FREE(type_c); - - subsys = buffer_get_ssh_string(session->in_buffer); + subsys = buffer_get_ssh_string(packet); if (subsys == NULL) { ssh_set_error_oom(session); goto error; @@ -639,64 +600,50 @@ static ssh_message handle_channel_request(ssh_session session) { msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM; msg->channel_request.subsystem = subsys_c; - leave_function(); - return msg; + goto end; } - if (strcmp(type_c, "shell") == 0) { - SAFE_FREE(type_c); + if (strcmp(request, "shell") == 0) { msg->channel_request.type = SSH_CHANNEL_REQUEST_SHELL; - - leave_function(); - return msg; + goto end; } - if (strcmp(type_c, "exec") == 0) { + if (strcmp(request, "exec") == 0) { ssh_string cmd = NULL; - - SAFE_FREE(type_c); - - cmd = buffer_get_ssh_string(session->in_buffer); + cmd = buffer_get_ssh_string(packet); if (cmd == NULL) { ssh_set_error_oom(session); goto error; } - msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC; msg->channel_request.command = string_to_char(cmd); + string_free(cmd); if (msg->channel_request.command == NULL) { - string_free(cmd); goto error; } - string_free(cmd); - - leave_function(); - return msg; + goto end; } - if (strcmp(type_c, "env") == 0) { + if (strcmp(request, "env") == 0) { ssh_string name = NULL; ssh_string value = NULL; - - SAFE_FREE(type_c); - - name = buffer_get_ssh_string(session->in_buffer); + name = buffer_get_ssh_string(packet); if (name == NULL) { ssh_set_error_oom(session); goto error; } - value = buffer_get_ssh_string(session->in_buffer); - if (value == NULL) { - ssh_set_error_oom(session); - string_free(name); - goto error; - } + value = buffer_get_ssh_string(packet); + if (value == NULL) { + ssh_set_error_oom(session); + string_free(name); + goto error; + } msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV; msg->channel_request.var_name = string_to_char(name); msg->channel_request.var_value = string_to_char(value); if (msg->channel_request.var_name == NULL || - msg->channel_request.var_value == NULL) { + msg->channel_request.var_value == NULL) { string_free(name); string_free(value); goto error; @@ -704,22 +651,19 @@ static ssh_message handle_channel_request(ssh_session session) { string_free(name); string_free(value); - leave_function(); - return msg; + goto end; } msg->channel_request.type = SSH_CHANNEL_UNKNOWN; - SAFE_FREE(type_c); - +end: + message_queue(session,msg); leave_function(); - return msg; + return SSH_OK; error: - string_free(type); - SAFE_FREE(type_c); ssh_message_free(msg); leave_function(); - return NULL; + return SSH_ERROR; } int ssh_message_channel_request_reply_success(ssh_message msg) { @@ -751,33 +695,6 @@ int ssh_message_channel_request_reply_success(ssh_message msg) { return SSH_OK; } -/* TODO this function should disapear in favor of SSH_PACKET handlers */ -ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype){ - ssh_message msg=NULL; - enter_function(); - switch(packettype) { - case SSH2_MSG_SERVICE_REQUEST: -// msg=handle_service_request(session); - break; - case SSH2_MSG_USERAUTH_REQUEST: -// msg = handle_userauth_request(session); - break; - case SSH2_MSG_CHANNEL_OPEN: -// msg = handle_channel_request_open(session); - break; - case SSH2_MSG_CHANNEL_REQUEST: - msg = handle_channel_request(session); - break; - default: - if (handle_unimplemented(session) == 0) { - ssh_set_error(session, SSH_FATAL, - "Unhandled message %d\n", session->in_packet.type); - } - } - leave_function(); - return msg; -} - /** @brief Retrieves a SSH message from SSH session * @param session SSH session * @return The SSH message received, NULL in case of error. @@ -794,6 +711,7 @@ ssh_message ssh_message_get(ssh_session session) { } msg=ssh_list_get_head(ssh_message, session->ssh_message_list); } while(msg==NULL); + leave_function(); return msg; } @@ -859,29 +777,6 @@ void ssh_message_free(ssh_message msg){ } /** @internal - * @brief handle various SSH request messages and stack them for callback. - * @param session SSH session. - * @param user user provided value. - * @param type packet type. - * @param packet buffer. - * @return SSH_PACKET_USED if a message has been created. - * @return SSH_PACKET_NOT_USED if the packet could not be used to create a - * message. - */ -int message_handle(ssh_session session, void *user, uint8_t type, ssh_buffer packet){ - ssh_message msg=ssh_message_retrieve(session,type); - ssh_log(session,SSH_LOG_PROTOCOL,"Stacking message from packet type %d",type); - (void)user; - (void)packet; - if(msg){ - message_queue(session,msg); - return SSH_PACKET_USED; - } else { - return SSH_PACKET_NOT_USED; - } -} - -/** @internal * @brief adds the message to the current queue of messages to be parsed * @param session SSH session * @param message message to add to the queue |