"The Linux Gazette...making Linux just a little more fun!"


(?) The Answer Guy (!)


By James T. Dennis, [email protected]
LinuxCare, http://www.linuxcare.com/


(?) ICEWM Key Bindings (Macros) and X in "Toaster" Mode

From Marc Kerschen on Sun, 26 Mar 2000

Hello, First I would like to thank for your amazing work on linuxgazette.com.

(!) Your welcome. It's a hobby. Heather does all the hard work (turning my e-mail babbling into HTML).

[ The really hard part is adding code markup where people describe commandline stuff; my preprocessor is good, but not quite an AI. And checking the links, which means I really have to read the whole thing through.

-- Heather ]

(?) 1.) I have read that you are using icewm.

Here is my question. When I log in as user I would like to open with a key shortcut an xterm window where I immediately have a root shell without having to type su. I want to do this on my portable Linuxbox. Security is of no concern here.

(!) The desire to have your system deliberately "insecure" is actually not all that uncommon. Actually my definition of security is:
Security is the enforcement of policy.
So, where someone else admonishes: "That's not secure!" I ask, "What is the set of policies that this fails to enforce?" (Actually I ask: "What are your policies?" then I ask how a particular set of requirements and constraints affects the enforcement of those policies?" But I digress).
Here you seem to be expressing a requirement that you be able to initiate privileged (root) shell sessions without requiring the use of a password. You've also expressed a preference that this be initiated by a key binding in your window manager, icewm.
I should note that, while I am using icewm on a couple of systems, it is not of any particular preference. I tend to use whatever window manager a system defaults to, since my only use for a window manager is to launch an xterm. From there I launch my other programs in by simply typing their name at a command prompt. All common window managers then allow me to drag and resize the new window (typically I resize it to full screen). Most of them allow me to access multiple virtual screens or "panes" --- so usually I put one or two windows per pane. If a wm has any keybindings I tend to learn the ones to cycle from on pane to the next, and to cycle among the windows on the current pane ([Alt]+[Tab] from MS-Windows, and on some window managers).
It turns out that icewm is a fairly lightweight window manager with reasonable keyboard controls. Classically it is against the philosophy of X to have window managers globally intercepting keystrokes; those might be intended for the foreground application. However, it is a common desire among most users that they be able to start, kill, switch among and otherwise control their application using the keyboard rather than being forced to use a mouse.
In this case you can set some keybinding like [Alt]+[Ctrl]+[r] to start a shell. You want that shell to be running as root --- so it would make sense to have it run a root-owned SUID shell. In other words you make a copy of whichever shell you prefer, chown it to root (actually it probably is already owned by root), chgrp it to some custom group (make a new one, let's call it "priv") and than mark it as an SUID program using the chmod command.
Of course we don't want to completely throw all security to the wind. It's nice to be able to enforce SOME policies. So we can set this so that only members of the group "priv" (your normal account, and any of your trustworthy friends and family) are in the "priv" group.
So, I set this up with the following commands:
groupadd -g 201 priv
mkdir /usr/local/priv
chown root.priv /usr/local/priv
chmod 750 /usr/local/priv
usermod -G priv,staff jimd
usermod -G priv,staff,wheel star
cp /usr/bin/bash /usr/local/priv/sh
chown root.priv /usr/local/priv/sh
chmod 4550 /usr/local/priv/sh
... so this: creates a group named "priv", makes a directory for it, changes the ownership and group association to root and priv respectively (I could do that in two separate commands, chown and chgrp, but I prefer the GNU syntactical extension of separating the user and group names with a dot), and it limits the access to this "priv" directory (so only members of priv, and the directory's owner are allowed to access it; then it gives me a non-world executable, SUID-root copy of bash in the directory.
(NOTE: The usermod commands here might need to be modified a bit. Unfortunately the usermod command REMOVES you from any groups that you don't list on the usermod -G argument. This is a bug in my opinion. I should be able to just add people to groups, perhaps using +G or some -G +, syntax to indication that this is purely additive. To do this in a script I'd like to do something like:
foo=$( id -Gn $1 | tr " " , )
foo=$foo,$2
...
... where $1 was the user name and $2 was the new group (or common delimited list of new groups -- with no spaces). But I digress again).
I've actually put (redundant) layers of protection here. I prevent anyone that's not in the priv group from seeing or accessing any of the contents of the priv subdirectory, AND I prevent anyone outside of the priv group from executing the file directly. Either of these measures alone should enforce the policy that "only members of the "priv" group are allowed to execute this copy of the shell (which runs with 'root' privileges).
There are other ways to do this, including using programs like 'super' and 'calife' and even 'sudo'. Classically 'sudo' allowed a sysadmin to control access to a set of privileged commands, but required that the users accessing those commands type in THEIR OWN password in order to run any of those commands. Thus you were enforcing the policy that a user could run certain, specified, privileged commands (not necessary as 'root') but that they must present their password (or have done so within the last few minutes, according to a configurable caching feature in later versions of sudo). The latest versions of sudo are supposed to allow one to configure certain users and members of certain groups to execute commands without requiring them to type their password. This was added to allow people to execute privileged 'at' commands and 'cron' jobs.
You could use 'sudo' for this, but my example will work on any form of UNIX and without any additional packages. Mine is a bit simpler, and less flexible. (It also probably takes up slightly more disk space since an extra copy of bash is bigger than the whole sudo package).
Anyway, once you have created a shell (or installed sudo, calife, or whatever) then you can simply create a line in your icewm/keys file like:
key "Alt+Ctrl+s" xterm -title "SuperUser xterm"  -e /usr/local/priv/sh
... (and you can add any other -fg -bg -fn and -geometry arguments to get the foreground and background color, default font and size/placement settings that you like).
I picked [Ctrl]+[Alt]+[s] for this example, but many other keys will work. (Oddly enough, [Ctrl]+[Alt]+[r] did NOT work with my copy of icewm --- which is from the Debian package, I grabbed the sources and noticed that this "r" combination is defined as "defgKeySysRun").
Read the xterm man page for all your xterm options. Don't forget that you can also use lightweight xterm alternatives like rxvt if 'xterm' doesn't make you happy enough.
Note that there many other considerations when running this sort of configuration. One reason that didn't suggest that you simply configure the root account to have an empty password is that it would then offer NO protection. This arrangement preserves an implicit policy that the shell be started by some process that is already authenticated as "you." A null password approach could mean that processes initiated over the wire (completely unauthenticated) could gain root access (and be basically immune from all other attempts to enforce any policies).
I've tried to describe an approach which reasonably matches your requirements while also being a an egregious compromise to sysadmin's "best practice." Note that any "attacker" who tricked any program that you run into executing arbitrary code could potentially execute your privileged copy of the shell, and then do anything to your system. Thus the potential damage from trojan horses, black widows (hostile bits of JavaScript or other dynamic web content) etc are much greater.
Let's consider that scenario for a moment. You log in as "yourself" (maybe an account named "marc"). You run a program like your mail client, newsreader or web browser. You are running in one security context (you user account) and interacting with data from another context (anonymous, internet users). Your applications are implicity trying to enforce a set of policies (viewing this content as data, rather than executing it as instructions from YOU).
Any bug in the data handling of any of these programs might be interpreted as code (buffer overflows, etc). A cleverly degenerate bit of mail, news, or HTML (or HTTP protocol handshaking) might then be able to trick your mail user agent, newsreader, or web browser (or any program which those execute as they process data) into executing arbitrary code. Since the program is being run by you, it can do anything that you can do. If a program you run is hostile, it can completely corrupt or wipe out all of your data. If it is run as root it can wipe out your whole system. (It can also create "backdoors" through which it can give access to your system to others).
If you were concerned about this sort of thing, one option is to create additional accounts. You can do your web browsing from one account, and your mail from another, and your news from another.
If you did a bit of clever work with the groups you could give your news reader read/only access to some of your mail folders, and your mail agent read and/or read/write access to some of your newsreader functions, etc.
Of course managing this various roles is far beyond anything that most users, particularly home users, are prepared to do. So we must try to eliminate the bugs in our applications software that allow untrusted data to be subverted. (Linux is way ahead of MS-Windows in this regard. However the various BSD's, OpenBSD in particular, are somewhat ahead of Linux, too). Specific applications (like Lynx and Netscape's Navigator and Communicator packages are WAY behind others like elm, mutt, etc).
But I digress once again. On to your other question.

(?) 2.) How can I boot directly to icewm as a specified user without having to type in my username and password. Can a simple script in initrc do that ?

(!) I refer to this as running X in "toaster mode."
It is for people who want their computer to be an appliance --- walk up and use it, no login required.
It is surprising tricky to get this to work on modern Linux boxes running recent versions of X. I had to spend a couple hours playing with it, running it under strace and finally resorted to downloading the sources and reading through some of them (xserver-wrapper.c from the Debian patches).
Basically here's what you'd expect to be able to do:
Add a line to /etc/inittab like:
x:4:respawn:/root/sbin/toasterX
And change the inittdefault line to something like:
id:4:initdefault:
(You'd now be using the custom "runlevel 4" as your default mode of operation).
And you'd expect the toasterX script to simply execute startx.
Of course you don't want X running as root, so you have to run it as some other user. No problem, that's what the su command is for. If you are using a command like:
su - joe -c "/usr/bin/X11/startx"
You'd think that might do the trick. Alas, you'd be wrong. I kept getting "You are not authorised to run X" when I tried this script through init, even though it worked fine from a shell prompt.
What I learned from the sources is that the Xwrapper program which is starting your real copy of the X server is actually testing to see if it's standard input file descriptor is attached to a console. This is presumably to protect your system from some remote attacker running X (or XWrapper) on your console, through some form of network login, cron job, at job, or other hack.
So we have to direct the input from a console. I really doesn't matter which one, just so long as it's from one of the /dev/ttyXX nodes (where XX is a number). My toasterX script looks like:
#!/bin/sh
exec /bin/su - guest -c "/usr/X11R6/bin/startx" < /dev/tty14 > /dev/tty15
... where I'm arbitrarily using tty14 for input and tty15 for output. (I do that since I might want to read some of the error messages that it output to that virtual console if I have problems with X later --- you wouldn't need that).
That's the trick. Heather, my wife, got it working without this redirection hack. She's on Red Hat, I'm using Debian (Woody -- the developmental releases). I don't know which version of Red Hat Heather is running on her laptop. So your mileage may vary.

[ It's Red Hat 6.1, and I believe that I used an uncommon command line option to the X server to specify which vt it should use. In which case, I am guessing, it checks to see if that vt is free to hog, instead. OTOH, maybe Red Hat's Xwrapper didn't have the defense mechanism you saw in the debian source.

-- Heather ]

(One of the guys at Linuxcare was wondering how to do this, and I was stumped for the short time I had to try it. That was on a Mandrake system. Sylvester --- I knew I'd figure it out eventually!).
Here's one cool thing about how this is done; it will automatically respawn a new X session when you logout/exit the last one.

(?) Thank you, I hope you will find the time to answer.
Marc
Paris

(!) Sorry it took so long to get around to it. I'd been meaning to unravel that Xwrapper mystery for Sylvester anyway. Sometimes I get too busy to hunt one down for a month or two.


Copyright © 2000, James T. Dennis
Published in The Linux Gazette Issue 52 April 2000
HTML transformation by Heather Stern of Tuxtops, Inc., http://www.tuxtops.com/


[ Answer Guy Current Index ] [ Index of Past Answers ] greetings 1 2 3 4
5 6 7 8 9
10 11 12 13 14 15 16 17
18 19 20 21 22 23 24


[ Table Of Contents ] [ Front Page ] [ Previous Section ] [ Linux Gazette FAQ ] [ Next Section ]