Depois de configurar o PAM para esperar algum tempo especificado antes que um novo prompt de login seja exibido após uma tentativa de login malsucedida, eu queria testar esse comportamento usando um programa simples que tentaria se conectar ao servidor remoto e mediria o tempo entre os prompts de login serem exibidos:
#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);
}
No entanto, o código acima retorna a seguinte saída:
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.
Surpreendentemente, o status da sessão sugere que a conexão foi bem-sucedida, além disso, Authentication succeeded with incorrect password.
diz que o programa conseguiu se conectar ao servidor. Isso não é verdade, pois nunca troquei chaves com o servidor. Além disso, não há nenhum usuário no servidor que corresponda a qualquer nome de usuário possível que a conexão possa usar.
Por favor, ajude a descobrir o que está acontecendo aqui: como fazer com que o programa receba o status correto da sessão SSH (tempo limite de conexão ou conexão recusada, como normalmente acontece ao acessar o servidor pelo console).
Não vejo o que há de surpreendente nisso. A conexão em nível de rede com o daemon do servidor ssh foi bem-sucedida. Provavelmente o canal seguro também foi estabelecido com sucesso. Isso não tem nada a ver com autenticação do usuário.
"Autenticação bem-sucedida com senha incorreta" é o diagnóstico do seu próprio programa, e você argumenta que seu programa está errado sobre isso. Leia os documentos
ssh_userauth_password()
com atenção. Observe bem que cinco códigos de retorno diferentes estão documentados, dos quais apenas um indica sucesso. Seu programa relata sucesso (sem senha) para quatro deles, o que será uma caracterização incorreta para três deles.Você parece querer isso: