Github user mike-jumper commented on a diff in the pull request:

    https://github.com/apache/guacamole-server/pull/187#discussion_r219631546
  
    --- 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 --
    
    Yep. There is a situation where `username_regex` will still not be NULL, 
yet the password regex will match.
    
    While no telnet server has support for sending the password as a dedicated 
authentication phase, some telnet servers have support for sending the username 
directly. This is accomplished through sending an environment variable called 
`USER`:
    
    
https://github.com/apache/guacamole-server/blob/332e187813595fc2e769f3e29c0582b7ec726ea1/src/protocols/telnet/telnet.c#L222-L229
    
    As this isn't guaranteed, the heuristics for recognizing username/password 
prompts have to be somewhat forgiving. It's possible that there will be a 
username prompt followed by a password prompt, and it's possible that there 
will be only a password prompt.


---

Reply via email to