Merge pull request #54 from glyptodon/vnc-rdp-sftp
GUAC-1171: Add support for SFTP file transfer to VNC and RDP.
This commit is contained in:
commit
6f93872e0e
@ -840,6 +840,9 @@ fi
|
|||||||
|
|
||||||
AM_CONDITIONAL([ENABLE_COMMON_SSH], [test "x${have_libssh2}" = "xyes" \
|
AM_CONDITIONAL([ENABLE_COMMON_SSH], [test "x${have_libssh2}" = "xyes" \
|
||||||
-a "x${have_ssl}" = "xyes"])
|
-a "x${have_ssl}" = "xyes"])
|
||||||
|
AM_COND_IF([ENABLE_COMMON_SSH],
|
||||||
|
[AC_DEFINE([ENABLE_COMMON_SSH],,
|
||||||
|
[Whether support for the common SSH core is enabled])])
|
||||||
|
|
||||||
AM_CONDITIONAL([ENABLE_SSH], [test "x${have_libssh2}" = "xyes" \
|
AM_CONDITIONAL([ENABLE_SSH], [test "x${have_libssh2}" = "xyes" \
|
||||||
-a "x${have_terminal}" = "xyes" \
|
-a "x${have_terminal}" = "xyes" \
|
||||||
|
@ -246,8 +246,8 @@ int guac_common_ssh_sftp_handle_file_stream(guac_object* filesystem,
|
|||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
guac_client_log(client, GUAC_LOG_INFO, "Unable to open file \"%s\": %s",
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
fullpath, libssh2_sftp_last_error(sftp_data->sftp_session));
|
"Unable to open file \"%s\"", fullpath);
|
||||||
guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed",
|
guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed",
|
||||||
GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
|
GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
|
||||||
guac_socket_flush(client->socket);
|
guac_socket_flush(client->socket);
|
||||||
@ -350,8 +350,7 @@ guac_stream* guac_common_ssh_sftp_download_file(guac_object* filesystem,
|
|||||||
LIBSSH2_FXF_READ, 0);
|
LIBSSH2_FXF_READ, 0);
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
guac_client_log(client, GUAC_LOG_INFO,
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
"Unable to read file \"%s\": %s",
|
"Unable to read file \"%s\"", filename);
|
||||||
filename, libssh2_sftp_last_error(sftp_data->sftp_session));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,8 +539,7 @@ static int guac_common_ssh_sftp_get_handler(guac_client* client,
|
|||||||
LIBSSH2_SFTP_HANDLE* dir = libssh2_sftp_opendir(sftp, name);
|
LIBSSH2_SFTP_HANDLE* dir = libssh2_sftp_opendir(sftp, name);
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
guac_client_log(client, GUAC_LOG_INFO,
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
"Unable to read directory \"%s\": %s",
|
"Unable to read directory \"%s\"", name);
|
||||||
name, libssh2_sftp_last_error(sftp));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,7 +550,7 @@ static int guac_common_ssh_sftp_get_handler(guac_client* client,
|
|||||||
list_state->directory = dir;
|
list_state->directory = dir;
|
||||||
list_state->sftp_data = sftp_data;
|
list_state->sftp_data = sftp_data;
|
||||||
strncpy(list_state->directory_name, name,
|
strncpy(list_state->directory_name, name,
|
||||||
sizeof(list_state->directory_name));
|
sizeof(list_state->directory_name) - 1);
|
||||||
|
|
||||||
/* Allocate stream for body */
|
/* Allocate stream for body */
|
||||||
guac_stream* stream = guac_client_alloc_stream(client);
|
guac_stream* stream = guac_client_alloc_stream(client);
|
||||||
@ -576,8 +574,7 @@ static int guac_common_ssh_sftp_get_handler(guac_client* client,
|
|||||||
LIBSSH2_FXF_READ, 0);
|
LIBSSH2_FXF_READ, 0);
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
guac_client_log(client, GUAC_LOG_INFO,
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
"Unable to read file \"%s\": %s",
|
"Unable to read file \"%s\"", name);
|
||||||
name, libssh2_sftp_last_error(sftp));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,8 +639,8 @@ static int guac_common_ssh_sftp_put_handler(guac_client* client,
|
|||||||
|
|
||||||
/* Abort on failure */
|
/* Abort on failure */
|
||||||
else {
|
else {
|
||||||
guac_client_log(client, GUAC_LOG_INFO, "Unable to open file \"%s\": %s",
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
name, libssh2_sftp_last_error(sftp));
|
"Unable to open file \"%s\"", name);
|
||||||
guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed",
|
guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed",
|
||||||
GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
|
GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
@ -665,24 +662,25 @@ guac_object* guac_common_ssh_create_sftp_filesystem(
|
|||||||
|
|
||||||
guac_client* client = session->client;
|
guac_client* client = session->client;
|
||||||
|
|
||||||
|
/* Request SFTP */
|
||||||
|
LIBSSH2_SFTP* sftp_session = libssh2_sftp_init(session->session);
|
||||||
|
if (sftp_session == NULL) {
|
||||||
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
|
||||||
|
"Unable to start SFTP session.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate data for SFTP session */
|
/* Allocate data for SFTP session */
|
||||||
guac_common_ssh_sftp_data* sftp_data =
|
guac_common_ssh_sftp_data* sftp_data =
|
||||||
malloc(sizeof(guac_common_ssh_sftp_data));
|
malloc(sizeof(guac_common_ssh_sftp_data));
|
||||||
|
|
||||||
/* Associate SSH session with SFTP data */
|
/* Associate SSH session with SFTP data */
|
||||||
sftp_data->ssh_session = session;
|
sftp_data->ssh_session = session;
|
||||||
|
sftp_data->sftp_session = sftp_session;
|
||||||
|
|
||||||
/* Initially upload files to current directory */
|
/* Initially upload files to current directory */
|
||||||
strcpy(sftp_data->upload_path, ".");
|
strcpy(sftp_data->upload_path, ".");
|
||||||
|
|
||||||
/* Request SFTP */
|
|
||||||
sftp_data->sftp_session = libssh2_sftp_init(session->session);
|
|
||||||
if (sftp_data->sftp_session == NULL) {
|
|
||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
|
|
||||||
"Unable to start SFTP session.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init filesystem */
|
/* Init filesystem */
|
||||||
guac_object* filesystem = guac_client_alloc_object(client);
|
guac_object* filesystem = guac_client_alloc_object(client);
|
||||||
filesystem->get_handler = guac_common_ssh_sftp_get_handler;
|
filesystem->get_handler = guac_common_ssh_sftp_get_handler;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef LIBSSH2_USES_GCRYPT
|
#ifdef LIBSSH2_USES_GCRYPT
|
||||||
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||||
@ -373,12 +374,18 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
|
|||||||
|
|
||||||
/* Get socket */
|
/* Get socket */
|
||||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
||||||
|
"Unable to create socket: %s", strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get addresses connection */
|
/* Get addresses connection */
|
||||||
if ((retval = getaddrinfo(hostname, port, &hints, &addresses))) {
|
if ((retval = getaddrinfo(hostname, port, &hints, &addresses))) {
|
||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
||||||
"Error parsing given address or port: %s",
|
"Error parsing given address or port: %s",
|
||||||
gai_strerror(retval));
|
gai_strerror(retval));
|
||||||
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +429,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
|
|||||||
if (current_address == NULL) {
|
if (current_address == NULL) {
|
||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
|
||||||
"Unable to connect to any addresses.");
|
"Unable to connect to any addresses.");
|
||||||
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +447,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
|
|||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
|
||||||
"Session allocation failed.");
|
"Session allocation failed.");
|
||||||
free(common_session);
|
free(common_session);
|
||||||
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +178,7 @@ int guac_common_ssh_key_sign(guac_common_ssh_key* key, const char* data,
|
|||||||
case SSH_KEY_RSA:
|
case SSH_KEY_RSA:
|
||||||
if (RSA_sign(NID_sha1, digest, dlen, sig, &len, key->rsa) == 1)
|
if (RSA_sign(NID_sha1, digest, dlen, sig, &len, key->rsa) == 1)
|
||||||
return len;
|
return len;
|
||||||
|
break;
|
||||||
|
|
||||||
case SSH_KEY_DSA: {
|
case SSH_KEY_DSA: {
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ void guac_common_ssh_destroy_user(guac_common_ssh_user* user) {
|
|||||||
/* Free all other data */
|
/* Free all other data */
|
||||||
free(user->password);
|
free(user->password);
|
||||||
free(user->username);
|
free(user->username);
|
||||||
|
free(user);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ endif
|
|||||||
libguac_client_rdp_la_CFLAGS = \
|
libguac_client_rdp_la_CFLAGS = \
|
||||||
-Werror -Wall -Iinclude \
|
-Werror -Wall -Iinclude \
|
||||||
@COMMON_INCLUDE@ \
|
@COMMON_INCLUDE@ \
|
||||||
|
@COMMON_SSH_INCLUDE@ \
|
||||||
@LIBGUAC_INCLUDE@
|
@LIBGUAC_INCLUDE@
|
||||||
|
|
||||||
libguac_client_rdp_la_LDFLAGS = \
|
libguac_client_rdp_la_LDFLAGS = \
|
||||||
@ -138,6 +139,7 @@ libguac_client_rdp_la_LIBADD = \
|
|||||||
guacdr_cflags = \
|
guacdr_cflags = \
|
||||||
-Werror -Wall -Iinclude \
|
-Werror -Wall -Iinclude \
|
||||||
@COMMON_INCLUDE@ \
|
@COMMON_INCLUDE@ \
|
||||||
|
@COMMON_SSH_INCLUDE@ \
|
||||||
@LIBGUAC_INCLUDE@
|
@LIBGUAC_INCLUDE@
|
||||||
|
|
||||||
guacdr_ldflags = \
|
guacdr_ldflags = \
|
||||||
@ -156,6 +158,7 @@ guacdr_libadd = \
|
|||||||
guacsnd_cflags = \
|
guacsnd_cflags = \
|
||||||
-Werror -Wall -Iinclude \
|
-Werror -Wall -Iinclude \
|
||||||
@COMMON_INCLUDE@ \
|
@COMMON_INCLUDE@ \
|
||||||
|
@COMMON_SSH_INCLUDE@ \
|
||||||
@LIBGUAC_INCLUDE@
|
@LIBGUAC_INCLUDE@
|
||||||
|
|
||||||
guacsnd_ldflags = \
|
guacsnd_ldflags = \
|
||||||
@ -174,6 +177,7 @@ guacsnd_libadd = \
|
|||||||
guacsvc_cflags = \
|
guacsvc_cflags = \
|
||||||
-Werror -Wall -Iinclude \
|
-Werror -Wall -Iinclude \
|
||||||
@COMMON_INCLUDE@ \
|
@COMMON_INCLUDE@ \
|
||||||
|
@COMMON_SSH_INCLUDE@ \
|
||||||
@LIBGUAC_INCLUDE@
|
@LIBGUAC_INCLUDE@
|
||||||
|
|
||||||
guacsvc_ldflags = \
|
guacsvc_ldflags = \
|
||||||
@ -185,6 +189,16 @@ guacsvc_libadd = \
|
|||||||
@COMMON_LTLIB@ \
|
@COMMON_LTLIB@ \
|
||||||
@LIBGUAC_LTLIB@
|
@LIBGUAC_LTLIB@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Optional SFTP support
|
||||||
|
#
|
||||||
|
|
||||||
|
if ENABLE_COMMON_SSH
|
||||||
|
libguac_client_rdp_la_SOURCES += sftp.c
|
||||||
|
noinst_HEADERS += sftp.h
|
||||||
|
libguac_client_rdp_la_LIBADD += @COMMON_SSH_LTLIB@
|
||||||
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# Autogenerate keymaps
|
# Autogenerate keymaps
|
||||||
#
|
#
|
||||||
|
@ -35,6 +35,12 @@
|
|||||||
#include "rdp_svc.h"
|
#include "rdp_svc.h"
|
||||||
#include "resolution.h"
|
#include "resolution.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
#include "guac_sftp.h"
|
||||||
|
#include "guac_ssh.h"
|
||||||
|
#include "sftp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
||||||
#include "rdp_disp.h"
|
#include "rdp_disp.h"
|
||||||
#endif
|
#endif
|
||||||
@ -122,6 +128,17 @@ const char* GUAC_CLIENT_ARGS[] = {
|
|||||||
"enable-full-window-drag",
|
"enable-full-window-drag",
|
||||||
"enable-desktop-composition",
|
"enable-desktop-composition",
|
||||||
"enable-menu-animations",
|
"enable-menu-animations",
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
"enable-sftp",
|
||||||
|
"sftp-hostname",
|
||||||
|
"sftp-port",
|
||||||
|
"sftp-username",
|
||||||
|
"sftp-password",
|
||||||
|
"sftp-private-key",
|
||||||
|
"sftp-passphrase",
|
||||||
|
#endif
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -158,6 +175,17 @@ enum RDP_ARGS_IDX {
|
|||||||
IDX_ENABLE_FULL_WINDOW_DRAG,
|
IDX_ENABLE_FULL_WINDOW_DRAG,
|
||||||
IDX_ENABLE_DESKTOP_COMPOSITION,
|
IDX_ENABLE_DESKTOP_COMPOSITION,
|
||||||
IDX_ENABLE_MENU_ANIMATIONS,
|
IDX_ENABLE_MENU_ANIMATIONS,
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
IDX_ENABLE_SFTP,
|
||||||
|
IDX_SFTP_HOSTNAME,
|
||||||
|
IDX_SFTP_PORT,
|
||||||
|
IDX_SFTP_USERNAME,
|
||||||
|
IDX_SFTP_PASSWORD,
|
||||||
|
IDX_SFTP_PRIVATE_KEY,
|
||||||
|
IDX_SFTP_PASSPHRASE,
|
||||||
|
#endif
|
||||||
|
|
||||||
RDP_ARGS_COUNT
|
RDP_ARGS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -276,6 +304,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
|||||||
if (guac_client_data->settings.drive_enabled) {
|
if (guac_client_data->settings.drive_enabled) {
|
||||||
guac_client_data->filesystem =
|
guac_client_data->filesystem =
|
||||||
guac_rdp_fs_alloc(client, guac_client_data->settings.drive_path);
|
guac_rdp_fs_alloc(client, guac_client_data->settings.drive_path);
|
||||||
|
client->file_handler = guac_rdp_upload_file_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If RDPDR required, load it */
|
/* If RDPDR required, load it */
|
||||||
@ -447,7 +476,6 @@ BOOL rdp_freerdp_post_connect(freerdp* instance) {
|
|||||||
|
|
||||||
/* Stream handlers */
|
/* Stream handlers */
|
||||||
client->clipboard_handler = guac_rdp_clipboard_handler;
|
client->clipboard_handler = guac_rdp_clipboard_handler;
|
||||||
client->file_handler = guac_rdp_upload_file_handler;
|
|
||||||
client->pipe_handler = guac_rdp_svc_pipe_handler;
|
client->pipe_handler = guac_rdp_svc_pipe_handler;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -789,6 +817,90 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
/* Load keymap into client */
|
/* Load keymap into client */
|
||||||
__guac_rdp_client_load_keymap(client, settings->server_layout);
|
__guac_rdp_client_load_keymap(client, settings->server_layout);
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
guac_common_ssh_init(client);
|
||||||
|
|
||||||
|
/* Connect via SSH if SFTP is enabled */
|
||||||
|
if (strcmp(argv[IDX_ENABLE_SFTP], "true") == 0) {
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"Connecting via SSH for SFTP filesystem access.");
|
||||||
|
|
||||||
|
/* Parse username - use RDP username by default */
|
||||||
|
const char* sftp_username = argv[IDX_SFTP_USERNAME];
|
||||||
|
if (sftp_username[0] == '\0')
|
||||||
|
sftp_username = settings->username;
|
||||||
|
|
||||||
|
guac_common_ssh_user* user = guac_common_ssh_create_user(sftp_username);
|
||||||
|
|
||||||
|
/* Import private key, if given */
|
||||||
|
if (argv[IDX_SFTP_PRIVATE_KEY][0] != '\0') {
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"Authenticating with private key.");
|
||||||
|
|
||||||
|
/* Abort if private key cannot be read */
|
||||||
|
if (guac_common_ssh_user_import_key(user,
|
||||||
|
argv[IDX_SFTP_PRIVATE_KEY],
|
||||||
|
argv[IDX_SFTP_PASSPHRASE]))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, use specified password */
|
||||||
|
else {
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"Authenticating with password.");
|
||||||
|
|
||||||
|
/* Parse password - use RDP password by default */
|
||||||
|
const char* sftp_password = argv[IDX_SFTP_USERNAME];
|
||||||
|
if (sftp_password[0] == '\0')
|
||||||
|
sftp_password = settings->password;
|
||||||
|
|
||||||
|
guac_common_ssh_user_set_password(user, sftp_password);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse hostname - use RDP hostname by default */
|
||||||
|
const char* sftp_hostname = argv[IDX_SFTP_HOSTNAME];
|
||||||
|
if (sftp_hostname[0] == '\0')
|
||||||
|
sftp_hostname = settings->hostname;
|
||||||
|
|
||||||
|
/* Parse port, defaulting to standard SSH port */
|
||||||
|
const char* sftp_port = argv[IDX_SFTP_PORT];
|
||||||
|
if (sftp_port[0] == '\0')
|
||||||
|
sftp_port = "22";
|
||||||
|
|
||||||
|
/* Attempt SSH connection */
|
||||||
|
guac_common_ssh_session* session =
|
||||||
|
guac_common_ssh_create_session(client, sftp_hostname, sftp_port,
|
||||||
|
user);
|
||||||
|
|
||||||
|
/* Fail if SSH connection does not succeed */
|
||||||
|
if (session == NULL) {
|
||||||
|
/* Already aborted within guac_common_ssh_create_session() */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load and expose filesystem */
|
||||||
|
guac_client_data->sftp_filesystem =
|
||||||
|
guac_common_ssh_create_sftp_filesystem(session, "/");
|
||||||
|
|
||||||
|
/* Abort if SFTP connection fails */
|
||||||
|
if (guac_client_data->sftp_filesystem == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Use SFTP for basic uploads, if drive not enabled */
|
||||||
|
if (!settings->drive_enabled)
|
||||||
|
client->file_handler = guac_rdp_sftp_file_handler;
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"SFTP connection succeeded.");
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create default surface */
|
/* Create default surface */
|
||||||
guac_client_data->default_surface = guac_common_surface_alloc(client->socket, GUAC_DEFAULT_LAYER,
|
guac_client_data->default_surface = guac_common_surface_alloc(client->socket, GUAC_DEFAULT_LAYER,
|
||||||
settings->width, settings->height);
|
settings->width, settings->height);
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
#include "rdp_keymap.h"
|
#include "rdp_keymap.h"
|
||||||
#include "rdp_settings.h"
|
#include "rdp_settings.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
#include "guac_sftp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
||||||
#include "rdp_disp.h"
|
#include "rdp_disp.h"
|
||||||
#endif
|
#endif
|
||||||
@ -157,6 +161,13 @@ typedef struct rdp_guac_client_data {
|
|||||||
*/
|
*/
|
||||||
guac_rdp_fs* filesystem;
|
guac_rdp_fs* filesystem;
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
/**
|
||||||
|
* The exposed filesystem object, implemented with SFTP.
|
||||||
|
*/
|
||||||
|
guac_object* sftp_filesystem;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
||||||
/**
|
/**
|
||||||
* Display size update module.
|
* Display size update module.
|
||||||
|
@ -33,6 +33,11 @@
|
|||||||
#include "rdp_rail.h"
|
#include "rdp_rail.h"
|
||||||
#include "rdp_stream.h"
|
#include "rdp_stream.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
#include <guac_sftp.h>
|
||||||
|
#include <guac_ssh.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <freerdp/cache/cache.h>
|
#include <freerdp/cache/cache.h>
|
||||||
#include <freerdp/channels/channels.h>
|
#include <freerdp/channels/channels.h>
|
||||||
#include <freerdp/codec/color.h>
|
#include <freerdp/codec/color.h>
|
||||||
@ -89,6 +94,14 @@ int rdp_guac_client_free_handler(guac_client* client) {
|
|||||||
if (guac_client_data->filesystem != NULL)
|
if (guac_client_data->filesystem != NULL)
|
||||||
guac_rdp_fs_free(guac_client_data->filesystem);
|
guac_rdp_fs_free(guac_client_data->filesystem);
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
/* Free SFTP filesystem, if loaded */
|
||||||
|
if (guac_client_data->sftp_filesystem)
|
||||||
|
guac_common_ssh_destroy_sftp_filesystem(guac_client_data->sftp_filesystem);
|
||||||
|
|
||||||
|
guac_common_ssh_uninit();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
||||||
/* Free display update module */
|
/* Free display update module */
|
||||||
guac_rdp_disp_free(guac_client_data->disp);
|
guac_rdp_disp_free(guac_client_data->disp);
|
||||||
|
@ -486,7 +486,7 @@ int guac_rdp_download_get_handler(guac_client* client, guac_object* object,
|
|||||||
rdp_stream->ls_status.fs = fs;
|
rdp_stream->ls_status.fs = fs;
|
||||||
rdp_stream->ls_status.file_id = file_id;
|
rdp_stream->ls_status.file_id = file_id;
|
||||||
strncpy(rdp_stream->ls_status.directory_name, name,
|
strncpy(rdp_stream->ls_status.directory_name, name,
|
||||||
sizeof(rdp_stream->ls_status.directory_name));
|
sizeof(rdp_stream->ls_status.directory_name) - 1);
|
||||||
|
|
||||||
/* Allocate stream for body */
|
/* Allocate stream for body */
|
||||||
guac_stream* stream = guac_client_alloc_stream(client);
|
guac_stream* stream = guac_client_alloc_stream(client);
|
||||||
|
43
src/protocols/rdp/sftp.c
Normal file
43
src/protocols/rdp/sftp.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
|
#include "guac_sftp.h"
|
||||||
|
#include "sftp.h"
|
||||||
|
|
||||||
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/stream.h>
|
||||||
|
|
||||||
|
int guac_rdp_sftp_file_handler(guac_client* client, guac_stream* stream,
|
||||||
|
char* mimetype, char* filename) {
|
||||||
|
|
||||||
|
rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data;
|
||||||
|
guac_object* filesystem = client_data->sftp_filesystem;
|
||||||
|
|
||||||
|
/* Handle file upload */
|
||||||
|
return guac_common_ssh_sftp_handle_file_stream(filesystem, stream,
|
||||||
|
mimetype, filename);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
55
src/protocols/rdp/sftp.h
Normal file
55
src/protocols/rdp/sftp.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUAC_RDP_SFTP_H
|
||||||
|
#define GUAC_RDP_SFTP_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/stream.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles an incoming stream from a Guacamole "file" instruction, saving the
|
||||||
|
* contents of that stream to the file having the given name.
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* The client receiving the uploaded file.
|
||||||
|
*
|
||||||
|
* @param stream
|
||||||
|
* The stream through which the uploaded file data will be received.
|
||||||
|
*
|
||||||
|
* @param mimetype
|
||||||
|
* The mimetype of the data being received.
|
||||||
|
*
|
||||||
|
* @param filename
|
||||||
|
* The filename of the file to write to.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero if the incoming stream has been handled successfully, non-zero on
|
||||||
|
* failure.
|
||||||
|
*/
|
||||||
|
int guac_rdp_sftp_file_handler(guac_client* client, guac_stream* stream,
|
||||||
|
char* mimetype, char* filename);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -46,6 +46,7 @@ endif
|
|||||||
libguac_client_vnc_la_CFLAGS = \
|
libguac_client_vnc_la_CFLAGS = \
|
||||||
-Werror -Wall -pedantic -Iinclude \
|
-Werror -Wall -pedantic -Iinclude \
|
||||||
@COMMON_INCLUDE@ \
|
@COMMON_INCLUDE@ \
|
||||||
|
@COMMON_SSH_INCLUDE@ \
|
||||||
@LIBGUAC_INCLUDE@
|
@LIBGUAC_INCLUDE@
|
||||||
|
|
||||||
libguac_client_vnc_la_LDFLAGS = \
|
libguac_client_vnc_la_LDFLAGS = \
|
||||||
@ -58,3 +59,10 @@ libguac_client_vnc_la_LIBADD = \
|
|||||||
@COMMON_LTLIB@ \
|
@COMMON_LTLIB@ \
|
||||||
@LIBGUAC_LTLIB@
|
@LIBGUAC_LTLIB@
|
||||||
|
|
||||||
|
# Optional SFTP support
|
||||||
|
if ENABLE_COMMON_SSH
|
||||||
|
libguac_client_vnc_la_SOURCES += sftp.c
|
||||||
|
noinst_HEADERS += sftp.h
|
||||||
|
libguac_client_vnc_la_LIBADD += @COMMON_SSH_LTLIB@
|
||||||
|
endif
|
||||||
|
|
||||||
|
@ -34,6 +34,12 @@
|
|||||||
#include "pulse.h"
|
#include "pulse.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
#include "guac_sftp.h"
|
||||||
|
#include "guac_ssh.h"
|
||||||
|
#include "sftp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <rfb/rfbclient.h>
|
#include <rfb/rfbclient.h>
|
||||||
#include <rfb/rfbproto.h>
|
#include <rfb/rfbproto.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
@ -71,6 +77,16 @@ const char* GUAC_CLIENT_ARGS[] = {
|
|||||||
"listen-timeout",
|
"listen-timeout",
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
"enable-sftp",
|
||||||
|
"sftp-hostname",
|
||||||
|
"sftp-port",
|
||||||
|
"sftp-username",
|
||||||
|
"sftp-password",
|
||||||
|
"sftp-private-key",
|
||||||
|
"sftp-passphrase",
|
||||||
|
#endif
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,6 +117,16 @@ enum VNC_ARGS_IDX {
|
|||||||
IDX_LISTEN_TIMEOUT,
|
IDX_LISTEN_TIMEOUT,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
IDX_ENABLE_SFTP,
|
||||||
|
IDX_SFTP_HOSTNAME,
|
||||||
|
IDX_SFTP_PORT,
|
||||||
|
IDX_SFTP_USERNAME,
|
||||||
|
IDX_SFTP_PASSWORD,
|
||||||
|
IDX_SFTP_PRIVATE_KEY,
|
||||||
|
IDX_SFTP_PASSPHRASE,
|
||||||
|
#endif
|
||||||
|
|
||||||
VNC_ARGS_COUNT
|
VNC_ARGS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -337,6 +363,77 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
} /* end if audio enabled */
|
} /* end if audio enabled */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
guac_common_ssh_init(client);
|
||||||
|
|
||||||
|
/* Connect via SSH if SFTP is enabled */
|
||||||
|
if (strcmp(argv[IDX_ENABLE_SFTP], "true") == 0) {
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"Connecting via SSH for SFTP filesystem access.");
|
||||||
|
|
||||||
|
guac_common_ssh_user* user =
|
||||||
|
guac_common_ssh_create_user(argv[IDX_SFTP_USERNAME]);
|
||||||
|
|
||||||
|
/* Import private key, if given */
|
||||||
|
if (argv[IDX_SFTP_PRIVATE_KEY][0] != '\0') {
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"Authenticating with private key.");
|
||||||
|
|
||||||
|
/* Abort if private key cannot be read */
|
||||||
|
if (guac_common_ssh_user_import_key(user,
|
||||||
|
argv[IDX_SFTP_PRIVATE_KEY],
|
||||||
|
argv[IDX_SFTP_PASSPHRASE]))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, use specified password */
|
||||||
|
else {
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"Authenticating with password.");
|
||||||
|
guac_common_ssh_user_set_password(user, argv[IDX_SFTP_PASSWORD]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse hostname - use VNC hostname by default */
|
||||||
|
const char* sftp_hostname = argv[IDX_SFTP_HOSTNAME];
|
||||||
|
if (sftp_hostname[0] == '\0')
|
||||||
|
sftp_hostname = guac_client_data->hostname;
|
||||||
|
|
||||||
|
/* Parse port, defaulting to standard SSH port */
|
||||||
|
const char* sftp_port = argv[IDX_SFTP_PORT];
|
||||||
|
if (sftp_port[0] == '\0')
|
||||||
|
sftp_port = "22";
|
||||||
|
|
||||||
|
/* Attempt SSH connection */
|
||||||
|
guac_common_ssh_session* session =
|
||||||
|
guac_common_ssh_create_session(client, sftp_hostname, sftp_port,
|
||||||
|
user);
|
||||||
|
|
||||||
|
/* Fail if SSH connection does not succeed */
|
||||||
|
if (session == NULL) {
|
||||||
|
/* Already aborted within guac_common_ssh_create_session() */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load and expose filesystem */
|
||||||
|
guac_client_data->sftp_filesystem =
|
||||||
|
guac_common_ssh_create_sftp_filesystem(session, "/");
|
||||||
|
|
||||||
|
/* Abort if SFTP connection fails */
|
||||||
|
if (guac_client_data->sftp_filesystem == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Set file handler for basic uploads */
|
||||||
|
client->file_handler = guac_vnc_sftp_file_handler;
|
||||||
|
|
||||||
|
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||||
|
"SFTP connection succeeded.");
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set remaining client data */
|
/* Set remaining client data */
|
||||||
guac_client_data->rfb_client = rfb_client;
|
guac_client_data->rfb_client = rfb_client;
|
||||||
guac_client_data->copy_rect_used = 0;
|
guac_client_data->copy_rect_used = 0;
|
||||||
|
@ -36,6 +36,10 @@
|
|||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
#include "guac_sftp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum duration of a frame in milliseconds.
|
* The maximum duration of a frame in milliseconds.
|
||||||
*/
|
*/
|
||||||
@ -186,6 +190,13 @@ typedef struct vnc_guac_client_data {
|
|||||||
*/
|
*/
|
||||||
guac_common_surface* default_surface;
|
guac_common_surface* default_surface;
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
/**
|
||||||
|
* The exposed filesystem object, implemented with SFTP.
|
||||||
|
*/
|
||||||
|
guac_object* sftp_filesystem;
|
||||||
|
#endif
|
||||||
|
|
||||||
} vnc_guac_client_data;
|
} vnc_guac_client_data;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
#include <guacamole/timestamp.h>
|
#include <guacamole/timestamp.h>
|
||||||
#include <rfb/rfbclient.h>
|
#include <rfb/rfbclient.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
#include <guac_sftp.h>
|
||||||
|
#include <guac_ssh.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_PULSE
|
#ifdef ENABLE_PULSE
|
||||||
#include "pulse.h"
|
#include "pulse.h"
|
||||||
#endif
|
#endif
|
||||||
@ -135,6 +140,14 @@ int vnc_guac_client_free_handler(guac_client* client) {
|
|||||||
guac_pa_stop_stream(client);
|
guac_pa_stop_stream(client);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_COMMON_SSH
|
||||||
|
/* Free SFTP filesystem, if loaded */
|
||||||
|
if (guac_client_data->sftp_filesystem)
|
||||||
|
guac_common_ssh_destroy_sftp_filesystem(guac_client_data->sftp_filesystem);
|
||||||
|
|
||||||
|
guac_common_ssh_uninit();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Free encodings string, if used */
|
/* Free encodings string, if used */
|
||||||
if (guac_client_data->encodings != NULL)
|
if (guac_client_data->encodings != NULL)
|
||||||
free(guac_client_data->encodings);
|
free(guac_client_data->encodings);
|
||||||
|
43
src/protocols/vnc/sftp.c
Normal file
43
src/protocols/vnc/sftp.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
|
#include "guac_sftp.h"
|
||||||
|
#include "sftp.h"
|
||||||
|
|
||||||
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/stream.h>
|
||||||
|
|
||||||
|
int guac_vnc_sftp_file_handler(guac_client* client, guac_stream* stream,
|
||||||
|
char* mimetype, char* filename) {
|
||||||
|
|
||||||
|
vnc_guac_client_data* client_data = (vnc_guac_client_data*) client->data;
|
||||||
|
guac_object* filesystem = client_data->sftp_filesystem;
|
||||||
|
|
||||||
|
/* Handle file upload */
|
||||||
|
return guac_common_ssh_sftp_handle_file_stream(filesystem, stream,
|
||||||
|
mimetype, filename);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
55
src/protocols/vnc/sftp.h
Normal file
55
src/protocols/vnc/sftp.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUAC_VNC_SFTP_H
|
||||||
|
#define GUAC_VNC_SFTP_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/stream.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles an incoming stream from a Guacamole "file" instruction, saving the
|
||||||
|
* contents of that stream to the file having the given name.
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* The client receiving the uploaded file.
|
||||||
|
*
|
||||||
|
* @param stream
|
||||||
|
* The stream through which the uploaded file data will be received.
|
||||||
|
*
|
||||||
|
* @param mimetype
|
||||||
|
* The mimetype of the data being received.
|
||||||
|
*
|
||||||
|
* @param filename
|
||||||
|
* The filename of the file to write to.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero if the incoming stream has been handled successfully, non-zero on
|
||||||
|
* failure.
|
||||||
|
*/
|
||||||
|
int guac_vnc_sftp_file_handler(guac_client* client, guac_stream* stream,
|
||||||
|
char* mimetype, char* filename);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user