File indexing completed on 2024-05-12 09:01:21

0001 /*
0002  * SPDX-FileCopyrightText: 2023 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  * SPDX-License-Identifier: GPL-2.0-or-later
0004  */
0005 
0006 #pragma once
0007 
0008 #include <atomic>
0009 #include <memory>
0010 #include <thread>
0011 
0012 #include <QImage>
0013 #include <QObject>
0014 #include <QSize>
0015 
0016 #include <freerdp/freerdp.h>
0017 
0018 class RdpSession;
0019 class RdpView;
0020 class RdpHostPreferences;
0021 
0022 struct RdpContext {
0023     rdpContext _c;
0024 
0025     RdpSession *session = nullptr;
0026 };
0027 
0028 struct Certificate {
0029     QString toString() const;
0030 
0031     QString host;
0032     qint16 port;
0033     QString commonName;
0034     QString subject;
0035     QString issuer;
0036     QString fingerprint;
0037     int flags;
0038 };
0039 
0040 class RdpSession : public QObject
0041 {
0042     Q_OBJECT
0043 
0044 public:
0045     /**
0046      * Session state.
0047      */
0048     enum class State {
0049         Initial,
0050         Starting,
0051         Connected,
0052         Running,
0053         Closed,
0054     };
0055 
0056     enum class CertificateResult {
0057         DoNotAccept,
0058         AcceptTemporarily,
0059         AcceptPermanently,
0060     };
0061 
0062     RdpSession(RdpView *view);
0063     ~RdpSession() override;
0064 
0065     /**
0066      * The current session state.
0067      */
0068     State state() const;
0069     Q_SIGNAL void stateChanged();
0070 
0071     QString host() const;
0072     void setHost(const QString &newHost);
0073 
0074     QString user() const;
0075     void setUser(const QString &newUser);
0076 
0077     QString domain() const;
0078     void setDomain(const QString &newDomain);
0079 
0080     QString password() const;
0081     void setPassword(const QString &newPassword);
0082 
0083     RdpHostPreferences *preferences() const;
0084     void setHostPreferences(RdpHostPreferences *preferences);
0085 
0086     QSize size() const;
0087     void setSize(QSize size);
0088     Q_SIGNAL void sizeChanged();
0089 
0090     int port() const;
0091     void setPort(int port);
0092 
0093     bool start();
0094     void stop();
0095 
0096     bool sendEvent(QEvent *event, QWidget *source);
0097 
0098     const QImage *videoBuffer() const;
0099 
0100     Q_SIGNAL void rectangleUpdated(const QRect &rectangle);
0101 
0102     Q_SIGNAL void errorMessage(const QString &title, const QString &message);
0103 
0104 private:
0105     friend BOOL preConnect(freerdp*);
0106     friend BOOL postConnect(freerdp*);
0107     friend void postDisconnect(freerdp*);
0108     friend BOOL authenticate(freerdp*, char**, char**, char**);
0109     friend DWORD verifyCertificate(freerdp*, const char*, UINT16 port,const char*, const char*, const char*, const char*, DWORD);
0110     friend DWORD verifyChangedCertificate(freerdp*, const char*, UINT16, const char*, const char*, const char*, const char*, const char* , const char*, const char*, DWORD);
0111     friend BOOL endPaint(rdpContext *);
0112     friend BOOL resizeDisplay(rdpContext *);
0113 
0114     void setState(State newState);
0115 
0116     bool onPreConnect();
0117     bool onPostConnect();
0118     void onPostDisconnect();
0119 
0120     bool onAuthenticate(char** username, char** password, char** domain);
0121     CertificateResult onVerifyCertificate(const Certificate &certificate);
0122     CertificateResult onVerifyChangedCertificate(const Certificate &oldCertificate, const Certificate &newCertificate);
0123 
0124     bool onEndPaint();
0125     bool onResizeDisplay();
0126 
0127     void run();
0128 
0129     void emitErrorMessage();
0130 
0131     RdpView *m_view;
0132 
0133     freerdp *m_freerdp = nullptr;
0134     RdpContext *m_context = nullptr;
0135 
0136     State m_state = State::Initial;
0137 
0138     QString m_user;
0139     QString m_domain;
0140     QString m_password;
0141     QString m_host;
0142     int m_port = -1;
0143     QSize m_size;
0144 
0145     std::thread m_thread;
0146 
0147     QImage m_videoBuffer;
0148 
0149     RdpHostPreferences *m_preferences;
0150 };