Reinstate SSH client.
This commit is contained in:
parent
0f978393a6
commit
80825072fe
@ -50,6 +50,10 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct ssh_guac_client_data {
|
typedef struct ssh_guac_client_data {
|
||||||
|
|
||||||
|
char hostname[1024];
|
||||||
|
char username[1024];
|
||||||
|
char password[1024];
|
||||||
|
|
||||||
pthread_t client_thread;
|
pthread_t client_thread;
|
||||||
|
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
|
@ -75,6 +75,16 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
client_data->mod_ctrl = 0;
|
client_data->mod_ctrl = 0;
|
||||||
client_data->clipboard_data = NULL;
|
client_data->clipboard_data = NULL;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
guac_client_log_error(client, "Wrong number of arguments");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read parameters */
|
||||||
|
strcpy(client_data->hostname, argv[0]);
|
||||||
|
strcpy(client_data->username, argv[1]);
|
||||||
|
strcpy(client_data->password, argv[2]);
|
||||||
|
|
||||||
/* Set up I-bar pointer */
|
/* Set up I-bar pointer */
|
||||||
client_data->ibar_cursor = guac_ssh_create_ibar(client);
|
client_data->ibar_cursor = guac_ssh_create_ibar(client);
|
||||||
|
|
||||||
|
@ -38,8 +38,11 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/protocol.h>
|
||||||
|
#include <guacamole/socket.h>
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
@ -126,24 +129,138 @@ static char* prompt(guac_client* client, const char* title, char* str, int size,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ssh_client_thread(void* data) {
|
void* ssh_input_thread(void* data) {
|
||||||
|
|
||||||
guac_client* client = (guac_client*) data;
|
guac_client* client = (guac_client*) data;
|
||||||
|
ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
|
||||||
|
|
||||||
char username[1024];
|
char buffer[8192];
|
||||||
char password[1024];
|
int bytes_read;
|
||||||
|
|
||||||
/* Get username */
|
int stdin_fd = client_data->stdin_pipe_fd[0];
|
||||||
if (prompt(client, "Login as: ", username, sizeof(username), true) == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Get password */
|
/* Write all data read */
|
||||||
if (prompt(client, "Password: ", password, sizeof(password), false) == NULL)
|
while ((bytes_read = read(stdin_fd, buffer, sizeof(buffer))) > 0)
|
||||||
return NULL;
|
channel_write(client_data->term_channel, buffer, bytes_read);
|
||||||
|
|
||||||
guac_client_log_info((guac_client*) data, "got: %s ... %s", username, password);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* ssh_client_thread(void* data) {
|
||||||
|
|
||||||
|
guac_client* client = (guac_client*) data;
|
||||||
|
ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
|
||||||
|
|
||||||
|
guac_socket* socket = client->socket;
|
||||||
|
char buffer[8192];
|
||||||
|
int bytes_read;
|
||||||
|
|
||||||
|
int stdout_fd = client_data->stdout_pipe_fd[1];
|
||||||
|
|
||||||
|
pthread_t input_thread;
|
||||||
|
|
||||||
|
/* Get username */
|
||||||
|
if (client_data->username[0] == 0 &&
|
||||||
|
prompt(client, "Login as: ", client_data->username, sizeof(client_data->username), true) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Get password */
|
||||||
|
if (client_data->password[0] == 0 &&
|
||||||
|
prompt(client, "Password: ", client_data->password, sizeof(client_data->password), false) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Open SSH session */
|
||||||
|
client_data->session = ssh_new();
|
||||||
|
if (client_data->session == NULL) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to create SSH session.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set session options */
|
||||||
|
ssh_options_set(client_data->session, SSH_OPTIONS_HOST, client_data->hostname);
|
||||||
|
ssh_options_set(client_data->session, SSH_OPTIONS_USER, client_data->username);
|
||||||
|
|
||||||
|
/* Connect */
|
||||||
|
if (ssh_connect(client_data->session) != SSH_OK) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to connect via SSH.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Authenticate */
|
||||||
|
if (ssh_userauth_password(client_data->session, NULL, client_data->password) != SSH_AUTH_SUCCESS) {
|
||||||
|
guac_protocol_send_error(socket, "SSH auth failed.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open channel for terminal */
|
||||||
|
client_data->term_channel = channel_new(client_data->session);
|
||||||
|
if (client_data->term_channel == NULL) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to open channel.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open session for channel */
|
||||||
|
if (channel_open_session(client_data->term_channel) != SSH_OK) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to open channel session.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request PTY */
|
||||||
|
if (channel_request_pty(client_data->term_channel) != SSH_OK) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to allocate PTY for channel.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request PTY size */
|
||||||
|
if (channel_change_pty_size(client_data->term_channel,
|
||||||
|
client_data->term->term_width, client_data->term->term_height) != SSH_OK) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to change PTY size.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request shell */
|
||||||
|
if (channel_request_shell(client_data->term_channel) != SSH_OK) {
|
||||||
|
guac_protocol_send_error(socket, "Unable to associate shell with PTY.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logged in */
|
||||||
|
guac_client_log_info(client, "SSH connection successful.");
|
||||||
|
|
||||||
|
/* 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");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* While data available, write to terminal */
|
||||||
|
while (channel_is_open(client_data->term_channel)
|
||||||
|
&& !channel_is_eof(client_data->term_channel)
|
||||||
|
&& (bytes_read = channel_read(client_data->term_channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||||
|
|
||||||
|
if (__write_all(stdout_fd, buffer, bytes_read) <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify on error */
|
||||||
|
if (bytes_read < 0) {
|
||||||
|
guac_protocol_send_error(socket, "Error reading data.");
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
guac_client_log_info(client, "SSH connection ended.");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user