Saturday, July 13, 2013

Setup a Wireless Access Point with Linux Mint 15 (Olivia)

In these days of tablets, smartphones and other "connected" devices, the ability to share a fast wired Internet connection via wi-fi can be very useful, specially at home or small offices. Wireless routers aren't very expensive and are simple enough to install – yet I have always thought they're kind of wasteful, considering most computers today ship with wi-fi interfaces, or can be fitted with USB cards that sell for pennies.

With Linux, wi-fi interfaces can be configured to operate in master mode, so they can accept client connections just like a dedicated router would. This is a huge improvement over "ad-hoc" wi-fi network sharing, because:
  1. Many mobile devices do not connect to "ad-hoc" access points;
  2. The WEP authentication standard used on those connections is known to be flawed, in contrast to the newer WPA standard used in "master mode" connections.
Today I updated my desktop to the latest Linux Mint 15 (Olivia), and as I went about configuring a Wireless Access Point (WAP) on it for my other devices, I took the time to document my changes to the system, so I can more easily reproduce them in future upgrades – and hopefully, also help others to setup a WAP with Mint.

The procedure I came up with was largely inspired by this blog post. It assumes the existence of a wired interface eth0 (which provides access to the Internet) and a mac80211-compatible wireless interface wlan0 (which will be configured to accept client connections in "master mode").

First open a command prompt and start a root session with su, then follow the steps below:

Step 1: Install Applications

Type the command below to install the required services:
apt-get install hostapd dnsmasq
As it is the services will be automatically started when the computer boots, but we need better control than that. So change the default settings to manual start:
update-rc.d -f hostapd remove
update-rc.d -f dnsmasq remove

Step 2: Configuration Files

Create or update the following config files with the contents below:

/etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=hotspot # Your WAP name, change it to something more unique
hw_mode=g
channel=6 # You may want to change this if the channel is too crowded
wpa=1
wpa_passphrase=hotspot_password # Password for clients
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
wpa_ptk_rekey=600

/etc/dnsmasq.conf
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=wlan0
# Specify starting_range,end_range,lease_time
dhcp-range=10.0.0.3,10.0.0.20,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

Step 3: Interface Scripts

Add the scripts below to your system:

/etc/network/if-up.d/wapstart
#!/bin/sh

WIRE=eth0
WIFI=wlan0

# Only run script for wired interface
if [ ! "$IFACE" = "$WIRE" ]
then
    exit 0
fi

# Setup wireless interface
ifconfig $WIFI up 10.0.0.1 netmask 255.255.255.0

# Start dnsmasq
/etc/init.d/dnsmasq start

#Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $WIRE -j MASQUERADE
iptables --append FORWARD --in-interface $WIFI -j ACCEPT

# Start the Wireless Access Point service
/etc/init.d/hostapd start

exit 0

/etc/network/if-post-down.d/wapstop
#!/bin/bash

WIRE=eth0
WIFI=wlan0

# Only run script for wired interface
if [ ! "$IFACE" = "$WIRE" ]
then
    exit 0
fi

# Stops Wireless Access Point services
/etc/init.d/hostapd stop
/etc/init.d/dnsmasq stop

# Asked nice the first time...
killall dnsmasq
killall hostapd

ifconfig $WIFI down
Make sure to create the scripts from the root account, so they'll have the right ownership. Also don't forget to give them running permission:
chmod +x /etc/network/if-up.d/wapstart
chmod +x /etc/network/if-post-down.d/wapstop

Usage

After performing the steps above, you should be able to start the WAP by stopping and restarting the wired interface:
ifconfig eth0 down
ifconfig eth0 up
From now on it will also be automatically started at boot time.

Troubleshooting

Make sure the wireless interface is turned "on" in the network manager applet before you start, as hostapd may fail to start otherwise.

Also check /etc/init.d/hostapd for whether the variable DAEMON_CONF is set; if not, set it to the path of the config file:
DAEMON_CONF=/etc/hostapd/hostapd.conf

Tuesday, March 19, 2013

John Nash Vindicated?

Kaspersky Lab's Global Research & Analysis Team (GReAT) reports some unsettling details on the MiniDuke malware:

(...) If the target system meets the pre-defined requirements, the malware will use Twitter (unbeknownst to the user) and start looking for specific tweets from pre-made accounts. These accounts were created by MiniDuke’s Command and Control (C2) operators and the tweets maintain specific tags labeling encrypted URLs for the backdoors.

Once the infected system locates the C2, it receives encrypted backdoors that are obfuscated within GIF files and disguised as pictures that appear on a victim’s machine.

Once they are downloaded to the machine, they can fetch a larger backdoor which carries out the cyberespionage activities, through functions such as copy file, move file, remove file, make directory, kill process and of course, download and execute new malware and lateral movement tools.


An espionage system that talks to his masters via hidden messages in public media? I guess we all owe Mr. Nash an apology then...

Monday, March 18, 2013

Straight out of a Jetsons episode, the future of robotic manufacture


With its vaguely humanoid frame and cartoonish screen-drawn eyes, Baxter looks like an early-20th century artist's impression of a robot. And indeed, in many ways it is closer from those old ideals of pervasive robotics than the practical restrictions we have come to expect from industrial robots. Will Knight writes:

Baxter is the first of a new generation of smarter, more adaptive industrial robots. Conventional industrial robots are expensive to program, incapable of handling even small deviations in their environment, and so dangerous that they have to be physically separated from human workers by cages. (...) Baxter, however, can be programmed more easily than a Tivo and can deftly respond to a toppled-over part or shifted table. And it is so safe that Baxter’s developer, Rethink Robotics, which loaned Baxter to Vanguard Plastics, believes it can work seamlessly alongside its human coworkers.

Saturday, January 19, 2013

Genkou Youshi Template for OpenOffice / LibreOffice

Writing assignments on genkou youshi are a staple of Japanese language classes. Tradition and the need to practice Kanji writing often dictate that such works be handwritten, but there's no reason one couldn't first compose the text on a computer (where editing, revision and indeed writing itself are much easier) and only reach to paper and pencil when the final version is ready.

Experience has taught me that hand-copying texts from a computer screen is much quicker and less error-prone when both digital document and paper share the same layout, and of course it's best if I can print genkou youshi sheets at my own leisure, rather than go out and buy them (not many stationery shops this side of the world have them, anyway). Searching the web it is relatively easy to find a genkou youshi template for Microsoft Word, but Open Document Format equivalents are harder to come by – and while it's possible to use the Word templates on OpenOffice / LibreOffice, rendering problems such as misaligned grids and hidden hanging punctuation are often present, which is kind of frustrating for a die-hard Linux user like me.

Today as I sit down to try and create a genkou youshi template on LibreOffice, I decided to try and look it out one last time – and there I found a genkou youshi Open Template on the OpenOffice Templates web site. I'm kind of baffled as to how I didn't come across it earlier (apparently it was uploaded in 2009), so I thought I'd link to it here, so others who might also be looking for it have a better chance of finding it. So there.

Friday, January 4, 2013

batcher - simple shell wrappers for Python

One of my favorite Linux features is how repetitive tasks can be automated via shell scripts. Unfortunately, the Bourne shell language and its variations (e.g. Bash) are bogged down by a number of idiosyncrasies – such as the nearly constant need to enclose variable references in quotes, the awkwardness of conditional constructs, the difficulties involved in performing simple arithmetics and so on – which needlessly complicate development. On the other hand, the ability to directly invoke user shell commands, scripts and command-line applications is a convenience seldom matched by alternatives, which explains why we mostly put up with it.

A while ago I wanted to write a relatively complex automation script, and not looking forward to doing the required text processing in Bash, decided instead to try my luck with Python, using Popen objects to invoke the needed command-line applications and collect their outputs. In order to make this task simpler, I came up with the function below:
def batch(*args, **options):
    options.setdefault('stdout', PIPE)
    options.setdefault('stderr', STDOUT)
    process = Popen(args, **options)
    return process.stdout
This allowed me to interface to shell tools in a straightforward way, for example:
for line in batch('git', 'status', '-s', cwd=path):
    # Do some line-oriented processing with the command's output
While it was simple and worked well enough, this interface surely had room for improvement. It bothered me that I had no access to the Popen object driving the shell process, but only to its stdout output object; I also felt it was wasteful that the process would run to completion even if control broke off the loop before it finished. Finally, on an aesthetic note, I thought it would be nice if there was some "automagic" way to turn command names into callables, so I could e.g. do git('status', '-s') instead of batch('git', 'status', '-s').

After some tinkering with Python's reflection API, I came up with the code below:
#! /usr/bin/env python
#coding=utf-8

# batcher.py
# Dynamic interfaces to shell commands

from subprocess import Popen, PIPE, STDOUT
from sys import modules

class batch(Popen):
    r'''A running shell command or script.
    '''
    def __init__(self, command, args, options):
        args = (command,) + args
        options.setdefault('stdout', PIPE)
        options.setdefault('stderr', STDOUT)
        Popen.__init__(self, args, **options)
        self.daemon = options.get('daemon', True)

    def __del__(self):
        if self.daemon:
            self.close()
        else:
            Popen.__del__(self)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.close()

    def __iter__(self):
        return self

    def close(self):
        if self.returncode != None:
            return

        try:
            self.kill()
        except:
            pass

    def next(self):
        return self.stdout.next().rstrip()

class batcher_module(object):
    r'''An extension to the default module object, which creates new
        command-calling functions as they are imported.
    '''
    def __init__(self, module):
        self.module = module

    def __getattr__(self, name):
        try:
            return getattr(self.module, name)
        except AttributeError:
            pass

        def batcher(*args, **options):
            return batch(name, args, options)

        setattr(self.module, name, batcher)
        return batcher

modules[__name__] = batcher_module(modules[__name__])
When a symbol is imported from the batcher module, the batcher_module object first checks whether it already exists. If it doesn't (which is most likely), the symbol is created and bound to a function that will run the correspondingly-named shell command when called. That function works by instantiating an object of the batch class, which inherits from Popen and adds the following customizations and extensions:
  • By default both standard and error outputs are collected in the stdout attribute. This can be changed at instantiation time using the named arguments stdout and stderr;
  • Whereas Popen objects try to remain alive for as long as the underlying process is active, batch objects work the other way around by killing the process (if not yet finished) when they're selected for garbage collection (the original behavior can be restored by passing the daemon named argument with a value of False);
  • batch objects are iterable, returning the next (right-trimmed) line of output at each iteration;
  • batch objects are also their own context managers, killing the underlying process (if not yet finished) when the context is exited;
  • Finally, batch objects implement the close() method, which kills the underlying process if it hasn't yet finished, and does nothing otherwise.
Using the batcher module makes it possible to write Python scripts that seamlessly interface with shell applications, for example:
#! /usr/bin/env python
#coding=utf-8

# repo_dirty.py - scans a repo base for git projects containing non-commited changes

from re import search
from batcher import git, repo

def gitdirty(path):
    for line in git('status', cwd=path):
        if search(r'(On branch master)|(nothing to commit)', line) != None:
            print 'Project "%s" is dirty' % path
            return True

    return False

def repodirty():
    projects = 0
    dirty = 0
    for path in repo('forall', '-c', 'pwd'):
        projects += 1
        dirty += 1 if gitdirty(path) else 0

    print 'Finished checking dirty projects'
    print 'Total projects checked: %d' % projects
    print 'Dirty projects: %d' % dirty

def main():
    repodirty()

if __name__ == '__main__':
    main()
For the past few days I have been using this interface to rewrite some of my own shell scripts in Python, and I am startled with the results. So far it worked without a hiccup; being able to use Python on shell automation duties brought great improvements to performance and reliability, as well as my own personal satisfaction with the resulting code. Between Python's power and this newfound seamless integration to the shell environment, I now see seldom reason to ever bother writing a shell script again.

Tuesday, April 3, 2012

Boot2Gecko and The Infinite Indifference

Vision Mobile's Stijn Schuermans reports the Boot2Gecko demonstration at MWC 2012, and discusses the system's perspectives on the current environment. His point is that Telefonica (and possibly later other carriers) could employ it as the base for a commodity application ecosystem, that would wrestle control of the market – and hopefully revenues – back from Apple and Google.

Of course, mobile operators already have a web technologies-based platform with which to fight Apple and Google. It's called the Wholesale Application Community (WAC): it's got a Javascript API, a W3C-compatible application packaging model, an infrastructure for operator-local app stores, the support of a string of carriers, model manufacturers and IT companies – and is going nowhere but down.

Did you know that Android is, on paper, the product of the Open Handset Alliance? That's a consortium of more than 80 companies – yet Google seems to be the only one actually working for its progress, while the others do little more than port the software to half-baked reference hardware and slap their logos on top of the things.

Technology is not the problem, lack of compromise is. Players in the mobile industry will gather to draw up (and sometimes even implement) standards all the time; getting any one of them to promote its use afterwards is another matter entirely. The whole mobile industry is terribly inertial: that's how they got driven off to the borders of their own market by Apple and Google to begin with. That's why WAP languished for years until being crushed under the rise of the mobile web, why WAC is stillborn, and why IMS will ultimately prove irrelevant.

The reason Boot2Gecko just might succeed is not technology, Telefonica's support or the increasing marginalization of carriers. The best thing it's got going for it is Mozilla's role as the driving force behind the platform. Just as with Android and Google, they've got the will to keep promoting it long after other involved parties have lost interest (which if experience is any guide, will happen within seconds of the 1.0 release).

If Mozilla can attract developer mindshare and drag the carriers and product manufacturers to provide consistent support, then Boot2Gecko may realize that vision of a web application platform which goes back all the way to WAP. Of course history is against it, but it's the best chance we've got so far.

Wednesday, February 22, 2012

A Python Implementation of The Log-Polar Transform, Redux




One of my first posts to this blog presented a Python implementation of the log-polar transform. Back then I was just beginning to learn NumPy, and didn't know many of its more useful tricks; in particular, I had no domain of fancy indexing, and did not know that it could be used to avoid the need for time-consuming Python loops. Besides that, I later realized that the algorithm I chose to implement, taken from an article I had read at the time, was unnecessarily complicated.

A couple of months ago I was considering the use of the log-polar transform for another project, and thought I should go back and rewrite my early implementation. I wanted to make use of the NumPy expertise I've earned since then, but also clean up my early blunder and present a simpler algorithm, that could be easily ported to other languages. The results are available below, and also for download in a nice package, with test code and thoroughly commented sources.

The first listing presents a "naive" implementation, which relies on Python loops:
def logpolar_naive(image, i_0, j_0, p_n=None, t_n=None):
    (i_n, j_n) = image.shape[:2]
    
    i_c = max(i_0, i_n - i_0)
    j_c = max(j_0, j_n - j_0)
    d_c = (i_c ** 2 + j_c ** 2) ** 0.5

    if p_n == None:
        p_n = int(ceil(d_c))
    
    if t_n == None:
        t_n = j_n
    
    p_s = log(d_c) / p_n
    t_s = 2.0 * pi / t_n
    
    transformed = zeros((p_n, t_n) + image.shape[2:], dtype=image.dtype)

    for p in range(0, p_n):
        p_exp = exp(p * p_s)
        for t in range(0, t_n):
            t_rad = t * t_s

            i = int(i_0 + p_exp * sin(t_rad))
            j = int(j_0 + p_exp * cos(t_rad))

            if 0 <= i < i_n and 0 <= j < j_n:
                transformed[p, t] = image[i, j]

    return transformed
The second version constructs a pair of NumPy fancy indices first – cached for later reference – and then uses them to perform the transform:
_transforms = {}

def _get_transform(i_0, j_0, i_n, j_n, p_n, t_n, p_s, t_s):
    transform = _transforms.get((i_0, j_0, i_n, j_n, p_n, t_n))

    if transform == None:
        i_k = []
        j_k = []
        p_k = []
        t_k = []

        for p in range(0, p_n):
            p_exp = exp(p * p_s)
            for t in range(0, t_n):
                t_rad = t * t_s

                i = int(i_0 + p_exp * sin(t_rad))
                j = int(j_0 + p_exp * cos(t_rad))

                if 0 <= i < i_n and 0 <= j < j_n:
                    i_k.append(i)
                    j_k.append(j)
                    p_k.append(p)
                    t_k.append(t)

        transform = ((array(p_k), array(t_k)), (array(i_k), array(j_k)))
        _transforms[i_0, j_0, i_n, j_n, p_n, t_n] = transform

    return transform

def logpolar_fancy(image, i_0, j_0, p_n=None, t_n=None):
    (i_n, j_n) = image.shape[:2]
    
    i_c = max(i_0, i_n - i_0)
    j_c = max(j_0, j_n - j_0)
    d_c = (i_c ** 2 + j_c ** 2) ** 0.5
    
    if p_n == None:
        p_n = int(ceil(d_c))
    
    if t_n == None:
        t_n = j_n
    
    p_s = log(d_c) / p_n
    t_s = 2.0 * pi / t_n
    
    (pt, ij) = _get_transform(i_0, j_0, i_n, j_n, p_n, t_n, p_s, t_s)

    transformed = zeros((p_n, t_n) + image.shape[2:], dtype=image.dtype)

    transformed[pt] = image[ij]
    return transformed
Both implementations are based on a "reverse transform" algorithm: rather than iterate over the Cartesian image calculating where each pixel fits in the transform (which resulted in all sorts of complications), iterate over the transform's cells and calculate which, if any, pixel from the Cartesian image should be put there.

According to my tests, the "fancy" version using a cached pair of indices runs about 10 times faster than the "naive" version – but even when it has to construct the indices before using them, it's still slightly faster.