Commit 00a43489 authored by Lefebvre, Jordan's avatar Lefebvre, Jordan
Browse files

Implementing interactive keyboard authentication with multiple prompts.

parent 7edeedfc
...@@ -107,6 +107,8 @@ SessionController::SessionController(QObject* parent) ...@@ -107,6 +107,8 @@ SessionController::SessionController(QObject* parent)
&SessionWorker::authenticate); &SessionWorker::authenticate);
QObject::connect(this, &SessionController::authenticateWithPasswordRequested, QObject::connect(this, &SessionController::authenticateWithPasswordRequested,
p->worker, &SessionWorker::authenticateWithPassword); p->worker, &SessionWorker::authenticateWithPassword);
QObject::connect(this, &SessionController::authenticatePromptsRequested,
p->worker, &SessionWorker::authenticatePrompts);
QObject::connect(this, &SessionController::requestExecRequested, p->worker, QObject::connect(this, &SessionController::requestExecRequested, p->worker,
&SessionWorker::requestExec); &SessionWorker::requestExec);
} }
...@@ -153,6 +155,11 @@ void SessionController::authenticateWithPassword(QString pswd) ...@@ -153,6 +155,11 @@ void SessionController::authenticateWithPassword(QString pswd)
emit authenticateWithPasswordRequested(pswd); emit authenticateWithPasswordRequested(pswd);
} }
void SessionController::authenticatePrompts(QStringList responses)
{
emit authenticatePromptsRequested(responses);
}
void SessionController::requestExec(QString command) void SessionController::requestExec(QString command)
{ {
emit requestExecRequested(command); emit requestExecRequested(command);
......
...@@ -78,6 +78,8 @@ class RSM_PUBLIC SessionController : public QObject ...@@ -78,6 +78,8 @@ class RSM_PUBLIC SessionController : public QObject
*/ */
void authenticateWithPassword(QString pswd); void authenticateWithPassword(QString pswd);
void authenticatePrompts(QStringList responses);
/** /**
* Requests remote execution of command * Requests remote execution of command
* @param command - QString command to execute * @param command - QString command to execute
...@@ -229,6 +231,8 @@ class RSM_PUBLIC SessionController : public QObject ...@@ -229,6 +231,8 @@ class RSM_PUBLIC SessionController : public QObject
*/ */
void authenticateWithPasswordRequested(QString pswd); void authenticateWithPasswordRequested(QString pswd);
void authenticatePromptsRequested(QStringList responses);
/** /**
* Requests remote execution of command * Requests remote execution of command
* @param command - QString command to execute * @param command - QString command to execute
......
...@@ -40,6 +40,25 @@ class SessionWorkerImpl ...@@ -40,6 +40,25 @@ class SessionWorkerImpl
} }
}; };
void SessionWorker::processPrompts()
{
QString instruction = ssh_userauth_kbdint_getname(p->session);
QString name = ssh_userauth_kbdint_getinstruction(p->session);
int num_prompts = ssh_userauth_kbdint_getnprompts(p->session);
// build list of prompts
QStringList prompts;
char echo;
for (int i = 0; i < num_prompts; ++i)
{
QString prompt = ssh_userauth_kbdint_getprompt(
p->session, static_cast<unsigned int>(i), &echo);
radix_tagged_line(i << ". " << prompt.toStdString());
if (prompt.isEmpty()) break;
prompts << prompt;
}
emit interactiveAuthenticationRequested(instruction, name, prompts);
}
SessionWorker::SessionWorker(QObject* parent) SessionWorker::SessionWorker(QObject* parent)
: QObject(parent) : QObject(parent)
{ {
...@@ -85,11 +104,14 @@ void SessionWorker::setUser(QString name) ...@@ -85,11 +104,14 @@ void SessionWorker::setUser(QString name)
void SessionWorker::connect() void SessionWorker::connect()
{ {
assert_ssh_session(p->session, "connect() -- Session is not allocated."); assert_ssh_session(p->session, "connect() -- Session is not allocated.");
if (ssh_is_connected(p->session) == 0) radix_tagged_line("connect()");
if (ssh_is_connected(p->session) == 1)
{ {
radix_tagged_line("session already connected. disconnectinng.");
ssh_disconnect(p->session); ssh_disconnect(p->session);
} }
{ {
radix_tagged_line("Attempting connection.");
// attempt a connection // attempt a connection
int rc = ssh_connect(p->session); int rc = ssh_connect(p->session);
if (rc != SSH_OK) if (rc != SSH_OK)
...@@ -98,7 +120,7 @@ void SessionWorker::connect() ...@@ -98,7 +120,7 @@ void SessionWorker::connect()
int rv = ssh_options_get(p->session, SSH_OPTIONS_HOST, &message); int rv = ssh_options_get(p->session, SSH_OPTIONS_HOST, &message);
std::ostringstream os; std::ostringstream os;
if (rv == SSH_OK) if (rv == SSH_OK) // if the error message retrieval was good
{ {
os << "Error connecting to " << message << ":"; os << "Error connecting to " << message << ":";
delete message; delete message;
...@@ -249,21 +271,7 @@ void SessionWorker::authenticate() ...@@ -249,21 +271,7 @@ void SessionWorker::authenticate()
err = ssh_userauth_kbdint(p->session, nullptr, nullptr); err = ssh_userauth_kbdint(p->session, nullptr, nullptr);
while (err == SSH_AUTH_INFO) while (err == SSH_AUTH_INFO)
{ {
QString instruction = ssh_userauth_kbdint_getname(p->session); processPrompts();
QString name = ssh_userauth_kbdint_getinstruction(p->session);
int num_prompts = ssh_userauth_kbdint_getnprompts(p->session);
// build list of prompts
QStringList prompts;
char echo;
for (int i = 0; i < num_prompts; ++i)
{
QString prompt = ssh_userauth_kbdint_getprompt(
p->session, static_cast<unsigned int>(i), &echo);
radix_tagged_line(i << ". " << prompt.toStdString());
if (prompt.isEmpty()) break;
prompts << prompt;
}
emit interactiveAuthenticationRequested(instruction, name, prompts);
return; return;
} }
} }
...@@ -306,8 +314,10 @@ void SessionWorker::authenticateWithPassword(QString pswd) ...@@ -306,8 +314,10 @@ void SessionWorker::authenticateWithPassword(QString pswd)
void SessionWorker::authenticatePrompts(QStringList responses) void SessionWorker::authenticatePrompts(QStringList responses)
{ {
int err; int err;
radix_tagged_line("authenticatePrompts()");
for (int i = 0; i < responses.size(); ++i) for (int i = 0; i < responses.size(); ++i)
{ {
radix_tagged_line("Setting response " << i);
const char* answer = responses.at(i).toStdString().c_str(); const char* answer = responses.at(i).toStdString().c_str();
err = ssh_userauth_kbdint_setanswer(p->session, err = ssh_userauth_kbdint_setanswer(p->session,
static_cast<unsigned int>(i), answer); static_cast<unsigned int>(i), answer);
...@@ -326,7 +336,12 @@ void SessionWorker::authenticatePrompts(QStringList responses) ...@@ -326,7 +336,12 @@ void SessionWorker::authenticatePrompts(QStringList responses)
ssh_disconnect(p->session); ssh_disconnect(p->session);
return; return;
} }
else if (err == SSH_AUTH_SUCCESS) if (err == SSH_AUTH_INFO)
{
processPrompts();
return;
}
if (err == SSH_AUTH_SUCCESS)
{ {
emit authenticationSucceeded(); emit authenticationSucceeded();
return; return;
......
...@@ -17,6 +17,8 @@ class RSM_PUBLIC SessionWorker : public QObject ...@@ -17,6 +17,8 @@ class RSM_PUBLIC SessionWorker : public QObject
// Private implementation // Private implementation
SessionWorkerImpl* p; SessionWorkerImpl* p;
void processPrompts();
public: public:
/** /**
* Basic Constructor * Basic Constructor
......
...@@ -151,6 +151,28 @@ void ExamplePortalWidget::interactiveAuthenticationRequested( ...@@ -151,6 +151,28 @@ void ExamplePortalWidget::interactiveAuthenticationRequested(
{ {
mTextEdit->append(prompts.at(i)); mTextEdit->append(prompts.at(i));
} }
if (!prompts.isEmpty())
{
QString text = QInputDialog::getText(this, "Authentication", prompts.at(0),
QLineEdit::Password);
if (text.isEmpty())
{
mSession->disconnect();
}
else
{
QStringList responses;
responses << text;
mSession->authenticatePrompts(responses);
}
}
else
{
radix_tagged_line("Reponsing with empty handshake.");
QStringList empty;
mSession->authenticatePrompts(empty);
}
} }
void ExamplePortalWidget::getServerPublicKeyFailed() void ExamplePortalWidget::getServerPublicKeyFailed()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment