Ihr Browser versucht gerade eine Seite aus dem sogenannten Internet auszudrucken. Das Internet ist ein weltweites Netzwerk von Computern, das den Menschen ganz neue Möglichkeiten der Kommunikation bietet.

Da Politiker im Regelfall von neuen Dingen nichts verstehen, halten wir es für notwendig, Sie davor zu schätzen. Dies ist im beidseitigen Interesse, da unnötige Angstzustiände bei Ihnen verhindert werden, ebenso wie es uns vor profilierungs- und machtsächtigen Politikern schützt.

Sollten Sie der Meinung sein, dass Sie diese Internetseite dennoch sehen sollten, so können Sie jederzeit durch normalen Gebrauch eines Internetbrowsers darauf zugreifen. Dazu sind aber minimale Computerkenntnisse erforderlich. Sollten Sie diese nicht haben, vergessen Sie einfach dieses Internet und lassen uns in Ruhe.

Die Umgehung dieser Ausdrucksperre ist nach §95a UrhG verboten.

Mehr Informationen unter www.politiker-stopp.de.

2 10. März 2010
0 9. März 2010
0 22. Februar 2010
1 29. Januar 2010


Archiv der Kategorie 'Universitaet'

Identifikation und Authentifikation in RESTful APIs

Mittwoch, den 10. März 2010

Ja, viele von euch (srsly?) haben sicher schon einmal ein (semi) RESTful API entwickelt. Ein haeufiges Problem ist herauszufinden, ob ein Aufruf auch durchgefuehrt werden darf. Das Problem besteht darin, dass wir es dabei mit einem zustandslosen Protokoll (RFC 2616) zu tun haben, also fallen die Elgamal- und Diffie-Hellman-Kryptosysteme aus.

Um nun festzustellen, ob die Person (bzw. eine Applikation, stellvertretend fuer eine Person), die die Anfrage sendet auch wirklich die Person ist, fuer die sie sich ausgibt (Identifikation) und um gleichzeitig festzustellen, ob die Anfrage nicht manipuliert wurde (Authentifikation), gibt es zum einen das freie OAuth Protokoll, was aber relativ kompliziert zu implementieren ist, und zum anderen gibt es aehnliche Ansaetze, wie zum Beispiel das Flickr Auth Protokoll. Beide Protokolle bieten ausserdem die Moeglichkeit externen Programmen (Clients) den Zugriff auf das System (Service Provider) zu authorisieren.

Sofern letzteres nicht noetig ist, reicht jedoch ein abgespecktes Protokoll, das dem Flickr Protokoll sehr nah kommt. Hierbei faellt der Aufwand der sicheren Schluesseluebertragung weg. Und so einfach kann es gehen:

  • Der Service Provider generiert einen oeffentlichen Schluessel (API Key) und einen privaten Schluessel (Secret). Ich habe fuer den oeffentlichen Schluessel die SHA1 Pruefsumme verschiedener Variablen und fuer den privaten Schluessel die MD5 Pruefsumme von Variablen, Zufallszahlen und Timestamps genutzt.
  • Der Client wird mit beiden Keys ausgestattet. Wie gesagt: Der unwiretapped Schluesselaustausch muss anders sichergestellt werden. Bei meinem System kann der Benutzer die Keys einsehen, wenn er sich zuvor mit seinen Zugangsdaten eingeloggt hat. Das ist auch gaengige Praxis.
  • Bei einer Anfragegenerierung werden die Variablen inkl. oeffentlichem Schluessel (die Bezeichner, nicht die Werte!) alphabetisch sortiert und dann mit ihrem Wert konkateniert. Dann werden die Key-Value-Strings konkateniert und der private Schluessel wird vorangestellt. Das Ganze wird jetzt gehasht (e.g. MD5). Nun werden alle Variablen und die zusaetzlich generierte signature-Variable uebertragen.
  • Der Service Provider empfaengt alle Variablen, nimmt davon den oeffentlichen Schluessel und sucht in seiner Datenbank nach dem dazu passenden privaten Schluessel. Jetzt kann der Service Provider das selbe Spiel spielen, das der Client schon durchgemacht hat: Variablen sortieren, Key-Value-Strings bauen, konkatenieren, den privaten Schluessel voranstellen und hashen. Der Vergleich der uebermittelten Signatur und der generierten Signatur erlaubt die Authentifizierung des Zugriffs.

Beispiel

Der API Key ist fd40e3589bbb58ec358122c5cd32fcc6481707bb, das Geheimnis ist 162c9d446beb754b804b904772ff87b6. Die Variablen sind (Bezeichner = Wert):

  • method = deleteEntries
  • rangeFrom = 99
  • rangeTo = 101

Die Anfrage wird nun wie folgt Client-seitig generiert:
Sortieren:

apiKey vor method vor rangeFrom vor rangeTo

Konkatenieren:

apiKeyfd40e3589bbb58ec358122c5cd32fcc6481707bbmethoddeleteEntriesrangeFrom99rangeTo101

Private Key voranstellen:

162c9d446beb754b804b904772ff87b6apiKeyfd40e3589bbb58ec358122c5cd32fcc6481707bbmethoddeleteEntriesrangeFrom99rangeTo101

Hashen:

9ad5100448f0549472b0e70722aa06bb

Variablen fuer die Anfrage zusammensetzen:

http://example.com/rest/?apiKey=fd40e3589bbb58ec358122c5cd32fcc6481707bb&method=deleteEntries&rangeFrom=99&rangeTo=101&signature=9ad5100448f0549472b0e70722aa06bb

Das wird nun ausgefuehrt und auf der Service Provider Seite geht es dann so weiter:
API Key auslesen:

fd40e3589bbb58ec358122c5cd32fcc6481707bb

In der Datenbank nach dem passenden privaten Schluessel suchen:

162c9d446beb754b804b904772ff87b6

Sortieren, Konkatenieren, Private Key voranstellen, Hashen (s.o.):

9ad5100448f0549472b0e70722aa06bb

Ergebnisse vergleichen:

9ad5100448f0549472b0e70722aa06bb = 9ad5100448f0549472b0e70722aa06bb

That’s it. Ist sehr einfach zu implementieren und ist dafuer extrem sicher.

Just Married: Zend Framework & Flickr

Dienstag, den 9. März 2010

Vorweg: Ich glaube dieser Post wird lang…

Also zur Zeit bastel ich an einem Projekt, das aus einigen Social Networks Daten beziehen und diese auf Public Displays anzeigen soll. Da nur-Text etwas oede ist, habe ich mich also an die Flickr API gesetzt. Eigentlich bietet das Zend Framework dafuer die Klasse Zend_Service_Flickr an, aber leider ist die nicht dafuer ausgelegt Applikationen mit Flickr zu verbinden, sondern lediglich fuer eine direkte Benutzerauthentifizierung via Benutzername/Passwort.

Mein erster Ansatz war also erstmal in die API von Flickr zu schauen, denn die bietet ein OAuth aehnliches Verfahren zur Anwendungsauthentifizierung an. Der Trick war nun Zend_Service_Flickr damit zu verheiraten. Und so geht’s:

Als erstes registriert man eine Anwendung bei Flickr und richtet eine Callback URL ein. In meinem Fall wird damit die callbackAction meines FlickrControllers getriggert. Ich brauchte also einen FlickrController…

class FlickrController extends Zend_Controller_Action
{
    public function indexAction() { }
    public function authenticateAction() { }
    public function callbackAction() { }
}

Die Authentifizierung laeuft so ab:

  1. Der Benutzer oeffnet die index-Seite. Dort ist ein Link zur authenticate-Seite, wenn alles nicht schon gelaufen ist.
  2. Die authenticate-Action prueft zunaechst, ob die Anwendung bereits mit Flickr verknuepft ist. Wenn ja, dann wird zur index-Seite weitergeleitet. Wenn nein, dann wird eine Authentication Request URL gebaut und dorthin wird weitergeleitet.
  3. Auf der Flickr-Seite muss der Benutzer der Anwendung nun den Zugriff erlauben. Ist das geschehen, wird der Benutzer von Flickr direkt zur callback-Seite geleitet. Flickr haengt dabei noch eine Variable mit dem Namen frob an.
  4. Die callback-Action sendet daraufhin eine Anfrage an Flickr, die u.A. auch die frob-Variable enthaelt. Ausserdem wird eine Signatur angehangen.
  5. Flickr antwortet mit einem Token, der dann gespeichert wird und fuer zukuenftige Calls verwendet wird.

So, bevor ich alle mit Erklaerungen langweile: Jetzt kommt Code!

class SenScreen_Service_Flickr extends Zend_Service_Flickr
{
    protected $_secret;
    protected $_perms;
    protected $_token;
 
    const PATH_AUTH = '/services/auth/';
    const PATH_REST = '/services/rest/';
 
    public function __construct(array $options = null)
    {
        parent::__construct(null);
 
        $this->setOptions($options);
    }
 
    public function setOptions(array $options = null)
    {
        if ($options == null) {
            return;
        }
 
        $validOptions = array('api_key', 'secret', 'perms', 'token');
 
        $this->_compareOptions($options, $validOptions);
 
        if (isset($options['api_key'])) {
            $this->apiKey = $options['api_key'];
        }
        if (isset($options['secret'])) {
            $this->_secret = $options['secret'];
        }
        if (isset($options['perms'])) {
            $this->_perms = $options['perms'];
        } else {
            $this->_perms = 'read';
        }
        if (isset($options['token']) && $options['token'] instanceof SenScreen_Service_Flickr_AuthToken) {
            $this->_token = $options['token'];
        }
    }
 
    public function setApiKey($apiKey)
    {
        $this->apiKey = $apiKey;
        return $this;
    }
 
    public function getApiKey()
    {
        return $this->apiKey;
    }
 
    public function setSecret($secret)
    {
        $this->_secret = $secret;
        return $this;
    }
 
    public function getSecret($secret)
    {
        return $this->_secret;
    }
 
    public function setPerms($perms)
    {
        $this->_perms = $perms;
        return $this;
    }
 
    public function getPerms()
    {
        return $this->_perms;
    }
 
    public function setToken($token)
    {
        $this->_token = $token;
        return $this;
    }
 
    public function getAuthToken()
    {
        return $this->_token;
    }
 
    public function getApiSignature(array $params)
    {
        $plainSignature = $this->_secret;
        ksort($params);
        foreach ($params as $key => $value) {
            $plainSignature .= $key . $value;
        }
        return md5($plainSignature);
    }
 
    private function _getSignedUrl($path, array $params)
    {
        $url = self::URI_BASE . $path . '?';
        $urlParams = array();
        foreach ($params as $key => $value) {
            $urlParams[] = $key . '=' . $value;
        }
        $url .= implode('&', $urlParams);
        $url .= '&api_sig=' . $this->getApiSignature($params);
        return $url;
    }
 
    public function redirect()
    {
        $params = array(
            'api_key' => $this->apiKey,
            'perms'   => $this->_perms
        );
        $redirectUrl = $this->_getSignedUrl(self::PATH_AUTH, $params);
        header('Location: ' . $redirectUrl);
        exit(1);
    }
 
    public function getFrob()
    {
        return $_GET['frob'];
    }
 
    public function requestToken()
    {
        $params = array(
            'method'  => 'flickr.auth.getToken',
            'api_key' => $this->apiKey,
            'frob'      => $this->getFrob(),
            'perms'      => $this->_perms
        );
 
        $httpClient = new Zend_Http_Client($this->_getSignedUrl(self::PATH_REST, $params));
        $httpClient->resetParameters();
        $httpClient->setParameterGet($params);
        $httpClient->setHeaders(array(
            'Accept-encoding' => ''
        ));
        return $this->_parseToken($httpClient->request('GET'));
    }
 
    private function _parseToken(Zend_Http_Response $response)
    {
        $xmlElement = new SimpleXMLElement($response->getBody());
        return new SenScreen_Service_Flickr_AuthToken(
            (string) $xmlElement->auth->token,
            (string) $xmlElement->auth->user['username'],
            (string) $xmlElement->auth->user['fullname']
        );
    }
 
    public function isRestrictedMethod($method)
    {
        $restrictedMethods = array(
            'flickr.photos.getContactsPhotos'
        );
 
        return in_array($method, $restrictedMethods);
    }
 
    private function _execute($method, $defaultOptions, $options)
    {
        $options = $this->_prepareOptions($method, $options, $defaultOptions);
 
        $restClient = $this->getRestClient();
        $restClient->getHttpClient()->resetParameters();
        $response = $restClient->restGet('/services/rest/', $options);
 
        if ($response->isError()) {
            throw new Zend_Service_Exception('An error occurred sending request. Status code: '
                                           . $response->getStatus());
        }
 
        $dom = new DOMDocument();
        $dom->loadXML($response->getBody());
 
        self::_checkErrors($dom);
 
        return new Zend_Service_Flickr_ResultSet($dom, $this);
    }
 
    public function getContactsPhotos(array $options = array())
    {
        static $method = 'flickr.photos.getContactsPhotos';
        static $defaultOptions = array(
            'count'           => 100,
            'just_friends' => 0,
            'single_photo' => 0,
            'include_self' => 0,
            'extras'       => 'license, date_upload, date_taken, owner_name, icon_server, original_format, last_update.'
        );
        return $this->_execute($method, $defaultOptions, $options);
    }
 
    public function getRecent()
    {
        static $method = 'flickr.photos.getRecent';
        static $defaultOptions = array(
            'per_page' => 10,
            'page'     => 1,
            'extras'   => 'license, date_upload, date_taken, owner_name, icon_server, original_format, last_update.'
        );
        return $this->_execute($method, $defaultOptions);
    }
}

Diese Klasse erweitert Zend_Service_Flickr, sodass diese auch mit Authentifizierung umgehen kann. Als naechstes muss der Zend_Http_Client ausgetauscht (bzw. erweitert) werden, sodass auch er mit Signaturen und dem Kram umgehen kann:

class SenScreen_Service_Flickr_Http_Client extends Zend_Http_Client
{
    protected $_flickr;
 
    public function __construct()
    {
        parent::__construct();
 
        $this->setHeaders(array('Accept-Encoding' => ''));
    }
 
    public function setFlickr(SenScreen_Service_Flickr $flickr)
    {
        $this->_flickr = $flickr;
    }
 
    public function request($method = null)
    {
        if ($this->_flickr->isRestrictedMethod($this->paramsGet['method'])) {
            $this->paramsGet['auth_token'] = $this->_flickr->getAuthToken()->getToken();
 
            $this->paramsGet = array_merge($this->paramsGet, array(
                'api_sig' => $this->_flickr->getApiSignature($this->paramsGet)
            ));
        }
        return parent::request($method);
    }
}

Als naechstes Brauchen wir noch eine Klasse, die unser Token aufbewahrt und serialisierbar in der DB ablegbar ist:

class SenScreen_Service_Flickr_AuthToken
{
    private $_token;
    private $_username;
    private $_fullname;
 
    public function __construct($token, $username, $fullname)
    {
        $this->_token    = $token;
        $this->_username = $username;
        $this->_fullname = $fullname;
    }
 
    public function getToken()
    {
        return $this->_token;
    }
 
    public function getUsername()
    {
        return $this->_username;
    }
 
    public function getFullname()
    {
        return $this->_fullname;
    }
}

Und dann koennen wir endlich den Controller fuellen und jetzt kommen auch mal Kommentare in den Code, damit ich nicht mehr so viel quarken muss:

class FlickrController extends Zend_Controller_Action
{
    protected $_config = array(
        'api_key' => 'myapplicationkey',
        'secret'  => 'mysecret'
    );
 
    protected $_flickr;
 
    public function init()
    {
        $this->_flickr = new SenScreen_Service_Flickr();
        $httpClient = new SenScreen_Service_Flickr_Http_Client();
        $httpClient->setFlickr($this->_flickr);
        Zend_Rest_Client::setHttpClient($httpClient);
    }
 
    public function indexAction()
    {
        $userId = Zend_Auth::getInstance()->getIdentity()->id;
        /**
         * Check whether the current user has an access
         * token for Flickr.
         */
        $userSettingModel = new Model_UserSetting();
        if ($userSettingModel->get($userId, 'flickr_token')) {
            /**
             * Get the access token.
             */
            $access_token = unserialize($userSettingModel->getValue());
 
            /**
             * Configure the Flickr instance.
             */
            $this->_flickr->setOptions(array_merge(
                $this->_config,
                array('token' => $access_token)
            ));
 
            $this->view->contactPhotos = $this->_flickr->getContactsPhotos(array('include_self' => 1, 'extras' => ''));
 
            $this->view->showAuthenticationButton = false;
        } else {
            $this->view->showAuthenticationButton = true;
        }
    }
 
    public function authenticateAction()
    {
        $userId = Zend_Auth::getInstance()->getIdentity()->id;
 
        /**
         * Check whether the current user has an access
         * token for Flickr.
         */
        $userSettingModel = new Model_UserSetting();
        if ($userSettingModel->get($userId, 'flickr_token')) {
            /**
             * Get the access token.
             */
            $this->_helper->redirector('index');
        } else {
            /**
             * The user is not authenticated with Flickr.
             * Request Flickr auth frob and redirect to
             * Flickr's authentication page.
             */
            $this->_flickr->setOptions($this->_config);
            $this->_flickr->redirect();
        }
    }
 
    public function callbackAction()
    {
        $userId = Zend_Auth::getInstance()->getIdentity()->id;
 
        $this->_flickr->setOptions($this->_config);
 
        /**
         * Check whether a frob is present for this user.
         */
        if ($this->_flickr->getFrob()) {
            /**
             * A frob is present. Request a token and
             * save it in the database.
             */
            $token = $this->_flickr->requestToken();
            $userSettingModel = new Model_UserSetting();
            $userSettingModel->setUserId($userId)
                             ->setKey('flickr_token')
                             ->setValue(serialize($token))
                             ->save();
 
            /**
             * Everything is done, redirect to the index
             * page.
             */
            $this->_helper->redirector('index', 'flickr');
        } else {
            /**
             * The callback has been called without having
             * a request token. Redirect to the index page.
             */
            $this->_helper->redirector('index', 'flickr');
        }
    }
}

Sollte soweit selbsterklaerend sein. Viel Spass damit. ;-)

Update:
Wie ihr vielleicht bemerkt habt, nutze ich das Abstract Data Mapper Design Pattern.

Impact

Montag, den 22. Februar 2010

Wenn man ueber etwas nachdenkt, dann ist es schwierig solange man sich mittendrin befindet. Wenn man jedoch am Ende steht, scheint es fuer Menschen wesentlich einfacher zu sein Dinge zu reflektieren. Anscheinend laesst sich das auch auf das Leben anwenden. Den Beweis fuer diese These hat Prof. Randy Pausch (* 23. Oktober 1960; † 25. Juli 2008) erbracht.

Pausch war Professor an der Carnegie Mellon University in Pittsburgh, Pennsylvania. Sein Forschungsgebiet war die Human-Computer Interaction (HCI), vor allem aber Virtual Reality. Er begruendete u.A. das Alice-Project, bei dem eine offensichtlich funktionierende Idee einfach einmal realisiert wurde: Wenn man Menschen dazu bringt Spass zu haben, dann fokussieren sie ihr Interesse darauf und beginnen dabei Dinge zu lernen, die keine offensichtlichen Beziehungen zum eigentlichen Geschehen haben. Das Alice-Project erleichtert es auf spielerische Weise Programmiersprachen zu lernen und wird (Stand 2008) von 10% der Studierenden von IT-Bereichen in den USA genutzt.

Bei Pausch wurde im September 2006 Bauchspeicheldruesenkrebs diagnostiziert. Er kaempfte mit vielen Behandlungen dagegen an, starb aber im Juli 2008. Zehn Monate vor seinem Tod hielt Randy Pausch seine Last Lecture. Eine letzte Vorlesung zu halten ist Brauch an vielen Universitaeten. Als die CMU allerdings zu seiner letzten Vorlesung lud, war bereits klar, dass der Begriff woertlich zu nehmen ist.

Seine offiziell letzte Vorlesung nutzte Pausch, um auf brilliante Art ueber sein Leben zu sprechen. Er stellte die Vorlesung unter einen Titel (Achieving Your Childhood Dreams), der durchdachter kaum sein koennte. Er nannte seine Kindheitstraeume und wie er sie erreicht hat bzw. wieso es gut ist, dass er auch manche Kindheitstraeume nicht erreicht hat. Er erklaerte, wie er anderen Menschen dabei geholfen hat ihre Kindheitstraeume zu erfuellen und was er aus Allem gelernt hat.

Um die Komplexitaet des Inhalts und der Botschaft seiner Last Lecture zu verstehen reicht es nicht aus darueber zu schreiben. Man muss sie sehen. Es lohnt sich und hat mich sehr beeindruckt.

Das Video der letzten Vorlesung:

(Entweder JavaScript ist nicht aktiviert, oder Sie benutzen eine alte Version von Adobe Flash Player. Installieren Sie bitte den aktuellsten Flash Player. )

Identitaet und Privatsphaere

Freitag, den 29. Januar 2010

Identitaet – was ist das eigentlich? Irrelevanzia definiert die Identitaet wie folgt:

Beim Menschen bezeichnet Identitaet (v. lat. idem, derselbe, der gleiche) die ihn kennzeichnende und als Individuum von anderen Menschen unterscheidende Eigentuemlichkeit seines Wesens.

Es geht also um Alleinstellungsmerkmale und die kann man zumindest stochastisch evaluieren. Wir ich schon in meinem Paper ueber Reality Mining1 bereits beschrieben habe, ist Entropie ein dabei besonders interessantes Mass. Es gilt als Einheit fuer Unordnung, aber es ist viel mehr als das. Entropie kann dazu verwendet werden, um Muster zu visualisieren und sie sogar mathematisch vergleichbar zu machen, selbst wenn wir diese Muster nicht in Worte fassen koennen. Eine andere Definition von Entropie nennt es die Generalisierung der Anzahl von moeglichen zufaelligen Unterschieden. Solche Anzahlen werden haeufig auch durch Bits of Entropy dargestellt. Beispiel: Bei einem Zufallsexperiment gibt es zwei moegliche Elementarereignisse. Wir sprechen hierbei dann von einer Entropy von einem Bit, da 2^1 = 2. Wenn wir eine Entropy von 3 Bits bei einem Zufallsexperiment annehmen, so gibt es 2^3 = 8 Ereignisse, usw.

Nun koennen wir dieses simple mathematische Modell auf die Identitaet anwenden: Es gibt ca. 6,9 Milliarden Menschen (6.900.000.000). Also benoetigt man \log_2 (1/6900000000) = 32,6839 Bits, um eine Person auf der Welt eindeutig zu identifizieren. Da es bei Computern so immer die Sache mit der 8 ist, koennen wir jetzt mal approximieren: 4*8 < 32,6839 < 5 * 8, also weniger als 5 Byte. Zum Vergleich: Auf x86 Maschinen ist die Assembler Anweisung nop (=no operation, hexadezimal 90 oder auch 10010000) 8 Bit lang. 8 Bits wuerden genuegen, um im optimalen Fall 256 Personen unterscheiden zu koennen. Das ist alles wirklich nicht viel.

Treiben wir das ganze noch weiter und werden politischer: Wenn EVILOFYOURCHOICE Daten von Personen speichert, z.B. Land, Most Viewed Website, durchschnittliche Online-Zeit, Browser, Displaygroesse, zuletzt online gekaufter Artikel, zuletzt offline gekaufter Artikel, etc., ohne zu wissen, wer diese Person ist, so ist das voellig egal, denn man kennt natuerlich auch die Personen, die mit dieser Person kontakt hatten (Telefon, E-Mail, SMS) und deren Daten und das alles aggregiert sich zu einem riesigen Netz (ja, jetzt sind wir beim Reality Mining angelangt). Jetzt nehmen wir mal an, dass wir dieses Netz kennen und eine Person aus diesem Neetz geht in einen Laden und nutzt seine Payback-Karte, die mit dem Namen der Person assoziiert ist… dann wissen wir auf einmal noch viel mehr und koennen ohne Muehe andere Personen aus diesem Netz identifizieren.

Leute, die unsere Daten speichern, nutzen solche Techniken (die ich bewusst sehr plump erklaert habe) schon seit Jahren! Sie nutzen das auch aus und senden Werbung oder bevorzugen besondere Zentralpersonen solcher Netze bei Hotlines und bei Kulanz. Wisst ihr ueberhaupt, wer was von euch weiss? Glaubt ihr wirklich, dass eure Privatsphaere geschuetzt ist und ihr nichts zu verbergen habt?

Uebrigens: Wenn die Polizei so etwas macht, dann nennt man das Rasterfahndung, deren Vertraeglichkeit mit dem Grundgesetz doch stark zu bezweifeln ist, da sie die Unschuldsvermutung, die wie folgt rechtlich (GG Art. 11 Abs. 1) definiert ist, aufhebt:

Jeder Mensch, der einer strafbaren Handlung beschuldigt wird, ist solange als unschuldig anzusehen, bis seine Schuld in einem oeffentlichen Verfahren, in dem alle fuer seine Verteidigung noetigen Voraussetzungen gewaehrleistet waren, gemaess dem Gesetz nachgewiesen ist.

Auf Europaeischer ebene verletzt es meiner Ansicht nach auch Art. 6 Abs. 2 der Europaeischen Menschenrechtskonvention:

Jede Person, die einer Straftat angeklagt ist, gilt bis zum gesetzlichen Beweis ihrer Schuld als unschuldig.

Dennoch wird es gemacht! Wollt ihr wirklich den neuen Personalausweis oder bis vor kurzem ePA?

SRSLY?

Mehr Informationen zu Bits & Privacy? Hier.

  1. Veroeffentlichung steht noch aus. []

Dragons Everywhere in Essen: Tag 4

Donnerstag, den 31. Dezember 2009

Meine Berichte werden immer kuerzer…

  • … und die Anzahl der Teilnehmer wurde wieder geringer.
  • Ein GBit Switch macht doch schon einiges mehr als ein 100MBit Switch.
  • Ein Beamer, ein kleiner Rechner, Maus und Tastatur (+CCC VPN) reichten heute vollkommen, um die Streams zu sehen. Der Rest blieb im Buero.
  • Ich will jetzt einen NAS.

Gesamt laesst sich wohl folgendes sagen:

  • Wenn man sich auf Andere verlaesst, dann ist man verlassen.
  • In Essen und Umgebung ist die Anzahl der Hacker (abzgl. derer, die nach Berlin gefahren sind) sehr gering.
  • Die Vortraege waren genial.
  • Das Streaming verlief im Schnitt relativ gut.
  • Wir waren fuer hunderte Personen vorbereitet und hatten zu Beginn enormen technischen Overhead.
  • Ich mache so eine Aktion nicht mehr mit.

Dragons Everywhere in Essen: Tag 3

Mittwoch, den 30. Dezember 2009

Wie gehabt:

  • Wir haben puenktlich begonnen, das SOAHarbor-Team war bereits da und nicht sehr erfreut… Als Entschaedigung gab es eine Kaffee-Flat.
  • Wir haben ein zweites NAS aufgestellt und beide mit externen Festplatten verstaerkt.
  • Die Teilnehmeranzahl ist erneut gesunken.
  • Auf Grund mangelnder Nachfrage fand kein Hackcontest mehr statt.
  • Es wurde aus ge-hack-ten Zwiebeln und Hack-fleisch eine leckere Festplatte gehackt.
  • Die VPN funktionierte problemlos, Streamingausfaelle blieben die Ausnahme.
  • Mate (und somit Tschunk) ist leer – aber Bier ist noch da.
  • Der Jahresrueckblick war genial.
  • Wir haben beschlossen, dass wir naechstes Jahr nach Berlin fahren.
  • Beim Abbauen haben wir vergessen dem hauptsaechlich genutzten NAS eine IP Adresse fest zuzuweisen, sodass wir ihn woanders hinstellen konnten… Ein rumfliegender Router hat das Problem geloest.
  • Morgen gibt es nur einen kleinen Rechner, einen Beamer und Lautsprecher.
  • Wir brauchen dringend mehr Schlaf.

Dragons Everywhere in Essen: Tag 2

Dienstag, den 29. Dezember 2009

Gerade startet Hacker Jeopardy, also wird es wohl Zeit ueber den heutigen Tag zu schreiben. Ich versuche es mal wie gestern:

  • Vor der Eroeffnung waren wir zu Zweit. Das blieb auch erstmal so.
  • Wir waren mehrere Stunden mit einem anderen Hacker da.
  • Wir haben uns letztendlich entschlossen unsere 1000m² aufzugeben und zu einer ueberschaubareren Location zu wechseln. Waehrend wir das vollzogen haben, hat sich die Anzahl der Personen erst quadriert und dann noch einmal fast verdoppelt.
  • Waehrend wir umgezogen sind, haben wir noch eine oeffentliche Kiosk-Mode-Workstation mit einem Ubuntu ausgestattet… Das tschechische Windows Vista Ultimate mit deutschem Language Pack haben wir natuerlich drauf gelassen… Ein versteckter Grub macht uns dann in Zukunft mehr Freiheit.
  • Nachdem der Umzug vollzogen war, wurde die Stimmung immer besser.
  • Wir haben einen Fileserver aufgesetzt.
  • Wir haben leckeren Tschunk gemixt und getrunken.
  • Morgen machen wir auch an der kleineren Location weiter. Diesmal aber erst ab 11 Uhr.
  • Der Hackcontest wurde durchgefuehrt. 5 Teams haben mitgemacht. Ein Team hat es geschafft innerhalb von 27 Minuten den Server einzunehmen. Morgen machen wir damit weiter.
  • Streaming hat heute besser funktioniert als gestern.
  • Die VPN  nach Berlin klappt jetzt mittlerweile auch.
  • Unsere Fragen zu den Jeopardy-Antworten sind besser.

Dragons Everywhere in Essen: Tag 1

Montag, den 28. Dezember 2009

Es ist nun Pi mal Daumen 23 Uhr. Wir sind seit 9 Uhr in der Universitaet, haben viele Sachen transportiert, aufgebaut und herumgetueftelt. Hier mal ein paar Stichpunkte zum Verlauf des aktuellen Tags:

  • Der Transport der Sachen verlief problemlos.
  • Bei der Ankunft stellten wir fest, dass der Strom in allen Hoersaelen abgestellt war. Wir haben das dem Pfoertner mitgeteilt, der wiederum den technischen Notdienst alarmiert hat. Eine Stunde Zeitverzoegerung. Erst kurz vor dem ersten Vortrag hatten wir Strom.
  • Die Streams waren zu Beginn fast nicht nutzbar. Waehrenddessen genauso wenig. Im Moment ist es relativ akzeptabel.
  • Die Konfigurationsdaten, die wir vom CCC erhalten haben, um der VPN des CCC in Berlin beizutreten waren nutzlos, da wir bisher keine Moeglichkeit gefunden haben, die Portblockaden der Universitaet zu umgehen, die Routen zu setzen etc. An dem Problem sassen wir bisher ungefaehr 12 Stunden.
  • Um ca. 20 Uhr wollte uns ein anderer Pfoertner verklickern, dass die Veranstaltung nur bis 18 Uhr angemeldet sei. Wir haben jedoch 4 volle Tage angemeldet. Wir koennen natuerlich weitermachen.
  • Mittags haben wir bei Pizzaboy bestellt. Das ging relativ schnell (40 Minuten) in Relation zu der Menge, die wir bestellt haben. Das Essen war lauwarm. Abends (ca. 19:30 Uhr) haben wir uns wieder entschieden bei Pizzaboy zu bestellen. Um 22 Uhr(!!!) wurde das Essen geliefert. Mein Cheese Burger hat gefehlt. Der Fahrer wollte trotzdem abkassieren, ich habe es verweigert und erst eine Nachlieferung gefordert. Die kam dann auch 30 Minuten spaeter und teilte mir mit, dass das Burgerbrot ausgegangen ist und sie stattdessen ein Baguette genommen haben. Der Burger/das Baguette hatte bereits die Aussentemperatur angenommen. Das war das letzte Mal, dass ich bei Pizzaboy bestellt habe. Trinkgeld gab es nicht.
  • Die durchschnittliche Personenanzahl lag etwa bei 15. Sehr wenig, was vielleicht daran liegt, dass heute Sonntag ist, gestern noch Weihnachten war und alle noch so groggy sind. Wir sind noch optimistisch, vor allem weil ALLE anwesenden Personen auch registriert waren und die Anzahl der Registrierungen noch wesentlich hoeher ist.
  • Die Atmosphaere hier in Essen war durchweg sehr gut – trotz Pizzaboy-Debakel.
  • Vertreter der Piratenpartei sind auch nach Essen gekommen.
  • Wir haben noch genug Mate.
  • Kaffee war heute das beliebteste Getraenk. Wir haben daher spontan eine Kaffee-Flat angeboten. Unser Kaffee-Vorrat ist so gut wie aufgebraucht. Morgen frueh haben die Geschaefte gluecklicherweise wieder auf.
  • Interessanterweise verbrachten die meisten Anwesenden lieber die Zeit ausserhalb der 3 Hoersaele. Wir haben uns daher kurzfristig dafuer entschieden einen Hoersaal zu schliessen und einen der Streams (je nach Vortrag) direkt im Foyer an die Wand zu werfen. Morgen entscheiden wir das wieder neu.
  • Den Hackcontest haben wir nicht wie semi-angekuendigt heute schon angefangen, sondern findet erst ab morgen statt (bedingt durch diverse technische Probleme, Zeitverzoegerungen und eine geringe Anzahl von potentiellen Teilnehmern).
  • Ich bin muede.

Mein idealer Arbeitsplatz

Sonntag, den 22. November 2009

Durch Dirks Umfrage zum idealen Arbeitsplatz fuehle ich mich gezwungen auch etwas zu schreiben…

Mein idealer Arbeitsplatz erfuellt folgende Kriterien:

  • das Arbeitsklima ist freundschaftlich; bei Fragen wird man unterstuetzt und Hilfe muss nicht erbettelt werden
  • die Arbeitszeit ist frei; solange X am Y fertig ist, ist alles okay; es gibt kein Zeiterfassungssystem
  • der Arbeitsort ist variabel. Wenn das Buero nervt, arbeitet man von Zuhause oder wo man moechte
  • das Geld stimmt
  • die Wahl der Hilfsmittel/Tools/Entwicklungsumgebungen/Software/Hardware ist frei
  • es gibt keine Rufbereitschaft
  • man muss nicht um Urlaubstermine streiten
  • die Arbeit wird dokumentiert
  • es wird strukturiert gearbeitet
  • die Vorgesetzten wissen, wovon sie reden
  • die Aufgabenstellungen werden klar formuliert
  • Deadlines werden sinnvoll gelegt
  • Risikoabschaetzung wird durchgefuehrt

Die meisten Punkte werden von meinem Job am Lehrstuhl extrem gut erfuellt, muss ich feststellen. :-)

GPS Device?

Montag, den 9. November 2009

Zur Zeit suche ich ein geeignetes GPS Geraet, das folgende Eigenschaften erfuellen soll:

  • Bluetooth + USB
  • Logging + Real-Time Navigation
  • Manuelle Speicherung der Position (Push-To-Log)
  • mind. 50 Kanaele
  • lange Akkulaufzeit (Minimum: 10 Stunden)
  • mind. 1 Hz (Logging & Receiving)
  • AGPS Unterstuetzung
  • NMEA via COM Port lesbar
  • Real-Time Navigation via Google Earth soll moeglich sein
  • Speicher fuer mind. 100.000 Wegpunkte
  • geringe Cold/Warm/Hot-Startzeiten
  • geringer Preis (< 80 EUR)

Hat jemand zufaellig Erfahrungen und Vorschlaege?

Nachtrag (10.11.2009):
Ich habe mir heute einen GPS Receiver von Nokia bei Amazon gekauft, weil ich das Teil heute life testen konnte und positiv ueberrascht war. Das werde ich erstmal durchtesten. Vorschlaege fuer andere Geraete sind immernoch willkommen, da ich einen Logger haben moechte. Ich habe das Geraet aber nur gekauft, weil es extrem guenstig und dafuer sehr gut ist. Gekauft habe ich es bei Amazon: Nokia LD-4W Bluetooth GPS Modul.

ZoneTrak

Freitag, den 30. Oktober 2009

Mjam, wie Einige schon mitbekommen haben, entwickle ich ein Real-Time Tracking System fuer Katastrophenschutzorganisationen am Pervasive Computing and User Interface Lehrstuhl von Prof. Albrecht Schmidt an der Universitaet Duisburg-Essen… Bevor ich alle langweile: Hier gibt es weitere Informationen fuer die jenigen, die mehr erfahren wollen:

ZoneTrak @ Tomorrow Lab

Distributed Calculation of Primes

Donnerstag, den 30. Juli 2009

Als Uebung fuer eine in der naechsten Woche anstehenden Klausur habe ich mal versucht Primzahlen verteilt (vgl. SETI@Home, Tiles@Home, etc) berechnen zu lassen.

Hier ist das Ergebnis:
Remote Method Invocation @ FSEwiki.

DBMS + REM2: done

Donnerstag, den 30. Juli 2009

Puh, das wars fuer diese Woche. Ich bin tot.

Cryptography: done

Mittwoch, den 29. Juli 2009

So, eben habe ich erfahren, dass ich bestanden habe. Ich haette zwar gerne eine 1 vor dem Komma gehabt, aber naja… Mal gucken, was ich bei der Einsicht der Klausur noch rausholen kann…

Und gleich gehts in die naechste Klausur: Datenbankmanagementsysteme.

Turing’s Guinea Pig

Montag, den 27. Juli 2009

Heute war es dann soweit: Das Final Exam stand fuer das Modul Cryptography an. Nachdem ich vor einiger Zeit zum Versuchskaninchen beim Zentralabitur in NRW wurde, musste ich heute wieder Neuland betreten: Computer-gestuetzte Klausuren.

Ziel des (nicht mehr ganz so) neuen Rektorats ist es, Klausuren an Computern schreiben zu lassen, um so Korrekturaufwand und somit Zeit zu sparen. Das von der LPLUS GmbH entwickelte TestStudio™ wurde bereits bei den Vorpruefungen zum Modul Datensicherheit / Kryptografie verwendet und fiel zumindest bei der zweiten Pruefung auf die Nase. Resultat war, dass die minimalen 25%, die man erreichen musste, um die Teilpruefung zu bestehen, allen Teilnehmern aus Kulanz gutgeschrieben wurden. Die Probleme des Systems sollten – in der Theorie – direkt von der LPLUS GmbH behoben werden. Jedoch existiert zumindest das Problem, dass man beim Einloggen schnell auf die Enter-Taste druecken muss, da ein Bestaetigungsfenster sich sonst sofort wieder schliesst, immernoch (nach 3 Vorpruefungen).

Also was ist heute passiert? Ganz normal beginn ich mit den auf einzelnen Seiten verteilten Aufgaben. Nachdem ich bei Aufgabe 20 den RSA Algorithmus durchgefuehrt habe und auf den Button klickte, der mich zur naechsten Aufgabe bringen sollte, kam ich nur zu einer ASP.NET Fehlerseite, auf der in roter Schrift (etwa in Schriftgroesse 30pt) IndexOutOfRangeException stand. Ich meldete diese Fehlermeldung sofort. Einer der wissenschaftlichen Mitarbeiter versuchte das Problem mit der Standardvorgehensweise (unter Windows) das Problem zu loesen: Woanders hinklicken, dann nochmal dahinklicken. Aber nichts: Das System konnte nur noch diese Meldung anzeigen. Interessanterweise betraf nur mich das Problem. Der wissenschaftliche Mitarbeiter rief also irgendwo an und wurde einige Minuten spaeter wieder zurueckgerufen. Er teilte mir daraufhin mit, dass ein Techniker der LPLUS GmbH am Server sitzt und versucht das Problem zu beheben…

Ich durfte beobachten, wie alle Teilnehmer nach und nach gingen. Kurz bevor die letzten paar gingen konnte ich endlich wieder weitermachen. Mir wurden 10 Minuten gutgeschrieben, die ich aber letztendlich nicht brauchte, weil ich sowieso noch 59 Minuten und 4 Sekunden gehabt haette und nur noch weitere 5 Minuten gebraucht habe.

Fazit: Computer koennen Menschen nicht ersetzen. Nichtmal bei so scheinbar einfachen Aufgaben. Zudem laesst sich mit dem System immer nur ein Loesungsweg abfragen, wobei es doch oft viele Alternativen gibt. Hiermit gilt fuer mich also bewiesen, dass das LPLUS System und somit Computer-gestuetzte Pruefungen sowohl beim Turing-Test, in der Praxis, als auch in Sachen Universitaetsniveau durchgefallen sind.

Setzen, 6.