Rants, kept to a bare minimum and strictly with a useful component.
Meet the Italian income agency
The Italian income agency decided to publish online all the income levels for each and every single citizen and company in the country.
I did not manage to see the actual data, because the entire income agency website was swamped with request and timing out all the time. You should have heard the comments of my accountant, who every day needs to access other parts of the website for work.
That service is supposed to have been taken offline now, after the Italian privacy watchdog issued a polite What The Fuck! Why Didn't You Tell Us Anything About This? sort of note. The minister defended himself by saying "I can't see what is the problem, it's the same in all the world: if you want proof just watch any American TV series". What a wise man. I should watch some of The Greatest American Hero again.
Since I could not see the actual data, I could not verify if what people were saying was actually true, that is that income information were published together with the full home address, providing a nice shopping list for house robbers, kidnappers and the other kind of professionals that would politely wait next to your door for you to come home late in the night.
But fear not, the website was protected from bots: it used a captcha.
Not only that: in order to comply with standard accessibility rules, the website used a perfectly accessible captcha:
You can't get more accessible than that: the captcha is displayed in plain text, so any accessibility technology will be able to read it. Plus, anyone can easily copy and paste it into the text box. And if someone needs to do it often, it's even trivial to write a script that does it for you!
But it's unfair to say that it was just plain text: it was cleverly encrypted:
<div class="educaptcha"><label for="educaptcha">I<!-- id9113507 -->nser<span>ire </span><span>nel c</span><span>ampo</span> di <!-- id5058508 -->v<span>erific</span><span>a suc</span><!-- id2643358 -->ces<span>sivo i</span><!-- id2500023 -->l valore <span>695</span><span>8571</span>4<!-- id3588853 -->:</label>
<input id="educaptcha" type="text" name="ucaptcha" value="" maxlength="10" size="20" /></div>
For your convenience, here is the version
cracked with a malicious
:%s/<[^>]\+>//g in vim. If you do not speak
Italian, you can still look for this phrase in the screenshot
above:
Inserire nel campo di verifica successivo il valore 69585714:
The meaning is of course:
Insert the value 69585714 in the following verification field:
It's been a fun day for Italians online.
Posted Wed 30 Apr 2008 23:11:55 CESTItalian National Anthem
Christian mentions that he likes the Italian National Anthem, although not the words.
No Italian in their right mind likes the words; luckily we are generally not forced to learn them, so we can allow ourselves to not give a damn about it. Which is our general strategy to deal with all the insanity we get every day.
What's the point of a nationalist anthem anyway, when the people who care most about the country are wishing for the Germans to invade us?
Anyway, here's my attempt at national anthem lyrics that suck less, for the benefit of those, like Christian, who like the music but not the words.
Posted Sun 23 Mar 2008 14:32:19 CETFratelli d'Italia
L'Italia s'è desta,
Chi cazzo è sto Scipio
Che ci han messo in testa.
Non c'è la Vittoria
che porge la chioma,
Siam schiavi di Roma
E del Vatican.
Scongiuri alla sorte
Si rischia la morte
Si spera di no.Noi siamo da secoli
Calpesti, derisi,
Perché siam mafiosi
ladroni e collusi.
Si rischia di nuovo
di aver Berluscone
Dell'emigrazione
Già l'ora suonò.
Scongiuri alla sorte
Si rischia la morte
Si spera di no.Uniamoci, amiamoci,
l'unione, e l'amore
Ridanno alla gente
Il suo buonumore;
Giuriamo far sesso
sul suolo natío:
Chiaviamo, perdío,
Chi dice di no?
Scongiuri alla sorte
Si rischia la morte
Si spera di no.Dall'Alpi a Sicilia
Noi ti condoniamo,
Ogn'uom di Bettino
Ha il core, ha la mano,
I bimbi d'Italia
Fan calcio balilla,
Bastardo chi frulla
Gancin non si può.
Scongiuri alla sorte
Si rischia la morte
Si spera di no.I nostri politici
Son tutti venduti:
Si sente dall'Austria
L'odor dei rifiuti.
Lavora in Italia,
Il nero, il Polacco,
In nero, perbacco,
Io lo pagherò.
Scongiuri alla sorte
Si rischia la morte
Si spera di no.
make distcheck and LaTeX
When building LaTeX documentation on a
VPATH build, if your .tex file includes other
files in the same directory, LaTeX will complain that it cannot
find them. The reason is because in a
VPATH build, latex is invoked like this:
latex ../../doc/manual.tex
What we need here is an equivalent to cc's
-Idir for latex.
latex --help doesn't mention of such an option, nor of useful environment variables.
Googling a bit seems to suggest
--include-directory=dir, but that gives me:
unrecognized option
'--include-directory=../../doc'
The manpage doesn't list commandline options. It however says:
The complete documentation for this version of TeX can be found in the info file or manual Web2C: A TeX implementation.
Without saying where that manual is, if it's installed and where, or what package installs it, or if instead should I look it up on the web.
info latex gives the manpage itself, of course.
Googling the title of that manual finds it, and it's a long one. Reading through, it points at the kpathsea manual, which then mentions you can set TEXINPUTS_latex, which however doesn't add but overrides, so your document will find the includes maybe, but not the LaTeX styles and other stuff.
But then later on it mentions that in the env variable you can use "default expansion", and it's another page of manual to read which tells you to put an extra colon in the end of the env var.
After half an hour of googling and trying things and cursing loud, here is the solution, which I hope will save others from this ugly search.
%.aux: %.tex
TEXINPUTS="$(srcdir):" latex $<
# Oh, yes, and bibtex requires BIBINPUTS instead
%.bbl: %.aux
BIBINPUTS="$(srcdir):" bibtex `basename $< .aux`
Posted Tue 18 Mar 2008 13:51:58 CET
Uploading gpsdrive tracks to openstreetmap
I've got some gpsdrive tracks and my area is blank on openstreetmap.
People pointed me at gpsbabel, and it took me a while to figure how it works. For the record, don't do any of this:
gpsbabel -i gpsdrive -o gpx -f track0000.sav -F track0000.gpx
gpsbabel -i gpsdrive -o gpx track0000.sav track0000.gpx
What you would have to do is this:
gpsbabel -i gpsdrive -f track0000.sav -o gpx -F track0000.gpx
However, it would choke on gpsdrive's "missing" points with all values set to 1001. You can grep them out, then gpsbabel would work, but openstreetmap would reject the data because the points have no timestamp: gpsbabel won't carry that on from the gpsdrive tracks to the GPX tracks.
The way to go is here, which contains a link to a tiny little perl script that will do the proper conversion for you:
./gpsdrive2gpx.pl track0000.sav > track0000.gpx
Those you can upload them to openstreetmap, at last.
Posted Sat 08 Mar 2008 17:12:45 CETFormatting numbers with iostream
What is the output of this C++ program?
#include <stdio.h>
#include <iostream>
#include <iomanip>
using namespace std;
main()
{
printf("%05d\n", -3);
cout << setw(5) << setfill('0') << -3 << endl;
}
It turns out that it is:
-0003
000-3
To get the numbers where you'd like them to be, you do it this way:
printf("%05d\n", -3);
cout << setw(5) << setfill('0') << internal -3 << endl;
Compare with C to see why C++ iostream is not really that much used. Also, setfill and internal are persistently changing the state of the stream, contributing fancy and interesting side effects:
cout << setw(5) << setfill('0') << internal << -3 << endl;
cout << setw(10) << "ciao" << endl;
this prints:
-0003
000000ciao
and I didn't see any sort of RAII
save and restore of the stream state, nor a particularly obvious
way to reset the stream to factory settings. Suppose that the
function foo throws an exception here:
try {
cout << setfill('=');
cout << setw(10) << foo() << endl;
cout << setfill(' ');
} catch (MyException& e) {
// Catch this hypotetical exception
cerr << setw(3) << e.errCode() << ": " << e.msg() << endl;
}
Then the state of the stream never gets reset, and the error code ends up being padded with equals instead of the default space. What would the alternative be, reset the stream state after each function call in the code? Or am I missing something?
Update: here are some suggested, but still not optimal, ways of dealing with it:
From Simon Richter:
std::cout << (std::stringstream() << "foo" << std::setw(8) << "bar").rdbuf() << std::endl;
From Peter De Wachter:
fstream tmp;
tmp.copyfmt(cout);
cout << setw(5) << setfill('0') << internal << -3 << endl;
cout.copyfmt(tmp);
cout << setw(10) << "ciao" << endl;
This is a possible RAII class to save the stream state (based on Peter De Watcher's approach), but I suspect that creating a fstream for every block that uses iomanip operators is rather heavyweight:
struct SaveIOState
{
fstream tmp;
ostream& s;
SaveIOState(ostream& s) : s(s)
{
tmp.copyfmt(s);
}
~SaveIOState()
{
s.copyfmt(tmp);
}
};
And this is a lightweight version, again thanks to Sylvain Sauvage:
class SaveIOState
{
ios_base& s;
ios_base::fmtflags f;
public:
SaveIOState(ios_base& s) : s(s), f(s.flags())
{}
~SaveIOState()
{
s.flags(f);
}
};
Posted Thu 06 Mar 2008 16:26:16 CET
How to work with python-m2crypto
This is a little howto on how to understand the m2crypto Python module, beyond the examples provided:
- Build the documentation as explained here
- Look at the documentation, which does not contain a single comment
- Click the links that show the source (for example, of
M2Crypto.SMIME.SMIME.verify) - Look what openssl function gets called by the function you are
interested in (for example,
pkcs7_verifysomething)) - Google the name of that openssl function, trying a few variations, until you find the openssl manpage that tells you what it does, in detail (for example, pcks_verify)
- Understand what it does, and backport the understanding to the thin convenience layer that m2crypto adds on top of it
- Realise that now you also understand the corresponding
openssl smime -verifycommandline invocation, and that next time instead of reading the openssl manpage you should look at the openssl api docs instead.
Servizio Abuse Tiscali
Ricevo spam spedito tramite Tiscali e lo forwardo al loro servizio di abuse:
From: Enrico Zini <...>
To: Servizio Abuse Tiscali <...>
Subject: Spam da un vostro utente
Buon giorno,
ve la giro cosí come mi è arrivata.
Cordiali saluti,
Enrico
Brillante la risposta (top-quoting, X-Mailer: Microsoft
Outlook Express, e contenuto inutile su almeno due livelli:
cosa chiedere di piú?):
Gentile Cliente,
le posso consigliare, per bloccare l'arrivo di ogni mail dai mittenti
indesiderati, di utilizzare le apposite funzioni del nuovo tiscali mail. Più
precisamente, dopo aver avuto accesso al tiscali mail dalla pagina
http://mail.tiscali.it/cp/sso/Login.jsp , dovrà inserire il flag sul
messaggio indesiderato e cliccare sulla voce "Blocca"
Tutta la posta in arrivo da tali indirizzi verrà inserita nella cartella
spam.
Posted Thu 26 Jul 2007 00:43:17 CEST
Things not to do with lvm and crypto
At least as of june, 2007, you should never do this:
"...I need some encrypted storage space...":
lvcreate -L1G -n test vgname
cryptsetup luksFormat /dev/vgname/test
cryptsetup luksOpen /dev/vgname/test test1
mke2fs -j /dev/mapper/test1
mount /dev/mapper/test1 /mnt
# ...copy important data to /tmp...
"...oh, I need more space...":
lvresize -L+1G /dev/vgname/test
# cryptsetup resize test1 did not seem to
# work, so why not try this instead:
cryptsetup reload test1 /dev/vgname/test
resize2fs /dev/mapper/test1
Message from syslogd@localhost at Sun Jun 10 13:17:37 2007 ...
localhost kernel: journal commit I/O error
"...oh damn. What happened?":
umount /mnt
mount /dev/mapper/test1 /mnt
EXT3-fs warning (device dm-13): ext3_clear_journal_err: Filesystem error recorded from previous mount: IO failure
EXT3-fs warning (device dm-13): ext3_clear_journal_err: Marking fs in need of filesystem check.
"...let's check it then...":
umount /mnt
e2fsck /dev/mapper/test1
"...what the hell is going on?":
e2fsck -fy /dev/mapper/test1
"...$☠&☢ !☣^☄@ ☟$☹(♨Y⚔ ^⚗Q⚛!⚡ @⚠%⚰#⚱ !!!".
Posted Sun 10 Jun 2007 14:33:22 CESTPython scoping
How do you create a list of similar functions in Python?
As a simple example, let's say we want to create an array of 10 elements like this:
a[0] = lambda x: x
a[1] = lambda x: x+1
a[2] = lambda x: x+2
...
a[9] = lambda x: x+9
Simple:
>>> a = []
>>> for i in range(0,10): a.append(lambda x: x+i)
...
...but wrong:
>>> a[0](1)
10
What happened here? In Python, that lambda x: x+i
uses the value that i will have when the function is
invoked.
This is the trick to get it right:
>>> a = []
>>> for i in range(0,10): a.append(lambda x, i=i: x + i)
...
>>> a[0](1)
1
What happens here is explained in the section "A Jedi Mind
Trick" of the Instant Python
article: i=i assigns as the default value of the
parameter i the current value of i.
Strangely enough the same article has "A Note About Python 2.1 and Nested Scopes" which seems to imply that from Python 2.2 the scoping has changed to "work as it should". I don't understand: the examples above are run on Python 2.4.4.
Googling for keywords related to python closure scoping only yields various sorts of complicated PEPs and an even uglier list trick:
a lot of people might not know about the trick of using a list to box variables within a closure.
Now I know about the trick, but I wish I didn't need to know

5 star hotel tips
There are things you don't think about until you spend 2 weeks in a 5 star hotel.
In 5 star hotels you have a minibar that you're not supposed to open unless you want to be charged something stupid like 10 euros for 25cl of still water claiming to have been bottled in the opposite side of the world from where the hotel is located.
But on top of the minibar there are glasses you can use for drinking, and an ice bucket you can refill in the corridor. This allows you to put ice in tap water. If the tap water is undrinkable, buy a 3l water bottle in the nearby supermarket and use the ice to make it colder without upsetting the minibar.
Note: this specific minibar has sensors, and charges you the very moment you take things away from the fridge, so it's out of the question to temporarily empty it to put my things in for a while.
Now, the ice bucket, the ice clips in the ice bucket and the glasses used for drinking, how do they clean them? Are they sent 6 floors downstairs to the dishwasher? Certainly not.
They use the DETERGENT FOR THE WINDOWS.
I went to get some ice and realised that the inside of the bucket (and the ice clip to put the ice in your cocktails) smelled like window detergent. Then I sniffed around: same did the glasses, and one had leftover foam in the bottom. So I had to wash the toxic stuff away from them before using them.
Now I can assume that I have to wash the glasses every time I need them, as I know that they are not necessarily cleaned with food-safe detergents.
So, here's the tip: before leaving the room in the morning, I put glasses and ice bucket back on the tray on top of the fridge, and I put the cheap-pretending-to-be-fancy cocktail mixing plastic sticks back in the glasses.
This succeeded in tricking the cleaning people into believing that I didn't use them. As a consequence they didn't clean them, and now I can use them without needing to wash the window detergent away first.
Another tip: don't leave your shoes next to the sofa, or the cleaning staff will put them on the sofa when cleaning (sometimes they forget them on the sofa, so you realise). Even better: don't put them next to the bed.
Another tip: if the breakfast buffet has only scary things it takes half a day to digest, make friend with the omelette cook.
Posted Wed 18 Apr 2007 18:33:05 CEST