tisdag 19 oktober 2010

Ternary operators i Java

Okej, jag kan vara lätt kod-fascistisk ibland, och jag uppskattar ett fläskigt syntax-solo lika mycket som the next nerd, men ternary operators, eller shorthand eller the child ny any other name osv borde avskaffas omedelbart i kod som skall läsas av många människor. Jag är ju ogärna gnällig men efter att ha stött på detta fenomen som kräver massor av tid varje gång av mig (eftersom det inte är direkt uppenbart vad ditt statement gör så måste jag naturligtvis läsa det och tolka det) så tänkte jag att jag bloggar en liten kommihåglapp så jag kan översätta snabbare.

Ta exemplet
minVal = (a < b) ? a : b;
där vi trivialt sätter det minsta av 2 värden (a och b då i det här fallet) till minVal. Motsvarande vanlig ifsats borde typiskt vara
if ( a < b ) { minVal = a; } else { minVal = b; }
men det är ju helt förkastligt att skriva om man vill imponera på folk med sin syntax-skill. Vilket natruligtvis är häftigt i nördsammanhang där och då, men när nyanställda putte ska laga ett PMD-fel från cruisecontrollen och hittar en lång jäkla harrang som han inte riktigt hänger med i så öppnar man ju upp för skapande av ett fel i koden som enbart beror på att man inte kunde kamma sig och skriva en vanlig bond-ifsats istället.

Naturligtvis är det inte fel att använda denna fina funktion som Sun stoppat in i specen, men jag skulle säga att det nog kan tänkas vara moraliskt snarare än tekniskt. Generellt så funkar det iaf så här
resultat = test ? värde1 : värde2;
eller med if/else
if ( test ) { resultat = värde1; } else { resultat = värde2; }
så det är ju förstås inte helt svårt när man väl vänjer sig. Ett bra exempel taget ur vanliga livet (något förvanskat förstås men ändå) är följande.
Iterable<Grupp> kanskeTom = listaMedPoster.iterator().hasNext() ? listaMedPoster : Arrays.asList(Grupp.EMPTY);

och efter en städning (fick PMD-warnings på raden)
Iterable<Grupp> kanskeTom = null; 
if(listaMedPoster.iterator().hasNext()) {  
    kanskeTom = listaMedPoster 
} else 
    kanskeTom = Arrays.asList(Grupp.EMPTY);  
så nästa gång du funderar på att köra shorthand, tänk på mig som istället för att skumma igenom din kod kommer behöva tänka flera sekunder till på din ifsats.

torsdag 7 oktober 2010

Android och IPSec/L2TP på Ubuntu.

Efter att ha trollat med att sätta upp en VPN som min telefon kan använda kan jag lätt konstatera att det inte fanns så där jättemånga "bra" howtos på teh internets. Så här gjorde jag.

1. Installera/configurera Openswan
För att kryptera IP-paketen vill vi installera Openswan som tillhandahåller kryptering och autentifiering för att skeppa paket mellan din enhet och din server. Här kör alla Openswan så det gjorde jag med.
sudo aptitude install openswan

och därefter så passade jag på att stoppa in följande i min /etc/ipsec.conf :

version 2.0
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
oe=off
protostack=netkey

conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=VPNSERVERNS.INTERNA.IP
leftprotoport=17/1701
right=%any
rightprotoport=17/%any

och passade därefter på att sätta lösenordet för att kryptera paket in till mitt fina intranät genom att skriva följande i min /etc/ipsec.secrets :

VPNSERVERNS.INTERNA.IP %any: PSK MITT LÖSENORD

och eftersom Openswan gnällde en hel massa på diverse så passade jag på att köra följande kommando i mitt fina shell :

for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done

och därefter så verifierade jag att allt var ok och därefter starta om Openswan genom att yppa de magiska orden (tillsammans med en magisk gest) :

sudo ipsec verify
sudo /etc/init.d/ipsec restart

Om man har lust att se vad som händer så visas helt magiskt allt som händer i detta sammanhang i loggen /var/log/syslog. Leta efter det magiska IPSec connection established.

2. Installera/konfigurera L2TP
L2TP är alltså delen som tunnlar data från din klient till ditt säkra nät. Det krypterar inte och det autentifierar inte (vilket är typ anledningen till att man måste köra IPSec framför, vilket alla, läs microsoft och apple, undviker att tänka på).

Hur som helst, installera paketet xl2tp från en apt nära dig :

sudo aptitude install xl2tpd

och konfigurera i en trevlig fil som heter /etc/xl2tpd/xl2tpd.conf :


[global]
ipsec saref = yes

[lns default]
ip range = 10.1.2.2-10.1.2.255
local ip = 10.1.2.1
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

Där alltså ip range betyder vilken range dina devices kommer få addresser i och local ip är vilken address som "vpn-adaptern" på servern kommer att få. Bra att inte sätta den i ranget som devices får ip av kan tilläggas.

Därefter passar vi på att (som vi just konfigurerade) sätta ppp-options i filen /etc/ppp/options.xl2tpd vilket osökt för oss in i nästa steg.

3. Installera/konfigurera PPP
Vi vill förstås ha nått som hanterar användarna, och till det väljer vi PPP.

sudo aptitude install ppp

som vi konfigurerar i ovan nämnda fil /etc/ppp/options.xl2tpd :

require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

och eftersom vi nu är på den så kallade "home strech" så passar vi på att lägga till ett lösenord för användaren vi tänkte oss använda när vi loggar in (man har alltså ett username/password och en delad "secret" till nätet, typ som WLAN men bättre). Detta görs med fördel i filen /etc/ppp/chap-secrets :

# user server password ip
test l2tpd testpassword *

och därefter passar vi på att starta om l2tp-demonen :

sudo /etc/init.d/xl2tpd restart

4. Routing, the final frontier.
Nu borde allt vara friden och fröjden, men det är det inte direkt eftersom man inte kommer åt nått utanför intranätet. Detta känns lite tråkigt eftersom hela poängen med vpn för mig är att kunna verka komma hemmifrån. En liten lätt routingförändring i iptables löser biffen :

iptables --table nat --append POSTROUTING --jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

och därefter är du good to go. Ett litet aber är förstås att om man kör debianpaketet för openswan från ubunturepot t.ex. så leker den inte bra nog med xl2tp på grund av versionsförbistringar, så att köra med en OSX-baserad klient funkar obra, men androidtelefoner verkar kirra biffen. Lösningen är enligt uppsago att kompilera en nyare version av openswan men det skiter jag i just nu.

Cheers. Skål och tack för en till.