diff options
-rw-r--r-- | include/libssh/priv.h | 5 | ||||
-rw-r--r-- | include/libssh/server.h | 6 | ||||
-rw-r--r-- | libssh/messages.c | 130 |
3 files changed, 86 insertions, 55 deletions
diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 51e89c6b..68f0e183 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -427,6 +427,10 @@ struct ssh_channel_request_open { u16 destination_port; }; +struct ssh_service_request { + char *service; +}; + struct ssh_channel_request { int type; CHANNEL *channel; @@ -454,6 +458,7 @@ struct ssh_message { struct ssh_auth_request auth_request; struct ssh_channel_request_open channel_request_open; struct ssh_channel_request channel_request; + struct ssh_service_request service_request; }; #ifndef _WIN32 diff --git a/include/libssh/server.h b/include/libssh/server.h index 26c33199..495a8c8f 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -126,6 +126,7 @@ int ssh_accept(SSH_SESSION *session); #define SSH_AUTH_REQUEST 1 #define SSH_CHANNEL_REQUEST_OPEN 2 #define SSH_CHANNEL_REQUEST 3 +#define SSH_SERVICE_REQUEST 4 #define SSH_AUTH_NONE (1<<0) #define SSH_AUTH_PASSWORD (1<<1) @@ -149,6 +150,7 @@ int ssh_accept(SSH_SESSION *session); typedef struct ssh_message SSH_MESSAGE; +SSH_MESSAGE *ssh_message_retrieve(SSH_SESSION *session, u32 packettype); SSH_MESSAGE *ssh_message_get(SSH_SESSION *session); int ssh_message_type(SSH_MESSAGE *msg); int ssh_message_subtype(SSH_MESSAGE *msg); @@ -168,6 +170,10 @@ char *ssh_message_channel_request_pty_term(SSH_MESSAGE *msg); char *ssh_message_channel_request_subsystem(SSH_MESSAGE *msg); int ssh_message_channel_request_reply_success(SSH_MESSAGE *msg); +int ssh_message_service_reply_success(SSH_MESSAGE *msg); +char *ssh_message_service_service(SSH_MESSAGE *msg); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/libssh/messages.c b/libssh/messages.c index 4e84caf7..18946805 100644 --- a/libssh/messages.c +++ b/libssh/messages.c @@ -61,45 +61,66 @@ static SSH_MESSAGE *message_new(SSH_SESSION *session){ return msg; } -static int handle_service_request(SSH_SESSION *session) { +static SSH_MESSAGE *handle_service_request(SSH_SESSION *session) { STRING *service = NULL; char *service_c = NULL; - int rc = -1; + SSH_MESSAGE *msg=NULL; enter_function(); service = buffer_get_ssh_string(session->in_buffer); if (service == NULL) { ssh_set_error(session, SSH_FATAL, "Invalid SSH_MSG_SERVICE_REQUEST packet"); - leave_function(); - return -1; + goto error; } service_c = string_to_char(service); if (service_c == NULL) { goto error; } - ssh_log(session, SSH_LOG_PACKET, - "Sending a SERVICE_ACCEPT for service %s", service_c); - SAFE_FREE(service_c); + "Received a SERVICE_REQUEST for service %s", service_c); + msg=message_new(session); + if(!msg){ + SAFE_FREE(service_c); + goto error; + } + msg->type=SSH_SERVICE_REQUEST; + msg->service_request.service=service_c; + error: + leave_function(); + return msg; +} +static int ssh_message_service_request_reply_default(SSH_MESSAGE *msg) { + /* The only return code accepted by specifications are success or disconnect */ + return ssh_message_service_reply_success(msg); +} +int ssh_message_service_reply_success(SSH_MESSAGE *msg) { + struct string_struct *service; + SSH_SESSION *session=msg->session; + if (msg == NULL) { + return SSH_ERROR; + } + ssh_log(session, SSH_LOG_PACKET, + "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service); if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_ACCEPT) < 0) { - goto error; + return -1; } + service=string_from_char(msg->service_request.service); if (buffer_add_ssh_string(session->out_buffer, service) < 0) { - goto error; - } - if (packet_send(session) != SSH_OK) { - goto error; + string_free(service); + return -1; } - - rc = 0; -error: string_free(service); - leave_function(); + return packet_send(msg->session); +} - return rc; +char *ssh_message_service_service(SSH_MESSAGE *msg){ + if (msg == NULL) { + return NULL; + } + return msg->service_request.service; } static int handle_unimplemented(SSH_SESSION *session) { @@ -661,52 +682,48 @@ static int ssh_message_channel_request_reply_default(SSH_MESSAGE *msg) { return SSH_OK; } +SSH_MESSAGE *ssh_message_retrieve(SSH_SESSION *session, u32 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 blocking message retrieval + * \bug does anything that is not a message, like a channel read/write + */ SSH_MESSAGE *ssh_message_get(SSH_SESSION *session) { SSH_MESSAGE *msg = NULL; - enter_function(); - do { if ((packet_read(session) != SSH_OK) || (packet_translate(session) != SSH_OK)) { - goto error; - } - switch(session->in_packet.type) { - case SSH2_MSG_SERVICE_REQUEST: - if (handle_service_request(session) < 0) { - goto error; - } - break; - case SSH2_MSG_IGNORE: - case SSH2_MSG_DEBUG: - break; - case SSH2_MSG_USERAUTH_REQUEST: - msg = handle_userauth_request(session); - - leave_function(); - return msg; - case SSH2_MSG_CHANNEL_OPEN: - msg = handle_channel_request_open(session); - - leave_function(); - return msg; - case SSH2_MSG_CHANNEL_REQUEST: - msg = handle_channel_request(session); - leave_function(); - - return msg; - default: - if (handle_unimplemented(session) == 0) { - ssh_set_error(session, SSH_FATAL, - "Unhandled message %d\n", session->in_packet.type); - } - goto error; + leave_function(); + return NULL; } - } while(1); - -error: + } while(session->in_packet.type==SSH2_MSG_IGNORE || session->in_packet.type==SSH2_MSG_DEBUG); + msg=ssh_message_retrieve(session,session->in_packet.type); leave_function(); - return NULL; + return msg; } int ssh_message_type(SSH_MESSAGE *msg) { @@ -746,6 +763,8 @@ int ssh_message_reply_default(SSH_MESSAGE *msg) { return ssh_message_channel_request_open_reply_default(msg); case SSH_CHANNEL_REQUEST: return ssh_message_channel_request_reply_default(msg); + case SSH_SERVICE_REQUEST: + return ssh_message_service_request_reply_default(msg); default: ssh_log(msg->session, SSH_LOG_PACKET, "Don't know what to default reply to %d type", @@ -784,6 +803,7 @@ void ssh_message_free(SSH_MESSAGE *msg){ break; } ZERO_STRUCTP(msg); + SAFE_FREE(msg); } /** |