Wednesday, July 28, 2010

How to run vim commands for certain file types

For the longest time I've created .tex files in vim and typeset them with pdflatex.  The problem is that every time I need to type

:set makeprg=pdflatex\ %

This was frustrating because I use tex all the time.  Alas, the solution is to place the following in your ~/.vimrc:

autocmd FileType tex setlocal makeprg=pdflatex\ %

Monday, June 7, 2010

LaTeXCalc 1.0 is out!

Ever been working on a homework set or a paper in LaTeX where you constantly resort to a calculator to do boring computations?  LaTeXCalc is your solution.  It is a "LaTeX Calculator" that allows you to in-line computations with TeX.  See the homepage at http://latexcalc.sourceforge.net.

Currently available on UNIX-like platforms (aka almost everything except Windows).  A Windows port will be available "soon".

Wednesday, May 26, 2010

Thoughts on Wikipedia

My close friend Jason recently got back from studying abroad in Ghana*.  Yesterday he was telling me how the classes in Ghana weren't well put together and often just involved professors reading from scripts.  Upon asking where the scripts were from he promptly replied "Wikipedia".

At first this is a little disappointing.  We all hope that education around the would could be better.  On the other hand, this means that the whole world can influence education in Ghana and other third world countries!

This is one of many good reasons to edit wikipedia.  As odd as it may sound, it has the power to educate and transform the world.  Undoubtedly you can contribute something too.  My biggest request is that you take care when you edit.  Don't just write.  Write quality material and follow Wikipedia's guidelines.  Each small contribution has a very real effect on every single person who visits the page.  Wikipedia has helped you, now return the favor!



* On a side note, Jason's compelling blog of his Africa journeys may be found at http://jasonghana.blogspot.com/.

Tuesday, May 11, 2010

Hacking XScreensaver to take photos of intruders

Once upon a time, I returned to my computer to see the message "11 Failed Login Attempts" when logging in.  Needless to say, this was unnerving.  To catch the culprit I successfully recompiled XScreensaver to take pictures of anyone getting my password wrong.  Here's how I did it.

Disclaimer: This uses an extremely cheap hack. In fact, I wouldn't be surprised if it introduces subtle security vulnerabilities, but I don't know of any.  (EDIT: it turns out that even though the system() command is given an absolute path, the shell environment can be modified to abuse it.  Since xscreensaver is a setuid program, this could lead to elevation of privilege attacks.)  Use at your own risk.

When I originally did this I used Arch Linux, but since then I've ported it to Ubuntu and it should work on any *nix system with tweaks.  This won't work for Windows, unless you can get xscreensaver and mplayer working in cygwin (good luck!).

First get your webcam setup and /dev/video0 working. You can test this with a program like cheese.  Install mplayer. Then

$mplayer tv:// -tv driver=v4l2:device=/dev/vi
deo0:width=800:height=600:outfmt=rgb24 -frames 4 -vo jpeg:outdir="/data/berkeley/failed-login-pics/`date +"%Y-%B-%d"`/`date +"%H.%M.%S"`" > /dev/null 2> /data/berkeley/failed-login-pics/mplayer-error-log

will take four pictures using /dev/video0 and v4l2 drivers and save it to /data/berkeley/failed-login-pics/date/time.  Obviously you'll want to change the paths for your system.  You may need to adjust other settings as well.  Get this working before continuing.  Place this command in a script of your choice somewhere in your system.

Here's how to make xscreensaver run this command when someone guesses your password wrong:

Download the xscreensaver source and modify xscreensaver-version/driver/lock.c as follows (I've done so much other stuff to this file I can't really provide a patch or diff):

1. Insert this line at the top, under the other standard includes

#include <stdlib.h>

2. Add a function int takePicture() as follows near the top somewhere. Use the command that worked for your computer above in the system("...") call! Be sure to escape every " with \. Don't ignore the mkdir command. Also note that there are actually only two lines in the body of the function.

int takePicture() {
     system("/path/to/script");
}

3. Somewhere around line 2040 you'll see code that looks like:

if (si->unlock_state == ul_fail && /* failed with caps lock on */
si->pw_data && si->pw_data->caps_p)
     s = "Authentication failed! (caps lock)";
else if (si->unlock_state == ul_fail) /* failed without caps lock */
     s = "Authentication failed!";

change it to this: (and feel free to customize the messages)

if (si->unlock_state == ul_fail && /* failed with caps lock on */
si->pw_data && si->pw_data->caps_p)
{
     takePicture();
     s = "Authentication FAIL!\n (caps lock is on)";
}
else if (si->unlock_state == ul_fail) /* failed without caps lock */
{
     takePicture();
     s = "Authentication FAIL!\n (this will be reported)";
}

4. While you're at it, I highly recommend changing the xscreensaver pictures/icons and replacing them with whatever you want. I used arch linux icons. You'll find them in one of the source directories.

5. If you're crafty you can also modify some of the other visual elements in the login screen. For example, at somewhere around line 250 you can modify the strings that contain "xscreensaver blahblahblah" and the hostname to whatever you want. Be careful! If you write it wrong or don't use strdup you could create segmentation faults when xscreensaver frees up the window resources causing xscreensaver to crash. If you do this then pressing the ESC button will bypass the login window.  Test your modifications throughly. 


Install can be a bit tricky. First remove xscreensaver and gnome screensaver from any package managers, eg.

$sudo apt-get remove xscreensaver
$sudo apt-get remove gnome-screensaver

OR

$sudo pacman -R xscreensaver
$sudo pacman -R gnome-screensaver

Then execute

$./configure --prefix=/usr
$make
$sudo make install

To test it out, do the following

$pkill xscreensaver   (or $killall xscreensaver)
$xscreensaver &
$xscreensaver-command -lock

When you test, make sure that

1) STDOUT and STDERR of mplayer and mkdir are suppressed or logged (you'll know if it's not)
2) You can't bypass the login screen by pressing ESC, waiting, overflowing some buffer, or otherwise causing a segfault.

For a GUI configuration editor, try

$xscreensaver-demo

Finally, make sure that xscreensaver is run at startup with your desktop manager so it actually turns on.

Have fun.

Thursday, May 6, 2010

Adding a new server to the MINIX 3.1.6 kernel.

For a class project I was required to add a new service to the MINIX kernel.  In MINIX, all the essential parts of the operating system are implemented as services.  For example, the file system is a service, the process manager is a service and so forth.

To my dismay, no documentation on adding a service exists (or is hard to find), except in my project's description.  Unfortunately, that too was outdated.  After much experimentation, here's what I discovered needs to be done to add a service:

(1)  Copy an existing service to create foundations.  Most services need the same basic structure: a dispatch loop that checks for messages and executes system calls.  The services have source code in /usr/src/services.  Simple servers to copy include ds (data store server) and is (information server).  For example:

$cp -r /usr/src/servers/ds /usr/src/servers/foo

Here, "foo" is the abreviated name for the new service.

  • You should modify the Makefile in your /usr/src/servers/foo folder to update the name of the binary.  You should only have to change the first or second line.
  • It would be a good idea to appropriately modify the Makefile in /usr/src/servers at this point as well.
  • Once you get everything working, you should remove all the code from the other service that's not relevant to you.  When I created my server from the ds server I ended up deleting store.c, store.h and removed calls from main.c to functions in those files.

(2)  Add "foo" to the boot image.  Since MINIX uses a microkernel architecture there are several places where boot image information needs to be updated.  In general, the order that services are listed in tables are important as it determines the order they startup.

  • /usr/src/tools/Makefile contains the Makefile that compiles to boot image.  You must add the path to your binary in the 'programs' variable.
  • /usr/src/include/minix/com.h lists constants for all of the boot image processes.  You'll see entries like "#define DS_PROC_NR ..." for each process.  You'll need to create your own constant for your process and update the constants on the other ones so the order is consistent.
  • /usr/src/kernel/table.c has a table of the boot image processes that the kernel uses.  This needs to be updated and is fairly self explanatory.  You will want to copy values from another process for the fields.  You could change the values if you know what you're doing, but you don't really need to.
  • /usr/src/servers/rs/table.c has THREE tables that you'll need to fill out.  Again, I would recommend copying entries from other processes.
  • /usr/src/servers/rs/manager.c has a list of if statements around line 1645 that needs to be updated with information for your process.
(3) That should be it!  You should recompile the kernel using 'make fresh install' from the /usr/src/tools directory.  It should be possible to compile it using a command like 'make install' or 'make hdboot' instead, but it's sometimes hard to know.  You should reboot to make sure your service starts up, and then you can start hacking!