From c5c46660130456afea285e460be44e1c723e4a49 Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Tue, 5 Oct 2010 15:07:43 +0200 Subject: Refactor InputEvent handler code. - Make static methods virtual and store instances in the chains. - Propagate security context information. - Saner security policy implementation. --- src/input/inputHandlerChain.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/input/inputHandlerChain.h (limited to 'src/input/inputHandlerChain.h') diff --git a/src/input/inputHandlerChain.h b/src/input/inputHandlerChain.h new file mode 100644 index 0000000..4bb9fe5 --- /dev/null +++ b/src/input/inputHandlerChain.h @@ -0,0 +1,34 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # inputHandlerChain.h: + # - Definition of the input handler chain + # -------------------------------------------------------------------------- + */ + +#ifndef INPUTHANDLERCHAIN_H_ +#define INPUTHANDLERCHAIN_H_ + +#include +#include "inputEventHandler.h" + +#include "x11FakeKeyboardHandler.h" +#include "x11FakeMouseHandler.h" + +typedef boost::mpl::list< + Handler >, + Handler >, + Handler > +>::type unprivileged_handler_list; + +typedef InputEventHandlerChain unprivileged_handler_chain; + +#endif /* INPUTHANDLERCHAIN_H_ */ -- cgit v1.2.3-55-g7522 From ac05f7d367ae9983e7996738871efbdbf3ec66e8 Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Tue, 5 Oct 2010 15:30:04 +0200 Subject: Implement privileged input daemon, first version without handlers. --- src/input/CMakeLists.txt | 45 ++++++- src/input/inputHandlerChain.h | 8 +- src/input/privilegedHandlerForwarder.cpp | 82 +++++++++++++ src/input/privilegedHandlerForwarder.h | 32 +++++ src/input/pvsPrivInputHandler.cpp | 108 +++++++++++++++++ src/input/pvsPrivInputHandler.h | 45 +++++++ src/input/pvsPrivInputSocket.cpp | 196 +++++++++++++++++++++++++++++++ src/input/pvsPrivInputSocket.h | 31 +++++ src/input/pvsprivinputd.cpp | 147 +++++++++++++++++++++++ 9 files changed, 687 insertions(+), 7 deletions(-) create mode 100644 src/input/privilegedHandlerForwarder.cpp create mode 100644 src/input/privilegedHandlerForwarder.h create mode 100644 src/input/pvsPrivInputHandler.cpp create mode 100644 src/input/pvsPrivInputHandler.h create mode 100644 src/input/pvsPrivInputSocket.cpp create mode 100644 src/input/pvsPrivInputSocket.h create mode 100644 src/input/pvsprivinputd.cpp (limited to 'src/input/inputHandlerChain.h') diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt index aa52ec3..5f009c5 100644 --- a/src/input/CMakeLists.txt +++ b/src/input/CMakeLists.txt @@ -2,18 +2,51 @@ INCLUDE(${QT_USE_FILE}) SET(pvsinput_SRCS inputEvent.cpp + inputEventHandler.cpp ) + +if(UNIX) + set(pvsprivinputd_SRCS + pvsprivinputd.cpp + pvsPrivInputHandler.cpp + pvsCheckPrivileges.cpp + ) + + set(pvsprivinputd_MOC_HDRS + pvsPrivInputHandler.h + ) -IF(UNIX) - list(APPEND pvsinput_SRCS - x11InputUtils.cpp + qt4_wrap_cpp(pvsprivinputd_MOC_SRCS + ${pvsprivinputd_MOC_HDRS} + ) + + add_executable(pvsprivinputd + ${pvsprivinputd_SRCS} + ${pvsprivinputd_MOC_SRCS} + ) + + set_property(SOURCE ${pvsprivinputd_SRCS} ${pvsprivinputd_MOC_SRCS} + APPEND + PROPERTY COMPILE_FLAGS " -I${QT_QTCORE_INCLUDE_DIR} -I${QT_QTDBUS_INCLUDE_DIR} -I${QT_QTNETWORK_INCLUDE_DIR}") + + target_link_libraries(pvsprivinputd + pvsinput + ${QT_QTCORE_LIBRARY} + ${QT_QTDBUS_LIBRARY} + ${QT_QTNETWORK_LIBRARY} + ) + + list(APPEND pvsinput_SRCS + pvsPrivInputSocket.cpp + x11InputUtils.cpp x11FakeKeyboardHandler.cpp - x11FakeMouseHandler.cpp) -ENDIF() + x11FakeMouseHandler.cpp + privilegedHandlerForwarder.cpp + ) +endif() ADD_LIBRARY( pvsinput STATIC - ${pvsinput_HDRS} ${pvsinput_SRCS} ) diff --git a/src/input/inputHandlerChain.h b/src/input/inputHandlerChain.h index 4bb9fe5..61c3d62 100644 --- a/src/input/inputHandlerChain.h +++ b/src/input/inputHandlerChain.h @@ -22,13 +22,19 @@ #include "x11FakeKeyboardHandler.h" #include "x11FakeMouseHandler.h" +#include "privilegedHandlerForwarder.h" typedef boost::mpl::list< Handler >, Handler >, - Handler > + Handler >, + Handler >::type unprivileged_handler_list; typedef InputEventHandlerChain unprivileged_handler_chain; +typedef boost::mpl::list< +>::type privileged_handler_list; + +typedef InputEventHandlerChain privileged_handler_chain; #endif /* INPUTHANDLERCHAIN_H_ */ diff --git a/src/input/privilegedHandlerForwarder.cpp b/src/input/privilegedHandlerForwarder.cpp new file mode 100644 index 0000000..3c0b3bd --- /dev/null +++ b/src/input/privilegedHandlerForwarder.cpp @@ -0,0 +1,82 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # inputHandlerChain.cpp: + # - Forward privileged input events to a special handler process - implementation + # -------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pvsPrivInputSocket.h" +#include "privilegedHandlerForwarder.h" + +using namespace std; + +#ifndef UNIX_PATH_MAX +# define UNIX_PATH_MAX 108 /* according to unix(7) */ +#endif + +void PrivilegedHandlerForwarder::initialize() +{ + QSettings settings(QSettings::NativeFormat, QSettings::SystemScope, "openslx", "pvsinputd"); + + QString defaultPath = "/tmp/pvsprivinputd.sock"; + QByteArray socketPath = settings.value("socketpath", defaultPath).toString().toLocal8Bit(); + + _socket = pvsPrivInputMakeClientSocket(); + if(_socket < 0) + { + return; + } +} + +void PrivilegedHandlerForwarder::handle(InputEvent const& evt, InputEventContext const*) +{ + qDebug("Trying to handle %s in PrivilegedHandlerForwarder", evt.toString().c_str()); + if(_socket < 0) + { + initialize(); + } + + QByteArray data; + QDataStream strm(&data, QIODevice::WriteOnly); + strm.setByteOrder(QDataStream::BigEndian); + strm << evt; + + assert(data.size() == 8); + + int delta = 0; + int count = 0; + do { + delta = write(_socket, data.constData(), data.size()); + if(delta < 0) + { + qWarning("Error while communicating with pvsprivinputd: %s", strerror(errno)); + close(_socket); + + // Try again: + initialize(); + } + else if(delta != 8) + { + // This should normally not happen. + qWarning("Could not send a complete packet. Only %d bytes sent", delta); + } + count++; + } while(delta != 8 && count < 3); +} diff --git a/src/input/privilegedHandlerForwarder.h b/src/input/privilegedHandlerForwarder.h new file mode 100644 index 0000000..37e8f24 --- /dev/null +++ b/src/input/privilegedHandlerForwarder.h @@ -0,0 +1,32 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # inputHandlerChain.h: + # - Forward privileged input events to a special handler process. + # -------------------------------------------------------------------------- + */ + +#ifndef PRIVILEGEDHANDLERFORWARDER_H_ +#define PRIVILEGEDHANDLERFORWARDER_H_ + +#include "inputEventHandler.h" + +class PrivilegedHandlerForwarder : public DefaultInputEventHandler +{ +public: + void handle(InputEvent const& evt, InputEventContext const* = 0); + void initialize(); + +private: + int _socket; +}; + +#endif /* PRIVILEGEDHANDLERFORWARDER_H_ */ diff --git a/src/input/pvsPrivInputHandler.cpp b/src/input/pvsPrivInputHandler.cpp new file mode 100644 index 0000000..70ed1bc --- /dev/null +++ b/src/input/pvsPrivInputHandler.cpp @@ -0,0 +1,108 @@ +/* + # 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 "inputEventHandler.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 getSenderPid() const + { + return _pid; + } + + uid_t getSenderUid() const + { + return _uid; + } + + gid_t getSenderGid() 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())); +} + +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)) + { + 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); +} diff --git a/src/input/pvsPrivInputHandler.h b/src/input/pvsPrivInputHandler.h new file mode 100644 index 0000000..9980cdf --- /dev/null +++ b/src/input/pvsPrivInputHandler.h @@ -0,0 +1,45 @@ +/* + # 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 - interface + # -------------------------------------------------------------------------- + */ + +#ifndef PVSPRIVINPUTHANDLER_H_ +#define PVSPRIVINPUTHANDLER_H_ + +#include +#include +#include +#include "inputHandlerChain.h" + +class QSocketNotifier; + +class PVSPrivInputHandler : public QObject +{ + Q_OBJECT +public: + PVSPrivInputHandler(int fd, QObject* parent = 0); + virtual ~PVSPrivInputHandler(); + +private slots: + void canRead(); + +private: + QSocketNotifier* _notifier; + QByteArray _messageAssembly; + int _bytes; + int _fd; + privileged_handler_chain _handlerChain; +}; + +#endif /* PVSPRIVINPUTHANDLER_H_ */ diff --git a/src/input/pvsPrivInputSocket.cpp b/src/input/pvsPrivInputSocket.cpp new file mode 100644 index 0000000..2428582 --- /dev/null +++ b/src/input/pvsPrivInputSocket.cpp @@ -0,0 +1,196 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # pvsPrivInputSocket.h: + # - Centralize knowledge of socket address and connection options + # for pvsprivinputd - implementation + # -------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include "pvsPrivInputSocket.h" + +using namespace std; + +#ifndef UNIX_PATH_MAX +# define UNIX_PATH_MAX 108 /* according to unix(7) */ +#endif + +QString pvsPrivInputGetSocketAddress() +{ + QSettings settings(QSettings::NativeFormat, QSettings::SystemScope, "openslx", "pvsprivinputd"); + return settings.value("socketpath", "/tmp/pvsprivinputd.sock").toString(); +} + +int pvsPrivInputMakeClientSocket() +{ + int sock = socket(AF_UNIX, SOCK_DGRAM, 0); + if(sock < 0) + { + qWarning("Could not create a socket: %s", strerror(errno)); + return -1; + } + + QByteArray socketPath = pvsPrivInputGetSocketAddress().toLocal8Bit(); + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socketPath.constData(), UNIX_PATH_MAX - 1); + if(connect(sock, reinterpret_cast(&addr), + sizeof(addr)) < 0) + { + qWarning("Could not connect to pvsprivinputd at %s: %s", socketPath.constData(), strerror(errno)); + close(sock); + return -1; + } + + return sock; +} + +int pvsPrivInputMakeServerSocket() +{ + int sock = socket(AF_UNIX, SOCK_DGRAM, 0); + if(sock < 0) + { + qCritical("Could not create a socket: %s", strerror(errno)); + return -1; + } + + // Bind to the address: + QByteArray socketPath = pvsPrivInputGetSocketAddress().toLocal8Bit(); + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socketPath.constData(), UNIX_PATH_MAX - 1); + if(bind(sock, reinterpret_cast(&addr), sizeof(addr)) < 0) + { + qCritical("Could not bind socket to %s", strerror(errno)); + close(sock); + return -1; + } + + // Announce that credentials are requested: + int passcred = 1; + if(setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &passcred, sizeof(passcred)) < 0) + { + // We will not operate without credentials. + qCritical("Could not request peer credentials: %s", strerror(errno)); + close(sock); + return -1; + } + +#if 0 /* Only for SOCK_STREAM: */ + // Listen for connections: + if(listen(sock, 1) < 0) + { + qCritical("Could not listen for connections to %s: %s", socketPath.constData(), strerror(errno)); + close(sock); + return -1; + } +#endif + + return sock; +} + +bool pvsPrivInputSendMessage(int sock, void* buf, size_t _len, int* err) +{ + /* + * Portability note: All UNIX-like systems can transmit credentials over UNIX + * sockets, but only Linux does it automagically. + */ + + long len = (long)_len; + + // send(2) does not split messages on a SOCK_DGRAM socket. + int e = send(sock, buf, len, 0); + if(e < 0) + { + qWarning("Failed to send message of length %d over socket %d: %s", (unsigned)len, e, strerror(errno)); + if(err) + *err = errno; + return false; + } + else if(e < len) + { + qWarning("Failed to send a complete message of length %d over socket %d, only %d bytes were sent", (unsigned)len, sock, e); + if(err) + *err = errno; + return false; + } + + return true; +} + +bool pvsPrivInputRecvMessage(int sock, void* buf, size_t& len, + pid_t& pid, uid_t& uid, gid_t& gid, int* err) +{ + struct iovec iov; + struct msghdr msg; + char ctlbuf[1024]; + iov.iov_base = buf; + iov.iov_len = len; + msg.msg_name = 0; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &ctlbuf; + msg.msg_controllen = sizeof(ctlbuf); + msg.msg_flags = 0; + int bytes_read = recvmsg(sock, &msg, 0); + if(bytes_read < 0) + { + qWarning("Could not read from socket: %s", strerror(errno)); + if(err) + *err = errno; + return false; + } + + pid = -1; + uid = -1; + gid = -1; + + struct cmsghdr* cmsg; + for(cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if(cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) + { + struct ucred* creds = reinterpret_cast(CMSG_DATA(cmsg)); + pid = creds->pid; + uid = creds->uid; + gid = creds->gid; + break; + } + else if(cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) + { + // We need to close passed file descriptors. If we don't, we + // have a denial-of-service vulnerability. + int* fds = reinterpret_cast(CMSG_DATA(cmsg)); + unsigned num_fds = cmsg->cmsg_len / sizeof(int); + for(unsigned i = 0; i < num_fds; i++) + { + close(fds[i]); + } + } + } + + if(pid == (pid_t)-1 || uid == (uid_t)-1 || gid == (gid_t)-1) + { + *err = 0; + return false; + } + + return true; +} diff --git a/src/input/pvsPrivInputSocket.h b/src/input/pvsPrivInputSocket.h new file mode 100644 index 0000000..e6fb0c0 --- /dev/null +++ b/src/input/pvsPrivInputSocket.h @@ -0,0 +1,31 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # pvsPrivInputSocket.h: + # - Centralize knowledge of socket address and connection options + # for pvsprivinputd - interface + # -------------------------------------------------------------------------- + */ + +#ifndef PVSPRIVINPUTSOCKET_H_ +#define PVSPRIVINPUTSOCKET_H_ + +#include +#include +#include + +QString pvsPrivInputGetSocketAddress(); +int pvsPrivInputMakeClientSocket(); +int pvsPrivInputMakeServerSocket(); +bool pvsPrivInputSendMessage(int sock, void* buf, size_t len, int* err = 0); +bool pvsPrivInputRecvMessage(int sock, void* buf, size_t& len, pid_t& pid, uid_t& uid, gid_t& gid, int* err = 0); + +#endif /* PVSPRIVINPUTSOCKET_H_ */ diff --git a/src/input/pvsprivinputd.cpp b/src/input/pvsprivinputd.cpp new file mode 100644 index 0000000..3a5e1a8 --- /dev/null +++ b/src/input/pvsprivinputd.cpp @@ -0,0 +1,147 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # pvsprivinputd.cpp: + # - Handle privileged input events - daemon + # -------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pvsPrivInputSocket.h" +#include "pvsPrivInputHandler.h" + +using namespace std; + +#ifndef UNIX_PATH_MAX +# define UNIX_PATH_MAX 108 /* according to unix(7) */ +#endif + +QByteArray socketPath; +int sigintFds[2]; + +static void unlinkSocket() +{ + if(!socketPath.isNull()) + { + unlink(socketPath.constData()); + } +} + +static void onInterrupt(int) +{ + char buf[] = { '!' }; + char msg[] = "SIGINT caught. Quitting.\n"; + write(sigintFds[0], buf, 1); + write(1, msg, sizeof(msg)-1); +} + +int main(int argc, char** argv) +{ + QCoreApplication app(argc, argv); + app.setApplicationName("pvsprivinputd"); + app.setOrganizationName("openslx"); + + bool no_fork = app.arguments().contains("--no-fork", Qt::CaseInsensitive); + if(!no_fork) + { + pid_t pid; + pid_t sid; + + pid = fork(); + if(pid < 0) + { + qCritical("Could not fork: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + if(pid > 0) + { + exit(EXIT_SUCCESS); + } + + // We are now inside a child process. + // Detach from parent: + sid = setsid(); + if(sid < 0) + { + qCritical("Could not detach from parent process: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + // Change to some benign directory: + if(chdir("/") < 0) + { + qCritical("Could not change directory: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + } + + // Okay, we are running as a daemon. Defer reopening standard file descriptors + // so we can report errors. + + // Set the file creation mask to allow all processes to connect to + // the socket (access control is handled differently): + umask(0); + + // Ignore SIGPIPE. Connection errors are handled internally. + // According to signal(2), the only error is that the signal number + // is invalid. This cannot happen. + signal(SIGPIPE, SIG_IGN); + + // set up signal handling: + if(socketpair(AF_UNIX, SOCK_STREAM, 0, sigintFds) < 0) + { + qCritical("Could not set up signal handling. Giving up."); + exit(EXIT_FAILURE); + } + socketPath = pvsPrivInputGetSocketAddress().toLocal8Bit(); + QSocketNotifier sigintWatcher(sigintFds[1], QSocketNotifier::Read); + QObject::connect(&sigintWatcher, SIGNAL(activated(int)), &app, SLOT(quit())); + signal(SIGINT, onInterrupt); + + // Create our socket: + int sock = pvsPrivInputMakeServerSocket(); + if(sock < 0) + { + exit(EXIT_FAILURE); + } + + // Our setup is complete. + if(!no_fork) + { + // Reopen standard file descriptors: + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stderr); + freopen("/dev/null", "w", stdout); + } + + // Install our main object + PVSPrivInputHandler handler(sock); + + atexit(unlinkSocket); + + // and run the main loop. + int ret = app.exec(); + + return ret; +} -- cgit v1.2.3-55-g7522 From 9b8657b04122838e3149208789a004baaa3ba635 Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Tue, 5 Oct 2010 15:31:11 +0200 Subject: Implement example privileged SayHelloHandler. --- src/input/CMakeLists.txt | 1 + src/input/inputHandlerChain.h | 2 ++ src/input/sayHelloHandler.cpp | 25 +++++++++++++++++++++++++ src/input/sayHelloHandler.h | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 src/input/sayHelloHandler.cpp create mode 100644 src/input/sayHelloHandler.h (limited to 'src/input/inputHandlerChain.h') diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt index 5f009c5..4aaa845 100644 --- a/src/input/CMakeLists.txt +++ b/src/input/CMakeLists.txt @@ -10,6 +10,7 @@ if(UNIX) pvsprivinputd.cpp pvsPrivInputHandler.cpp pvsCheckPrivileges.cpp + sayHelloHandler.cpp ) set(pvsprivinputd_MOC_HDRS diff --git a/src/input/inputHandlerChain.h b/src/input/inputHandlerChain.h index 61c3d62..57168c2 100644 --- a/src/input/inputHandlerChain.h +++ b/src/input/inputHandlerChain.h @@ -23,6 +23,7 @@ #include "x11FakeKeyboardHandler.h" #include "x11FakeMouseHandler.h" #include "privilegedHandlerForwarder.h" +#include "sayHelloHandler.h" typedef boost::mpl::list< Handler >, @@ -34,6 +35,7 @@ typedef boost::mpl::list< typedef InputEventHandlerChain unprivileged_handler_chain; typedef boost::mpl::list< + Handler >::type privileged_handler_list; typedef InputEventHandlerChain privileged_handler_chain; diff --git a/src/input/sayHelloHandler.cpp b/src/input/sayHelloHandler.cpp new file mode 100644 index 0000000..fc6f668 --- /dev/null +++ b/src/input/sayHelloHandler.cpp @@ -0,0 +1,25 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # rebootSystemHandler.h + # - Handle "say hello" requests - interface + # -------------------------------------------------------------------------- + */ + +#include "sayHelloHandler.h" +#include + +using namespace std; + +void SayHelloHandler::handle(InputEvent const&, InputEventContext const* ctx) +{ + cerr << "I'm right here! You sent this message from pid " << ctx->getSenderPid() << " as user " << ctx->getSenderUid() << " with gid " << ctx->getSenderGid() << endl; +} diff --git a/src/input/sayHelloHandler.h b/src/input/sayHelloHandler.h new file mode 100644 index 0000000..b0d4c7e --- /dev/null +++ b/src/input/sayHelloHandler.h @@ -0,0 +1,34 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # rebootSystemHandler.h + # - Handle "say hello" requests - interface + # -------------------------------------------------------------------------- + */ + +#ifndef SAYHELLOHANDLER_CPP_ +#define SAYHELLOHANDLER_CPP_ + +#include +#include "inputEventHandler.h" + +class SayHelloHandler : public DefaultInputEventHandler +{ +public: + void handle(InputEvent const&, InputEventContext const*); + + static void describeInto(QList& list) + { + list << SpecialInputEventDescription(tr(QT_TRANSLATE_NOOP("InputEventHandler", "Say Hello")), InputEvent::ET_SPECIAL, InputEvent::EC_SAY_HELLO); + } +}; + +#endif /* SAYHELLOHANDLER_CPP_ */ -- cgit v1.2.3-55-g7522 From 52585c14017d11c439d4962c1ec12f5b87cc93d6 Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Tue, 5 Oct 2010 15:34:12 +0200 Subject: Implement RebootSystem and KillX11 handlers. --- src/input/CMakeLists.txt | 2 + src/input/inputHandlerChain.h | 7 ++- src/input/killX11Handler.cpp | 89 +++++++++++++++++++++++++++++++++++++++ src/input/killX11Handler.h | 34 +++++++++++++++ src/input/rebootSystemHandler.cpp | 32 ++++++++++++++ src/input/rebootSystemHandler.h | 34 +++++++++++++++ 6 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/input/killX11Handler.cpp create mode 100644 src/input/killX11Handler.h create mode 100644 src/input/rebootSystemHandler.cpp create mode 100644 src/input/rebootSystemHandler.h (limited to 'src/input/inputHandlerChain.h') diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt index 4aaa845..311d8ce 100644 --- a/src/input/CMakeLists.txt +++ b/src/input/CMakeLists.txt @@ -10,6 +10,8 @@ if(UNIX) pvsprivinputd.cpp pvsPrivInputHandler.cpp pvsCheckPrivileges.cpp + rebootSystemHandler.cpp + killX11Handler.cpp sayHelloHandler.cpp ) diff --git a/src/input/inputHandlerChain.h b/src/input/inputHandlerChain.h index 57168c2..8bcb1d8 100644 --- a/src/input/inputHandlerChain.h +++ b/src/input/inputHandlerChain.h @@ -23,7 +23,9 @@ #include "x11FakeKeyboardHandler.h" #include "x11FakeMouseHandler.h" #include "privilegedHandlerForwarder.h" +#include "rebootSystemHandler.h" #include "sayHelloHandler.h" +#include "killX11Handler.h" typedef boost::mpl::list< Handler >, @@ -35,8 +37,11 @@ typedef boost::mpl::list< typedef InputEventHandlerChain unprivileged_handler_chain; typedef boost::mpl::list< - Handler + Handler, + Handler, policy::Security >, + Handler, policy::Security > >::type privileged_handler_list; typedef InputEventHandlerChain privileged_handler_chain; + #endif /* INPUTHANDLERCHAIN_H_ */ diff --git a/src/input/killX11Handler.cpp b/src/input/killX11Handler.cpp new file mode 100644 index 0000000..7ac75a1 --- /dev/null +++ b/src/input/killX11Handler.cpp @@ -0,0 +1,89 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # killX11Handler.h + # - Kill the X11 Server - implementation + # -------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include "pvsCheckPrivileges.h" +#include "killX11Handler.h" + +using namespace std; + +void KillX11Handler::handle(InputEvent const&, InputEventContext const* ctx) +{ + // Find out which display device is used: + QString displayDevice = PVSCheckPrivileges::instance()->getX11DisplayDevice(ctx); + QString displayDeviceAbs = QFileInfo(displayDevice).canonicalFilePath(); + + if(displayDevice.isNull()) + { + qWarning("Can not kill X server for %d,%d,%d: No Display Device", ctx->getSenderPid(), ctx->getSenderUid(), ctx->getSenderGid()); + return; + } + + QList pids; + + // Find all processes that have it opened: + QDir proc("/proc"); + QFileInfoList entries = proc.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach(QFileInfo fi, entries) + { + // We are only interested in numerical ids: + bool ok; + pid_t pid = fi.fileName().toUInt(&ok); + if(!ok) + continue; + + // We have a pid. Now check open files: + QDir fds(QString("/proc/%1/fd").arg(pid)); + qDebug("Searching for X server in %s", fds.absolutePath().toLocal8Bit().constData()); + QFileInfoList fdfiles = fds.entryInfoList(QDir::Files); + foreach(QFileInfo fdfile, fdfiles) + { + qDebug(" Looking for terminal in %s", fdfile.absoluteFilePath().toLocal8Bit().constData()); + QFileInfo fdTarget(fdfile.readLink()); + if(fdTarget.canonicalFilePath() == displayDeviceAbs) + { + qDebug(" ... found"); + pids << pid; + } + } + } + + // If everything is well, we have exactly one pid: + if(pids.size() != 1) + { + QStringList pidStrs; + foreach(pid_t pid, pids) + { + pidStrs << QString::number(pid); + } + + qWarning("Display device %s is open by multiple or zero processes (%s). We don't know which is X. Aborting.", + displayDeviceAbs.toLocal8Bit().constData(), + pidStrs.join(", ").toLocal8Bit().constData()); + return; + } + + // We found the PID for the X server. Now kill it. + QString exe = QFileInfo(QString("/proc/%1/exe").arg(pids[0])).readLink(); + qDebug("Killing X server, PID %d, exe name %s with SIGTERM", pids[0], exe.toLocal8Bit().constData()); + +// kill(pids[0], SIGTERM); +} diff --git a/src/input/killX11Handler.h b/src/input/killX11Handler.h new file mode 100644 index 0000000..2f3ef44 --- /dev/null +++ b/src/input/killX11Handler.h @@ -0,0 +1,34 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # killX11Handler.h + # - Kill the X11 Server - interface + # -------------------------------------------------------------------------- + */ + +#ifndef KILLX11HANDLER_H_ +#define KILLX11HANDLER_H_ + +#include +#include "inputEventHandler.h" + +class KillX11Handler : public DefaultInputEventHandler +{ +public: + void handle(InputEvent const&, InputEventContext const*); + + static void describeInto(QList& list) + { + list << SpecialInputEventDescription(tr(QT_TRANSLATE_NOOP("InputEventHandler", "Kill X Server")), InputEvent::ET_SPECIAL, InputEvent::EC_KILL_X); + } +}; + +#endif /* KILLX11HANDLER_H_ */ diff --git a/src/input/rebootSystemHandler.cpp b/src/input/rebootSystemHandler.cpp new file mode 100644 index 0000000..b5b8f8a --- /dev/null +++ b/src/input/rebootSystemHandler.cpp @@ -0,0 +1,32 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # rebootSystemHandler.cpp + # - Handle system reboot requests - implementation + # -------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include "rebootSystemHandler.h" + +using namespace std; + +void RebootLinuxSystemHandler::handle(InputEvent const& evt, InputEventContext const* ctx) +{ + // Rebooting a linux system is particulary easy: + if(kill(1, SIGINT) < 0) + { + qWarning("Could not kill /sbin/init: %s", strerror(errno)); + } +} diff --git a/src/input/rebootSystemHandler.h b/src/input/rebootSystemHandler.h new file mode 100644 index 0000000..34fa8ae --- /dev/null +++ b/src/input/rebootSystemHandler.h @@ -0,0 +1,34 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # rebootSystemHandler.h + # - Handle system reboot requests - interface + # -------------------------------------------------------------------------- + */ + +#ifndef REBOOTSYSTEMHANDLER_H_ +#define REBOOTSYSTEMHANDLER_H_ + +#include +#include "inputEventHandler.h" + +class RebootLinuxSystemHandler : public DefaultInputEventHandler +{ +public: + void handle(InputEvent const&, InputEventContext const*); + + static void describeInto(QList& list) + { + list << SpecialInputEventDescription(tr(QT_TRANSLATE_NOOP("InputEventHandler", "Reboot")), InputEvent::ET_SPECIAL, InputEvent::EC_REBOOT); + } +}; + +#endif /* REBOOTSYSTEMHANDLER_H_ */ -- cgit v1.2.3-55-g7522 From c5a99933202c91630edc2ddd97e0e964b27540d6 Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Wed, 6 Oct 2010 17:56:59 +0200 Subject: Sanitize security model yet again The flags model was not satisfactory since it made it unnecessarily difficult to express the standard policy of "allow all to users that are physically sitting in front of the machine and to privileged users". The new model expressly knows different policies (two at the moment) and refrains from decomposing them. Additional policies are not difficult to add. --- src/input/CMakeLists.txt | 2 +- src/input/inputEventHandler.h | 58 +++++++++++++++++++++++++++++++------------ src/input/inputHandlerChain.h | 10 ++++---- 3 files changed, 48 insertions(+), 22 deletions(-) (limited to 'src/input/inputHandlerChain.h') diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt index 398ca55..0e72c4c 100644 --- a/src/input/CMakeLists.txt +++ b/src/input/CMakeLists.txt @@ -2,7 +2,6 @@ include(${QT_USE_FILE}) set(pvsinput_SRCS inputEvent.cpp - inputEventHandler.cpp ) if(UNIX) @@ -23,6 +22,7 @@ if(UNIX) rebootSystemHandler.cpp killX11Handler.cpp sayHelloHandler.cpp + inputEventHandler.cpp ) set(pvsprivinputd_MOC_HDRS diff --git a/src/input/inputEventHandler.h b/src/input/inputEventHandler.h index 44713c2..52e3338 100644 --- a/src/input/inputEventHandler.h +++ b/src/input/inputEventHandler.h @@ -18,6 +18,7 @@ #define INPUTEVENTHANDLER_H_ #include +#include #include #include #include @@ -97,26 +98,33 @@ public: namespace policy { enum SecurityFlags { - SEC_PHYSICAL_SEAT = 1, - SEC_PRIVILEGED_USER = 2 + SEC_FREE_FOR_ALL, + SEC_PHYSICAL_OR_PRIVILEGED }; bool allowPhysicalSeat(InputEvent const& evt, InputEventContext const* ctx); bool allowPrivilegedUser(InputEvent const& evt, InputEventContext const* ctx); -template -struct Security +struct SecurityAllowAny { bool allow(InputEvent const& evt, InputEventContext const* ctx) { - if((flags & SEC_PHYSICAL_SEAT) && !allowPhysicalSeat(evt, ctx)) - return false; - if((flags & SEC_PRIVILEGED_USER) && !allowPrivilegedUser(evt, ctx)) - return false; return true; } }; +struct SecurityAllowPhysicalOrPrivileged +{ + bool allow(InputEvent const& evt, InputEventContext const* ctx) + { + if(allowPhysicalSeat(evt, ctx)) + return true; + else if(allowPrivilegedUser(evt, ctx)) + return true; + return false; + } +}; + struct UnixLike; struct Linux; struct Windows; @@ -154,6 +162,8 @@ public: bool handle(InputEvent const& evt, InputEventContext const* context = 0) { if(!securityPolicy.allow(evt, context)) { + std::string evtStr = evt.toString(); + qWarning("Input Event %s has been denied by security policy", evtStr.c_str()); return true; } if(delegate.matches(evt, context)) { @@ -196,19 +206,32 @@ public: } }; -template > +template struct Handler : public HandlerHelper { }; -template +template +struct ApplyDefaultSecurityPolicy +{ + typedef HandlerType type; +}; + +template +struct ApplyDefaultSecurityPolicy > +{ + typedef Handler type; +}; + +template struct InputEventHandlerChainHelper { private: typedef typename boost::mpl::next::type next_iterator_type; - typedef InputEventHandlerChainHelper next_in_chain; + typedef InputEventHandlerChainHelper next_in_chain; - typedef typename boost::mpl::deref::type handler_type; + typedef typename boost::mpl::deref::type handler_entry_type; + typedef typename ApplyDefaultSecurityPolicy::type handler_type; handler_type _handler; next_in_chain _next; @@ -239,8 +262,8 @@ public: } }; -template -struct InputEventHandlerChainHelper +template +struct InputEventHandlerChainHelper { void handle(InputEvent const&, InputEventContext const* context = 0) { // do nothing @@ -261,8 +284,11 @@ struct InputEventHandlerChainHelper } }; -template -struct InputEventHandlerChain : public InputEventHandlerChainHelper::type, typename boost::mpl::end::type> +template +struct InputEventHandlerChain : + public InputEventHandlerChainHelper::type, + typename boost::mpl::end::type> { }; diff --git a/src/input/inputHandlerChain.h b/src/input/inputHandlerChain.h index 8bcb1d8..b012aa6 100644 --- a/src/input/inputHandlerChain.h +++ b/src/input/inputHandlerChain.h @@ -34,14 +34,14 @@ typedef boost::mpl::list< Handler >::type unprivileged_handler_list; -typedef InputEventHandlerChain unprivileged_handler_chain; +typedef InputEventHandlerChain unprivileged_handler_chain; typedef boost::mpl::list< - Handler, - Handler, policy::Security >, - Handler, policy::Security > + Handler, + Handler >, + Handler > >::type privileged_handler_list; -typedef InputEventHandlerChain privileged_handler_chain; +typedef InputEventHandlerChain privileged_handler_chain; #endif /* INPUTHANDLERCHAIN_H_ */ -- cgit v1.2.3-55-g7522 From 32672a51fe8b8ccf63e1cfeb89ac5e020fde787a Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Wed, 6 Oct 2010 18:00:08 +0200 Subject: Implement magic SysRq handler. --- CMakeLists.txt | 1 + src/input/CMakeLists.txt | 1 + src/input/inputHandlerChain.h | 4 ++- src/input/magicSysRqHandler.cpp | 28 ++++++++++++++++ src/input/magicSysRqHandler.h | 72 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/input/magicSysRqHandler.cpp create mode 100644 src/input/magicSysRqHandler.h (limited to 'src/input/inputHandlerChain.h') diff --git a/CMakeLists.txt b/CMakeLists.txt index 85fb968..cc695ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ SET( PVSMGR_SRCS src/input/killX11Handler.h src/input/rebootSystemHandler.h src/input/sayHelloHandler.h + src/input/magicSysRqHandler.h ) # pvs diff --git a/src/input/CMakeLists.txt b/src/input/CMakeLists.txt index 0e72c4c..20fd531 100644 --- a/src/input/CMakeLists.txt +++ b/src/input/CMakeLists.txt @@ -21,6 +21,7 @@ if(UNIX) pvsPrivInputSignalHandler.cpp rebootSystemHandler.cpp killX11Handler.cpp + magicSysRqHandler.cpp sayHelloHandler.cpp inputEventHandler.cpp ) diff --git a/src/input/inputHandlerChain.h b/src/input/inputHandlerChain.h index b012aa6..3c9446c 100644 --- a/src/input/inputHandlerChain.h +++ b/src/input/inputHandlerChain.h @@ -26,6 +26,7 @@ #include "rebootSystemHandler.h" #include "sayHelloHandler.h" #include "killX11Handler.h" +#include "magicSysRqHandler.h" typedef boost::mpl::list< Handler >, @@ -39,7 +40,8 @@ typedef InputEventHandlerChain, Handler >, - Handler > + Handler >, + Handler > >::type privileged_handler_list; typedef InputEventHandlerChain privileged_handler_chain; diff --git a/src/input/magicSysRqHandler.cpp b/src/input/magicSysRqHandler.cpp new file mode 100644 index 0000000..108bfca --- /dev/null +++ b/src/input/magicSysRqHandler.cpp @@ -0,0 +1,28 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # inputEventHandler.h: + # - Common definitions for input event handlers + # -------------------------------------------------------------------------- + */ + +#include +#include "magicSysRqHandler.h" + +void MagicSysRqHandler::handle(InputEvent const& evt, InputEventContext const*) +{ + QFile trigger("/proc/sysrq-trigger"); + trigger.open(QIODevice::WriteOnly); + char c = (char)(evt.value() & 0xff); + trigger.write(&c, 1); + trigger.flush(); + trigger.close(); +} diff --git a/src/input/magicSysRqHandler.h b/src/input/magicSysRqHandler.h new file mode 100644 index 0000000..563d091 --- /dev/null +++ b/src/input/magicSysRqHandler.h @@ -0,0 +1,72 @@ +/* + # 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/ + # -------------------------------------------------------------------------- + # magicSysRqHandler.h + # - Trigger Magic-SysRq functions - interface + # -------------------------------------------------------------------------- + */ + +#ifndef MAGICSYSRQHANDLER_H_ +#define MAGICSYSRQHANDLER_H_ + +#include "inputEventHandler.h" + +class MagicSysRqHandler : public DefaultInputEventHandler +{ +public: + void handle(InputEvent const& evt, InputEventContext const* ctx); + + static void describeInto(QList& list) + { + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Reboot immediately"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'b'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Crash system"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'c'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Show all held logs"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'd'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Send SIGTERM to all"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'e'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Activate OOM killer"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'f'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Send SIGKILL to all"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'i'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Force thaw filesystems"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'j'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Kill all on terminal"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'k'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Show stack traces"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'l'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Dump memory info"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'm'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Make real-time tasks niceable"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'n'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Power off immediately"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'o'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Dump registers and flags"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'p'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Dump timers and clockevents"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'q'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Turn off raw keyboard mode"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'r'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Sync all mounted filesystems"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 's'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Dump task list"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 't'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Remount all read-only"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'u'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Dump uninterruptible tasks"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'w'); + list << SpecialInputEventDescription(QCoreApplication::translate("InputEventHandler", "Dump ftrace buffer"), + InputEvent::ET_SPECIAL, InputEvent::EC_SYSRQ, 'z'); + } +}; + +#endif /* MAGICSYSRQHANDLER_H_ */ -- cgit v1.2.3-55-g7522