**Dies ist eine alte Version des Dokuments!**

PlayGround

[SN: Vorläufige Testversion 25.März 2016; Links zu aufgeführten Dateien und erklärenden Bildern fehlen noch und werden in den nächsten Tagen nachgeholt]

Anleitung zur Headersignierung mit dem Hamster

Benötigt wird GPG4Win, ein paar Scripte, etwas Zeit und natürlich ein Hamster.

GPG4win bekommt man dort: https://www.gpg4win.org/index-de.html

Den Hamster kann man hier downloaden: http://hamster-classic.de/download:download

Wenn GPG4win installiert wurde, sollte man sich zuerst gründlich einlesen.

Dann nach Anleitung einen PGP-Key erstellen, den wir später im Script zum signieren benötigen.

Dieser (öffentliche) Key sollte natürlich auch auf einen Keyserver hochgeladen werden, damit andere die damit signierten Header auch überprüfen können.

GPG4win bietet mit dem Programm „Kleopatra“ ein komfortables Werkzeug genau dies zu erledigen.

Als nächstes bringen wir dem Hamster das signieren bei. Die folgende Datei GnuPGUsenetHeader.hsc

!hs2

!load hstrings.hsm

!load hmessage.hsm

# GnuPG_Usenet_Header.hsc

Autor: Michael Jaritz

Version vom 20.11.2010

Abgeleitet von XPGPSig_GnuPG_Sign.hsc / Michael Jaritz

Signiert ein Posting in Hamster\NewsOut mit einem

X-PGP-Sig-Header mittels GnuPG (gpg.exe)

und setzt einen X-PGP-Hash-Header SHA1 (oder auch wahlweise MD5)

Falls der Hamster ein Playground ist:

#!load hclassic.hsm

HIER NOCH NICHTS ÄNDERN!

Ob das Script per Action oder per RunScript aufgerufen wird ist egal,

es wird immer das richtige ParamStr(x) genommen.

varset( $sign_this, ParamStr(paramcount) )

Test-Eintrage - nach kurzem Test deaktivieren

print("Test_a: " + ParamStr(0))

print("Test_b: " + ParamStr(1))

print("Test_c: " + ParamStr(2))

print("Test_d: " + ParamStr(3))

print("Test_e: " + $sign_this)

Test-Eintraege

zur Erzeugung von eindeutigen temporären Dateinamen

var( $msgnumber ) REParse( $signthis, „(\d+).msg$“, $msgnumber )

fuer lokale Newsgruppen:

if( $msgnumber == „“ ) $msgnumber = ticks endif

Wie sollen die temporären Dateien heissen?

varset( $pgptmptosign, HamPath + $msgnumber + „sign.tmp“ ) varset( $pgptmpsigned, HamPath + $msg_number + „sign.tmp.asc“ )

Test-Eintrage - nach kurzem Test deaktivieren

print("Test_f: " + $pgp_tmp_to_sign)

print("Test_g: " + $pgp_tmp_signed)

Test-Eintraege

Anfang individuelle Änderungen

welche Header sollen signiert werden:

varset( $xsignedheaders, „Subject,Newsgroups,User-Agent,Message-ID,Date,From“ )

GnuPG-spezifisches

varset( $pgppath, „C:\Programme\GNU\GnuPG\“ )

^^^^^^^^^^^^^^^^^^^^^^^^^^^ # <----- Kontrolle erforderlich!

varset( $PGP_Command, „cmd.exe /C “ + $pgppath + „gpg2.exe“ )

normal C, K zum testen ->^^ ^^^^^^^^^^^^ im Falle von GnuPG1.4.x gpg.exe

Key-spezifisches

varset( $my_key, "2048R/C4A5CB88" )

^^^^^^^^Test-Key fuer Testgruppen!

varset( $mykey, „2048R/1D07D78E“ ) # ^^^^^^^^^^^^^^^^ # hier den eigenen Key eintragen! RSA oder DSA # für RSA-Keys zB # varset( $mykey, „2048R/AA00BB00CC“ )

für DSA-Keys zB # varset( $my_key, "1024D/CC11BB00" )

var( $rsadsa, $myID ) REParse( $mykey, „^\d+(.)\/(.+)$“, $rsadsa, $myID )

^^^^^^^^ ^^^^^^

in $rsa_dsa steht nur "R" wenn RSA oder "D" wenn DSA

in $my_ID steht der eigentliche Key (zur Angabe fuer --local-user

if( $rsadsa == „R“) varset( $PGPclearsign, „ –batch –quiet –local-user “ + $myID + „ –no-comments –clearsign –passphrase-file=passphrase.txt –digest-algo SHA512 “ + chr(34) + $pgptmptosign + chr(34) )

varset( $PGP_clearsign, " --batch --quiet --local-user " + $my_ID + " --no-comments --clearsign --passphrase-file=passphrase.txt " + chr(34) + $pgp_tmp_to_sign + chr(34) )

^^^^^^ <---- Deine RSA-Key-Passphrase

elseif( $rsa_dsa == „D“)

varset( $PGPclearsign, „ –local-user “ + $myID + „ –pgp2 –no-comments –clearsign “ + chr(34) + $pgptmpto_sign + chr(34) )

else

  print( "Der Key ist kein RSA- oder DSA-Key! Geht nicht." )
  quit

endif

Ende individuelle Änderungen

varset( $postingtosign, ArtAlloc() ) ArtLoad( $postingtosign, $sign_this )

varset( $headerlist, ListAlloc() ) ListSetText( $headerlist, ArtGetHeaders( $postingtosign) )

varset( $bodylist, ListAlloc() ) ListSetText( $bodylist, ArtGetBody( $postingtosign) )

var( $i, $j, $line, $version, $hdrtmp0, $hdrtmp1, $hdrtmp2, $erg, $exitcode ) var($signedmessageflag, $beginsignatureflag, $endsignatureflag, $versionflag, $xpgpsig )

varset( $tosignlist, ListAlloc() ) ListAdd( $tosignlist, „X-Signed-Headers: “ + $xsignedheaders )

$hdrtmp0 = $xsignedheaders while( REExtract( $hdrtmp0, „.+,.+“ ) != „“ ) RESplit( $hdrtmp0, „,“, $hdrtmp1, $hdrtmp2 )

ListAdd( $to_sign_list, $hdrtmp1 + ": " + ArtGetHeader( $posting_to_sign, $hdrtmp1, 1 ) )
$hdrtmp0 = $hdrtmp2

endwhile ListAdd( $tosignlist, $hdrtmp2 + „: “ + ArtGetHeader( $postingtosign, $hdrtmp2, 1 ) ) ListAdd( $tosignlist, „“ )

$i = 0 while( $i < ListCount($bodylist) ) ListAdd( $tosignlist, ListGet( $bodylist, $i ) )

inc($i)

endwhile ListAdd( $tosignlist, „“ )

ListSave( $tosignlist, $pgptmpto_sign )

print( $PGPCommand + $PGPclearsign ) # nur zum testen $erg = Execute( $PGPCommand + $PGPclearsign, hampath, 1, true, $exitcode ) print(„Execute liefert “ + $erg + „ zurück - mit $exitcode = “ + $exitcode) # nur zum testen

varset( $signedlist, ListAlloc() ) varset( $hcount, 2 ) varset( $signhash, „MD5“ )

varset( $signhash, "SHA512" )

ListLoad( $signedlist, $pgptmpsigned ) $i = 0 $signedmessageflag = false $beginsignatureflag = false $endsignatureflag = false $versionflag = false while( $i < ListCount($signedlist) )

$line = ListGet( $signed_list, $i )
if( $i == 0 )
    if( RE_Match( $line, "^-----BEGIN PGP SIGNED MESSAGE-----$" ) )
        inc($i)
        if( RE_Match( ListGet( $signed_list, $i ), "^$" ) )
            $signedmessageflag = true
        endif
        if( RE_Match( ListGet( $signed_list, $i ), "^Hash: .+" ) )
            RE_Parse( ListGet( $signed_list, $i ), "^.+ (\S+)$", $signhash )
            inc($i)
            inc($h_count)
     if( RE_Match( ListGet( $signed_list, $i ), "^$" ) )
                $signedmessageflag = true
            endif
        endif
    endif
endif
if( $i > $h_count )
  if( RE_Match( $line, "^-----BEGIN PGP SIGNATURE-----$" ) )
    $beginsignatureflag = true
    inc($i)
    if( RE_Match( ListGet( $signed_list, $i ), "^Version: .+" ) )
      $versionflag = true
      $version = Replace( ListGet( $signed_list, $i ), "Version: ", "" )
      $version = Replace( $version, " ", "_", 1 )
      inc($i)
      if( RE_Match( ListGet( $signed_list, $i ), "^$" ) )
        $j = $i + 1
        if( RE_Match( ListGet( $signed_list, ListCount($signed_list) - 1 ), "^-----END PGP SIGNATURE-----$" ) )
          $endsignatureflag = true
        endif
      endif
    endif
  endif
endif
inc($i)

endwhile

if( $signedmessageflag && $beginsignatureflag && $endsignatureflag && $versionflag )

if( $signhash != "MD5" )
    ListAdd( $header_list, "X-PGP-Hash: " + $signhash )
endif
ListAdd( $header_list, "X-PGP-Sig: " + $version + " " + $x_signed_headers )
for( $i, $j, ListCount($signed_list) - 2, 1 )
  ListAdd( $header_list, "      " + ListGet( $signed_list, $i ) )
endfor
ListAdd( $header_list, "" )
for( $i, 0, ListCount($body_list) - 1, 1 )
  ListAdd( $header_list, ListGet( $body_list, $i ) )
endfor
ListSave( $header_list, $sign_this )

endif

ListFree( $tosignlist ) ListFree( $bodylist ) ListFree( $headerlist ) ArtFree( $postingtosign ) ListFree( $signed_list )

löschen der temporären Dateien

if( FileExists( $pgptmptosign ) ) FileDelete( $pgptmptosign ) endif if( FileExists( $pgptmpsigned ) ) FileDelete( $pgptmpsigned ) endif

quit

wird im Hamster im Menü „Automatische Abläufe“ → ausgehender Artikel eingetragen http://hamster-classic.de/_media/playground:headersignierung:hamstergpg-script.png

Anschließend benötigt der Hamster noch einen Eintrag in der Datei, welche den automatischen Versand und Empfang von Mail und News regelt. Folgendes kurzes Script soll als Beispiel dienen:

!load hamster.hsm

AtClear

AtAdd Beispile-Eintrag:

AtAdd ( Mail, "00:00", "23:59", "1111111", 15, true )

Der Eintrag bewirkt ein automatisches abholen und versenden

aller eMail ueber die im Menue eingetragenen Mailserver.

Dies geschieht 24 Stunden lang, alle 15 Minuten.

Gleiches gilt fuer den Eintrag AtAdd ( News, ...) alle 5 Minuten.

Nutzungsbedingungen des Providers beachten und ggfls. anpassen!

Auch sind die Anzahl der Threads im Hamster nach den Vorgaben des

Newsproviders zu bachten! 2 Threads reichen im allgemeinen aus.

AtAdd ( Mail, „00:00“, „23:59“, „1111111“, 15, true ) AtAdd ( News, „00:00“, „23:59“, „1111111“, 5, true )

AtAdd ( Purge, "05:55", "", "1111111")

AtExecute

Quit

Anfang Sub-News

Sub News HamWaitIdle

HamNewsPull Beispiel-Eintrag:

HamNewsPull ("news.provider.tld,nntp")

HamNewsPull(„news.tota-refugium.de,nntp“) HamNewsPull(„reader.albasani.net,nntp“) HamNewsPull(„news.szaf.org,nntp“)

HamNewsPost Beispiel-Eintrag:

HamNewsPost ("news.provider.tld,nntp")

HamNewsPost(„news.tota-refugium.de,nntp“) HamNewsPost(„reader.albasani.net,nntp“) HamNewsPost(„news.szaf.org,nntp“)

HamWaitIdle EndSub

Ende Sub-News

HamNewsJobsClear HamNewsJobsPostDef HamNewsJobsPullDef HamNewsJobsStart

HamWaitIdle

Anfang Sub-Mail

Im Beispiel ist nur jeweils ein Server fuer POP3 und SMTP

eingerichtet. Wenn mehrere Postfaecher gewuenscht sind, oder

bei mehreren genutzten Absender-Adressen die jeweiligen Post-

faecher genutzt werden sollen, dann bitte in den Hamsterguppen

nach einer speziellen Loesung fragen! Dies hier ist lediglich

ein einfaches Beispiel zur Demonstration und Fehlersuche!

Sub Mail HamWaitIdle

HamFetchMail („securepop.t-online.de“) HamSendMailAuth („securesmtp.t-online.de“)

HamWaitIdle Endsub

Ende Sub-Mail

Anfang Aufruf des Scriptes zur Headersignierung

Aktuelles und funktionierendes Script:

RunScript( „GnuPGUsenetHeader.hsc“, ParamStr(2), true)

Ende Aufruf des Scriptes zur Headersignierung

quit

Zum signieren der Header war es das eigentlich schon.

Jetzt geht es an die Überprüfung signierter Header: Dazu wird einfach nur das Script AutoVerifynewsinnew.hsc

!hs2

!load hstrings.hsm

!load hmessage_casesensitiv.hsm

# AutoVerify_newsin_new.hsc

Autor: Michael Jaritz (sub getAlgoFormHash von Alfred Peters)

Version vom 31.12.2012

Stand: 29.07.2015

# Schaut sich Postings waehrend der Newsin-Action an.

Falls ein Header X-PGP-Sig existent ist wird versucht diesen zu verifizieren.

Der eventuell vom Signierenden gesetzte Header X-PGP-Hash wird dabei nicht beachtet.

Der benutzte Hash (MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224) wird aus der

Signatur ermittelt und in einem Header X-PGP-Hash-Info notiert.

Das Ergebnis wird in einem Header X-MyCheck-PGP im Klartext notiert.

Das Ergebnis wird in einem Header X-PGP-V utf8-codiert notiert.

Ob man sich im Newsreader X-MyCheck-PGP oder X-PGP-V anzeigen laesst, hängt vom

benutzten Newsreader ab.

# Was braucht das Script?

# 1. HamsterClassic

# 2. GnuPG, siehe http://www.gnupg.org/ in Version 1.4.x oder 2.0.x

# 3. Das Modul hmessage_casesensitiv.hsm,

siehe http://zielgra.de/temp/hamster/hmessage_casesensitiv.hsm

das ist die hmessage.hsm die beim Hamster dabei ist, nur sind die

lower() deaktiviert, damit Gross-/Kleinschreibung erhalten bleibt.

# 4. Ein Unterverzeichnis namens "XPGPtmp" im Hamsterverzeichnis, also zB

D:\Hamster\XPGPtmp\

BEGINN individuelle Aenderungen

Wie muss GnuPG aufgerufen werden?

fuer GnuPG1.4.x, zB

varset( $PGP_Command, "cmd /C C:\Programme\GNU\GnuPG14\gpg.exe" )

fuer GnuPG2.0.x, zB

varset( $PGP_Command, "cmd /C C:\Programme\GNU\GnuPG2\gpg2.exe" )

fuer GnuPG2.0.x unter Win7 (x64) und höher

varset( $PGP_Command, "cmd /C " + chr(34) + "C:\Program Files (x86)\GNU\GnuPG\gpg2.exe" + chr(34) )

fuer GnuPG2.0.x unter Vista

varset( $PGP_Command, „cmd /C “ + chr(34) + „C:\Programme\GNU\GnuPG\gpg2.exe“ + chr(34) )

varset( $PGP_Command, HamPath + "bin\run_gpgv.exe" )

print( ParamStr( ParamCount ) ) # nur zum testen

ENDE individuelle Aenderungen

Allerlei andere Variablen:

varset( $hdrtmp0, $hdrtmp1, $hdrtmp2, „xxxxxxxxxxxxx“ ) # ist ein Test-Rest, muss nicht so sein var( $xpgpsigall, $xpgpsigline1, $version, $xsignedheaders, $sigline ) var( $i, $j, $k, $line, $erg, $exitcode, $acthash, $xpgphash, $setresult, $gpgreturncode, $execreturn, $gpgreturn ) varset( $dummy, $errsig, „xxx“ ) var( $art, $artall, $artheader, $artbody, $setresultQP, $set_resultB64, $Xref )

$art = ArtAlloc ArtLoad( $art, ParamStr( ParamCount ) ) $artheader = ArtGetHeaders( $art )

Falls Artikel einen X-PGP-Sig-Header enthaelt...

if( REMatch( $artheader, „(?sm-i)^X-PGP-Sig: .+“ ) ) # …und noch keinen X-MyCheck-PGP-Header enthaelt if( ! REMatch( $artheader, „(?sm-i)^X-MyCheck-PGP: .+“ ) )

    $Xref = ArtGetHeader( $art, "Xref" )
    $Xref = Replace( $Xref, " ", "", true, false )
    $Xref = Replace( $Xref, ".", "", true, false )
    $Xref = Replace( $Xref, ":", "", true, false )

    # Mit welchen temporaeren Dateien soll GnuPG arbeiten?
    varset( $pgp_tmp_signed, HamPath + "XPGPtmp\" + $Xref + "gpg_to_verify.tmp" )
    varset( $pgp_tmp_log,    HamPath + "XPGPtmp\" + $Xref + "gpg__log.tmp" )
    varset( $pgp_tmp_status, HamPath + "XPGPtmp\" + $Xref + "gpg__stat.tmp" )

# varset( $pgptmpready, HamPath + „XPGPtmp\“ + $Xref + „gpg__ready.tmp“ ) # wird unter WIN nicht mehr benötigt

    # die Optionen und Files mit denen GnuPG aufgerufen wird
    varset( $PGP_verify, "--verify --logger-fd=1 --status-fd=2 --allow-weak-digest-algos --utf8-strings " + $pgp_tmp_signed + " 1> " + $pgp_tmp_log + " 2> " + $pgp_tmp_status )

    # Die folgende Zeile maskiert die Pfade, welche Leerzeichen enthalten, zu den temporären Dateien. 
    # Beispiel: "C:\Program Files\Hamster\XPGPtmp\newstota-refugiumdedetest101215gpg_to_log.tmp"
    # Das Ergebnis funktioniert über die Konsole(!) - jedoch *nicht* aus diesem Script! "*log.tmp" & "*stat.tmp" werden nicht angelegt! 

# varset( $PGPverify, „–verify –logger-fd=1 –status-fd=2 “ + chr(34) + $pgptmpsigned + chr(34) + „ 1> “ + chr(34) + $pgptmplog + chr(34) + „ 2> “ + chr(34) + $pgptmp_status + chr(34) )

    $artall = ArtGetText( $art )
    $artbody = ArtGetBody( $art )
    # Liste mit den moeglichen Hashes erstellen
    varset( $hash_list, ListAlloc() )
    ListAdd( $hash_list, "MD5" )
    ListAdd( $hash_list, "SHA1" )
    ListAdd( $hash_list, "RIPEMD160" )
    ListAdd( $hash_list, "SHA256" )
    ListAdd( $hash_list, "SHA384" )
    ListAdd( $hash_list, "SHA512" )
    ListAdd( $hash_list, "SHA224" )

    # Das Flag $is_verified wird true wenn
    # GnuPG eine brauchbare Meldung entlockt werden konnte
    varset( $is_verified, false )

    # In der Liste $sig_list wird die Signatur eingelesen
    # Beispiel:
    # X-PGP-Sig: 2.6.3ia From,Newsgroups,Subject,Approved,Message-ID,Date
    #	iQCVAwUBSByZBuapsbxd5uZZAQEgLQP/UfH0izqyva3AIb/I80FcSa6quXuUglGJ
    #	K2ph7ibQ1HCRNUMLQvTmQdowZJgysMGUgjh1wJSLRYePwqFOa/vaeXVt2Abx64Sm
    #	+EEirClVfKFrPlC0x1nHPWN8Un1IIDU7Of8m8OUzONPAKDYo/VD/Q5mdJ5P6XCzp
    #	3qKuJk+tSXI=
    #	=jPEf
    varset( $sig_list, ListAlloc() )

    # In $body_list kommt der Text des Postings
    varset( $body_list, ListAlloc() )

    # In $test_asc wird die Datei gebaut, die
    # letztendlich GnuPG zum verifizieren gegeben wird
    varset( $test_asc, ListAlloc() )

    # in $result_list wird der GnuPG-Output eingelesen
    varset( $result_list, ListAlloc() )

    # in $status_list wird der GnuPG-Status eingelesen
    varset( $status_list, ListAlloc() )

    # Je Posting werden zwei Listen gebraucht, weil es
    # zwar ArtGetBody gibt aber nicht ListGetbody, und List...
    # wird gebraucht um Casesensitiv zu bleiben
    varset( $signed_posting_art, ArtAlloc() )
    varset( $signed_posting_list, ListAlloc() )

    # das Posting in die zwei Listen packen
    ListSetText( $signed_posting_list, $artall )
    ArtSetText( $signed_posting_art, $artall )

    # Inhalte des Headers X-PGP-Sig einlesen
    $xpgpsig_all = MsgGetHeader( $signed_posting_list, "X-PGP-Sig:" )

    # Inhalte des Header X-PGP-Sig in $sig_list schreiben
    ListSetText( $sig_list, $xpgpsig_all )
    # 1.Zeile der Signatur, zB "2.6.3ia From,Newsgroups,Subject,Approved,Message-ID,Date"
    # in $xpgpsig_line1 packen
    $xpgpsig_line1 = ListGet( $sig_list, 0 )


    varset( $getAlgoFormHash_Info_str, "" )

# von Alfred:

      varset( $trueHash, getAlgoFormHash( $sig_list ) )

# Print( „Hashverfahren laut Hash: “ + $trueHash )

von Alfred:

    # Version und signierte Header trennen und in $version bzw. $x_signed_headers packen
    RE_Parse( $xpgpsig_line1, "^(.+) (\S+)", $version, $x_signed_headers )

    # die Datei zum Verifizieren:
    ListAdd( $test_asc, "-----BEGIN PGP SIGNED MESSAGE-----" )
    ListAdd( $test_asc, "Hash: " + $trueHash )

# ListAdd( $testasc, „“ ) # hier kommt der Hash hin………………alte Version ListAdd( $testasc, „“ )

      ListAdd( $test_asc, "X-Signed-Headers: " + $x_signed_headers )
      # Die Einzelheader aus X-Signed-Headers holen
      $hdrtmp0 = $x_signed_headers
      while( RE_Extract( $hdrtmp0, ".+,.+" ) != "" )
          RE_Split( $hdrtmp0, ",", $hdrtmp1, $hdrtmp2 )
          ListAdd( $test_asc, $hdrtmp1 + ": " + MsgGetHeader( $signed_posting_list, $hdrtmp1+":") )
          $hdrtmp0 = $hdrtmp2
      endwhile
      # den letzten Header setzen
      if( $hdrtmp2 != "" ) # ist eigentlich Quatsch, da muss was drinstehen
          ListAdd( $test_asc, $hdrtmp2 + ": " + MsgGetHeader( $signed_posting_list, $hdrtmp2+":" ) )
      endif
      # Leerzeile vor den Bodytext setzen
      ListAdd( $test_asc, "" )
      # Den Bodytext einsetzen
      ListSetText( $body_list, ArtGetBody( $signed_posting_art ) )
      $k = 0
      while( $k < ListCount($body_list) )
          $line = ListGet( $body_list, $k )
          if( RE_Match( $line, "^-" ) )
              $line = replace( $line, "-", "- -" )
          endif
          ListAdd( $test_asc, $line )
          inc( $k )
      endwhile
      # Leerzeile hinter den Bodytext setzen
      ListAdd( $test_asc, "" )
      ListAdd( $test_asc, "-----BEGIN PGP SIGNATURE-----" )
      ListAdd( $test_asc, "Version: " + $version )
      ListAdd( $test_asc, "" )
    # Die Signatur selbst einsetzen
    #	iQCVAwUBSByZBuapsbxd5uZZAQEgLQP/UfH0izqyva3AIb/I80FcSa6quXuUglGJ
    #	K2ph7ibQ1HCRNUMLQvTmQdowZJgysMGUgjh1wJSLRYePwqFOa/vaeXVt2Abx64Sm
    #	+EEirClVfKFrPlC0x1nHPWN8Un1IIDU7Of8m8OUzONPAKDYo/VD/Q5mdJ5P6XCzp
    #	3qKuJk+tSXI=
    #	=jPEf
    $k = 1
    while( $k < ListCount($sig_list) )
        $line = ListGet( $sig_list, $k )
        RE_Parse( $line, "\s*(.+)", $sigline )
        ListAdd( $test_asc, $sigline )
        inc( $k )
    endwhile
    ListAdd( $test_asc, "-----END PGP SIGNATURE-----" )

    # die Datei zum Verifizieren fertig gebaut:
    #-----BEGIN PGP SIGNED MESSAGE-----
    #Hash: MD5
    #
    #X-Signed-Headers: From,Newsgroups,Subject,Approved,Message-ID,Date
    #From: Klaus Fischer <chloriti@web.de>
    #Newsgroups: de.newusers.questions
    #Subject: Datum und Uhrzeit im Posting
    #Approved: contact-2008-17@dnqmail.priggish.de
    #Message-ID: <fvi5cj$fco$00$2@news.t-online.com>
    #Date: Sat, 03 May 2008 18:54:43 +0200
    #
    #Hallo,
    #
    #kann mir jemand erkl?n, wie ich es hinbekomme, da?sowohl das Datum
    #als auch die Uhrzeit in meinem Posting erscheint? Bei mir ist nur die
    #Uhrzeit zu sehen.
    #Ich benutze den Thunderbird.
    #
    #Gru?
    #
    #Klaus Fischer
    #
    #-----BEGIN PGP SIGNATURE-----
    #Version: 2.6.3ia
    #
    #iQCVAwUBSByZBuapsbxd5uZZAQEgLQP/UfH0izqyva3AIb/I80FcSa6quXuUglGJ
    #K2ph7ibQ1HCRNUMLQvTmQdowZJgysMGUgjh1wJSLRYePwqFOa/vaeXVt2Abx64Sm
    #+EEirClVfKFrPlC0x1nHPWN8Un1IIDU7Of8m8OUzONPAKDYo/VD/Q5mdJ5P6XCzp
    #3qKuJk+tSXI=
    #=jPEf
    #-----END PGP SIGNATURE-----

    # Jetzt verifizieren
    VerifyWithGnuPG_new # siehe Sub

    # Falls verifiziert ist Ergebnis ins HamsterLog schreiben
    if( $is_verified )
        print( $set_result )
    else
        $set_result = $pgp_tmp_signed + " konnte kein Ergebnis erzielen, Sorry"
        print( $set_result )
        $set_resultB64 = "=?utf-8?B?" + encodeBase64( $set_result ) + "?="
    endif

    ArtAddHeader( $art, "X-MyCheck-PGP:", $set_result )
    ArtAddHeader( $art, "X-PGP-Hash-Info:", $getAlgoFormHash_Info_str )
    ArtAddHeader( $art, "X-PGP-V:", $set_resultB64 )
    ArtSave( $art, ParamStr( ParamCount ) )

    # Listen freigeben
    ArtFree( $signed_posting_art )
    ListFree( $signed_posting_list )
    ListFree( $hash_list )
    ListFree( $test_asc )
    ListFree( $sig_list )
    ListFree( $body_list )
    ListFree( $result_list )
    ListFree( $status_list )


    # temporaere Dateien loeschen
    if( FileExists( $pgp_tmp_signed ) )
        FileDelete( $pgp_tmp_signed )     # zum testen auskommentiert
    endif
    if( FileExists( $pgp_tmp_log ) )
        FileDelete( $pgp_tmp_log )        # zum testen auskommentiert
    endif
    if( FileExists( $pgp_tmp_status ) )
        FileDelete( $pgp_tmp_status )     # zum testen auskommentiert
    endif
endif

endif

ArtFree( $art )

quit

sub VerifyWithGnuPGnew ListSave( $testasc, $pgptmpsigned )

  # GnuPG-Aufruf
  print( $PGP_Command + " " + $pgp_verify ) # nur zum testen

# Execute( $PGPCommand + „ “ + $pgpverify, „“, 0, true ) # ReturnCode fehlt! ORIGINAL

  $exec_return = Execute( $PGP_Command + " " + $pgp_verify, "", 0, true, $gpg_return ) # Tipp von Michael und alles wird gut! :-)
  print("Execute liefert $exec_return = " + $exec_return + " mit $gpg_return = " + $gpg_return) # zum testen auskommentiert
  # Ergebnis von $gpg_return = 0 --> korrekte Signatur
  # Ergebnis von $gpg_return = 1 --> FALSCHE oder unkorrekte Signatur

########### Original Michael

do # ***** <--- In dieser Schleife bleibt der Hamster "hängen"! Weil:

if( FileExists( $pgp_tmp_ready ) ) # ***** <--- Diese Datei wird in disem Script *nicht* erstellt!

print("Joo")

sleep(30)

break

endif

print("Nee")

sleep(10)

continue

loop # ***** <--- In dieser Schleife bleibt der Hamster "hängen"!

$gpg_returncode = read_gpg_returncode # siehe sub

########### Original Michael

$gpg_returncode = $gpg_return
print $gpg_returncode + " ******************************** $gpg_returncode **************"
if( $gpg_returncode == 0  ||  $gpg_returncode == 1 )
    $is_verified = true
    SetTheHeader_new
endif
print  $is_verified + " **** HIER BIN ICH! *** !HALLO! *** HIER GUCKEN! ****"

endsub

sub SetTheHeadernew # Das Log von GnuPG in Liste laden ListLoad( $resultlist, $pgptmplog )

  varset( $subi, 0 )
  var( $var1, $var2, $var3, $var4, $var5 )
  varset( $date_regexp, "(.+ )([0-1][0-9])\/([0-3][0-9])\/([0-9][0-9])( .+)" )
  # var                  `-1-?----2-----? `----3-----? `----4-----?-5-?
  # gpg: WARNING: digest algorithm MD5 is deprecated
  # gpg: please see http://www.gnupg.org/faq/weak-digest-algos.html for more information
  # gpg: WARNING: This key is not certified with a trusted signature!
  # gpg:          There is no indication that the signature belongs to the owner.
  varset( $dont_want_to_see, "WARNING: digest algorithm MD5 is deprecated|WARNUNG: Die Verwendung des Hashverfahrens MD5 ist nicht ratsam|Siehe http.* weitere Infos|please see http.+for more information|WARNING: This key is not certified with a trusted signature!|There is no indication that the signature belongs to the owner\." )
#X-MyCheck-PGP: Unterschrift vom So 28 Nov 2010 09:20:41 CET CET mittels RSA-Schlüssel ID 3D9A9243
#      Korrekte Unterschrift von "Peter Faust <peter.faust-solingen@t-online.de>"
#      WARNUNG: Dieser Schlüssel trägt keine vertrauenswürdige Signatur!
#               Es gibt keinen Hinweis, daß die Signatur wirklich dem vorgeblichen Besitzer gehört.
#      Haupt-Fingerabdruck  = 92EA F962 B322 8CCF A6B2  5F3E FD0C 3DC5 3D9A 9243

$dont_want_to_see = $dont_want_to_see + "|WARNUNG: Dieser Schlüssel trägt keine vertrauenswürdige Signatur!|Es gibt keinen Hinweis, dass die Signatur wirklich dem vorgeblichen Besitzer gehört\."


# GnuPG-Log durchlaufen
while( $subi < ListCount( $result_list ) )
    $line = ListGet( $result_list, $subi )
    $line = Replace( $line, "gpg: ", "", true, false )
    if( $subi == 0 )

# $isverified = true if( REMatch( $line, $dateregexp ) ) REParse( $line, $dateregexp, $var1, $var2, $var3, $var4, $var5 ) $line = $var1 + $var3 + „.“ + $var2 + „.20“ + $var4 + $var5 endif $setresult = $line

          $set_resultB64 = "=?utf-8?B?" + encodeBase64( charsetconvert( $line,  "iso-8859-1",  "utf-8" ) ) + "?="
      else
          if( ! RE_Match( $line , $dont_want_to_see ) )
              if( RE_Match( $line, "(\s{3}(alias|aka)|\s<[\S]+@[\S]+\.[\S]+>)" ) )   # Namenszeile ist schon utf-8 wg. gpg.conf
                  if( ! RE_Match( $line , $dont_want_to_see ) )
                      $set_result = $set_result + $CRLF + "      " + $line
                      $set_resultB64 = $set_resultB64 + " ->" + $CRLF + "      " + "=?utf-8?B?" + encodeBase64( $line ) + "?="
                  endif
              else
                  $set_result = $set_result + $CRLF + "      " + $line
                  $set_resultB64 = $set_resultB64 + " ->" + $CRLF + "      " + "=?utf-8?B?" + encodeBase64( charsetconvert( $line,  "iso-8859-1",  "utf-8" ) ) + "?="
              endif
          endif
      endif
      inc( $subi )
  endwhile

endsub

sub readgpgreturncode

  # Das Statusfile von GnuPG ($pgp_tmp_status) in Liste laden
  ListLoad( $status_list, $pgp_tmp_status )
  return( ListGet( $status_list, ListCount( $status_list )-1 ) )

endsub

sub readgpgstatusline( $linenr )

  return( ListGet( $status_list, $line_nr ) )

endsub

sub getAlgoFormHash( $lPGP )

  varset $i, 1
  varset $Signature, $line, ""
  varset $hash, "<not available>"
  while( $i < ListCount($lPGP) )
     $line = ListGet( $lPGP, $i )
     inc( $i )
     if ( Re_Match( $line, "^(Version|Comment|MessageID|Hash|Charset):\s" ) )
        continue()
     endif
     RE_Parse( $line, "(\S+)$", $line )
     $Signature = decodeBase64( $line )
     if ( $Signature <> "" )
        break()
     endif
  endwhile
  $i= 1
  varset $PacketTag, ord( copy( $Signature, $i, 1 ) )
  if( 0=($PacketTag & 0x80) )
     warning( "Fehler im Packet Tag" )
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "Fehler im Packet Tag: Hash kann nicht ermittelt werden"
     return $hash
  endif
  varset $headerLength, $packetLength, 0
  if( 0=($PacketTag & 0x40) )
     #Print( "Old packet format" )
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "Old packet format -> "
     $headerLength = ($PacketTag & 0x03)
     $headerLength = iCase( $headerLength, 0, 2,   1, 3,   2, 5,    else, 1 )
     $PacketTag = ($PacketTag & 0x3C) >> 2
  else
     #Print( "New packet format" )
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "New packet format -> "
     $packetLength = ord( copy( $Signature, $i+1, 1 ) )
     if $packetLength < 192
        $headerLength = 2
     elseif  $packetLength < 224
        $headerLength = 3
     elseif  $packetLength < 255
        $headerLength = 2
        warning( "Partial Body Length header is't supportet" )
     else
        $headerLength = 6
     endif
     $PacketTag = ($PacketTag & 0x3F)
  endif
  $i = $i + $headerLength
  if( $PacketTag = 2 )
     $PacketTag = ord( copy( $Signature, $i, 1 ) )
  else
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "Packet Tag Typ isn't supportet"
     warning( "Packet Tag Typ isn't supportet " )
     return $hash
  endif
  if( $PacketTag = 3 )
     #Print( "Version 3 Signature Packet Format" )
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "Version 3 Signature Packet Format -> "
     $PacketTag = ord( copy( $Signature, $i+16, 1 ) )
  elseif( $PacketTag = 4 )
     #Print( "Version 4 Signature Packet Format" )
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "Version 4 Signature Packet Format -> "
     $PacketTag = ord( copy( $Signature, $i+3, 1 ) )
  else
     $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + "Signature Packet Format isn't supportet"
     warning( "Signature Packet Format isn't supportet." )
     return $hash
  endif
  $hash = iCase( $PacketTag, 1, "MD5", 2, "SHA1", 3, "RIPEMD160", _
        4, "Reserved", 5, "Reserved", 6, "Reserved", 7, "Reserved", _
        8, "SHA256", 9, "SHA384", 10, "SHA512", 11, "SHA224", else, "Experimental" )
  $getAlgoFormHash_Info_str = $getAlgoFormHash_Info_str + $hash
  return $hash

endsub

ebenfalls in den automatischen Abläufen, diesmal jedoch beim Feld „Eingehend (NNTP)“ eingetragen: http://hamster-classic.de/_media/playground:headersignierung:hamsterautoverify.png

Fertig.

Beim nächsten laden von neuen Newsbeiträgen wird der Hamster die Header überprüfen und ein paar zusätzliche Header in die Beiträge schreiben. Diese kann man sich dann mit einem passenden Newsreader anzeigen lassen.

Als Beispiel soll hier Thunderbird genannt werden, der mit der Erweiterung Mnenhy genau das (und noch mehr) leistet. Weiter sind Claws Mail und Gnus/Emacs (jeweils für Windows) zu nennen, die es leicht machen diese Header anzuzeigen.

Wenn alle geforderten Einträge korrekt gemacht wurden, dann sollte der Hamster ab sofort jeden an ihn geschickten Beitrag mit signierten Headern ins weltweite Nutznetz verschicken und jeden empfangenen signierten Beitrag mit den Headern versehen: X-MyCheck-PGP: X-PGP-Hash-Info: X-PGP-V: Diese kann man sich dann in den oben genannten Newsreadern anzeigen lassen.

Bei Problemen, Fragen oder sonstigen Hinweisen sollte die Gruppe hamster.de.misc genutzt werden.

Erfolgreich getestet wurden alle Scripte von mir auf mehreren Computern mit Windows XP Prof. und Windows Vista Business. Allerdings haben weitere Nutzer mit Windows 7, 8, 8.1 und 10 ebenfalls keine Probleme gemeldet.

Abschließend sei noch mal eindringlich zu einem gewissenhaften editieren der persönlichen Eintragungen geraten! In den Scripten befinden sich meine persönlichen PGP-Keys, die natürlich angepasst werden müssen: Mit meinen Keys kann schließlich nur ich signieren. ;-)

In diesem Sinne: Viel Spaß beim signieren und verifizieren von Headern!