aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/priv.h8
-rw-r--r--include/libssh/server.h3
-rw-r--r--libssh/messages.c54
-rw-r--r--libssh/packet.c3
-rw-r--r--libssh/session.c9
5 files changed, 63 insertions, 14 deletions
diff --git a/include/libssh/priv.h b/include/libssh/priv.h
index d0d0ea2d..dab9aa73 100644
--- a/include/libssh/priv.h
+++ b/include/libssh/priv.h
@@ -324,6 +324,8 @@ struct keys_struct {
const char *publickey;
};
+struct ssh_message;
+
struct ssh_session {
struct error_struct error;
struct socket *socket;
@@ -386,7 +388,8 @@ struct ssh_session {
/* auths accepted by server */
int auth_methods;
int hostkeys; /* contains type of host key wanted by client, in server impl */
- struct ssh_message *ssh_message; /* ssh message */
+ struct ssh_list *ssh_message_list; /* list of delayed SSH messages */
+ int (*ssh_message_callback)( struct ssh_session *session,struct ssh_message *msg);
int log_verbosity; /*cached copy of the option structure */
int log_indent; /* indentation level in enter_function logs */
};
@@ -737,7 +740,7 @@ const void *_ssh_list_get_head(struct ssh_list *list);
* @return the first element of the list
*/
#define ssh_list_get_head(type, ssh_list)\
- ((type)_ssh_list_head(ssh_list))
+ ((type)_ssh_list_get_head(ssh_list))
/* channels1.c */
@@ -760,6 +763,7 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
/* messages.c */
void message_handle(SSH_SESSION *session, u32 type);
+int ssh_execute_message_callbacks(SSH_SESSION *session);
/* log.c */
diff --git a/include/libssh/server.h b/include/libssh/server.h
index 495a8c8f..915edd8d 100644
--- a/include/libssh/server.h
+++ b/include/libssh/server.h
@@ -173,7 +173,8 @@ 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);
-
+void ssh_set_message_callback(SSH_SESSION *session,
+ int(*ssh_message_callback)(struct ssh_session *session, struct ssh_message *msg));
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libssh/messages.c b/libssh/messages.c
index 425829bb..d67f9982 100644
--- a/libssh/messages.c
+++ b/libssh/messages.c
@@ -3,7 +3,7 @@
*
* This file is part of the SSH Library
*
- * Copyright (c) 2003-2005 by Aris Adamantiadis
+ * Copyright (c) 2003-2009 by Aris Adamantiadis
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -46,18 +46,13 @@
static SSH_MESSAGE *message_new(SSH_SESSION *session){
- SSH_MESSAGE *msg = session->ssh_message;
-
+ SSH_MESSAGE *msg = malloc(sizeof(SSH_MESSAGE));
if (msg == NULL) {
- msg = malloc(sizeof(SSH_MESSAGE));
- if (msg == NULL) {
- return NULL;
- }
- session->ssh_message = msg;
+ return NULL;
}
+
memset(msg, 0, sizeof(*msg));
msg->session = session;
-
return msg;
}
@@ -815,9 +810,48 @@ void ssh_message_free(SSH_MESSAGE *msg){
void message_handle(SSH_SESSION *session, u32 type){
SSH_MESSAGE *msg=ssh_message_retrieve(session,type);
if(msg){
- /* TODO store msg somewhere */
+ if(!session->ssh_message_list){
+ session->ssh_message_list=ssh_list_new();
+ }
+ ssh_list_add(session->ssh_message_list,msg);
}
}
+
+/** @brief defines the SSH_MESSAGE callback
+ * @param session the current ssh session
+ * @param ssh_message_callback a function pointer to a callback taking the
+ * current ssh session and received message as parameters. the function returns
+ * 0 if the message has been parsed and treated sucessfuly, 1 otherwise (libssh
+ * must take care of the response).
+ */
+void ssh_set_message_callback(SSH_SESSION *session,
+ int(*ssh_message_callback)(struct ssh_session *session, struct ssh_message *msg)){
+ session->ssh_message_callback=ssh_message_callback;
+}
+
+int ssh_execute_message_callbacks(SSH_SESSION *session){
+ SSH_MESSAGE *msg=NULL;
+ int ret;
+ if(!session->ssh_message_list)
+ return SSH_OK;
+ if(session->ssh_message_callback){
+ while((msg=ssh_list_get_head(SSH_MESSAGE *, session->ssh_message_list)) != NULL){
+ ret=session->ssh_message_callback(session,msg);
+ if(ret==1){
+ ret = ssh_message_reply_default(msg);
+ if(ret != SSH_OK)
+ return ret;
+ }
+ }
+ } else {
+ while((msg=ssh_list_get_head(SSH_MESSAGE *, session->ssh_message_list)) != NULL){
+ ret = ssh_message_reply_default(msg);
+ if(ret != SSH_OK)
+ return ret;
+ }
+ }
+ return SSH_OK;
+}
/**
* @}
*/
diff --git a/libssh/packet.c b/libssh/packet.c
index 870efd4a..2304441c 100644
--- a/libssh/packet.c
+++ b/libssh/packet.c
@@ -753,6 +753,9 @@ static int packet_wait2(SSH_SESSION *session, int type, int blocking) {
case SSH2_MSG_CHANNEL_REQUEST:
case SSH2_MSG_CHANNEL_EOF:
case SSH2_MSG_CHANNEL_CLOSE:
+ case SSH2_MSG_SERVICE_REQUEST:
+ case SSH2_MSG_USERAUTH_REQUEST:
+ case SSH2_MSG_CHANNEL_OPEN:
packet_parse(session);
break;
case SSH2_MSG_IGNORE:
diff --git a/libssh/session.c b/libssh/session.c
index e8f63361..c83fecdc 100644
--- a/libssh/session.c
+++ b/libssh/session.c
@@ -125,7 +125,14 @@ void ssh_cleanup(SSH_SESSION *session) {
privatekey_free(session->dsa_key);
privatekey_free(session->rsa_key);
- ssh_message_free(session->ssh_message);
+ if(session->ssh_message_list){
+ SSH_MESSAGE *msg;
+ while((msg=ssh_list_get_head(SSH_MESSAGE *,session->ssh_message_list))
+ != NULL){
+ ssh_message_free(msg);
+ }
+ ssh_list_free(session->ssh_message_list);
+ }
ssh_options_free(session->options);
/* burn connection, it could hang sensitive datas */