/* # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg # # This program is free software distributed under the GPL version 2. # See http://openslx.org/COPYING # # If you have any feedback please consult http://openslx.org/feedback and # send your suggestions, praise, or complaints to feedback@openslx.org # # General information about OpenSLX can be found at http://openslx.org/ # -------------------------------------------------------------------------- # pvsPrivInputHandler.h # - Handle privileged input connection requests - implementation # -------------------------------------------------------------------------- */ #include #include #include #include #include #include #include "inputEvent.h" #include "inputHandlerChains.h" #include "pvsPrivInputSocket.h" #include "pvsPrivInputHandler.h" using namespace std; class PrivInputContext : public InputEventContext { public: PrivInputContext(pid_t pid, uid_t uid, gid_t gid) : _pid(pid), _uid(uid), _gid(gid) { } pid_t senderPid() const { return _pid; } uid_t senderUid() const { return _uid; } gid_t senderGid() const { return _gid; } private: pid_t _pid; uid_t _uid; gid_t _gid; }; PVSPrivInputHandler::PVSPrivInputHandler(int fd, QObject* parent) : QObject(parent) { _fd = fd; _notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); _notifier->setEnabled(true); connect(_notifier, SIGNAL(activated(int)), this, SLOT(canRead())); _handlerChain = makePrivilegedInputEventHandlerChain(); } PVSPrivInputHandler::~PVSPrivInputHandler() { delete _notifier; } void PVSPrivInputHandler::canRead() { _notifier->setEnabled(false); // We need to retrieve the credentials of the process: size_t siz = 8; _messageAssembly.clear(); _messageAssembly.resize(8); pid_t pid; uid_t uid; gid_t gid; int err; if(!pvsPrivInputRecvMessage(_fd, _messageAssembly.data(), siz, pid, uid, gid, &err)) { switch(err) { case EAGAIN: #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif // That's okay. Nothing to do. break; case 0: // We'll survive. There was no actual error, just the library routine // that decided it did not really want to receive that packet. break; default: qWarning("Something bad just happened, and cannot handle it. Panicking."); close(_fd); deleteLater(); return; } } else { if(siz != 8) { qWarning("Malformed PVS Input Event packet"); return; } QDataStream strm(&_messageAssembly, QIODevice::ReadOnly); InputEvent evt; strm.setByteOrder(QDataStream::BigEndian); strm >> evt; PrivInputContext ctx(pid, uid, gid); _handlerChain.handle(evt, &ctx); } _notifier->setEnabled(true); }