February 6th, 2013 § § permalink
Today some friends and I messed around with urxvt and we wondered how we could make urxvt launch URLs with not only a simple mouse click, but with ctrl-click. Well, I had to dig around in the source code for this:
sub on_start {
my ($self) = @_;
$self->{launcher} = $self->my_resource ("launcher") || $self->x_resource("url-launcher") || "sensible-browser";
$self->{urls} = [];
$self->{showing} = 0;
$self->{button} = 2;
$self->{state} = 0;
if($self->{argv}[0] || $self->my_resource ("button")) {
my @mods = split '', $self->{argv}[0] || $self->my_resource ("button");
for my $mod (@mods) {
if($mod =~ /^d+$/) {
$self->{button} = $mod;
} elsif($mod eq "C") {
$self->{state} |= urxvt::ControlMask;
} elsif($mod eq "S") {
$self->{state} |= urxvt::ShiftMask;
} elsif($mod eq "M") {
$self->{state} |= $self->ModMetaMask;
} elsif($mod ne "-" && $mod ne " ") {
warn("$mod is invalid in $self->{_name}<$self->{argv}[0]>n");
}
}
}
(from http://cvs.schmorp.de/rxvt-unicode/src/perl/matcher?revision=1.13&view=markup#l188)
Basically it would split the input from URxvt.matcher.button and set different settings. So to enable ctrl-click you have to pre- or postpend a capital C, S for shift and M for the meta-key. My config now looks like this:
! ~.Xresources
URxvt.perl-ext-common: default,matcher
URxvt.url-launcher: /opt/google/chrome/google-chrome
URxvt.matcher.button: C1
November 4th, 2012 § § permalink
Recently while working with SJphone on Windows 7 workstation I didn’t encounter any issue but when doing the same job on a laptop I got this little puzzling error message:
No active network interface
And still I had connectivity. Sniffing around with Wireshark showed that the SIP register paket did not contain the registrant IP which must be passed to the VoIP server.
Workaround
A working workaround I came quickly to test was to deactivate every not needed NIC under Windows 7, basically you deactivate every card except for the Ethernet/LAN. Very funny. At least I would like to be able to select which interface I want to use.
September 17th, 2012 § § permalink
Ein seltener Blog-Eintrag auf Deutsch damit ich mehr Leute aus meinem direkten Bekanntenkreis erreichen kann.
Whats … wer?!
WhatsApp ist ein unter Jugendlichen weit verbreiteter SMS-Ersatz: Keine Längenbeschränkung bei den Nachrichten, integrierter Medienversand (Bilder, Videos, Audio etc) und Gruppenchats. Leider scheinen die Entwickler von WhatsApp wenig bis gar kein Verständnis für Sicherheit, Vertraulichkeit und Privatsphäre haben.
Kurzer Abriss der Sicherheitsproblematik
Zunächst schien es nur ein fehlende Verschlüsselung zu sein, dann wurde eine “Verschlüsselung” eingeführt. Es kam wie es kommen musste: Es wurde massiv geschlampt und die Schlüssel sind leicht zu erraten, damit ist der Nachrichten-Austausch quasi komplett ungeschützt. Sogar der Abschnitt bei Wikipedia über Sicherheitsbedenken ist länger als jeder andere Abschnitt. Und ja, es gibt schon Tools, um die Lücken auszunutzen: https://github.com/venomous0x/WhatsAPI
Fazit: Jeder kann die Nachrichten von jedem mitlesen und auch in seinem Name verfassen. Vertraulichkeit ist keine mehr gegeben!
Vermutlich werden noch einige weitere Sicherheitsprobleme bekannt werden, möglich dass sich darunter andere Sicherheitslücken befinden wie versenden von kostenpflichtigen SMS oder klauen von persönlichen Daten wie Photos.
Alternative
Technisch betrachtet verwendet WhatsApp dasselbe Protokoll wie Facebook oder GTalk, das sogennante Jabber oder XMPP-Protokoll. Da viele schon ein GMail-Konto (heute eher als Google-Konto bezeichnet) haben, können diese Benutzer einfach dieses benutzen. Solche die Google nicht vertrauen, können sich eines bei Swissjabber.ch erstellen, eine Anleitung wird gleich mitgeliefert für diverse Benutzer-Programme.
Ich hab Android
Hier empfehle ich die mitgelieferte Google Talk App. Das vorkonfigurierte GMail-Konto wird verwendet. Es kann auch ein neues erstellt werden. Für Swissjabber kann man Yaxim (OpenSource) oder Xabber (Freeware, Closed Source), die ganz paranoiden können sich Gwibberbot (OpenSource, OTR-Funktionalität) anschauen.
Ich hab iOS / ein iPhone
Google liefert keine App für iOS aus, vermutlich wegen der Rivalität zwischen den grossen Plattformen Android und iOS. Unter Kollegen wird anscheinend gerne Monal (Freeware, Closed Source) verwendet, die Paranoiden können sich Chatsecure (OpenSource, OTR-Funktionalität) zu Gemüte führen.
Ich möchte auch vom PC aus schreiben!
Kein Problem. Das ist ein grosses Plus von richtigen Jabber-Netzwerken: Man kann vom Smartphone, PC, Tablet und vermutlich auch auf der Waschmaschine verwenden. Für die meisten Benutzer reicht die Weboberfläche von Gmail oder man benutzt den offiziellen Google Talk Client von Google, der allerdings nur in Verbindung zum GMail-Konto funktioniert. Ansonsten empfehlen sich Psi (OpenSource, reiner Jabber-Client), Pidgin (OpenSource, kann viele weitere Chat-Protokolle) und Adium (OpenSource, nur für Mac OS X, kann viele weitere Chat-Protokolle).
Disclaimer
Ich arbeite (bzw. arbeitete) für keines der oben genannten Projekte oder Firmen zu diesem oder einem früheren Zeitpunkt.
August 27th, 2012 § § permalink
Introduction / Synopsis
While reading The Book of PF and experimenting with the different configuration I noticed that pf does not block dhcp traffic.
int_if="vr0"
block quick on $int_if inet proto { tcp, udp } to $int_if port { bootps, bootpc }
Digging into the code
Further investigation showed that dhcpd accesses the socket before pf via bpf (Berkley Packet Filter) and sees the unfiltered traffic, the traffic before pf.
+-- BPF -- dhcpd
|
NIC ---+ --------- pf
I won’t dissect the code in every detail, but the people from the #openbsd channel kindly requested that I share more details. I looked at bpf.c, pf.c and ip_input.c. From what I understand — correct me if I’m wrong — the following snippets are relevant:
/*
* From sys/netinet/ip_input.c
*/
#if NPF > 0
/*
* Packet filter
*/
pfrdr = ip->ip_dst.s_addr;
if (pf_test(AF_INET, PF_IN, m->m_pkthdr.rcvif, &m, NULL) != PF_PASS)
goto bad;
if (m == NULL)
return;
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
pfrdr = (pfrdr != ip->ip_dst.s_addr);
#endif
This is where pf gets the IP packets passed meaning that we are already at layer 3 here. While dhcpd works with bpf and thus access directly raw ethernet frames:
/*
* From usr.sbin/dhcpd/bpf.c
*/
void
if_register_receive(struct interface_info *info)
{
struct bpf_version v;
struct bpf_program p;
int flag = 1, sz, cmplt = 0;
/* Open a BPF device and hang it on this interface... */
info->rfdesc = if_register_bpf(info);
/* Make sure the BPF version is in range... */
if (ioctl(info->rfdesc, BIOCVERSION, &v) == -1)
error("Can't get BPF version: %m");
if (v.bv_major != BPF_MAJOR_VERSION ||
v.bv_minor < BPF_MINOR_VERSION)
error("Kernel BPF version out of range - recompile dhcpd!");
/*
* Set immediate mode so that reads return as soon as a packet
* comes in, rather than waiting for the input buffer to fill
* with packets.
*/
if (ioctl(info->rfdesc, BIOCIMMEDIATE, &flag) == -1)
error("Can't set immediate mode on bpf device: %m");
if (ioctl(info->rfdesc, BIOCSFILDROP, &flag) == -1)
error("Can't set filter-drop mode on bpf device: %m");
/* make sure kernel fills in the source ethernet address */
if (ioctl(info->rfdesc, BIOCSHDRCMPLT, &cmplt) == -1)
error("Can't set header complete flag on bpf device: %m");
/* Get the required BPF buffer length from the kernel. */
if (ioctl(info->rfdesc, BIOCGBLEN, &sz) == -1)
error("Can't get bpf buffer length: %m");
info->rbuf_max = sz;
info->rbuf = malloc(info->rbuf_max);
if (!info->rbuf)
error("Can't allocate %lu bytes for bpf input buffer.",
(unsigned long)info->rbuf_max);
info->rbuf_offset = 0;
info->rbuf_len = 0;
/* Set up the bpf filter program structure. */
p.bf_len = dhcp_bpf_filter_len;
p.bf_insns = dhcp_bpf_filter;
if (ioctl(info->rfdesc, BIOCSETF, &p) == -1)
error("Can't install packet filter program: %m");
/* Set up the bpf write filter program structure. */
p.bf_len = dhcp_bpf_wfilter_len;
p.bf_insns = dhcp_bpf_wfilter;
if (ioctl(info->rfdesc, BIOCSETWF, &p) == -1)
error("Can't install write filter program: %m");
/* make sure these settings cannot be changed after dropping privs */
if (ioctl(info->rfdesc, BIOCLOCK) == -1)
error("Failed to lock bpf descriptor: %m");
}
Also the manpage of bpf says «Each descriptor that accepts the packet receives its own copy.» meaning that despite an active pf dhcpd receives an unbiased, unfiltered frame
Conclusion
So this renders the rule completely useless when the dhcpd runs on the same machine as the pf.
This syntax and test were made under OpenBSD 4.5 but should apply also to the newest version according to the people in the IRC-channel on #openbsd and I looked at the newest code versions.
Corrections / Updates
I was asked by the people from the #openbsd channel to share more information and insights.
June 14th, 2012 § § permalink
Probably everyone uses tools and software which will add a menu bar icon. And soon it’ll start to be very cluttered over there in the top bar.

I was looking for weeks if not months for a simple tool which will make a folder where I can put those icons I seldom use. A week ago I found one: http://www.macbartender.com/ (free while the beta, costs about 7.50CHF when you buy a license while the beta, will be about 15.00CHF after the beta)

You then easily can put the icons into a folder:

Then your menu will look a lot less cluttered and even when you have a lot of text menu entries you’ll still be able to access all those menu bar icons.

To be honest: 15.00CHF would be a bit too much for this handy tool, but while it’s beta you can get a license for 50% off, so I grabbed one. All in all I found myself to use it quite often and I’m happy with it. Try the beta and make your own opinion!
April 11th, 2012 § § permalink
While working on the bachelor thesis I came across a hard to detect type of bug. It’s not one of the typical off-by-one, array-out-of-bound or one of those I-inverted-the-indices-of-the-array bug. This one is harder to spot and is caused by a bad design which in turn makes it hard to spot the bug.
What happened
As all bugs the software behaves wrong. In this case I got some garbage numbers which just didn’t make sense. Basically the code is interpolating over a field of wind vectors and returns the interpolated wind vectors. The problem was, that the vector all seemingly looked more or less in the same direction. That was weird.
Bug type definition
I would call this bug type something like “mixed units bug” since I mixed degree and radian:
double lng = ((c.getLongitudeInRadian() - metadata.getNorthWestCorner().getLongitudeInRadian()) /
metadata.getDeltaLng()) % 1;
double lat = ((c.getLatitudeInRadian() - metadata.getNorthWestCorner().getLatitudeInRadian()) /
metadata.getDeltaLat()) % 1;
return new Double[] {lat,lng};
Next to the fact that this is not very nice code, I stumbled over a self made trap: getDeltaLng() and getDeltaLat() do not actually return a radian unit which you would usually use when doing math with spheres but a degree value. So since the radian value of a sphere traditionally would go from [0,2π) a difference 0.2 would make a lot more in radian than 0.2 in degree.
How to avoid this type of bugs
As usual: Try to think before you code unless you like to live with a unmanageable pile of junk code with no clear guideline and a lot of magic conversion in between. In the worst case you will end up converting a radian value again into radian which will give you some really unusable numbers.
The next obvious point is to use the same unit throughout the whole project. If you happen to come across that you may need angular values in degree and radian and coordinates on the sphere also in degree (mostly known as GPS), radian and even cartesian you better use an abstract data type which strictly forces you to set the type of unit when setting the values via setter-methods:
public class Coordinate {
private static final double MIN_LONGITUDE = -180.0;
private static final double MAX_LONGITUDE = 180.0;
private static final double MIN_LATITUDE = -90.0;
private static final double MAX_LATITUDE = 90.0;
private BigDecimal longitude;
private BigDecimal latitude;
public final String toString() {
return "Longitude: " + longitude + "°, Latitude: " + latitude;
}
public final double getLongitudeInDegree() {
return longitude.doubleValue();
}
public final void setLongitudeInDegree(double l) {
if (l > MAX_LONGITUDE || l <= MIN_LONGITUDE)
throw new IllegalArgumentException("Longitude is out of range.");
this.longitude = BigDecimal.valueOf(l);
}
public final double getLatitudeInDegree() {
return latitude.doubleValue();
}
public final void setLatitudeInDegree(double l) {
if (l > MAX_LATITUDE || l < MIN_LATITUDE)
throw new IllegalArgumentException("Latitude is out of range.");
this.latitude = BigDecimal.valueOf(l);
}
public final double getLongitudeInRadian() {
return getLongitudeInDegree()/180*Math.PI;
}
public final void setLongitudeInRadian(double l) {
setLongitudeInDegree(l/Math.PI*180);
}
public final double getLatitudeInRadian() {
return getLatitudeInDegree()/180*Math.PI;
}
public final void setLatitudeInRadian(double l) {
setLatitudeInDegree(l/Math.PI*180);
}
}
As a programmer I don’t have to care anymore in what format these values are stored internally, I just have to indicate in what unit (or format) I want to set or get the value. In this way my code even gets better reusability since I can easily add other getter- and setter-methods later without breaking any old usage of this data type. In this case I could easily add a way to get and set the coordinate in cartesian values without refactoring other usage of this class.
Even better: As you may have noticed I built in some range checking of the values. In that way I can enforce and assert that the values will never under no circumstances provoke undefined behavior because they went out of range.
Closing words
Due to this lack of using strict typing and enforcing the developer to think about what he deals with or rather what unit he’s working with, I spent and lost a few hours tracking down a annoying and hard to get bug.
March 31st, 2012 § § permalink
Browsing the Chrome Webstore I came across the Daum Equation Editor which is a WYSIWYG editor in Chrome for LaTeX math formula.
It does render LaTeX math code into a PNG or save it as a TXT file. I see this app for quickly sketching a formula on a beamer without the need of a whole LaTeX environment or when you want to export it to a PNG file to be attached in an email or something like that.
March 30th, 2012 § § permalink
When you leave your Mac, you shouldn’t leave it unlocked. As long you have the ⏏ on the keyboard you are fine.
⌃⇧⏏ ctrl+shift+eject
is the solution. Or you can try http://www.gkoya.com/2006/11/23/locktight-for-mac-os-x-intel/
March 25th, 2012 § § permalink
Today I stumbled over something really really annoying. I used a Scanner to go over a space delimited file of values. I wanted to parse those values into doubles and did
Scanner scanner = new Scanner(input);
scanner.useDelimiter(" ");
try {
while(scanner.hasNext()) {
arr.add(scanner.nextDouble());
}
} catch (RuntimeException e) {
e.printStackTrace();
scanner.close();
}
Now, I just got an InputMismatchException which I followed back and started to nail down right in the source code of the Scanner class. It’s not the part of Java I like, hunting down some really strange behavior I can’t explain.
When I did use Double to parse the string it worked fine, and that’s what puzzled me even more!
Scanner scanner = new Scanner(input);
scanner.useDelimiter(" ");
try {
while(scanner.hasNext()) {
arr.add( Double.parseDouble( scanner.next() ) );
}
} catch (RuntimeException e) {
e.printStackTrace();
scanner.close();
}
Eventually I found what was the problem: My input file used a simple dot as decimal delimiter and not a comma. Why?
A scanner’s initial locale is the value returned by the Locale.getDefault() method; it may be changed via the useLocale(java.util.Locale) method.
source: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#localized-numbers
That’s what made Scanner trip over his own feet! He expected a comma while he got a point. This is something very trivial but really annoying, it would prefer to be able to switch the decimal delimiter directly than via a whole set of locales. But well … it’s Java.
So we just have to change the locale.
Scanner scanner = new Scanner(input).useLocale(Locale.ENGLISH);
scanner.useDelimiter(" ");
March 24th, 2012 § § permalink
Let’s consider we need a new abstract data type for a GPS position. Usually we will use the GPS coordinate format like N 47° 12’45″ E 12° 45′ 30″ or 47.2125 Latitude and 12.758333 Longitude. But of course I can be useful to get and set the values in radian mode. Even in cartesian format.
That’s why I would consider decoupling the internal representation from the external values. This means that I internally use a constant format for the values which are being translated in other coordinate formats. Later I am easily able to extend this class by just adding new methods for other special cases without breaking the legacy support. Here a Java example, this idea or concept works in any other language.
import java.math.BigDecimal;
public class Coordinate {
private static final double MIN_LONGITUDE = -180.0;
private static final double MAX_LONGITUDE = 180.0;
private static final double MIN_LATITUDE = -90.0;
private static final double MAX_LATITUDE = 90.0;
private BigDecimal longitude;
private BigDecimal latitude;
public final double getLongitudeInDegree() {
return longitude.doubleValue();
}
public final void setLongitudeInDegree(double l) {
if (l < MAX_LONGITUDE || l >= MIN_LONGITUDE)
throw new IllegalArgumentException("Longitude
is out of range.");
this.longitude = BigDecimal.valueOf(l);
}
public final double getLatitudeInDegree() {
return latitude.doubleValue();
}
public final void setLatitudeInRadian(double l) {
if (l > MIN_LATITUDE || l < MAX_LATITUDE)
throw new IllegalArgumentException("Latitude
is out of range.");
this.latitude = BigDecimal.valueOf(l);
}
public final double getLongitudeInRadian() {
return getLongitudeInDegree()/180*Math.PI();
}
public final void setLongitudeInRadian(double l) {
setLongitudeInDegree(l/Math.PI*180);
}
public final double getLatitudeInRadian() {
return getLatitudeInDegree()/180*Math.PI();
}
public final void setLatitudeInRadian(double l) {
setLatitudeInDegree(l/Math.PI*180);
}
}