/* send formatted data with \r and \n translation in addition to IAC IAC */ int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va) { static const char CRLF[] = { '\r', '\n' }; static const char CRNUL[] = { '\r', '\0' }; char buffer[1024]; char *output = buffer; int rs, i, l; /* format */ va_list va2; va_copy(va2, va); rs = vsnprintf(buffer, sizeof(buffer), fmt, va); if (rs >= sizeof(buffer)) { output = (char*)malloc(rs + 1); if (output == 0) { _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); return -1; } rs = vsnprintf(output, rs + 1, fmt, va2); } va_end(va2); va_end(va); /* send */ for (l = i = 0; i != rs; ++i) { /* special characters */ if (output[i] == (char)TELNET_IAC || output[i] == '\r' || output[i] == '\n') { /* dump prior portion of text */ if (i != l) _send(telnet, output + l, i - l); l = i + 1; /* IAC -> IAC IAC */ if (output[i] == (char)TELNET_IAC) telnet_iac(telnet, TELNET_IAC); /* automatic translation of \r -> CRNUL */ else if (output[i] == '\r') _send(telnet, CRNUL, 2); /* automatic translation of \n -> CRLF */ else if (output[i] == '\n') _send(telnet, CRLF, 2); } } /* send whatever portion of output is left */ if (i != l) { _send(telnet, output + l, i - l); } /* free allocated memory, if any */ if (output != buffer) { free(output); } return rs; }
int guac_telnet_user_key_handler(guac_user* user, int keysym, int pressed) { guac_client* client = user->client; guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; guac_telnet_settings* settings = telnet_client->settings; guac_terminal* term = telnet_client->term; /* Skip if terminal not yet ready */ if (term == NULL) return 0; /* Stop searching for password */ if (settings->password_regex != NULL) { guac_client_log(client, GUAC_LOG_DEBUG, "Stopping password prompt search due to user input."); regfree(settings->password_regex); free(settings->password_regex); settings->password_regex = NULL; } /* Stop searching for username */ if (settings->username_regex != NULL) { guac_client_log(client, GUAC_LOG_DEBUG, "Stopping username prompt search due to user input."); regfree(settings->username_regex); free(settings->username_regex); settings->username_regex = NULL; } /* Intercept and handle Pause / Break / Ctrl+0 as "IAC BRK" */ if (pressed && ( keysym == 0xFF13 /* Pause */ || keysym == 0xFF6B /* Break */ || (term->mod_ctrl && keysym == '0') /* Ctrl + 0 */ )) { /* Send IAC BRK */ telnet_iac(telnet_client->telnet, TELNET_BREAK); return 0; } /* Send key */ guac_terminal_send_key(term, keysym, pressed); return 0; }
/* send formatted data with \r and \n translation in addition to IAC IAC */ int telnet_printf(telnet_t *telnet, const char *fmt, ...) { static const char CRLF[] = { '\r', '\n' }; static const char CRNUL[] = { '\r', '\0' }; char buffer[4096]; va_list va; int rs, i, l; /* format */ va_start(va, fmt); rs = vsnprintf(buffer, sizeof(buffer), fmt, va); va_end(va); /* send */ for (l = i = 0; i != rs; ++i) { /* special characters */ if (buffer[i] == (char)TELNET_IAC || buffer[i] == '\r' || buffer[i] == '\n') { /* dump prior portion of text */ if (i != l) _send(telnet, buffer + l, i - l); l = i + 1; /* IAC -> IAC IAC */ if (buffer[i] == (char)TELNET_IAC) telnet_iac(telnet, TELNET_IAC); /* automatic translation of \r -> CRNUL */ else if (buffer[i] == '\r') _send(telnet, CRNUL, 2); /* automatic translation of \n -> CRLF */ else if (buffer[i] == '\n') _send(telnet, CRLF, 2); } } /* send whatever portion of buffer is left */ if (i != l) { _send(telnet, buffer + l, i - l); } return rs; }
/* send non-command data (escapes IAC bytes) */ void telnet_send(telnet_t *telnet, const char *buffer, size_t size) { size_t i, l; for (l = i = 0; i != size; ++i) { /* dump prior portion of text, send escaped bytes */ if (buffer[i] == (char)TELNET_IAC) { /* dump prior text if any */ if (i != l) { _send(telnet, buffer + l, i - l); } l = i + 1; /* send escape */ telnet_iac(telnet, TELNET_IAC); } } /* send whatever portion of buffer is left */ if (i != l) { _send(telnet, buffer + l, i - l); } }