Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
LEFEBVREJP email
rsm
Commits
7edeedfc
Commit
7edeedfc
authored
Jan 27, 2020
by
LEFEBVREJP email
Browse files
Working authentication and command submission. Started on interactive authentication.
parent
2d792e1e
Changes
6
Hide whitespace changes
Inline
Side-by-side
rsmcore/sessioncontroller.cc
View file @
7edeedfc
...
...
@@ -51,6 +51,11 @@ SessionController::SessionController(QObject* parent)
&
SessionController
::
connectionFailed
);
QObject
::
connect
(
p
->
worker
,
&
SessionWorker
::
connectionSuccessful
,
this
,
&
SessionController
::
connectionSuccessful
);
QObject
::
connect
(
p
->
worker
,
&
SessionWorker
::
disconnectSuccessful
,
this
,
&
SessionController
::
disconnectSuccessful
);
QObject
::
connect
(
p
->
worker
,
&
SessionWorker
::
interactiveAuthenticationRequested
,
this
,
&
SessionController
::
interactiveAuthenticationRequested
);
QObject
::
connect
(
p
->
worker
,
&
SessionWorker
::
verifyKnownHostSuccessful
,
this
,
&
SessionController
::
verifyKnownHostSuccessful
);
QObject
::
connect
(
p
->
worker
,
&
SessionWorker
::
getServerPublicKeyFailed
,
this
,
...
...
rsmcore/sessioncontroller.hh
View file @
7edeedfc
...
...
@@ -88,7 +88,11 @@ class RSM_PUBLIC SessionController : public QObject
void
connectionFailed
(
QString
message
);
void
connectionSuccessful
();
void
disconnectSuccessful
();
void
verifyKnownHostSuccessful
();
void
interactiveAuthenticationRequested
(
QString
instruction
,
QString
name
,
QStringList
prompts
);
/**
* @brief getServerPublicKeyFailed
* Signal is emitted when the remote host does not have or provide a public
...
...
rsmcore/sessionworker.cc
View file @
7edeedfc
...
...
@@ -86,6 +86,9 @@ void SessionWorker::connect()
{
assert_ssh_session
(
p
->
session
,
"connect() -- Session is not allocated."
);
if
(
ssh_is_connected
(
p
->
session
)
==
0
)
{
ssh_disconnect
(
p
->
session
);
}
{
// attempt a connection
int
rc
=
ssh_connect
(
p
->
session
);
...
...
@@ -111,10 +114,12 @@ void SessionWorker::connect()
void
SessionWorker
::
disconnect
()
{
assert_ssh_session
(
p
->
session
,
"disconnect() -- Session is not allocated."
);
radix_tagged_line
(
"disconnect()"
);
if
(
ssh_is_connected
(
p
->
session
)
!=
0
)
{
radix_tagged_line
(
"Disconnecting session."
);
ssh_disconnect
(
p
->
session
);
emit
disconnectSuccessful
();
}
}
...
...
@@ -129,6 +134,7 @@ void SessionWorker::verifyKnownHost()
size_t
hlen
;
QString
qhexa
;
radix_tagged_line
(
"verifyKnownHost()"
);
int
rc
=
ssh_get_server_publickey
(
p
->
session
,
&
server_public_key
);
if
(
rc
<
0
)
{
...
...
@@ -191,6 +197,7 @@ void SessionWorker::acceptHostPublicKeyUpdate()
{
assert_ssh_session
(
p
->
session
,
"acceptHostPublicKeyUpdate() -- Session is not allocated."
);
radix_tagged_line
(
"authenticateHostPublicKeyUpdate()"
);
int
rc
=
ssh_session_update_known_hosts
(
p
->
session
);
if
(
rc
!=
SSH_OK
)
{
...
...
@@ -202,6 +209,7 @@ void SessionWorker::authenticate()
{
assert_ssh_session
(
p
->
session
,
"authenticate() -- Session is not allocated."
);
radix_tagged_line
(
"Authenticate."
);
// Try authenticating with no credentials - rarely works
int
rc
=
ssh_userauth_none
(
p
->
session
,
nullptr
);
if
(
rc
==
SSH_AUTH_ERROR
)
...
...
@@ -232,6 +240,34 @@ void SessionWorker::authenticate()
}
radix_tagged_line
(
"SSH_AUTH_METHOD_PUBLICKEY didn't work."
);
}
// public key authentication
// Try to authenticate with keyboard interactive";
if
(
method
&
SSH_AUTH_METHOD_INTERACTIVE
)
{
int
err
;
err
=
ssh_userauth_kbdint
(
p
->
session
,
nullptr
,
nullptr
);
while
(
err
==
SSH_AUTH_INFO
)
{
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
);
return
;
}
}
// Try to authenticate with password
if
(
method
&
SSH_AUTH_METHOD_PASSWORD
)
{
...
...
@@ -245,6 +281,7 @@ void SessionWorker::authenticateWithPassword(QString pswd)
{
assert_ssh_session
(
p
->
session
,
"authenticateWithPassword() -- Session is not allocated."
);
radix_tagged_line
(
"Authenticate with password."
);
int
rc
=
ssh_userauth_password
(
p
->
session
,
nullptr
,
pswd
.
toStdString
().
c_str
());
if
(
rc
==
SSH_AUTH_ERROR
)
...
...
@@ -266,6 +303,36 @@ void SessionWorker::authenticateWithPassword(QString pswd)
}
}
void
SessionWorker
::
authenticatePrompts
(
QStringList
responses
)
{
int
err
;
for
(
int
i
=
0
;
i
<
responses
.
size
();
++
i
)
{
const
char
*
answer
=
responses
.
at
(
i
).
toStdString
().
c_str
();
err
=
ssh_userauth_kbdint_setanswer
(
p
->
session
,
static_cast
<
unsigned
int
>
(
i
),
answer
);
if
(
err
<
0
)
{
emit
authenticationError
(
"Failed to authenticate prompts."
);
ssh_disconnect
(
p
->
session
);
return
;
}
}
// check status
err
=
ssh_userauth_kbdint
(
p
->
session
,
nullptr
,
nullptr
);
if
(
err
==
SSH_AUTH_DENIED
)
{
emit
authenticationError
(
"Authentication denied."
);
ssh_disconnect
(
p
->
session
);
return
;
}
else
if
(
err
==
SSH_AUTH_SUCCESS
)
{
emit
authenticationSucceeded
();
return
;
}
}
void
SessionWorker
::
requestExec
(
QString
command
)
{
assert_ssh_session
(
p
->
session
,
"request_exec() -- Session is not allocated."
);
...
...
@@ -303,9 +370,9 @@ void SessionWorker::requestExec(QString command)
while
(
nbytes
>
0
)
{
p
->
output_buffer
.
append
(
buffer
,
nbytes
);
emit
execOutputReady
();
nbytes
=
ssh_channel_read
(
channel
,
buffer
,
sizeof
(
buffer
),
0
);
}
emit
execOutputReady
();
radix_tagged_line
(
"nbytes="
<<
nbytes
);
radix_tagged_line
(
"Finished reading response
\n
"
<<
p
->
output_buffer
.
data
());
...
...
rsmcore/sessionworker.hh
View file @
7edeedfc
...
...
@@ -85,6 +85,8 @@ class RSM_PUBLIC SessionWorker : public QObject
*/
void
authenticateWithPassword
(
QString
pswd
);
void
authenticatePrompts
(
QStringList
responses
);
/**
* Requests remote execution of command
* @param command - QString command to execute
...
...
@@ -94,7 +96,11 @@ class RSM_PUBLIC SessionWorker : public QObject
signals:
void
connectionFailed
(
QString
message
);
void
connectionSuccessful
();
void
disconnectSuccessful
();
void
verifyKnownHostSuccessful
();
void
interactiveAuthenticationRequested
(
QString
instruction
,
QString
name
,
QStringList
prompts
);
/**
* @brief getServerPublicKeyFailed
* Signal is emitted when the remote host does not have or provide a public
...
...
rsmwidgets/examples/rsmportalexample.cc
View file @
7edeedfc
...
...
@@ -9,7 +9,9 @@
#include
<QApplication>
#include
<QGridLayout>
#include
<QHeaderView>
#include
<QInputDialog>
#include
<QLabel>
#include
<QMessageBox>
#include
"radixbug/bug.hh"
using
namespace
rsm
;
...
...
@@ -45,18 +47,26 @@ ExamplePortalWidget::ExamplePortalWidget(QWidget *parent)
connect
(
mConnectButton
,
&
QPushButton
::
pressed
,
this
,
&
ExamplePortalWidget
::
connectToHost
);
connect
(
mCommandSubmitButton
,
&
QPushButton
::
pressed
,
this
,
&
ExamplePortalWidget
::
submitCommandToHost
);
mSession
=
new
SessionController
();
connect
(
mSession
,
&
SessionController
::
connectionFailed
,
this
,
&
ExamplePortalWidget
::
connectionFailed
);
connect
(
mSession
,
&
SessionController
::
connectionSuccessful
,
this
,
&
ExamplePortalWidget
::
connectionSuccessful
);
connect
(
mSession
,
&
SessionController
::
disconnectSuccessful
,
this
,
&
ExamplePortalWidget
::
disconnectSuccessful
);
connect
(
mSession
,
&
SessionController
::
interactiveAuthenticationRequested
,
this
,
&
ExamplePortalWidget
::
interactiveAuthenticationRequested
);
connect
(
mSession
,
&
SessionController
::
getServerPublicKeyFailed
,
this
,
&
ExamplePortalWidget
::
getServerPublicKeyFailed
);
connect
(
mSession
,
&
SessionController
::
hostUnknown
,
this
,
&
ExamplePortalWidget
::
hostUnknown
);
connect
(
mSession
,
&
SessionController
::
hostPublicKeyChanged
,
this
,
&
ExamplePortalWidget
::
hostPublicKeyChanged
);
connect
(
mSession
,
&
SessionController
::
verifyKnownHostSuccessful
,
this
,
&
ExamplePortalWidget
::
verifyKnownHostSuccessful
);
connect
(
mSession
,
&
SessionController
::
knownHostError
,
this
,
&
ExamplePortalWidget
::
knownHostError
);
connect
(
mSession
,
&
SessionController
::
authenticationError
,
this
,
...
...
@@ -79,13 +89,26 @@ void ExamplePortalWidget::connectToHost()
{
radix_tagged_line
(
"Host:"
<<
mHostEdit
->
text
().
toStdString
());
mSession
->
setHost
(
mHostEdit
->
text
());
mSession
->
setPort
(
mPortEdit
->
text
().
toInt
());
mSession
->
setUser
(
mUserNameEdit
->
text
());
mSession
->
connect
();
if
(
mConnectButton
->
text
().
compare
(
"Disconnect"
)
==
0
)
{
mSession
->
disconnect
();
mConnectButton
->
setText
(
"Connect"
);
}
else
{
mSession
->
setHost
(
mHostEdit
->
text
());
mSession
->
setPort
(
mPortEdit
->
text
().
toInt
());
mSession
->
setUser
(
mUserNameEdit
->
text
());
mSession
->
connect
();
}
}
void
ExamplePortalWidget
::
disconnectFromHost
()
{
mSession
->
disconnect
();
}
void
ExamplePortalWidget
::
submitCommandToHost
()
{
radix_tagged_line
(
"submitCommandToHost()"
);
QString
command
=
mCommandEdit
->
text
();
mSession
->
requestExec
(
command
);
}
void
ExamplePortalWidget
::
slotExecOutputReady
()
{
...
...
@@ -105,12 +128,31 @@ void ExamplePortalWidget::connectionSuccessful()
mSession
->
verifyKnownHost
();
}
void
ExamplePortalWidget
::
verifyKnownHostSuccesful
()
void
ExamplePortalWidget
::
disconnectSuccessful
()
{
mTextEdit
->
append
(
"Disconnected.
\n
"
);
}
void
ExamplePortalWidget
::
verifyKnownHostSuccessful
()
{
mTextEdit
->
append
(
"Verification successful.\Authenticating...
\n
"
);
mTextEdit
->
append
(
"Verification successful.
\
n
Authenticating...
\n
"
);
mSession
->
authenticate
();
}
void
ExamplePortalWidget
::
interactiveAuthenticationRequested
(
QString
instruction
,
QString
name
,
QStringList
prompts
)
{
mTextEdit
->
append
(
"Interactive authentication requested."
);
mTextEdit
->
append
(
"Instruction: "
);
mTextEdit
->
append
(
instruction
);
mTextEdit
->
append
(
"Name:"
);
mTextEdit
->
append
(
name
);
for
(
int
i
=
0
;
i
<
prompts
.
size
();
++
i
)
{
mTextEdit
->
append
(
prompts
.
at
(
i
));
}
}
void
ExamplePortalWidget
::
getServerPublicKeyFailed
()
{
mTextEdit
->
append
(
"Retrieval of host's public key failed.
\n
"
);
...
...
@@ -119,9 +161,21 @@ void ExamplePortalWidget::getServerPublicKeyFailed()
void
ExamplePortalWidget
::
hostUnknown
(
QString
host_hash
)
{
mTextEdit
->
append
(
"Host key unknown.
\n
Do you accept:"
);
mTextEdit
->
append
(
host_hash
);
mTextEdit
->
append
(
"
\n
"
);
int
ret
=
QMessageBox
::
warning
(
this
,
tr
(
"Host Unknown"
),
QString
(
"The remote host is unknown.
\n
"
)
.
append
(
"Are you sure you want to continue connecting?
\n
"
)
.
append
(
"Remote host key:"
)
.
append
(
host_hash
),
QMessageBox
::
Yes
|
QMessageBox
::
Cancel
);
if
(
ret
==
QMessageBox
::
Yes
)
{
mSession
->
acceptHostPublicKeyUpdate
();
}
else
{
mSession
->
disconnect
();
}
}
void
ExamplePortalWidget
::
hostPublicKeyChanged
(
QString
host_hash
)
...
...
@@ -159,17 +213,33 @@ void ExamplePortalWidget::authenticationSucceeded()
{
mTextEdit
->
append
(
"Authentication succeeded."
);
mTextEdit
->
append
(
"
\n
"
);
mConnectButton
->
setText
(
"Disconnect"
);
}
void
ExamplePortalWidget
::
passwordRequested
()
{
mTextEdit
->
append
(
"Password requested."
);
mTextEdit
->
append
(
"
\n
"
);
// TODO: Prompt password dialog
QString
text
=
QInputDialog
::
getText
(
this
,
"Authentication"
,
"Password:"
,
QLineEdit
::
Password
);
if
(
text
.
isEmpty
())
{
mSession
->
disconnect
();
}
else
{
mSession
->
authenticateWithPassword
(
text
);
}
}
void
ExamplePortalWidget
::
loginBannerIssued
(
QString
message
)
{
int
ret
=
QMessageBox
::
warning
(
this
,
tr
(
"Host Login Banner"
),
message
,
QMessageBox
::
Ok
|
QMessageBox
::
Cancel
);
if
(
ret
!=
QMessageBox
::
Ok
)
{
mSession
->
disconnect
();
}
mTextEdit
->
append
(
message
);
mTextEdit
->
append
(
"
\n
"
);
}
...
...
rsmwidgets/examples/rsmportalexample.hh
View file @
7edeedfc
...
...
@@ -33,12 +33,16 @@ class ExamplePortalWidget : public QWidget
public
slots
:
void
connectToHost
();
void
disconnectFrom
Host
();
void
submitCommandTo
Host
();
void
slotExecOutputReady
();
void
connectionFailed
(
QString
message
);
void
connectionSuccessful
();
void
verifyKnownHostSuccesful
();
void
disconnectSuccessful
();
void
verifyKnownHostSuccessful
();
void
interactiveAuthenticationRequested
(
QString
instruction
,
QString
name
,
QStringList
prompts
);
void
getServerPublicKeyFailed
();
void
hostUnknown
(
QString
host_hash
);
void
hostPublicKeyChanged
(
QString
host_hash
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment