clibssh

SSH Session giving unexpected status


After configuring PAM to wait some specified time before new login prompt gets displayed after a failed login attempt, I wanted to test this behavior using a simple program that would try to connect to the remote server and measure the time between login prompts are displayed:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <libssh/libssh.h>

#define BILLION 1000000000.0

int main(void) {
    struct timespec start, finish;

    ssh_session session;
    int rc;
    int session_status;
    const char *server_banner;
    session = ssh_new();

    const char *host = "10.11.12.13";
    const char *username = "baduser";
    const char *password = "badpass";

    ssh_options_set(session, SSH_OPTIONS_HOST, host);
    ssh_options_set(session, SSH_OPTIONS_USER, username);

    clock_gettime(CLOCK_REALTIME, &start);
    rc = ssh_connect(session);
    session_status = ssh_get_status(session);
    printf("Session status: %d\n", session_status);
    server_banner = ssh_get_serverbanner(session);
    printf("Server banner: %s\n", server_banner);

    if (rc != SSH_OK) {
        fprintf(stderr, "Error connecting to %s: %s\n", host, ssh_get_error(session));
        ssh_free(session);
        exit(-1);
    }

    printf("Return Code is: %d\n", rc);

    if (ssh_userauth_password(session, NULL, password) != SSH_AUTH_ERROR) {
        fprintf(stderr, "Authentication succeeded with incorrect password.\n");
    }
    else {
        fprintf(stderr, "Authentication failed with incorrect password.\n");
    }

    clock_gettime(CLOCK_REALTIME, &finish);

    ssh_disconnect(session);
    ssh_free(session);

    double time_spent = (finish.tv_sec - start.tv_sec) + (finish.tv_nsec - start.tv_nsec) / BILLION;
    printf("Elapsed time: %.4f seconds.\n", time_spent);

    return (0);
}

However, the code above returns the following output:

Session status: 0
Server banner: SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.8
Return Code is: 0
Authentication succeeded with incorrect password.
Elapsed time: 2.2801 seconds.

Surprisingly, the session status suggests that the connection was succesful, moreover, the Authentication succeeded with incorrect password. says the program was able to connect with the server. This is not true, because I've never exchanged keys with the server. Also, there's no user on the server that would match any possible username the connection could use.

Please help to find out what is happening here: how to get the program to receive correct status of the SSH session (connection timeout, or connection refused, as it normally happens when accessing the server from console).


Solution

  • Surprisingly, the session status suggests that the connection was succesful,

    I don't see what's surprising about that. The network-level connection to the ssh server daemon was successful. Probably the secure channel has successfully been established as well. That has nothing to do with user authentication.

    moreover, the Authentication succeeded with incorrect password. says the program was able to connect with the server. This is not true, because I've never exchanged keys with the server. Also, there's no user on the server that would match any possible username the connection could use.

    "Authentication succeeded with incorrect password" is your own program's diagnosis, and you make a good case for your program being wrong about that. Do read the docs of ssh_userauth_password() carefully. Note well that five different return codes are documented, only one of which indicates success. Your program reports success (without a password) for four of those, which will be an incorrect characterization for three of them.

    You appear to want this, instead:

        if (ssh_userauth_password(session, NULL, password) == SSH_AUTH_SUCCESS) {
            fprintf(stderr, "Authentication succeeded with incorrect password.\n");
        }