diff --git a/src/protocols/ssh/client.c b/src/protocols/ssh/client.c index 77af109e..ebbd2003 100644 --- a/src/protocols/ssh/client.c +++ b/src/protocols/ssh/client.c @@ -35,7 +35,6 @@ #include #include -#include #include #include @@ -132,7 +131,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) { client_data->term_channel = NULL; if (argc != SSH_ARGS_COUNT) { - guac_client_log_error(client, "Wrong number of arguments"); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Wrong number of arguments"); return -1; } @@ -182,8 +181,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) { /* Fail if terminal init failed */ if (client_data->term == NULL) { - guac_error = GUAC_STATUS_BAD_STATE; - guac_error_message = "Terminal initialization failed"; + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Terminal initialization failed"); return -1; } @@ -212,7 +210,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) { /* Start client thread */ if (pthread_create(&(client_data->client_thread), NULL, ssh_client_thread, (void*) client)) { - guac_client_log_error(client, "Unable to SSH client thread"); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start SSH client thread"); return -1; } diff --git a/src/protocols/ssh/display.c b/src/protocols/ssh/display.c index 5304df96..27f40e6c 100644 --- a/src/protocols/ssh/display.c +++ b/src/protocols/ssh/display.c @@ -358,13 +358,14 @@ guac_terminal_display* guac_terminal_display_alloc(guac_client* client, font = pango_font_map_load_font(font_map, context, display->font_desc); if (font == NULL) { - guac_client_log_error(display->client, "Unable to get font \"%s\"", font_name); + guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to get font \"%s\"", font_name); return NULL; } metrics = pango_font_get_metrics(font, NULL); if (metrics == NULL) { - guac_client_log_error(display->client, "Unable to get font metrics for font \"%s\"", font_name); + guac_client_abort(display->client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, + "Unable to get font metrics for font \"%s\"", font_name); return NULL; } diff --git a/src/protocols/ssh/guac_handlers.c b/src/protocols/ssh/guac_handlers.c index 65dc1c7b..10452764 100644 --- a/src/protocols/ssh/guac_handlers.c +++ b/src/protocols/ssh/guac_handlers.c @@ -37,13 +37,11 @@ #include #include #include -#include #include #include int ssh_guac_client_handle_messages(guac_client* client) { - guac_socket* socket = client->socket; ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; char buffer[8192]; @@ -72,16 +70,16 @@ int ssh_guac_client_handle_messages(guac_client* client) { /* Read data, write to terminal */ if ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) { - if (guac_terminal_write(client_data->term, buffer, bytes_read)) + if (guac_terminal_write(client_data->term, buffer, bytes_read)) { + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error writing data"); return 1; + } } /* Notify on error */ if (bytes_read < 0) { - guac_protocol_send_error(socket, "Error reading data.", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); - guac_socket_flush(socket); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error reading data"); return 1; } @@ -96,8 +94,7 @@ int ssh_guac_client_handle_messages(guac_client* client) { } else if (ret_val < 0) { - guac_error_message = "Error waiting for pipe"; - guac_error = GUAC_STATUS_SEE_ERRNO; + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error waiting for data"); return 1; } diff --git a/src/protocols/ssh/sftp.c b/src/protocols/ssh/sftp.c index d9682923..ca70be87 100644 --- a/src/protocols/ssh/sftp.c +++ b/src/protocols/ssh/sftp.c @@ -74,8 +74,7 @@ int guac_sftp_file_handler(guac_client* client, guac_stream* stream, /* Ensure filename is a valid filename and not a path */ if (!__ssh_guac_valid_filename(filename)) { - guac_protocol_send_ack(client->socket, stream, - "SFTP: Illegal filename", + guac_protocol_send_ack(client->socket, stream, "SFTP: Illegal filename", GUAC_PROTOCOL_STATUS_CLIENT_BAD_REQUEST); guac_socket_flush(client->socket); return 0; @@ -103,8 +102,7 @@ int guac_sftp_file_handler(guac_client* client, guac_stream* stream, /* If path + filename exceeds max length, abort */ if (i == GUAC_SFTP_MAX_PATH) { - guac_protocol_send_ack(client->socket, stream, "SFTP: Name too long", - GUAC_PROTOCOL_STATUS_CLIENT_BAD_REQUEST); + guac_protocol_send_ack(client->socket, stream, "SFTP: Name too long", GUAC_PROTOCOL_STATUS_CLIENT_OVERRUN); guac_socket_flush(client->socket); return 0; } @@ -119,15 +117,13 @@ int guac_sftp_file_handler(guac_client* client, guac_stream* stream, /* Inform of status */ if (file != NULL) { - guac_protocol_send_ack(client->socket, stream, "SFTP: File opened", - GUAC_PROTOCOL_STATUS_SUCCESS); + guac_protocol_send_ack(client->socket, stream, "SFTP: File opened", GUAC_PROTOCOL_STATUS_SUCCESS); guac_socket_flush(client->socket); } else { guac_client_log_error(client, "Unable to open file \"%s\": %s", fullpath, libssh2_sftp_last_error(client_data->sftp_session)); - guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); + guac_protocol_send_ack(client->socket, stream, "SFTP: Open failed", GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND); guac_socket_flush(client->socket); } @@ -146,8 +142,7 @@ int guac_sftp_blob_handler(guac_client* client, guac_stream* stream, /* Attempt write */ if (libssh2_sftp_write(file, data, length) == length) { - guac_protocol_send_ack(client->socket, stream, "SFTP: OK", - GUAC_PROTOCOL_STATUS_SUCCESS); + guac_protocol_send_ack(client->socket, stream, "SFTP: OK", GUAC_PROTOCOL_STATUS_SUCCESS); guac_socket_flush(client->socket); } @@ -155,8 +150,7 @@ int guac_sftp_blob_handler(guac_client* client, guac_stream* stream, else { guac_client_log_error(client, "Unable to write to file: %s", libssh2_sftp_last_error(client_data->sftp_session)); - guac_protocol_send_ack(client->socket, stream, "SFTP: Write failed", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); + guac_protocol_send_ack(client->socket, stream, "SFTP: Write failed", GUAC_PROTOCOL_STATUS_SERVER_ERROR); guac_socket_flush(client->socket); } @@ -171,14 +165,12 @@ int guac_sftp_end_handler(guac_client* client, guac_stream* stream) { /* Attempt to close file */ if (libssh2_sftp_close(file) == 0) { - guac_protocol_send_ack(client->socket, stream, "SFTP: OK", - GUAC_PROTOCOL_STATUS_SUCCESS); + guac_protocol_send_ack(client->socket, stream, "SFTP: OK", GUAC_PROTOCOL_STATUS_SUCCESS); guac_socket_flush(client->socket); } else { guac_client_log_error(client, "Unable to close file"); - guac_protocol_send_ack(client->socket, stream, "SFTP: Close failed", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); + guac_protocol_send_ack(client->socket, stream, "SFTP: Close failed", GUAC_PROTOCOL_STATUS_SERVER_ERROR); guac_socket_flush(client->socket); } diff --git a/src/protocols/ssh/ssh_client.c b/src/protocols/ssh/ssh_client.c index e6a5c612..cbf058c0 100644 --- a/src/protocols/ssh/ssh_client.c +++ b/src/protocols/ssh/ssh_client.c @@ -168,9 +168,7 @@ static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, /* Get addresses connection */ if ((retval = getaddrinfo(client_data->hostname, client_data->port, &hints, &addresses))) { - - guac_client_log_error(client, - "Error parsing given address or port: %s", + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error parsing given address or port: %s", gai_strerror(retval)); return NULL; @@ -188,8 +186,7 @@ static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, connected_address, sizeof(connected_address), connected_port, sizeof(connected_port), NI_NUMERICHOST | NI_NUMERICSERV))) - guac_client_log_error(client, "Unable to resolve host: %s", - gai_strerror(retval)); + guac_client_log_info(client, "Unable to resolve host: %s", gai_strerror(retval)); /* Connect */ if (connect(fd, current_address->ai_addr, @@ -215,7 +212,7 @@ static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, /* If unable to connect to anything, fail */ if (current_address == NULL) { - guac_client_log_error(client, "Unable to connect to any addresses."); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to connect to any addresses."); return NULL; } @@ -226,13 +223,13 @@ static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, LIBSSH2_SESSION* session = libssh2_session_init_ex(NULL, NULL, NULL, client); if (session == NULL) { - guac_client_log_error(client, "Session allocation failed"); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Session allocation failed."); return NULL; } /* Perform handshake */ if (libssh2_session_handshake(session, fd)) { - guac_client_log_error(client, "SSH handshake failed"); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "SSH handshake failed."); return NULL; } @@ -250,7 +247,7 @@ static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, else { char* error_message; libssh2_session_last_error(session, &error_message, NULL, 0); - guac_client_log_error(client, + guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, "Public key authentication failed: %s", error_message); return NULL; } @@ -264,7 +261,7 @@ static LIBSSH2_SESSION* __guac_ssh_create_session(guac_client* client, else { char* error_message; libssh2_session_last_error(session, &error_message, NULL, 0); - guac_client_log_error(client, + guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, "Password authentication failed: %s", error_message); return NULL; } @@ -290,9 +287,8 @@ void* ssh_client_thread(void* data) { libssh2_init(0); /* Get username */ - if (client_data->username[0] == 0 && - prompt(client, "Login as: ", client_data->username, sizeof(client_data->username), true) == NULL) - return NULL; + if (client_data->username[0] == 0) + prompt(client, "Login as: ", client_data->username, sizeof(client_data->username), true); /* Send new name */ snprintf(name, sizeof(name)-1, "%s@%s", client_data->username, client_data->hostname); @@ -309,12 +305,9 @@ void* ssh_client_thread(void* data) { if (client_data->key == NULL) { /* Prompt for passphrase if missing */ - if (client_data->key_passphrase[0] == 0) { - if (prompt(client, "Key passphrase: ", - client_data->key_passphrase, - sizeof(client_data->key_passphrase), false) == NULL) - return NULL; - } + if (client_data->key_passphrase[0] == 0) + prompt(client, "Key passphrase: ", client_data->key_passphrase, + sizeof(client_data->key_passphrase), false); /* Import key with passphrase */ client_data->key = ssh_key_alloc(client_data->key_base64, @@ -335,11 +328,8 @@ void* ssh_client_thread(void* data) { } /* end if key given */ /* Otherwise, get password if not provided */ - else if (client_data->password[0] == 0) { - if (prompt(client, "Password: ", client_data->password, - sizeof(client_data->password), false) == NULL) - return NULL; - } + else if (client_data->password[0] == 0) + prompt(client, "Password: ", client_data->password, sizeof(client_data->password), false); /* Clear screen */ guac_terminal_write_all(stdout_fd, "\x1B[H\x1B[J", 6); @@ -347,19 +337,14 @@ void* ssh_client_thread(void* data) { /* Open SSH session */ client_data->session = __guac_ssh_create_session(client, &socket_fd); if (client_data->session == NULL) { - guac_protocol_send_error(socket, "Unable to create SSH session.", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); - guac_socket_flush(socket); + /* Already aborted within __guac_ssh_create_session() */ return NULL; } /* Open channel for terminal */ - client_data->term_channel = - libssh2_channel_open_session(client_data->session); + client_data->term_channel = libssh2_channel_open_session(client_data->session); if (client_data->term_channel == NULL) { - guac_protocol_send_error(socket, "Unable to open channel.", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); - guac_socket_flush(socket); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to open terminal channel."); return NULL; } @@ -385,14 +370,15 @@ void* ssh_client_thread(void* data) { /* Create SSH session specific for SFTP */ guac_client_log_info(client, "Reconnecting for SFTP..."); client_data->sftp_ssh_session = __guac_ssh_create_session(client, NULL); + if (client_data->sftp_ssh_session == NULL) { + /* Already aborted within __guac_ssh_create_session() */ + return NULL; + } /* Request SFTP */ - client_data->sftp_session = - libssh2_sftp_init(client_data->sftp_ssh_session); + client_data->sftp_session = libssh2_sftp_init(client_data->sftp_ssh_session); if (client_data->sftp_session == NULL) { - guac_protocol_send_error(socket, "Unable to start SFTP session..", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); - guac_socket_flush(socket); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to start SFTP session."); return NULL; } @@ -407,21 +393,15 @@ void* ssh_client_thread(void* data) { } /* Request PTY */ - if (libssh2_channel_request_pty_ex(client_data->term_channel, - "linux", sizeof("linux")-1, NULL, 0, - client_data->term->term_width, client_data->term->term_height, - 0, 0)) { - guac_protocol_send_error(socket, "Unable to allocate PTY for channel.", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); - guac_socket_flush(socket); + if (libssh2_channel_request_pty_ex(client_data->term_channel, "linux", sizeof("linux")-1, NULL, 0, + client_data->term->term_width, client_data->term->term_height, 0, 0)) { + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY."); return NULL; } /* Request shell */ if (libssh2_channel_shell(client_data->term_channel)) { - guac_protocol_send_error(socket, "Unable to associate shell with PTY.", - GUAC_PROTOCOL_STATUS_SERVER_ERROR); - guac_socket_flush(socket); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY."); return NULL; } @@ -430,7 +410,7 @@ void* ssh_client_thread(void* data) { /* Start input thread */ if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) { - guac_client_log_error(client, "Unable to start SSH input thread"); + guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread"); return NULL; }