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
|
tests
|
||||||
|
|
||||||
if ENABLE_COMMON_SSH
|
if ENABLE_COMMON_SSH
|
||||||
SUBDIRS += src/common-ssh
|
SUBDIRS += src/common-ssh
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_TERMINAL
|
if ENABLE_TERMINAL
|
||||||
SUBDIRS += src/terminal
|
SUBDIRS += src/terminal
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_RDP
|
if ENABLE_RDP
|
||||||
SUBDIRS += src/protocols/rdp
|
SUBDIRS += src/protocols/rdp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_SSH
|
if ENABLE_SSH
|
||||||
SUBDIRS += src/protocols/ssh
|
SUBDIRS += src/protocols/ssh
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_TELNET
|
if ENABLE_TELNET
|
||||||
SUBDIRS += src/protocols/telnet
|
SUBDIRS += src/protocols/telnet
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_VNC
|
if ENABLE_VNC
|
||||||
SUBDIRS += src/protocols/vnc
|
SUBDIRS += src/protocols/vnc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST = \
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -21,7 +21,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
AC_PREREQ([2.61])
|
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_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ PROJECT_NAME = libguac
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# 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)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
@ -34,6 +34,78 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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
|
* Concatenates the given filename with the given path, separating the two
|
||||||
* with a single forward slash. The full result must be no more than
|
* 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,
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
"Unable to open file \"%s\"", fullpath);
|
"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_sftp_get_status(filesystem));
|
||||||
guac_socket_flush(client->socket);
|
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,
|
guac_client_log(client, GUAC_LOG_INFO,
|
||||||
"Unable to open file \"%s\"", name);
|
"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_sftp_get_status(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set handlers for file stream */
|
/* Set handlers for file stream */
|
||||||
|
@ -77,7 +77,7 @@ initdir = @init_dir@
|
|||||||
init_SCRIPTS = init.d/guacd
|
init_SCRIPTS = init.d/guacd
|
||||||
|
|
||||||
init.d/guacd: init.d/guacd.in
|
init.d/guacd: init.d/guacd.in
|
||||||
sed -e 's,[@]sbindir[@],$(sbindir),g' < init.d/guacd.in > init.d/guacd
|
sed -e 's,[@]sbindir[@],$(sbindir),g' < init.d/guacd.in > init.d/guacd
|
||||||
chmod +x init.d/guacd
|
chmod +x init.d/guacd
|
||||||
endif
|
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
|
.SH NAME
|
||||||
guacd \- Guacamole proxy daemon
|
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
|
.SH NAME
|
||||||
/etc/guacamole/guacd.conf \- Configuration file for guacd
|
/etc/guacamole/guacd.conf \- Configuration file for guacd
|
||||||
|
@ -98,13 +98,13 @@ endif
|
|||||||
libguac_la_CFLAGS = \
|
libguac_la_CFLAGS = \
|
||||||
-Werror -Wall -pedantic -Iguacamole
|
-Werror -Wall -pedantic -Iguacamole
|
||||||
|
|
||||||
libguac_la_LDFLAGS = \
|
libguac_la_LDFLAGS = \
|
||||||
-version-info 9:0:0 \
|
-version-info 10:0:0 \
|
||||||
@CAIRO_LIBS@ \
|
@CAIRO_LIBS@ \
|
||||||
@JPEG_LIBS@ \
|
@JPEG_LIBS@ \
|
||||||
@PNG_LIBS@ \
|
@PNG_LIBS@ \
|
||||||
@PTHREAD_LIBS@ \
|
@PTHREAD_LIBS@ \
|
||||||
@UUID_LIBS@ \
|
@UUID_LIBS@ \
|
||||||
@VORBIS_LIBS@
|
@VORBIS_LIBS@
|
||||||
|
|
||||||
libguac_la_LIBADD = \
|
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 */
|
/* Send key */
|
||||||
guac_terminal_send_key(term, keysym, pressed);
|
guac_terminal_send_key(term, keysym, pressed);
|
||||||
|
|
||||||
|
@ -27,8 +27,41 @@
|
|||||||
|
|
||||||
#include <guacamole/audio.h>
|
#include <guacamole/audio.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/socket.h>
|
||||||
#include <pulse/pulseaudio.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,
|
static void __stream_read_callback(pa_stream* stream, size_t length,
|
||||||
void* data) {
|
void* data) {
|
||||||
|
|
||||||
@ -41,16 +74,22 @@ static void __stream_read_callback(pa_stream* stream, size_t length,
|
|||||||
/* Read data */
|
/* Read data */
|
||||||
pa_stream_peek(stream, &buffer, &length);
|
pa_stream_peek(stream, &buffer, &length);
|
||||||
|
|
||||||
/* Write data */
|
/* Avoid sending silence unless data is waiting to be flushed */
|
||||||
guac_audio_stream_write_pcm(audio, buffer, length);
|
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 */
|
/* Advance buffer */
|
||||||
|
Loading…
Reference in New Issue
Block a user