⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtransportauth_qws.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    Q_D(QTransportAuth);    d->m_logFilePath = path;}QString QTransportAuth::logFilePath() const{    Q_D(const QTransportAuth);    return d->m_logFilePath;}void QTransportAuth::setPackageRegistry( QObject *registry ){    Q_D(QTransportAuth);    d->m_packageRegistry = registry;}bool QTransportAuth::isDiscoveryMode() const{#if defined(SXE_DISCOVERY)    static bool checked = false;    static bool yesItIs = false;    if ( checked ) return yesItIs;    yesItIs = ( getenv( "SXE_DISCOVERY_MODE" ) != 0 );    if ( yesItIs )    {        qWarning("SXE Discovery mode on, ALLOWING ALL requests and logging to %s",                 qPrintable(logFilePath()));        QFile::remove( logFilePath() );    }    checked = true;    return yesItIs;#else    return false;#endif}/*!  \internal  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.*/QIODevice *QTransportAuth::passThroughByClient( QWSClient *client ) const{    Q_D(const QTransportAuth);    if ( client == 0 ) return 0;    if ( d->buffersByClient.contains( client ))    {        return d->buffersByClient[client];    }    // qWarning( "buffer not found for client %p", client );    return 0;}/*!  \internal  Return a QIODevice pointer (to an internal QBuffer) which can be used  to receive data after authorisation on transport \a d.  The return QIODevice will act as a pass-through.  The data will be consumed from \a iod and forwarded on to the returned  QIODevice which can be connected to readyRead() signal handlers in  place of the original QIODevice \a iod.  This will be called in the server process to handle incoming  authenticated requests.  The returned QIODevice will take ownership of \a data which will be deleted  when the QIODevice is delected.  \sa setTargetDevice()*/QAuthDevice *QTransportAuth::recvBuf( QTransportAuth::Data *data, QIODevice *iod ){    return new QAuthDevice( iod, data, QAuthDevice::Receive );}/*!  Return a QIODevice pointer (to an internal QBuffer) which can be used  to write data onto, for authorisation on transport \a 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 \a data which will be deleted  when the QIODevice is delected.  \sa setTargetDevice()*/QAuthDevice *QTransportAuth::authBuf( QTransportAuth::Data *data, QIODevice *iod ){    return new QAuthDevice( iod, data, QAuthDevice::Send );}const unsigned char *QTransportAuth::getClientKey( unsigned char progId ){    Q_D(QTransportAuth);    return d->getClientKey( progId );}void QTransportAuth::invalidateClientKeyCache(){    Q_D(QTransportAuth);    d->invalidateClientKeyCache();}QMutex *QTransportAuth::getKeyFileMutex(){    Q_D(QTransportAuth);    return &d->keyfileMutex;}/*   \internal   Respond to the destroyed(QObject*) signal of the QAuthDevice's   client object and remove it from the buffersByClient lookup hash.*/void QTransportAuth::bufferDestroyed( QObject *cli ){    Q_D(QTransportAuth);    if ( cli == NULL ) return;    if ( d->buffersByClient.contains( cli ))    {        d->buffersByClient.remove( cli );        // qDebug( "@@@@@@@ client %p removed @@@@@@@@@", cli );    }    // qDebug( "           client count %d", d->buffersByClient.count() );}bool QTransportAuth::authorizeRequest( QTransportAuth::Data &d, const QString &request ){    bool isAuthorized = true;    if ( !request.isEmpty() && request != "Unknown" )    {        d.status &= QTransportAuth::ErrMask;  // clear the status        emit policyCheck( d, request );        isAuthorized = (( d.status & QTransportAuth::StatusMask ) == QTransportAuth::Allow );    }#if defined(SXE_DISCOVERY)    if (isDiscoveryMode()) {#ifndef QT_NO_TEXTSTREAM        if (!logFilePath().isEmpty()) {            QFile log( logFilePath() );            if (!log.open(QIODevice::WriteOnly | QIODevice::Append)) {                qWarning("Could not write to log in discovery mode: %s",                         qPrintable(logFilePath()));            } else {                QTextStream ts( &log );                ts << d.progId << '\t' << ( isAuthorized ? "Allow" : "Deny" ) << '\t' << request << endl;            }        }#endif        isAuthorized = true;    }#endif    if ( !isAuthorized )    {        qWarning( "%s - denied: for Program Id %u [PID %d]"                , qPrintable(request), d.progId, d.processId );        char linkTarget[BUF_SIZE]="";        char exeLink[BUF_SIZE]="";        char cmdlinePath[BUF_SIZE]="";        char cmdline[BUF_SIZE]="";                //get executable from /proc/pid/exe        snprintf( exeLink, BUF_SIZE, "/proc/%d/exe", d.processId );        if ( -1 == ::readlink( exeLink, linkTarget, BUF_SIZE - 1 ) )         {            qWarning( "SXE:- Error encountered in retrieving executable link target from /proc/%u/exe : %s",                 d.processId, strerror(errno) );            snprintf( linkTarget, BUF_SIZE, "%s", linkTarget );        }        //get cmdline from proc/pid/cmdline        snprintf( cmdlinePath, BUF_SIZE, "/proc/%d/cmdline", d.processId );        int  cmdlineFd = open( cmdlinePath, O_RDONLY );         if ( cmdlineFd == -1 )        {            qWarning( "SXE:- Error encountered in opening /proc/%u/cmdline: %s",                d.processId, strerror(errno) );            snprintf( cmdline, BUF_SIZE, "%s", "Unknown" );        }        else        {            if ( -1 == ::read(cmdlineFd, cmdline, BUF_SIZE - 1 ) )            {                qWarning( "SXE:- Error encountered in reading /proc/%u/cmdline : %s",                    d.processId, strerror(errno) );                snprintf( cmdline, BUF_SIZE, "%s", "Unknown" );            }            close( cmdlineFd );        }                syslog( LOG_ERR | LOG_LOCAL6, "%s // PID:%u // ProgId:%u // Exe:%s // Request:%s // Cmdline:%s",                "<SXE Breach>", d.processId, d.progId, linkTarget, qPrintable(request), cmdline);    }    return isAuthorized;}inline bool __fileOpen( QFile *f ){#ifdef QTRANSPORTAUTH_DEBUG    if ( f->open( QIODevice::ReadOnly ))    {        qDebug( "Opened file: %s\n", qPrintable( f->fileName() ));        return true;    }    else    {        qWarning( "Could not open file: %s\n", qPrintable( f->fileName() ));        return false;    }#else    return ( f->open( QIODevice::ReadOnly ));#endif}/*!  \internal  Find client keys for the \a progId.  If it is cached should be very  fast, otherwise requires a read of the secret key file  In the success case a pointer to the keys is returned.  The pointer is  to storage allocated for the internal cache and must be used asap.  The list returned is a sequence of one or more keys which match the  progId.  There is no separator, each 16 byte sequence represents a key.  The sequence is followed by two iterations of the SXE magic  bytes,eg  0xBA, 0xD4, 0xD4, 0xBA, 0xBA, 0xD4, 0xD4, 0xBA  NULL is returned in the following cases:  \list    \o the keyfiles could not be accessed - error condition    \o there was no key for the supplied program id - key auth failed  \endlist  Note that for the keyfiles, there is multi-thread and multi-process  concurrency issues: they can be read by the qpe process when  QTransportAuth calls getClientKey to verify a request, and they can be  read or written by the packagemanager when updating package data.  To protect against this, the keyfileMutex & SxeRegistryLocker is used.  The sxe_installer tool can also update inode and device numbers in  the manifest file, but this only occurs outside of normal operation,  so qpe and packagemanager are never running when this occurs.*/const unsigned char *QTransportAuthPrivate::getClientKey(unsigned char progId){    int manifestMatchCount = 0;    struct IdBlock mr;    struct usr_key_entry kr;    int total_size = 0;    char *result = 0;    char *result_ptr;    int keysFound = 0;    bool foundKey;    int keysRead = 0;    struct usr_key_entry keys_list[128];    if ( keyCache.contains( progId ))        return (const unsigned char *)keyCache[progId];    SxeRegistryLocker rlock( m_packageRegistry );    // This is hacky - fix in 4.3 - see documentation for setKeyFilePath    QString manifestPath = m_keyFilePath + QLatin1String( "/manifest" );    QString actualKeyPath( "/proc/lids/keys" );    bool noFailOnKeyMissing = true;    if ( !QFile::exists( actualKeyPath ))    {        actualKeyPath = m_keyFilePath + QLatin1String( "/" QSXE_KEYFILE );        noFailOnKeyMissing = false;    }    QFile kf( actualKeyPath );    QFile mn( manifestPath );    if ( !__fileOpen( &mn ))        goto key_not_found;    // first find how much storage is needed    while ( mn.read( (char*)&mr, sizeof(struct IdBlock)) != 0 )        if ( mr.progId == progId )            manifestMatchCount++;    if ( manifestMatchCount == 0 )        goto key_not_found;    if ( !__fileOpen( &kf ))    {        noFailOnKeyMissing = false;        goto key_not_found;    }    total_size = 2 * QSXE_MAGIC_BYTES + manifestMatchCount * QSXE_KEY_LEN;    result = (char*)malloc( total_size );    Q_CHECK_PTR( result );    mn.seek( 0 );    result_ptr = result;    /* reading whole key array in is much more efficient, 99% case is this loop only       executes once, should not have more than 128 keyed items */    while (( keysRead = kf.read( (char*)keys_list, sizeof(struct usr_key_entry)*128 )) != 0 )    {        /* qDebug("PID %d: getClientKey() - read %d bytes = %d keys from %s", getpid(), keysRead,                keysRead/sizeof(struct usr_key_entry), qPrintable(actualKeyPath)); */        keysRead /= sizeof(struct usr_key_entry);        while ( mn.read( (char*)&mr, sizeof(struct IdBlock)) != 0 )        {            if ( mr.progId == progId )            {                foundKey = false;                for ( int i = 0; i < keysRead; ++i )                {                    /* if ( i == 0 )                        qDebug() << "         pid" << getpid() << "looking for device"  << (dev_t)mr.device << "inode" << (ino_t)mr.inode;                    qDebug() << "         pid" << getpid() << "trying device" <<  keys_list[i].dev << "inode" <<  keys_list[i].ino; */                    if ( keys_list[i].ino == (ino_t)mr.inode && keys_list[i].dev == (dev_t)mr.device )                    {                        memcpy( result_ptr, keys_list[i].key, QSXE_KEY_LEN );                        result_ptr += QSXE_KEY_LEN;                        foundKey = true;                        break;                    }                }                if ( foundKey )                {                    keysFound++;                    if ( keysFound == manifestMatchCount )                        break;                }            }        }    }    if ( result_ptr == result ) // nothing found!        goto key_not_found;    // 2 x magic bytes sentinel at end of sequence    for ( int i = 0; i < 2; ++i )        for ( int j = 0; j < QSXE_MAGIC_BYTES; ++j )            *result_ptr++ = magic[j];    keyCache.insert( progId, result, total_size / 10 );    /* qDebug( "PID %d : Found %d client keys for prog %u", getpid(), keysFound, progId ); */    goto success_out;key_not_found:    if ( noFailOnKeyMissing )  // return an "empty" set of keys in this case    {        if ( result == 0 )        {            result = (char*)malloc( 2 * QSXE_MAGIC_BYTES );            Q_CHECK_PTR( result );        }        result_ptr = result;        for ( int i = 0; i < 2; ++i )            for ( int j = 0; j < QSXE_MAGIC_BYTES; ++j )                *result_ptr++ = magic[j];        return (unsigned char *)result;    }    qWarning( "PID %d : Not found client key for prog %u", getpid(), progId );    if ( result )    {        free( result );        result = 0;    }success_out:    if ( mn.isOpen() )        mn.close();    if ( kf.isOpen() )        kf.close();    return (unsigned char *)result;}void QTransportAuthPrivate::invalidateClientKeyCache(){    keyfileMutex.lock();    keyCache.clear();    keyfileMutex.unlock();}////////////////////////////////////////////////////////////////////////////////  RequestAnalyzer definition////RequestAnalyzer::RequestAnalyzer()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -