mirror of
https://github.com/clearml/dropbear
synced 2025-01-31 10:57:01 +00:00
7cdad3c200
remote hostkey verification though. --HG-- extra : convert_revision : 8635abe49e499e16d44a8ee79d474dc35257e9cc
186 lines
4.1 KiB
C
186 lines
4.1 KiB
C
#include "includes.h"
|
|
#include "session.h"
|
|
#include "auth.h"
|
|
#include "dbutil.h"
|
|
#include "buffer.h"
|
|
#include "ssh.h"
|
|
#include "packet.h"
|
|
#include "runopts.h"
|
|
|
|
|
|
void cli_authinitialise() {
|
|
|
|
memset(&ses.authstate, 0, sizeof(ses.authstate));
|
|
}
|
|
|
|
|
|
/* Send a "none" auth request to get available methods */
|
|
void cli_auth_getmethods() {
|
|
|
|
TRACE(("enter cli_auth_getmethods"));
|
|
|
|
CHECKCLEARTOWRITE();
|
|
|
|
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
|
|
buf_putstring(ses.writepayload, cli_opts.username,
|
|
strlen(cli_opts.username));
|
|
buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION,
|
|
SSH_SERVICE_CONNECTION_LEN);
|
|
buf_putstring(ses.writepayload, "none", 4); /* 'none' method */
|
|
|
|
encrypt_packet();
|
|
TRACE(("leave cli_auth_getmethods"));
|
|
|
|
}
|
|
|
|
void recv_msg_userauth_banner() {
|
|
|
|
unsigned char* banner = NULL;
|
|
unsigned int bannerlen;
|
|
unsigned int i, linecount;
|
|
|
|
TRACE(("enter recv_msg_userauth_banner"));
|
|
if (ses.authstate.authdone) {
|
|
TRACE(("leave recv_msg_userauth_banner: banner after auth done"));
|
|
return;
|
|
}
|
|
|
|
banner = buf_getstring(ses.payload, &bannerlen);
|
|
buf_eatstring(ses.payload); /* The language string */
|
|
|
|
if (bannerlen > MAX_BANNER_SIZE) {
|
|
TRACE(("recv_msg_userauth_banner: bannerlen too long: %d", bannerlen));
|
|
goto out;
|
|
}
|
|
|
|
cleantext(banner);
|
|
|
|
/* Limit to 25 lines */
|
|
linecount = 1;
|
|
for (i = 0; i < bannerlen; i++) {
|
|
if (banner[i] == '\n') {
|
|
if (linecount >= MAX_BANNER_LINES) {
|
|
banner[i] = '\0';
|
|
break;
|
|
}
|
|
linecount++;
|
|
}
|
|
}
|
|
|
|
printf("%s\n", banner);
|
|
|
|
out:
|
|
m_free(banner);
|
|
TRACE(("leave recv_msg_userauth_banner"));
|
|
}
|
|
|
|
|
|
void recv_msg_userauth_failure() {
|
|
|
|
unsigned char * methods = NULL;
|
|
unsigned char * tok = NULL;
|
|
unsigned int methlen = 0;
|
|
unsigned int partial = 0;
|
|
unsigned int i = 0;
|
|
|
|
TRACE(("<- MSG_USERAUTH_FAILURE"));
|
|
TRACE(("enter recv_msg_userauth_failure"));
|
|
|
|
if (cli_ses.state != USERAUTH_REQ_SENT) {
|
|
/* Perhaps we should be more fatal? */
|
|
TRACE(("But we didn't send a userauth request!!!!!!"));
|
|
return;
|
|
}
|
|
|
|
#ifdef DROPBEAR_PUBKEY_AUTH
|
|
/* If it was a pubkey auth request, we should cross that key
|
|
* off the list. */
|
|
if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) {
|
|
cli_pubkeyfail();
|
|
}
|
|
#endif
|
|
|
|
methods = buf_getstring(ses.payload, &methlen);
|
|
|
|
partial = buf_getbyte(ses.payload);
|
|
|
|
if (partial) {
|
|
dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required");
|
|
} else {
|
|
ses.authstate.failcount++;
|
|
}
|
|
|
|
TRACE(("Methods (len %d): '%s'", methlen, methods));
|
|
|
|
ses.authstate.authdone=0;
|
|
ses.authstate.authtypes=0;
|
|
|
|
/* Split with nulls rather than commas */
|
|
for (i = 0; i < methlen; i++) {
|
|
if (methods[i] == ',') {
|
|
methods[i] = '\0';
|
|
}
|
|
}
|
|
|
|
tok = methods; /* tok stores the next method we'll compare */
|
|
for (i = 0; i <= methlen; i++) {
|
|
if (methods[i] == '\0') {
|
|
TRACE(("auth method '%s'", tok));
|
|
#ifdef DROPBEAR_PUBKEY_AUTH
|
|
if (strncmp(AUTH_METHOD_PUBKEY, tok,
|
|
AUTH_METHOD_PUBKEY_LEN) == 0) {
|
|
ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
|
|
}
|
|
#endif
|
|
#ifdef DROPBEAR_PASSWORD_AUTH
|
|
if (strncmp(AUTH_METHOD_PASSWORD, tok,
|
|
AUTH_METHOD_PASSWORD_LEN) == 0) {
|
|
ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
|
|
}
|
|
#endif
|
|
tok = &methods[i+1]; /* Must make sure we don't use it after the
|
|
last loop, since it'll point to something
|
|
undefined */
|
|
}
|
|
}
|
|
|
|
cli_ses.state = USERAUTH_FAIL_RCVD;
|
|
|
|
TRACE(("leave recv_msg_userauth_failure"));
|
|
}
|
|
|
|
void recv_msg_userauth_success() {
|
|
TRACE(("received msg_userauth_success"));
|
|
ses.authstate.authdone = 1;
|
|
cli_ses.state = USERAUTH_SUCCESS_RCVD;
|
|
}
|
|
|
|
void cli_auth_try() {
|
|
|
|
TRACE(("enter cli_auth_try"));
|
|
int finished = 0;
|
|
|
|
CHECKCLEARTOWRITE();
|
|
|
|
/* XXX We hardcode that we try a pubkey first */
|
|
#ifdef DROPBEAR_PUBKEY_AUTH
|
|
if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) {
|
|
finished = cli_auth_pubkey();
|
|
cli_ses.lastauthtype = AUTH_TYPE_PUBKEY;
|
|
}
|
|
#endif
|
|
|
|
#ifdef DROPBEAR_PASSWORD_AUTH
|
|
if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) {
|
|
finished = cli_auth_password();
|
|
cli_ses.lastauthtype = AUTH_TYPE_PASSWORD;
|
|
}
|
|
#endif
|
|
|
|
if (!finished) {
|
|
dropbear_exit("No auth methods could be used.");
|
|
}
|
|
|
|
TRACE(("leave cli_auth_try"));
|
|
}
|