You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2017/01/25 00:39:40 UTC
[1/4] incubator-guacamole-server git commit: GUACAMOLE-175: Move
common core of guacd into libguacd utility library.
Repository: incubator-guacamole-server
Updated Branches:
refs/heads/master 396eaa21f -> 5d2c9676f
GUACAMOLE-175: Move common core of guacd into libguacd utility library.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/d7a604c8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/d7a604c8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/d7a604c8
Branch: refs/heads/master
Commit: d7a604c8b29574be21002ad5c90ff27d76301824
Parents: a1886f5
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Sep 9 10:44:16 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jan 24 15:44:51 2017 -0800
----------------------------------------------------------------------
Makefile.am | 8 +-
configure.ac | 5 ++
src/guacd/Makefile.am | 20 ++---
src/guacd/log.c | 168 -----------------------------------------
src/guacd/log.h | 80 --------------------
src/guacd/socket-ssl.c | 153 -------------------------------------
src/guacd/socket-ssl.h | 71 -----------------
src/guacd/user.c | 113 ---------------------------
src/guacd/user.h | 98 ------------------------
src/libguacd/Makefile.am | 50 ++++++++++++
src/libguacd/log.c | 168 +++++++++++++++++++++++++++++++++++++++++
src/libguacd/log.h | 80 ++++++++++++++++++++
src/libguacd/socket-ssl.c | 153 +++++++++++++++++++++++++++++++++++++
src/libguacd/socket-ssl.h | 71 +++++++++++++++++
src/libguacd/user.c | 113 +++++++++++++++++++++++++++
src/libguacd/user.h | 98 ++++++++++++++++++++++++
16 files changed, 749 insertions(+), 700 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index 54899e9..78f76e1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,6 +22,7 @@ ACLOCAL_AMFLAGS = -I m4
# Subprojects
DIST_SUBDIRS = \
src/libguac \
+ src/libguacd \
src/common \
src/common-ssh \
src/terminal \
@@ -33,9 +34,10 @@ DIST_SUBDIRS = \
src/protocols/vnc \
tests
-SUBDIRS = \
- src/libguac \
- src/common \
+SUBDIRS = \
+ src/libguac \
+ src/common \
+ src/libguacd \
tests
if ENABLE_COMMON_SSH
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 4c43359..a763d6a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,6 +119,10 @@ AC_SUBST([LIBGUAC_INCLUDE], '-I$(top_srcdir)/src/libguac')
AC_SUBST([COMMON_LTLIB], '$(top_builddir)/src/common/libguac_common.la')
AC_SUBST([COMMON_INCLUDE], '-I$(top_srcdir)/src/common')
+# Common utility library for guacd implementations
+AC_SUBST([LIBGUACD_LTLIB], '$(top_builddir)/src/libguacd/libguacd.la')
+AC_SUBST([LIBGUACD_INCLUDE], '-I$(top_srcdir)/src/libguacd')
+
# Common base SSH client
AC_SUBST([COMMON_SSH_LTLIB], '$(top_builddir)/src/common-ssh/libguac_common_ssh.la')
AC_SUBST([COMMON_SSH_INCLUDE], '-I$(top_srcdir)/src/common-ssh')
@@ -1101,6 +1105,7 @@ AC_CONFIG_FILES([Makefile
src/common-ssh/Makefile
src/terminal/Makefile
src/libguac/Makefile
+ src/libguacd/Makefile
src/guacd/Makefile
src/guacenc/Makefile
src/protocols/rdp/Makefile
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/Makefile.am
----------------------------------------------------------------------
diff --git a/src/guacd/Makefile.am b/src/guacd/Makefile.am
index 51e5f87..e25a101 100644
--- a/src/guacd/Makefile.am
+++ b/src/guacd/Makefile.am
@@ -30,11 +30,9 @@ noinst_HEADERS = \
conf-file.h \
conf-parse.h \
connection.h \
- log.h \
move-fd.h \
proc.h \
- proc-map.h \
- user.h
+ proc-map.h
guacd_SOURCES = \
conf-args.c \
@@ -42,19 +40,19 @@ guacd_SOURCES = \
conf-parse.c \
connection.c \
daemon.c \
- log.c \
move-fd.c \
proc.c \
- proc-map.c \
- user.c
+ proc-map.c
guacd_CFLAGS = \
-Werror -Wall -pedantic \
@COMMON_INCLUDE@ \
+ @LIBGUACD_INCLUDE@ \
@LIBGUAC_INCLUDE@
-guacd_LDADD = \
- @COMMON_LTLIB@ \
+guacd_LDADD = \
+ @COMMON_LTLIB@ \
+ @LIBGUACD_LTLIB@ \
@LIBGUAC_LTLIB@
guacd_LDFLAGS = \
@@ -68,12 +66,6 @@ EXTRA_DIST = \
CLEANFILES = $(init_SCRIPTS)
-# SSL support
-if ENABLE_SSL
-noinst_HEADERS += socket-ssl.h
-guacd_SOURCES += socket-ssl.c
-endif
-
# Init script
if ENABLE_INIT
initdir = @init_dir@
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/log.c
----------------------------------------------------------------------
diff --git a/src/guacd/log.c b/src/guacd/log.c
deleted file mode 100644
index 229d2f9..0000000
--- a/src/guacd/log.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "config.h"
-#include "log.h"
-
-#include <guacamole/client.h>
-#include <guacamole/error.h>
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <unistd.h>
-
-int guacd_log_level = GUAC_LOG_INFO;
-
-void vguacd_log(guac_client_log_level level, const char* format,
- va_list args) {
-
- const char* priority_name;
- int priority;
-
- char message[2048];
-
- /* Don't bother if the log level is too high */
- if (level > guacd_log_level)
- return;
-
- /* Copy log message into buffer */
- vsnprintf(message, sizeof(message), format, args);
-
- /* Convert log level to syslog priority */
- switch (level) {
-
- /* Error log level */
- case GUAC_LOG_ERROR:
- priority = LOG_ERR;
- priority_name = "ERROR";
- break;
-
- /* Warning log level */
- case GUAC_LOG_WARNING:
- priority = LOG_WARNING;
- priority_name = "WARNING";
- break;
-
- /* Informational log level */
- case GUAC_LOG_INFO:
- priority = LOG_INFO;
- priority_name = "INFO";
- break;
-
- /* Debug log level */
- case GUAC_LOG_DEBUG:
- priority = LOG_DEBUG;
- priority_name = "DEBUG";
- break;
-
- /* Any unknown/undefined log level */
- default:
- priority = LOG_INFO;
- priority_name = "UNKNOWN";
- break;
- }
-
- /* Log to syslog */
- syslog(priority, "%s", message);
-
- /* Log to STDERR */
- fprintf(stderr, GUACD_LOG_NAME "[%i]: %s:\t%s\n",
- getpid(), priority_name, message);
-
-}
-
-void guacd_log(guac_client_log_level level, const char* format, ...) {
- va_list args;
- va_start(args, format);
- vguacd_log(level, format, args);
- va_end(args);
-}
-
-void guacd_client_log(guac_client* client, guac_client_log_level level,
- const char* format, va_list args) {
- vguacd_log(level, format, args);
-}
-
-void guacd_log_guac_error(guac_client_log_level level, const char* message) {
-
- if (guac_error != GUAC_STATUS_SUCCESS) {
-
- /* If error message provided, include in log */
- if (guac_error_message != NULL)
- guacd_log(level, "%s: %s",
- message,
- guac_error_message);
-
- /* Otherwise just log with standard status string */
- else
- guacd_log(level, "%s: %s",
- message,
- guac_status_string(guac_error));
-
- }
-
- /* Just log message if no status code */
- else
- guacd_log(level, "%s", message);
-
-}
-
-void guacd_client_log_guac_error(guac_client* client,
- guac_client_log_level level, const char* message) {
-
- if (guac_error != GUAC_STATUS_SUCCESS) {
-
- /* If error message provided, include in log */
- if (guac_error_message != NULL)
- guac_client_log(client, level, "%s: %s",
- message,
- guac_error_message);
-
- /* Otherwise just log with standard status string */
- else
- guac_client_log(client, level, "%s: %s",
- message,
- guac_status_string(guac_error));
-
- }
-
- /* Just log message if no status code */
- else
- guac_client_log(client, level, "%s", message);
-
-}
-
-void guacd_log_handshake_failure() {
-
- if (guac_error == GUAC_STATUS_CLOSED)
- guacd_log(GUAC_LOG_INFO,
- "Guacamole connection closed during handshake");
- else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
- guacd_log(GUAC_LOG_ERROR,
- "Guacamole protocol violation. Perhaps the version of "
- "guacamole-client is incompatible with this version of "
- "guacd?");
- else
- guacd_log(GUAC_LOG_WARNING,
- "Guacamole handshake failed: %s",
- guac_status_string(guac_error));
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/log.h
----------------------------------------------------------------------
diff --git a/src/guacd/log.h b/src/guacd/log.h
deleted file mode 100644
index 09fe152..0000000
--- a/src/guacd/log.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-#ifndef __GUACD_LOG_H
-#define __GUACD_LOG_H
-
-#include "config.h"
-
-#include <guacamole/client.h>
-
-/**
- * The maximum level at which to log messages. All other messages will be
- * dropped.
- */
-extern int guacd_log_level;
-
-/**
- * The string to prepend to all log messages.
- */
-#define GUACD_LOG_NAME "guacd"
-
-/**
- * Writes a message to guacd's logs. This function takes a format and va_list,
- * similar to vprintf.
- */
-void vguacd_log(guac_client_log_level level, const char* format, va_list args);
-
-/**
- * Writes a message to guacd's logs. This function accepts parameters
- * identically to printf.
- */
-void guacd_log(guac_client_log_level level, const char* format, ...);
-
-/**
- * Writes a message using the logging facilities of the given client. This
- * function accepts parameters identically to printf.
- */
-void guacd_client_log(guac_client* client, guac_client_log_level level,
- const char* format, va_list args);
-
-/**
- * Prints an error message to guacd's logs, automatically including any
- * information present in guac_error. This function accepts parameters
- * identically to printf.
- */
-void guacd_log_guac_error(guac_client_log_level level, const char* message);
-
-/**
- * Prints an error message using the logging facilities of the given client,
- * automatically including any information present in guac_error. This function
- * accepts parameters identically to printf.
- */
-void guacd_client_log_guac_error(guac_client* client,
- guac_client_log_level level, const char* message);
-
-/**
- * Logs a reasonable explanatory message regarding handshake failure based on
- * the current value of guac_error.
- */
-void guacd_log_handshake_failure();
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/socket-ssl.c
----------------------------------------------------------------------
diff --git a/src/guacd/socket-ssl.c b/src/guacd/socket-ssl.c
deleted file mode 100644
index 4f19442..0000000
--- a/src/guacd/socket-ssl.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "config.h"
-
-#include "socket-ssl.h"
-
-#include <poll.h>
-#include <stdlib.h>
-
-#include <guacamole/error.h>
-#include <guacamole/socket.h>
-#include <openssl/ssl.h>
-
-static ssize_t __guac_socket_ssl_read_handler(guac_socket* socket,
- void* buf, size_t count) {
-
- /* Read from socket */
- guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
- int retval;
-
- retval = SSL_read(data->ssl, buf, count);
-
- /* Record errors in guac_error */
- if (retval <= 0) {
- guac_error = GUAC_STATUS_SEE_ERRNO;
- guac_error_message = "Error reading data from secure socket";
- }
-
- return retval;
-
-}
-
-static ssize_t __guac_socket_ssl_write_handler(guac_socket* socket,
- const void* buf, size_t count) {
-
- /* Write data to socket */
- guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
- int retval;
-
- retval = SSL_write(data->ssl, buf, count);
-
- /* Record errors in guac_error */
- if (retval <= 0) {
- guac_error = GUAC_STATUS_SEE_ERRNO;
- guac_error_message = "Error writing data to secure socket";
- }
-
- return retval;
-
-}
-
-static int __guac_socket_ssl_select_handler(guac_socket* socket, int usec_timeout) {
-
- guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
-
- int retval;
-
- /* Initialize with single underlying file descriptor */
- struct pollfd fds[1] = {{
- .fd = data->fd,
- .events = POLLIN,
- .revents = 0,
- }};
-
- /* No timeout if usec_timeout is negative */
- if (usec_timeout < 0)
- retval = poll(fds, 1, -1);
-
- /* Handle timeout if specified, rounding up to poll()'s granularity */
- else
- retval = poll(fds, 1, (usec_timeout + 999) / 1000);
-
- /* Properly set guac_error */
- if (retval < 0) {
- guac_error = GUAC_STATUS_SEE_ERRNO;
- guac_error_message = "Error while waiting for data on secure socket";
- }
-
- if (retval == 0) {
- guac_error = GUAC_STATUS_TIMEOUT;
- guac_error_message = "Timeout while waiting for data on secure socket";
- }
-
- return retval;
-
-}
-
-static int __guac_socket_ssl_free_handler(guac_socket* socket) {
-
- /* Shutdown SSL */
- guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
- SSL_shutdown(data->ssl);
-
- /* Close file descriptor */
- close(data->fd);
-
- free(data);
- return 0;
-}
-
-guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) {
-
- /* Allocate socket and associated data */
- guac_socket* socket = guac_socket_alloc();
- guac_socket_ssl_data* data = malloc(sizeof(guac_socket_ssl_data));
-
- /* Init SSL */
- data->context = context;
- data->ssl = SSL_new(context);
- SSL_set_fd(data->ssl, fd);
-
- /* Accept SSL connection, handle errors */
- if (SSL_accept(data->ssl) <= 0) {
-
- guac_error = GUAC_STATUS_INTERNAL_ERROR;
- guac_error_message = "SSL accept failed";
-
- free(data);
- guac_socket_free(socket);
- return NULL;
- }
-
- /* Store file descriptor as socket data */
- data->fd = fd;
- socket->data = data;
-
- /* Set read/write handlers */
- socket->read_handler = __guac_socket_ssl_read_handler;
- socket->write_handler = __guac_socket_ssl_write_handler;
- socket->select_handler = __guac_socket_ssl_select_handler;
- socket->free_handler = __guac_socket_ssl_free_handler;
-
- return socket;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/socket-ssl.h
----------------------------------------------------------------------
diff --git a/src/guacd/socket-ssl.h b/src/guacd/socket-ssl.h
deleted file mode 100644
index e1a341e..0000000
--- a/src/guacd/socket-ssl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-#ifndef __GUACD_SOCKET_SSL_H
-#define __GUACD_SOCKET_SSL_H
-
-#include "config.h"
-
-#include <guacamole/socket.h>
-#include <openssl/ssl.h>
-
-/**
- * SSL socket-specific data.
- */
-typedef struct guac_socket_ssl_data {
-
- /**
- * The file descriptor that SSL communication will take place
- * over.
- */
- int fd;
-
- /**
- * The current SSL context.
- */
- SSL_CTX* context;
-
- /**
- * The SSL connection, created automatically via
- * guac_socket_open_secure().
- */
- SSL* ssl;
-
-} guac_socket_ssl_data;
-
-/**
- * Creates a new guac_socket which will use SSL for all communication. Freeing
- * this guac_socket will automatically close the associated file descriptor.
- *
- * @param context
- * The SSL_CTX structure describing the desired SSL configuration.
- *
- * @param fd
- * The file descriptor to use for the SSL connection underlying the
- * created guac_socket.
- *
- * @return
- * A newly-allocated guac_socket which will transparently use SSL for
- * all communication.
- */
-guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/user.c
----------------------------------------------------------------------
diff --git a/src/guacd/user.c b/src/guacd/user.c
deleted file mode 100644
index 0a37147..0000000
--- a/src/guacd/user.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "config.h"
-
-#include "log.h"
-#include "user.h"
-
-#include <guacamole/client.h>
-#include <guacamole/error.h>
-#include <guacamole/parser.h>
-#include <guacamole/protocol.h>
-#include <guacamole/socket.h>
-#include <guacamole/user.h>
-
-#include <pthread.h>
-#include <stdlib.h>
-
-void* guacd_user_input_thread(void* data) {
-
- guacd_user_input_thread_params* params = (guacd_user_input_thread_params*) data;
- guac_user* user = params->user;
- guac_parser* parser = params->parser;
- guac_client* client = user->client;
- guac_socket* socket = user->socket;
-
- /* Guacamole user input loop */
- while (client->state == GUAC_CLIENT_RUNNING && user->active) {
-
- /* Read instruction, stop on error */
- if (guac_parser_read(parser, socket, GUACD_USEC_TIMEOUT)) {
-
- if (guac_error == GUAC_STATUS_TIMEOUT)
- guac_user_abort(user, GUAC_PROTOCOL_STATUS_CLIENT_TIMEOUT, "User is not responding.");
-
- else {
- if (guac_error != GUAC_STATUS_CLOSED)
- guacd_client_log_guac_error(client, GUAC_LOG_WARNING,
- "Guacamole connection failure");
- guac_user_stop(user);
- }
-
- return NULL;
- }
-
- /* Reset guac_error and guac_error_message (user/client handlers are not
- * guaranteed to set these) */
- guac_error = GUAC_STATUS_SUCCESS;
- guac_error_message = NULL;
-
- /* Call handler, stop on error */
- if (guac_user_handle_instruction(user, parser->opcode, parser->argc, parser->argv) < 0) {
-
- /* Log error */
- guacd_client_log_guac_error(client, GUAC_LOG_WARNING,
- "User connection aborted");
-
- /* Log handler details */
- guac_user_log(user, GUAC_LOG_DEBUG, "Failing instruction handler in user was \"%s\"", parser->opcode);
-
- guac_user_stop(user);
- return NULL;
- }
-
- }
-
- return NULL;
-
-}
-
-int guacd_user_start(guac_parser* parser, guac_user* user) {
-
- guacd_user_input_thread_params params = {
- .parser = parser,
- .user = user
- };
-
- pthread_t input_thread;
-
- if (pthread_create(&input_thread, NULL, guacd_user_input_thread, (void*) ¶ms)) {
- guac_user_log(user, GUAC_LOG_ERROR, "Unable to start input thread");
- guac_user_stop(user);
- return -1;
- }
-
- /* Wait for I/O threads */
- pthread_join(input_thread, NULL);
-
- /* Explicitly signal disconnect */
- guac_protocol_send_disconnect(user->socket);
- guac_socket_flush(user->socket);
-
- /* Done */
- return 0;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/guacd/user.h
----------------------------------------------------------------------
diff --git a/src/guacd/user.h b/src/guacd/user.h
deleted file mode 100644
index 65eef70..0000000
--- a/src/guacd/user.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-#ifndef _GUACD_USER_H
-#define _GUACD_USER_H
-
-#include "config.h"
-
-#include <guacamole/parser.h>
-#include <guacamole/socket.h>
-#include <guacamole/user.h>
-
-/**
- * The number of milliseconds to wait for messages in any phase before
- * timing out and closing the connection with an error.
- */
-#define GUACD_TIMEOUT 15000
-
-/**
- * The number of microseconds to wait for messages in any phase before
- * timing out and closing the conncetion with an error. This is always
- * equal to GUACD_TIMEOUT * 1000.
- */
-#define GUACD_USEC_TIMEOUT (GUACD_TIMEOUT*1000)
-
-/**
- * The maximum number of concurrent connections to a single instance
- * of guacd.
- */
-#define GUACD_CLIENT_MAX_CONNECTIONS 65536
-
-/**
- * Parameters required by the user input thread.
- */
-typedef struct guacd_user_input_thread_params {
-
- /**
- * The parser which will be used throughout the user's session.
- */
- guac_parser* parser;
-
- /**
- * A reference to the connected user.
- */
- guac_user* user;
-
-} guacd_user_input_thread_params;
-
-/**
- * Starts the input/output threads of a new user. This function will block
- * until the user disconnects. If an error prevents the input/output threads
- * from starting, guac_user_stop() will be invoked on the given user.
- *
- * @param parser
- * The guac_parser to use to handle all input from the given user.
- *
- * @param user
- * The user whose associated I/O transfer threads should be started.
- *
- * @return
- * Zero if the I/O threads started successfully and user has disconnected,
- * or non-zero if the I/O threads could not be started.
- */
-int guacd_user_start(guac_parser* parser, guac_user* user);
-
-/**
- * The thread which handles all user input, calling event handlers for received
- * instructions.
- *
- * @param data
- * A pointer to a guacd_user_input_thread_params structure describing the
- * user whose input is being handled and the guac_parser with which to
- * handle it.
- *
- * @return
- * Always NULL.
- */
-void* guacd_user_input_thread(void* data);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/Makefile.am
----------------------------------------------------------------------
diff --git a/src/libguacd/Makefile.am b/src/libguacd/Makefile.am
new file mode 100644
index 0000000..9e20cec
--- /dev/null
+++ b/src/libguacd/Makefile.am
@@ -0,0 +1,50 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_LTLIBRARIES = libguacd.la
+
+noinst_HEADERS = \
+ log.h \
+ user.h
+
+libguacd_la_SOURCES = \
+ log.c \
+ user.c
+
+libguacd_la_CFLAGS = \
+ -Werror -Wall -pedantic \
+ @COMMON_INCLUDE@ \
+ @LIBGUAC_INCLUDE@
+
+libguacd_la_LIBADD = \
+ @COMMON_LTLIB@ \
+ @LIBGUAC_LTLIB@
+
+libguacd_la_LDFLAGS = \
+ @PTHREAD_LIBS@ \
+ @SSL_LIBS@
+
+# SSL support
+if ENABLE_SSL
+noinst_HEADERS += socket-ssl.h
+libguacd_la_SOURCES += socket-ssl.c
+endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/log.c
----------------------------------------------------------------------
diff --git a/src/libguacd/log.c b/src/libguacd/log.c
new file mode 100644
index 0000000..229d2f9
--- /dev/null
+++ b/src/libguacd/log.c
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "log.h"
+
+#include <guacamole/client.h>
+#include <guacamole/error.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <unistd.h>
+
+int guacd_log_level = GUAC_LOG_INFO;
+
+void vguacd_log(guac_client_log_level level, const char* format,
+ va_list args) {
+
+ const char* priority_name;
+ int priority;
+
+ char message[2048];
+
+ /* Don't bother if the log level is too high */
+ if (level > guacd_log_level)
+ return;
+
+ /* Copy log message into buffer */
+ vsnprintf(message, sizeof(message), format, args);
+
+ /* Convert log level to syslog priority */
+ switch (level) {
+
+ /* Error log level */
+ case GUAC_LOG_ERROR:
+ priority = LOG_ERR;
+ priority_name = "ERROR";
+ break;
+
+ /* Warning log level */
+ case GUAC_LOG_WARNING:
+ priority = LOG_WARNING;
+ priority_name = "WARNING";
+ break;
+
+ /* Informational log level */
+ case GUAC_LOG_INFO:
+ priority = LOG_INFO;
+ priority_name = "INFO";
+ break;
+
+ /* Debug log level */
+ case GUAC_LOG_DEBUG:
+ priority = LOG_DEBUG;
+ priority_name = "DEBUG";
+ break;
+
+ /* Any unknown/undefined log level */
+ default:
+ priority = LOG_INFO;
+ priority_name = "UNKNOWN";
+ break;
+ }
+
+ /* Log to syslog */
+ syslog(priority, "%s", message);
+
+ /* Log to STDERR */
+ fprintf(stderr, GUACD_LOG_NAME "[%i]: %s:\t%s\n",
+ getpid(), priority_name, message);
+
+}
+
+void guacd_log(guac_client_log_level level, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ vguacd_log(level, format, args);
+ va_end(args);
+}
+
+void guacd_client_log(guac_client* client, guac_client_log_level level,
+ const char* format, va_list args) {
+ vguacd_log(level, format, args);
+}
+
+void guacd_log_guac_error(guac_client_log_level level, const char* message) {
+
+ if (guac_error != GUAC_STATUS_SUCCESS) {
+
+ /* If error message provided, include in log */
+ if (guac_error_message != NULL)
+ guacd_log(level, "%s: %s",
+ message,
+ guac_error_message);
+
+ /* Otherwise just log with standard status string */
+ else
+ guacd_log(level, "%s: %s",
+ message,
+ guac_status_string(guac_error));
+
+ }
+
+ /* Just log message if no status code */
+ else
+ guacd_log(level, "%s", message);
+
+}
+
+void guacd_client_log_guac_error(guac_client* client,
+ guac_client_log_level level, const char* message) {
+
+ if (guac_error != GUAC_STATUS_SUCCESS) {
+
+ /* If error message provided, include in log */
+ if (guac_error_message != NULL)
+ guac_client_log(client, level, "%s: %s",
+ message,
+ guac_error_message);
+
+ /* Otherwise just log with standard status string */
+ else
+ guac_client_log(client, level, "%s: %s",
+ message,
+ guac_status_string(guac_error));
+
+ }
+
+ /* Just log message if no status code */
+ else
+ guac_client_log(client, level, "%s", message);
+
+}
+
+void guacd_log_handshake_failure() {
+
+ if (guac_error == GUAC_STATUS_CLOSED)
+ guacd_log(GUAC_LOG_INFO,
+ "Guacamole connection closed during handshake");
+ else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
+ guacd_log(GUAC_LOG_ERROR,
+ "Guacamole protocol violation. Perhaps the version of "
+ "guacamole-client is incompatible with this version of "
+ "guacd?");
+ else
+ guacd_log(GUAC_LOG_WARNING,
+ "Guacamole handshake failed: %s",
+ guac_status_string(guac_error));
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/log.h
----------------------------------------------------------------------
diff --git a/src/libguacd/log.h b/src/libguacd/log.h
new file mode 100644
index 0000000..09fe152
--- /dev/null
+++ b/src/libguacd/log.h
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef __GUACD_LOG_H
+#define __GUACD_LOG_H
+
+#include "config.h"
+
+#include <guacamole/client.h>
+
+/**
+ * The maximum level at which to log messages. All other messages will be
+ * dropped.
+ */
+extern int guacd_log_level;
+
+/**
+ * The string to prepend to all log messages.
+ */
+#define GUACD_LOG_NAME "guacd"
+
+/**
+ * Writes a message to guacd's logs. This function takes a format and va_list,
+ * similar to vprintf.
+ */
+void vguacd_log(guac_client_log_level level, const char* format, va_list args);
+
+/**
+ * Writes a message to guacd's logs. This function accepts parameters
+ * identically to printf.
+ */
+void guacd_log(guac_client_log_level level, const char* format, ...);
+
+/**
+ * Writes a message using the logging facilities of the given client. This
+ * function accepts parameters identically to printf.
+ */
+void guacd_client_log(guac_client* client, guac_client_log_level level,
+ const char* format, va_list args);
+
+/**
+ * Prints an error message to guacd's logs, automatically including any
+ * information present in guac_error. This function accepts parameters
+ * identically to printf.
+ */
+void guacd_log_guac_error(guac_client_log_level level, const char* message);
+
+/**
+ * Prints an error message using the logging facilities of the given client,
+ * automatically including any information present in guac_error. This function
+ * accepts parameters identically to printf.
+ */
+void guacd_client_log_guac_error(guac_client* client,
+ guac_client_log_level level, const char* message);
+
+/**
+ * Logs a reasonable explanatory message regarding handshake failure based on
+ * the current value of guac_error.
+ */
+void guacd_log_handshake_failure();
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/socket-ssl.c
----------------------------------------------------------------------
diff --git a/src/libguacd/socket-ssl.c b/src/libguacd/socket-ssl.c
new file mode 100644
index 0000000..4f19442
--- /dev/null
+++ b/src/libguacd/socket-ssl.c
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "socket-ssl.h"
+
+#include <poll.h>
+#include <stdlib.h>
+
+#include <guacamole/error.h>
+#include <guacamole/socket.h>
+#include <openssl/ssl.h>
+
+static ssize_t __guac_socket_ssl_read_handler(guac_socket* socket,
+ void* buf, size_t count) {
+
+ /* Read from socket */
+ guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
+ int retval;
+
+ retval = SSL_read(data->ssl, buf, count);
+
+ /* Record errors in guac_error */
+ if (retval <= 0) {
+ guac_error = GUAC_STATUS_SEE_ERRNO;
+ guac_error_message = "Error reading data from secure socket";
+ }
+
+ return retval;
+
+}
+
+static ssize_t __guac_socket_ssl_write_handler(guac_socket* socket,
+ const void* buf, size_t count) {
+
+ /* Write data to socket */
+ guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
+ int retval;
+
+ retval = SSL_write(data->ssl, buf, count);
+
+ /* Record errors in guac_error */
+ if (retval <= 0) {
+ guac_error = GUAC_STATUS_SEE_ERRNO;
+ guac_error_message = "Error writing data to secure socket";
+ }
+
+ return retval;
+
+}
+
+static int __guac_socket_ssl_select_handler(guac_socket* socket, int usec_timeout) {
+
+ guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
+
+ int retval;
+
+ /* Initialize with single underlying file descriptor */
+ struct pollfd fds[1] = {{
+ .fd = data->fd,
+ .events = POLLIN,
+ .revents = 0,
+ }};
+
+ /* No timeout if usec_timeout is negative */
+ if (usec_timeout < 0)
+ retval = poll(fds, 1, -1);
+
+ /* Handle timeout if specified, rounding up to poll()'s granularity */
+ else
+ retval = poll(fds, 1, (usec_timeout + 999) / 1000);
+
+ /* Properly set guac_error */
+ if (retval < 0) {
+ guac_error = GUAC_STATUS_SEE_ERRNO;
+ guac_error_message = "Error while waiting for data on secure socket";
+ }
+
+ if (retval == 0) {
+ guac_error = GUAC_STATUS_TIMEOUT;
+ guac_error_message = "Timeout while waiting for data on secure socket";
+ }
+
+ return retval;
+
+}
+
+static int __guac_socket_ssl_free_handler(guac_socket* socket) {
+
+ /* Shutdown SSL */
+ guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data;
+ SSL_shutdown(data->ssl);
+
+ /* Close file descriptor */
+ close(data->fd);
+
+ free(data);
+ return 0;
+}
+
+guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) {
+
+ /* Allocate socket and associated data */
+ guac_socket* socket = guac_socket_alloc();
+ guac_socket_ssl_data* data = malloc(sizeof(guac_socket_ssl_data));
+
+ /* Init SSL */
+ data->context = context;
+ data->ssl = SSL_new(context);
+ SSL_set_fd(data->ssl, fd);
+
+ /* Accept SSL connection, handle errors */
+ if (SSL_accept(data->ssl) <= 0) {
+
+ guac_error = GUAC_STATUS_INTERNAL_ERROR;
+ guac_error_message = "SSL accept failed";
+
+ free(data);
+ guac_socket_free(socket);
+ return NULL;
+ }
+
+ /* Store file descriptor as socket data */
+ data->fd = fd;
+ socket->data = data;
+
+ /* Set read/write handlers */
+ socket->read_handler = __guac_socket_ssl_read_handler;
+ socket->write_handler = __guac_socket_ssl_write_handler;
+ socket->select_handler = __guac_socket_ssl_select_handler;
+ socket->free_handler = __guac_socket_ssl_free_handler;
+
+ return socket;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/socket-ssl.h
----------------------------------------------------------------------
diff --git a/src/libguacd/socket-ssl.h b/src/libguacd/socket-ssl.h
new file mode 100644
index 0000000..e1a341e
--- /dev/null
+++ b/src/libguacd/socket-ssl.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef __GUACD_SOCKET_SSL_H
+#define __GUACD_SOCKET_SSL_H
+
+#include "config.h"
+
+#include <guacamole/socket.h>
+#include <openssl/ssl.h>
+
+/**
+ * SSL socket-specific data.
+ */
+typedef struct guac_socket_ssl_data {
+
+ /**
+ * The file descriptor that SSL communication will take place
+ * over.
+ */
+ int fd;
+
+ /**
+ * The current SSL context.
+ */
+ SSL_CTX* context;
+
+ /**
+ * The SSL connection, created automatically via
+ * guac_socket_open_secure().
+ */
+ SSL* ssl;
+
+} guac_socket_ssl_data;
+
+/**
+ * Creates a new guac_socket which will use SSL for all communication. Freeing
+ * this guac_socket will automatically close the associated file descriptor.
+ *
+ * @param context
+ * The SSL_CTX structure describing the desired SSL configuration.
+ *
+ * @param fd
+ * The file descriptor to use for the SSL connection underlying the
+ * created guac_socket.
+ *
+ * @return
+ * A newly-allocated guac_socket which will transparently use SSL for
+ * all communication.
+ */
+guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/user.c
----------------------------------------------------------------------
diff --git a/src/libguacd/user.c b/src/libguacd/user.c
new file mode 100644
index 0000000..0a37147
--- /dev/null
+++ b/src/libguacd/user.c
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "log.h"
+#include "user.h"
+
+#include <guacamole/client.h>
+#include <guacamole/error.h>
+#include <guacamole/parser.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+#include <guacamole/user.h>
+
+#include <pthread.h>
+#include <stdlib.h>
+
+void* guacd_user_input_thread(void* data) {
+
+ guacd_user_input_thread_params* params = (guacd_user_input_thread_params*) data;
+ guac_user* user = params->user;
+ guac_parser* parser = params->parser;
+ guac_client* client = user->client;
+ guac_socket* socket = user->socket;
+
+ /* Guacamole user input loop */
+ while (client->state == GUAC_CLIENT_RUNNING && user->active) {
+
+ /* Read instruction, stop on error */
+ if (guac_parser_read(parser, socket, GUACD_USEC_TIMEOUT)) {
+
+ if (guac_error == GUAC_STATUS_TIMEOUT)
+ guac_user_abort(user, GUAC_PROTOCOL_STATUS_CLIENT_TIMEOUT, "User is not responding.");
+
+ else {
+ if (guac_error != GUAC_STATUS_CLOSED)
+ guacd_client_log_guac_error(client, GUAC_LOG_WARNING,
+ "Guacamole connection failure");
+ guac_user_stop(user);
+ }
+
+ return NULL;
+ }
+
+ /* Reset guac_error and guac_error_message (user/client handlers are not
+ * guaranteed to set these) */
+ guac_error = GUAC_STATUS_SUCCESS;
+ guac_error_message = NULL;
+
+ /* Call handler, stop on error */
+ if (guac_user_handle_instruction(user, parser->opcode, parser->argc, parser->argv) < 0) {
+
+ /* Log error */
+ guacd_client_log_guac_error(client, GUAC_LOG_WARNING,
+ "User connection aborted");
+
+ /* Log handler details */
+ guac_user_log(user, GUAC_LOG_DEBUG, "Failing instruction handler in user was \"%s\"", parser->opcode);
+
+ guac_user_stop(user);
+ return NULL;
+ }
+
+ }
+
+ return NULL;
+
+}
+
+int guacd_user_start(guac_parser* parser, guac_user* user) {
+
+ guacd_user_input_thread_params params = {
+ .parser = parser,
+ .user = user
+ };
+
+ pthread_t input_thread;
+
+ if (pthread_create(&input_thread, NULL, guacd_user_input_thread, (void*) ¶ms)) {
+ guac_user_log(user, GUAC_LOG_ERROR, "Unable to start input thread");
+ guac_user_stop(user);
+ return -1;
+ }
+
+ /* Wait for I/O threads */
+ pthread_join(input_thread, NULL);
+
+ /* Explicitly signal disconnect */
+ guac_protocol_send_disconnect(user->socket);
+ guac_socket_flush(user->socket);
+
+ /* Done */
+ return 0;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/d7a604c8/src/libguacd/user.h
----------------------------------------------------------------------
diff --git a/src/libguacd/user.h b/src/libguacd/user.h
new file mode 100644
index 0000000..65eef70
--- /dev/null
+++ b/src/libguacd/user.h
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef _GUACD_USER_H
+#define _GUACD_USER_H
+
+#include "config.h"
+
+#include <guacamole/parser.h>
+#include <guacamole/socket.h>
+#include <guacamole/user.h>
+
+/**
+ * The number of milliseconds to wait for messages in any phase before
+ * timing out and closing the connection with an error.
+ */
+#define GUACD_TIMEOUT 15000
+
+/**
+ * The number of microseconds to wait for messages in any phase before
+ * timing out and closing the conncetion with an error. This is always
+ * equal to GUACD_TIMEOUT * 1000.
+ */
+#define GUACD_USEC_TIMEOUT (GUACD_TIMEOUT*1000)
+
+/**
+ * The maximum number of concurrent connections to a single instance
+ * of guacd.
+ */
+#define GUACD_CLIENT_MAX_CONNECTIONS 65536
+
+/**
+ * Parameters required by the user input thread.
+ */
+typedef struct guacd_user_input_thread_params {
+
+ /**
+ * The parser which will be used throughout the user's session.
+ */
+ guac_parser* parser;
+
+ /**
+ * A reference to the connected user.
+ */
+ guac_user* user;
+
+} guacd_user_input_thread_params;
+
+/**
+ * Starts the input/output threads of a new user. This function will block
+ * until the user disconnects. If an error prevents the input/output threads
+ * from starting, guac_user_stop() will be invoked on the given user.
+ *
+ * @param parser
+ * The guac_parser to use to handle all input from the given user.
+ *
+ * @param user
+ * The user whose associated I/O transfer threads should be started.
+ *
+ * @return
+ * Zero if the I/O threads started successfully and user has disconnected,
+ * or non-zero if the I/O threads could not be started.
+ */
+int guacd_user_start(guac_parser* parser, guac_user* user);
+
+/**
+ * The thread which handles all user input, calling event handlers for received
+ * instructions.
+ *
+ * @param data
+ * A pointer to a guacd_user_input_thread_params structure describing the
+ * user whose input is being handled and the guac_parser with which to
+ * handle it.
+ *
+ * @return
+ * Always NULL.
+ */
+void* guacd_user_input_thread(void* data);
+
+#endif
+
[2/4] incubator-guacamole-server git commit: GUACAMOLE-175: Split
logging between guacd and libguacd.
Posted by jm...@apache.org.
GUACAMOLE-175: Split logging between guacd and libguacd.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/45adc635
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/45adc635
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/45adc635
Branch: refs/heads/master
Commit: 45adc6359729d5f10636dd25488080c04b0463ea
Parents: d7a604c
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Sep 10 19:29:57 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jan 24 15:44:55 2017 -0800
----------------------------------------------------------------------
src/guacd/Makefile.am | 2 +
src/guacd/connection.c | 4 +-
src/guacd/daemon.c | 2 +-
src/guacd/log.c | 143 ++++++++++++++++++++++++++++++++
src/guacd/log.h | 72 ++++++++++++++++
src/guacd/proc-map.c | 2 +-
src/guacd/proc-map.h | 2 +-
src/guacd/proc.c | 2 +-
src/libguacd/Makefile.am | 8 +-
src/libguacd/libguacd/log.h | 36 ++++++++
src/libguacd/libguacd/socket-ssl.h | 71 ++++++++++++++++
src/libguacd/libguacd/user.h | 98 ++++++++++++++++++++++
src/libguacd/log.c | 115 +------------------------
src/libguacd/log.h | 80 ------------------
src/libguacd/socket-ssl.c | 2 +-
src/libguacd/socket-ssl.h | 71 ----------------
src/libguacd/user.c | 4 +-
src/libguacd/user.h | 98 ----------------------
18 files changed, 436 insertions(+), 376 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/Makefile.am
----------------------------------------------------------------------
diff --git a/src/guacd/Makefile.am b/src/guacd/Makefile.am
index e25a101..b9433e8 100644
--- a/src/guacd/Makefile.am
+++ b/src/guacd/Makefile.am
@@ -30,6 +30,7 @@ noinst_HEADERS = \
conf-file.h \
conf-parse.h \
connection.h \
+ log.h \
move-fd.h \
proc.h \
proc-map.h
@@ -40,6 +41,7 @@ guacd_SOURCES = \
conf-parse.c \
connection.c \
daemon.c \
+ log.c \
move-fd.c \
proc.c \
proc-map.c
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/connection.c
----------------------------------------------------------------------
diff --git a/src/guacd/connection.c b/src/guacd/connection.c
index 3ad8eae..87efc5a 100644
--- a/src/guacd/connection.c
+++ b/src/guacd/connection.c
@@ -22,9 +22,9 @@
#include "connection.h"
#include "log.h"
#include "move-fd.h"
+#include "libguacd/user.h"
#include "proc.h"
#include "proc-map.h"
-#include "user.h"
#include <guacamole/client.h>
#include <guacamole/error.h>
@@ -36,7 +36,7 @@
#ifdef ENABLE_SSL
#include <openssl/ssl.h>
-#include "socket-ssl.h"
+#include "libguacd/socket-ssl.h"
#endif
#include <errno.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/daemon.c
----------------------------------------------------------------------
diff --git a/src/guacd/daemon.c b/src/guacd/daemon.c
index 7d978aa..840c68f 100644
--- a/src/guacd/daemon.c
+++ b/src/guacd/daemon.c
@@ -22,9 +22,9 @@
#include "connection.h"
#include "conf-args.h"
#include "conf-file.h"
+#include "libguacd/user.h"
#include "log.h"
#include "proc-map.h"
-#include "user.h"
#ifdef ENABLE_SSL
#include <openssl/ssl.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/log.c
----------------------------------------------------------------------
diff --git a/src/guacd/log.c b/src/guacd/log.c
new file mode 100644
index 0000000..121bb69
--- /dev/null
+++ b/src/guacd/log.c
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "log.h"
+
+#include <guacamole/client.h>
+#include <guacamole/error.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <unistd.h>
+
+int guacd_log_level = GUAC_LOG_INFO;
+
+void vguacd_log(guac_client_log_level level, const char* format,
+ va_list args) {
+
+ const char* priority_name;
+ int priority;
+
+ char message[2048];
+
+ /* Don't bother if the log level is too high */
+ if (level > guacd_log_level)
+ return;
+
+ /* Copy log message into buffer */
+ vsnprintf(message, sizeof(message), format, args);
+
+ /* Convert log level to syslog priority */
+ switch (level) {
+
+ /* Error log level */
+ case GUAC_LOG_ERROR:
+ priority = LOG_ERR;
+ priority_name = "ERROR";
+ break;
+
+ /* Warning log level */
+ case GUAC_LOG_WARNING:
+ priority = LOG_WARNING;
+ priority_name = "WARNING";
+ break;
+
+ /* Informational log level */
+ case GUAC_LOG_INFO:
+ priority = LOG_INFO;
+ priority_name = "INFO";
+ break;
+
+ /* Debug log level */
+ case GUAC_LOG_DEBUG:
+ priority = LOG_DEBUG;
+ priority_name = "DEBUG";
+ break;
+
+ /* Any unknown/undefined log level */
+ default:
+ priority = LOG_INFO;
+ priority_name = "UNKNOWN";
+ break;
+ }
+
+ /* Log to syslog */
+ syslog(priority, "%s", message);
+
+ /* Log to STDERR */
+ fprintf(stderr, GUACD_LOG_NAME "[%i]: %s:\t%s\n",
+ getpid(), priority_name, message);
+
+}
+
+void guacd_log(guac_client_log_level level, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ vguacd_log(level, format, args);
+ va_end(args);
+}
+
+void guacd_client_log(guac_client* client, guac_client_log_level level,
+ const char* format, va_list args) {
+ vguacd_log(level, format, args);
+}
+
+void guacd_log_guac_error(guac_client_log_level level, const char* message) {
+
+ if (guac_error != GUAC_STATUS_SUCCESS) {
+
+ /* If error message provided, include in log */
+ if (guac_error_message != NULL)
+ guacd_log(level, "%s: %s",
+ message,
+ guac_error_message);
+
+ /* Otherwise just log with standard status string */
+ else
+ guacd_log(level, "%s: %s",
+ message,
+ guac_status_string(guac_error));
+
+ }
+
+ /* Just log message if no status code */
+ else
+ guacd_log(level, "%s", message);
+
+}
+
+void guacd_log_handshake_failure() {
+
+ if (guac_error == GUAC_STATUS_CLOSED)
+ guacd_log(GUAC_LOG_INFO,
+ "Guacamole connection closed during handshake");
+ else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
+ guacd_log(GUAC_LOG_ERROR,
+ "Guacamole protocol violation. Perhaps the version of "
+ "guacamole-client is incompatible with this version of "
+ "guacd?");
+ else
+ guacd_log(GUAC_LOG_WARNING,
+ "Guacamole handshake failed: %s",
+ guac_status_string(guac_error));
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/log.h
----------------------------------------------------------------------
diff --git a/src/guacd/log.h b/src/guacd/log.h
new file mode 100644
index 0000000..58a8752
--- /dev/null
+++ b/src/guacd/log.h
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef __GUACD_LOG_H
+#define __GUACD_LOG_H
+
+#include "config.h"
+
+#include <guacamole/client.h>
+
+/**
+ * The maximum level at which to log messages. All other messages will be
+ * dropped.
+ */
+extern int guacd_log_level;
+
+/**
+ * The string to prepend to all log messages.
+ */
+#define GUACD_LOG_NAME "guacd"
+
+/**
+ * Writes a message to guacd's logs. This function takes a format and va_list,
+ * similar to vprintf.
+ */
+void vguacd_log(guac_client_log_level level, const char* format, va_list args);
+
+/**
+ * Writes a message to guacd's logs. This function accepts parameters
+ * identically to printf.
+ */
+void guacd_log(guac_client_log_level level, const char* format, ...);
+
+/**
+ * Writes a message using the logging facilities of the given client. This
+ * function accepts parameters identically to printf.
+ */
+void guacd_client_log(guac_client* client, guac_client_log_level level,
+ const char* format, va_list args);
+
+/**
+ * Prints an error message to guacd's logs, automatically including any
+ * information present in guac_error. This function accepts parameters
+ * identically to printf.
+ */
+void guacd_log_guac_error(guac_client_log_level level, const char* message);
+
+/**
+ * Logs a reasonable explanatory message regarding handshake failure based on
+ * the current value of guac_error.
+ */
+void guacd_log_handshake_failure();
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/proc-map.c
----------------------------------------------------------------------
diff --git a/src/guacd/proc-map.c b/src/guacd/proc-map.c
index c09c06a..bbe50b3 100644
--- a/src/guacd/proc-map.c
+++ b/src/guacd/proc-map.c
@@ -19,9 +19,9 @@
#include "config.h"
#include "common/list.h"
+#include "libguacd/user.h"
#include "proc.h"
#include "proc-map.h"
-#include "user.h"
#include <guacamole/client.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/proc-map.h
----------------------------------------------------------------------
diff --git a/src/guacd/proc-map.h b/src/guacd/proc-map.h
index 123449d..7313244 100644
--- a/src/guacd/proc-map.h
+++ b/src/guacd/proc-map.h
@@ -23,8 +23,8 @@
#include "config.h"
#include "common/list.h"
+#include "libguacd/user.h"
#include "proc.h"
-#include "user.h"
#include <guacamole/client.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/guacd/proc.c
----------------------------------------------------------------------
diff --git a/src/guacd/proc.c b/src/guacd/proc.c
index 5bf1e5c..f4d7f2a 100644
--- a/src/guacd/proc.c
+++ b/src/guacd/proc.c
@@ -19,11 +19,11 @@
#include "config.h"
+#include "libguacd/user.h"
#include "log.h"
#include "move-fd.h"
#include "proc.h"
#include "proc-map.h"
-#include "user.h"
#include <guacamole/client.h>
#include <guacamole/error.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/Makefile.am
----------------------------------------------------------------------
diff --git a/src/libguacd/Makefile.am b/src/libguacd/Makefile.am
index 9e20cec..23cab3b 100644
--- a/src/libguacd/Makefile.am
+++ b/src/libguacd/Makefile.am
@@ -21,9 +21,9 @@ AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libguacd.la
-noinst_HEADERS = \
- log.h \
- user.h
+noinst_HEADERS = \
+ libguacd/log.h \
+ libguacd/user.h
libguacd_la_SOURCES = \
log.c \
@@ -44,7 +44,7 @@ libguacd_la_LDFLAGS = \
# SSL support
if ENABLE_SSL
-noinst_HEADERS += socket-ssl.h
+noinst_HEADERS += libguacd/socket-ssl.h
libguacd_la_SOURCES += socket-ssl.c
endif
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/libguacd/log.h
----------------------------------------------------------------------
diff --git a/src/libguacd/libguacd/log.h b/src/libguacd/libguacd/log.h
new file mode 100644
index 0000000..2e65f5a
--- /dev/null
+++ b/src/libguacd/libguacd/log.h
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef LIBGUACD_LOG_H
+#define LIBGUACD_LOG_H
+
+#include "config.h"
+
+#include <guacamole/client.h>
+
+/**
+ * Prints an error message using the logging facilities of the given client,
+ * automatically including any information present in guac_error. This function
+ * accepts parameters identically to printf.
+ */
+void guacd_client_log_guac_error(guac_client* client,
+ guac_client_log_level level, const char* message);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/libguacd/socket-ssl.h
----------------------------------------------------------------------
diff --git a/src/libguacd/libguacd/socket-ssl.h b/src/libguacd/libguacd/socket-ssl.h
new file mode 100644
index 0000000..e1a341e
--- /dev/null
+++ b/src/libguacd/libguacd/socket-ssl.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef __GUACD_SOCKET_SSL_H
+#define __GUACD_SOCKET_SSL_H
+
+#include "config.h"
+
+#include <guacamole/socket.h>
+#include <openssl/ssl.h>
+
+/**
+ * SSL socket-specific data.
+ */
+typedef struct guac_socket_ssl_data {
+
+ /**
+ * The file descriptor that SSL communication will take place
+ * over.
+ */
+ int fd;
+
+ /**
+ * The current SSL context.
+ */
+ SSL_CTX* context;
+
+ /**
+ * The SSL connection, created automatically via
+ * guac_socket_open_secure().
+ */
+ SSL* ssl;
+
+} guac_socket_ssl_data;
+
+/**
+ * Creates a new guac_socket which will use SSL for all communication. Freeing
+ * this guac_socket will automatically close the associated file descriptor.
+ *
+ * @param context
+ * The SSL_CTX structure describing the desired SSL configuration.
+ *
+ * @param fd
+ * The file descriptor to use for the SSL connection underlying the
+ * created guac_socket.
+ *
+ * @return
+ * A newly-allocated guac_socket which will transparently use SSL for
+ * all communication.
+ */
+guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/libguacd/user.h
----------------------------------------------------------------------
diff --git a/src/libguacd/libguacd/user.h b/src/libguacd/libguacd/user.h
new file mode 100644
index 0000000..a872f14
--- /dev/null
+++ b/src/libguacd/libguacd/user.h
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef LIBGUACD_USER_H
+#define LIBGUACD_USER_H
+
+#include "config.h"
+
+#include <guacamole/parser.h>
+#include <guacamole/socket.h>
+#include <guacamole/user.h>
+
+/**
+ * The number of milliseconds to wait for messages in any phase before
+ * timing out and closing the connection with an error.
+ */
+#define GUACD_TIMEOUT 15000
+
+/**
+ * The number of microseconds to wait for messages in any phase before
+ * timing out and closing the conncetion with an error. This is always
+ * equal to GUACD_TIMEOUT * 1000.
+ */
+#define GUACD_USEC_TIMEOUT (GUACD_TIMEOUT*1000)
+
+/**
+ * The maximum number of concurrent connections to a single instance
+ * of guacd.
+ */
+#define GUACD_CLIENT_MAX_CONNECTIONS 65536
+
+/**
+ * Parameters required by the user input thread.
+ */
+typedef struct guacd_user_input_thread_params {
+
+ /**
+ * The parser which will be used throughout the user's session.
+ */
+ guac_parser* parser;
+
+ /**
+ * A reference to the connected user.
+ */
+ guac_user* user;
+
+} guacd_user_input_thread_params;
+
+/**
+ * Starts the input/output threads of a new user. This function will block
+ * until the user disconnects. If an error prevents the input/output threads
+ * from starting, guac_user_stop() will be invoked on the given user.
+ *
+ * @param parser
+ * The guac_parser to use to handle all input from the given user.
+ *
+ * @param user
+ * The user whose associated I/O transfer threads should be started.
+ *
+ * @return
+ * Zero if the I/O threads started successfully and user has disconnected,
+ * or non-zero if the I/O threads could not be started.
+ */
+int guacd_user_start(guac_parser* parser, guac_user* user);
+
+/**
+ * The thread which handles all user input, calling event handlers for received
+ * instructions.
+ *
+ * @param data
+ * A pointer to a guacd_user_input_thread_params structure describing the
+ * user whose input is being handled and the guac_parser with which to
+ * handle it.
+ *
+ * @return
+ * Always NULL.
+ */
+void* guacd_user_input_thread(void* data);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/log.c
----------------------------------------------------------------------
diff --git a/src/libguacd/log.c b/src/libguacd/log.c
index 229d2f9..26b24e4 100644
--- a/src/libguacd/log.c
+++ b/src/libguacd/log.c
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "log.h"
+#include "libguacd/log.h"
#include <guacamole/client.h>
#include <guacamole/error.h>
@@ -28,102 +28,6 @@
#include <syslog.h>
#include <unistd.h>
-int guacd_log_level = GUAC_LOG_INFO;
-
-void vguacd_log(guac_client_log_level level, const char* format,
- va_list args) {
-
- const char* priority_name;
- int priority;
-
- char message[2048];
-
- /* Don't bother if the log level is too high */
- if (level > guacd_log_level)
- return;
-
- /* Copy log message into buffer */
- vsnprintf(message, sizeof(message), format, args);
-
- /* Convert log level to syslog priority */
- switch (level) {
-
- /* Error log level */
- case GUAC_LOG_ERROR:
- priority = LOG_ERR;
- priority_name = "ERROR";
- break;
-
- /* Warning log level */
- case GUAC_LOG_WARNING:
- priority = LOG_WARNING;
- priority_name = "WARNING";
- break;
-
- /* Informational log level */
- case GUAC_LOG_INFO:
- priority = LOG_INFO;
- priority_name = "INFO";
- break;
-
- /* Debug log level */
- case GUAC_LOG_DEBUG:
- priority = LOG_DEBUG;
- priority_name = "DEBUG";
- break;
-
- /* Any unknown/undefined log level */
- default:
- priority = LOG_INFO;
- priority_name = "UNKNOWN";
- break;
- }
-
- /* Log to syslog */
- syslog(priority, "%s", message);
-
- /* Log to STDERR */
- fprintf(stderr, GUACD_LOG_NAME "[%i]: %s:\t%s\n",
- getpid(), priority_name, message);
-
-}
-
-void guacd_log(guac_client_log_level level, const char* format, ...) {
- va_list args;
- va_start(args, format);
- vguacd_log(level, format, args);
- va_end(args);
-}
-
-void guacd_client_log(guac_client* client, guac_client_log_level level,
- const char* format, va_list args) {
- vguacd_log(level, format, args);
-}
-
-void guacd_log_guac_error(guac_client_log_level level, const char* message) {
-
- if (guac_error != GUAC_STATUS_SUCCESS) {
-
- /* If error message provided, include in log */
- if (guac_error_message != NULL)
- guacd_log(level, "%s: %s",
- message,
- guac_error_message);
-
- /* Otherwise just log with standard status string */
- else
- guacd_log(level, "%s: %s",
- message,
- guac_status_string(guac_error));
-
- }
-
- /* Just log message if no status code */
- else
- guacd_log(level, "%s", message);
-
-}
-
void guacd_client_log_guac_error(guac_client* client,
guac_client_log_level level, const char* message) {
@@ -149,20 +53,3 @@ void guacd_client_log_guac_error(guac_client* client,
}
-void guacd_log_handshake_failure() {
-
- if (guac_error == GUAC_STATUS_CLOSED)
- guacd_log(GUAC_LOG_INFO,
- "Guacamole connection closed during handshake");
- else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
- guacd_log(GUAC_LOG_ERROR,
- "Guacamole protocol violation. Perhaps the version of "
- "guacamole-client is incompatible with this version of "
- "guacd?");
- else
- guacd_log(GUAC_LOG_WARNING,
- "Guacamole handshake failed: %s",
- guac_status_string(guac_error));
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/log.h
----------------------------------------------------------------------
diff --git a/src/libguacd/log.h b/src/libguacd/log.h
deleted file mode 100644
index 09fe152..0000000
--- a/src/libguacd/log.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-#ifndef __GUACD_LOG_H
-#define __GUACD_LOG_H
-
-#include "config.h"
-
-#include <guacamole/client.h>
-
-/**
- * The maximum level at which to log messages. All other messages will be
- * dropped.
- */
-extern int guacd_log_level;
-
-/**
- * The string to prepend to all log messages.
- */
-#define GUACD_LOG_NAME "guacd"
-
-/**
- * Writes a message to guacd's logs. This function takes a format and va_list,
- * similar to vprintf.
- */
-void vguacd_log(guac_client_log_level level, const char* format, va_list args);
-
-/**
- * Writes a message to guacd's logs. This function accepts parameters
- * identically to printf.
- */
-void guacd_log(guac_client_log_level level, const char* format, ...);
-
-/**
- * Writes a message using the logging facilities of the given client. This
- * function accepts parameters identically to printf.
- */
-void guacd_client_log(guac_client* client, guac_client_log_level level,
- const char* format, va_list args);
-
-/**
- * Prints an error message to guacd's logs, automatically including any
- * information present in guac_error. This function accepts parameters
- * identically to printf.
- */
-void guacd_log_guac_error(guac_client_log_level level, const char* message);
-
-/**
- * Prints an error message using the logging facilities of the given client,
- * automatically including any information present in guac_error. This function
- * accepts parameters identically to printf.
- */
-void guacd_client_log_guac_error(guac_client* client,
- guac_client_log_level level, const char* message);
-
-/**
- * Logs a reasonable explanatory message regarding handshake failure based on
- * the current value of guac_error.
- */
-void guacd_log_handshake_failure();
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/socket-ssl.c
----------------------------------------------------------------------
diff --git a/src/libguacd/socket-ssl.c b/src/libguacd/socket-ssl.c
index 4f19442..aa8664f 100644
--- a/src/libguacd/socket-ssl.c
+++ b/src/libguacd/socket-ssl.c
@@ -19,7 +19,7 @@
#include "config.h"
-#include "socket-ssl.h"
+#include "libguacd/socket-ssl.h"
#include <poll.h>
#include <stdlib.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/socket-ssl.h
----------------------------------------------------------------------
diff --git a/src/libguacd/socket-ssl.h b/src/libguacd/socket-ssl.h
deleted file mode 100644
index e1a341e..0000000
--- a/src/libguacd/socket-ssl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-#ifndef __GUACD_SOCKET_SSL_H
-#define __GUACD_SOCKET_SSL_H
-
-#include "config.h"
-
-#include <guacamole/socket.h>
-#include <openssl/ssl.h>
-
-/**
- * SSL socket-specific data.
- */
-typedef struct guac_socket_ssl_data {
-
- /**
- * The file descriptor that SSL communication will take place
- * over.
- */
- int fd;
-
- /**
- * The current SSL context.
- */
- SSL_CTX* context;
-
- /**
- * The SSL connection, created automatically via
- * guac_socket_open_secure().
- */
- SSL* ssl;
-
-} guac_socket_ssl_data;
-
-/**
- * Creates a new guac_socket which will use SSL for all communication. Freeing
- * this guac_socket will automatically close the associated file descriptor.
- *
- * @param context
- * The SSL_CTX structure describing the desired SSL configuration.
- *
- * @param fd
- * The file descriptor to use for the SSL connection underlying the
- * created guac_socket.
- *
- * @return
- * A newly-allocated guac_socket which will transparently use SSL for
- * all communication.
- */
-guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/user.c
----------------------------------------------------------------------
diff --git a/src/libguacd/user.c b/src/libguacd/user.c
index 0a37147..e9f73be 100644
--- a/src/libguacd/user.c
+++ b/src/libguacd/user.c
@@ -19,8 +19,8 @@
#include "config.h"
-#include "log.h"
-#include "user.h"
+#include "libguacd/log.h"
+#include "libguacd/user.h"
#include <guacamole/client.h>
#include <guacamole/error.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/45adc635/src/libguacd/user.h
----------------------------------------------------------------------
diff --git a/src/libguacd/user.h b/src/libguacd/user.h
deleted file mode 100644
index 65eef70..0000000
--- a/src/libguacd/user.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-#ifndef _GUACD_USER_H
-#define _GUACD_USER_H
-
-#include "config.h"
-
-#include <guacamole/parser.h>
-#include <guacamole/socket.h>
-#include <guacamole/user.h>
-
-/**
- * The number of milliseconds to wait for messages in any phase before
- * timing out and closing the connection with an error.
- */
-#define GUACD_TIMEOUT 15000
-
-/**
- * The number of microseconds to wait for messages in any phase before
- * timing out and closing the conncetion with an error. This is always
- * equal to GUACD_TIMEOUT * 1000.
- */
-#define GUACD_USEC_TIMEOUT (GUACD_TIMEOUT*1000)
-
-/**
- * The maximum number of concurrent connections to a single instance
- * of guacd.
- */
-#define GUACD_CLIENT_MAX_CONNECTIONS 65536
-
-/**
- * Parameters required by the user input thread.
- */
-typedef struct guacd_user_input_thread_params {
-
- /**
- * The parser which will be used throughout the user's session.
- */
- guac_parser* parser;
-
- /**
- * A reference to the connected user.
- */
- guac_user* user;
-
-} guacd_user_input_thread_params;
-
-/**
- * Starts the input/output threads of a new user. This function will block
- * until the user disconnects. If an error prevents the input/output threads
- * from starting, guac_user_stop() will be invoked on the given user.
- *
- * @param parser
- * The guac_parser to use to handle all input from the given user.
- *
- * @param user
- * The user whose associated I/O transfer threads should be started.
- *
- * @return
- * Zero if the I/O threads started successfully and user has disconnected,
- * or non-zero if the I/O threads could not be started.
- */
-int guacd_user_start(guac_parser* parser, guac_user* user);
-
-/**
- * The thread which handles all user input, calling event handlers for received
- * instructions.
- *
- * @param data
- * A pointer to a guacd_user_input_thread_params structure describing the
- * user whose input is being handled and the guac_parser with which to
- * handle it.
- *
- * @return
- * Always NULL.
- */
-void* guacd_user_input_thread(void* data);
-
-#endif
-
[4/4] incubator-guacamole-server git commit: GUACAMOLE-175: Merge
move of guacd core into library.
Posted by jm...@apache.org.
GUACAMOLE-175: Merge move of guacd core into library.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/5d2c9676
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/5d2c9676
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/5d2c9676
Branch: refs/heads/master
Commit: 5d2c9676f4681e49a95149ecb43176aba8a56528
Parents: 396eaa2 4c06d75
Author: James Muehlner <ja...@guac-dev.org>
Authored: Tue Jan 24 16:38:50 2017 -0800
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Tue Jan 24 16:38:50 2017 -0800
----------------------------------------------------------------------
Makefile.am | 8 +-
configure.ac | 5 +
src/guacd/Makefile.am | 18 +-
src/guacd/connection.c | 4 +-
src/guacd/daemon.c | 2 +-
src/guacd/log.c | 25 ---
src/guacd/log.h | 8 -
src/guacd/proc-map.c | 2 +-
src/guacd/proc-map.h | 2 +-
src/guacd/proc.c | 212 +--------------------
src/guacd/socket-ssl.c | 153 ---------------
src/guacd/socket-ssl.h | 71 -------
src/guacd/user.c | 113 -----------
src/guacd/user.h | 98 ----------
src/libguacd/Makefile.am | 50 +++++
src/libguacd/libguacd/log.h | 42 +++++
src/libguacd/libguacd/socket-ssl.h | 71 +++++++
src/libguacd/libguacd/user.h | 113 +++++++++++
src/libguacd/log.c | 72 +++++++
src/libguacd/socket-ssl.c | 153 +++++++++++++++
src/libguacd/user.c | 321 ++++++++++++++++++++++++++++++++
21 files changed, 844 insertions(+), 699 deletions(-)
----------------------------------------------------------------------
[3/4] incubator-guacamole-server git commit: GUACAMOLE-175: Move
guacd_handle_user() to libguacd.
Posted by jm...@apache.org.
GUACAMOLE-175: Move guacd_handle_user() to libguacd.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/4c06d755
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/4c06d755
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/4c06d755
Branch: refs/heads/master
Commit: 4c06d755f95bfacaa6f1b5f435b6a94ef2d8a608
Parents: 45adc63
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 11 13:18:27 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jan 24 15:44:59 2017 -0800
----------------------------------------------------------------------
src/guacd/proc.c | 210 --------------------------------------
src/libguacd/libguacd/log.h | 6 ++
src/libguacd/libguacd/user.h | 15 +++
src/libguacd/log.c | 17 +++
src/libguacd/user.c | 208 +++++++++++++++++++++++++++++++++++++
5 files changed, 246 insertions(+), 210 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4c06d755/src/guacd/proc.c
----------------------------------------------------------------------
diff --git a/src/guacd/proc.c b/src/guacd/proc.c
index f4d7f2a..74ba146 100644
--- a/src/guacd/proc.c
+++ b/src/guacd/proc.c
@@ -41,216 +41,6 @@
#include <sys/socket.h>
/**
- * Copies the given array of mimetypes (strings) into a newly-allocated NULL-
- * terminated array of strings. Both the array and the strings within the array
- * are newly-allocated and must be later freed via guacd_free_mimetypes().
- *
- * @param mimetypes
- * The array of mimetypes to copy.
- *
- * @param count
- * The number of mimetypes in the given array.
- *
- * @return
- * A newly-allocated, NULL-terminated array containing newly-allocated
- * copies of each of the mimetypes provided in the original mimetypes
- * array.
- */
-static char** guacd_copy_mimetypes(char** mimetypes, int count) {
-
- int i;
-
- /* Allocate sufficient space for NULL-terminated array of mimetypes */
- char** mimetypes_copy = malloc(sizeof(char*) * (count+1));
-
- /* Copy each provided mimetype */
- for (i = 0; i < count; i++)
- mimetypes_copy[i] = strdup(mimetypes[i]);
-
- /* Terminate with NULL */
- mimetypes_copy[count] = NULL;
-
- return mimetypes_copy;
-
-}
-
-/**
- * Frees the given array of mimetypes, including the space allocated to each
- * mimetype string within the array. The provided array of mimetypes MUST have
- * been allocated with guacd_copy_mimetypes().
- *
- * @param mimetypes
- * The NULL-terminated array of mimetypes to free. This array MUST have
- * been previously allocated with guacd_copy_mimetypes().
- */
-static void guacd_free_mimetypes(char** mimetypes) {
-
- char** current_mimetype = mimetypes;
-
- /* Free all strings within NULL-terminated mimetype array */
- while (*current_mimetype != NULL) {
- free(*current_mimetype);
- current_mimetype++;
- }
-
- /* Free the array itself, now that its contents have been freed */
- free(mimetypes);
-
-}
-
-/**
- * Handles the initial handshake of a user and all subsequent I/O. This
- * function blocks until the user disconnects.
- *
- * @param user
- * The user whose handshake and entire Guacamole protocol exchange should
- * be handled.
- *
- * @return
- * Zero if the user's Guacamole connection was successfully handled and
- * the user has disconnected, or non-zero if an error prevented the user's
- * connection from being handled properly.
- */
-static int guacd_handle_user(guac_user* user) {
-
- guac_socket* socket = user->socket;
- guac_client* client = user->client;
-
- /* Send args */
- if (guac_protocol_send_args(socket, client->args)
- || guac_socket_flush(socket)) {
-
- /* Log error */
- guacd_log_handshake_failure();
- guacd_log_guac_error(GUAC_LOG_DEBUG, "Error sending \"args\" to new user");
-
- return 1;
- }
-
- guac_parser* parser = guac_parser_alloc();
-
- /* Get optimal screen size */
- if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "size")) {
-
- /* Log error */
- guacd_log_handshake_failure();
- guacd_log_guac_error(GUAC_LOG_DEBUG, "Error reading \"size\"");
-
- guac_parser_free(parser);
- return 1;
- }
-
- /* Validate content of size instruction */
- if (parser->argc < 2) {
- guacd_log(GUAC_LOG_ERROR, "Received \"size\" instruction lacked required arguments.");
- guac_parser_free(parser);
- return 1;
- }
-
- /* Parse optimal screen dimensions from size instruction */
- user->info.optimal_width = atoi(parser->argv[0]);
- user->info.optimal_height = atoi(parser->argv[1]);
-
- /* If DPI given, set the client resolution */
- if (parser->argc >= 3)
- user->info.optimal_resolution = atoi(parser->argv[2]);
-
- /* Otherwise, use a safe default for rough backwards compatibility */
- else
- user->info.optimal_resolution = 96;
-
- /* Get supported audio formats */
- if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "audio")) {
-
- /* Log error */
- guacd_log_handshake_failure();
- guacd_log_guac_error(GUAC_LOG_DEBUG, "Error reading \"audio\"");
-
- guac_parser_free(parser);
- return 1;
- }
-
- /* Store audio mimetypes */
- char** audio_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
- user->info.audio_mimetypes = (const char**) audio_mimetypes;
-
- /* Get supported video formats */
- if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "video")) {
-
- /* Log error */
- guacd_log_handshake_failure();
- guacd_log_guac_error(GUAC_LOG_DEBUG, "Error reading \"video\"");
-
- guac_parser_free(parser);
- return 1;
- }
-
- /* Store video mimetypes */
- char** video_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
- user->info.video_mimetypes = (const char**) video_mimetypes;
-
- /* Get supported image formats */
- if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "image")) {
-
- /* Log error */
- guacd_log_handshake_failure();
- guacd_log_guac_error(GUAC_LOG_DEBUG, "Error reading \"image\"");
-
- guac_parser_free(parser);
- return 1;
- }
-
- /* Store image mimetypes */
- char** image_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
- user->info.image_mimetypes = (const char**) image_mimetypes;
-
- /* Get args from connect instruction */
- if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "connect")) {
-
- /* Log error */
- guacd_log_handshake_failure();
- guacd_log_guac_error(GUAC_LOG_DEBUG, "Error reading \"connect\"");
-
- guac_parser_free(parser);
- return 1;
- }
-
- /* Acknowledge connection availability */
- guac_protocol_send_ready(socket, client->connection_id);
- guac_socket_flush(socket);
-
- /* Attempt join */
- if (guac_client_add_user(client, user, parser->argc, parser->argv))
- guacd_log(GUAC_LOG_ERROR, "User \"%s\" could NOT join connection \"%s\"", user->user_id, client->connection_id);
-
- /* Begin user connection if join successful */
- else {
-
- guacd_log(GUAC_LOG_INFO, "User \"%s\" joined connection \"%s\" (%i users now present)",
- user->user_id, client->connection_id, client->connected_users);
-
- /* Handle user I/O, wait for connection to terminate */
- guacd_user_start(parser, user);
-
- /* Remove/free user */
- guac_client_remove_user(client, user);
- guacd_log(GUAC_LOG_INFO, "User \"%s\" disconnected (%i users remain)", user->user_id, client->connected_users);
-
- }
-
- /* Free mimetype lists */
- guacd_free_mimetypes(audio_mimetypes);
- guacd_free_mimetypes(video_mimetypes);
- guacd_free_mimetypes(image_mimetypes);
-
- guac_parser_free(parser);
-
- /* Successful disconnect */
- return 0;
-
-}
-
-/**
* Parameters for the user thread.
*/
typedef struct guacd_user_thread_params {
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4c06d755/src/libguacd/libguacd/log.h
----------------------------------------------------------------------
diff --git a/src/libguacd/libguacd/log.h b/src/libguacd/libguacd/log.h
index 2e65f5a..76509e3 100644
--- a/src/libguacd/libguacd/log.h
+++ b/src/libguacd/libguacd/log.h
@@ -32,5 +32,11 @@
void guacd_client_log_guac_error(guac_client* client,
guac_client_log_level level, const char* message);
+/**
+ * Logs a reasonable explanatory message regarding handshake failure based on
+ * the current value of guac_error.
+ */
+void guacd_client_log_handshake_failure(guac_client* client);
+
#endif
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4c06d755/src/libguacd/libguacd/user.h
----------------------------------------------------------------------
diff --git a/src/libguacd/libguacd/user.h b/src/libguacd/libguacd/user.h
index a872f14..cb2a8b3 100644
--- a/src/libguacd/libguacd/user.h
+++ b/src/libguacd/libguacd/user.h
@@ -81,6 +81,21 @@ typedef struct guacd_user_input_thread_params {
int guacd_user_start(guac_parser* parser, guac_user* user);
/**
+ * Handles the initial handshake of a user and all subsequent I/O. This
+ * function blocks until the user disconnects.
+ *
+ * @param user
+ * The user whose handshake and entire Guacamole protocol exchange should
+ * be handled.
+ *
+ * @return
+ * Zero if the user's Guacamole connection was successfully handled and
+ * the user has disconnected, or non-zero if an error prevented the user's
+ * connection from being handled properly.
+ */
+int guacd_handle_user(guac_user* user);
+
+/**
* The thread which handles all user input, calling event handlers for received
* instructions.
*
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4c06d755/src/libguacd/log.c
----------------------------------------------------------------------
diff --git a/src/libguacd/log.c b/src/libguacd/log.c
index 26b24e4..e746373 100644
--- a/src/libguacd/log.c
+++ b/src/libguacd/log.c
@@ -53,3 +53,20 @@ void guacd_client_log_guac_error(guac_client* client,
}
+void guacd_client_log_handshake_failure(guac_client* client) {
+
+ if (guac_error == GUAC_STATUS_CLOSED)
+ guac_client_log(client, GUAC_LOG_INFO,
+ "Guacamole connection closed during handshake");
+ else if (guac_error == GUAC_STATUS_PROTOCOL_ERROR)
+ guac_client_log(client, GUAC_LOG_ERROR,
+ "Guacamole protocol violation. Perhaps the version of "
+ "guacamole-client is incompatible with this version of "
+ "guacd?");
+ else
+ guac_client_log(client, GUAC_LOG_WARNING,
+ "Guacamole handshake failed: %s",
+ guac_status_string(guac_error));
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4c06d755/src/libguacd/user.c
----------------------------------------------------------------------
diff --git a/src/libguacd/user.c b/src/libguacd/user.c
index e9f73be..db39fce 100644
--- a/src/libguacd/user.c
+++ b/src/libguacd/user.c
@@ -31,6 +31,65 @@
#include <pthread.h>
#include <stdlib.h>
+#include <string.h>
+
+/**
+ * Copies the given array of mimetypes (strings) into a newly-allocated NULL-
+ * terminated array of strings. Both the array and the strings within the array
+ * are newly-allocated and must be later freed via guacd_free_mimetypes().
+ *
+ * @param mimetypes
+ * The array of mimetypes to copy.
+ *
+ * @param count
+ * The number of mimetypes in the given array.
+ *
+ * @return
+ * A newly-allocated, NULL-terminated array containing newly-allocated
+ * copies of each of the mimetypes provided in the original mimetypes
+ * array.
+ */
+static char** guacd_copy_mimetypes(char** mimetypes, int count) {
+
+ int i;
+
+ /* Allocate sufficient space for NULL-terminated array of mimetypes */
+ char** mimetypes_copy = malloc(sizeof(char*) * (count+1));
+
+ /* Copy each provided mimetype */
+ for (i = 0; i < count; i++)
+ mimetypes_copy[i] = strdup(mimetypes[i]);
+
+ /* Terminate with NULL */
+ mimetypes_copy[count] = NULL;
+
+ return mimetypes_copy;
+
+}
+
+/**
+ * Frees the given array of mimetypes, including the space allocated to each
+ * mimetype string within the array. The provided array of mimetypes MUST have
+ * been allocated with guacd_copy_mimetypes().
+ *
+ * @param mimetypes
+ * The NULL-terminated array of mimetypes to free. This array MUST have
+ * been previously allocated with guacd_copy_mimetypes().
+ */
+static void guacd_free_mimetypes(char** mimetypes) {
+
+ char** current_mimetype = mimetypes;
+
+ /* Free all strings within NULL-terminated mimetype array */
+ while (*current_mimetype != NULL) {
+ free(*current_mimetype);
+ current_mimetype++;
+ }
+
+ /* Free the array itself, now that its contents have been freed */
+ free(mimetypes);
+
+}
void* guacd_user_input_thread(void* data) {
@@ -111,3 +170,152 @@ int guacd_user_start(guac_parser* parser, guac_user* user) {
}
+int guacd_handle_user(guac_user* user) {
+
+ guac_socket* socket = user->socket;
+ guac_client* client = user->client;
+
+ /* Send args */
+ if (guac_protocol_send_args(socket, client->args)
+ || guac_socket_flush(socket)) {
+
+ /* Log error */
+ guacd_client_log_handshake_failure(client);
+ guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
+ "Error sending \"args\" to new user");
+
+ return 1;
+ }
+
+ guac_parser* parser = guac_parser_alloc();
+
+ /* Get optimal screen size */
+ if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "size")) {
+
+ /* Log error */
+ guacd_client_log_handshake_failure(client);
+ guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
+ "Error reading \"size\"");
+
+ guac_parser_free(parser);
+ return 1;
+ }
+
+ /* Validate content of size instruction */
+ if (parser->argc < 2) {
+ guac_client_log(client, GUAC_LOG_ERROR, "Received \"size\" "
+ "instruction lacked required arguments.");
+ guac_parser_free(parser);
+ return 1;
+ }
+
+ /* Parse optimal screen dimensions from size instruction */
+ user->info.optimal_width = atoi(parser->argv[0]);
+ user->info.optimal_height = atoi(parser->argv[1]);
+
+ /* If DPI given, set the client resolution */
+ if (parser->argc >= 3)
+ user->info.optimal_resolution = atoi(parser->argv[2]);
+
+ /* Otherwise, use a safe default for rough backwards compatibility */
+ else
+ user->info.optimal_resolution = 96;
+
+ /* Get supported audio formats */
+ if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "audio")) {
+
+ /* Log error */
+ guacd_client_log_handshake_failure(client);
+ guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
+ "Error reading \"audio\"");
+
+ guac_parser_free(parser);
+ return 1;
+ }
+
+ /* Store audio mimetypes */
+ char** audio_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
+ user->info.audio_mimetypes = (const char**) audio_mimetypes;
+
+ /* Get supported video formats */
+ if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "video")) {
+
+ /* Log error */
+ guacd_client_log_handshake_failure(client);
+ guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
+ "Error reading \"video\"");
+
+ guac_parser_free(parser);
+ return 1;
+ }
+
+ /* Store video mimetypes */
+ char** video_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
+ user->info.video_mimetypes = (const char**) video_mimetypes;
+
+ /* Get supported image formats */
+ if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "image")) {
+
+ /* Log error */
+ guacd_client_log_handshake_failure(client);
+ guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
+ "Error reading \"image\"");
+
+ guac_parser_free(parser);
+ return 1;
+ }
+
+ /* Store image mimetypes */
+ char** image_mimetypes = guacd_copy_mimetypes(parser->argv, parser->argc);
+ user->info.image_mimetypes = (const char**) image_mimetypes;
+
+ /* Get args from connect instruction */
+ if (guac_parser_expect(parser, socket, GUACD_USEC_TIMEOUT, "connect")) {
+
+ /* Log error */
+ guacd_client_log_handshake_failure(client);
+ guacd_client_log_guac_error(client, GUAC_LOG_DEBUG,
+ "Error reading \"connect\"");
+
+ guac_parser_free(parser);
+ return 1;
+ }
+
+ /* Acknowledge connection availability */
+ guac_protocol_send_ready(socket, client->connection_id);
+ guac_socket_flush(socket);
+
+ /* Attempt join */
+ if (guac_client_add_user(client, user, parser->argc, parser->argv))
+ guac_client_log(client, GUAC_LOG_ERROR, "User \"%s\" could NOT "
+ "join connection \"%s\"", user->user_id, client->connection_id);
+
+ /* Begin user connection if join successful */
+ else {
+
+ guac_client_log(client, GUAC_LOG_INFO, "User \"%s\" joined connection "
+ "\"%s\" (%i users now present)", user->user_id,
+ client->connection_id, client->connected_users);
+
+ /* Handle user I/O, wait for connection to terminate */
+ guacd_user_start(parser, user);
+
+ /* Remove/free user */
+ guac_client_remove_user(client, user);
+ guac_client_log(client, GUAC_LOG_INFO, "User \"%s\" disconnected (%i "
+ "users remain)", user->user_id, client->connected_users);
+
+ }
+
+ /* Free mimetype lists */
+ guacd_free_mimetypes(audio_mimetypes);
+ guacd_free_mimetypes(video_mimetypes);
+ guacd_free_mimetypes(image_mimetypes);
+
+ guac_parser_free(parser);
+
+ /* Successful disconnect */
+ return 0;
+
+}
+