home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / ftp.vapor.com / microdot-1 / md1_src_02.lzx / pgp.c < prev    next >
C/C++ Source or Header  |  2014-05-19  |  27KB  |  895 lines

  1. /*
  2.  *  MicroDot PGP Interface
  3.  */
  4.  
  5. #include "microdot.h"
  6. #include "ogre.h"
  7. #include "ogre_protos.h"
  8.  
  9. #include "asyncio.h"
  10.  
  11. #include <dos/dostags.h>
  12.  
  13. static char *passphrase;
  14. static ULONG passphrasesize;
  15.  
  16. static UBYTE *mykey;
  17. static ULONG mykeysize;
  18.  
  19. int pgpavail;
  20.  
  21. static char pgppath[á128 ];
  22. static char pgpcmdpath[ 256 ];
  23.  
  24. #define PGPWARN "PGP-`Pass phrase' setzen.\n\n\
  25. WARNUNG! Diese Option setzt das Passwort,\n\
  26. mit dem PGP Ihre Keyrings schⁿtzt!\n\
  27. Verwenden Sie diese Option nicht, ohne sich\n\
  28. vorher in der Anleitung von MicroDot ⁿber die\n\
  29. Implikationen informiert zu haben."
  30.  
  31. #define CODE(c) ((int)sextet[((c) & 077)])
  32. #define FUELL   '='
  33.  
  34. void pgp_addb64hl( struct hlist *hl, char *header, UBYTE *data, int size  )
  35. {
  36.         char buffer[ 8192 ];
  37.         static char sextet[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  38.                         "abcdefghijklmnopqrstuvwxyz"
  39.                         "0123456789+/";
  40.         int count = size, cnt;
  41.         UBYTE buf[ 4 ], *bp = data, *to = buffer;
  42.         int a, b, c, d;
  43.  
  44.         while( count )
  45.         {
  46.                 memset(buf, 0, 3);
  47.                 /*
  48.                  *  3 Byte einlesen:
  49.                  */
  50.         
  51.                 cnt = min( count, 3 );
  52.                 count -= cnt;
  53.                 memcpy( buf, bp, cnt );
  54.                 bp += cnt;
  55.  
  56.                 /*
  57.                  *  und als 4 sextets ausgeben
  58.                  */
  59.                 a = buf[0] >> 2;
  60.                 b = ((buf[0] << 4) & 060)   | ((buf[1] >> 4) & 017);
  61.                 c = ((buf[1] << 2) & 074) | ((buf[2] >> 6) & 03);
  62.                 d = buf[2] & 077;
  63.                 *to++ = CODE( a );
  64.                 *to++ = CODE( b );
  65.                 if (cnt == 1)   {
  66.                         *to++ = FUELL;
  67.                         *to++ = FUELL;
  68.                 } else {
  69.                         *to++ = CODE( c );
  70.                         if (cnt == 2)
  71.                                 *to++ = FUELL;
  72.                         else
  73.                                 *to++ = CODE( d );
  74.                 }
  75.         }
  76.         *to = 0;
  77.         hl_addheader( hl, header, buffer );
  78. }
  79.  
  80. void pgp_addb64hlfile( struct hlist *hl, char *header, char *filename )
  81. {
  82.         BPTR f;
  83.         int len = getfilelen( filename );
  84.         APTR mem;
  85.  
  86.         if( len < 1 )
  87.                 return;
  88.  
  89.         mem = myAllocVec( len, MEMF_ANY );
  90.         if( !mem )
  91.                 return;
  92.  
  93.         f = Open( filename, MODE_OLDFILE );
  94.         Read( f, mem, len );
  95.         Close( f );
  96.  
  97.         pgp_addb64hl( hl, header, mem, len );
  98.  
  99.         myFreeVec( mem );
  100.  
  101. }
  102.  
  103. void pgp_addpubkey( struct hlist *hl )
  104. {
  105.         char buffer[á512 ];
  106.  
  107.         if( prefs.mode == MDM_RFC )
  108.             sprintf( buffer, "%s <%s@%s%s>",
  109.                 prefs.userrealname,
  110.                 prefs.username,
  111.                 prefs.pointname,
  112.                 prefs.boxdomain
  113.             );
  114.  
  115.         else
  116.             sprintf( buffer, "%s <%s@%s%s>",
  117.                 prefs.userrealname,
  118.                 prefs.username,
  119.                 prefs.boxname,
  120.                 prefs.boxdomain
  121.             );
  122.  
  123.         if( stricmp( buffer, prefs.pgp_userid ) )
  124.                 hl_addheader( hl, "PGP-ID", prefs.pgp_userid );
  125.  
  126.         pgp_addb64hl( hl, "PGP-PUBLIC-KEY", mykey, mykeysize );
  127. }
  128.  
  129.  
  130. void pgp_setpassphrase( void )
  131. {
  132.         char *tempbuff = myAllocVec( 4096, 0 );
  133.         ULONG pcrc;
  134.  
  135.         if( !tempbuff )
  136.         {
  137.                 displaybeep();
  138.                 return;
  139.         }
  140.  
  141.         if( GetVar( "PGPPASS", tempbuff, 127, 0 ) > 0 )
  142.         {
  143.             FreeVec( tempbuff );
  144.             return;
  145.         }
  146.  
  147. redo:
  148.         tempbuff[á0 ]á= 0;
  149.         switch( rtGetString( tempbuff, 4095, NULL, rinfo,
  150.                 RTGS_Invisible, TRUE,
  151.                 RTGS_TextFmt, PGPWARN,
  152.                 RTGS_GadFmt, "OK|Hilfe|Abbruch",
  153.                 TAG_DONE ) )
  154.         {
  155.                 case 1:
  156.                         if( passphrase )
  157.                                 LibFreePooled( miscmempool, passphrase, passphrasesize );
  158.                         passphrasesize = strlen( tempbuff ) + 1;
  159.                         passphrase = NULL;
  160.                         if( passphrasesize < 2 )
  161.                         {
  162.                                 askreq( "PGP 'Pass phrase' gel÷scht.", "Weiter" );
  163.                                 myFreeVec( tempbuff );
  164.                                 return;
  165.                         }
  166.  
  167.                         pcrc = crc32( tempbuff, strlen( tempbuff ) );
  168.                         if( prefs.pgp_lastpassphrase && ( pcrc != prefs.pgp_lastpassphrase ) )
  169.                         {
  170.                             if( askreq( "Die eingegebene Passphrase stimmt nicht mit der\nⁿberein, die Sie zuletzt an dieser Stelle eingegeben haben.",
  171.                                 "Nochmal eingeben|Trotzdem benutzen"
  172.                             )) goto redo;
  173.                         }
  174.  
  175.                         passphrase = LibAllocPooled( miscmempool, passphrasesize );
  176.                         if( !passphrase )
  177.                         {
  178.                                 displaybeep();
  179.                                 myFreeVec( tempbuff );
  180.                                 return;
  181.                         }
  182.                         strcpy( passphrase, tempbuff );
  183.                         prefs.pgp_lastpassphrase = pcrc;
  184.                         myFreeVec( tempbuff );
  185.                         break;
  186.  
  187.                 case 2:
  188.                         showguide( "pgp_setpassphrase" );
  189.                         goto redo;
  190.         }
  191. }
  192.  
  193. int runpgp( char *cmd, int pp, int flags )
  194. {
  195.         char tmp[á256 ];
  196.         BPTR outwin, oldcd, pgpcd, outwin2 = NULL;
  197.         int rc;
  198.         char *textmode = ( flags & 16 ) ? "on" : "off";
  199.         char *armor = ( flags & 8 ) ? "on" : "off";
  200.  
  201.         if( pp && !passphrase && prefs.pgp_autoaskpp )
  202.                 pgp_setpassphrase();
  203.  
  204.         /* Kein Quiet, falls Passphrase per PGP eingegeben werden mu▀ */
  205.         if( pp && !passphrase )
  206.                 flags &= ~2;
  207.  
  208.         if( ! ( flags & 2 ) )
  209.         {
  210.                 strcpy( tmp, prefs.pgp_win );
  211.                 if( flags & 1 )
  212.                         strcat( tmp, "/WAIT/CLOSE" );
  213.                 outwin = OpenCon( tmp );
  214.                 if( !outwin )
  215.                 {
  216.                         displaybeep();
  217.                         return( -2 );
  218.                 }
  219.         }
  220.         else
  221.         {
  222.                 outwin = Open( "NIL:", MODE_OLDFILE );
  223.                 outwin2 = Open( "NIL:", MODE_OLDFILE );
  224.         }
  225.  
  226.         pgpcd = Lock( pgppath, SHARED_LOCK );
  227.         if( !pgpcd )
  228.         {
  229.                 displaybeep();
  230.                 Close( outwin );
  231.                 return( -3 );
  232.         }
  233.  
  234.         oldcd = CurrentDir( pgpcd );
  235.  
  236.         if( !pp )
  237.                 sprintf( tmp, "\"%s\" +armor=%s +textmode=%s %s%s", pgpcmdpath, armor, textmode, ( flags & 4 ) ? "" : "+batchmode +force ", cmd );
  238.         else if( pp && !passphrase )
  239.                 sprintf( tmp, "\"%s\" +armor=%s +textmode=%s %s", pgpcmdpath, armor, textmode, cmd );
  240.         else
  241.                 sprintf( tmp, "\"%s\" +armor=%s +textmode=%s %s\"-z%s\" %s",
  242.                         pgpcmdpath,
  243.                         armor, textmode,
  244.                         pp != 2 ? "+batchmode " : "",
  245.                         passphrase,
  246.                         cmd
  247.                 );
  248.  
  249.         if( flags & 1 )
  250.             FPrintf( outwin, "╖\x08" );
  251.  
  252.         //FPrintf( outwin, "EXEC: '%s'\n", tmp );
  253.  
  254.         rc = SystemTags( tmp,
  255.                 NP_StackSize, 10240,
  256.                 SYS_Input, outwin,
  257.                 SYS_Output, outwin2,
  258.                 TAG_DONE
  259.         );
  260.  
  261.         if( flags & 1 )
  262.         {
  263.             FPrintf( outwin, "\n\nPGP-Aufruf abgeschlossen (rc %ld).\nBitte dieses Fenster per CLOSE-Gadget oder CTRL-\\ schlie▀en.", rc );
  264.         }
  265.  
  266.         Close( outwin );
  267.         if( outwin2 )
  268.             Close( outwin2 );
  269.  
  270.         UnLock( CurrentDir( oldcd ) );
  271.  
  272.         return( rc );
  273. }
  274.  
  275.  
  276. static char *krentries[] = { "Nie", "Immer", "Nachfragen", NULL };
  277.  
  278. #define PP_OK 1
  279. #define PP_CANCEL 2
  280. #define PP_UID 3
  281. #define PP_AVAIL 4
  282. #define PP_KEYREQ 5
  283. #define PP_EB 6
  284. #define PP_WIN 7
  285. #define PP_AUTOASKPP 8
  286. #define PP_RING1 9
  287. #define PP_RING2 10
  288.  
  289. void pgp_prefs( void )
  290. {
  291.         struct ogwin *ogw;
  292.         struct Window *iw;
  293.         struct IntuiMessage *im;
  294.         int Done = FALSE;
  295.  
  296.         ogw = ogreInitWindow( scr, 0, 0, "PGP-Voreinstellungen" );
  297.  
  298.         ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Info " );
  299.         ogreAddString( ogw, 0, 'u', "Eigene _UserID:", PP_UID, prefs.pgp_userid, 40, 256 );
  300.         ogreAddString( ogw, 1, 'i', "PGP-KEY-AVAIL:-_Info", PP_AVAIL, prefs.pgp_avail, 40, 128 );
  301.  
  302.         ogreAddGroup( ogw, 1, OGFRAME_OUTLINE, " Optionen " );
  303.         ogreAddCheckbox( ogw, 0, 'p', "`_Pass phrase' automatisch erfragen:", PP_AUTOASKPP, prefs.pgp_autoaskpp );
  304.         ogreAddCheckbox( ogw, 1, 'e', "Eigenen Key bei _EmpfangsbestΣtigungen mitschicken:", PP_EB, prefs.pgp_sendoneb );
  305.         ogreAddCycle( ogw, 2, 'r', "Key-_Requests beantworten:", PP_KEYREQ, krentries, 12, prefs.pgp_request );
  306.  
  307.         ogreAddGroup( ogw, 2, OGFRAME_OUTLINE, " Sonstiges " );
  308.         ogreAddString( ogw, 0, 'f', "_Fenster fⁿr PGP-Aufruf:", PP_WIN, prefs.pgp_win, 40, 128 );
  309.         ogreAddString( ogw, 1, 0, "Keyring:", PP_RING1, prefs.pgp_ring1, 40, 128 );
  310.         //ogreAddString( ogw, 2, 0, "SekundΣrer Keyring:", PP_RING2, prefs.pgp_ring2, 40, 128 );
  311.  
  312.         ogreAddGroup( ogw, 3, OGFRAME_NONE, NULL );
  313.         ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", PP_OK );
  314.         ogreAddHelp( ogw, 0 );
  315.         ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", PP_CANCEL );
  316.  
  317.         iw = ogreOpenWindow( ogw );
  318.         if( !iw )
  319.             return;
  320.  
  321.         while( !Done )
  322.         {
  323.                 im = ogreWaitIM( ogw );
  324.  
  325.                 if( im->Class == IDCMP_GADGETHELP)
  326.                         showguidenum( "pgp_prefsgads", im->Code );
  327.                 else if( im->Class == IDCMP_GADGETUP )
  328.                 {
  329.                         switch( im->Code )
  330.                         {
  331.                                 case PP_OK:
  332.                                         Done = 2;
  333.                                         break;
  334.  
  335.                                 case PP_CANCEL:
  336.                                         Done = 1;
  337.                                         break;
  338.                         }
  339.                 }
  340.                 ogreIMReply( ogw, im );
  341.         }
  342.  
  343.         if( Done == 2 )
  344.         {
  345.                 ogreCopyStringValue( ogw, PP_UID, prefs.pgp_userid );
  346.                 ogreCopyStringValue( ogw, PP_AVAIL, prefs.pgp_avail );
  347.                 ogreCopyStringValue( ogw, PP_WIN, prefs.pgp_win );
  348.                 ogreCopyStringValue( ogw, PP_RING1, prefs.pgp_ring1 );
  349.                 // ogreCopyStringValue( ogw, PP_RING2, prefs.pgp_ring2 );
  350.                 prefs.pgp_sendoneb = ogreValue( ogw, PP_EB );
  351.                 prefs.pgp_request = ogreValue( ogw, PP_KEYREQ );
  352.                 prefs.pgp_autoaskpp = ogreValue( ogw, PP_AUTOASKPP );
  353.         }
  354.  
  355.         ogreExitWindow( ogw );
  356. }
  357.  
  358. int getpubkey( char *userid, char *toname )
  359. {
  360.         char tmp[á128 ];
  361.         int rc;
  362.  
  363.         DeleteFile( toname );
  364.  
  365.         /* Ersten Ring versuchen */
  366.         sprintf( tmp, "-kx \"%s\" %s \"%s\"",
  367.                 userid,
  368.                 toname,
  369.                 prefs.pgp_ring1 );
  370.  
  371.         rc = runpgp( tmp, 0, 2 );
  372.  
  373.         if( rc && prefs.pgp_ring2[á0 ] )
  374.         {
  375.                 /* Zweiten Ring versuchen */
  376.                 sprintf( tmp, "-kx \"%s\" %s \"%s\"",
  377.                         userid,
  378.                         toname,
  379.                         prefs.pgp_ring2 );
  380.  
  381.                 rc = runpgp( tmp, 0, 2 );
  382.                 if( !rc && ( getfilelen( toname ) > 0 ) )
  383.                         return( 2 );
  384.         }
  385.  
  386.         if( !rc && ( getfilelen( toname ) > 0 ) )
  387.                 return( 1 );
  388.         else
  389.                 return( 0 );
  390.  
  391. }
  392.  
  393. static int readmykey( char *filename )
  394. {
  395.         BPTR f;
  396.  
  397.         mykeysize = getfilelen( filename );
  398.         if( mykeysize < 1 )
  399.                 return( -1 );
  400.         mykey = LibAllocPooled( miscmempool, mykeysize );
  401.         if( !mykey )
  402.                 return( -2 );
  403.  
  404.         f = Open( filename, MODE_OLDFILE );
  405.         if( !f )
  406.                 return( -3 );
  407.  
  408.         Read( f, mykey, mykeysize );
  409.         Close( f );
  410.  
  411.         return( 0 );
  412. }
  413.  
  414.  
  415. void pgp_init( void )
  416. {
  417.         char tmp[ 256 ];
  418.         BPTR f;
  419.  
  420.         if( GetVar( "PGPPath", pgppath, 128, 0 ) < 1 )
  421.                 return;
  422.  
  423.         if( !checkprograminpathfull( "PGP", pgpcmdpath ) )
  424.         {
  425.                 strcpy( tmp, pgppath );
  426.                 AddPart( tmp, "PGP", 256 );
  427.                 if( getfilelen( tmp ) < 1 )
  428.                         return;
  429.                 strcpy( pgpcmdpath, tmp );
  430.         }
  431.  
  432.         pgpavail = TRUE;
  433.  
  434.         /* Userid? */
  435.         if( !prefs.pgp_userid[á0 ]á)
  436.         {
  437.                 if( prefs.mode == MDM_RFC )
  438.                     sprintf( prefs.pgp_userid, "%s <%s@%s%s>",
  439.                         prefs.userrealname,
  440.                         prefs.username,
  441.                         prefs.pointname,
  442.                         prefs.boxdomain
  443.                     );
  444.                 else
  445.                     sprintf( prefs.pgp_userid, "%s <%s@%s%s>",
  446.                         prefs.userrealname,
  447.                         prefs.username,
  448.                         prefs.boxname,
  449.                         prefs.boxdomain
  450.                     );
  451.         }
  452.  
  453.         if( !prefs.pgp_win[á0 ]á)
  454.                 strcpy( prefs.pgp_win, "CON://1024/1024/MicroDot-PGP-Shell/AUTO" );
  455.  
  456.         if( !prefs.pgp_ring1[á0 ]á)
  457.                 strcpy( prefs.pgp_ring1, "pubring.pgp" );
  458.  
  459.         prefs.pgp_ring2[á0 ]á= 0;
  460.  
  461.         /* Gut. Eigenen Public-Key einlesen */
  462.         pushhomedir();
  463.         if( !readmykey( "microdot.pgpkey" ) )
  464.         {
  465.                 popdir();
  466.                 return;
  467.         }
  468.         popdir();
  469.  
  470. retry:
  471.         if( !getpubkey( prefs.pgp_userid, "T:mdpgpkey.pgp" ) )
  472.         {
  473. reask:
  474.                 switch( askreq( "Ihr eigener Public-Key unter der UserID\n\"%s\"\nwurde nicht gefunden. Wollen Sie jetzt\nein Key-Paar generieren?",
  475.                                 "Keys generieren|PGP-Voreinstellungen|Hilfe|Abbruch",
  476.                                 prefs.pgp_userid ) )
  477.                 {
  478.                         case 0:
  479.                                 pgpavail = 0;
  480.                                 return;
  481.  
  482.                         case 1:
  483.                                 if( !runpgp( "-kg", 0, 5 ) )
  484.                                 {
  485.                                         sprintf( tmp, "-ks \"%s\"", prefs.pgp_userid );
  486.                                         runpgp( tmp, 1, 5 );
  487.                                 }
  488.                                 goto retry;
  489.                                 break;
  490.  
  491.                         case 2:
  492.                                 pgp_prefs();
  493.                                 goto retry;
  494.  
  495.                         case 3:
  496.                                 showguide( "pgp_genkeys" );
  497.                                 goto reask;
  498.                 }
  499.         }
  500.  
  501.         readmykey( "T:mdpgpkey.pgp" );
  502.         pushhomedir();
  503.         f = Open( "microdot.pgpkey", MODE_NEWFILE );
  504.         if( f )
  505.         {
  506.                 Write( f, mykey, mykeysize );
  507.                 Close( f );
  508.         }
  509.         popdir();
  510.  
  511.         DeleteFile( "T:mdpgpkey.pgp" );
  512.  
  513. }
  514.  
  515. #define IGID_LV 1
  516. #define IGID_OK 2
  517. #define IGID_CANCEL 3
  518.  
  519. #define IGID_DEL 4
  520. #define IGID_ADD1 5
  521. #define IGID_ADD2 6
  522. #define IGID_VIEW 7
  523. #define IGID_ALL 8
  524.  
  525. struct keymem {
  526.         char *userid;
  527.         UBYTE *key;
  528.         ULONG keysize;
  529.         char label[á128 ];
  530. };
  531.  
  532. static void doviewfingerprint( struct keymem *km )
  533. {
  534.         char exec[á128 ], tmpkey[ 64 ], tmpring[ 64 ];
  535.         BPTR f;
  536.  
  537.         sprintf( tmpkey, "T:mdkeytmp%lx.pgp", time( 0 ) );
  538.         sprintf( tmpring, "T:mdringtmp%lx.pgp", time( 0 ) );
  539.  
  540.         f = Open( tmpkey, MODE_NEWFILE );
  541.         if( !f )
  542.         {
  543.                 displaybeep();
  544.                 return;
  545.         }
  546.         Write( f, km->key, km->keysize );
  547.         Close( f );
  548.  
  549.         sprintf( exec, "-ka %s %s", tmpkey, tmpring );
  550.         runpgp( exec, 0, 2 );
  551.         sprintf( exec, "-kvc \"%s\" %s", km->userid, tmpring );
  552.         runpgp( exec, 0, 1 );
  553.  
  554.  
  555.         // Tempfiles l÷schen
  556.  
  557.         DeleteFile( tmpring );
  558.         strcpy( strchr( tmpring, '.' ), ".bak" );
  559.         DeleteFile( tmpring );
  560.         DeleteFile( tmpkey );
  561. }
  562.  
  563. #if 0
  564. static void doaddkey( struct keymem *km, int keyring )
  565. {
  566.         char exec[á128 ], tmpkey[ 64 ];
  567.         BPTR f;
  568.  
  569.         sprintf( tmpkey, "T:mdkeytmp%lx.pgp", time( 0 ) );
  570.  
  571.         f = Open( tmpkey, MODE_NEWFILE );
  572.         if( !f )
  573.         {
  574.                 displaybeep();
  575.                 return;
  576.         }
  577.         Write( f, km->key, km->keysize );
  578.         Close( f );
  579.  
  580.         sprintf( exec, "-ka %s \"%s\"", tmpkey, keyring ? prefs.pgp_ring2 : prefs.pgp_ring1 );
  581.         runpgp( exec, 0, 0 );
  582.  
  583.         // Tempfiles l÷schen
  584.  
  585.         DeleteFile( tmpkey );
  586. }
  587. #endif
  588.  
  589. void pgp_procincoming( void )
  590. {
  591.         struct ogwin *ogw;
  592.         struct Window *iw;
  593.         struct IntuiMessage *im;
  594.         int Done = FALSE;
  595.         struct ogrevn *vn;
  596.         struct AsyncFile *f;
  597.         ULONG lm, olm;
  598.         struct keymem *keymem;
  599.         APTR keypool;
  600.         int isediting = -1, keyring = 0;
  601.         int c;
  602.  
  603.         pushhomedir();
  604.         f = OpenAsync( "microdot.new_pgpkeys", MODE_READ, 4096 );
  605.         popdir();
  606.         if( !f )
  607.         {
  608.                 askreq( "Keine eingegangenen Keys.", "Weiter" );
  609.                 return;
  610.         }
  611.  
  612.         keypool = LibCreatePool( 0, 4096, 2048 );
  613.  
  614.         ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, "Eingegangene PGP-Keys verwalten:" );
  615.         ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
  616.         ogreAddList( ogw, 0, 0xff, NULL, IGID_LV, 60, 12, TRUE, NULL );
  617.         ogreLVInit( ogw, IGID_LV );
  618.  
  619. #define MDKID 0x4d44504b
  620.  
  621.         for(;;)
  622.         {
  623.                 keymem = LibAllocPooled( keypool, sizeof( *keymem ) );
  624.                 if( !keymem )
  625.                         break;
  626.                 if( ReadAsync( f, &olm, 4 ) != 4 )
  627.                         break;
  628.                 if( olm != MDKID )
  629.                 {
  630.                         askreq( "Fehler in der Datei \"microdot.new_pgpkeys\":\nFalsche ID %lx", "Abbruch", olm );
  631.                         break;
  632.                 }
  633.                 if( ReadAsync( f, &lm, 4 ) != 4 )
  634.                         break;
  635.                 keymem->userid = LibAllocPooled( keypool, lm + 1 );
  636.                 if( !keymem->userid )
  637.                         break;
  638.                 ReadAsync( f, keymem->userid, lm + 1 );
  639.                 if( ReadAsync( f, &lm, 4 ) != 4 )       /* CRC */
  640.                         break;
  641.                 if( ReadAsync( f, &lm, 4 ) != 4 )
  642.                         break;
  643.                 keymem->key = LibAllocPooled( keypool, keymem->keysize = lm );
  644.                 ReadAsync( f, keymem->key, lm );
  645.                 if( ReadAsync( f, &lm, 4 ) != 4 )       /* CRC */
  646.                         break;
  647.  
  648.                 sprintf( keymem->label, "%s: %s", olm == MDKID ? "KEY" : "SIG", keymem->userid );
  649.  
  650.                 if( ogreLVFindEntry( ogw, IGID_LV, keymem->label ) )
  651.                 {
  652.                         struct ogrevn *vn;
  653.  
  654.                         for( c = 0; ; c++ )
  655.                         {
  656.                                 vn = ogreLVGetEntry( ogw, IGID_LV, c );
  657.                                 if( !vn )
  658.                                         break;
  659.                                 if( !stricmp( ( ( struct keymem * ) vn->userdata ) -> label, keymem->label ) )
  660.                                 {
  661.                                         Remove( ( struct Node * ) vn );
  662.                                         break;
  663.                                 }
  664.                         }
  665.                 }
  666.  
  667.                 ogreLVAddEntry( ogw, IGID_LV, keymem->label, 0, keymem );
  668.         }
  669.         CloseAsync( f );
  670.  
  671.         ogreAddButton( ogw, 1, 'a', "_Alle", IGID_ALL );
  672.         ogreAddButton( ogw, 1, 'l', "_L÷schen", IGID_DEL );
  673.         ogreAddButton( ogw, 1, '1', "-> Keyring _1", IGID_ADD1 );
  674.         if( prefs.pgp_ring2[á0 ]á)
  675.                 ogreAddButton( ogw, 1, '2', "-> Keyring _2", IGID_ADD2 );
  676.         ogreAddButton( ogw, 1, 'f', "_Fingerprint anzeigen", IGID_VIEW );
  677.  
  678.         ogreAddButton( ogw, 2 | OGB_ONENTER, '@', "OK", IGID_OK );
  679.         ogreAddHelp( ogw, 2 );
  680.         ogreAddButton( ogw, 2 | OGB_ONESC, '\x1b', "Abbruch", IGID_CANCEL );
  681.  
  682.         iw = ogreOpenWindow( ogw );
  683.         if( !iw )
  684.         {
  685.                 LibDeletePool( keypool );
  686.                 return;
  687.         }
  688.  
  689.         while( !Done )
  690.         {
  691.                 ogreEnable( ogw, isediting >= 0, IGID_DEL, IGID_ADD1, IGID_ADD2, IGID_VIEW, 0 );
  692.                 ogreEnable( ogw, ogreLVGetNumEntries( ogw, IGID_LV ), IGID_ALL, 0 );
  693.  
  694.                 im = ogreWaitIM( ogw );
  695.                 if( im->Class == IDCMP_GADGETHELP)
  696.                         showguidenum( "pgpkeywin_gads", im->Code );
  697.                 else if( im->Class == IDCMP_GADGETUP )
  698.                 {
  699.                         switch( im->Code )
  700.                         {
  701.                                 case IGID_LV:
  702.                                         isediting = ogreValue( ogw, IGID_LV );
  703.                                         break;
  704.  
  705.                                 case IGID_OK:
  706.                                         Done = 2;
  707.                                         break;
  708.  
  709.                                 case IGID_CANCEL:
  710.                                         Done = 1;
  711.                                         break;
  712.  
  713.                                 case IGID_ALL:
  714.                                         for( c = 0; ; c++ )
  715.                                         {
  716.                                             struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, c );
  717.                                             if( !vn )
  718.                                                 break;
  719.                                             ogreLVSelect( ogw, IGID_LV, c );
  720.                                             isediting = 0;
  721.                                         }
  722.                                         ogreLVRefresh( ogw, IGID_LV );
  723.                                         break;
  724.  
  725.                                 case IGID_DEL:
  726.                                         if( isediting >= 0 )
  727.                                         {
  728.                                                 struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, 0 ), *next;
  729.  
  730.                                                 while( next = ( struct ogrevn * ) vn->n.mln_Succ )
  731.                                                 {
  732.                                                     if( vn->sel )
  733.                                                         Remove( vn );
  734.                                                     vn = next;
  735.                                                 }
  736.                                                 ogreLVRefresh( ogw, IGID_LV );
  737.                                                 isediting = -1;
  738.                                         }
  739.                                         break;
  740.  
  741.                                 case IGID_ADD2:
  742.                                         keyring = 1;
  743.  
  744.                                 case IGID_ADD1:
  745.                                         if( isediting >= 0 )
  746.                                         {
  747.                                                 struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, 0 ), *next;
  748.                                                 char exec[á128 ], tmpkey[ 64 ];
  749.                                                 BPTR f;
  750.  
  751.                                                 sprintf( tmpkey, "T:mdkeytmp%lx.pgp", time( 0 ) );
  752.  
  753.                                                 f = Open( tmpkey, MODE_NEWFILE );
  754.  
  755.                                                 if( !f )
  756.                                                 {
  757.                                                     displaybeep();
  758.                                                     break;
  759.                                                 }
  760.  
  761.                                                 while( next = ( struct ogrevn * ) vn->n.mln_Succ )
  762.                                                 {
  763.                                                     if( vn->sel )
  764.                                                     {
  765.                                                         struct keymem *km = vn->userdata;
  766.  
  767.                                                         Write( f, km->key, km->keysize );
  768.                                                         Remove( vn );
  769.                                                     }
  770.                                                     vn = next;
  771.                                                 }
  772.  
  773.                                                 Close( f );
  774.  
  775.                                                 sprintf( exec, "-ka %s \"%s\"", tmpkey, keyring ? prefs.pgp_ring2 : prefs.pgp_ring1 );
  776.                                                 runpgp( exec, 0, 0 );
  777.  
  778.                                                 // Tempfiles l÷schen
  779.  
  780.                                                 DeleteFile( tmpkey );
  781.  
  782.                                                 ogreLVRefresh( ogw, IGID_LV );
  783.                                                 isediting = -1;
  784.                                         }
  785.                                         keyring = 0;
  786.                                         break;
  787.  
  788.                                 case IGID_VIEW:
  789.                                         if( isediting >= 0 )
  790.                                         {
  791.                                                 struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, 0 ), *next;
  792.  
  793.                                                 while( next = ( struct ogrevn * ) vn->n.mln_Succ )
  794.                                                 {
  795.                                                     if( vn->sel )
  796.                                                     {
  797.                                                         doviewfingerprint( vn->userdata );
  798.                                                         vn->sel = FALSE;
  799.                                                     }
  800.                                                     vn = next;
  801.                                                 }
  802.                                                 ogreLVRefresh( ogw, IGID_LV );
  803.                                                 isediting = -1;
  804.                                         }
  805.                                         break;
  806.                         }
  807.                 }
  808.                 ogreIMReply( ogw, im );
  809.         }
  810.  
  811.         if( Done == 2 )
  812.         {
  813.                 struct ogrevn *vn;
  814.                 struct keymem *km;
  815.  
  816.                 pushhomedir();
  817.                 DeleteFile( "microdot.new_pgpkeys.bak" );
  818.                 Rename( "microdot.new_pgpkeys", "microdot.new_pgpkeys.bak" );
  819.                 f = OpenAsync( "microdot.new_pgpkeys", MODE_WRITE, 4096 );
  820.                 if( f )
  821.                 {
  822.                         /* ▄brige Keys wieder abspeichern */
  823.                         for( c = 0; ; c++ )
  824.                         {
  825.                                 vn = ogreLVGetEntry( ogw, IGID_LV, c );
  826.                                 if( !vn )
  827.                                         break;
  828.                                 km = vn->userdata;
  829.  
  830.                                 lm = MDKID;
  831.                                 WriteAsync( f, &lm, 4 );
  832.                                 lm = strlen( km->userid );
  833.                                 WriteAsync( f, &lm, 4 );
  834.                                 WriteAsync( f, km->userid, lm + 1 );
  835.                                 WriteAsync( f, &lm, 4 );        /* Dummy */
  836.                                 WriteAsync( f, &km->keysize, 4 );
  837.                                 WriteAsync( f, km->key, km->keysize );
  838.                                 WriteAsync( f, &lm, 4 );        /* Dummy */
  839.                         }
  840.                         CloseAsync( f );
  841.                 }
  842.                 if( !c )
  843.                         DeleteFile( "microdot.new_pgpkeys" );
  844.                 popdir();
  845.         }
  846.  
  847.         ogreExitWindow( ogw );
  848.         LibDeletePool( keypool );
  849. }
  850.  
  851. void pgp_showkeys( int verbose )
  852. {
  853.         char exec[á64 ];
  854.  
  855.         sprintf( exec, "-kv%s %s", verbose ? "v" : "", prefs.pgp_ring1 );
  856.         runpgp( exec, 0, 1 );
  857.  
  858.         if( prefs.pgp_ring2[á0 ]á)
  859.         {
  860.                 sprintf( exec, "-kv%s %s",  verbose ? "v" : "", prefs.pgp_ring2 );
  861.                 runpgp( exec, 0, 1 );
  862.         }
  863. }
  864.  
  865. void pgp_checkkeys( void )
  866. {
  867.         char exec[á64 ];
  868.  
  869.         sprintf( exec, "-kc %s", prefs.pgp_ring1 );
  870.         runpgp( exec, 0, 1 );
  871.  
  872.         if( prefs.pgp_ring2[á0 ]á)
  873.         {
  874.                 sprintf( exec, "-kc %s", prefs.pgp_ring2 );
  875.                 runpgp( exec, 0, 1 );
  876.         }
  877. }
  878.  
  879. void pgp_changepassphrase( void )
  880. {
  881.         char tmp[ 256 ];
  882.  
  883.         sprintf( tmp, "-ke \"%s\"", prefs.pgp_userid );
  884.  
  885.         runpgp( tmp, 2, 0 );
  886. }
  887.  
  888. void pgp_rereadownkey( void )
  889. {
  890.     pushhomedir();
  891.     DeleteFile( "microdot.pgpkey" );
  892.     popdir();
  893.     pgp_init();
  894. }
  895.