Remote Linux Idle time of local user - linux

I'm looking for a way to determine the local input (mouse/keyboard) idle time,
remotely through SSH, without having root access or access to the currently logged on user Xauthority.
I know the following solution which works if you have access to the X server:
detecting keyboard, mouse activity in linux
But is it possible without having to connect to the X server?
Is there another way? E.g. indirectly via CPU or memory usage of certain processes?
Any ideas welcome.

Using w and /dev solutions will only get you so far, since it could be that the user is around, but has not typed anything in the shell - for example, he/she could be playing some game. A better approach would be to poll /proc/interrupts. The local interrupts for the mouse and keyboard are often under "i8042" (though in some rare cases it might be different). You might want to try: "grep i8042 /proc/interrupts". This will yield IRQ 1 (keyboard) and IRQ 12 (usually, the mouse). You can get the values, store them, and then poll occasionally (no callback, alas), to get the counts. If the numbers changed, interrupts occurred - meaning keyboard (IRQ 1) or mouse (IRQ 12) were touched/pressed etc. Key presses generally generate two interrupts (key down, key up). Mouse movement is more erratic.
This has several advantages:
1) If the user so much as touches the mouse, or presses a key - you know
2) You can do so programmatically (i.e. fopen() /proc/interrupts , or (alternatively) /proc/stat, and get the "intr" line) and fread() the relevant lines
3) You don't even need to be root for this.

As an unprivileged, distinct user, I'd try to do this by monitoring for new processes spawned with the target user ID. If you see a new process, chances are it means the user caused it to be spawned, unless its parent is cron (or one of a handful of similar supervisors, you'll have to try it on your system and filter out the few false alarms you get at first).
This won't give you a very precise idle time, but perhaps a maximum bound. If you want something more precise, you probably ought to have privileges to do it.

The commands w and ls -l /dev/pts are the best ones I can think of. Between them, you can get a pretty good view of idleness on the linux console, ssh, and xterm sessions.
If the user is just sitting on a local thing playing with firefox or something, this won't catch it, but I'm not sure you can get that without access to X or being root. Looking for cpu usage isn't reliable because a lot of apps use a little cpu even when idle, or virtually zero when used, and watching /proc/x_server_pid/* doesn't help either, since X can still have activity even when the user is idle.
Looking for new processes like the other answer said is the best I can think of if /dev/pts doesn't help and you can't actually look at the input.

Related

Persistent prompt in Linux (not just shell)

I spent several decades using Digital Equipment Corporation's VMS operating system, and one of the things I really miss is the terminal driver's 'read-with-prompt' functionality.
It would display the prompt and position the cursor for input, as you'd expect, but the prompt was immune to things like CTRL/U, CTRL/R, and CTRL/W. It was an attribute of the read operation, and every time the terminal driver was ready to read from the terminal with this option, it would show the prompt. The user couldn't erase it, so if it went off the screen he'd still know what was being requested.
This is one of the few things that I think VMS did better than U*X -- unless there's a Linuxish way of doing this.
So far I've never found it, but maybe I'm just not looking in the right place.
Is there a way on Linux to read from a tty with a persistent prompt?
Thanks!

What is the tty subsystem for?

By now I have now spent at least 10 hours trying to get my head around the famous blog post by Linus Akesson, and Im still struggling. So let me ask my doubts about tty/ptty as a series of short questions.
1) Is the tty/ptty in user space or kernel space?
2) What is tty/ptty's connection to devices or drivers or some numbering or something?
3) The tty seems to be linked to something called the controlling terminal of a process, What is the relation and is every process related to a terminal?
4) On the whole I still dont understand where the heck this terminal concept fits in. A process wants to read something from the stdio, cant it simply do it from the required device file. What exactly is the problem that the tty intends to take care of?
5) I read somewhere that there are attempts to move the tty from the userspace to the kernel space. Is the tty simply a historical residue than a strong design feature.??
A clarification (which might answer some of your questions):
I think you meant pty (and not ptty) which is pseudo-tty/pseudo-terminal.
A tty (/dev/ttyx) - stands for teletype - is the original terminals (used a line printer for output and a keyboard for input!). A terminal is basically just a user interface device that uses text for input and output.
A pty (/dev/pty/n) is a pseudo-terminal - it's a software implementation that appears to the attached program like a terminal, but instead of communicating directly with a "real" terminal, it transfers the input and output to another program. It's the end point of telnet/SSH or even the GNOME terminal.
For example, when you ssh into a remote machine and run ls, the ls output is sent to a pseudo-terminal, the other side of which is attached to the SSH daemon.
EDIT:
As far as I know, the tty and so pty, are usermode. BUT they represent terminal-driver. What I mean is: the device file /dev/tty1 is the first virtual console. Most code lives in drivers/char, in the files tty_io.c and n_tty.c and vt.c (kernel source). In contrast to character devices in order to open those files tty_open routine is called, and trust me, it's way messier than opening a character device...
Tty/pty stands for terminal drivers mentioned above but they stands for serial ports (the"numbering" you said). I know very little about it so I don't want to say incorrect data... but you can search the net about it (or someone else can continue from here)
EDIT2:
You have changed the question so now it seems like I spoke out of context...
Anyway, tty has many different roles even nowday. Terminal driver is the way user-kernel can "communicate". There are some techniques such as terminal drivers, character device etc.
If you still have a question please comment and don't change the whole post....

Capturing Global Keyboard Events On Linux With NodeJS

I have a headless Debian ARM machine that I'm running Node on. The device has hard buttons that are mapped to normal keyboard events using gpio-keys.
My goal is to capture the global events from both the hard buttons as well as any attached keyboards in Node. I need a solution that can capture the keydown/keyup events independently of the terminal that it's run in (it will be run over an SSH session). It doesn't have to be cross-platform, as long as it works on ARM Debian I'll accept it.
I am imagining something reading directly from whatever sysfs attributes are necessary, but that's not a requirement.
Can anyone help me on this? I've been stuck for a while.
One of the device files /dev/input/event* will represent the gpio-keys device. You can figure out which one in a number of ways; one easy one is to look at the contents of the uevent file for the device, e.g. /sys/class/input/event0/device/uevent. It'll contain a number of useful key-value properties.
Once you've figured out which device you want, you can open and read from it. It'll return a stream of struct input_events, as defined in <linux/input.h>. These events will correspond to presses and releases for each of your buttons.
You may also want to take a look for existing solutions for at least part of the problem, such as node-keyboard: https://github.com/Bornholm/node-keyboard

Recover from OpenCL freeze in Linux

I am writing my first OpenCL kernels on an Ubuntu machine with an NVIDIA card. Once in a while, the application totally freezes the whole computer. The mouse does not move, and the only way to reboot is by force-pressing the power button.
I've realized that the reason for the freezes is that I accidentally read past the last index of a global, read-only float array. While this is something I don't intend to do often, it might still happen in the future.
My question is - is there any way to prevent the computer from completely shutting down if this happens again? I know that, for example, Windows can shut down bad GLSL kernels and recover with a graphics driver restart. Is something similar possible here?
You may not be able to completely recover but you can recover better using SysRq (sometimes called System Request or Magic SysRq). By executing a specific key combination you can have Linux reboot in some what of a sane way (killing processes and unmounting filesystems). This key sequence is described in detail at http://en.wikipedia.org/wiki/Magic_SysRq_key so I won't repeat it here.
In some cases you might be able to still SSH to the device. If this is your case you might be in more luck. If you can SSH there are a number of other options you can try such as: unloading/reloading the crashed module, restarting the xserver, or at least rebooting the normal way.
Although I'm not an expert on "HURD" I believe it was designed to handle this type of condition better. The only other solution I can think of is using two graphics cards one for X and one for OpenCL. Dependidng on what you are doing you might have to passthrough the NVIDIA to a VM in order to completely isolate it off your host.

Detect Fast User Switch Linux

I'm currently attempting to detect when a user has fast-user-switched to another user on the Linux platform (specifically, Fedora 14-16, RedHat 4.7-6.x, CentOS 4-6, OpenSuse 10-11). I've been looking for something similar to the WTSRegisterSessionNotification() function that is available on Windows, but all I've come across is a bunch of references to bugs in the Wine software.
Has anyone else run across this snag? There seems to be a ton of resources on how to do this on Windows and Mac OS X (which is fine), but on Linux there seems to be nothing...
EDIT:
Apparently, on newer systems (at least Fedora 16) this may appear to be a viable option. I wonder if it has a DBus interface...More to come soon!
First of all, I need to tell you I'm not an expert in this area, but I have enough knowledge to give you pointers to places where you may go and learn more. So I may be wrong in some ways.
My guess is:
this is not easy
for most methods you may implement there are probably many ways to trick them into believing something that's not true, which may lead to security problems
your method may depend on the:
chosen Linux Distribution
version of the Distribution
Desktop Environment
Display Manager
As far as I know (and I may be wrong if something changed during the last years), fast user switching is implemented by launching another X server on another VT. So one way would be to detect if there are multiple X servers running.
But there are many cases where there multiple X servers running and it's not because of fast user switching. Examples: Multiseat or even simple Xephyr logins. With Xephyr and XDMCP, you may even have the same user logged in twice in a non-fast-user-switching case.
I started googling about this and found this old web page:
http://fedoraproject.org/wiki/Desktop/FastUserSwitching
If things haven't changed since then, you should study ConsoleKit and PolicyKit (and also DeviceKit and maybe Systemd today) and their DBus APIs.
There are also the commands ck-list-sessions and ck-launch-session. But I believe you can fool these commands easily: try to ck-launch-session xterm and then ck-list-session.
Why exactly are you trying to detect fast user switching? What's your ultimate goal? Maybe you can solve your problem without trying to detect fast user switch...
Well it appears that the most useful way of getting at this information is to use the ConsoleKit DBus interface.
The following procedure outlines how to enumerate the sessions and determine if they are active or not:
1.) Enumerate the sessions using the following:
Bus: org.freedesktop.ConsoleKit
Path: /org/freedesktop/ConsoleKit/Manager
Method: org.freedesktop.ConsoleKit.Manager.GetSessions
What is returned is an array of object paths that export the Session interface. These, in turn, can be queried using DBus to get their appropriate properties. For example, I used dbus-send to communicate with ConsoleKit to enumerate the sessions in my system:
dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.GetSessions
And what I received in return was the following:
method return sender=:1.15 -> dest=:1.205 reply_serial=2
array [
object path "/org/freedesktop/ConsoleKit/Session2"
]
2.) Using the returned object path(s), I can query them for their attributes, such as if they are active or not using the following:
Bus: org.freedesktop.ConsoleKit
Path: /org/freedesktop/ConsoleKit/Session2
Method: org.freedesktop.ConsoleKit.Session.IsActive
Depending on the method, I can query what I need from the session(s)! Using the ConsoleKit interface I can also retrieve the identifier for the current session, so I can always query it to see if it's active when I need to. Just for fun, here's the output of the following command:
dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Session2 org.freedesktop.ConsoleKit.Session.IsActive
method return sender=:1.15 -> dest=:1.206 reply_serial=2
boolean true
Neat.
You have to do it by polling to be sure of working on all machines (you obviously don't have to have DBus running to do user switching!).
Solaris, HP-UX, and others, do not do user switching on the console.
Platforms to support: linux, FreeBSD, AIX. Linux/BSD use virtual terminals; AIX uses /dev/lft0 if you're interested.
Suppose you want to reliably and securely run a application on the console, and restart it on the new active X server when the console switches to another VT. The problems are that you may or may not have a desktop environment running (some of us use twm!). The session may not have been started via a login manager (you could do Ctrl-Alt-F2 on linux, login, and run startx quite happily). The system might not even have xdm/gdm/similar installed.
The dumb solution is the only reliable one: every few seconds, query what the active virtual terminal is (VT_GETSTATE on linux, VT_GETACTIVE on BSD). If it's changed, you know a switch has happened. If you switched to a non-graphical session (eg with Ctrl-Alt-F1) there won't be an X server active.
Otherwise, you have to hunt hard to find which display number is active. For example, you might see two X servers in ps, with display numbers :1 and :2. Which of those is on VT7 though? The final piece of the puzzle, mapping VT numbers to display numbers, is the hardest. This question is answered in this duplicate question, "Which virtual terminal is a given X process running on?".

Resources