Merge branch 'master' into experimental

Conflicts:
	src/common/guac_surface.c
This commit is contained in:
Michael Jumper 2015-09-14 14:19:54 -07:00
commit 4e97843ef0
10 changed files with 155 additions and 31 deletions

View File

@ -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 = \

View File

@ -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])

View File

@ -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.

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = \

View File

@ -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);

View File

@ -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 */