Freitag, 26. Juni 2020

Palm m515 Handheld - Unter Windows 10 betreiben

Der Palm M515 gehörte im Jahr 2002 zu der PDA High-End-Serie. Er hat 16 MB Speicher, 4 MB Flash-ROM, 16-Bit-Farbdisplay mit 160 x 160 Pixeln Auflösung und eine Infrarot- sowie SD-Card-Schnittstelle. Als Software zum Datenabgleich kommt Palm Desktop 4.0.1 zum Einsatz und ist nur mit einer USB-Docking-Station möglich.


Was wird benötigt?

  • Gebrauchter Palm M515 bei ebay (kleinanzeigen) zwischen 10-20 EUR. Hinweis: Bitte darauf achten, dass auch eine funktionierende Docking Station (Hotsync) mit dabei ist.
  • Ggf. ein neuer Akku (850mAh, 3.7V).
  • SD-Karte (max. 1GB) bei ebay (kleinanzeigen) ab 1 EUR verfügbar.
  • Logitech TypeAway Keyboard bei ebay (kleinanzeigen) ab 1 EUR verfügbar.

Warum einen Palm im jahr 2020 verwenden?

  • Kleine Mitschriften und Notizen sind unterwegs komplett ohne Internetverbdinung möglich und wandern somit auch nicht in irgendeine Cloud (Datenschutz).
  • Einsatz als ultra kleine Schreibmaschine möglich in Verbindung mit dem Logitech TypeAway Keyboard und Anwendung CardTXT (https://freeware.palmclub.nl/c1/108-cardtxt.html). Die Dateien werden auf der SD-Karte (max. 1GB) im txt-Format abgespeichert und können am PC direkt weiter verarbeitet werden (SD-Karte aus dem Palm entnehmen und in den PC stecken).
  • Mit einem neuem Akku, hat der Palm eine sehr lange Akkulaufzeit im Standby (ca. 3-4 Wochen). 
 

Installation unter Windows 10


Software installieren

  • Quick Install im Palm Desktop aufrufen
  • Die zu installierenden Dateien (.prc) hinzufügen und anschließend den "Hotsync" durchführen

Installation Logitech TypeAway-Tastatur

Zuerst benötigt man einen Treiber, welcher per "Hotsync" direkt auf dem Palm installiert werden muss. Siehe dazu auch https://download01.logitech.com/web/ftp/pub/pdf/keyboards/typeaway.pdf .

 
Achtung: Der mitgelieferte Treiber funktioniert nur auf Palm OS 4. Es gibt aber auch einen Beta-Treiber für OS5, welcher auch mit dem Tungsten T funktioniert. Siehe ftp://ftp.logitech.com/pub/techsupport/keyboards/pda/ .



Freitag, 5. Juni 2020

Firefox - command line option, start from a batch file

Will man nach dem Starten von Windows direkt mit seinen Lieblingswebseiten surfen, bietet sich beim Firefox Browser die folgenden Möglichkeiten per "command line" oder "batch file" an.


Aufruf per command line (cmd):

"C:\Program Files\Mozilla Firefox\firefox.exe" -new-window "http://www.ebay.de/" -new-window "https://www.mydealz.de/" -new-window "https://mail.google.com/mail/u/0/#inbox"


Aufruf per batch file (.bat):

@echo off
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" -new-window "http://www.ebay.de/" -new-window "https://www.mydealz.de/" -new-window "https://mail.google.com/mail/u/0/#inbox"

Donnerstag, 4. Juni 2020

Cloud - Pizza as a Service

Was hat eigentlich "Pizza" mit Cloud Services zu tun?

 
Das Pizza Modell von Albert Barron (veröffentlicht in 2014 auf Linkedin) beschreibt anhand von "Wie möchte ich eine Pizza essen?" die unterschiedlichen Cloudvarianten.
  • Pizza selbst machen
  • Tiefkühlpizza in den Ofen schieben
  • beim Lieferdienst bestellen,
  • ins Restaurant gehen

Die Entscheidung für ein Servicemodell ist dabei abhängig von,
  • wie viel man selbst erledigen kann und will,
  • wie viel Zeit man hat,
  • wie viel man vom Kochen versteht
  • oder welche Zutaten ­man gerade zur Verfügung hat.


Quelle: Albert Barron (https://www.linkedin.com/pulse/20140730172610-9679881-pizza-as-a-service)

Sonntag, 31. Mai 2020

Clickjacking - Schutz mit Hilfe von Content Security Policy (CSP) oder X-Frame-Options

Bei Clickjacking versucht eine böswillige dritte Website die eigentliche Website des Nutzers in einem unsichtbaren Rahmen zu laden bzw. zu überlagern (z.B. per iframe). Der Benutzer wird dann dazu verleitet, Aktionen auf der ursprünglichen (böswilligen) Website auszulösen ohne dass er sich dessen bewusst ist.


Hintergrund: Clickjacking ist ein konzeptionelles Problem von JavaScript und Webanwendungssicherheit. (Quelle: https://de.wikipedia.org/wiki/Clickjacking)
 

Welche Gegenmaßnahmen gibt es?


Um so einen Angriff zu verhindern, sollte man eine explizite Whitelist von Seiten definieren, die die aktuelle Seite über die Direktive für Frame-Vorfahren in die Content Security Policy (CSP) einbetten können.

Damit auch ältere Browser unterstützt werden, kann der (veraltete) Header X-Frame-Optionen zusätzlich auf DENY oder SAMEORIGIN gesetzt werden. Die Option DENY verhindert, dass Browser die Website in einem iframe anzeigt.

Header set X-Frame-Options "DENY"

Wird der Header auf SAMEORIGIN gesetzt, kann die Website in iframes auf anderen Seiten derselben Domain eingebettet werden, verhindert jedoch das Einbetten in Websites von dritten.

Header always set X-Frame-Options "SAMEORIGIN"

Wichtig: X-Frame-Options funktioniert nur durch den HTTP-Header, und NICHT per meta-tag! Daher muss die Einstellung direkt im Apache vorgenommen oder per .htaccess gesetzt werden.

Dienstag, 26. Mai 2020

Leaflet.js - draggable marker und Ausgabe der Koordinaten (lat, lng)

In dem Beitrag "Webseite mit interaktiver Karte ohne Google Maps? Leaflet.js" hatte ich beschrieben, wie man Leaflet.js auf seiner Webseite als gute Alternative zu Google Maps einbindet. 


In diesem Beispiel geht es darum einen "ziehbaren" Marker zu erstellen und die Koordinaten in zwei Feldern (lat, lng) anzuzeigen.


Es wird die Dragend-Methode für den Marker verwendet um lat und lng abzufangen:

<script type="text/javascript">
    function showMap() {
      
        var map = L.map('map_leaflet').setView([50.9033081, 9.5924615], 14);
        var my_divicon = L.divIcon({
            className: 'arrow_box'
        });
        var marker = L.marker([50.9033081, 9.5924615], {
            draggable:true
        });
        function addToTextBox(lt,ln){
            document.getElementById('lat').innerHTML = lt;
            document.getElementById('lng').innerHTML = ln;
          
        }
        marker.on('dragend', function(event){
            //alert('drag ended');
            var marker = event.target;
            var location = marker.getLatLng();
            var lat = location.lat;
            var lon = location.lng;
            addToTextBox(lat,lon);
            //alert(lat);
            //retrieved the position
          });
       
        // load a tile layer
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            {
                attribution: 'Map data © OpenStreetMap and contributors CC-BY-SA',
                maxZoom: 18,
                minZoom: 9
            }).addTo(map);
          
        // initialize the map
        //var map = L.map('map_leaflet', { layers: osm, tap: false } );
        L.control.scale({imperial:false}).addTo(map); // metrisch

        marker.addTo(map);
    }
</script>



Samstag, 23. Mai 2020

JavaScript - Fetch API File Upload: Apache 403 Forbidden error SecFilterEngine

Für eine Erweiterung meiner Webcamseiten, benötigte ich ein Formular mit Bild-Upload-Funktion. Das Hochladen von Dateien ist eine der häufigsten Funktionen für eine Webanwendung. Ich verwende in meinem Beispiel KEINE der vielen JavaScript-Bibliotheken, sondern die Fetch-API (eine native JavaScript Funktion).


Als erstes benötigt man auf der Webseite ein HTML Formular mit einem Eingabeelement:

...
    <form action="xyz.php" name="melderForm" method="post" enctype="multipart/form-data">
...
        <input id="formMelderImage-file" class="form-control" type="file">
...
    </form>


Mit dem folgenden JavaScript Code wird ein Event-Listener hinzugefügt, wenn der Benutzer eine Datei auswählt. Mit der Methode fileUpload () wird ein Dateiobjekt als Eingabe empfangen und es mit fetch () auf den Server hochgeladen (inklusive einer Überprüfung des Dateityps (nur Bilder) und der Dateigröße (< 10MB).

<script>
    // Datei vom Formular
    const fileInput = document.getElementById('formMelderImage-file');

    // event listener
    fileInput.addEventListener('change', () => {
        fileUpload(fileInput.files[0]);
    });
   
    const fileUpload = (file) => {
        // Check des Dateityps
        if(!['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml'].includes(file.type)) {
            console.log('Es sind nur Bilder erlaubt!');
            return;
        } else if(file.size > 10 * 1024 * 1024) { // Check der Groesse (< 10MB)
            console.log('Die Datei muss kleiner 10MB sein!');
            return;
        } else {
            // Datei zum FormData object hinzufügen
            const fd = new FormData();
            fd.append('formMelderImage-file', file);

            // `POST` request senden
            fetch('/upload/image', {
                method: 'POST',
                body: fd
            })
            // Abfangen von Fehlern
            .then(res => res.json())
            .then(json => console.log(json))
            .catch(err => console.error(err));
        }
    }
</script>

SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data" - 403 Forbidden


404- oder 403-Fehlern nach dem Senden eines Formulars können an der mod_security-Einstellung in Apache auf dem Server liegen. Das Apaches-Modul mod_security hat standardmäßig ein Upload-Limit von 60 KB, sodass bei jedem größeren Upload ein 403-Fehlercode ausgegeben wird.

Man kann versuchen diese zu deaktivieren, und folgendes zu der .htaccess-Datei hinzuzufügen, man wird aber vermutlich keinen Erfolg mehr haben (support for .htaccess files was discontinued in 2.x as it raised too many security issues https://stackoverflow.com/questions/19093542/how-to-disable-mod-security-and-mod-security2-in-htaccess/19196856#19196856)

<IfModule mod_security.c>
  SecFilterEngine Off
</IfModule>

Oder wenn man direkten Zugriff auf die Apache Einstellungen hat, geht dies auch direkt unter nano  /etc/httpd/conf.d/mod_security.conf .

<IfModule mod_security.c>

    # Turn the filtering engine On or Off
    SecFilterEngine Off

Freitag, 24. April 2020

Raspberry Pi - Adafruit Mini PiTFT 135x240 Color TFT Add-on [Programmierung]

In dem Betrag Raspberry Pi - Adafruit Mini PiTFT 135x240 Color TFT Add-on wurde das Display bereits näher beschrieben. In diesem Beitrag möchte ich das Display als Erweiterungsoption für die Raspberry Pi - zero : Wetterstation incl. OLED-Display vorstellen. Zur Anzeige von WLAN-, Sensor- und Speicherplatzinformationen. Zusätzlich kann direkt ein Upload des Webcam Bildes und ein Reboot per Tastendruck erfolgen.


Hinweis: Als Basis wurden die Beispiele von Adafruit für das Display verwendet.

Im ersten Schritt wurden die Befehle/Funktionen definiert, welche den jeweiligen Status anzeigen sollen oder per Buttondruck aufgerufen werden sollen.


cmdWlanSsid = "iwconfig wlan0 | grep ESSID | awk -F: '{print $2}'"
cmdHostName = "hostname -I | cut -d' ' -f1"
cmdCam = "vcgencmd get_camera | cut -d' ' -f2" #supported=1 detected=1 => OK
cmdDisk = 'df -h | awk \'$NF=="/"{printf "Disk: %d/%d GB  %s", $3,$2,$5}\''
cmdWebcam = '/home/pi/webcam/webcam.sh'
cmdReboot = 'sudo reboot'

def is_connected():
    try:
        # connect to the host -- tells us if the host is actually
        # reachable
        socket.create_connection(("www.google.com", 80))
        return "online"
    except OSError:
        pass
    return "offline"


# Temperatursensor ermitteln
SensorPfad = "/sys/bus/w1/devices/" # Pfad
SensorNames = open("/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves" ,"r")
Sensor = SensorNames.readline()
if Sensor:
    SensorNames.close() 


Anschließend werden diese Informationen an das Display in einer "while" Schleife gesendet.


while True:
     
        # Draw a black filled box to clear the image.
        draw.rectangle((0, 0, width, height), outline=0, fill=(0, 0, 0))
     
        #Show WLAN
        WLAN = subprocess.check_output(cmdWlanSsid, shell=True).decode("utf-8")
...
        # Write lines of text.
        y = top
        draw.text((x, y), WLAN, font=font, fill="#FFFFFF")
...
        # Display image.
        display.image(image, rotation)
        time.sleep(0.1)


 

Mit Hilfe von buttonA = digitalio.DigitalInOut(board.D23) kann das Drücken der Taste abgefangen werden. 


So erfolgt beim Drücken des "Button A" ein "Upload des Webcam Bildes" mit dem bekannten Script (https://sebastianhemel.blogspot.com/2019/11/raspberry-pi-camera-modul-v21.html) und beim Drücken des "Button B" die Anzeige eines "Copyright". Werden beiden Tasten gleichzeitig gedrückt, erfolgt ein Reboot des Pi.

...
        if buttonB.value and not buttonA.value:  # just button A pressed
...
            y = top
            text = "Webcam Upload..."
            draw.text((x, y), text, font=font, fill="#FFFFFF")
            y += font.getsize(text)[1]
            # Display image.
            display.image(image, rotation)
            subprocess.check_output(cmdWebcam, shell=True).decode("utf-8")
            draw.text((x, y), "...finished!", font=font, fill="#FFFFFF")
...



Anbei das komplette Python Script (rgb_display_stats-picture.py), welches man am Besten direkt beim Booten starten sollte.

sudo nano /etc/rc.local

Und die folgende Zeile hinzufügen:

sudo python3 /home/pi/rgb_display_stats-picture.py &

vor dem "exit 0" in der Datei.