Qt 4.8
Classes | Public Types | Signals | Public Functions | Static Public Functions | Private Slots | Private Functions | Friends | List of all members
QTransportAuth Class Reference

Authenticate a message transport. More...

#include <qtransportauth_qws.h>

Inheritance diagram for QTransportAuth:
QObject

Classes

struct  Data
 

Public Types

enum  Properties {
  Trusted = 0x01, Connection = 0x02, UnixStreamSock = 0x04, SharedMemory = 0x08,
  MessageQueue = 0x10, UDP = 0x20, TCP = 0x40, UserDefined = 0x80,
  TransportType = 0xfc
}
 
enum  Result {
  Pending = 0x00, TooSmall = 0x01, CacheMiss = 0x02, NoMagic = 0x03,
  NoSuchKey = 0x04, FailMatch = 0x05, OutOfDate = 0x06, Success = 0x1e,
  ErrMask = 0x1f, Allow = 0x20, Deny = 0x40, Ask = 0x60,
  StatusMask = 0xe0
}
 

Signals

void authViolation (QTransportAuth::Data &)
 
void policyCheck (QTransportAuth::Data &, const QString &)
 
- Signals inherited from QObject
void destroyed (QObject *=0)
 This signal is emitted immediately before the object obj is destroyed, and can not be blocked. More...
 

Public Functions

QAuthDeviceauthBuf (QTransportAuth::Data *, QIODevice *)
 Return a QIODevice pointer (to an internal QBuffer) which can be used to write data onto, for authorization on transport d. More...
 
bool authFromMessage (QTransportAuth::Data &d, const char *msg, int msgLen)
 Check authorization on the msg, which must be of size msgLen, for the transport d. More...
 
bool authorizeRequest (QTransportAuth::Data &d, const QString &request)
 
bool authToMessage (QTransportAuth::Data &d, char *hdr, const char *msg, int msgLen)
 Add authentication header to the beginning of a message. More...
 
QTransportAuth::DataconnectTransport (unsigned char, int)
 Record a new transport connection with properties and descriptor. More...
 
const unsigned char * getClientKey (unsigned char progId)
 
QMutexgetKeyFileMutex ()
 
void invalidateClientKeyCache ()
 
bool isDiscoveryMode () const
 
QString keyFilePath () const
 
QString logFilePath () const
 
QIODevicepassThroughByClient (QWSClient *) const
 
QAuthDevicerecvBuf (QTransportAuth::Data *, QIODevice *)
 Return a QIODevice pointer (to an internal QBuffer) which can be used to receive data after authorization on transport d. More...
 
void registerPolicyReceiver (QObject *)
 Register pr as a policy handler object. More...
 
void setKeyFilePath (const QString &)
 Set the full path to the key file. More...
 
void setLogFilePath (const QString &)
 
void setPackageRegistry (QObject *registry)
 
void setProcessKey (const char *)
 Set the process key for this currently running Qt Extended process to the authdata. More...
 
void setProcessKey (const char *, const char *)
 Apply key as the process key for the currently running application. More...
 
void unregisterPolicyReceiver (QObject *)
 Unregister the pr from being a policy handler. More...
 
- Public Functions inherited from QObject
bool blockSignals (bool b)
 If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke anything connected to it). More...
 
const QObjectListchildren () const
 Returns a list of child objects. More...
 
bool connect (const QObject *sender, const char *signal, const char *member, Qt::ConnectionType type=Qt::AutoConnection) const
 
bool disconnect (const char *signal=0, const QObject *receiver=0, const char *member=0)
 
bool disconnect (const QObject *receiver, const char *member=0)
 
void dumpObjectInfo ()
 Dumps information about signal connections, etc. More...
 
void dumpObjectTree ()
 Dumps a tree of children to the debug output. More...
 
QList< QByteArraydynamicPropertyNames () const
 Returns the names of all properties that were dynamically added to the object using setProperty(). More...
 
virtual bool event (QEvent *)
 This virtual function receives events to an object and should return true if the event e was recognized and processed. More...
 
virtual bool eventFilter (QObject *, QEvent *)
 Filters events if this object has been installed as an event filter for the watched object. More...
 
template<typename T >
findChild (const QString &aName=QString()) const
 Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. More...
 
template<typename T >
QList< T > findChildren (const QString &aName=QString()) const
 Returns all children of this object with the given name that can be cast to type T, or an empty list if there are no such objects. More...
 
template<typename T >
QList< T > findChildren (const QRegExp &re) const
 
bool inherits (const char *classname) const
 Returns true if this object is an instance of a class that inherits className or a QObject subclass that inherits className; otherwise returns false. More...
 
void installEventFilter (QObject *)
 Installs an event filter filterObj on this object. More...
 
bool isWidgetType () const
 Returns true if the object is a widget; otherwise returns false. More...
 
void killTimer (int id)
 Kills the timer with timer identifier, id. More...
 
virtual const QMetaObjectmetaObject () const
 Returns a pointer to the meta-object of this object. More...
 
void moveToThread (QThread *thread)
 Changes the thread affinity for this object and its children. More...
 
QString objectName () const
 
QObjectparent () const
 Returns a pointer to the parent object. More...
 
QVariant property (const char *name) const
 Returns the value of the object's name property. More...
 
Q_INVOKABLE QObject (QObject *parent=0)
 Constructs an object with parent object parent. More...
 
void removeEventFilter (QObject *)
 Removes an event filter object obj from this object. More...
 
void setObjectName (const QString &name)
 
void setParent (QObject *)
 Makes the object a child of parent. More...
 
bool setProperty (const char *name, const QVariant &value)
 Sets the value of the object's name property to value. More...
 
void setUserData (uint id, QObjectUserData *data)
 
bool signalsBlocked () const
 Returns true if signals are blocked; otherwise returns false. More...
 
int startTimer (int interval)
 Starts a timer and returns a timer identifier, or returns zero if it could not start a timer. More...
 
QThreadthread () const
 Returns the thread in which the object lives. More...
 
QObjectUserDatauserData (uint id) const
 
virtual ~QObject ()
 Destroys the object, deleting all its child objects. More...
 

Static Public Functions

static const char * errorString (const QTransportAuth::Data &)
 
static QTransportAuthgetInstance ()
 Return a pointer to the instance of this process's QTransportAuth object. More...
 
- Static Public Functions inherited from QObject
static bool connect (const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
 Creates a connection of the given type from the signal in the sender object to the method in the receiver object. More...
 
static bool connect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type=Qt::AutoConnection)
 
static bool disconnect (const QObject *sender, const char *signal, const QObject *receiver, const char *member)
 Disconnects signal in object sender from method in object receiver. More...
 
static bool disconnect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &member)
 
static uint registerUserData ()
 
static QString tr (const char *sourceText, const char *comment=0, int n=-1)
 
static QString trUtf8 (const char *sourceText, const char *comment=0, int n=-1)
 

Private Slots

void bufferDestroyed (QObject *)
 

Private Functions

 QTransportAuth ()
 
 ~QTransportAuth ()
 

Friends

class QAuthDevice
 

Additional Inherited Members

- Public Slots inherited from QObject
void deleteLater ()
 Schedules this object for deletion. More...
 
- Static Public Variables inherited from QObject
static const QMetaObject staticMetaObject
 This variable stores the meta-object for the class. More...
 
- Protected Functions inherited from QObject
virtual void childEvent (QChildEvent *)
 This event handler can be reimplemented in a subclass to receive child events. More...
 
virtual void connectNotify (const char *signal)
 This virtual function is called when something has been connected to signal in this object. More...
 
virtual void customEvent (QEvent *)
 This event handler can be reimplemented in a subclass to receive custom events. More...
 
virtual void disconnectNotify (const char *signal)
 This virtual function is called when something has been disconnected from signal in this object. More...
 
 QObject (QObjectPrivate &dd, QObject *parent=0)
 
int receivers (const char *signal) const
 Returns the number of receivers connected to the signal. More...
 
QObjectsender () const
 Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; otherwise it returns 0. More...
 
int senderSignalIndex () const
 
virtual void timerEvent (QTimerEvent *)
 This event handler can be reimplemented in a subclass to receive timer events for the object. More...
 
- Protected Variables inherited from QObject
QScopedPointer< QObjectDatad_ptr
 
- Static Protected Variables inherited from QObject
static const QMetaObject staticQtMetaObject
 

Detailed Description

Authenticate a message transport.

Warning
This function is not part of the public interface.

For performance reasons, message authentication is tied to an individual message transport instance. For example in connection oriented transports the authentication cookie can be cached against the connection avoiding the overhead of authentication on every message.

For each process there is one instance of the QTransportAuth object. For server processes it can determine the SXE Program Identity and provide access to policy data to determine if the message should be forwarded for action. If not actioned, the message may be treated as being from a flawed or malicious process.

Retrieve the instance with the getInstance() method. The constructor is disabled and instances of QTransportAuth should never be constructed by calling classes.

To make the Authentication easier to use a proxied QIODevice is provided which uses an internal QBuffer.

In the server code first get a pointer to a QTransportAuth::Data object using the connectTransport() method:

Here it is asserted that the transport is trusted. See the assumptions listed in the SXE documentation

Then proxy in the authentication device:

// mySocket can be any QIODevice subclass
AuthDevice *ad = a->recvBuf( d, mySocket );
// proxy in the auth device where the socket would have gone
connect( ad, SIGNAL(readyRead()), this, SLOT(mySocketReadyRead()));

In the client code it is similar. Use the connectTransport() method just the same then proxy in the authentication device instead of the socket in write calls:

AuthDevice *ad = a->authBuf( d, mySocket );
ad->write( someData );

Definition at line 69 of file qtransportauth_qws.h.

Enumerations

◆ Properties

Enumerator
Trusted 
Connection 
UnixStreamSock 
SharedMemory 
MessageQueue 
UDP 
TCP 
UserDefined 
TransportType 

Definition at line 96 of file qtransportauth_qws.h.

◆ Result

Enumerator
Pending 
TooSmall 
CacheMiss 
NoMagic 
NoSuchKey 
FailMatch 
OutOfDate 
Success 
ErrMask 
Allow 
Deny 
Ask 
StatusMask 

Definition at line 75 of file qtransportauth_qws.h.

75  {
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  };

Constructors and Destructors

◆ QTransportAuth()

QTransportAuth::QTransportAuth ( )
private
Warning
This function is not part of the public interface. Construct a new QTransportAuth

Definition at line 198 of file qtransportauth_qws.cpp.

199 {
200  // qDebug( "creating transport auth" );
201 }
Q_INVOKABLE QObject(QObject *parent=0)
Constructs an object with parent object parent.
Definition: qobject.cpp:753

◆ ~QTransportAuth()

QTransportAuth::~QTransportAuth ( )
private
Warning
This function is not part of the public interface. Destructor

Definition at line 207 of file qtransportauth_qws.cpp.

208 {
209  // qDebug( "deleting transport auth" );
210 }

Functions

◆ authBuf()

QAuthDevice * QTransportAuth::authBuf ( QTransportAuth::Data data,
QIODevice iod 
)

Return a QIODevice pointer (to an internal QBuffer) which can be used to write data onto, for authorization on transport d.

The return QIODevice will act as a pass-through.

The data written to the return QIODevice will be forwarded on to the returned QIODevice. In the case of a QTcpSocket, this will cause it to send out the data with the authentication information on it.

This will be called in the client process to generate outgoing authenticated requests.

The returned QIODevice will take ownership of data which will be deleted when the QIODevice is delected.

See also
setTargetDevice()

Definition at line 493 of file qtransportauth_qws.cpp.

Referenced by QWSDisplay::Data::init(), and QWSDisplay::Data::reinit().

494 {
495  return new QAuthDevice( iod, data, QAuthDevice::Send );
496 }
friend class QAuthDevice

◆ authFromMessage()

bool QTransportAuth::authFromMessage ( QTransportAuth::Data d,
const char *  msg,
int  msgLen 
)

Check authorization on the msg, which must be of size msgLen, for the transport d.

If able to determine authorization, return the program identity of the message source in the reference progId, and return true.

Otherwise return false.

If data is being received on a socket, it may be that more data is yet needed before authentication can proceed.

Also the message may not be an authenticated at all.

In these cases the method returns false to indicate authorization could not be determined:

  • The message is too small to carry the authentication data (status TooSmall is set on the d transport )
  • The 4 magic bytes are missing from the message start (status NoMagic is set on the d transport )
  • The message is too small to carry the auth + claimed payload (status TooSmall is set on the d transport )

If however the authentication header (preceded by the magic bytes) and any authenticated payload is received the method will determine the authentication status, and return true.

In the following cases as well as returning true it will also emit an authViolation():

  • If the program id claimed by the message is not found in the key file (status NoSuchKey is set on the d transport )
  • The authentication token failed against the claimed program id:
    • in the case of trusted transports, the secret did not match
    • in the case of untrusted transports the HMAC code did not match
    (status FailMatch is set on the d transport )

In these cases the authViolation( QTransportAuth::Data d ) signal is emitted and the error string can be obtained from the status like this:

Definition at line 1294 of file qtransportauth_qws.cpp.

1295 {
1296  if ( msgLen < QSXE_MAGIC_BYTES )
1297  {
1299  return false;
1300  }
1301  // if no magic bytes, exit straight away
1302  int m;
1303  const unsigned char *mptr = reinterpret_cast<const unsigned char *>(msg);
1304  for ( m = 0; m < QSXE_MAGIC_BYTES; ++m )
1305  {
1306  if ( *mptr++ != magic[m] )
1307  {
1309  return false;
1310  }
1311  }
1312 
1313  if ( msgLen < AUTH_SPACE(1) )
1314  {
1316  return false;
1317  }
1318 
1319  // At this point we know the header is at least long enough to contain valid auth
1320  // data, however the data may be spoofed. If it is not verified then the status will
1321  // be set to uncertified so the spoofed data will not be relied on. However we want to
1322  // know the program id which is being reported (even if it might be spoofed) for
1323  // policy debugging purposes. So set it here, rather than after verification.
1324  d.progId = msg[QSXE_PROG_IDX];
1325 
1326 #ifdef QTRANSPORTAUTH_DEBUG
1327  char authhdr[QSXE_HEADER_LEN*2+1];
1328  hexstring( authhdr, reinterpret_cast<const unsigned char *>(msg), QSXE_HEADER_LEN );
1329  qDebug( "%d SERVER authFromMessage(): message header is %s",
1330  getpid(), authhdr );
1331 #endif
1332 
1333  unsigned char authLen = (unsigned char)(msg[ QSXE_LEN_IDX ]);
1334 
1335  if ( msgLen < AUTH_SPACE(authLen) )
1336  {
1338  return false;
1339  }
1340 
1341  bool isCached = d_func()->keyCache.contains( d.progId );
1342  const unsigned char *clientKey = d_func()->getClientKey( d.progId );
1343  if ( clientKey == NULL )
1344  {
1346  return false;
1347  }
1348 
1349 #ifdef QTRANSPORTAUTH_DEBUG
1350  char keydisplay[QSXE_KEY_LEN*2+1];
1351  hexstring( keydisplay, clientKey, QSXE_KEY_LEN );
1352  qDebug( "\t\tauthFromMessage(): message %s against prog id %u and key %s\n",
1353  AUTH_DATA(msg), ((unsigned int)d.progId), keydisplay );
1354 #endif
1355 
1356  const unsigned char *auth_tok;
1357  unsigned char digest[QSXE_KEY_LEN];
1358  bool multi_tok = false;
1359 
1360  bool need_to_recheck=false;
1361  do
1362  {
1363  if ( !d.trusted())
1364  {
1365  hmac_md5( AUTH_DATA(msg), authLen, clientKey, QSXE_KEY_LEN, digest );
1366  auth_tok = digest;
1367  }
1368  else
1369  {
1370  auth_tok = clientKey;
1371  multi_tok = true; // 1 or more keys are in the clientKey
1372  }
1373  while( true )
1374  {
1375  if ( memcmp( auth_tok, magic, QSXE_MAGIC_BYTES ) == 0
1376  && memcmp( auth_tok + QSXE_MAGIC_BYTES, magic, QSXE_MAGIC_BYTES ) == 0 )
1377  break;
1378  if ( memcmp( msg + QSXE_KEY_IDX, auth_tok, QSXE_KEY_LEN ) == 0 )
1379  {
1381  return true;
1382  }
1383  if ( !multi_tok )
1384  break;
1385  auth_tok += QSXE_KEY_LEN;
1386  }
1387  //the keys cached on d.progId may not contain the binary key because the cache entry was made
1388  //before the binary had first started, must search for client key again.
1389  if ( isCached )
1390  {
1391  d_func()->keyCache.remove(d.progId);
1392  isCached = false;
1393 
1394 #ifdef QTRANSPORTAUTH_DEBUG
1395  qDebug() << "QTransportAuth::authFromMessage(): key not found in set of keys cached"
1396  << "against prog Id =" << d.progId << ". Re-obtaining client key. ";
1397 #endif
1398  clientKey = d_func()->getClientKey( d.progId );
1399  if ( clientKey == NULL )
1400  {
1402  return false;
1403  }
1404  need_to_recheck = true;
1405  }
1406  else
1407  {
1408  need_to_recheck = false;
1409  }
1410  } while( need_to_recheck );
1411 
1413  qWarning() << "QTransportAuth::authFromMessage():failed authentication";
1415  emit authViolation( d );
1416  return false;
1417 }
const unsigned char magic[QSXE_MAGIC_BYTES]
#define QSXE_KEY_IDX
#define AUTH_SPACE(x)
#define QSXE_KEY_LEN
#define QSXE_PROG_IDX
Q_CORE_EXPORT void qDebug(const char *,...)
bool trusted() const
Is the transport trusted.
#define AUTH_DATA(x)
static FAREnforcer * getInstance()
#define emit
Definition: qobjectdefs.h:76
Q_CORE_EXPORT void qWarning(const char *,...)
void logAuthAttempt(QDateTime time=QDateTime::currentDateTime())
#define QSXE_LEN_IDX
#define QSXE_HEADER_LEN
void authViolation(QTransportAuth::Data &)
static QDateTime currentDateTime()
Returns the current datetime, as reported by the system clock, in the local time zone.
Definition: qdatetime.cpp:3138
#define QSXE_MAGIC_BYTES
static int hmac_md5(unsigned char *text, int text_length, const unsigned char *key, int key_length, unsigned char *digest)

◆ authorizeRequest()

bool QTransportAuth::authorizeRequest ( QTransportAuth::Data d,
const QString request 
)

Definition at line 534 of file qtransportauth_qws.cpp.

Referenced by QAuthDevice::authorizeMessage(), and QAuthDevice::recvReadyRead().

535 {
536  bool isAuthorized = true;
537 
538  if ( !request.isEmpty() && request != QLatin1String("Unknown") )
539  {
540  d.status &= QTransportAuth::ErrMask; // clear the status
541  emit policyCheck( d, request );
542  isAuthorized = (( d.status & QTransportAuth::StatusMask ) == QTransportAuth::Allow );
543  }
544 #if defined(SXE_DISCOVERY)
545  if (isDiscoveryMode()) {
546 #ifndef QT_NO_TEXTSTREAM
547  if (!logFilePath().isEmpty()) {
548  QFile log( logFilePath() );
549  if (!log.open(QIODevice::WriteOnly | QIODevice::Append)) {
550  qWarning("Could not write to log in discovery mode: %s",
552  } else {
553  QTextStream ts( &log );
554  ts << d.progId << '\t' << ( isAuthorized ? "Allow" : "Deny" ) << '\t' << request << endl;
555  }
556  }
557 #endif
558  isAuthorized = true;
559  }
560 #endif
561  if ( !isAuthorized )
562  {
563  qWarning( "%s - denied: for Program Id %u [PID %d]"
564  , qPrintable(request), d.progId, d.processId );
565 
566  char linkTarget[BUF_SIZE]="";
567  char exeLink[BUF_SIZE]="";
568  char cmdlinePath[BUF_SIZE]="";
569  char cmdline[BUF_SIZE]="";
570 
571  //get executable from /proc/pid/exe
572  snprintf( exeLink, BUF_SIZE, "/proc/%d/exe", d.processId );
573  if ( -1 == ::readlink( exeLink, linkTarget, BUF_SIZE - 1 ) )
574  {
575  qWarning( "SXE:- Error encountered in retrieving executable link target from /proc/%u/exe : %s",
576  d.processId, strerror(errno) );
577  snprintf( linkTarget, BUF_SIZE, "%s", linkTarget );
578  }
579 
580  //get cmdline from proc/pid/cmdline
581  snprintf( cmdlinePath, BUF_SIZE, "/proc/%d/cmdline", d.processId );
582  int cmdlineFd = QT_OPEN( cmdlinePath, O_RDONLY );
583  if ( cmdlineFd == -1 )
584  {
585  qWarning( "SXE:- Error encountered in opening /proc/%u/cmdline: %s",
586  d.processId, strerror(errno) );
587  snprintf( cmdline, BUF_SIZE, "%s", "Unknown" );
588  }
589  else
590  {
591  if ( -1 == QT_READ(cmdlineFd, cmdline, BUF_SIZE - 1 ) )
592  {
593  qWarning( "SXE:- Error encountered in reading /proc/%u/cmdline : %s",
594  d.processId, strerror(errno) );
595  snprintf( cmdline, BUF_SIZE, "%s", "Unknown" );
596  }
597  QT_CLOSE( cmdlineFd );
598  }
599 
600  syslog( LOG_ERR | LOG_LOCAL6, "%s // PID:%u // ProgId:%u // Exe:%s // Request:%s // Cmdline:%s",
601  "<SXE Breach>", d.processId, d.progId, linkTarget, qPrintable(request), cmdline);
602  }
603 
604  return isAuthorized;
605 }
#define BUF_SIZE
void policyCheck(QTransportAuth::Data &, const QString &)
#define O_RDONLY
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
#define QT_READ
Definition: qcore_unix_p.h:280
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define emit
Definition: qobjectdefs.h:76
Q_CORE_EXPORT void qWarning(const char *,...)
#define QT_OPEN
Definition: qcore_unix_p.h:186
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
The QTextStream class provides a convenient interface for reading and writing text.
Definition: qtextstream.h:73
QString logFilePath() const
#define qPrintable(string)
Definition: qglobal.h:1750
int errno
#define QT_CLOSE
Definition: qcore_unix_p.h:304
bool isDiscoveryMode() const
Q_CORE_EXPORT QTextStream & endl(QTextStream &s)

◆ authToMessage()

bool QTransportAuth::authToMessage ( QTransportAuth::Data d,
char *  hdr,
const char *  msg,
int  msgLen 
)

Add authentication header to the beginning of a message.

Note that the per-process auth cookie is used.

Warning
This function is not part of the public interface. This key should be rewritten in the binary image of the executable at install time to make it unique.

For this to be secure some mechanism (eg MAC kernel or other permissions) must prevent other processes from reading the key.

The buffer must have AUTH_SPACE(0) bytes spare at the beginning for the authentication header to be added.

Returns true if header successfully added. Will fail if the per-process key has not yet been set with setProcessKey()

Definition at line 1199 of file qtransportauth_qws.cpp.

1200 {
1201  // qDebug( "authToMessage(): prog id %u", d.progId );
1202  // only authorize connection oriented transports once, unless key has changed
1204  d_func()->authKey.progId == d.progId )
1205  return false;
1206  d.progId = d_func()->authKey.progId;
1207  // If Unix socket credentials are being used the key wont be set
1208  if ( !d_func()->keyInitialised )
1209  return false;
1210  unsigned char digest[QSXE_KEY_LEN];
1211  char *msgPtr = hdr;
1212  // magic always goes on the beginning
1213  for ( int m = 0; m < QSXE_MAGIC_BYTES; ++m )
1214  *msgPtr++ = magic[m];
1215  hdr[ QSXE_LEN_IDX ] = (unsigned char)msgLen;
1216  if ( !d.trusted())
1217  {
1218  // Use HMAC
1219  int rc = hmac_md5( (unsigned char *)msg, msgLen, d_func()->authKey.key, QSXE_KEY_LEN, digest );
1220  if ( rc == -1 )
1221  return false;
1222  memcpy( hdr + QSXE_KEY_IDX, digest, QSXE_KEY_LEN );
1223  }
1224  else
1225  {
1226  memcpy( hdr + QSXE_KEY_IDX, d_func()->authKey.key, QSXE_KEY_LEN );
1227  }
1228 
1229  hdr[ QSXE_PROG_IDX ] = d_func()->authKey.progId;
1230 
1231 #ifdef QTRANSPORTAUTH_DEBUG
1232  char keydisplay[QSXE_KEY_LEN*2+1];
1233  hexstring( keydisplay, d_func()->authKey.key, QSXE_KEY_LEN );
1234 
1235  qDebug( "%d CLIENT Auth to message %s against prog id %u and key %s\n",
1236  getpid(), msg, d_func()->authKey.progId, keydisplay );
1237 #endif
1238 
1239  // TODO implement sequence to prevent replay attack, not required
1240  // for trusted transports
1241  hdr[ QSXE_SEQ_IDX ] = 1; // dummy sequence
1242 
1244  return true;
1245 }
const unsigned char magic[QSXE_MAGIC_BYTES]
#define QSXE_KEY_IDX
#define QSXE_KEY_LEN
#define QSXE_PROG_IDX
Q_CORE_EXPORT void qDebug(const char *,...)
bool trusted() const
Is the transport trusted.
#define QSXE_SEQ_IDX
#define QSXE_LEN_IDX
#define QSXE_MAGIC_BYTES
bool connection() const
Is the transport connection oriented.
static int hmac_md5(unsigned char *text, int text_length, const unsigned char *key, int key_length, unsigned char *digest)

◆ authViolation

void QTransportAuth::authViolation ( QTransportAuth::Data )
signal

◆ bufferDestroyed

void QTransportAuth::bufferDestroyed ( QObject cli)
privateslot

Definition at line 521 of file qtransportauth_qws.cpp.

522 {
524  if ( cli == NULL ) return;
525 
526  if ( d->buffersByClient.contains( cli ))
527  {
528  d->buffersByClient.remove( cli );
529  // qDebug( "@@@@@@@ client %p removed @@@@@@@@@", cli );
530  }
531  // qDebug( " client count %d", d->buffersByClient.count() );
532 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ connectTransport()

QTransportAuth::Data * QTransportAuth::connectTransport ( unsigned char  properties,
int  descriptor 
)

Record a new transport connection with properties and descriptor.

The calling code is responsible for destroying the returned data when the tranport connection is closed.

Definition at line 288 of file qtransportauth_qws.cpp.

Referenced by QWSServerPrivate::_q_newConnection(), QWSDisplay::Data::init(), and QWSDisplay::Data::reinit().

289 {
290  Data *data = new Data(properties, descriptor);
291  data->status = Pending;
292  return data;
293 }
static const char * data(const QByteArray &arr)
static const QCssKnownValue properties[NumProperties - 1]
Definition: qcssparser.cpp:67

◆ errorString()

const char * QTransportAuth::errorString ( const QTransportAuth::Data d)
static

Definition at line 157 of file qtransportauth_qws.cpp.

158 {
159  if (( d.status & ErrMask ) == Success )
160  return "success";
161  int e = d.status & ErrMask;
162  if ( e > OutOfDate )
163  return "unknown";
164  return errorStrings[e];
165 }
const char *const errorStrings[]

◆ getClientKey()

const unsigned char * QTransportAuth::getClientKey ( unsigned char  progId)

Definition at line 498 of file qtransportauth_qws.cpp.

499 {
501  return d->getClientKey( progId );
502 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ getInstance()

QTransportAuth * QTransportAuth::getInstance ( )
static

Return a pointer to the instance of this process's QTransportAuth object.

Definition at line 359 of file qtransportauth_qws.cpp.

Referenced by QWSServerPrivate::_q_newConnection(), QAuthDevice::authorizeMessage(), QWSDisplay::Data::init(), FAREnforcer::logAuthAttempt(), qws_write_command(), QWSClient::readMoreCommand(), QAuthDevice::recvReadyRead(), QWSDisplay::Data::reinit(), QAuthDevice::setClient(), and QAuthDevice::writeData().

360 {
361  static QTransportAuth theInstance;
362 
363  return &theInstance;
364 }
Authenticate a message transport.

◆ getKeyFileMutex()

QMutex * QTransportAuth::getKeyFileMutex ( )

Definition at line 510 of file qtransportauth_qws.cpp.

511 {
513  return &d->keyfileMutex;
514 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ invalidateClientKeyCache()

void QTransportAuth::invalidateClientKeyCache ( )

Definition at line 504 of file qtransportauth_qws.cpp.

505 {
507  d->invalidateClientKeyCache();
508 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ isDiscoveryMode()

bool QTransportAuth::isDiscoveryMode ( ) const

Definition at line 405 of file qtransportauth_qws.cpp.

Referenced by authorizeRequest(), and FAREnforcer::logAuthAttempt().

406 {
407 #if defined(SXE_DISCOVERY)
408  static bool checked = false;
409  static bool yesItIs = false;
410 
411  if ( checked ) return yesItIs;
412 
413  yesItIs = ( getenv( "SXE_DISCOVERY_MODE" ) != 0 );
414  if ( yesItIs )
415  {
416  qWarning("SXE Discovery mode on, ALLOWING ALL requests and logging to %s",
419  }
420  checked = true;
421  return yesItIs;
422 #else
423  return false;
424 #endif
425 }
Q_CORE_EXPORT void qWarning(const char *,...)
QString logFilePath() const
bool remove()
Removes the file specified by fileName().
Definition: qfile.cpp:715
#define qPrintable(string)
Definition: qglobal.h:1750

◆ keyFilePath()

QString QTransportAuth::keyFilePath ( ) const

Definition at line 381 of file qtransportauth_qws.cpp.

382 {
383  Q_D(const QTransportAuth);
384  return d->m_keyFilePath;
385 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ logFilePath()

QString QTransportAuth::logFilePath ( ) const

Definition at line 393 of file qtransportauth_qws.cpp.

Referenced by authorizeRequest(), isDiscoveryMode(), and FAREnforcer::logAuthAttempt().

394 {
395  Q_D(const QTransportAuth);
396  return d->m_logFilePath;
397 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ passThroughByClient()

QIODevice * QTransportAuth::passThroughByClient ( QWSClient client) const
Warning
This function is not part of the public interface. Return the authorizer device mapped to this client. Note that this could probably all be void* instead of QWSClient* for generality. Until the need for that rears its head its QWSClient* to save the casts.

OK the need has arrived, but the public API is frozen.

Definition at line 435 of file qtransportauth_qws.cpp.

Referenced by qws_write_command(), and QWSClient::readMoreCommand().

436 {
437  Q_D(const QTransportAuth);
438 
439  if ( client == 0 ) return 0;
440  if ( d->buffersByClient.contains( client ))
441  {
442  return d->buffersByClient[client];
443  }
444  // qWarning( "buffer not found for client %p", client );
445  return 0;
446 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ policyCheck

void QTransportAuth::policyCheck ( QTransportAuth::Data ,
const QString  
)
signal

◆ recvBuf()

QAuthDevice * QTransportAuth::recvBuf ( QTransportAuth::Data data,
QIODevice iod 
)

Return a QIODevice pointer (to an internal QBuffer) which can be used to receive data after authorization on transport d.

Warning
This function is not part of the public interface.

The return QIODevice will act as a pass-through.

The data will be consumed from iod and forwarded on to the returned QIODevice which can be connected to readyRead() signal handlers in place of the original QIODevice iod.

This will be called in the server process to handle incoming authenticated requests.

The returned QIODevice will take ownership of data which will be deleted when the QIODevice is delected.

See also
setTargetDevice()

Definition at line 470 of file qtransportauth_qws.cpp.

Referenced by QWSServerPrivate::_q_newConnection().

471 {
472  return new QAuthDevice( iod, data, QAuthDevice::Receive );
473 }
friend class QAuthDevice

◆ registerPolicyReceiver()

void QTransportAuth::registerPolicyReceiver ( QObject pr)

Register pr as a policy handler object.

The object pointed to by pr should have a slot as follows

All requests received by this server will then generate a call to this slot, and may be processed for policy compliance.

Definition at line 262 of file qtransportauth_qws.cpp.

263 {
264  // not every policy receiver needs setup - no error if this fails
265  QMetaObject::invokeMethod( pr, "setupPolicyCheck" );
266 
269 }
void policyCheck(QTransportAuth::Data &, const QString &)
#define SLOT(a)
Definition: qobjectdefs.h:226
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define SIGNAL(a)
Definition: qobjectdefs.h:227
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ setKeyFilePath()

void QTransportAuth::setKeyFilePath ( const QString path)

Set the full path to the key file.

Since this is normally relative to Qtopia::qpeDir() this needs to be set within the Qt Extended framework.

The keyfile should be protected by file permissions or by MAC rules such that it can only be read/written by the "qpe" server process

Definition at line 375 of file qtransportauth_qws.cpp.

376 {
378  d->m_keyFilePath = path;
379 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ setLogFilePath()

void QTransportAuth::setLogFilePath ( const QString path)

Definition at line 387 of file qtransportauth_qws.cpp.

388 {
390  d->m_logFilePath = path;
391 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ setPackageRegistry()

void QTransportAuth::setPackageRegistry ( QObject registry)

Definition at line 399 of file qtransportauth_qws.cpp.

400 {
402  d->m_packageRegistry = registry;
403 }
double d
Definition: qnumeric_p.h:62
#define Q_D(Class)
Definition: qglobal.h:2482
Authenticate a message transport.

◆ setProcessKey() [1/2]

void QTransportAuth::setProcessKey ( const char *  authdata)

Set the process key for this currently running Qt Extended process to the authdata.

authdata should be sizeof(struct AuthCookie) in length and contain the key and program id. Use this method when setting or changing the SXE identity of the current program.

Definition at line 218 of file qtransportauth_qws.cpp.

Referenced by setProcessKey().

219 {
221  ::memcpy(&d->authKey, authdata, sizeof(struct AuthCookie));
222  QFile proc_key( QLatin1String("/proc/self/lids_key") );
223  // where proc key exists use that instead
224  if ( proc_key.open( QIODevice::ReadOnly ))
225  {
226  qint64 kb = proc_key.read( (char*)&d->authKey.key, QSXE_KEY_LEN );
227 #ifdef QTRANSPORTAUTH_DEBUG
228  qDebug( "Using %li bytes of /proc/%i/lids_key\n", (long int)kb, getpid() );
229 #else
230  Q_UNUSED( kb );
231 #endif
232  }
233  d->keyInitialised = true;
234 }
double d
Definition: qnumeric_p.h:62
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
#define QSXE_KEY_LEN
#define Q_D(Class)
Definition: qglobal.h:2482
Q_CORE_EXPORT void qDebug(const char *,...)
__int64 qint64
Definition: qglobal.h:942
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
Authenticate a message transport.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729

◆ setProcessKey() [2/2]

void QTransportAuth::setProcessKey ( const char *  key,
const char *  prog 
)

Apply key as the process key for the currently running application.

prog is current ignored

Deprecated function

Definition at line 244 of file qtransportauth_qws.cpp.

245 {
246  Q_UNUSED(prog);
247  setProcessKey( key );
248 #ifdef QTRANSPORTAUTH_DEBUG
249  char displaybuf[QSXE_KEY_LEN*2+1];
250  hexstring( displaybuf, (const unsigned char *)key, QSXE_KEY_LEN );
251  qDebug() << "key" << displaybuf << "set";
252 #endif
253 }
#define QSXE_KEY_LEN
Q_CORE_EXPORT void qDebug(const char *,...)
void setProcessKey(const char *)
Set the process key for this currently running Qt Extended process to the authdata.
int key
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729

◆ unregisterPolicyReceiver()

void QTransportAuth::unregisterPolicyReceiver ( QObject pr)

Unregister the pr from being a policy handler.

No more policyCheck signals are received by this object.

Definition at line 275 of file qtransportauth_qws.cpp.

276 {
277  disconnect( pr );
278  // not every policy receiver needs tear down - no error if this fails
279  QMetaObject::invokeMethod( pr, "teardownPolicyCheck" );
280 }
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

Friends and Related Functions

◆ QAuthDevice

friend class QAuthDevice
friend

Definition at line 171 of file qtransportauth_qws.h.

Referenced by authBuf(), and recvBuf().


The documentation for this class was generated from the following files: