GUACAMOLE-337: Move SSL socket into libguac.
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/f311c23f Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/f311c23f Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/f311c23f Branch: refs/heads/master Commit: f311c23ffa4f8a015ddfe55866a27204d389075d Parents: 78dbf64 Author: Michael Jumper <[email protected]> Authored: Mon Jun 12 14:06:47 2017 -0700 Committer: Michael Jumper <[email protected]> Committed: Sat Jul 1 18:50:03 2017 -0700 ---------------------------------------------------------------------- src/guacd/connection.c | 2 +- src/libguac/Makefile.am | 6 ++ src/libguac/guacamole/socket-ssl.h | 69 ++++++++++++++ src/libguac/socket-ssl.c | 160 ++++++++++++++++++++++++++++++++ src/libguacd/Makefile.am | 9 +- src/libguacd/libguacd/socket-ssl.h | 69 -------------- src/libguacd/socket-ssl.c | 160 -------------------------------- 7 files changed, 237 insertions(+), 238 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/f311c23f/src/guacd/connection.c ---------------------------------------------------------------------- diff --git a/src/guacd/connection.c b/src/guacd/connection.c index 87efc5a..6c517bf 100644 --- a/src/guacd/connection.c +++ b/src/guacd/connection.c @@ -36,7 +36,7 @@ #ifdef ENABLE_SSL #include <openssl/ssl.h> -#include "libguacd/socket-ssl.h" +#include <guacamole/socket-ssl.h> #endif #include <errno.h> http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/f311c23f/src/libguac/Makefile.am ---------------------------------------------------------------------- diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am index 4590e9f..0bfa409 100644 --- a/src/libguac/Makefile.am +++ b/src/libguac/Makefile.am @@ -99,6 +99,11 @@ libguac_la_SOURCES += encode-webp.c noinst_HEADERS += encode-webp.h endif +# SSL support +if ENABLE_SSL +libguac_la_SOURCES += socket-ssl.c +libguacinc_HEADERS += guacamole/socket-ssl.h +endif libguac_la_CFLAGS = \ -Werror -Wall -pedantic -Iguacamole @@ -109,6 +114,7 @@ libguac_la_LDFLAGS = \ @JPEG_LIBS@ \ @PNG_LIBS@ \ @PTHREAD_LIBS@ \ + @SSL_LIBS@ \ @UUID_LIBS@ \ @VORBIS_LIBS@ \ @WEBP_LIBS@ http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/f311c23f/src/libguac/guacamole/socket-ssl.h ---------------------------------------------------------------------- diff --git a/src/libguac/guacamole/socket-ssl.h b/src/libguac/guacamole/socket-ssl.h new file mode 100644 index 0000000..715db5b --- /dev/null +++ b/src/libguac/guacamole/socket-ssl.h @@ -0,0 +1,69 @@ +/* + * 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 <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/f311c23f/src/libguac/socket-ssl.c ---------------------------------------------------------------------- diff --git a/src/libguac/socket-ssl.c b/src/libguac/socket-ssl.c new file mode 100644 index 0000000..f8f3f87 --- /dev/null +++ b/src/libguac/socket-ssl.c @@ -0,0 +1,160 @@ +/* + * 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 "error.h" +#include "socket-ssl.h" +#include "socket.h" + +#include <poll.h> +#include <stdlib.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"; + } + + else 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); + SSL_free(data->ssl); + + /* Close file descriptor */ + close(data->fd); + + free(data); + return 0; +} + +guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) { + + /* Create new SSL structure */ + SSL* ssl = SSL_new(context); + if (ssl == NULL) + return NULL; + + /* 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; + SSL_set_fd(data->ssl, fd); + + /* Accept SSL connection, handle errors */ + if (SSL_accept(ssl) <= 0) { + + guac_error = GUAC_STATUS_INTERNAL_ERROR; + guac_error_message = "SSL accept failed"; + + free(data); + guac_socket_free(socket); + SSL_free(ssl); + 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/f311c23f/src/libguacd/Makefile.am ---------------------------------------------------------------------- diff --git a/src/libguacd/Makefile.am b/src/libguacd/Makefile.am index 35eeaf9..c0373f1 100644 --- a/src/libguacd/Makefile.am +++ b/src/libguacd/Makefile.am @@ -43,12 +43,5 @@ libguacd_la_LIBADD = \ libguacd_la_LDFLAGS = \ -version-info 0:0:0 \ -no-undefined \ - @PTHREAD_LIBS@ \ - @SSL_LIBS@ - -# SSL support -if ENABLE_SSL -libguacdinc_HEADERS += libguacd/socket-ssl.h -libguacd_la_SOURCES += socket-ssl.c -endif + @PTHREAD_LIBS@ http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/f311c23f/src/libguacd/libguacd/socket-ssl.h ---------------------------------------------------------------------- diff --git a/src/libguacd/libguacd/socket-ssl.h b/src/libguacd/libguacd/socket-ssl.h deleted file mode 100644 index 715db5b..0000000 --- a/src/libguacd/libguacd/socket-ssl.h +++ /dev/null @@ -1,69 +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 <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/f311c23f/src/libguacd/socket-ssl.c ---------------------------------------------------------------------- diff --git a/src/libguacd/socket-ssl.c b/src/libguacd/socket-ssl.c deleted file mode 100644 index cfd2f66..0000000 --- a/src/libguacd/socket-ssl.c +++ /dev/null @@ -1,160 +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 "libguacd/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); - SSL_free(data->ssl); - - /* Close file descriptor */ - close(data->fd); - - free(data); - return 0; -} - -guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) { - - /* Create new SSL structure */ - SSL* ssl = SSL_new(context); - if (ssl == NULL) - return NULL; - - /* 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; - SSL_set_fd(data->ssl, fd); - - /* Accept SSL connection, handle errors */ - if (SSL_accept(ssl) <= 0) { - - guac_error = GUAC_STATUS_INTERNAL_ERROR; - guac_error_message = "SSL accept failed"; - - free(data); - guac_socket_free(socket); - SSL_free(ssl); - 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; - -} -
