This is an automated email from the ASF dual-hosted git repository. mjumper pushed a commit to branch patch in repository https://gitbox.apache.org/repos/asf/guacamole-server.git
commit 97558a8c7a11b3d2fcf6c8ba978c6dd75df15bc7 Merge: de072881 da3ca38e Author: Mike Jumper <[email protected]> AuthorDate: Sat Jan 11 01:41:11 2025 -0800 GUACAMOLE-2012: Merge addition of AES GCM to preferred FIPS ciphers. src/common-ssh/ssh.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --cc src/common-ssh/ssh.c index 37bd9d70,1751d901..582c3ebc --- a/src/common-ssh/ssh.c +++ b/src/common-ssh/ssh.c @@@ -412,15 -406,139 +415,68 @@@ static int guac_common_ssh_authenticate } + /** + * Verifies if given algorithms are supported by libssh2. + * Writes log messages if an algorithm is not supported or + * could not get the list of supported algorithms from libssh2. + * + * @param client + * The Guacamole client that is using SSH. + * + * @param session + * The session associated with the user to be authenticated. + * + * @param method_type + * One of the libssh2 Method Type constants for libssh2_session_method_pref(). + * + * @param algs + * A string with preferred list of algorithms, for example FIPS_COMPLIANT_CIPHERS. + * + */ + static void check_if_algs_are_supported(guac_client* client, LIBSSH2_SESSION* session, + int method_type, const char* algs) { + + /* Request the list of supported algorithms/cyphers from libssh2. */ + const char** supported_algs; + int supported_algs_count = + libssh2_session_supported_algs(session, method_type, &supported_algs); + + if (supported_algs_count > 0) { + char** preferred_algs = guac_split(algs, ','); + for (int i = 0; preferred_algs[i]; i++) { + bool found = false; + /* Check if the algorithm is found in the libssh2 supported list. */ + for (int j = 0; j < supported_algs_count; j++) { + if (strcmp(preferred_algs[i], supported_algs[j]) == 0) { + found = true; + break; + } + } + if (!found) { + guac_client_log(client, GUAC_LOG_WARNING, + "Preferred algorithm/cipher '%s' is not supported by libssh2", preferred_algs[i]); + } + } + guac_mem_free(preferred_algs); + /* should free if supported_algs_count is a positive number. */ + libssh2_free(session, supported_algs); + } + else { + guac_client_log(client, GUAC_LOG_WARNING, + "libssh2 reports that no ciphers/algorithms are supported. This may be a bug in libssh2. " + "If the SSH connection fails, it may not be possible to log the cause here."); + } + } + guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client, const char* hostname, const char* port, guac_common_ssh_user* user, - int keepalive, const char* host_key, + int timeout, int keepalive, const char* host_key, guac_ssh_credential_handler* credential_handler) { - int retval; - - int fd; - struct addrinfo* addresses; - struct addrinfo* current_address; - - char connected_address[1024]; - char connected_port[64]; - - struct addrinfo hints = { - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - .ai_protocol = IPPROTO_TCP - }; - - /* Get addresses connection */ - if ((retval = getaddrinfo(hostname, port, &hints, &addresses))) { + int fd = guac_tcp_connect(hostname, port, timeout); + if (fd < 0) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, - "Error parsing given address or port: %s", - gai_strerror(retval)); - return NULL; - } - - /* Attempt connection to each address until success */ - current_address = addresses; - while (current_address != NULL) { - - /* Resolve hostname */ - if ((retval = getnameinfo(current_address->ai_addr, - current_address->ai_addrlen, - connected_address, sizeof(connected_address), - connected_port, sizeof(connected_port), - NI_NUMERICHOST | NI_NUMERICSERV))) - guac_client_log(client, GUAC_LOG_DEBUG, - "Unable to resolve host: %s", gai_strerror(retval)); - - /* Get socket */ - fd = socket(current_address->ai_family, SOCK_STREAM, 0); - if (fd < 0) { - guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, - "Unable to create socket: %s", strerror(errno)); - freeaddrinfo(addresses); - return NULL; - } - - /* Connect */ - if (connect(fd, current_address->ai_addr, - current_address->ai_addrlen) == 0) { - - guac_client_log(client, GUAC_LOG_DEBUG, - "Successfully connected to host %s, port %s", - connected_address, connected_port); - - /* Done if successful connect */ - break; - - } - - /* Otherwise log information regarding bind failure */ - guac_client_log(client, GUAC_LOG_DEBUG, "Unable to connect to " - "host %s, port %s: %s", - connected_address, connected_port, strerror(errno)); - - close(fd); - current_address = current_address->ai_next; - - } - - /* Free addrinfo */ - freeaddrinfo(addresses); - - /* If unable to connect to anything, fail */ - if (current_address == NULL) { - guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_NOT_FOUND, - "Unable to connect to any addresses."); + "Failed to open TCP connection to %s on %s.", hostname, port); return NULL; }
