mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-30 13:01:23 +03:00
Some work for async channel requests
This commit is contained in:
@@ -23,6 +23,23 @@
|
|||||||
#define CHANNELS_H_
|
#define CHANNELS_H_
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* Describes the different possible states in a
|
||||||
|
* outgoing (client) channel request
|
||||||
|
*/
|
||||||
|
enum ssh_channel_request_state_e {
|
||||||
|
/** No request has been made */
|
||||||
|
SSH_CHANNEL_REQ_STATE_NONE = 0,
|
||||||
|
/** A request has been made and answer is pending */
|
||||||
|
SSH_CHANNEL_REQ_STATE_PENDING,
|
||||||
|
/** A request has been replied and accepted */
|
||||||
|
SSH_CHANNEL_REQ_STATE_ACCEPTED,
|
||||||
|
/** A request has been replied and refused */
|
||||||
|
SSH_CHANNEL_REQ_STATE_DENIED,
|
||||||
|
/** A request has been replied and an error happend */
|
||||||
|
SSH_CHANNEL_REQ_STATE_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
struct ssh_channel_struct {
|
struct ssh_channel_struct {
|
||||||
struct ssh_channel_struct *prev;
|
struct ssh_channel_struct *prev;
|
||||||
struct ssh_channel_struct *next;
|
struct ssh_channel_struct *next;
|
||||||
@@ -44,10 +61,13 @@ struct ssh_channel_struct {
|
|||||||
int version;
|
int version;
|
||||||
int blocking;
|
int blocking;
|
||||||
int exit_status;
|
int exit_status;
|
||||||
|
enum ssh_channel_request_state_e request_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail);
|
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_success);
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_failure);
|
||||||
|
|
||||||
void channel_handle(ssh_session session, int type);
|
void channel_handle(ssh_session session, int type);
|
||||||
ssh_channel channel_new(ssh_session session);
|
ssh_channel channel_new(ssh_session session);
|
||||||
|
|||||||
@@ -172,6 +172,16 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief open a channel by sending a SSH_OPEN_CHANNEL message and
|
||||||
|
* waiting reply.
|
||||||
|
* @param channel the current channel.
|
||||||
|
* @param type_c C string describing kind of channel (e.g. "exec").
|
||||||
|
* @param window receiving window of the channel. The window is the
|
||||||
|
* maximum size of data that can stay in buffers and network.
|
||||||
|
* @param maxpacket maximum packet size allowed (like MTU).
|
||||||
|
* @param payload buffer containing additionnal payload for the query.
|
||||||
|
*/
|
||||||
static int channel_open(ssh_channel channel, const char *type_c, int window,
|
static int channel_open(ssh_channel channel, const char *type_c, int window,
|
||||||
int maxpacket, ssh_buffer payload) {
|
int maxpacket, ssh_buffer payload) {
|
||||||
ssh_session session = channel->session;
|
ssh_session session = channel->session;
|
||||||
@@ -179,12 +189,11 @@ static int channel_open(ssh_channel channel, const char *type_c, int window,
|
|||||||
uint32_t tmp = 0;
|
uint32_t tmp = 0;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
channel->local_channel = ssh_channel_new_id(session);
|
channel->local_channel = ssh_channel_new_id(session);
|
||||||
channel->local_maxpacket = maxpacket;
|
channel->local_maxpacket = maxpacket;
|
||||||
channel->local_window = window;
|
channel->local_window = window;
|
||||||
|
|
||||||
ssh_log(session, SSH_LOG_RARE,
|
ssh_log(session, SSH_LOG_PROTOCOL,
|
||||||
"Creating a channel %d with %d window and %d max packet",
|
"Creating a channel %d with %d window and %d max packet",
|
||||||
channel->local_channel, window, maxpacket);
|
channel->local_channel, window, maxpacket);
|
||||||
|
|
||||||
@@ -218,7 +227,7 @@ static int channel_open(ssh_channel channel, const char *type_c, int window,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_log(session, SSH_LOG_RARE,
|
ssh_log(session, SSH_LOG_PACKET,
|
||||||
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
|
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
|
||||||
type_c, channel->local_channel);
|
type_c, channel->local_channel);
|
||||||
|
|
||||||
@@ -1066,6 +1075,14 @@ void channel_set_blocking(ssh_channel channel, int blocking) {
|
|||||||
channel->blocking = (blocking == 0 ? 0 : 1);
|
channel->blocking = (blocking == 0 ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_success){
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
|
||||||
static int channel_request(ssh_channel channel, const char *request,
|
static int channel_request(ssh_channel channel, const char *request,
|
||||||
ssh_buffer buffer, int reply) {
|
ssh_buffer buffer, int reply) {
|
||||||
ssh_session session = channel->session;
|
ssh_session session = channel->session;
|
||||||
@@ -1073,6 +1090,11 @@ static int channel_request(ssh_channel channel, const char *request,
|
|||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
|
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
|
||||||
|
ssh_set_error(session,SSH_REQUEST_DENIED,"channel_request_* used in incorrect state");
|
||||||
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
req = string_from_char(request);
|
req = string_from_char(request);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
@@ -1093,13 +1115,13 @@ static int channel_request(ssh_channel channel, const char *request,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING;
|
||||||
if (packet_send(session) != SSH_OK) {
|
if (packet_send(session) != SSH_OK) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_log(session, SSH_LOG_RARE,
|
ssh_log(session, SSH_LOG_PACKET,
|
||||||
"Sent a SSH_MSG_CHANNEL_REQUEST %s", request);
|
"Sent a SSH_MSG_CHANNEL_REQUEST %s", request);
|
||||||
if (reply == 0) {
|
if (reply == 0) {
|
||||||
leave_function();
|
leave_function();
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ ssh_packet_callback default_packet_handlers[]= {
|
|||||||
channel_rcv_eof, //#define SSH2_MSG_CHANNEL_EOF 96
|
channel_rcv_eof, //#define SSH2_MSG_CHANNEL_EOF 96
|
||||||
channel_rcv_close, //#define SSH2_MSG_CHANNEL_CLOSE 97
|
channel_rcv_close, //#define SSH2_MSG_CHANNEL_CLOSE 97
|
||||||
channel_rcv_request, //#define SSH2_MSG_CHANNEL_REQUEST 98
|
channel_rcv_request, //#define SSH2_MSG_CHANNEL_REQUEST 98
|
||||||
NULL, //#define SSH2_MSG_CHANNEL_SUCCESS 99
|
ssh_packet_channel_success, //#define SSH2_MSG_CHANNEL_SUCCESS 99
|
||||||
NULL, //#define SSH2_MSG_CHANNEL_FAILURE 100
|
ssh_packet_channel_failure, //#define SSH2_MSG_CHANNEL_FAILURE 100
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XXX include selected mac size */
|
/* XXX include selected mac size */
|
||||||
|
|||||||
Reference in New Issue
Block a user