aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/priv.h5
-rw-r--r--include/libssh/server.h6
-rw-r--r--libssh/messages.c130
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);
}
/**