2#include <QLoggingCategory>
4Q_DECLARE_LOGGING_CATEGORY(ssh)
6CConnectSSH::CConnectSSH(
CConnecterSSH *pConnecter, QObject *parent)
8 m_pConnecter(pConnecter),
13 connector_in(nullptr),
14 connector_out(nullptr),
15 connector_err(nullptr),
21int CConnectSSH::SetParameter(
void *pPara)
27 if(m_pPara->GetHost().isEmpty())
29 qCritical(ssh) <<
"The host isn't setting";
30 emit
sigError(-1,
"The host isn't setting");
32 else if (ssh_options_set(m_pSession, SSH_OPTIONS_HOST,
33 m_pPara->GetHost().toStdString().c_str()) < 0) {
34 qCritical(ssh) <<
"The host set is fail";
35 emit
sigError(-2,
"The host set is fail");
39 if(m_pPara->GetUser().isEmpty())
41 qCritical(ssh) <<
"The user isn't setting";
42 emit
sigError(-3,
"The user isn't setting");
43 }
else if (ssh_options_set(m_pSession, SSH_OPTIONS_USER,
44 m_pPara->GetUser().toStdString().c_str()) < 0) {
45 qCritical(ssh) <<
"The user set fail";
46 emit
sigError(-3,
"The user set fail");
50 if(!m_pPara->captrueFile.isEmpty())
52 m_pPcapFile = ssh_pcap_file_new();
53 if (m_pPcapFile == NULL) {
57 if (ssh_pcap_file_open(m_pPcapFile,
58 m_pPara->captrueFile.toStdString().c_str())
60 qCritical(ssh) <<
"Error opening pcap file:" << m_pPara->captrueFile;
61 ssh_pcap_file_free(m_pPcapFile);
65 ssh_set_pcap_file(m_pSession, m_pPcapFile);
71int CConnectSSH::Initialize()
75 m_pSession = ssh_new();
76 if(!m_pSession)
return -1;
78 m_pCb =
new ssh_callbacks_struct();
81 memset(m_pCb, 0,
sizeof(
struct ssh_callbacks_struct));
82 m_pCb->userdata =
this;
83 m_pCb->auth_function = cbAuthCallback;
85 ssh_callbacks_init(m_pCb);
86 nRet = ssh_set_callbacks(m_pSession, m_pCb);
89 nRet = SetParameter(m_pPara);
94CConnect::OnInitReturnValue CConnectSSH::OnInit()
99 if(nRet)
return OnInitReturnValue::Fail;
102 if(!pConsole)
return OnInitReturnValue::Fail;
112 if (ssh_connect(m_pSession)) {
113 qCritical(ssh) <<
"Connection failed:" << ssh_get_error(m_pSession);
114 return OnInitReturnValue::Fail;
117 int state = VerifyKnownhost(m_pSession);
119 return OnInitReturnValue::Fail;
122 ssh_userauth_none(m_pSession, NULL);
123 char* banner = ssh_get_issue_banner(m_pSession);
125 qCritical(ssh) << banner;
129 int auth = Authenticate(m_pSession);
130 if (auth != SSH_AUTH_SUCCESS) {
131 return OnInitReturnValue::Fail;
134 m_pChannel = ssh_channel_new(m_pSession);
135 if (m_pChannel == NULL) {
136 qCritical(ssh) <<
"Don't create channel:" << ssh_get_error(m_pSession);
137 return OnInitReturnValue::Fail;
140 if (ssh_channel_open_session(m_pChannel)) {
141 qCritical(ssh) <<
"Error opening channel:" << ssh_get_error(m_pSession);
142 return OnInitReturnValue::Fail;
145 ssh_channel_request_pty(m_pChannel);
146 ssh_channel_change_pty_size(m_pChannel, pConsole->screenColumnsCount(), pConsole->screenLinesCount());
147 qDebug(ssh) <<
"row:" << pConsole->screenLinesCount()
148 <<
";col:" << pConsole->screenColumnsCount();
150 if (ssh_channel_request_shell(m_pChannel)) {
151 qCritical(ssh) <<
"Requesting shell:" << ssh_get_error(m_pSession);
152 return OnInitReturnValue::Fail;
155 m_pEvent = ssh_event_new();
158 connector_in = ssh_connector_new(m_pSession);
159 if(connector_in && m_pChannel && m_pEvent)
161 nRet = ssh_connector_set_out_channel(connector_in, m_pChannel, SSH_CONNECTOR_STDOUT);
162 if(nRet)
return OnInitReturnValue::Fail;
163 ssh_connector_set_in_fd(connector_in, pConsole->getPtySlaveFd());
164 nRet = ssh_event_add_connector(m_pEvent, connector_in);
165 if(nRet)
return OnInitReturnValue::Fail;
169 connector_out = ssh_connector_new(m_pSession);
170 if(connector_out && m_pChannel && m_pEvent)
172#ifndef SSH_CONNECTOR_STDINOUT
173#define SSH_CONNECTOR_STDINOUT SSH_CONNECTOR_STDOUT
175 nRet = ssh_connector_set_in_channel(connector_out, m_pChannel, SSH_CONNECTOR_STDINOUT);
176 if(nRet)
return OnInitReturnValue::Fail;
177 ssh_connector_set_out_fd(connector_out, pConsole->getPtySlaveFd());
178 nRet = ssh_event_add_connector(m_pEvent, connector_out);
179 if(nRet)
return OnInitReturnValue::Fail;
183 connector_err = ssh_connector_new(m_pSession);
184 if(connector_err && m_pChannel && m_pEvent)
186 ssh_connector_set_out_fd(connector_err, 2);
187 nRet = ssh_connector_set_in_channel(connector_err, m_pChannel, SSH_CONNECTOR_STDERR);
188 if(nRet)
return OnInitReturnValue::Fail;
189 nRet = ssh_event_add_connector(m_pEvent, connector_err);
190 if(nRet)
return OnInitReturnValue::Fail;
193 return OnInitReturnValue::UseOnProcess;
196int CConnectSSH::OnClean()
204 ssh_event_remove_connector(m_pEvent, connector_in);
205 ssh_connector_free(connector_in);
209 ssh_event_remove_connector(m_pEvent, connector_out);
210 ssh_connector_free(connector_out);
214 ssh_event_remove_connector(m_pEvent, connector_err);
215 ssh_connector_free(connector_err);
218 ssh_event_free(m_pEvent);
222 ssh_channel_free(m_pChannel);
226 ssh_disconnect(m_pSession);
227 ssh_free(m_pSession);
233 ssh_pcap_file_free(m_pPcapFile);
234 m_pPcapFile =
nullptr;
240int CConnectSSH::OnProcess()
244 if (ssh_channel_is_open(m_pChannel)) {
245 nRet = ssh_event_dopoll(m_pEvent, 500);
246 if (nRet == SSH_ERROR) {
247 qCritical(ssh) <<
"Error in ssh_event_dopoll()";
249 }
else if(nRet == SSH_EOF)
251 else if(SSH_AGAIN == nRet || SSH_OK == nRet)
254 qCritical(ssh) <<
"ssh channel isn't open";
259void CConnectSSH::slotClipBoardChanged()
263int CConnectSSH::cbAuthCallback(
const char *prompt,
271 qCritical(ssh) <<
"prompt:" << prompt <<
";echo:" << echo <<
";verify:" << verify;
272 return pThis->GetPassword(prompt, buf, len, echo, verify);
275int CConnectSSH::GetPassword(
const char *prompt,
286 if(len > m_pPara->GetPassword().toStdString().length())
287 length = m_pPara->GetPassword().toStdString().length();
289 memcpy(buf, m_pPara->GetPassword().toStdString().c_str(), length);
294int CConnectSSH::VerifyKnownhost(ssh_session session)
398void CConnectSSH::error(ssh_session session)
400 qCritical(ssh) <<
"Authentication failed:" << ssh_get_error(session);
403int CConnectSSH::Authenticate(ssh_session session)
405 int rc = SSH_AUTH_SUCCESS;
406 int method = SSH_AUTH_METHOD_UNKNOWN;
407 char password[128] = {0};
408 char *banner =
nullptr;
411 rc = ssh_userauth_none(session, NULL);
412 if (rc == SSH_AUTH_ERROR) {
417 method = ssh_userauth_list(session, NULL);
418 while (rc != SSH_AUTH_SUCCESS) {
419 if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
420 rc = ssh_userauth_gssapi(session);
421 if(rc == SSH_AUTH_ERROR) {
424 }
else if (rc == SSH_AUTH_SUCCESS) {
429 if (method & SSH_AUTH_METHOD_PUBLICKEY) {
430 rc = ssh_userauth_publickey_auto(session, NULL, NULL);
431 if (rc == SSH_AUTH_ERROR) {
434 }
else if (rc == SSH_AUTH_SUCCESS) {
470 if (method & SSH_AUTH_METHOD_INTERACTIVE) {
472 if (rc == SSH_AUTH_ERROR) {
475 }
else if (rc == SSH_AUTH_SUCCESS) {
481 if (method & SSH_AUTH_METHOD_PASSWORD) {
482 memcpy(password, m_pPara->GetPassword().toStdString().c_str(),
483 m_pPara->GetPassword().toStdString().length());
484 rc = ssh_userauth_password(session, NULL, password);
485 if (rc == SSH_AUTH_ERROR) {
488 }
else if (rc == SSH_AUTH_SUCCESS) {
492 memset(password, 0,
sizeof(password));
495 banner = ssh_get_issue_banner(session);
497 qInfo(ssh) << banner;
505void CConnectSSH::slotSendData(
const char *buf,
int len)
508 if(!pConsole)
return;
510 for(
int i = 0; i < len; i++)
513 write(pConsole->getPtySlaveFd(), buf, len);
516void CConnectSSH::slotReceivedData(
const QString &text)
518 qDebug(ssh) <<
"Receive data:" << text;
void sigError(const int nError, const QString &szError=QString())
Triggered when an error is generated.
QWidget * GetViewer() override
Get Viewer.