mirror of
https://github.com/kingToolbox/WindTerm.git
synced 2025-03-14 10:10:06 +08:00
Add support for external socket in libssh.
This commit is contained in:
parent
ee1a5ca4ae
commit
3b5a92f238
@ -400,6 +400,17 @@ struct ssh_socket_callbacks_struct {
|
||||
};
|
||||
typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
|
||||
|
||||
struct ssh_socket_external_callbacks_struct {
|
||||
/**
|
||||
* User-provided data. User is free to set anything he wants here
|
||||
*/
|
||||
void *userdata;
|
||||
/** This function will be called each time data need send.
|
||||
*/
|
||||
ssh_callback_data send;
|
||||
};
|
||||
typedef struct ssh_socket_external_callbacks_struct *ssh_socket_external_callbacks;
|
||||
|
||||
#define SSH_SOCKET_FLOW_WRITEWILLBLOCK 1
|
||||
#define SSH_SOCKET_FLOW_WRITEWONTBLOCK 2
|
||||
|
||||
|
@ -362,6 +362,9 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_HOST,
|
||||
SSH_OPTIONS_PORT,
|
||||
SSH_OPTIONS_PORT_STR,
|
||||
SSH_OPTIONS_PROXY_HOST,
|
||||
SSH_OPTIONS_PROXY_PORT,
|
||||
SSH_OPTIONS_PROXY_PORT_STR,
|
||||
SSH_OPTIONS_FD,
|
||||
SSH_OPTIONS_USER,
|
||||
SSH_OPTIONS_SSH_DIR,
|
||||
@ -400,6 +403,7 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_PROCESS_CONFIG,
|
||||
SSH_OPTIONS_REKEY_DATA,
|
||||
SSH_OPTIONS_REKEY_TIME,
|
||||
SSH_OPTIONS_EXTERNAL_CALLBACKS
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -200,6 +200,7 @@ struct ssh_session_struct {
|
||||
struct ssh_packet_callbacks_struct default_packet_callbacks;
|
||||
struct ssh_list *packet_callbacks;
|
||||
struct ssh_socket_callbacks_struct socket_callbacks;
|
||||
struct ssh_socket_external_callbacks_struct socket_external_callbacks;
|
||||
ssh_poll_ctx default_poll_ctx;
|
||||
/* options */
|
||||
#ifdef WITH_PCAP
|
||||
@ -209,6 +210,7 @@ struct ssh_session_struct {
|
||||
struct ssh_list *identity;
|
||||
char *username;
|
||||
char *host;
|
||||
char *proxy_host;
|
||||
char *bindaddr; /* bind the client to an ip addr */
|
||||
char *sshdir;
|
||||
char *knownhosts;
|
||||
@ -220,6 +222,7 @@ struct ssh_session_struct {
|
||||
unsigned long timeout; /* seconds */
|
||||
unsigned long timeout_usec;
|
||||
unsigned int port;
|
||||
unsigned int proxy_port;
|
||||
socket_t fd;
|
||||
int StrictHostKeyChecking;
|
||||
char compressionlevel;
|
||||
|
@ -60,6 +60,7 @@ int ssh_socket_set_nonblocking(socket_t fd);
|
||||
int ssh_socket_set_blocking(socket_t fd);
|
||||
|
||||
void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
|
||||
void ssh_socket_set_external_callbacks(ssh_socket s, ssh_socket_external_callbacks external_callbacks);
|
||||
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);
|
||||
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle(ssh_socket s);
|
||||
|
||||
|
@ -571,6 +571,8 @@ int ssh_connect(ssh_session session)
|
||||
session->socket_callbacks.exception = ssh_socket_exception_callback;
|
||||
session->socket_callbacks.userdata = session;
|
||||
|
||||
ssh_socket_set_external_callbacks(session->socket, &session->socket_external_callbacks);
|
||||
|
||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||
@ -581,10 +583,17 @@ int ssh_connect(ssh_session session)
|
||||
session->opts.ProxyCommand);
|
||||
#endif
|
||||
} else {
|
||||
ret = ssh_socket_connect(session->socket,
|
||||
session->opts.host,
|
||||
session->opts.port > 0 ? session->opts.port : 22,
|
||||
session->opts.bindaddr);
|
||||
if (session->opts.proxy_host != NULL) {
|
||||
ret = ssh_socket_connect(session->socket,
|
||||
session->opts.proxy_host,
|
||||
session->opts.proxy_port > 0 ? session->opts.proxy_port : 22,
|
||||
session->opts.bindaddr);
|
||||
} else {
|
||||
ret = ssh_socket_connect(session->socket,
|
||||
session->opts.host,
|
||||
session->opts.port > 0 ? session->opts.port : 22,
|
||||
session->opts.bindaddr);
|
||||
}
|
||||
}
|
||||
if (ret == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
|
@ -520,7 +520,44 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_PROXY_HOST:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
q = strdup(value);
|
||||
if (q == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
p = strchr(q, '@');
|
||||
|
||||
SAFE_FREE(session->opts.proxy_host);
|
||||
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
session->opts.proxy_host = strdup(p + 1);
|
||||
if (session->opts.proxy_host == NULL) {
|
||||
SAFE_FREE(q);
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SAFE_FREE(session->opts.username);
|
||||
session->opts.username = strdup(q);
|
||||
SAFE_FREE(q);
|
||||
if (session->opts.username == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
session->opts.proxy_host = q;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_PORT:
|
||||
case SSH_OPTIONS_PROXY_PORT:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
@ -531,10 +568,15 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->opts.port = *x & 0xffffU;
|
||||
if (type == SSH_OPTIONS_PORT) {
|
||||
session->opts.port = *x & 0xffffU;
|
||||
} else if (type == SSH_OPTIONS_PROXY_PORT) {
|
||||
session->opts.proxy_port = *x & 0xffffU;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_PORT_STR:
|
||||
case SSH_OPTIONS_PROXY_PORT_STR:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
@ -555,7 +597,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->opts.port = i & 0xffffU;
|
||||
if (type == SSH_OPTIONS_PORT_STR) {
|
||||
session->opts.port = i & 0xffffU;
|
||||
} else if (type == SSH_OPTIONS_PROXY_PORT_STR) {
|
||||
session->opts.proxy_port = i & 0xffffU;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_FD:
|
||||
@ -1029,6 +1075,16 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
session->opts.rekey_time = (*x) * 1000;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_EXTERNAL_CALLBACKS:
|
||||
if (value == NULL) {
|
||||
session->socket_external_callbacks.send = NULL;
|
||||
session->socket_external_callbacks.userdata = NULL;
|
||||
} else {
|
||||
ssh_socket_external_callbacks external_callbacks = (ssh_socket_external_callbacks) value;
|
||||
session->socket_external_callbacks.send = external_callbacks->send;
|
||||
session->socket_external_callbacks.userdata = external_callbacks->userdata;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||
return -1;
|
||||
|
@ -300,6 +300,7 @@ void ssh_free(ssh_session session)
|
||||
SAFE_FREE(session->opts.custombanner);
|
||||
SAFE_FREE(session->opts.username);
|
||||
SAFE_FREE(session->opts.host);
|
||||
SAFE_FREE(session->opts.proxy_host);
|
||||
SAFE_FREE(session->opts.sshdir);
|
||||
SAFE_FREE(session->opts.knownhosts);
|
||||
SAFE_FREE(session->opts.global_knownhosts);
|
||||
|
@ -88,6 +88,7 @@ struct ssh_socket_struct {
|
||||
ssh_buffer in_buffer;
|
||||
ssh_session session;
|
||||
ssh_socket_callbacks callbacks;
|
||||
ssh_socket_external_callbacks external_callbacks;
|
||||
ssh_poll_handle poll_handle;
|
||||
#ifndef _WIN32
|
||||
pid_t proxy_pid;
|
||||
@ -214,6 +215,11 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks)
|
||||
s->callbacks = callbacks;
|
||||
}
|
||||
|
||||
void ssh_socket_set_external_callbacks(ssh_socket s, ssh_socket_external_callbacks external_callbacks)
|
||||
{
|
||||
s->external_callbacks = external_callbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SSH poll callback. This callback will be used when an event
|
||||
* caught on the socket.
|
||||
@ -577,7 +583,11 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
}
|
||||
|
||||
if (s->fd_is_socket) {
|
||||
w = send(s->fd, buffer, len, flags);
|
||||
if (s->external_callbacks->send != NULL) {
|
||||
w = s->external_callbacks->send(buffer, len, s->external_callbacks->userdata);
|
||||
} else {
|
||||
w = send(s->fd, buffer, len, flags);
|
||||
}
|
||||
} else {
|
||||
w = write(s->fd, buffer, len);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user