Für Indy .p12 zu .pem wandeln

Literatur

Zur Beachtung Unter Delphi 2009 funktioniert die unten angegebene Funktion testCert zwar, aber der Zugriff auf einen anderen Server lieferte nur 403 Forbidden. Unter Delphi 10 Tokyo funktioniert der Zugriff immer.

  • Delphi 2009: Indy version: 10.2.5
  • Delphi 10.2: Indy version: 10.6.2.5366

Convert a PKCS#12 file (.pfx .p12) containing a private key and certificates to PEM

openssl pkcs12 -in zugang.p12 -out zugang.pem -nodes

in Delphi

  • me ist vom Typ TMemo
uses
  SysUtils, Classes, Forms, IdHTTP, IdSSLOpenSSL, idGlobal,
   Controls, ComCtrls, ToolWin, StdCtrls;

function TForm1.testCert: boolean;
var IdHTTP1 : TIdHTTP;
    Id_HandlerSocket : TIdSSLIOHandlerSocketOpenSSL;
    cert:string;
    s : string;
begin
    try
      me.Clear;
      IdHTTP1 := TIdHTTP.Create( self );
      IdHTTP1.Request.BasicAuthentication := False;
      IdHTTP1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
      Id_HandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create( IdHTTP1 );
      cert := 'zugang.pem';
      Id_HandlerSocket.SSLOptions.CertFile := cert; (* PEM contain both CERT and Key *)
      Id_HandlerSocket.SSLOptions.KeyFile := cert;

      Id_HandlerSocket.SSLOptions.Mode := sslmClient;
      Id_HandlerSocket.SSLOptions.Method := sslvSSLv23;
      IdHTTP1.IOHandler := Id_HandlerSocket;

      me.Add( Id_HandlerSocket.SSLOptions.CertFile );

      s := IdHTTP1.Get( 'https://www.scriptjunkie.us/auth/verifycert' );

      me.Add( s );
      Result:=True;

    finally
      Id_HandlerSocket.Free;
      IdHTTP1.Free;
    end;
end;

do-release-upgrade auf Kubuntu 18.04

$ do-release-upgrade -m desktop -f DistUpgradeViewKDE -d

Nebenwirkungen

  • yakuake hat seine Konfiguration vergessen
  • pip ist auf Version 9.x zurückgesetzt
$ python3 -m pip --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)
$ python3 -m pip install --upgrade pip
$ python3 -m pip --version
pip 10.0.1 from /home/wnf/.local/lib/python3.6/site-packages/pip (python 3.6)
  • Firebird SQL Server ist nur in Version 3.0 verfügbar, so dass die Datenbanken über die Datensicherung neu erzeugt werden müssen.
fdb.fbcore.DatabaseError: ('Error while connecting to database:
 - SQLCODE: -820
 - unsupported on-disk structure for file /var/lib/firebird/2.5/data/datenbank.fdb;
   found 11.2, support 12.0
 - IProvider::attachDatabase failed when loading mapping cache', -820, 335544379)
  • Lazarus und libfbclient
Can not load default Firebird clients ("libfbclient.so.2.5.1" or "libgds.so" or "libfbembed.so.2.5"). Check your installation.

Durch setzen eines symbolischen Links kann das Problem gelöst werden:

$ cd /usr/lib/x86_64-linux-gnu/
$ sudo ln -s libfbclient.so.3.0.2 libfbclient.so.2.5.1

Der Zugriff von externen Rechnern ist standardmäßig nicht möglich. Deshalb muss die Datei /etc/firebird/3­.0/firebird.conf editiert werden:

alt:

RemoteBindAddress = localhost

neu:

RemoteBindAddress =

danach den Firebirrd-Server neu starten:

$ sudo service firebird3.0 restart

Javascript Tabelle füllen und beim Scrollen Datensätze nachladen

Literatur

<!DOCTYPE html>
<html lang="de">
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=9">
  <meta charset="utf-8">
  <meta name="author" content="wlsoft">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta name="robots" content="index,follow">
  <title>Datens&auml;tze beim scrollen nachladen</title>
  <link rel="stylesheet" href="css/wnfportal_2.css" type="text/css"/>
  <script src="js/jquery-2.1.1.min.js" type="text/javascript"></script>

  <script type="text/javascript">

  var QUERY_LISTEA = 'jsonListEASkip';
        var listeaJSON = {};
  var aSkip = 0;
  var aFirst = 20;
  var aSumme = 0;

        function getfirst_ea(){
                aSkip = 0;
                $.getJSON(QUERY_LISTEA+'/'+aFirst+'/'+aSkip, '', jsonEintragen);
        }

        function getnext_ea(){
                $.getJSON(QUERY_LISTEA+'/'+aFirst+'/'+aSkip, '', jsonEintragen);
        }

  function addZeile(aDatum,aBez,aBetrag) {
    var tableRef = document.getElementById('table_EA').getElementsByTagName('tbody')[0];
    // Insert a row in the table at the last row
    var newRow   = tableRef.insertRow(tableRef.rows.length);
    // Insert a cell in the row at index 0
    var newCell  = newRow.insertCell(0);
    // Append a text node to the cell
    var newText  = document.createTextNode(aDatum);
    newCell.appendChild(newText);

    var newCell  = newRow.insertCell(1);
    var newText  = document.createTextNode(aBez);
    newCell.appendChild(newText);

    var newCell  = newRow.insertCell(2);
    var newText  = document.createTextNode(aBetrag);
    newCell.appendChild(newText);
  }

  function editFuss(aAnzahl,aBez,aBetrag) {
    document.getElementById('foot_EA_0').innerHTML=aAnzahl;
    document.getElementById('foot_EA_1').innerHTML=aBez;
    document.getElementById('foot_EA_2').innerHTML=aBetrag;
  }

  function jsonEintragen(aData) {
                if (!$.isEmptyObject(aData)){
                        console.log(aData);
                  for (var i = 0; i < aData.length; i++) {
                    aBetrag=parseFloat(aData[i].betrag);
        addZeile(aData[i].datum,aData[i].kurz,aBetrag.toFixed(2));
        aSumme += aBetrag;
                }
                        aSkip += aFirst;
                        console.log(aFirst,aSkip);
      editFuss(aSkip,'Summe',aSumme.toFixed(2));
                }
        }

  function datenNachladen(event) {
    //Nachladen erst, wenn das Ende erreicht wird
    if($(window).scrollTop() == $(document).height() - $(window).height()) {
      console.log('Nachladen ...');
      getnext_ea();
    }
  }

  function dokumentGeladen(event) {
    getfirst_ea();
  }

  document.addEventListener('DOMContentLoaded', dokumentGeladen, false);
  document.addEventListener('scroll', datenNachladen)

  </script>
</head>
<body>
<h1 id="listeaHeader">Einnahmen/Ausgaben</h1>
<table id="table_EA">
  <thead>
  <tr>
    <th>Datum</th>
    <th>Bezeichnung</th>
    <th>Betrag</th>
  </tr>
  </thead>
  <tbody>
  </tbody>
  <tfoot>
    <th id="foot_EA_0"></th>
    <th id="foot_EA_1">Bezeichnung</th>
    <th id="foot_EA_2"></th>
  </tfoot>
</table>
</body>
</html>
Tags: 

CLT 2018

https://chemnitzer.linux-tage.de/…a78627d053e2

CLT = 2 Tage mit besuchten 8 Vorträgen für 10 Euro

Mein verlinkter Stichwortzettel

1. Linux-Server absichern

2. Container-Docker

3. MQTT

4. IoT-Sicherheit

5. Hardware-Erstellung (bestückte Leiterplatten)

  • KrCad
  • iOM
  • Bill of Material

6. Rescue-Pi

  • Finnix
  • Bananapi 1GBit LAN (50 Euro)
  • SD-Card 32 GB (10 Euro)
  • Gehäuse (9 Euro)

7. ESP32

8. App

Tags: 

Angular de_DE (de) und Euro

Damit die Währungsanzeige in Angular mit Pipes funktioniert, wie zum Beispiel hier:

<h2>Kontostand</h2>
<table class="kontostandRecords">
  <tr>
    <th>Datum</th>
    <th>Bezeichnung</th>
    <th>Betrag</th>
  </tr>
  <tr *ngFor="let konto of kontostandRecords"
    [class.selected]="konto === selectedKonto">
    <td>{{konto.datum | date: 'dd.MM.yy'}}</td>
    <td><a routerLink="/kubea/detail/{{konto.id}}">{{konto.kurz}}</a></td>
    <td class="wnfDM">{{konto.betrag | currency: '€'}}</td>
  </tr>
  <tr *ngIf="kontostandSumme">
    <th>Summe</th>
    <th></th>
    <th class="wnfSumme">{{kontostandSumme.summe | currency: '€'}}</th>
  </tr>
</table>

muss die Datei app.module.ts ergänzt werden um:

...
import { registerLocaleData } from '@angular/common';
import localeDE from '@angular/common/locales/de';
..
registerLocaleData(localeDE);
...
  providers: [
      {
      provide: LOCALE_ID,
      useValue: 'de' // 'de-DE' for Germany, 'fr-FR' for France ...
      },
..

Dabei ist zu beachten, dass es in angular/common/lo­cales kein de_DE gibt, sondern nur de

FLXP-9iaU-Qk6B-8P4A-KYwY

Tags: 

Javascript beliebte Fehler

Der verwöhnte Delphi-Programmierer hat unter Javascript zu leiden.

In dieser Tabelle (kontostand.com­ponent.html) wurde nichts angezeigt

<h2>Kontostand</h2>
<table class="kontostandRecords">
  <tr>
    <th>Datum</th>
    <th>Bezeichnung</th>
    <th>Betrag</th>
  </tr>
  <tr *ngFor="let konto of kontostandRecords"
    [class.selected]="konto === selectedKonto">
    <td>{{konto.datum | date: 'dd.MM.yy'}}</td>
    <td><a routerLink="/kubea/detail/{{konto.id}}">{{konto.kurz}}</a></td>
    <td class="wnfDM">{{konto.betrag}}</td>
  </tr>
</table>

weil in der Datei (kontostand.com­ponent.ts) ein falscher Name für kontostandRecords verwendet wurde:

export class KontostandComponent implements OnInit {
  kontenRecords: KontoRecord[];
  ...
  getKontostand(): void {
    this.kubeaService.getKontostand()
        .subscribe(konto => this.kontenRecords = konto);
  ...
  }

nach der Korrektur von kontenRecords auf kontostandRecords

export class KontostandComponent implements OnInit {
  kontostandRecords: KontoRecord[];
  ...
  getKontostand(): void {
    this.kubeaService.getKontostand()
        .subscribe(konto => this.kontostandRecords = konto);
  }
}

funktioniert die Anzeige des Kontostandes.

Tags: 

Radicale auf BBB

Die Installation von Radicale als CalDav und CardDav Server auf meinem BBB war erfolgreich. Radicale kommt mit einem eigenen Http-Server daher und muss deshalb nicht in nginx eingebunden werden.

Leider hatte Thunderbird/Lig­htning bei der ganzen Probiererei die Zusammenarbeit mit meinem CalDav-Kalender eingestellt. Es gab nur das gelbe Warndreieck: „Der Kalender ist nicht verfügbar“. Wie „hier (Kalender syncronisiert nicht – DAV_NOT_DAV – gelbes Warndreieck)“: https://www.thunderbird-mail.de/…warndreieck/ zu lesen ist, liegt das daran, dass Thunderbird die Passwörter nur einmal pro Server speichern kann. Deshalb habe ich

  • die Passwörter für den Radicale-Server in Thunderbird gelöscht.
  • Den Radicale-Kalender in Thunderbird abgemeldet
  • Thunderbird neu gestartet
  • Den Radicale-Kalender neu erstellt (mit der kompletten Pfadangabe, wie Radicale sie anzeigt.)
https://radicale.fritz.box:5232/user/xxxa40a-84cb-b167-4d4c-06f92db7xxx/
  • Es wird erneut nach User und Passwort gefragt, dann sollte der Radicale Kalender auch unter Thunderbird funktionieren.

Literatur

wnfPortal mit angular

Erzeuge Projekt wnfPortal

Web-Oberfläche für wnfKontakt und wnfKuB

$ ng new wnfportal
$ cd wnfportal
$ ng serve

NG Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/

Projekt in Github eintragen

Dazu auf Github ein leeres Repository anlegen (ohne .gitignore, ohné Readme und ohne Lizenz, sonst gibt es Ärger mit den folgenden Befehlen.)

$ cd wnfportal/
$ git init
$ git add .
$ git commit -m "First commit"
$ git remote add orign https://github.com/wnf58/wnfportal
$ git remote -v
$ git push orign master

Erzeugen der Komponente und des Service kubea

$ cd wnfportal
$ ng generate component kubea
$ ng generate component kubea-detail
$ ng generate component kubea-search
$ ng generate component dashboard
$ ng generate service kubea --module=app
$ ng generate service message --module=app
$ ng generate module app-routing --flat --module=app

angular httpclient

Der httpclient holt die anzuzeigenden Daten von meinem CherryPy-Server. Dabei kommt es zu dem beliebten Fehler No ‚Access-Control-Allow-Origin‘ header is present. Wie in Stackoverflow beschrieben muss der Cherrypy-Server folgendermaßen gestartet werden:

def server_dict():
    '''Erstellung der Konfiguration für CherryPy'''
    g={}
    g['tools.staticdir.root']=os.path.dirname(os.path.abspath(__file__))
    g['server.socket_port']=8081
    g['server.socket_host']='0.0.0.0'
    g['tools.sessions.on']=True
    g['tools.sessions.timeout'] =1000
    g['tools.sessions.name']="wnfportal8081id"
    g['tools.CORS.on'] = True
    c={'global': g}
    c['/']={'tools.staticdir.on':True,'tools.staticdir.dir':"www",'tools.staticdir.index' : "index.html"}
    return c

def CORS():
    cherrypy.response.headers["Access-Control-Allow-Origin"] = "*"

def main():
    cherrypy.tools.CORS = cherrypy.Tool('before_handler', CORS)
    cherrypy.quickstart(wnfPortal(),config=server_dict())
$ ng serve --host 0.0.0.0 --disable-host-check

Eine Kopie für den Verkauf erstellen

#!/bin/bash
DIRECTORY="/home/wnf/Entwicklung/wnfportal"
cd $DIRECTORY
pwd
ng build --prod
if [ -d "$DIRECTORY/dist" ]; then
  # Control will enter here if $DIRECTORY exists.
  rsync -azve ssh --delete "$DIRECTORY/dist/" wnf@bone2013.fritz.box:/var/www/wnfportal
fi
Tags: 

Seiten