File indexing completed on 2024-04-28 04:58:53

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 *,
0111                                           const char *,
0112                                           UINT16,
0113                                           const char *,
0114                                           const char *,
0115                                           const char *,
0116                                           const char *,
0117                                           const char *,
0118                                           const char *,
0119                                           const char *,
0120                                           DWORD);
0121     friend BOOL endPaint(rdpContext *);
0122     friend BOOL resizeDisplay(rdpContext *);
0123 
0124     void setState(State newState);
0125 
0126     bool onPreConnect();
0127     bool onPostConnect();
0128     void onPostDisconnect();
0129 
0130     bool onAuthenticate(char **username, char **password, char **domain);
0131     CertificateResult onVerifyCertificate(const Certificate &certificate);
0132     CertificateResult onVerifyChangedCertificate(const Certificate &oldCertificate, const Certificate &newCertificate);
0133 
0134     bool onEndPaint();
0135     bool onResizeDisplay();
0136 
0137     void run();
0138 
0139     void emitErrorMessage();
0140 
0141     RdpView *m_view;
0142 
0143     freerdp *m_freerdp = nullptr;
0144     RdpContext *m_context = nullptr;
0145 
0146     State m_state = State::Initial;
0147 
0148     QString m_user;
0149     QString m_domain;
0150     QString m_password;
0151     QString m_host;
0152     int m_port = -1;
0153     QSize m_size;
0154 
0155     std::thread m_thread;
0156 
0157     QImage m_videoBuffer;
0158 
0159     RdpHostPreferences *m_preferences;
0160 };