mirror of
https://github.com/kingToolbox/WindTerm.git
synced 2025-03-22 10:50:07 +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;
|
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_WRITEWILLBLOCK 1
|
||||||
#define SSH_SOCKET_FLOW_WRITEWONTBLOCK 2
|
#define SSH_SOCKET_FLOW_WRITEWONTBLOCK 2
|
||||||
|
|
||||||
|
@ -362,6 +362,9 @@ enum ssh_options_e {
|
|||||||
SSH_OPTIONS_HOST,
|
SSH_OPTIONS_HOST,
|
||||||
SSH_OPTIONS_PORT,
|
SSH_OPTIONS_PORT,
|
||||||
SSH_OPTIONS_PORT_STR,
|
SSH_OPTIONS_PORT_STR,
|
||||||
|
SSH_OPTIONS_PROXY_HOST,
|
||||||
|
SSH_OPTIONS_PROXY_PORT,
|
||||||
|
SSH_OPTIONS_PROXY_PORT_STR,
|
||||||
SSH_OPTIONS_FD,
|
SSH_OPTIONS_FD,
|
||||||
SSH_OPTIONS_USER,
|
SSH_OPTIONS_USER,
|
||||||
SSH_OPTIONS_SSH_DIR,
|
SSH_OPTIONS_SSH_DIR,
|
||||||
@ -400,6 +403,7 @@ enum ssh_options_e {
|
|||||||
SSH_OPTIONS_PROCESS_CONFIG,
|
SSH_OPTIONS_PROCESS_CONFIG,
|
||||||
SSH_OPTIONS_REKEY_DATA,
|
SSH_OPTIONS_REKEY_DATA,
|
||||||
SSH_OPTIONS_REKEY_TIME,
|
SSH_OPTIONS_REKEY_TIME,
|
||||||
|
SSH_OPTIONS_EXTERNAL_CALLBACKS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -200,6 +200,7 @@ struct ssh_session_struct {
|
|||||||
struct ssh_packet_callbacks_struct default_packet_callbacks;
|
struct ssh_packet_callbacks_struct default_packet_callbacks;
|
||||||
struct ssh_list *packet_callbacks;
|
struct ssh_list *packet_callbacks;
|
||||||
struct ssh_socket_callbacks_struct socket_callbacks;
|
struct ssh_socket_callbacks_struct socket_callbacks;
|
||||||
|
struct ssh_socket_external_callbacks_struct socket_external_callbacks;
|
||||||
ssh_poll_ctx default_poll_ctx;
|
ssh_poll_ctx default_poll_ctx;
|
||||||
/* options */
|
/* options */
|
||||||
#ifdef WITH_PCAP
|
#ifdef WITH_PCAP
|
||||||
@ -209,6 +210,7 @@ struct ssh_session_struct {
|
|||||||
struct ssh_list *identity;
|
struct ssh_list *identity;
|
||||||
char *username;
|
char *username;
|
||||||
char *host;
|
char *host;
|
||||||
|
char *proxy_host;
|
||||||
char *bindaddr; /* bind the client to an ip addr */
|
char *bindaddr; /* bind the client to an ip addr */
|
||||||
char *sshdir;
|
char *sshdir;
|
||||||
char *knownhosts;
|
char *knownhosts;
|
||||||
@ -220,6 +222,7 @@ struct ssh_session_struct {
|
|||||||
unsigned long timeout; /* seconds */
|
unsigned long timeout; /* seconds */
|
||||||
unsigned long timeout_usec;
|
unsigned long timeout_usec;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
|
unsigned int proxy_port;
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
int StrictHostKeyChecking;
|
int StrictHostKeyChecking;
|
||||||
char compressionlevel;
|
char compressionlevel;
|
||||||
|
@ -60,6 +60,7 @@ int ssh_socket_set_nonblocking(socket_t fd);
|
|||||||
int ssh_socket_set_blocking(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_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);
|
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);
|
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.exception = ssh_socket_exception_callback;
|
||||||
session->socket_callbacks.userdata = session;
|
session->socket_callbacks.userdata = session;
|
||||||
|
|
||||||
|
ssh_socket_set_external_callbacks(session->socket, &session->socket_external_callbacks);
|
||||||
|
|
||||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||||
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||||
@ -581,10 +583,17 @@ int ssh_connect(ssh_session session)
|
|||||||
session->opts.ProxyCommand);
|
session->opts.ProxyCommand);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ret = ssh_socket_connect(session->socket,
|
if (session->opts.proxy_host != NULL) {
|
||||||
session->opts.host,
|
ret = ssh_socket_connect(session->socket,
|
||||||
session->opts.port > 0 ? session->opts.port : 22,
|
session->opts.proxy_host,
|
||||||
session->opts.bindaddr);
|
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) {
|
if (ret == SSH_ERROR) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
|
@ -520,7 +520,44 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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_PORT:
|
||||||
|
case SSH_OPTIONS_PROXY_PORT:
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
ssh_set_error_invalid(session);
|
ssh_set_error_invalid(session);
|
||||||
return -1;
|
return -1;
|
||||||
@ -531,10 +568,15 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
return -1;
|
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;
|
break;
|
||||||
case SSH_OPTIONS_PORT_STR:
|
case SSH_OPTIONS_PORT_STR:
|
||||||
|
case SSH_OPTIONS_PROXY_PORT_STR:
|
||||||
v = value;
|
v = value;
|
||||||
if (v == NULL || v[0] == '\0') {
|
if (v == NULL || v[0] == '\0') {
|
||||||
ssh_set_error_invalid(session);
|
ssh_set_error_invalid(session);
|
||||||
@ -555,7 +597,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
return -1;
|
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;
|
break;
|
||||||
case SSH_OPTIONS_FD:
|
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;
|
session->opts.rekey_time = (*x) * 1000;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -300,6 +300,7 @@ void ssh_free(ssh_session session)
|
|||||||
SAFE_FREE(session->opts.custombanner);
|
SAFE_FREE(session->opts.custombanner);
|
||||||
SAFE_FREE(session->opts.username);
|
SAFE_FREE(session->opts.username);
|
||||||
SAFE_FREE(session->opts.host);
|
SAFE_FREE(session->opts.host);
|
||||||
|
SAFE_FREE(session->opts.proxy_host);
|
||||||
SAFE_FREE(session->opts.sshdir);
|
SAFE_FREE(session->opts.sshdir);
|
||||||
SAFE_FREE(session->opts.knownhosts);
|
SAFE_FREE(session->opts.knownhosts);
|
||||||
SAFE_FREE(session->opts.global_knownhosts);
|
SAFE_FREE(session->opts.global_knownhosts);
|
||||||
|
@ -88,6 +88,7 @@ struct ssh_socket_struct {
|
|||||||
ssh_buffer in_buffer;
|
ssh_buffer in_buffer;
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
ssh_socket_callbacks callbacks;
|
ssh_socket_callbacks callbacks;
|
||||||
|
ssh_socket_external_callbacks external_callbacks;
|
||||||
ssh_poll_handle poll_handle;
|
ssh_poll_handle poll_handle;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pid_t proxy_pid;
|
pid_t proxy_pid;
|
||||||
@ -214,6 +215,11 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks)
|
|||||||
s->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
|
* @brief SSH poll callback. This callback will be used when an event
|
||||||
* caught on the socket.
|
* caught on the socket.
|
||||||
@ -577,7 +583,11 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (s->fd_is_socket) {
|
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 {
|
} else {
|
||||||
w = write(s->fd, buffer, len);
|
w = write(s->fd, buffer, len);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user