in src/common-ssh/sftp.c [740:841]
static int guac_common_ssh_sftp_get_handler(guac_user* user,
guac_object* object, char* name) {
char fullpath[GUAC_COMMON_SSH_SFTP_MAX_PATH];
guac_common_ssh_sftp_filesystem* filesystem =
(guac_common_ssh_sftp_filesystem*) object->data;
LIBSSH2_SFTP* sftp = filesystem->sftp_session;
LIBSSH2_SFTP_ATTRIBUTES attributes;
/* Translate stream name into filesystem path */
if (!guac_common_ssh_sftp_translate_name(fullpath, object, name)) {
guac_user_log(user, GUAC_LOG_INFO, "Unable to generate real path "
"for stream \"%s\"", name);
return 0;
}
/* Attempt to read file information */
if (libssh2_sftp_stat(sftp, fullpath, &attributes)) {
guac_user_log(user, GUAC_LOG_INFO, "Unable to read file \"%s\"",
fullpath);
return 0;
}
/* If directory, send contents of directory */
if (LIBSSH2_SFTP_S_ISDIR(attributes.permissions)) {
/* Open as directory */
LIBSSH2_SFTP_HANDLE* dir = libssh2_sftp_opendir(sftp, fullpath);
if (dir == NULL) {
guac_user_log(user, GUAC_LOG_INFO,
"Unable to read directory \"%s\"", fullpath);
return 0;
}
/* Init directory listing state */
guac_common_ssh_sftp_ls_state* list_state =
guac_mem_alloc(sizeof(guac_common_ssh_sftp_ls_state));
list_state->directory = dir;
list_state->filesystem = filesystem;
int length = guac_strlcpy(list_state->directory_name, name,
sizeof(list_state->directory_name));
/* Bail out if directory name is too long to store */
if (length >= sizeof(list_state->directory_name)) {
guac_user_log(user, GUAC_LOG_INFO, "Unable to read directory "
"\"%s\": Path too long", fullpath);
guac_mem_free(list_state);
return 0;
}
/* Allocate stream for body */
guac_stream* stream = guac_user_alloc_stream(user);
stream->ack_handler = guac_common_ssh_sftp_ls_ack_handler;
stream->data = list_state;
/* Init JSON object state */
guac_common_json_begin_object(user, stream, &list_state->json_state);
/* Associate new stream with get request */
guac_protocol_send_body(user->socket, object, stream,
GUAC_USER_STREAM_INDEX_MIMETYPE, name);
}
/* Otherwise, send file contents */
else {
/* If downloads are disabled, log and return. */
if (filesystem->disable_download) {
guac_user_log(user, GUAC_LOG_INFO,
"Unable to download file \"%s\", "
"file downloads have been disabled.", fullpath);
return 0;
}
/* Open as normal file */
LIBSSH2_SFTP_HANDLE* file = libssh2_sftp_open(sftp, fullpath,
LIBSSH2_FXF_READ, 0);
if (file == NULL) {
guac_user_log(user, GUAC_LOG_INFO,
"Unable to read file \"%s\"", fullpath);
return 0;
}
/* Allocate stream for body */
guac_stream* stream = guac_user_alloc_stream(user);
stream->ack_handler = guac_common_ssh_sftp_ack_handler;
stream->data = file;
/* Associate new stream with get request */
guac_protocol_send_body(user->socket, object, stream,
"application/octet-stream", name);
}
guac_socket_flush(user->socket);
return 0;
}