OTP in der Gnome Shell

2018-11-12

Ich habe das Bashscript zur Erzeugung von One-Time-Passwords (OTP) erweitert, um es mit Hilfe von Argos in die Gnome Shell zu integrieren. Zwei Mausklicks genügen dann, um ein OTP in die Zwischenablage zu kopieren. Das Script ist hier und so sieht es dann aus.

OTP in der Gnome Shell

Tags: Bash, Argos, otp, Gnome-Shell

OTP mit Bash und Android

2018-10-02

Zwei-Faktor-Authentifizierung (2FA) erhöht die Sicherheit der eigenen Konten erheblich und sollte, wann immer möglich, auch verwendet werden. SMS und OTP (Einmalpasswort) gehören dabei zu den häufigsten Methoden, die zur Anwendung kommen. Für beides eignet sich ein Smartphone, unter Android ist der Google Authenticator sicher der bekannteste Generator. Ich nutzte lieber andOTP, da dieses erlaubt die Kontoinformationen in einer einfachen JSON-Datei zu speichern. Diese kann dann leicht vom Smartphone auf den PC übertragen werden. Die Datei dient dann als Backup, falls man sein Handy verliert, und man kann daraus mit Bash OTP-Codes direkt auf dem PC erzeugen. Das folgende Script macht das ganz einfach möglich:

#!/usr/bin/env bash
set -euo pipefail
IFS="$(printf '\n\t')"
# --- CONFIG
readonly JSON_FILE="${HOME}/.config/otp_accounts.json"
# ---

error()
{
  echo "[Error]: $*" >&2
}

if [[ ! -f "$JSON_FILE" ]]; then
  error "Password file $JSON_FILE is missing. Abort."
  exit 101
fi


if [[ $(stat -c %a "$JSON_FILE") != 600 ]]; then
  error "Password file has wrong permissions. Abort."
  exit 102
fi

checkTool()
{
    if ! type -p "$1" &>/dev/null; then
        error "$1 is not installed, exiting..."
        exit 1
    fi
}

checkTool oathtool
checkTool jq
checkTool sed

for ROW in $(jq -c 'sort_by(.label) | .[]' "${JSON_FILE}"); do
    each()
    {
        echo "${ROW}" | jq -r "$1"
    }

   LABEL=$(each '.label')
   SECRET=$(each '.secret')
   CODE=$(oathtool --totp -b "$SECRET" | sed 's/\(...\)/\1 /g' )
   echo " --- ---    -----------"
   echo " ${CODE}   ${LABEL}"
done
echo " --- ---    -----------"

Tags: OTP, Android, Bash

Radicale auf Uberspace 6 installieren

2018-06-10

Radicale ist ein Open-Source CalDAV und CardDav Server

Installation

Die Installation erfolgt mit dem Python-Paketmanager pip für den lokalen Nutzer.

$ python3.6 -m pip install --upgrade radicale --user

Als Alternative kann man Radicale auch in seiner eigenen virtuellen Umgebung installieren.

$ mkdir Radicale
$ cd Radicale
$ python3.6 -m venv venv
$ source venv/bin/activate
(Radicale) $ python3.6 -m pip install --upgrade radicale

Konfiguration

Einen freien Port ermittelt man mit uberspace-add-port. Den ermittelten Port trägt man dann in die Konfiguration ein. Hier benutze ich als Beispiel(!) 63970.

Die Konfiguration muss unter ~/.config/radicale/config abgelegt werden. Zusätzlich kann man auch die Umgebungsvariable RADICALE_CONFIG verwenden. Die Konfiguration kann etwa so aussehen:

[server]
# Bind all addresses
hosts = 0.0.0.0:63970

[auth]
type = htpasswd
htpasswd_filename = ~/.config/radicale/users
htpasswd_encryption = plain
ssl = True
certificate = /cert.pem
key = /privkey.pem

[storage]
filesystem_folder = ~/.config/radicale/collections

[rights]
# Rights backend
# Value: None | authenticated | owner_only | owner_write | from_file | custom
type = owner_only

Dabei ist alles der Einfachheit halber in .config/radicale abgelegt. Die Benutzernamen sind plain im Dateisystem abgelegt. Schließlich sind die Kalender und Adressbücher selber ja auch unverschlüsselt auf der Platte.

Damit der Server auch von außen erreichbar ist, wird unter /html/radicale folgende .htaccess angelegt:

RewriteEngine On
RewriteRule ^(.*) http://localhost:63970/$1 [P]

Jetzt testen wir erstmals ob die Konfiguration funktionier und von außen erreichbar ist:

$ ~/bin/radicale

Über das Webinterface kann man jetzt für die Benutzer Kalender und Adressbücher anlegen. Es ist erreichbar unter http://<ubernaut>.<server>.uberspace.de/radicale/. Das ist besonders wichtig, wenn man Thunderbird mit Lightning benutzen will! Hilfe für die Konfiguration der einzelnen Clients um die Kalender und Adressbücher zu synchronisieren findet man hier.

Dämon

Zur Einrichtung des Dämons benötigen wir ein Starterskript unter ~/bin/run-radicale.sh.

#! /bin/sh
python3.6 -m radicale -Df 2>&1

Die Option -f sorgt dafür, dass Radicale nicht selber versucht als Dämon zu laufen. Die -D schalten Debug-Informationen auf, die beim Debugging helfen. Die Einrichtung erfolgt mit uberspace-setup-service run-radicale ~/bin/run-radicale.sh im Nu.

Tags: Uberspace, CalDAV, Radicale

Das Rad neu erfinden

2018-04-11

Für die häufigsten Probleme gibt es akzeptierte Lösungen oder fertige Tools. Dazu gehört das Packen von Sprites oder Texturen in eine große Textur oder Sprite-Sheet. Kein Grund also wieder einmal das Rad neu zu erfinden. Es sei denn man hält es wie Richard Feynman:

What I cannot create, I do not understand.

In meinem Fall hatte ich etwas überspezifische Anforderungen, die keines der verfügbaren Tools für mich bot. Die Informationen der Subtexturen sollten im JSON-Format vorliegen und die Möglichkeit diese über numerische IDs zu finden. FSM sei Dank, hat Nicolas Perdu genug Vorarbeit geleistet um meine Wunsch-Features einfach selber zu implementieren ohne alles Drumherum neu zu machen. (Mal wieder ein Paradebeispiel für die Vorteile von FOSS).

Schwuppdiwupp, und der Sprite Sheet Packer ist fertig! Das JSON-Format ist sehr einfach und sieht so aus:

{"TextureAtlas":
{
    "imagePath": "example",
    "SubTexture":
    [
        { "name": "img17", "x": 235, "y": 149,
            "width": 58, "height": 59,
            "rotation": 0, "id": 2822025959 },
        { "name": "img18", "x": 470, "y": 0,
            "width": 29, "height": 76,
            "rotation": 0, "id": 948678518 }
    ]
}}

Die numerischen IDs sind einfache CRC32-Summen der Dateinamen. Das ist einfach genug, ich erwarte da sobald keine Kollisionen. Man kann sich auch gleich eine C++-Header mit allen IDs generieren lassen. Einfacher geht es wirklich nicht. Durch die großartige Vorarbeit von Jukka Jylänk ist auch auf der algorithmischen Seite alles erschlagen. Das Packergebnis sieht gut aus und ich muss kein weiteres Gehirnschmalz in dieses Problem investieren.

Example sprite sheet packing

Tags: GameDev, C++

Podcasts mit Bash abonnieren

2018-02-15

Podcatcher gibt es wie Sand am mehr. Bisher habe ich gPodder auf dem Desktop und AntennaPod für Android verwendet. Auf dem Smartphone ist aber der Speicherplatz begrenzt und der Desktop wird gar nicht mehr so oft verwendet wie früher. Ideal wäre auf dem Server per cronjob Podcasts zu abonnieren. Vor allem das öffentlich-rechtliche Angebot wird regelmäßig wieder de-publiziert. Glück, wer ein Archive hat.

Dafür gibt es sicher schon was, bestimmt auch in Bash?
Tatsächlich gibt es was, aber entweder ist der Funktionumfang zu gering oder das Projekt wird nicht mehr gepflegt. Also schnell was selbst (nein, nicht neu geschrieben) geforkt und angepasst. Taadaa, willkommen DashPodder!

Jetzt hat man ein einfaches Skript auf dem Server, das Podcasts aus Feeds heraus speichert. Warum nicht auch auf dem Desktop genauso Podcasts abonnieren? Mit Hilfe von Argos kann man seine Skripte einfach in die Gnome Shell integrieren. Das sieht dann etwa so aus:

DashPodder in der GNOME Shell

Nächster Halt Bash auf Android! :-)

Tags: Bash, Podcast, DashPodder, Argos

Rückblick Wolfenstein 3D

2017-09-19

Eine nostalgische Fahrt zurück an den Anfang der 1990er beginnt mit dem ersten Game Engine Black Book von Fabien Sanglard. Darin beschreibt er im technischen und historischen Kontext wie Wolfenstein 3D enstand und den Grundstein sowohl für id Software als auch für das Genre des Ego-Shooters legte. Zu Beginn werden die Grundlagen zur damaligen PC-Technik gelegt bzw. aufgefrischt. Bereits hier kann der Leser in wohligen Kindheitserinnerung schwelgen. Ordentlich sortierte Diskettenboxen, stundenlanges Kopieren für den nächsten Schultag oder vergebliches Optimieren des freien Arbeitsspeichers kommen zurück in Gedächtnis.

Game Engine Black Book: Wolfenstein 3D

Fabien Sanglard

Game Engine Blackbook Wolfenstein 3D

Besonders die Einordnung der Hardware der damaligen Zeit erlaubt dem Leser die Errungenschaften von Wolfenstein 3D technisch einzuordnen. Dabei wird nicht an Details gespart, egal ob 286, 386, Real Mode, Protected Mode oder VGA Graphik. Zusammen mit den Unmengen Trivia und Kommentaren von John Carmack bekommt man nicht nur ein Gefühl für die Zeit, sondern man versteht im Detail die Technik. Was Raycasting leistet und was nötig war um Wolfenstein wieder und wieder zu portieren. Die Tools die für Wolfenstein 3D verwendet wurden, sagen in ihrer Einfachheit viel über das Spiel selbst. Dieses Buch behandelt die Technik erschöpfend und konservierend für die Zukunft.

Für mich war Wolfenstein 3D nicht der einschneidende Meilenstein, auch nicht Doom. Das war für mich doch erst Quake. Die unzähligen Stunden mit diesen Spielen haben viele aus meiner Generation nachhaltig geprägt. Der sozio-kulturelle Aspekte kommen hier in diesem Buch nicht vor. Es geht nicht um das Spiel oder die Kunst. Fabien Sanglard nimmt eine rein technische Nerdperspektive ein und beschreibt Wolfenstein 3D einzig aus dieser Sicht aber umfassend. So ist das Buch fast schon eine Pflichtlektüre für interesseierte Programmierer unabhänngig vom Alter. Die Leistungen, die id Software damals vollbracht hat, ist auch ihne Nostalgie heute noch lehrreich. In dieser komprimierten Form ist das Buch einzigartig. Eine klare Leseempfehlung!

Tags: Bücher, Engine

C++-Projekte mit CMake

2017-07-27

Makefiles von Hand schreiben ist einfach nur nervig. Je mehr Dateien das Projekt hat, umso nerviger wird es korrekte Abhängigkeiten oder Unittests zu pflegen. Die Liste an Alternativen zu GNU Make ist natürlich sehr lang. Da ich in der Regel nur C++-Projekte unter Linux bauen will, landete ich letztendlich bei CMake. Dabei erzeugt CMake in meinem Fall auch nur wieder ein Makefile, ach die Ironie.

Aufteilung

Das Beispiel hier zeigt einen Auszug für ein Programm, das in einen Library-Teil mylib und einen Executable-Teil myprg aufgeteilt ist. Den Einstieg enthält dann die Datei main.cpp und wird gegen mylib gelinkt. Die statische Bibliothek kann man später genauso nutzen um gegen die Unittests zu linken.

# target CMakeLists.txt
add_library(mylib STATIC
    DataItem.cpp
    DataItemManager.cpp
)
add_executable(myprg main.cpp)
target_link_libraries(myprog mylib)

Unity Build

Unity Builds sind auch als Single Compilation Unit Builds bekannt und können die Kompilierzeit verkürzen und bessere Optimierungen ermöglichen. Mit einem Modul wie cotire ist es mit wenigen Zeilen eingerichtet. Man erhält damit neue Build-Targets, die auf _unity enden.

# top level CMakeLists.txt
include(cotire)
# target CMakeLists.txt
cotire(myprg)

Testabdeckung

Mit Unittests bin ich eher bereit größere Änderungen am Code vorzunehmen. Damit man mögliche Regressionen sehr früh findet, sollten die Unittest möglichst alle/viele Pfade abdecken. Auch für die Testabdeckung gibt es ein passendes CMake-Modul. Mit nur drei Zeilen gibt es ein weiteres Maketarget coverage dafür.

# top level CMakeLists.txt
include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()
SETUP_TARGET_FOR_COVERAGE(NAME "coverage" EXECUTABLE "unittest")

Statische Analyse

Zur statischen Code-Analyse mit cppcheck genügt das Erzeugen der Kompilierungs-Kommandos, da es CMake bereits unterstützt.

$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
$ cppcheck --project=compile_commands.json

Ich bin sehr zufrieden mit CMake und seinen Möglichkeiten. Letztendlich kopiere ich mir zwar immer noch die nötigen Dateien aus alten Projekten zusammen und am Ende führe ich ein Makefile aus, aber alles funktioniert zuverlässig und ich habe nützliche Zusatzfunktionen, die ich niemals selbst mit make umgesetzt hätte. Selbst Boost wird auf CMake umsatteln. So erwarte ich eine noch besser Unterstützung von C++ in der Zukunft.

Tags: Code, CMake, C++

Zuletzt gelesen

2017-02-18

Auf erzählerische und einfache Weise gelingt es Gregory T. Brown den nicht technischen Alltag bei der Softwareentwicklung einzufangen. Die einzelnen Episoden geben dem Leser eine Gelegenheit den eigenen Arbeitsalltag zu reflektieren. Nicht jeder hat zwar direkt mit einem Kunden zu tun, aber die Beispiele lassen sich leicht auf "Fachbereiche" oder andere Teilnehmer übertragen. Die kleinen Geschichten geben einem auch einen guten Ansatz, wenn man mal das eigene Schaffen einem Laien näher bringen möchten. Programmieren ist für ein Programmieräffchen dann doch nicht alles (^_^)

Programming Beyond Practices

Gregory T. Brown

Programming Beyond Practices

Die Bücher von Scott Meyers gehören einfach zu den Standardwerken, die jeder C++-Programmierer mindestens einmal in der Hand hatte. Dieses gehört ganz klar dazu. Gerade zum Nachschlagen ist es ideal. Vor dem Hintergrund von C++14 und C++17 frage ich mich aber schon, ob eine Überarbeitung und Erweiterung der alten Bücher nicht der bessere Weg wäre. Auch wenn das Wissen in den alten Büchern nicht obsolet ist, so ist zumindest etwas "gealtert". Trotzdem bleibt dieses Buch vorerst eine Pflichtlektüre.

Effective Modern C++

Scott Meyers

Effective Modern C++

Tags: Bücher, C++