Groovy & Grails und das Problem des Basic-Auth’s

Hallo zusammen,
Wieder einmal gab es ein Problem, wieder einmal wurde es gelöst
Dieses mal war meine Aufgabe, ein Login in Groovy & Grails zu machen, welches unseren LDAP-Server als Basis nimmt. Nach diversen versuchen mit dem Acegi-Plugin wurde dieser versuch aufgegeben.
Da in unserem Geschäft der Login per LDAP auch nötig ist, wenn die Anwendung selbst kein LDAP unterstützt, haben wir eine Base-Authentifizierung, welche im Hintergrund mit LDAP zusammenarbeitet.
So weit, so gut. Da ein Dashboard nötig ist, bei dem jeder Benutzer seine Einstellungen machen kann, kam die Idee auf, den Namen des Base-Authentifierzten auszulesen und als Basis zu verwenden, um intern einen neuen Benutzer zu erstellen, der wiederum in Grails eingebunden ist (dh problemlos diverse anwendungsspezifische Einstellungen u.ä speichern kann).
Also, erster Schritt, das Auslesen des Namens; normalerweise gibt es dazu eine Methode:
request.getRemoteUser()
Diese funktionierte zwar in meinem lokalen Testsystem (Tomcat 6), jedoch nicht auf unserem Produktiven Server (Apache -> Tomcat 6 -> Anwendung), was nach dem Deploy auch zackig zum temporären Absturz führte (ca 1 min).
Nun denn, eine andere Lösung musste her. Nach einigem tüfteln und suchen war klar: der Benutzername befindet sich zum einen im Request-Header, zum andern in den Attributen des Request-Objekts.
Mit der Methode "getRemoteUser" wird auf die Attribute zugegriffen, was auch das Problem war - aus irgend einem komischen Grund war der Benutzername nicht in den Attributen, dafür jedoch im Header (was jedoch nichts hilft, wenn die Methode dies grosszügig übersieht). Also hiess es: Coden
Der Basestandart sieht etwa so aus:
Base dXNlcjpwYXNzd29yZA==
Das komische Ding hinter Base ist Base64-Kodiert und enthält den Benutzernamen und das Passwort im Klartext (deshalb sollten solche Websites NIE ohne SSL verwendet werden!!!), also "übersetzt" etwa das:
Base user:password
Im Internet gibt es zahlreiche Base64-Encoder & Decoder, für die, die's ausprobieren möchten
Item - der Code um den Benutzernamen auszulesen, sieht etwa wie folgt aus (er könnte schöner sein, funktioniert jedoch):
byte[] tmpName = request.getHeader("authorization").substring(6).decodeBase64() // Substring, weil das "Base " weg muss, decodeBase64 weil mir ne Base64-Kodierung an sich nichts nützt ![]()
String full = new String(tmpName); //decodeBase64 gibt Chars in einem Array zurück - nicht das, was ich brauche, so let's make a String ![]()
int pos = full.indexOf(":"); // Das : ist das Trennzeichen der Base-Authentifizierung, dh suchen wir uns doch die Position des :
String result = full.substring(0, pos) // Jetzt wählen wir den Teil vom Anfang bis zum : (bsw dessen Position).. und was bleibt? Ja, der Benutzername
Das war das heutige Problem - im nächsten Artikel erkläre ich das Prinzip der "Hybrid-Authentifizierung".
Huawei e1762 / B81 auf *buntu 10.04…
... oder wie Mensch den M-Budget-Stick für's Mobile Internet zum laufen bekommt.
Vor einer Weile hab ich mir den M-Budget-Stick gekauft, voller vorfreude. Ich steckte das Ding ein und hoffte, dass alles out of the box funktioniert. Dem war leider nicht so.
Das grosse Internet liess mich diverse Lösungsansätze sehen, aber irgendwie wollte nichts so richtig funktionieren. Nun hab ich es jedoch hinbekommen - wer zu viel probiert, kann halt auch verhindern, dass die eigentliche Lösung läuft
In einem ersten Schritt muss man ein Package installieren:
sudo apt-get install usb-modeswitch
Der Stick hat zwei Modis: Zum einen einer als ROM/unbeschreibbarer Speicher, der alle Installationsdaten liefert (die wir unter Linux gar nicht brauchen) und zum andern den Modemmodus. Das installierte Packet ist dazu in der Lage, vom ROM-Modus in den Modemmodus zu wechseln.
Nun sollte es das doch auch jedes mal tun, wenn wir den Stick einstecken, oder?
Also machen wir mal ne hübsche Datei
sudo gedit /etc/udev/rules.d/15-huawei-e1762.rules
und fügen dort folgendes ein:
SUBSYSTEM=="usb", SYSFS{idProduct}=="1446", SYSFS{idVendor}=="12d1", RUN+="/usr/sbin/usb_modeswitch"
Spätestens nach einem Neustart des Computers sollte der standartmässig installierte Networtmanager das Modem erkennen. In Gnome kann man nun den Anbieter "Swisscom" auswählen, wodurch alle Informationen automatisch ausgefüllt werden (ausser dem PIN natürlich).
Bei KDE ist das leider anders. Dort muss man die benötigten Infos von Hand eintragen.
- Number/Nummer: *99#
- Username: gprs
- Password: gprs
- APN: gprs.swisscom.ch
Das mag komisch klingen, wenn man nicht weiss, das die Natelangebote von M-Budget über das Swisscom-Netz gehen. Dem ist aber so, deshalb stimmen die Informationen auch
Was ich ausprobiert habe und was sich nicht lohnt: Das PPA des Networkmanagers (git oder svn-zeugs) zu übernehmen. Diesem fehlt die Unterstüzung für GSM-Modems, was aber nicht klar ersichtlich ist. In einem Thread wurde dies in einem Lösungsweg beschrieben. Das trifft jedoch nur auf Ubuntu 8.* zu!
Falls dies schon gemacht wurde: PPA entfernetn, Networkmanager entfernen, sudo apt-get update, wieder installieren
Zudem noch ein kleiner Tipp: In der Originalsoftware wird das Guthaben angezeigt und kann auch aufgeladen werden - das funktioniert mit dem Networkmanager unter Linux nicht!
Man kann jedoch die Simkarte in ein Natel stecken und genau gleich wie ein Natel aufladen. Der aktuelle Stand des Guthabens ist hier ersichtlich: https://www.m-budget-mobile-service.ch/mbudget/default.asp?lang=d
Hier noch die restlichen Infos: http://www.migros.ch/DE/Supermarkt/Markenwelt/M-Budget/M-BudgetData/Seiten/Mobile.aspx
SSH-Tunnel für alle!
...und schon wieder geht es um einen SSH-Tunnel. Dieses mal habe ich herausgefunden, wie ich alle meine Programme tunneln kann.
Zuerst sollte man proxychains installieren:
sudo apt-get install proxychains
Hat man proxychains installiert, muss die Konfiguration angepasst werden:
sudo kwrite /etc/proxychains.conf
Der unterste Teil der Konfiguration sollte etwa so aussehen:
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
#socks4 127.0.0.1 9050
socks5 127.0.0.1 12345
Man sollte den Tunnel, nach Möglichkeit, bei jedem Start gleich eröffnen. Es ist ein ssh-fähiger Server nötig!
ssh -D 12345 benutzer@server
12345 ist der Port. Dieser kann ersetzt werden, muss dann aber bei der Konfiguration entsprechend berücksichtigt werden.
Nun kann man jede beliebige Anwendung per
proxychains anwendungsname
starten und durch den Tunnel laufen lassen.
Da ich die KDE-Anwendungen nutze, wollte ich auch KMail darüber laufen lassen - was nicht funktioniert. Jede KDE-Anwendung verweigert mir hier ihren Dienst.
Der Trick ist einfach, wenn man ihn kennt:
proxychains kdeinit4
Nun lässt sich jede KDE-Anwendung zwar normal starten, diese laufen aber über die SSH-Verbindung.
Liebe GIBB, ihr könnt mich nun mal! Ich hab meine Freiheit komplett zurück und brauche kein Webmail mehr
Als Alternative kann auch tsocks verwendet werden. Dort sieht die Konfiguration (/etc/tsocks.conf) so aus:
server = 127.0.0.1
server_port = 8080
Viel spass dabei
DJ Control Mp3 e2 auf Mixxx 1.7.2
Heute geht's um DJ-Zeugs
Ein Kollege von mir besitzt das DJ Control MP3 e2 (von Hercules), welches ich auch benutzen darf. Wiedereinmal gab es einige, kleine Kniffe, die jedoch, wenn man sie (wie hier) lesen kann, einfach und sauber zu erledigen sind.
Zuerst brauchen wir die Treiber - die von Hercules selbst funzen nicht direkt. Für debianer und ubuntunianer gibt's jedoch ein PPA.
Man trägt den aktuellen Teil des PPA's bei sich in der Liste ein (wenn jemand tatsächlich nicht weiss, wie, nachfragen. Ist aber grad bei Ubuntu sehr gut dokumentiert)
Derzeit sind es diese:
deb http://ppa.launchpad.net/dnjl/multimedia/ubuntu karmic main deb-src http://ppa.launchpad.net/dnjl/multimedia/ubuntu karmic main abschliessend für die Treiber macht man schlicht sudo apt-get update; sudo apt-get install hdjmod-dkms hdjcpl Dann sind die Treiber soweit installiert. Wer ohne Neustart loslegen möchte, macht in der Konsole einfach noch ein sudo modprobe hdj_mod Ich habe nun noch nicht ausprobiert, ob die Treiber bei einem Neustart auch geladen werden - ich hoffe es natürlich. Ansonsten gibt es auch hier eine Lösung. Hängt einfach an die Datei /etc/modules den Werthdj_mod an, dann wird er auf sicher geladen![]()
Nun fehlt nur noch die Konfiguration für Mixxx. Im 4. Eintrag beim Link findet sich ein Script für Mappings. Man entpackt dieses und verschiebt die 2 Dateien (eine xml, eine js) nach /usr/share/mixxx/midi/
Jetzt sind wir fast am Ziel!!!
Jetzt wird Mixxx gestartet! Unter Options->Preferences->Midi muss der Controler nun Aktiviert werden und die richtigen Bindings müssen ausgewählt werden. That's it!
Das einzige, das noch fehlt, sind die LED's - dafür gibt's derzeit keine Bindings. Der rest läuft sehr geil!
Adobe Air auf einem 64-Bit Linux
Wiedermal ein Eintrag
Dieses mal geht's um Adobe Air. Ich halte aufgrund meiner Erfahrungen mit dem Flashplayer nicht nicht von Adobe, den dieser braucht derbe viel Ressourcen, mehr als mein ganzes PIM-System oder der Musikplayer, er stürzt oft ab und reisst den FF mit (was sich dank Mozilla ab Firefox 3.6.4 ändern sollte - ENDLICH
), hat immer noch keinen anständigen 64-Bit-Support und ist properitär - ecklig!
Nun hat Adobe es auch geschafft, eine Anleitung für 64-Bit Pc's rauszubringen, um zu zeigen, wie man Adobe Air nutzen kann (http://kb2.adobe.com/cps/521/cpsid_52132.html). Wie immer geht Adobe sehr professionell vor (mensch beachte die Ironie) und beschreibt im Endeffekt, dass man den Link einer Datei ins System kopieren sollte, welche man wieder verlinkt. Das könnte ja unter Umständen irgendwie, eventuell und bei sehr unsauberen Ideen Sinn machen.
Der Aufbau ist aber lustig!
Wenn's nach Adobe geht, kopiert man die Dateien
- libnss3.so.1d
- libnssutil3.so.1d
- libsmime3.so.1d
- libssl3.so.1d
in's System. Diese sind, wie gesagt, Links und keine eigenständigen Dateien. Worauf verweisen sie?
└─(10:00:%)── ls -an /usr/lib32/libnss3.so.1d ──(Don,Apr22)─┘
lrwxrwxrwx 1 0 0 10 22. Apr 09:55 /usr/lib32/libnss3.so.1d -> libnss3.so
└─(10:28:%)── ls -an /usr/lib32/libnssutil3.so.1d ──(Don,Apr22)─┘
lrwxrwxrwx 1 0 0 14 22. Apr 09:55 /usr/lib32/libnssutil3.so.1d -> libnssutil3.so
etc..
Was sagt die Adobe-Anleitung weiter?
Jungs & Mädels, macht wieder einen Link! Und zwar mit dem Namen
libnss3.so
libnssutil3.so
Worauf sollen diese verweisen?
libnss3.so -> /usr/lib32/libnss3.so.1d
libnssutil3.so -> /usr/lib32/libnssutil3.so.1d
Gut, nun verweist z.B libnss3.so auf libnss3.so.1d. libnss3.so.1d ist aber nur ein Link auf libnss3.so. Wo bleibt die echte Datei? Es gibt sie nicht! Vorhanden sind lediglich 2 Links (pro lib!), die aufeinander verweisen...
Die Lösung des Problems
Es ist eigentlich sehr simpel! Kopiert einfach die Dateien, die Adobe angibt, aber die kein .1d am Schluss haben und macht die Links gerade anders rum, also statt
sudo ln -s /usr/lib32/libnss3.so.1d /usr/lib32/libnss3.so einsudo ln -s /usr/lib32/libnss3.so /usr/lib32/libnss3.so.1d Dann funktioniert sogar diese proprietäre Kacke! Ach, einige mögen sich jetzt noch fragen, warum ich Adobe Air den überhaupt installieren, wenn ich's scheisse finde - es ist simpel, ich brauche geschäftlich eine Anwendung, die über Adobe Air läuft. Fazit: Linux ist kompliziert - wenn grosse Firmen scheiss Anleitungen für die eigene Software veröffentlichen! PS: Das ganze basiert auf der Anleitung von Adobe: http://kb2.adobe.com/cps/521/cpsid_52132.html . Sonst wär's ein wenig unvollständig![]()
Die wunderbare Welt der Pythonmodule
...und wieder einst ein wenig Code, der je nach je nützlich ist. Ich brauchte eine Lösung, um mein Programm mit Plugins auszustatten. Diese Lösung sollte flexibel sein, also keine Veränderung im eigentlichen Code benötigen. Ich suchte eine weile, wurde aber nur halb schlau aus den kleinen, nicht funktionierenden Beispielen. Deshalb gleich von Anfang an; hier ist eines, das einfach macht, was es soll
plugins
Einer der wichtigsten Punkte, den ich am Anfang nicht beachtete ist der Unterschied zwischen New- und Oldstyle-Klassen. Eine Newstyleklasse ist notwendig, wenn die Methode __subclasses__() genutzt werden sollte.
Auch dazu findet man nicht viel. Eine Newstyleklasse muss von einer Superklasse abgeleitet sein, falls es die "nicht gibt", ist es Object (class irgendneklasse(object) ). Sie muss zudem die Methode __init__ (eigentlich Konstruktor) beinhalten, obwohl dieser auch nur ein pass beinhalten kann
Das wär's eigentlich in etwa.. Für alle, die den Code direkt sehen möchten, schmeiss ich noch den Pluginmanager rein.. Hf
'''
Created on 08.03.2010
@author: skamster
'''
from plugins.superClass import *
import os
class PluginManager(object):
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
self.pluginsList = []
# check, if the dir exists
if(os.path.isdir("plugins/")):
# make a list with all files from the dir...
dirList=os.listdir("plugins/")
# ... and took all the files to import them..
for fname in dirList:
# .. but just if they are python-files ![]()
if fname.endswith(".py"):
try:
# the init-file is necessary in the pluginfolder.. strange thing, but it could be empty.
# we do ignore this file and do not import it!
if fname[:-3] != "__init__":
__import__("plugins."+fname[:-3])
except Exception:
raise
'''
wtf i do here?
ok, with __subclasses__ we got all subclasses.. a very clean solution.
we save them in a list
but first: we instance them. this is safer, because you could directly use them after call the list
you're also able to save just the classes (add then the notInstancePluginObject to the list), this is maybe more memory-friendly,
but don't forget then the instance before execute methods..
'''
for notInstancePluginObject in superClass.__subclasses__():
instanceObject = notInstancePluginObject()
self.pluginsList.append(instanceObject)
print instanceObject.getPluginName()
def getPluginList(self):
return self.pluginsList
Doom 3 auf einem 64Bit-Linuxpc – Fehler gefunden
Hallo zusammen,
heute war mein Doom3-Torrent für Linux endlich unten und ich freute mich schon auf's spielen. Das x86 in der ausführbaren Datei reduzierte meine Hoffnung bald, doch ich versuchte es weiter.
Die Installation funktionierte ohne weiteres. Man führe den installer aus, der diverse Dateien unter /usr/local/games/doom3 erstellt und entpacke alle Dateien auf den Cd's mit Namen file-x.tar.bz2 (x=1-3, je nach cd) in den Ordner /usr/local/games/doom3/base/ .
Fertig ist's, danach kann man es per Startmenü oder per doom3, in der Konsole, ausführen.
Bei mir verabschiedete sich das Spiel jedoch immer gleich beim Start:
glprogs/environment.vfp
glprogs/environment.vfp
-------------------------------
WARNING: vertex array range in virtual memory (SLOW)
signal caught: Segmentation fault
si_code 1
Trying to exit gracefully..
Shutting down sound hardware
----------- Alsa Shutdown ------------
close pcm
dlclose
--------------------------------------
idRenderSystem::Shutdown()
Dh. schaute ich mal hier nach, wurde aber nicht wirklich schlau daraus (hat aber viele gute Sachen, deshalb der Verweis
).
Nun wurde mir klar, dass der nvidia-treiber von Haus aus keine 32-Bit-Unterstüzung hat (jedenfalls auf den 64-Bit-Systemen
) und es daran lag. Um das zu beheben, reichte ein kleiner Befehl:
sudo apt-get install nvidia-glx-ia32
seit dem funktioniert's wunderbar, brauchte nicht mal einen XServer-neustart. Hoffe, es nützt jemandem was.. Die Performance ist wahrscheinlich um einiges besser als bei einem "wine-doom", objektiv kann ich's aber noch nicht wirklich sagen (logisch, dass es ruckelt, wenn nebenbei qtmoko kompiliert
).
Minihowto: Durch ein Datum iterieren
Vielleicht kennen einige sowas: Man hat eine Bestimmte Zeit, und jeden Tag sollte etwas anders sein. Ich für meinen Teil brauchte etwas, das genau dies tut.
Python bietet zwar ein sogenanntes timedelta, welches eine Zeitspanne represäntiert, durchiterieren geht jedoch nicht. Deshalb meine Lösung des Problems:
import datetime
startday = 22
startmonth = 1
startyear = 2010
endday = 25
endmonth = 1
endyear = 2010
firstDate = datetime.date(startyear, startmonth, startday)
secondDate = datetime.date(endyear, endmonth, endday)
singleOpIndex = 0
while firstDate < secondDate:
try:
firstDate = datetime.date(startyear, startmonth,startday)
startday += 1
# wenn's ein wochentag ist..
if(firstDate.weekday()<5):
print "wochentag
"
else:
print "wochenende
"
except Exception, error1:
if(startmonth > 12):
startmonth = 1
startyear += 1
else:
startmonth += 1
startday = 1
#print error1
pass
Der Code ist natürlich hässlich eingerückt und kann dh nicht funzen. Abgesehen von der Einrückung sollt's aber klappen (ich lad das ganze bei Gelegenheit noch in einer Datei mit korrekter Einrückung hoch).
Ob es nun Wochenende ist oder nicht, muss natürlich nicht geprüft werden, aber es ist doch schön, wenn man seine freien Tage auch gleich bemerkt :p
Mailman und SSL
Hallo zusammen,
heute habe ich versucht, Mailman ssl-fähig zu machen. Und ich hab's geschafft
Einige kennen das Problem vielleicht: Es ist schlicht "nicht möglich", eine Einstellung zu finden, welche alle Links mit einem https:// versieht. Das ganze muss einfach immer http:// sein.
Da es recht mühsam ist und nur wenige Erklärungen gibt: Hier ist meine!
- Apache-Config anpassen:
Zuerst muss die Apacheconfig angepasst sein. Irgendwo, optimalerweise in der mailman.conf vom Apache, könnt ihr
RewriteEngine on
RewriteCond %{HTTPS} off [NC]
RewriteRule ^/mailman(/.*) https://%{HTTP_HOST}/mailman$1 [L,R=permanent]
hinzufügen. Dies sorgt dafür, dass jedes mal, wenn man auf einer http://-Seite landet, man auf die gleiche Seite mit https:// redirected wird.
- Mailmanconfig anpassen:
Simpel und einfach: Man öffne die Datei /etc/mailman/mm_cfg.py und füge die Linie
DEFAULT_URL_PATTERN = 'https://%s/mailman/'
hinzu. Dadurch sollte bei allen ab jetzt erstellten Mailinglisten alle Links schon mit einem https:// versehen sein.
- Zu guter Letzt: alte Mailinglisten mit den https://-links versehen
Dafür gibt's schon ein Tool. Man gebe in der Konsole
/usr/lib/mailman/bin/withlist -l -r fix_url dieListe -u derHost
ein und schon wird's gefixt. dieListe muss natürlich mit dem Listennamen und derHost mit dem Hostnamen getauscht werden (der Hostname muss jedoch nur aus dem Namen bestehen, der Rest nimmt's aus der config. Beispiel: death-head.ch)
Leider scheint man beim Listennamen kein * für alle Listen verwenden zu können. Aber es funzt und ist ja nur einmalig zu erledigen
