Rabbit Remote Control 0.0.36
Loading...
Searching...
No Matches
ConnectLayerSSHTunnel.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include "winpr/winsock.h"
4#include "ConnectLayerSSHTunnel.h"
5#include <QLoggingCategory>
6
7static Q_LOGGING_CATEGORY(log, "FreeRDP.Connect.Layer.SSH")
8
10 : CConnectLayer{connect}
11 , m_pChannelSSH(nullptr)
12 , m_hSshSocket(nullptr)
13{}
14
15ConnectLayerSSHTunnel::~ConnectLayerSSHTunnel()
16{
17 qDebug(log) << Q_FUNC_INFO;
18}
19
20int ConnectLayerSSHTunnel::OnInit(rdpContext *context)
21{
22 int nRet = 0;
23
24 m_pChannelSSH = new CChannelSSHTunnel(
25 &m_pParameter->m_Proxy.m_SSH, &m_pParameter->m_Net, m_pConnect);
26 if(!m_pChannelSSH)
27 return -1;
28 bool bRet = m_pChannelSSH->open(QIODevice::ReadWrite);
29 if(!bRet)
30 return -1;
31 if(SSH_INVALID_SOCKET == m_pChannelSSH->GetSocket()) {
32 qCritical(log) << "The socket is invalid";
33 return -1;
34 }
35 m_hSshSocket = WSACreateEvent();
36 if(!m_hSshSocket) {
37 qCritical(log) << "CreateEvent ssh socket event failed";
38 return -1;
39 }
40 nRet = WSAEventSelect(m_pChannelSSH->GetSocket(), m_hSshSocket, FD_READ | FD_CLOSE);
41 if(nRet)
42 return -1;
43 if(m_pParameter->m_Net.GetHost().isEmpty())
44 {
45 QString szErr;
46 szErr = tr("The server is empty, please input it");
47 qCritical(log) << szErr;
48 emit m_pConnect->sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
49 emit m_pConnect->sigError(-1, szErr.toStdString().c_str());
50 return -1;
51 }
52
53 auto &net = m_pParameter->m_Net;
54 auto settings = context->settings;
55 freerdp_settings_set_string(
56 settings, FreeRDP_ServerHostname,
57 net.GetHost().toStdString().c_str());
58 freerdp_settings_set_uint32(
59 settings, FreeRDP_ServerPort,
60 net.GetPort());
61
62 nRet = freerdp_client_start(context);
63 if(nRet)
64 {
65 qCritical(log) << "freerdp_client_start fail";
66 return -1;
67 }
68 return 0;
69}
70
71int ConnectLayerSSHTunnel::OnClean()
72{
73 int nRet = 0;
74
75 if(m_pChannelSSH)
76 {
77 m_pChannelSSH->close();
78 m_pChannelSSH->deleteLater();
79 m_pChannelSSH = nullptr;
80 }
81 if(m_hSshSocket)
82 {
83 WSACloseEvent(m_hSshSocket);
84 m_hSshSocket = nullptr;
85 }
86
87 return nRet;
88}
89
90int ConnectLayerSSHTunnel::OnLayerRead(void *data, int bytes)
91{
92 int nRet = 0;
93
94 if(!m_pChannelSSH || !m_pChannelSSH->isOpen()) {
95 qCritical(log) << Q_FUNC_INFO << "The channel is close";
96 return -1;
97 }
98
99 if(m_hSshSocket)
100 WSAResetEvent(m_hSshSocket);
101
102 nRet = m_pChannelSSH->read((char*)data, bytes);
103
104 return nRet;
105}
106
107int ConnectLayerSSHTunnel::OnLayerWrite(const void *data, int bytes)
108{
109 //qDebug(log) << Q_FUNC_INFO;
110 int nRet = 0;
111 if(!m_pChannelSSH || !m_pChannelSSH->isOpen()) {
112 qCritical(log) << Q_FUNC_INFO << "The channel is close";
113 return -1;
114 }
115 nRet = m_pChannelSSH->write((const char*)data, bytes);
116 return nRet;
117}
118
119BOOL ConnectLayerSSHTunnel::OnLayerWait(BOOL waitWrite, DWORD timeout)
120{
121 //qDebug(log) << Q_FUNC_INFO << "wait write:" << waitWrite;
122 Q_ASSERT(!waitWrite);
123 if(!m_pChannelSSH || !m_pChannelSSH->isOpen()
124 || m_pChannelSSH->GetSocket() == SSH_INVALID_SOCKET) {
125 qCritical(log) << Q_FUNC_INFO << "The channel is close";
126 return false;
127 }
128
129 int nRet = m_pChannelSSH->DoWait(waitWrite, timeout);
130 if(nRet) return false;
131 return true;
132}
133
134HANDLE ConnectLayerSSHTunnel::OnLayerGetEvent()
135{
136 //qDebug(log) << Q_FUNC_INFO;
137 return m_hSshSocket;
138}
ssh tunnel class
virtual bool open(OpenMode mode) override
The connect layer class.
void sigError(const int nError, const QString &szError=QString())
Triggered when an error is generated.
void sigShowMessageBox(const QString &szTitle, const QString &szMessage, const QMessageBox::Icon &icon=QMessageBox::Information)
Trigger the display of a message dialog (QMessageBox) in the main thread from a background thread wit...