Github user necouchman commented on a diff in the pull request:
https://github.com/apache/guacamole-server/pull/187#discussion_r217206655
--- Diff: src/protocols/telnet/telnet.c ---
@@ -82,57 +83,178 @@ static int __guac_telnet_write_all(int fd, const char*
buffer, int size) {
}
/**
- * Searches for a line matching the stored password regex, appending the
given
- * buffer to the internal pattern matching buffer. The internal pattern
match
- * buffer is cleared whenever a newline is read. Returns TRUE if a match
is found and the
- * value is sent.
+ * Matches the given line against the given regex, returning true and
sending
+ * the given value if a match is found. An enter keypress is automatically
+ * sent after the value is sent.
+ *
+ * @param client
+ * The guac_client associated with the telnet session.
+ *
+ * @param regex
+ * The regex to search for within the given line buffer.
+ *
+ * @param value
+ * The string value to send through STDIN of the telnet session if a
+ * match is found, or NULL if no value should be sent.
+ *
+ * @param line_buffer
+ * The line of character data to test.
+ *
+ * @return
+ * true if a match is found, false otherwise.
*/
-static bool __guac_telnet_regex_search(guac_client* client, regex_t*
regex, char* value, const char* buffer, int size) {
+static bool guac_telnet_regex_exec(guac_client* client, regex_t* regex,
+ const char* value, const char* line_buffer) {
- static char line_buffer[1024] = {0};
- static int length = 0;
+ guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
+
+ /* Send value upon match */
+ if (regexec(regex, line_buffer, 0, NULL, 0) == 0) {
+
+ /* Send value */
+ if (value != NULL) {
+ guac_terminal_send_string(telnet_client->term, value);
+ guac_terminal_send_string(telnet_client->term, "\x0D");
+ }
+
+ /* Stop searching for prompt */
+ return true;
+
+ }
+
+ return false;
+
+}
+
+/**
+ * Matches the given line against the various stored regexes, automatically
+ * sending the configured username, password, or reporting login
+ * success/failure depending on context. If no search is in progress,
either
+ * because no regexes have been defined or because all applicable searches
have
+ * completed, this function has no effect.
+ *
+ * @param client
+ * The guac_client associated with the telnet session.
+ *
+ * @param line_buffer
+ * The line of character data to test.
+ */
+static void guac_telnet_search_line(guac_client* client, const char*
line_buffer) {
guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
+ guac_telnet_settings* settings = telnet_client->settings;
+
+ /* Continue search for username prompt */
+ if (settings->username_regex != NULL) {
+ if (guac_telnet_regex_exec(client, settings->username_regex,
+ settings->username, line_buffer)) {
+ guac_client_log(client, GUAC_LOG_DEBUG, "Username sent");
+ guac_telnet_regex_free(&settings->username_regex);
+ }
+ }
+
+ /* Continue search for password prompt */
+ if (settings->password_regex != NULL) {
+ if (guac_telnet_regex_exec(client, settings->password_regex,
+ settings->password, line_buffer)) {
- int i;
- const char* current;
+ guac_client_log(client, GUAC_LOG_DEBUG, "Password sent");
- /* Ensure line buffer contains only the most recent line */
- current = buffer;
- for (i = 0; i < size; i++) {
+ /* Do not continue searching for username/password once
password is sent */
+ guac_telnet_regex_free(&settings->username_regex);
--- End diff --
I'm guessing I'm just missing something, here, but what's the purpose of
freeing the `username_regex` pointer here? Isn't it going to have already been
processed by the block above, which checks for its presence? Or is there some
situation where it would fail the `if (settings->username_regex != null)` but
still actually contain something?
---