Mittwoch, 14. Dezember 2016

Das in Chrome eingebettete Flash-Plugin aktualisieren

Die Aktualisierung von Chrome kann man anstossen, indem man den Browser startet und danach die Adresse

chrome://help/

ansurft.

Um die Aktualisierung des in Chrome integrierten Flash-Plugins anzustossen, startet man den Browser und surft man die folgende Adresse an:

chrome://components/

Dort sucht man den Eintrag „Adobe Flash Player“ und klickt auf den Button „Check for updates“:

image-7114

Tags: , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 14. Dezember 2016

Mehrere Benutzerkonten mit derselben E-Mail-Adresse

Bis kürzlich hatte ich noch nie von Web-Sites gehört, auf welchen man sich mit ein- und derselben E-Mail-Adresse mehrmals registrieren kann. PCP bricht aus mir unerklärlichen Gründen mit dieser Best Practice. Daraus resultieren dann Usability-Nightmares wie diese hier:

PCP Selbe E-Mail mehrere Benutzer
image-7110

Tags: , , , ,
Labels: Funny, Web

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 13. Dezember 2016

mitmproxy: Server-Antworten umschreiben (oder: M6 Geoblocker umgehen)

Heute durfte ich für einen Kollegen in den USA eine im Internet als Stream verfügbare M6 News-Sendung rippen.

Geoblocker

Damit ich an die m3u8-Datei des Streams herankam, musste ich aber zuerst die Geo-Sperre umgehen. Die Web-Site frägt nämlich beim Aufruf (gleich zweimal) ab, in welchem Land sich der Surfer befindet. Hierzu ruft der JavaScript-Code der Web-Site folgende zwei URLs auf:

Als Antwort erhält der Browser folgenden JSON-Code zurück (IP anonymisiert):

{"offset":"2","isp":"Andreas Fink","areas":[10],"country_code":"CH","asn":"AS6775","ip":"85.195.0.0"}

Diese Antwort bewegt den Player dazu, folgende Fehlermeldung anzuzeigen:

M6 6play Geoblock
image-7099

mitmproxy installieren und konfigurieren

Der erste Task war somit klar: Ich musste mit dem quelloffenen Tool mitmproxy alle HTTP(S)-Requests meines iPads proxyifizieren und dann obige JSON-Antwort mit einer validen Antwort ersetzen, so wie sie über einen französischen ISP erfolgen würde.

mitmproxy hatte ich bereits auf meinem lokalen Linux-Server konfiguriert, weshalb ich auf dem iPad in den Netzwerkeinstellungen den Proxy nur noch erfassen musste: 10.0.X.Y:8888.

Auf dem Linux-Server startete ich mitmproxy folgendermassen:

# mitmproxy -p 8888

Als nächstes musste ich noch das mitmproxy-Zertifikat auf dem iPad installieren, damit HTTPS-Verbindungen entschlüsselt und umgeschrieben werden können. Hierzu reicht es, auf dem iPad die folgende URL aufzurufen …

mitm.it

… und den Anweisungen zu folgen (ACHTUNG: Sicherheitssensitive Personen löschen das Zertifikat nach der Verwendung wieder vom iPad. Es findet sich unter Settings > General > Profiles).

Inline-Script zum Umschreiben von Antworten

Damit ich vom Proxy-Server empfangene Antworten der M6-Server umschreiben konnte, musste ich nun noch ein mitmproxy Inline-Script einbauen, welches Aufrufe auf die oben genannten URLs abfängt und nach meinem Gusto umschreibt.

Hierzu legte ich unter /tmp/m6-geoip.py folgendes Python-Script ab:

import json

def response(context, flow):
	f = open('/tmp/mitm.log','a+')
	url = flow.request.get_url()
	f.write('URL "' + url  + '"' + "\n")

	if url.endswith('geoInfo') or url.endswith('geoInfos'):
		f.write('    matched' + "\n")
		data = json.loads(flow.response.content)
		# {"offset":"2","isp":"Andreas Fink","areas":[10],"country_code":"CH","asn":"AS6775","ip":"85.195.0.0"}
		# {"offset":"2","isp":"QSC AG","areas":[1,2,3,10,11],"country_code":"FR","asn":"AS20676","ip":"92.222.83.58"} via http://www.franceproxy.net
		#data["country_code"] = "FR"
		#jsonOut = json.dumps(data)
		jsonOut = '{"offset":"2","isp":"QSC AG","areas":[1,2,3,10,11],"country_code":"FR","asn":"AS20676","ip":"92.222.83.58"}'
		flow.response.content = jsonOut
		f.write("    " + jsonOut + "\n")
	f.close()

Tipp 1: Da selten Leute vom Himmel gefallen sind, welche ein Script auf Anhieb richtig hingekriegt haben, hilft es zum Debugging, statt mitmproxy mitmdump zu verwenden:

# mitmdump -e -p 8888 -s "/tmp/m6-geoip.py"

Bei Python-Problemen mit dem Inline-Script wird der Stack Trace und die Fehlermeldung direkt auf der Kommandozeile ausgegeben.

Tipp 2: Die Ausgabe aller URLs in eine Log-Datei resultiert in Performance-Einbussen, kann für das Debugging aber sehr nützlich sein.

Anschliessend startete ich den mitmproxy neu:

# mitmproxy -p 8888 -s "/tmp/m6-geoip.py"

JSON-Quelle

Doch von wo hatte ich den JSON-String?

Nach etwas Googeln fand ich folgenden Proxy-Service:

www.franceproxy.net

Gibt man dort eine der obigen URLs ein, erhält man als Antwort den JSON-Code, welchen ich dann auch für die Umgehung des Geoblockers verwendete.

Kostenloser Tipp an die Web-Entwickler von M6: Die Geo-Location eines Aufrufs prüft man nicht im JavaScript auf dem Client, sondern auf dem Server.

Der erneute Versuch im Web-Browser

Ich lud die Web-Seite auf dem iPad erneut — erhielt zwar eine Fehlermeldung, dass trotzdem irgendetwas schief gelaufen war, doch im mitmproxy-Log fand sich die sehnlichst gesuchte URL zur m3u8-Datei:

lb.cdn.m6web.fr

Daraus — und mit Informationen der aktuellsten Sendung, welche sich auch für Schweizer streamen lässt — leitete ich die tatsächliche URL zur Master-Playlist ab:

e112.cdn.m6web.fr

Von dieser Datei war es dann nur noch ein Katzensprung zur m3u8-Datei mit dem Stream mit der höchsten Bit-Rate:

e112.cdn.m6web.fr

Und so lud ich den Stream dann mit ffmpeg herunter:

$ ffmpeg -protocol_whitelist file,http,https,tcp,tls -i "http://e112.cdn.m6web.fr/usp/mb_sd3/2/8/1/Le-1945_c11636016_19-45-du-dimanche-11/Le-1945_c11636016_19-45-du-dimanche-11_unpnp.ism/Le-1945_c11636016_19-45-du-dimanche-11_unpnp-audio_fra=93468-video_eng=1501000.m3u8" video.mp4

Tags: , , , , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 13. Dezember 2016

~/Library/Caches/com.apple.bird gigantisch

Wie bereits an folgenden Orten dokumentiert ist auch mein com.apple.bird auf 48.9 GB angewachsen:

Ein auf Github gefundenes Script namens blame-bird.py habe ich ausgeführt; das Resultat:

$ python blame-bird.py 
com.apple.Numbers                                   0.00MB      1
F6266T9T75.com.apple.iMovie                         0.00MB      1
LWL9XTYF8Q.com.syniumsoftware.macfamilytree7        0.00MB      1
com.apple.Pages                                     0.00MB      2
com.apple.Keynote                                   0.00MB      2
8YE23NZS57.com.kayak.travel                         0.00MB      3
iCloud.com.bodunov.galileo                          0.00MB      7
com.apple.mail                                      0.00MB     16
com.apple.TextInput                                 0.00MB     37
com.apple.TextEdit                                  0.00MB      3
4R6749AYRE.com.pixelmatorteam.pixelmator            0.00MB     53
com.apple.shoebox                                   0.00MB     38
iCloud.com.apple.iBooks                             0.02MB    310
57T9237FN3.net.whatsapp.WhatsApp                35564.12MB    717

Accounted for: 35564MB.  Still unaccounted: 16968MB

Also auch bei mir WhatsApp, welche das mit dem iCloud-Backup einfach nicht gebacken kriegen (im Sommer plagte mich folgendes, verwandtes Problem: WhatsApp kann nicht auf iCloud backupen).

Ich habe den Ordner nun gelöscht und hoffe, dass er nicht bald wieder fettleibig wird …

Labels: IT

1 Kommentar | neuen Kommentar verfassen

Montag, 5. Dezember 2016

Geschwindigkeiten von SD-Karten

Die Industrie unterscheidet zwei SD-Kartenarten: Standard sowie UHS.

Die (neueren) Standard-Karten kodieren ihre Geschwindigkeiten als Zahl in einem Kreis, aufgedruckt auf das Etikett:

Zahl im Kreis Geschwindigkeit
10 10 MBit/s
6 6 MBit/s
4 4 MBit/s
2 2 MBit/s

Die UHS-Karten haben die Geschwindigkeit als Zahl in einem u-ähnlichen Symbol aufgeführt:

Zahl im U Geschwindigkeit
3 30 MBit/s
1 10 MBit/s

Quelle: Speed Class

Tags: , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 27. November 2016

Die REST-API von SeedDMS ansprechen

Vor einiger Zeit habe ich mir auf meinem Linux-Server hier zu Hause das Dokumentenmanagement-System SeedDMS installiert. Ich habe dieses Produkt ausgewählt, weil es mit PHP programmiert ist (eine Alternative benötigt Java und scheint nach einem Testlauf nicht die erhofte Maturität aufzuweisen.)

Obwohl die Installation dieses Produkts auch nicht ganz simpel ist (dies erläutere ich dereinst in einem separaten Blog-Artikel), weist es die nötige Maturität aus und bringt eine ansehnliche Liste von Features mit. Grösstes Manko ist eine aktuelle, für Endanwender verständliche Dokumentation.

Eine der von mir gesuchten Funktionalitäten ist die REST API, welche man unter der URL /restapi/index.php ansprechen kann.

Als ich damit die ersten API-Calls machen wollte, kam leider eine leere Antwort zurück. Im php.err fand sich folgende Zeile:

...
[27-Nov-2016 11:55:44 Europe/Zurich] PHP Warning:  require(Slim/Slim.php): failed to open stream: No such file or directory in /var/www/seeddms/restapi/index.php on line 55
[27-Nov-2016 11:55:44 Europe/Zurich] PHP Fatal error:  require(): Failed opening required 'Slim/Slim.php' (include_path='/var/www/seeddms/::.:/usr/share/php/') in /var/www/seeddms/restapi/index.php on line 55
...

Hmmm! Da scheinen mit der Quickstart-Version 5.0.7 (die einzige, die ich auf meinem Server zum Laufen gebracht zu habe) nicht alle externen Dependencies mitzukommen.

Ein Issue auf Sourceforge bestätigt meine Vermutung, bringt aber keine Lösung mit (was bringt es dem Endbenutzer, wenn die Dependency im README ergänzt wird?).

Ein, zwei Google-Suchen später finde ich dann einerseits die Web-Site des Frameworks, andererseits das Github-Repository.

Doch wie und wo installiere ich das Paket nun?

Eine weitere Google-Suche leitet mich auf eine Web-Site weiter, welche die Dokumentenstruktur einer älteren SeedDMS-Installation auflistet und dabei auch einen Ordner Slim aufweist. Der Ordner enthält folgende Dateien:

Als ich diese Struktur mit dem Github-Repository verglich, konnte ich keine Ähnlichkeiten feststellen.

Dann der Geistesblitz: Vielleicht verwendet SeedDMS noch eine ältere Version des Frameworks? Richtig geraten: Aktuell trägt das Framework die Version 3.0, SeedDMS baut aber auf Version 2.0 des Frameworks auf.

Ein Blick auf die Dateistruktur des 2.x Branches bestätigt meine Vermutung. Ich lade mir von diesem Branch die ZIP-Datei herunter und kopiere anschliessend den Unterordner Slim im Ordner Slim-2.x in das Web-Root von SeedDMS (/var/www/seeddms/Slim).

Nun klappt der Aufruf der API, weil PHP die Include-Datei unter /var/www/seeddms/Slim/Slim.php findet!

Am Ende der /restapi/index.php findet sich auch eine Liste aller verfügbarer API-Calls:

$app->post('/login', 'doLogin');
$app->get('/logout', 'doLogout');
$app->get('/account', 'getAccount');
$app->get('/search', 'doSearch');
$app->get('/searchbyattr', 'doSearchByAttr');
$app->get('/folder/:id', 'getFolder');
$app->post('/folder/:id/move', 'moveFolder');
$app->delete('/folder/:id', 'deleteFolder');
$app->get('/folder/:id/children', 'getFolderChildren');
$app->get('/folder/:id/parent', 'getFolderParent');
$app->get('/folder/:id/path', 'getFolderPath');
$app->get('/folder/:id/attributes', 'getFolderAttributes');
$app->post('/folder/:id/createfolder', 'createFolder');
$app->put('/folder/:id/document', 'uploadDocument');
$app->get('/document/:id', 'getDocument');
$app->delete('/document/:id', 'deleteDocument');
$app->post('/document/:id/move', 'moveDocument');
$app->get('/document/:id/content', 'getDocumentContent');
$app->get('/document/:id/versions', 'getDocumentVersions');
$app->get('/document/:id/version/:version', 'getDocumentVersion');
$app->get('/document/:id/files', 'getDocumentFiles');
$app->get('/document/:id/file/:fileid', 'getDocumentFile');
$app->get('/document/:id/links', 'getDocumentLinks');
$app->get('/document/:id/attributes', 'getDocumentAttributes');
$app->put('/account/fullname', 'setFullName');
$app->put('/account/email', 'setEmail');
$app->get('/account/locked', 'getLockedDocuments');
$app->post('/accounts', 'createAccount');
$app->get('/accounts/:id', 'getAccountById');
$app->put('/accounts/:id/disable', 'setDisabledAccount');
$app->post('/groups', 'createGroup');
$app->get('/groups/:id', 'getGroup');
$app->put('/groups/:id/addUser', 'addUserToGroup');
$app->put('/groups/:id/removeUser', 'removeUserFromGroup');
$app->put('/folder/:id/setInherit', 'setFolderInheritsAccess');
$app->put('/folder/:id/access/group/add', 'addGroupAccessToFolder'); // 
$app->put('/folder/:id/access/user/add', 'addUserAccessToFolder'); // 
$app->put('/folder/:id/access/group/remove', 'removeGroupAccessFromFolder'); 
$app->put('/folder/:id/access/user/remove', 'removeUserAccessFromFolder'); 
$app->put('/folder/:id/access/clear', 'clearFolderAccessList');
$app->run();

Eine simple API-Abfrage schaut folgendermassen aus:

  1. /restapi/index.php/login mit den POST-Parametern user und pass
  2. Das Session-Cookie mydms_session=XXX; in eine Variable speichern. Es muss bei allen folgenden API-Calls mit übermittelt werden
  3. /restapi/index.php/searchbyattr?name=AttrName&value=AttrValue mit den GET-Parametern name und value
  4. Die Antwort wird als JSON zurückgegeben, welche mit json_decode() in ein PHP-Objekt/Array geparsed werden kann

Tags:
Labels: IT, Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 20. November 2016

Der beste Indikator, dass US-Asiaten tatsächlich die vielgepriesene Model Minority sind?

Eine Kollegin von Stephanie und mir hat heute auf Facebook den Artikel The real secret to Asian American success was not education gepostet.

Die Hypothese des Artikels ist es, dass die asiatischen Einwanderer in die USA nicht das höchste Einkommen aller US-Bevölkerungsgruppen verzeichnen, weil „sie“ strebsam und arbeitswillig sind sowie ihren Nachwuchs mit allen Mittel auf beste Schulnoten trimmen. Sondern weil seit den 1960er der Rassismus gegen diese Bevölkerungsgruppe markant zurückgegangen ist und die Gruppe im Berufsleben wie auch im gesellschaftlichen Leben zunehmend akzeptiert sei.

Man kann diese Model Minority noch so sehr über den Klee loben und herleiten, wieso gerade „die“ Asiaten geschafft haben, was bisher anderen Minderheiten (allen voran Afro-Amerikanern, aber auch Latinos) verwehrt geblieben ist — ich behaupte: Solange wir nicht mindestens ein halbes Dutzend asiatische Gesichter auf Apples Leadership Web-Seite sehen, haben es „die“ Asiaten (als gäbe es „die“ Europäer …) noch nicht geschafft, mit dem weissen Mann auf einer Stufe zu stehen:

Apple Executive Profiles

Dies ist aus meiner Sicht der beste, wenn auch völlig unwissenschaftliche Indikator, um die Gültigkeit des Model Minority-Status zu verifizieren.

Nachtrag

Wer aber wirklich Grips hat, wird insbesondere die Verallgemeinerung der „Asiaten“ in Frage stellen. Es macht auch keinen Sinn, einwandernde „Europäer“ alle in einen Topf zu werfen. Innerhalb der asiatischen Minderheit gibt es nämlich markante Unterschiede:

So, while Chinese-Americans and Indian-Americans are among the most prosperous groups in the country, Korean-Americans, Vietnamese-Americans, and Filipino-Americans have lower median personal earnings than the general population.

Quelle: THE TWO ASIAN AMERICAS

Nachtrag 2

Die Harvard Business Review gibt in einem Artikel mögliche Erklärungsansätze ab, wieso ein solcher „bamboo ceiling“ existiert:

As Wesley Yang wrote in New York magazine, Western society teaches that “the squeaky wheel gets the grease,” while Eastern society teaches that “the nail that sticks out gets hammered down.” […]

So Asians face a double bind as well: If they act more dominant, they will be less liked, but if they do not project dominance, they will not be seen as leaders.

Quelle: Why Aren’t There More Asian Americans in Leadership Positions?

Tags: , , , , , ,
Labels: Apple, USA

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 16. November 2016

Wenn sogar James Kunstler daneben liegt …

Knapp daneben ist auch vorbei … Ich mag den Contrarian und Prepper Kunstler sehr, doch das will nicht heissen, dass auch der Mann regelmässig warme Luft aussondert. Hier wagte er im September 2015 einen Blick in die Glaskugel:

I would not even bet against the possibility of the 2016 selection being canceled in some manner.

Quelle: The Parties Crawl Off to Die

Tags: , , , ,
Labels: USA

Keine Kommentare | neuen Kommentar verfassen

Montag, 14. November 2016

iMac erkennt sporadisch Original Apple-Tastatur nicht

Meine Frau hat vor einiger Zeit von meiner Schwester einen iMac Early 2009 geerbt. Die Maschine habe ich mittlerweile mit dem maximal möglichen Arbeitsspeicher sowie mit einer SSD-Festplatte ausgestattet und läuft dementsprechend für ihr biblisches Alter relativ flott.

Nur ein Problem hat mich bisher regelmässig eingeholt: Dann und wann erkennt der iMac nach einem frischen Neustart die Original Apple-Tastatur mit us-amerikanischem Layout nicht. Über dem Login-Fenster prangt dann ein Dialogfenster, welches einem zum Pairing einer Bluetooth-Tastatur und -Maus auffordert. Das Problem liess sich in solchen Fällen auch nicht durch mehrere Neustarts lösen.

Stattdessen hielt ich einzig aus diesem Grund die ursprünglich mit dem Gerät mitgelieferte Tastatur mit deutschweizerischem Tastaturlayout vorrätig. Wenn immer das Problem auftritt, musste ich die amerikanische Tastatur vom iMac trennen und diese Tastatur anschliessen. Die schweizerische Version wird auf Anhieb erkannt und funktioniert immer problemlos.

Vor einigen Tagen wurmte mich das Problem wieder einmal und ich startete eine weitere Google-Suche nach möglichen Ursachen und Lösungen meines Problems. Dieses Mal wurde ich im Diskussionsforum des Apfelherstellers selbst fündig:

external mac keyboard not working with maverick on macbook air

Ein Kommentar brachte die Erleuchtung:

Thanks, pal!
I was facing the same issue — Apple USB keyboard attached to MBA Mid2013 with Mavericks (latest updates installed so far) was iether working or not. It`s a real puzzle to figure out the logics it starts working. Have just tried extension cord and it`s working fine now.

In meinem Kabelarchiv fand ich tatsächlich ein besagtes USB-Verlängerungskabel und steckte es an den USB-Anschluss des iMacs und verband das Original-Tastaturkabel damit:

iMac Early 2009 USB Apple Keyboard Extension Cord
image-7060

Bis jetzt hat sich das Problem nie wieder gezeigt; ich bin aber erst vorsichtig optimistisch, dass mein Problem dadurch tatsächlich behoben wurde.

Was nicht funktioniert hat

Has your Apple Mac external USB keyboard stopped working?

Labels: Apple

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 13. November 2016

UniFi Access Points mittels IKEA-Hack in der Wohnung platzieren

Zur selben Zeit, als ich Brandmelder angeschafft habe und mir am Überlegen war, wie man diese Sensoren ohne Beschädigung der Decken in der Wohnung platzieren kann, habe ich mir auch zwei UniFi Access Point angeschafft.

Der IKEA-Hack mit den Variera Tellerhaltern für die Montage der Brandmelder liess sich 1:1 auch auf die Access Points übertragen, da IKEA Tellerhalter in zwei Grössen im Angebot führt (die UniFis hätten rein vom Durchmesser überhaupt nicht in die Brandmelder-Halterung gepasst). Für UniFi Access Points eignet sich das grössere der beiden Modelle, das Teller in der Grösse von 19cm bis 32cm aufnimmt:

VARIERA Tellerhalter, Buche hell, Edelstahl (IKEA Artikelnummer 802.404.16; 9.95 CHF)

Wieso dieser Aufwand? UniFi Access Points senden ihre Signale in Form eines „Donuts“ aus, wenn der Access Point horizontal aufliegt. Der „Donut“ ist aus der horizontalen Sicht aber nicht symmetrisch: Auf der Deckenseite des Access Point mit der Zuführung des Ethernet-Kabels ist die Abstrahlung weniger wulstig als auf der Luftseite (dort, wo das Logo prangt und die blaue LED leuchtet):

unifi-access-point-donut-horizontal
image-7049

NACHTRAG: Unter Antenna radiation pattern for UniFi AP (diagramm inside) habe ich weitere Diagramme gefunden:

unifi-horizontal-polarization-mounted-wall
image-7050

unifi-horizontal-polarization-mounted-roof
image-7051

unifi-vertical-polarization-mounted-wall
image-7052

unifi-vertical-polarization-mounted-roof
image-7053

Quelle: [Ervaringen/discussie] Ubiquiti-apparatuur

Dies ist einfach erklärbar: Die Macher der semi-professionellen Access Points gehen davon aus, dass die Dinger in der Regel an Decken montiert werden. Richtung Decke selber bringt eine WiFi-Durchdringung niemandem etwas, aber von der Decke weg (Richtung Zimmerboden) muss eine möglichst grosse Abdeckung erreicht werden.

Aus diesem Grund habe ich beide Access Points auf dem Tellerhalter montiert und in der Stube sowie im Büro möglichst an hoher Position aufgestellt. Das sieht dann so aus:

UniFi Access Point IKEA Variera Mount Living Room
image-7054

Tags: , , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen