Apples wundersame Welt der iOS-Extensions

Teil 1: Die Möglichkeiten der iOS Network Extension

01.03.2017
Von   
Mark Zimmermann leitet hauptberuflich das Center of Excellence (CoE mobile) zur mobilen Lösungsentwicklung bei der EnBW Energie Baden-Württemberg AG in Karlsruhe. Er weist mehrere Jahre Erfahrung in den Bereichen Mobile Sicherheit, Mobile Lösungserstellung, Digitalisierung und Wearables auf. Der Autor versteht es, seine Themen aus unterschiedlichsten Blickwinkeln für unternehmensspezifische Herausforderungen darzustellen. Neben seiner hauptberuflichen Tätigkeiten ist er Autor zahlreicher Artikel in Fachmagazinen.

NEHotSpotHelper für Entwickler: Praktischer Einsatz

Nutzt der Entwickler diese Extension, erfährt der Anwender davon nichts. Es kommt keine Sicherheitsabfrage und auch sonst keine optische Information darüber. Dies stellt in meinen Augen auch ein enormes Sicherheitsrisiko dar, denn theoretisch könnte eine App mit dieser Berechtigung viele Daten erheben, die man nicht so einfach freigeben möchte. Neben der Information der gerade in Empfangsreichweite befindlichen WLAN-Netzwerke erfährt die Extension beispielsweise auch Informationen über die Signalstärke oder mit welchem WLAN sich der Anwender gerade verbunden hat. Es wäre somit ein Leichtes, diese Informationen an einen Daten sammelnden Server zu übermitteln.

Aufgrund der fehlenden Transparenz dem Anwender gegenüber sollte es zum guten Ton gehören, diesem mitzuteilen, dass man die Kontrolle über diverse WLAN-Verbindungsversuche übernehmen wird. Hierzu bietet die Extension an, das jeweilige WiFi in der WLAN Übersicht (Einstellungen -> WLAN) zu annotieren:

NEHotspotHelper.register(options: [kNEHotspotHelperOptionDisplayName: NSString(string: "…wird verwaltet von mir")], queue: DispatchQueue.main, handler: NetworkExtension.NEHotspotHelperHandler)

Klickt der Anwender (in der ersten Anmeldung muss er das von Hand tun) auf das verwaltete WLAN steht dem Entwickler in seiner App eine State Machine zur Verfügung, in welcher die wichtigsten Anmelderoutinen zur Verfügung stehen (siehe Bild).

State Machine der NeHotSpotHelper Extension
State Machine der NeHotSpotHelper Extension

Aktiviert der Anwender eine WLAN-Verbindung prüft die App (commandtype: .evaluate) ob es sich um ein WLAN handelt, bei dem der Programmcode die Anmeldung übernehmen kann. Ist dem so, kann dies dem Betriebssystem durch network.setConfidence(.high) mitgeteilt werden.

Der eigentliche Anmeldeversuch (commandtype:.authenticate:) ist in dem Fall spannend, wenn es sich um ein Captive-Portal handelt. Im anderen Fall bietet die Extension die Möglichkeit, die Anmeldedaten an die standardisierten Verfahren (z.B. WPA2) programmatisch zu übermitteln. IM letzteren Fall werden somit nur Eigenschaften der Extension aufgerufen um eine Anmeldung zu vollziehen.

Bei einem Captive-Portal ist das Vorgehen etwas komplizierter. Der Anmeldeprozess, das Aushandeln von Session-, Portal-Tokens und ähnliches muss nachgebaut werden.

Die Abfragen müssen dabei genau wie im Browser verlaufen. Rufen Sie als erstes captive.apple.com auf und reagieren Sie auf die Rückmeldung. Entweder erhalten Sie bereits vom Router einen redirect oder einen HTML Response, der einen Browser dazu bewegen würde, einen redirect auszuführen.

Google Chrome bietet alles was man braucht, um Header, Post/Get Aufrufe usw. zu analysieren.
Google Chrome bietet alles was man braucht, um Header, Post/Get Aufrufe usw. zu analysieren.

Anhand dieses einfachen Satzes merken Sie, dass Sie auch den Response auswerten und parsen müssen. Es ist nicht nur wichtig, die richtige URL zur richtigen Zeit aufzurufen und den Response zu parsen. Auch die Header Informationen müssen jeweils korrekt gesetzt werden:

.addValue("application/x-www-form-urlencoded; charset=UTF-8", forHttpHeaderField: "Content-Type")

.addvalue("http://captive.apple.com", forHttpHeaderField: "Referer")

Zum Setzen sind die Werte aus dem vorherigen Response wichtig. Was sich kompliziert anhört ist gar nicht so schwer. Sie können mit dem Chrome Browser, über dessen Entwickler Werkzeuge, einfach die notwendigen Parameter extrahieren und die komplette Anmeldestrecke mitschneiden. Der Rest ist Fleißarbeit und eine Qualitätssicherung, das nichts vergessen wird. Eine noch so kleine Abweichung, wie ein vergessenes Cookie oder ein vergessen User-Agent entscheiden hier über den Erfolg oder den Misserfolg. Natürlich müssen Sie das nicht unbedingt nach Implementieren, Ihr Infrastrukturbetreiber kann Ihnen sicherlich mit ausführlicher Dokumentation oder alternativen Web-Schnittstellen aushelfen.

Ist die Anmeldung schließlich erfolgreich, müssen Entwickler diesen Erfolg (oder Misserfolg) dem Betriebssystem mitteilen:

Erfolgsfall:

result.setNetwork(command.network!)

result.deliver()

Misserfolgsfall:

let result = command.createResponse(.failure)

result.setNetwork(command.network!)

result.deliver()

Besteht die Verbindung und muss diese "offen gehalten" werden, steht ebenfalls das Ausführen von Programmcode für den Betrieb (commandtype:.maintain:) als Möglichkeit zur Verfügung. Dieser Betriebsstatus wird aus zwei Gründen aufgerufen, einmal ca. alle 300 Sekunden (= 5 Minuten) nach einer erfolgreichen Anmeldung, um die Möglichkeit zur haben, die Verbindung aufrecht zu halten. Aber der Code wird auch dann ausgeführt, wenn es in der Vergangenheit einmal eine Erfolgreiche Anmeldung durch die Network Extension gegeben hat.

Network Extensions sind ein mächtiges Werkzeug. Erstellen Sie damit Apps für Ihre Belegschaft, um eine einfachere und differenziertere Anmeldung zu ermöglichen. Messen Sie die Ausleuchtung Ihrer WLAN-Netze. Vergeben Sie tagesgültige Zugänge an Gäste oder Besucher. Sorgen Sie für automatisierte Anmeldungen per App, ohne langwierige Captive Portal Zugriffe. Nicht nur die Anmeldezeit wird damit optimiert, auch die Stabilität der Verbindung profitiert davon. (mb)