Merge branch 'master' into experimental
Conflicts: src/common/guac_surface.c
This commit is contained in:
commit
4e97843ef0
12
Makefile.am
12
Makefile.am
@ -42,27 +42,27 @@ SUBDIRS = \
|
||||
tests
|
||||
|
||||
if ENABLE_COMMON_SSH
|
||||
SUBDIRS += src/common-ssh
|
||||
SUBDIRS += src/common-ssh
|
||||
endif
|
||||
|
||||
if ENABLE_TERMINAL
|
||||
SUBDIRS += src/terminal
|
||||
SUBDIRS += src/terminal
|
||||
endif
|
||||
|
||||
if ENABLE_RDP
|
||||
SUBDIRS += src/protocols/rdp
|
||||
SUBDIRS += src/protocols/rdp
|
||||
endif
|
||||
|
||||
if ENABLE_SSH
|
||||
SUBDIRS += src/protocols/ssh
|
||||
SUBDIRS += src/protocols/ssh
|
||||
endif
|
||||
|
||||
if ENABLE_TELNET
|
||||
SUBDIRS += src/protocols/telnet
|
||||
SUBDIRS += src/protocols/telnet
|
||||
endif
|
||||
|
||||
if ENABLE_VNC
|
||||
SUBDIRS += src/protocols/vnc
|
||||
SUBDIRS += src/protocols/vnc
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013 Glyptodon LLC
|
||||
# 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
|
||||
@ -21,7 +21,7 @@
|
||||
#
|
||||
|
||||
AC_PREREQ([2.61])
|
||||
AC_INIT([guacamole-server], [0.9.7])
|
||||
AC_INIT([guacamole-server], [0.9.8])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
|
@ -31,7 +31,7 @@ PROJECT_NAME = libguac
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.9.7
|
||||
PROJECT_NUMBER = 0.9.8
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
@ -34,6 +34,78 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Translates the last error message received by the SFTP layer of an SSH
|
||||
* session into a Guacamole protocol status code.
|
||||
*
|
||||
* @param filesystem
|
||||
* The Guacamole protocol object defining the filesystem associated with
|
||||
* the SFTP and SSH sessions.
|
||||
*
|
||||
* @return
|
||||
* The Guacamole protocol status code corresponding to the last reported
|
||||
* error of the SFTP layer, if nay, or GUAC_PROTOCOL_STATUS_SUCCESS if no
|
||||
* error has occurred.
|
||||
*/
|
||||
static guac_protocol_status guac_sftp_get_status(guac_object* filesystem) {
|
||||
|
||||
guac_common_ssh_sftp_data* sftp_data =
|
||||
(guac_common_ssh_sftp_data*) filesystem->data;
|
||||
|
||||
/* Get libssh2 objects */
|
||||
LIBSSH2_SFTP* sftp = sftp_data->sftp_session;
|
||||
LIBSSH2_SESSION* session = sftp_data->ssh_session->session;
|
||||
|
||||
/* Return success code if no error occurred */
|
||||
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_SFTP_PROTOCOL)
|
||||
return GUAC_PROTOCOL_STATUS_SUCCESS;
|
||||
|
||||
/* Translate SFTP error codes defined by
|
||||
* https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02 (the most
|
||||
* commonly-implemented standard) */
|
||||
switch (libssh2_sftp_last_error(sftp)) {
|
||||
|
||||
/* SSH_FX_OK (not an error) */
|
||||
case 0:
|
||||
return GUAC_PROTOCOL_STATUS_SUCCESS;
|
||||
|
||||
/* SSH_FX_EOF (technically not an error) */
|
||||
case 1:
|
||||
return GUAC_PROTOCOL_STATUS_SUCCESS;
|
||||
|
||||
/* SSH_FX_NO_SUCH_FILE */
|
||||
case 2:
|
||||
return GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND;
|
||||
|
||||
/* SSH_FX_PERMISSION_DENIED */
|
||||
case 3:
|
||||
return GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN;
|
||||
|
||||
/* SSH_FX_FAILURE */
|
||||
case 4:
|
||||
return GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR;
|
||||
|
||||
/* SSH_FX_BAD_MESSAGE */
|
||||
case 5:
|
||||
return GUAC_PROTOCOL_STATUS_SERVER_ERROR;
|
||||
|
||||
/* SSH_FX_NO_CONNECTION / SSH_FX_CONNECTION_LOST */
|
||||
case 6:
|
||||
case 7:
|
||||
return GUAC_PROTOCOL_STATUS_UPSTREAM_TIMEOUT;
|
||||
|
||||
/* SSH_FX_OP_UNSUPPORTED */
|
||||
case 8:
|
||||
return GUAC_PROTOCOL_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Return generic error if cause unknown */
|
||||
default:
|
||||
return GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates the given filename with the given path, separating the two
|
||||
* with a single forward slash. The full result must be no more than
|
||||
@ -249,7 +321,7 @@ int guac_common_ssh_sftp_handle_file_stream(guac_object* filesystem,
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Unable to open file \"%s\"", fullpath);
|
||||
guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed",
|
||||
GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
|
||||
guac_sftp_get_status(filesystem));
|
||||
guac_socket_flush(client->socket);
|
||||
}
|
||||
|
||||
@ -642,7 +714,7 @@ static int guac_common_ssh_sftp_put_handler(guac_client* client,
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Unable to open file \"%s\"", name);
|
||||
guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed",
|
||||
GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
|
||||
guac_sftp_get_status(object));
|
||||
}
|
||||
|
||||
/* Set handlers for file stream */
|
||||
|
@ -77,7 +77,7 @@ initdir = @init_dir@
|
||||
init_SCRIPTS = init.d/guacd
|
||||
|
||||
init.d/guacd: init.d/guacd.in
|
||||
sed -e 's,[@]sbindir[@],$(sbindir),g' < init.d/guacd.in > init.d/guacd
|
||||
chmod +x init.d/guacd
|
||||
sed -e 's,[@]sbindir[@],$(sbindir),g' < init.d/guacd.in > init.d/guacd
|
||||
chmod +x init.d/guacd
|
||||
endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH guacd 8 "8 Jun 2015" "version 0.9.7" "Guacamole"
|
||||
.TH guacd 8 "4 Sep 2015" "version 0.9.8" "Guacamole"
|
||||
.
|
||||
.SH NAME
|
||||
guacd \- Guacamole proxy daemon
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH guacd.conf 5 "8 Jun 2015" "version 0.9.7" "Guacamole"
|
||||
.TH guacd.conf 5 "4 Sep 2015" "version 0.9.8" "Guacamole"
|
||||
.
|
||||
.SH NAME
|
||||
/etc/guacamole/guacd.conf \- Configuration file for guacd
|
||||
|
@ -98,13 +98,13 @@ endif
|
||||
libguac_la_CFLAGS = \
|
||||
-Werror -Wall -pedantic -Iguacamole
|
||||
|
||||
libguac_la_LDFLAGS = \
|
||||
-version-info 9:0:0 \
|
||||
@CAIRO_LIBS@ \
|
||||
@JPEG_LIBS@ \
|
||||
@PNG_LIBS@ \
|
||||
@PTHREAD_LIBS@ \
|
||||
@UUID_LIBS@ \
|
||||
libguac_la_LDFLAGS = \
|
||||
-version-info 10:0:0 \
|
||||
@CAIRO_LIBS@ \
|
||||
@JPEG_LIBS@ \
|
||||
@PNG_LIBS@ \
|
||||
@PTHREAD_LIBS@ \
|
||||
@UUID_LIBS@ \
|
||||
@VORBIS_LIBS@
|
||||
|
||||
libguac_la_LIBADD = \
|
||||
|
@ -84,6 +84,19 @@ int guac_telnet_client_key_handler(guac_client* client, int keysym, int pressed)
|
||||
|
||||
}
|
||||
|
||||
/* Intercept and handle Pause / Break / Ctrl+0 as "IAC BRK" */
|
||||
if (pressed && (
|
||||
keysym == 0xFF13 /* Pause */
|
||||
|| keysym == 0xFF6B /* Break */
|
||||
|| (term->mod_ctrl && keysym == '0') /* Ctrl + 0 */
|
||||
)) {
|
||||
|
||||
/* Send IAC BRK */
|
||||
telnet_iac(client_data->telnet, TELNET_BREAK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send key */
|
||||
guac_terminal_send_key(term, keysym, pressed);
|
||||
|
||||
|
@ -27,8 +27,41 @@
|
||||
|
||||
#include <guacamole/audio.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
/**
|
||||
* Returns whether the given buffer contains only silence (only null bytes).
|
||||
*
|
||||
* @param buffer
|
||||
* The audio buffer to check.
|
||||
*
|
||||
* @param length
|
||||
* The length of the buffer to check.
|
||||
*
|
||||
* @return
|
||||
* Non-zero if the audio buffer contains silence, zero otherwise.
|
||||
*/
|
||||
static int guac_pa_is_silence(const void* buffer, size_t length) {
|
||||
|
||||
int i;
|
||||
|
||||
const unsigned char* current = (const unsigned char*) buffer;
|
||||
|
||||
/* For each byte in buffer */
|
||||
for (i = 0; i < length; i++) {
|
||||
|
||||
/* If current value non-zero, then not silence */
|
||||
if (*(current++))
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* Otherwise, the buffer contains 100% silence */
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static void __stream_read_callback(pa_stream* stream, size_t length,
|
||||
void* data) {
|
||||
|
||||
@ -41,16 +74,22 @@ static void __stream_read_callback(pa_stream* stream, size_t length,
|
||||
/* Read data */
|
||||
pa_stream_peek(stream, &buffer, &length);
|
||||
|
||||
/* Write data */
|
||||
guac_audio_stream_write_pcm(audio, buffer, length);
|
||||
/* Avoid sending silence unless data is waiting to be flushed */
|
||||
if (audio->pcm_bytes_written != 0 || !guac_pa_is_silence(buffer, length)) {
|
||||
|
||||
/* Write data */
|
||||
guac_audio_stream_write_pcm(audio, buffer, length);
|
||||
|
||||
/* Flush occasionally */
|
||||
if (audio->pcm_bytes_written > GUAC_VNC_PCM_WRITE_RATE) {
|
||||
guac_audio_stream_end(audio);
|
||||
guac_audio_stream_begin(client_data->audio,
|
||||
GUAC_VNC_AUDIO_RATE,
|
||||
GUAC_VNC_AUDIO_CHANNELS,
|
||||
GUAC_VNC_AUDIO_BPS);
|
||||
guac_socket_flush(client->socket);
|
||||
}
|
||||
|
||||
/* Flush occasionally */
|
||||
if (audio->pcm_bytes_written > GUAC_VNC_PCM_WRITE_RATE) {
|
||||
guac_audio_stream_end(audio);
|
||||
guac_audio_stream_begin(client_data->audio,
|
||||
GUAC_VNC_AUDIO_RATE,
|
||||
GUAC_VNC_AUDIO_CHANNELS,
|
||||
GUAC_VNC_AUDIO_BPS);
|
||||
}
|
||||
|
||||
/* Advance buffer */
|
||||
|
Loading…
Reference in New Issue
Block a user