Merge changes from patch branch back to main.
This commit is contained in:
commit
3258efe2be
@ -114,6 +114,10 @@ void guac_common_ssh_uninit();
|
||||
*
|
||||
* @param user
|
||||
* The user to authenticate as, once connected.
|
||||
*
|
||||
* @param timeout
|
||||
* The number of seconds to attempt to connect to the SSH server before
|
||||
* timing out.
|
||||
*
|
||||
* @param keepalive
|
||||
* How frequently the connection should send keepalive packets, in
|
||||
@ -138,7 +142,7 @@ void guac_common_ssh_uninit();
|
||||
*/
|
||||
guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
|
||||
const char* hostname, const char* port, guac_common_ssh_user* user,
|
||||
int keepalive, const char* host_key,
|
||||
int timeout, int keepalive, const char* host_key,
|
||||
guac_ssh_credential_handler* credential_handler);
|
||||
|
||||
/**
|
||||
|
||||
@ -35,11 +35,17 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef LIBSSH2_USES_GCRYPT
|
||||
@ -408,10 +414,10 @@ static int guac_common_ssh_authenticate(guac_common_ssh_session* common_session)
|
||||
|
||||
guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
|
||||
const char* hostname, const char* port, guac_common_ssh_user* user,
|
||||
int keepalive, const char* host_key,
|
||||
int timeout, int keepalive, const char* host_key,
|
||||
guac_ssh_credential_handler* credential_handler) {
|
||||
|
||||
int fd = guac_socket_tcp_connect(hostname, port);
|
||||
int fd = guac_socket_tcp_connect(hostname, port, timeout);
|
||||
if (fd < 0) {
|
||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
||||
"Failed to open TCP connection to %s on %s.", hostname, port);
|
||||
|
||||
@ -35,10 +35,13 @@
|
||||
* @param port
|
||||
* The TCP port to which to attempt to connect.
|
||||
*
|
||||
* @param timeout
|
||||
* The number of seconds to try the TCP connection before timing out.
|
||||
*
|
||||
* @return
|
||||
* A valid socket if the connection succeeds, or a negative integer if it
|
||||
* fails.
|
||||
*/
|
||||
int guac_socket_tcp_connect(const char* hostname, const char* port);
|
||||
int guac_socket_tcp_connect(const char* hostname, const char* port, const int timeout);
|
||||
|
||||
#endif // __GUAC_SOCKET_TCP_H
|
||||
@ -33,6 +33,12 @@
|
||||
*/
|
||||
#define GUAC_WOL_DEFAULT_CONNECT_RETRIES 5
|
||||
|
||||
/**
|
||||
* The default number of seconds for the connection timeout when attempting
|
||||
* to connect to the remote system to see if it is awake.
|
||||
*/
|
||||
#define GUAC_WOL_DEFAULT_CONNECTION_TIMEOUT 10
|
||||
|
||||
/**
|
||||
* The value for the local IPv4 broadcast address.
|
||||
*/
|
||||
|
||||
@ -83,6 +83,10 @@ int guac_wol_wake(const char* mac_addr, const char* broadcast_addr,
|
||||
* @param port
|
||||
* The TCP port of the remote system on which the connection will be
|
||||
* attempted after the system has been woken.
|
||||
*
|
||||
* @param timeout
|
||||
* The number of seconds to wait when attempting the connection to the
|
||||
* remote system when checking to see if it is awake.
|
||||
*
|
||||
* @return
|
||||
* Zero if the packet is successfully sent to the destination; non-zero
|
||||
@ -90,7 +94,7 @@ int guac_wol_wake(const char* mac_addr, const char* broadcast_addr,
|
||||
*/
|
||||
int guac_wol_wake_and_wait(const char* mac_addr, const char* broadcast_addr,
|
||||
const unsigned short udp_port, int wait_time, int retries,
|
||||
const char* hostname, const char* port);
|
||||
const char* hostname, const char* port, const int timeout);
|
||||
|
||||
#endif /* GUAC_WOL_H */
|
||||
|
||||
|
||||
@ -22,11 +22,13 @@
|
||||
#include "guacamole/socket.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int guac_socket_tcp_connect(const char* hostname, const char* port) {
|
||||
int guac_socket_tcp_connect(const char* hostname, const char* port, const int timeout) {
|
||||
|
||||
int retval;
|
||||
|
||||
@ -73,15 +75,31 @@ int guac_socket_tcp_connect(const char* hostname, const char* port) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Connect */
|
||||
if (connect(fd, current_address->ai_addr,
|
||||
current_address->ai_addrlen) == 0) {
|
||||
/* Set socket to non-blocking */
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
/* Done if successful connect */
|
||||
/* Set up timeout. */
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fd, &fdset);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/* Connect and wait for timeout */
|
||||
if (connect(fd, current_address->ai_addr, current_address->ai_addrlen) < 0) {
|
||||
guac_error = GUAC_STATUS_REFUSED;
|
||||
guac_error_message = "Unable to connect via socket.";
|
||||
close(fd);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Check for the connection and break if successful */
|
||||
if (select(fd + 1, NULL, &fdset, NULL, &tv) > 0)
|
||||
break;
|
||||
|
||||
/* Connection not successful - free resources and go to the next address. */
|
||||
close(fd);
|
||||
current_address = current_address->ai_next;
|
||||
|
||||
|
||||
@ -201,10 +201,10 @@ int guac_wol_wake(const char* mac_addr, const char* broadcast_addr,
|
||||
|
||||
int guac_wol_wake_and_wait(const char* mac_addr, const char* broadcast_addr,
|
||||
const unsigned short udp_port, int wait_time, int retries,
|
||||
const char* hostname, const char* port) {
|
||||
const char* hostname, const char* port, const int timeout) {
|
||||
|
||||
/* Attempt to connect, first. */
|
||||
int sockfd = guac_socket_tcp_connect(hostname, port);
|
||||
int sockfd = guac_socket_tcp_connect(hostname, port, timeout);
|
||||
|
||||
/* If connection succeeds, no need to wake the system. */
|
||||
if (sockfd > 0) {
|
||||
@ -225,7 +225,7 @@ int guac_wol_wake_and_wait(const char* mac_addr, const char* broadcast_addr,
|
||||
/* Try to connect on the specified TCP port and hostname or IP. */
|
||||
for (int i = 0; i < retries; i++) {
|
||||
|
||||
sockfd = guac_socket_tcp_connect(hostname, port);
|
||||
sockfd = guac_socket_tcp_connect(hostname, port, timeout);
|
||||
|
||||
/* Connection succeeded - close socket and exit. */
|
||||
if (sockfd > 0) {
|
||||
|
||||
@ -717,7 +717,8 @@ void* guac_rdp_client_thread(void* data) {
|
||||
settings->wol_wait_time,
|
||||
GUAC_WOL_DEFAULT_CONNECT_RETRIES,
|
||||
settings->hostname,
|
||||
(const char *) str_port)) {
|
||||
(const char *) str_port,
|
||||
GUAC_WOL_DEFAULT_CONNECTION_TIMEOUT)) {
|
||||
guac_client_log(client, GUAC_LOG_ERROR, "Failed to send WOL packet, or server failed to wake up.");
|
||||
guac_mem_free(str_port);
|
||||
return NULL;
|
||||
@ -799,6 +800,33 @@ void* guac_rdp_client_thread(void* data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Import the public key, if that is specified. */
|
||||
if (settings->sftp_public_key != NULL) {
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Attempting public key import");
|
||||
|
||||
/* Attempt to read public key */
|
||||
if (guac_common_ssh_user_import_public_key(rdp_client->sftp_user,
|
||||
settings->sftp_public_key)) {
|
||||
|
||||
/* Public key import fails. */
|
||||
guac_client_abort(client,
|
||||
GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED,
|
||||
"Failed to import public key: %s",
|
||||
guac_common_ssh_key_error());
|
||||
|
||||
guac_common_ssh_destroy_user(rdp_client->sftp_user);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/* Success */
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Public key successfully imported.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Otherwise, use specified password */
|
||||
@ -815,8 +843,8 @@ void* guac_rdp_client_thread(void* data) {
|
||||
/* Attempt SSH connection */
|
||||
rdp_client->sftp_session =
|
||||
guac_common_ssh_create_session(client, settings->sftp_hostname,
|
||||
settings->sftp_port, rdp_client->sftp_user, settings->sftp_server_alive_interval,
|
||||
settings->sftp_host_key, NULL);
|
||||
settings->sftp_port, rdp_client->sftp_user, settings->sftp_timeout,
|
||||
settings->sftp_server_alive_interval, settings->sftp_host_key, NULL);
|
||||
|
||||
/* Fail if SSH connection does not succeed */
|
||||
if (rdp_client->sftp_session == NULL) {
|
||||
|
||||
@ -56,6 +56,7 @@ const char fips_nla_mode_warning[] = (
|
||||
const char* GUAC_RDP_CLIENT_ARGS[] = {
|
||||
"hostname",
|
||||
"port",
|
||||
"timeout",
|
||||
GUAC_RDP_ARGV_DOMAIN,
|
||||
GUAC_RDP_ARGV_USERNAME,
|
||||
GUAC_RDP_ARGV_PASSWORD,
|
||||
@ -105,10 +106,12 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
|
||||
"sftp-hostname",
|
||||
"sftp-host-key",
|
||||
"sftp-port",
|
||||
"sftp-timeout",
|
||||
"sftp-username",
|
||||
"sftp-password",
|
||||
"sftp-private-key",
|
||||
"sftp-passphrase",
|
||||
"sftp-public-key",
|
||||
"sftp-directory",
|
||||
"sftp-root-directory",
|
||||
"sftp-server-alive-interval",
|
||||
@ -164,6 +167,11 @@ enum RDP_ARGS_IDX {
|
||||
*/
|
||||
IDX_PORT,
|
||||
|
||||
/**
|
||||
* The amount of time to wait for the server to respond, in seconds.
|
||||
*/
|
||||
IDX_TIMEOUT,
|
||||
|
||||
/**
|
||||
* The domain of the user logging in.
|
||||
*/
|
||||
@ -455,6 +463,12 @@ enum RDP_ARGS_IDX {
|
||||
*/
|
||||
IDX_SFTP_PORT,
|
||||
|
||||
/**
|
||||
* The number of seconds to attempt to connect to the SSH server before
|
||||
* timing out.
|
||||
*/
|
||||
IDX_SFTP_TIMEOUT,
|
||||
|
||||
/**
|
||||
* The username to provide when authenticating with the SSH server for
|
||||
* SFTP. If blank, the username provided for the RDP user will be used.
|
||||
@ -479,6 +493,12 @@ enum RDP_ARGS_IDX {
|
||||
*/
|
||||
IDX_SFTP_PASSPHRASE,
|
||||
|
||||
/**
|
||||
* The base64-encoded public key to use when authenticating with the SSH
|
||||
* server for SFTP.
|
||||
*/
|
||||
IDX_SFTP_PUBLIC_KEY,
|
||||
|
||||
/**
|
||||
* The default location for file uploads within the SSH server. This will
|
||||
* apply only to uploads which do not use the filesystem guac_object (where
|
||||
@ -816,6 +836,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
|
||||
guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_PORT,
|
||||
settings->security_mode == GUAC_SECURITY_VMCONNECT ? RDP_DEFAULT_VMCONNECT_PORT : RDP_DEFAULT_PORT);
|
||||
|
||||
/* Look for timeout settings and parse or set defaults. */
|
||||
settings->timeout =
|
||||
guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_TIMEOUT, RDP_DEFAULT_TIMEOUT);
|
||||
|
||||
guac_user_log(user, GUAC_LOG_DEBUG,
|
||||
"User resolution is %ix%i at %i DPI",
|
||||
user->info.optimal_width,
|
||||
@ -1087,6 +1112,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PORT, "22");
|
||||
|
||||
/* SFTP timeout */
|
||||
settings->sftp_timeout =
|
||||
guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_TIMEOUT, RDP_DEFAULT_SFTP_TIMEOUT);
|
||||
|
||||
/* Username for SSH/SFTP authentication */
|
||||
settings->sftp_username =
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
@ -1103,11 +1133,16 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PRIVATE_KEY, NULL);
|
||||
|
||||
/* Passphrase for decrypting the SFTP private key (if applicable */
|
||||
/* Passphrase for decrypting the SFTP private key (if applicable) */
|
||||
settings->sftp_passphrase =
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PASSPHRASE, "");
|
||||
|
||||
/* Public key for authenticating to SFTP server, if applicable. */
|
||||
settings->sftp_public_key =
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PUBLIC_KEY, NULL);
|
||||
|
||||
/* Default upload directory */
|
||||
settings->sftp_directory =
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
@ -1374,6 +1409,7 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) {
|
||||
guac_mem_free(settings->sftp_password);
|
||||
guac_mem_free(settings->sftp_port);
|
||||
guac_mem_free(settings->sftp_private_key);
|
||||
guac_mem_free(settings->sftp_public_key);
|
||||
guac_mem_free(settings->sftp_username);
|
||||
#endif
|
||||
|
||||
@ -1721,6 +1757,7 @@ void guac_rdp_push_settings(guac_client* client,
|
||||
/* Connection */
|
||||
rdp_settings->ServerHostname = guac_strdup(guac_settings->hostname);
|
||||
rdp_settings->ServerPort = guac_settings->port;
|
||||
rdp_settings->TcpAckTimeout = guac_settings->timeout * 1000;
|
||||
|
||||
/* Session */
|
||||
rdp_settings->ColorDepth = guac_settings->color_depth;
|
||||
|
||||
@ -33,11 +33,21 @@
|
||||
*/
|
||||
#define RDP_CLIENT_HOSTNAME_SIZE 32
|
||||
|
||||
/**
|
||||
* The default server response timeout, in seconds.
|
||||
*/
|
||||
#define RDP_DEFAULT_TIMEOUT 10
|
||||
|
||||
/**
|
||||
* The default RDP port.
|
||||
*/
|
||||
#define RDP_DEFAULT_PORT 3389
|
||||
|
||||
/**
|
||||
* The default SFTP connection timeout, in seconds.
|
||||
*/
|
||||
#define RDP_DEFAULT_SFTP_TIMEOUT 10
|
||||
|
||||
/**
|
||||
* The default RDP port used by Hyper-V "VMConnect".
|
||||
*/
|
||||
@ -156,6 +166,11 @@ typedef struct guac_rdp_settings {
|
||||
*/
|
||||
int port;
|
||||
|
||||
/**
|
||||
* The timeout, in seconds, to wait for the remote host to respond.
|
||||
*/
|
||||
int timeout;
|
||||
|
||||
/**
|
||||
* The domain of the user logging in.
|
||||
*/
|
||||
@ -452,6 +467,12 @@ typedef struct guac_rdp_settings {
|
||||
*/
|
||||
char* sftp_port;
|
||||
|
||||
/**
|
||||
* The number of seconds to attempt to connect to the SSH server before
|
||||
* timing out.
|
||||
*/
|
||||
int sftp_timeout;
|
||||
|
||||
/**
|
||||
* The username to provide when authenticating with the SSH server for
|
||||
* SFTP.
|
||||
@ -476,6 +497,11 @@ typedef struct guac_rdp_settings {
|
||||
*/
|
||||
char* sftp_passphrase;
|
||||
|
||||
/**
|
||||
* The public key to use when connecting to the SFTP server, if applicable.
|
||||
*/
|
||||
char* sftp_public_key;
|
||||
|
||||
/**
|
||||
* The default location for file uploads within the SSH server. This will
|
||||
* apply only to uploads which do not use the filesystem guac_object (where
|
||||
|
||||
@ -38,6 +38,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = {
|
||||
"hostname",
|
||||
"host-key",
|
||||
"port",
|
||||
"timeout",
|
||||
"username",
|
||||
"password",
|
||||
GUAC_SSH_ARGV_FONT_NAME,
|
||||
@ -99,6 +100,11 @@ enum SSH_ARGS_IDX {
|
||||
*/
|
||||
IDX_PORT,
|
||||
|
||||
/**
|
||||
* The timeout of the connection attempt, in seconds. Optional.
|
||||
*/
|
||||
IDX_TIMEOUT,
|
||||
|
||||
/**
|
||||
* The name of the user to login as. Optional.
|
||||
*/
|
||||
@ -454,6 +460,11 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
|
||||
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
|
||||
IDX_PORT, GUAC_SSH_DEFAULT_PORT);
|
||||
|
||||
/* Parse the timeout value. */
|
||||
settings->timeout =
|
||||
guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
|
||||
IDX_TIMEOUT, GUAC_SSH_DEFAULT_TIMEOUT);
|
||||
|
||||
/* Read-only mode */
|
||||
settings->read_only =
|
||||
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
|
||||
|
||||
@ -32,6 +32,12 @@
|
||||
*/
|
||||
#define GUAC_SSH_DEFAULT_PORT "22"
|
||||
|
||||
/**
|
||||
* The default number of seconds to attempt a connection to the SSH/SFTP
|
||||
* server before giving up.
|
||||
*/
|
||||
#define GUAC_SSH_DEFAULT_TIMEOUT 10
|
||||
|
||||
/**
|
||||
* The filename to use for the typescript, if not specified.
|
||||
*/
|
||||
@ -69,6 +75,12 @@ typedef struct guac_ssh_settings {
|
||||
*/
|
||||
char* port;
|
||||
|
||||
/**
|
||||
* The number of seconds to attempt to connect to the SSH server before
|
||||
* timing out.
|
||||
*/
|
||||
int timeout;
|
||||
|
||||
/**
|
||||
* The name of the user to login as, if any. If no username is specified,
|
||||
* this will be NULL.
|
||||
|
||||
@ -134,33 +134,34 @@ static guac_common_ssh_user* guac_ssh_get_user(guac_client* client) {
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Auth key successfully imported.");
|
||||
|
||||
} /* end if key given */
|
||||
/* Import public key, if available. */
|
||||
if (settings->public_key_base64 != NULL) {
|
||||
|
||||
if (settings->public_key_base64 != NULL) {
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Attempting public key import");
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Attempting public key import");
|
||||
/* Attempt to read public key */
|
||||
if (guac_common_ssh_user_import_public_key(user,
|
||||
settings->public_key_base64)) {
|
||||
|
||||
/* Attempt to read public key */
|
||||
if (guac_common_ssh_user_import_public_key(user,
|
||||
settings->public_key_base64)) {
|
||||
/* Public key import fails. */
|
||||
guac_client_abort(client,
|
||||
GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED,
|
||||
"Auth public key import failed: %s",
|
||||
guac_common_ssh_key_error());
|
||||
|
||||
/* If failing*/
|
||||
guac_client_abort(client,
|
||||
GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED,
|
||||
"Auth public key import failed: %s",
|
||||
guac_common_ssh_key_error());
|
||||
guac_common_ssh_destroy_user(user);
|
||||
return NULL;
|
||||
|
||||
guac_common_ssh_destroy_user(user);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Auth public key successfully imported.");
|
||||
|
||||
}
|
||||
|
||||
/* Success */
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Auth public key successfully imported.");
|
||||
|
||||
}
|
||||
} /* end if key given */
|
||||
|
||||
/* If available, get password from settings */
|
||||
else if (settings->password != NULL) {
|
||||
@ -250,7 +251,8 @@ void* ssh_client_thread(void* data) {
|
||||
settings->wol_wait_time,
|
||||
GUAC_WOL_DEFAULT_CONNECT_RETRIES,
|
||||
settings->hostname,
|
||||
settings->port)) {
|
||||
settings->port,
|
||||
settings->timeout)) {
|
||||
guac_client_log(client, GUAC_LOG_ERROR, "Failed to send WOL packet or connect to remote server.");
|
||||
return NULL;
|
||||
}
|
||||
@ -336,7 +338,8 @@ void* ssh_client_thread(void* data) {
|
||||
|
||||
/* Open SSH session */
|
||||
ssh_client->session = guac_common_ssh_create_session(client,
|
||||
settings->hostname, settings->port, ssh_client->user, settings->server_alive_interval,
|
||||
settings->hostname, settings->port, ssh_client->user,
|
||||
settings->timeout, settings->server_alive_interval,
|
||||
settings->host_key, guac_ssh_get_credential);
|
||||
if (ssh_client->session == NULL) {
|
||||
/* Already aborted within guac_common_ssh_create_session() */
|
||||
@ -387,8 +390,8 @@ void* ssh_client_thread(void* data) {
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "Reconnecting for SFTP...");
|
||||
ssh_client->sftp_session =
|
||||
guac_common_ssh_create_session(client, settings->hostname,
|
||||
settings->port, ssh_client->user, settings->server_alive_interval,
|
||||
settings->host_key, NULL);
|
||||
settings->port, ssh_client->user, settings->timeout,
|
||||
settings->server_alive_interval, settings->host_key, NULL);
|
||||
if (ssh_client->sftp_session == NULL) {
|
||||
/* Already aborted within guac_common_ssh_create_session() */
|
||||
return NULL;
|
||||
|
||||
@ -386,7 +386,7 @@ static telnet_t* __guac_telnet_create_session(guac_client* client) {
|
||||
guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
|
||||
guac_telnet_settings* settings = telnet_client->settings;
|
||||
|
||||
int fd = guac_socket_tcp_connect(settings->hostname, settings->port);
|
||||
int fd = guac_socket_tcp_connect(settings->hostname, settings->port, settings->timeout);
|
||||
|
||||
/* Open telnet session */
|
||||
telnet_t* telnet = telnet_init(__telnet_options, __guac_telnet_event_handler, 0, client);
|
||||
@ -511,7 +511,8 @@ void* guac_telnet_client_thread(void* data) {
|
||||
settings->wol_wait_time,
|
||||
GUAC_WOL_DEFAULT_CONNECT_RETRIES,
|
||||
settings->hostname,
|
||||
settings->port)) {
|
||||
settings->port,
|
||||
settings->timeout)) {
|
||||
guac_client_log(client, GUAC_LOG_ERROR, "Failed to send WOL packet or connect to remote server.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -68,10 +68,12 @@ const char* GUAC_VNC_CLIENT_ARGS[] = {
|
||||
"sftp-hostname",
|
||||
"sftp-host-key",
|
||||
"sftp-port",
|
||||
"sftp-timeout",
|
||||
"sftp-username",
|
||||
"sftp-password",
|
||||
"sftp-private-key",
|
||||
"sftp-passphrase",
|
||||
"sftp-public-key",
|
||||
"sftp-directory",
|
||||
"sftp-root-directory",
|
||||
"sftp-server-alive-interval",
|
||||
@ -241,6 +243,12 @@ enum VNC_ARGS_IDX {
|
||||
*/
|
||||
IDX_SFTP_PORT,
|
||||
|
||||
/**
|
||||
* The number of seconds to attempt to connect to the SFTP server before
|
||||
* timing out.
|
||||
*/
|
||||
IDX_SFTP_TIMEOUT,
|
||||
|
||||
/**
|
||||
* The username to provide when authenticating with the SSH server for
|
||||
* SFTP.
|
||||
@ -265,6 +273,12 @@ enum VNC_ARGS_IDX {
|
||||
*/
|
||||
IDX_SFTP_PASSPHRASE,
|
||||
|
||||
/**
|
||||
* The base64-encode public key to use when authentication with the SSH
|
||||
* server for SFTP using key-based authentication.
|
||||
*/
|
||||
IDX_SFTP_PUBLIC_KEY,
|
||||
|
||||
/**
|
||||
* The default location for file uploads within the SSH server. This will
|
||||
* apply only to uploads which do not use the filesystem guac_object (where
|
||||
@ -576,6 +590,11 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user,
|
||||
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PORT, "22");
|
||||
|
||||
/* SFTP connection timeout */
|
||||
settings->sftp_timeout =
|
||||
guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_TIMEOUT, GUAC_VNC_DEFAULT_SFTP_TIMEOUT);
|
||||
|
||||
/* Username for SSH/SFTP authentication */
|
||||
settings->sftp_username =
|
||||
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
|
||||
@ -596,6 +615,11 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user,
|
||||
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PASSPHRASE, "");
|
||||
|
||||
/* Public key for SFTP using key-based authentication. */
|
||||
settings->sftp_public_key =
|
||||
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
|
||||
IDX_SFTP_PUBLIC_KEY, NULL);
|
||||
|
||||
/* Default upload directory */
|
||||
settings->sftp_directory =
|
||||
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
|
||||
@ -731,6 +755,7 @@ void guac_vnc_settings_free(guac_vnc_settings* settings) {
|
||||
guac_mem_free(settings->sftp_password);
|
||||
guac_mem_free(settings->sftp_port);
|
||||
guac_mem_free(settings->sftp_private_key);
|
||||
guac_mem_free(settings->sftp_public_key);
|
||||
guac_mem_free(settings->sftp_username);
|
||||
#endif
|
||||
|
||||
|
||||
@ -29,6 +29,11 @@
|
||||
*/
|
||||
#define GUAC_VNC_DEFAULT_RECORDING_NAME "recording"
|
||||
|
||||
/**
|
||||
* The default number of seconds to attempt to connect to the SFTP server.
|
||||
*/
|
||||
#define GUAC_VNC_DEFAULT_SFTP_TIMEOUT 10
|
||||
|
||||
/**
|
||||
* VNC-specific client data.
|
||||
*/
|
||||
@ -188,6 +193,11 @@ typedef struct guac_vnc_settings {
|
||||
*/
|
||||
char* sftp_port;
|
||||
|
||||
/**
|
||||
* The number of seconds to attempt to connect to the SFTP server.
|
||||
*/
|
||||
int sftp_timeout;
|
||||
|
||||
/**
|
||||
* The username to provide when authenticating with the SSH server for
|
||||
* SFTP.
|
||||
@ -212,6 +222,12 @@ typedef struct guac_vnc_settings {
|
||||
*/
|
||||
char* sftp_passphrase;
|
||||
|
||||
/**
|
||||
* The base64-encoded public key to use when authenticating with the SSH
|
||||
* server for SFTP using key-based authentication.
|
||||
*/
|
||||
char* sftp_public_key;
|
||||
|
||||
/**
|
||||
* The default location for file uploads within the SSH server. This will
|
||||
* apply only to uploads which do not use the filesystem guac_object (where
|
||||
|
||||
@ -301,7 +301,8 @@ void* guac_vnc_client_thread(void* data) {
|
||||
settings->wol_wait_time,
|
||||
GUAC_WOL_DEFAULT_CONNECT_RETRIES,
|
||||
settings->hostname,
|
||||
(const char *) str_port)) {
|
||||
(const char *) str_port,
|
||||
GUAC_WOL_DEFAULT_CONNECTION_TIMEOUT)) {
|
||||
guac_client_log(client, GUAC_LOG_ERROR, "Failed to send WOL packet or connect to remote system.");
|
||||
guac_mem_free(str_port);
|
||||
return NULL;
|
||||
@ -396,6 +397,33 @@ void* guac_vnc_client_thread(void* data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Import the public key, if that is specified. */
|
||||
if (settings->sftp_public_key != NULL) {
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Attempting public key import");
|
||||
|
||||
/* Attempt to read public key */
|
||||
if (guac_common_ssh_user_import_public_key(vnc_client->sftp_user,
|
||||
settings->sftp_public_key)) {
|
||||
|
||||
/* Public key import fails. */
|
||||
guac_client_abort(client,
|
||||
GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED,
|
||||
"Failed to import public key: %s",
|
||||
guac_common_ssh_key_error());
|
||||
|
||||
guac_common_ssh_destroy_user(vnc_client->sftp_user);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/* Success */
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Public key successfully imported.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Otherwise, use specified password */
|
||||
@ -409,8 +437,8 @@ void* guac_vnc_client_thread(void* data) {
|
||||
/* Attempt SSH connection */
|
||||
vnc_client->sftp_session =
|
||||
guac_common_ssh_create_session(client, settings->sftp_hostname,
|
||||
settings->sftp_port, vnc_client->sftp_user, settings->sftp_server_alive_interval,
|
||||
settings->sftp_host_key, NULL);
|
||||
settings->sftp_port, vnc_client->sftp_user, settings->sftp_timeout,
|
||||
settings->sftp_server_alive_interval, settings->sftp_host_key, NULL);
|
||||
|
||||
/* Fail if SSH connection does not succeed */
|
||||
if (vnc_client->sftp_session == NULL) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user