1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QTRANSPORTAUTH_QWS_H
43 #define QTRANSPORTAUTH_QWS_H
44 
45 #include <QtCore/qglobal.h>
46 
47 #if !defined(QT_NO_SXE) || defined(SXE_INSTALLER)
48 
49 #include <QtCore/qobject.h>
50 #include <QtCore/qhash.h>
51 #include <QtCore/qstring.h>
52 #include <QtCore/qbuffer.h>
53 #include <QtCore/qpointer.h>
54 
55 #include <sys/types.h>
56 
57 QT_BEGIN_HEADER
58 
59 QT_BEGIN_NAMESPACE
60 
61 QT_MODULE(Gui)
62 
63 class QAuthDevice;
64 class QWSClient;
65 class QIODevice;
66 class QTransportAuthPrivate;
67 class QMutex;
68 
69 class Q_GUI_EXPORT QTransportAuth : public QObject
70 {
71     Q_OBJECT
72 public:
73     static QTransportAuth *getInstance();
74 
75     enum Result {
76         // Error codes
77         Pending = 0x00,
78         TooSmall = 0x01,
79         CacheMiss = 0x02,
80         NoMagic = 0x03,
81         NoSuchKey = 0x04,
82         FailMatch = 0x05,
83         OutOfDate = 0x06,
84         // reserved for expansion
85         Success = 0x1e,
86         ErrMask = 0x1f,
87 
88         // Verification codes
89         Allow = 0x20,
90         Deny = 0x40,
91         Ask = 0x60,
92         // reserved
93         StatusMask = 0xe0
94     };
95 
96     enum Properties {
97         Trusted = 0x01,
98         Connection = 0x02,
99         UnixStreamSock = 0x04,
100         SharedMemory = 0x08,
101         MessageQueue = 0x10,
102         UDP = 0x20,
103         TCP = 0x40,
104         UserDefined = 0x80,
105         TransportType = 0xfc
106     };
107 
108     struct Data
109     {
DataData110         Data() { processId = -1; }
DataData111         Data( unsigned char p, int d )
112             : properties( p )
113             , descriptor( d )
114             , processId( -1 )
115         {
116             if (( properties & TransportType ) == TCP ||
117                 ( properties & TransportType ) == UnixStreamSock )
118                 properties |= Connection;
119         }
120 
121         unsigned char properties;
122         unsigned char progId;
123         unsigned char status;
124         unsigned int descriptor;   // socket fd or shmget key
125         pid_t processId;
126 
127         bool trusted() const;
128         void setTrusted( bool );
129         bool connection() const;
130         void setConnection( bool );
131     };
132 
133     static const char *errorString( const QTransportAuth::Data & );
134 
135     QTransportAuth::Data *connectTransport( unsigned char, int );
136 
137     QAuthDevice *authBuf( QTransportAuth::Data *, QIODevice * );
138     QAuthDevice *recvBuf( QTransportAuth::Data *, QIODevice * );
139     QIODevice *passThroughByClient( QWSClient * ) const;
140 
141     void setKeyFilePath( const QString & );
142     QString keyFilePath() const;
143     const unsigned char *getClientKey( unsigned char progId );
144     void invalidateClientKeyCache();
145     QMutex *getKeyFileMutex();
146     void setLogFilePath( const QString & );
147     QString logFilePath() const;
148     void setPackageRegistry( QObject *registry );
149     bool isDiscoveryMode() const;
150     void setProcessKey( const char * );
151     void setProcessKey( const char *, const char * );
152     void registerPolicyReceiver( QObject * );
153     void unregisterPolicyReceiver( QObject * );
154 
155     bool authToMessage( QTransportAuth::Data &d, char *hdr, const char *msg, int msgLen );
156     bool authFromMessage( QTransportAuth::Data &d, const char *msg, int msgLen );
157 
158     bool authorizeRequest( QTransportAuth::Data &d, const QString &request );
159 
160 Q_SIGNALS:
161     void policyCheck( QTransportAuth::Data &, const QString & );
162     void authViolation( QTransportAuth::Data & );
163 private Q_SLOTS:
164     void bufferDestroyed( QObject * );
165 
166 private:
167     // users should never construct their own
168     QTransportAuth();
169     ~QTransportAuth();
170 
171     friend class QAuthDevice;
172     Q_DECLARE_PRIVATE(QTransportAuth)
173 };
174 
175 class Q_GUI_EXPORT RequestAnalyzer
176 {
177 public:
178     RequestAnalyzer();
179     virtual ~RequestAnalyzer();
operator()180     QString operator()( QByteArray *data ) { return analyze( data ); }
requireMoreData()181     bool requireMoreData() const { return moreData; }
bytesAnalyzed()182     qint64 bytesAnalyzed() const { return dataSize; }
183 protected:
184     virtual QString analyze( QByteArray * );
185     bool moreData;
186     qint64 dataSize;
187 };
188 
189 /*!
190   \internal
191   \class QAuthDevice
192 
193   \brief Pass-through QIODevice sub-class for authentication.
194 
195    Use this class to forward on or receive forwarded data over a real
196    device for authentication.
197 */
198 class Q_GUI_EXPORT QAuthDevice : public QIODevice
199 {
200     Q_OBJECT
201 public:
202     enum AuthDirection {
203         Receive,
204         Send
205     };
206     QAuthDevice( QIODevice *, QTransportAuth::Data *, AuthDirection );
207     ~QAuthDevice();
setTarget(QIODevice * t)208     void setTarget( QIODevice *t ) { m_target = t; }
target()209     QIODevice *target() const { return m_target; }
210     void setClient( QObject* );
211     QObject *client() const;
212     void setRequestAnalyzer( RequestAnalyzer * );
213     bool isSequential() const;
214     bool atEnd() const;
215     qint64 bytesAvailable() const;
216     qint64 bytesToWrite() const;
217     bool seek( qint64 );
218     QByteArray & buffer();
219 
220 protected:
221     qint64 readData( char *, qint64 );
222     qint64 writeData(const char *, qint64 );
223 private Q_SLOTS:
224     void recvReadyRead();
225     void targetBytesWritten( qint64 );
226 private:
227     bool authorizeMessage();
228 
229     QTransportAuth::Data *d;
230     AuthDirection way;
231     QIODevice *m_target;
232     QObject *m_client;
233     QByteArray msgQueue;
234     qint64 m_bytesAvailable;
235     qint64 m_skipWritten;
236 
237     RequestAnalyzer *analyzer;
238 };
239 
isSequential()240 inline bool QAuthDevice::isSequential() const
241 {
242     return true;
243 }
244 
seek(qint64)245 inline bool QAuthDevice::seek( qint64 )
246 {
247     return false;
248 }
249 
atEnd()250 inline bool QAuthDevice::atEnd() const
251 {
252     return msgQueue.isEmpty();
253 }
254 
bytesAvailable()255 inline qint64 QAuthDevice::bytesAvailable() const
256 {
257     if ( way == Receive )
258         return m_bytesAvailable;
259     else
260         return ( m_target ? m_target->bytesAvailable() : 0 );
261 }
262 
bytesToWrite()263 inline qint64 QAuthDevice::bytesToWrite() const
264 {
265     return msgQueue.size();
266 }
267 
buffer()268 inline QByteArray &QAuthDevice::buffer()
269 {
270     return msgQueue;
271 }
272 
273 
274 
275 
276 QT_END_NAMESPACE
277 
278 QT_END_HEADER
279 
280 #endif // QT_NO_SXE
281 #endif // QTRANSPORTAUTH_QWS_H
282