Functional Programming in JavaScript

A list of some articles I’m in the process of reading about FP in JavaScript. Suggestions welcome!

J.R. Sinclair: A Gentle Introduction to Functional JavaScript

J.R. Sinclair: Things I wish someone had explained about functional programming

Functional Programming Patterns With RamdaJS!

Tom Harding: Fantas, Eel, and Specification

Exploiting the sudo password timeout.

I love sudo. Sudo allows me to do necessary system administration without having to login as root and potentially wrecking my system. I also really like that after issuing the first sudo command, I don’t have to type my password over and over, unless and until I leave my terminal window alone for 15 minutes.

Recently, I started using windows terminal as my preferred shell on Windows. It’s highly configurable and pretty awesome in general, and Open Source too!

One thing that seemed disappointing was that it’s not possible to open an elevated shell in a tab, when the application itself is not elevated. Combined with the lack of a sudo command in Windows, this made the application less useful than I’d hoped it would be. According to this (very chatty) bug report (#632), it turns out the reason this isn’t supported is because it’s theoretically possible to send keystrokes to any unelevated window from any other unelevated process. I’m not sure how big a problem this really is, but if this is a security risk in Windows, it’s probably a risk in Linux too.

I’ve created a small bash script to demonstrate the risk. It waits for a sudo process to show up, which is active when the user tries to run a command with sudo the first time and has to type their password. Then, the script waits for the process to disappear, assuming the password was correct and the command has finished (hopefully within sudo’s password timeout). Now we know that there’s probably some window that is allowed to run sudo commands without asking for a password. The script then lists all X windows with ‘terminal’ in its name, using xwininfo and grep, and sends the malicious command sudo ls to them, using xvkbd.

#!/bin/bash

# Wait for sudo to start
until pids=$(pidof sudo)
do
        sleep 0.2
done

echo $pids

# Wait for the user to finish typing their password
pids2=$pids
while [[ $pids == $pids2 ]]
do
        sleep 1
        pids2=$(pidof sudo)
done

echo "Sudo finished, running malicious command..."
xwininfo -root -children | grep -i terminal | grep -v '10x10' | tr -s [:blank:] | cut -d ' ' -f 2 | xargs -I '{}' xvkbd -text 'sudo ls\r' -window '{}'

echo "Pwnage finished!"

The script itself doesn’t have to run in an elevated window, it just waits and bides its time to run an elevated command in another window. In this case the script has to be run manually and depends on several not quite common tools like xwininfo and xvkbd. The script also makes no attempt to hide or disguise itself. But as a proof of concept it’s easy to see how code could be written with the same functionality that is run more covertly.

Mitigation

I’m not sure what the best way to mitigate this problem is. Configuring sudo to ask for a password every time is possible, but that would be very user unfriendly. People would probably turn to sudo -i or su a lot more, making the problem only worse. Maybe it’s possible to disable receiving keystrokes (with the XTEST protocol) during the time sudoing without password is allowed.

Quickie: Generate EXM.CryptographicKey with PowerShell

The Sitecore documentation states that the EXM.InternalApiKey , EXM.CryptographicKey and the EXM.AuthenticationKey

must be represented in hexadecimal format by 64 characters and you can only use the symbols 0-9 and A-F.

However, it doesn’t say how to obtain said keys, nor the security considerations and implications of said keys. It’s obviously a Bad Thingtm to copy the example, or just use 64 zeroes (or any other character that fits the pattern).

I came up with two quick ways to generate the keys, which are essentially a hexadecimal representation of a 32-byte sequence.

Method 1 (use the .Net Random class)
$r = New-Object Random; $key = ""; for ($i = 0; $i -lt 32; $i++) { $key += $r.Next(256).ToString("X2"); }; $key | Set-Clipboard

Cons: You have to trust the .Net RNG to be secure enough.

Method 2 (use random.org):
(Invoke-WebRequest 'https://www.random.org/cgi-bin/randbyte?nbytes=32&format=h').Content.ToUpper() -Replace "[`n ]","" | Set-Clipboard

Cons: You need an active internet connection (and you need to trust random.org)

Both commands place the generated key on the clipboard, ready to paste into your configuration files.

HTH,
Matthijs

Finding JAVA_HOME on Windows

I’m running a program on a Windows machine that needs JAVA_HOME to be set. Because I’m running it with just a JRE (no JDK installed) the JAVA_HOME environment variable isn’t set (the JDK installer usually creates the JAVA_HOME environment variable). Because I don’t want to modify my scripts or my environment manually every time the JRE decides to update (pretty often), I created a script that sets the JAVA_HOME variable based on the path of java.exe.

The batch script requires the path of java.exe to be in the PATH. The Oracle JRE installer usually does this for you.

set_java_home.bat:

@echo off
:: Find java.exe symlink (C:\ProgramData\Oracle\Java\java.exe)
for /f %%i in ('where java.exe') do set java_lnk=%%i

:: Find symlink target
for /f "tokens=2 delims=[]" %%h in ('dir %java_lnk%') do set java_dir=%%h

:: Find parent directory
for %%a in ("%java_dir%\..") do set "JAVA_HOME=%%~dpa"

:: Remove trailing slash
IF %JAVA_HOME:~-1%==\ SET parent=%JAVA_HOME:~0,-1%

Java plugin without installing toolbars

When trying to update the java plugin (which is good practice security-wise), the installer usually wants to install a crappy Ask.com toolbar. Normally there is a checkbox you can uncheck if you don’t want the toolbar (which you don’t, for obvious reasons). Unfortunately the checkbox is gone, and the installer forces you to install the accursed toolbar before continuing.

There are a few ways to install the java plugin without installing the Ask.com toolbar, but it’s probably better to uninstall the damn thing altogether, ridding yourself of the cesspit of vulnerabilities it currently is (and has been for a while).

It’s a shame. I used to like java (for server stuff it’s fine and alive & kicking), but it looks like Oracle is doing a great job of killing the last grains of hope there were for java on the client.

Batch converting a directory of FLAC files to MP3

Just a quick one, because it took me a while to get the command right. Hope it helps someone out there with a similar problem. I’m using Debian unstable with (unofficial) deb-multimedia repositories enabled.

The magic command I use is:


find . -name "*.flac" -print0 | xargs -0 -n 1 basename -s ".flac" | xargs -n 1 -I % ffmpeg -i %.flac -ab 196k %.mp3

The 1st command of course finds the input files. The 2nd turns filename.flac into filename. The last command runs ffmpeg on all flac files to convert it to mp3 files (at 196kbps).

If you’re running a version of ffmpeg that can’t encode mp3 files (because of format / patent restrictions), you’ll have to pipe the output from ffmpeg into lame or some other mp3 encoder.

Enjoy!

Reboot to Windows from Linux

I, like many others, have a dual-boot system. I run Debian (unstable / sid) as my primary OS, and Windows 7 when I play games. Hopefully Steam coming to Linux means that I won’t have to reboot anymore, but for the moment I do.

Of course, it’s not really hard to reboot your system and then choose the correct option in th GRUB menu, but it does mean you have to stay around to prevent GRUB from booting the default OS, instead of walking to the kitchen to get a cup of coffee / tea  / [insert beverage of choice here]. Well, there’s a solution for that, a command called grub-reboot. For example:

sudo grub-reboot 6

This will set the 7th entry in the list of OSes as the default for one boot (it’s a 0-based index). Then reboot, et voila! You still have to know which entry to boot, of course, but you can just count it once and remember. Right? Well, it’s not always that simple.

The problem is that sometimes a new Linux kernel is installed and the old one is kept, to be able to reboot safely when the new kernel doesn’t work (which has actually never happened to me, but is a possibility when running Debian unstable). In that case, you might need to reboot to a different entry. Besides that, I wanted to have a nice icon to click on, that would set the grub entry and reboot me in one simple step.

I’ve created a simple shell script that reads the correct menu entry from grub.cfg and sets that up for the next boot. After that the script calls gnome-session-quit to request a reboot (you can choose between Cancel, Restart or Power Off):

#!/bin/sh

# Find the menuentry containing Windows
#entry=`grep menuentry /boot/grub/grub.cfg | grep -n Windows | cut -d":" -f 1`
#entry=`grep -E '^menuentry|submenu' /boot/grub/grub.cfg | grep -n Windows | cut -d":" -f 1`
entry=`grep -E '^menuentry' /boot/grub/grub.cfg | grep -n Windows | cut -d":" -f 1`

/usr/sbin/grub-reboot $(($entry - 1))
# Use line below for gnome
#gnome-session-quit --power-off

# Use line below for xfce
xfce4-session-logout --fast

Update (16-5-2013): The version of Grub I currently use, adds support for submenus. Only top-level menuitems and submenus should be counted.

Update (12-2-2014): The current version of Grub does not count submenu items as bootable items. Changed reboot command to match XFCE, which is my current DE (a script could/should be made to auto-detect this).

Save it as ~/bin/reboot-to-windows.sh (or some such). Use chmod to make it executable. Also, you will probably have to fiddle with write rights to /boot/grub/grubenv. Either create a grub-reboot group that you add all allowed users to, and set that as the group for the file. Or you can add yourself and other allowed users to the ‘root’ group (Beware: This might introduce serious security issues). Or you can just make the file world-writeable (which allows all users to fuck up your system by corrupting the file).

Now, to create an entry in the Gnome-shell menu (yes, I use Gnome-shell), create a file ~/.local/share/applications/RebootWindows.desktop with the following contents:

#!/usr/bin/env xdg-open
[Desktop Entry]
Encoding=UTF-8
Name=Reboot to Windows
Exec=/home/your-username/bin/reboot-to-windows.sh
Icon=/home/your-username/bin/Windows-reboot.svg
Type=Application
Categories=System;

Where ‘your-username’ is your username, obviously. I’m not sure ~/bin/reboot-to-windows.sh will work, instead of a full path. The Icon entry refers to a svg graphic I created, here it is:
Windows reboot desktop icon
Save the file. The entry should now show up and be clickable.

Enjoy!

Update (31-12-2012): I forgot a modification in /etc/default/grub:

# Enable grub-reboot
#GRUB_DEFAULT=0
GRUB_DEFAULT=saved

Otherwise, grub will just boot the first entry, no matter what.

Synchronous .NET event handling with PowerShell

There are multiple ways in Windows PowerShell to handle events generated by objects in the .NET framework. The most common, or at least, the most documented way to register an event handler to a .NET object is with Register-ObjectEvent. Usage is fairly straightforward: Register-ObjectEvent -InputObject $obj -EventName "BeforeProcess" -Action { Write-Host "BeforeProcess called" }.

The thing is, that the action you registered with Register-ObjectEvent is called asynchronously. This means that the code that generates the BeforeProcess event doesn’t have to wait for the action to end. Consider, for example, a .NET class:

namespace Echo
{
	public class Echo
	{
		public event EventHandler<EchoEventArgs> BeforeEcho;

		public void EchoMessages(string messages)
		{
			foreach (string message in messages.Split(','))
			{
				EchoEventArgs args = new EchoEventArgs { Message = message };
				if (BeforeEcho != null)
				{
					BeforeEcho(this, args);
				}

				Console.WriteLine(message);
			}
		}
	}

	public class EchoEventArgs : EventArgs
	{
		public string Message { get; set; }
	}
}

Now, create an Echo object in PowerShell:

[void] [System.Reflection.Assembly]::LoadFrom('echo.dll')
$echoObject = New-Object Echo.Echo

Running it without event handlers:

$echoObject.EchoMessages('Mary,had,a,little,lamb')

should yield:
Mary
had
a
little
lamb

Now, when you attach an event handler with Register-ObjectEvent:

Register-ObjectEvent -InputObject $echoObject -EventName "BeforeEcho" -Action { Write-Host ("ObjectEvent: " + $EventArgs.Message) }
$echoObject.EchoMessages('Foo,bar')

Result:
Foo
bar
ObjectEvent: Foo
ObjectEvent: bar

As you can see, the foreach loop in EchoMessages doesn’t wait for the Action to finish, before going on to the next message.

Very often, this is exactly what you want. A lot of examples use System.Timers.Timer, where you just want to execute something every so-and-so hours. But once in a while, you may need the event handler to finish before the next line of code is executed.

Let’s say we want the event handler to be able to skip certain messages, or cancel the rest of the messages altogether. Or maybe modify the message before it is written.

namespace Echo
{
	public class Echo
	{
		public event EventHandler<EchoEventArgs> BeforeEcho;

		public void EchoMessages(string messages)
		{
			foreach (string message in messages.Split(','))
			{
				EchoEventArgs args = new EchoEventArgs { Message = message };
				if (BeforeEcho != null)
				{
					BeforeEcho(this, args);
				}

				if (args.Cancel)
				{
					break;
				}
				else if (!args.Skip)
				{
					Console.WriteLine(args.Message);
				}
			}
		}
	}

	public class EchoEventArgs : EventArgs
	{
		public string Message { get; set; }
		public bool Skip { get; set; }
		public bool Cancel { get; set; }
	}
}

Now, let’s say I want to cancel all messages straight away:

Register-ObjectEvent -InputObject $echoObject -EventName "BeforeEcho" -Action { $EventArgs.Cancel = $true }
$echoObject.EchoMessages('1,2,3,4,5')

Result:
1
2
3
4
5

Why? Because you’re already too late. When you decide to cancel, the number is already outputted. Next invocation is with a new EchoEventArgs object. So we need to register the event handler for synchronous execution. Unfortunately, it isn’t documented at all how to do this. Looking with Reflector, we can see the compiler generated two methods for us: add_BeforeEcho and remove_BeforeEcho:
Echo class in Reflector

So, when we register the event handler with add_BeforeEcho, it all works as expected:

$echoObject.add_BeforeEcho({
  param($Source, $EventArgs)
  if ($EventArgs.Message -eq '2') {
    $EventArgs.Skip = $true
  } elseif ($EventArgs.Message -eq '7') {
    $EventArgs.Cancel = $true
  } else {
    $EventArgs.Message = ($EventArgs.Message + ".00")
  }
})
$echoObject.EchoMessages('1,2,3,4,5,6,7,8,9,10')

Result:
1.00
3.00
4.00
5.00
6.00

Hurray!