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 >
Wrap
C/C++ Source or Header
|
2014-05-19
|
27KB
|
895 lines
/*
* MicroDot PGP Interface
*/
#include "microdot.h"
#include "ogre.h"
#include "ogre_protos.h"
#include "asyncio.h"
#include <dos/dostags.h>
static char *passphrase;
static ULONG passphrasesize;
static UBYTE *mykey;
static ULONG mykeysize;
int pgpavail;
static char pgppath[á128 ];
static char pgpcmdpath[ 256 ];
#define PGPWARN "PGP-`Pass phrase' setzen.\n\n\
WARNUNG! Diese Option setzt das Passwort,\n\
mit dem PGP Ihre Keyrings schⁿtzt!\n\
Verwenden Sie diese Option nicht, ohne sich\n\
vorher in der Anleitung von MicroDot ⁿber die\n\
Implikationen informiert zu haben."
#define CODE(c) ((int)sextet[((c) & 077)])
#define FUELL '='
void pgp_addb64hl( struct hlist *hl, char *header, UBYTE *data, int size )
{
char buffer[ 8192 ];
static char sextet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
int count = size, cnt;
UBYTE buf[ 4 ], *bp = data, *to = buffer;
int a, b, c, d;
while( count )
{
memset(buf, 0, 3);
/*
* 3 Byte einlesen:
*/
cnt = min( count, 3 );
count -= cnt;
memcpy( buf, bp, cnt );
bp += cnt;
/*
* und als 4 sextets ausgeben
*/
a = buf[0] >> 2;
b = ((buf[0] << 4) & 060) | ((buf[1] >> 4) & 017);
c = ((buf[1] << 2) & 074) | ((buf[2] >> 6) & 03);
d = buf[2] & 077;
*to++ = CODE( a );
*to++ = CODE( b );
if (cnt == 1) {
*to++ = FUELL;
*to++ = FUELL;
} else {
*to++ = CODE( c );
if (cnt == 2)
*to++ = FUELL;
else
*to++ = CODE( d );
}
}
*to = 0;
hl_addheader( hl, header, buffer );
}
void pgp_addb64hlfile( struct hlist *hl, char *header, char *filename )
{
BPTR f;
int len = getfilelen( filename );
APTR mem;
if( len < 1 )
return;
mem = myAllocVec( len, MEMF_ANY );
if( !mem )
return;
f = Open( filename, MODE_OLDFILE );
Read( f, mem, len );
Close( f );
pgp_addb64hl( hl, header, mem, len );
myFreeVec( mem );
}
void pgp_addpubkey( struct hlist *hl )
{
char buffer[á512 ];
if( prefs.mode == MDM_RFC )
sprintf( buffer, "%s <%s@%s%s>",
prefs.userrealname,
prefs.username,
prefs.pointname,
prefs.boxdomain
);
else
sprintf( buffer, "%s <%s@%s%s>",
prefs.userrealname,
prefs.username,
prefs.boxname,
prefs.boxdomain
);
if( stricmp( buffer, prefs.pgp_userid ) )
hl_addheader( hl, "PGP-ID", prefs.pgp_userid );
pgp_addb64hl( hl, "PGP-PUBLIC-KEY", mykey, mykeysize );
}
void pgp_setpassphrase( void )
{
char *tempbuff = myAllocVec( 4096, 0 );
ULONG pcrc;
if( !tempbuff )
{
displaybeep();
return;
}
if( GetVar( "PGPPASS", tempbuff, 127, 0 ) > 0 )
{
FreeVec( tempbuff );
return;
}
redo:
tempbuff[á0 ]á= 0;
switch( rtGetString( tempbuff, 4095, NULL, rinfo,
RTGS_Invisible, TRUE,
RTGS_TextFmt, PGPWARN,
RTGS_GadFmt, "OK|Hilfe|Abbruch",
TAG_DONE ) )
{
case 1:
if( passphrase )
LibFreePooled( miscmempool, passphrase, passphrasesize );
passphrasesize = strlen( tempbuff ) + 1;
passphrase = NULL;
if( passphrasesize < 2 )
{
askreq( "PGP 'Pass phrase' gel÷scht.", "Weiter" );
myFreeVec( tempbuff );
return;
}
pcrc = crc32( tempbuff, strlen( tempbuff ) );
if( prefs.pgp_lastpassphrase && ( pcrc != prefs.pgp_lastpassphrase ) )
{
if( askreq( "Die eingegebene Passphrase stimmt nicht mit der\nⁿberein, die Sie zuletzt an dieser Stelle eingegeben haben.",
"Nochmal eingeben|Trotzdem benutzen"
)) goto redo;
}
passphrase = LibAllocPooled( miscmempool, passphrasesize );
if( !passphrase )
{
displaybeep();
myFreeVec( tempbuff );
return;
}
strcpy( passphrase, tempbuff );
prefs.pgp_lastpassphrase = pcrc;
myFreeVec( tempbuff );
break;
case 2:
showguide( "pgp_setpassphrase" );
goto redo;
}
}
int runpgp( char *cmd, int pp, int flags )
{
char tmp[á256 ];
BPTR outwin, oldcd, pgpcd, outwin2 = NULL;
int rc;
char *textmode = ( flags & 16 ) ? "on" : "off";
char *armor = ( flags & 8 ) ? "on" : "off";
if( pp && !passphrase && prefs.pgp_autoaskpp )
pgp_setpassphrase();
/* Kein Quiet, falls Passphrase per PGP eingegeben werden mu▀ */
if( pp && !passphrase )
flags &= ~2;
if( ! ( flags & 2 ) )
{
strcpy( tmp, prefs.pgp_win );
if( flags & 1 )
strcat( tmp, "/WAIT/CLOSE" );
outwin = OpenCon( tmp );
if( !outwin )
{
displaybeep();
return( -2 );
}
}
else
{
outwin = Open( "NIL:", MODE_OLDFILE );
outwin2 = Open( "NIL:", MODE_OLDFILE );
}
pgpcd = Lock( pgppath, SHARED_LOCK );
if( !pgpcd )
{
displaybeep();
Close( outwin );
return( -3 );
}
oldcd = CurrentDir( pgpcd );
if( !pp )
sprintf( tmp, "\"%s\" +armor=%s +textmode=%s %s%s", pgpcmdpath, armor, textmode, ( flags & 4 ) ? "" : "+batchmode +force ", cmd );
else if( pp && !passphrase )
sprintf( tmp, "\"%s\" +armor=%s +textmode=%s %s", pgpcmdpath, armor, textmode, cmd );
else
sprintf( tmp, "\"%s\" +armor=%s +textmode=%s %s\"-z%s\" %s",
pgpcmdpath,
armor, textmode,
pp != 2 ? "+batchmode " : "",
passphrase,
cmd
);
if( flags & 1 )
FPrintf( outwin, "╖\x08" );
//FPrintf( outwin, "EXEC: '%s'\n", tmp );
rc = SystemTags( tmp,
NP_StackSize, 10240,
SYS_Input, outwin,
SYS_Output, outwin2,
TAG_DONE
);
if( flags & 1 )
{
FPrintf( outwin, "\n\nPGP-Aufruf abgeschlossen (rc %ld).\nBitte dieses Fenster per CLOSE-Gadget oder CTRL-\\ schlie▀en.", rc );
}
Close( outwin );
if( outwin2 )
Close( outwin2 );
UnLock( CurrentDir( oldcd ) );
return( rc );
}
static char *krentries[] = { "Nie", "Immer", "Nachfragen", NULL };
#define PP_OK 1
#define PP_CANCEL 2
#define PP_UID 3
#define PP_AVAIL 4
#define PP_KEYREQ 5
#define PP_EB 6
#define PP_WIN 7
#define PP_AUTOASKPP 8
#define PP_RING1 9
#define PP_RING2 10
void pgp_prefs( void )
{
struct ogwin *ogw;
struct Window *iw;
struct IntuiMessage *im;
int Done = FALSE;
ogw = ogreInitWindow( scr, 0, 0, "PGP-Voreinstellungen" );
ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Info " );
ogreAddString( ogw, 0, 'u', "Eigene _UserID:", PP_UID, prefs.pgp_userid, 40, 256 );
ogreAddString( ogw, 1, 'i', "PGP-KEY-AVAIL:-_Info", PP_AVAIL, prefs.pgp_avail, 40, 128 );
ogreAddGroup( ogw, 1, OGFRAME_OUTLINE, " Optionen " );
ogreAddCheckbox( ogw, 0, 'p', "`_Pass phrase' automatisch erfragen:", PP_AUTOASKPP, prefs.pgp_autoaskpp );
ogreAddCheckbox( ogw, 1, 'e', "Eigenen Key bei _EmpfangsbestΣtigungen mitschicken:", PP_EB, prefs.pgp_sendoneb );
ogreAddCycle( ogw, 2, 'r', "Key-_Requests beantworten:", PP_KEYREQ, krentries, 12, prefs.pgp_request );
ogreAddGroup( ogw, 2, OGFRAME_OUTLINE, " Sonstiges " );
ogreAddString( ogw, 0, 'f', "_Fenster fⁿr PGP-Aufruf:", PP_WIN, prefs.pgp_win, 40, 128 );
ogreAddString( ogw, 1, 0, "Keyring:", PP_RING1, prefs.pgp_ring1, 40, 128 );
//ogreAddString( ogw, 2, 0, "SekundΣrer Keyring:", PP_RING2, prefs.pgp_ring2, 40, 128 );
ogreAddGroup( ogw, 3, OGFRAME_NONE, NULL );
ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", PP_OK );
ogreAddHelp( ogw, 0 );
ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", PP_CANCEL );
iw = ogreOpenWindow( ogw );
if( !iw )
return;
while( !Done )
{
im = ogreWaitIM( ogw );
if( im->Class == IDCMP_GADGETHELP)
showguidenum( "pgp_prefsgads", im->Code );
else if( im->Class == IDCMP_GADGETUP )
{
switch( im->Code )
{
case PP_OK:
Done = 2;
break;
case PP_CANCEL:
Done = 1;
break;
}
}
ogreIMReply( ogw, im );
}
if( Done == 2 )
{
ogreCopyStringValue( ogw, PP_UID, prefs.pgp_userid );
ogreCopyStringValue( ogw, PP_AVAIL, prefs.pgp_avail );
ogreCopyStringValue( ogw, PP_WIN, prefs.pgp_win );
ogreCopyStringValue( ogw, PP_RING1, prefs.pgp_ring1 );
// ogreCopyStringValue( ogw, PP_RING2, prefs.pgp_ring2 );
prefs.pgp_sendoneb = ogreValue( ogw, PP_EB );
prefs.pgp_request = ogreValue( ogw, PP_KEYREQ );
prefs.pgp_autoaskpp = ogreValue( ogw, PP_AUTOASKPP );
}
ogreExitWindow( ogw );
}
int getpubkey( char *userid, char *toname )
{
char tmp[á128 ];
int rc;
DeleteFile( toname );
/* Ersten Ring versuchen */
sprintf( tmp, "-kx \"%s\" %s \"%s\"",
userid,
toname,
prefs.pgp_ring1 );
rc = runpgp( tmp, 0, 2 );
if( rc && prefs.pgp_ring2[á0 ] )
{
/* Zweiten Ring versuchen */
sprintf( tmp, "-kx \"%s\" %s \"%s\"",
userid,
toname,
prefs.pgp_ring2 );
rc = runpgp( tmp, 0, 2 );
if( !rc && ( getfilelen( toname ) > 0 ) )
return( 2 );
}
if( !rc && ( getfilelen( toname ) > 0 ) )
return( 1 );
else
return( 0 );
}
static int readmykey( char *filename )
{
BPTR f;
mykeysize = getfilelen( filename );
if( mykeysize < 1 )
return( -1 );
mykey = LibAllocPooled( miscmempool, mykeysize );
if( !mykey )
return( -2 );
f = Open( filename, MODE_OLDFILE );
if( !f )
return( -3 );
Read( f, mykey, mykeysize );
Close( f );
return( 0 );
}
void pgp_init( void )
{
char tmp[ 256 ];
BPTR f;
if( GetVar( "PGPPath", pgppath, 128, 0 ) < 1 )
return;
if( !checkprograminpathfull( "PGP", pgpcmdpath ) )
{
strcpy( tmp, pgppath );
AddPart( tmp, "PGP", 256 );
if( getfilelen( tmp ) < 1 )
return;
strcpy( pgpcmdpath, tmp );
}
pgpavail = TRUE;
/* Userid? */
if( !prefs.pgp_userid[á0 ]á)
{
if( prefs.mode == MDM_RFC )
sprintf( prefs.pgp_userid, "%s <%s@%s%s>",
prefs.userrealname,
prefs.username,
prefs.pointname,
prefs.boxdomain
);
else
sprintf( prefs.pgp_userid, "%s <%s@%s%s>",
prefs.userrealname,
prefs.username,
prefs.boxname,
prefs.boxdomain
);
}
if( !prefs.pgp_win[á0 ]á)
strcpy( prefs.pgp_win, "CON://1024/1024/MicroDot-PGP-Shell/AUTO" );
if( !prefs.pgp_ring1[á0 ]á)
strcpy( prefs.pgp_ring1, "pubring.pgp" );
prefs.pgp_ring2[á0 ]á= 0;
/* Gut. Eigenen Public-Key einlesen */
pushhomedir();
if( !readmykey( "microdot.pgpkey" ) )
{
popdir();
return;
}
popdir();
retry:
if( !getpubkey( prefs.pgp_userid, "T:mdpgpkey.pgp" ) )
{
reask:
switch( askreq( "Ihr eigener Public-Key unter der UserID\n\"%s\"\nwurde nicht gefunden. Wollen Sie jetzt\nein Key-Paar generieren?",
"Keys generieren|PGP-Voreinstellungen|Hilfe|Abbruch",
prefs.pgp_userid ) )
{
case 0:
pgpavail = 0;
return;
case 1:
if( !runpgp( "-kg", 0, 5 ) )
{
sprintf( tmp, "-ks \"%s\"", prefs.pgp_userid );
runpgp( tmp, 1, 5 );
}
goto retry;
break;
case 2:
pgp_prefs();
goto retry;
case 3:
showguide( "pgp_genkeys" );
goto reask;
}
}
readmykey( "T:mdpgpkey.pgp" );
pushhomedir();
f = Open( "microdot.pgpkey", MODE_NEWFILE );
if( f )
{
Write( f, mykey, mykeysize );
Close( f );
}
popdir();
DeleteFile( "T:mdpgpkey.pgp" );
}
#define IGID_LV 1
#define IGID_OK 2
#define IGID_CANCEL 3
#define IGID_DEL 4
#define IGID_ADD1 5
#define IGID_ADD2 6
#define IGID_VIEW 7
#define IGID_ALL 8
struct keymem {
char *userid;
UBYTE *key;
ULONG keysize;
char label[á128 ];
};
static void doviewfingerprint( struct keymem *km )
{
char exec[á128 ], tmpkey[ 64 ], tmpring[ 64 ];
BPTR f;
sprintf( tmpkey, "T:mdkeytmp%lx.pgp", time( 0 ) );
sprintf( tmpring, "T:mdringtmp%lx.pgp", time( 0 ) );
f = Open( tmpkey, MODE_NEWFILE );
if( !f )
{
displaybeep();
return;
}
Write( f, km->key, km->keysize );
Close( f );
sprintf( exec, "-ka %s %s", tmpkey, tmpring );
runpgp( exec, 0, 2 );
sprintf( exec, "-kvc \"%s\" %s", km->userid, tmpring );
runpgp( exec, 0, 1 );
// Tempfiles l÷schen
DeleteFile( tmpring );
strcpy( strchr( tmpring, '.' ), ".bak" );
DeleteFile( tmpring );
DeleteFile( tmpkey );
}
#if 0
static void doaddkey( struct keymem *km, int keyring )
{
char exec[á128 ], tmpkey[ 64 ];
BPTR f;
sprintf( tmpkey, "T:mdkeytmp%lx.pgp", time( 0 ) );
f = Open( tmpkey, MODE_NEWFILE );
if( !f )
{
displaybeep();
return;
}
Write( f, km->key, km->keysize );
Close( f );
sprintf( exec, "-ka %s \"%s\"", tmpkey, keyring ? prefs.pgp_ring2 : prefs.pgp_ring1 );
runpgp( exec, 0, 0 );
// Tempfiles l÷schen
DeleteFile( tmpkey );
}
#endif
void pgp_procincoming( void )
{
struct ogwin *ogw;
struct Window *iw;
struct IntuiMessage *im;
int Done = FALSE;
struct ogrevn *vn;
struct AsyncFile *f;
ULONG lm, olm;
struct keymem *keymem;
APTR keypool;
int isediting = -1, keyring = 0;
int c;
pushhomedir();
f = OpenAsync( "microdot.new_pgpkeys", MODE_READ, 4096 );
popdir();
if( !f )
{
askreq( "Keine eingegangenen Keys.", "Weiter" );
return;
}
keypool = LibCreatePool( 0, 4096, 2048 );
ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, "Eingegangene PGP-Keys verwalten:" );
ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
ogreAddList( ogw, 0, 0xff, NULL, IGID_LV, 60, 12, TRUE, NULL );
ogreLVInit( ogw, IGID_LV );
#define MDKID 0x4d44504b
for(;;)
{
keymem = LibAllocPooled( keypool, sizeof( *keymem ) );
if( !keymem )
break;
if( ReadAsync( f, &olm, 4 ) != 4 )
break;
if( olm != MDKID )
{
askreq( "Fehler in der Datei \"microdot.new_pgpkeys\":\nFalsche ID %lx", "Abbruch", olm );
break;
}
if( ReadAsync( f, &lm, 4 ) != 4 )
break;
keymem->userid = LibAllocPooled( keypool, lm + 1 );
if( !keymem->userid )
break;
ReadAsync( f, keymem->userid, lm + 1 );
if( ReadAsync( f, &lm, 4 ) != 4 ) /* CRC */
break;
if( ReadAsync( f, &lm, 4 ) != 4 )
break;
keymem->key = LibAllocPooled( keypool, keymem->keysize = lm );
ReadAsync( f, keymem->key, lm );
if( ReadAsync( f, &lm, 4 ) != 4 ) /* CRC */
break;
sprintf( keymem->label, "%s: %s", olm == MDKID ? "KEY" : "SIG", keymem->userid );
if( ogreLVFindEntry( ogw, IGID_LV, keymem->label ) )
{
struct ogrevn *vn;
for( c = 0; ; c++ )
{
vn = ogreLVGetEntry( ogw, IGID_LV, c );
if( !vn )
break;
if( !stricmp( ( ( struct keymem * ) vn->userdata ) -> label, keymem->label ) )
{
Remove( ( struct Node * ) vn );
break;
}
}
}
ogreLVAddEntry( ogw, IGID_LV, keymem->label, 0, keymem );
}
CloseAsync( f );
ogreAddButton( ogw, 1, 'a', "_Alle", IGID_ALL );
ogreAddButton( ogw, 1, 'l', "_L÷schen", IGID_DEL );
ogreAddButton( ogw, 1, '1', "-> Keyring _1", IGID_ADD1 );
if( prefs.pgp_ring2[á0 ]á)
ogreAddButton( ogw, 1, '2', "-> Keyring _2", IGID_ADD2 );
ogreAddButton( ogw, 1, 'f', "_Fingerprint anzeigen", IGID_VIEW );
ogreAddButton( ogw, 2 | OGB_ONENTER, '@', "OK", IGID_OK );
ogreAddHelp( ogw, 2 );
ogreAddButton( ogw, 2 | OGB_ONESC, '\x1b', "Abbruch", IGID_CANCEL );
iw = ogreOpenWindow( ogw );
if( !iw )
{
LibDeletePool( keypool );
return;
}
while( !Done )
{
ogreEnable( ogw, isediting >= 0, IGID_DEL, IGID_ADD1, IGID_ADD2, IGID_VIEW, 0 );
ogreEnable( ogw, ogreLVGetNumEntries( ogw, IGID_LV ), IGID_ALL, 0 );
im = ogreWaitIM( ogw );
if( im->Class == IDCMP_GADGETHELP)
showguidenum( "pgpkeywin_gads", im->Code );
else if( im->Class == IDCMP_GADGETUP )
{
switch( im->Code )
{
case IGID_LV:
isediting = ogreValue( ogw, IGID_LV );
break;
case IGID_OK:
Done = 2;
break;
case IGID_CANCEL:
Done = 1;
break;
case IGID_ALL:
for( c = 0; ; c++ )
{
struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, c );
if( !vn )
break;
ogreLVSelect( ogw, IGID_LV, c );
isediting = 0;
}
ogreLVRefresh( ogw, IGID_LV );
break;
case IGID_DEL:
if( isediting >= 0 )
{
struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, 0 ), *next;
while( next = ( struct ogrevn * ) vn->n.mln_Succ )
{
if( vn->sel )
Remove( vn );
vn = next;
}
ogreLVRefresh( ogw, IGID_LV );
isediting = -1;
}
break;
case IGID_ADD2:
keyring = 1;
case IGID_ADD1:
if( isediting >= 0 )
{
struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, 0 ), *next;
char exec[á128 ], tmpkey[ 64 ];
BPTR f;
sprintf( tmpkey, "T:mdkeytmp%lx.pgp", time( 0 ) );
f = Open( tmpkey, MODE_NEWFILE );
if( !f )
{
displaybeep();
break;
}
while( next = ( struct ogrevn * ) vn->n.mln_Succ )
{
if( vn->sel )
{
struct keymem *km = vn->userdata;
Write( f, km->key, km->keysize );
Remove( vn );
}
vn = next;
}
Close( f );
sprintf( exec, "-ka %s \"%s\"", tmpkey, keyring ? prefs.pgp_ring2 : prefs.pgp_ring1 );
runpgp( exec, 0, 0 );
// Tempfiles l÷schen
DeleteFile( tmpkey );
ogreLVRefresh( ogw, IGID_LV );
isediting = -1;
}
keyring = 0;
break;
case IGID_VIEW:
if( isediting >= 0 )
{
struct ogrevn *vn = ogreLVGetEntry( ogw, IGID_LV, 0 ), *next;
while( next = ( struct ogrevn * ) vn->n.mln_Succ )
{
if( vn->sel )
{
doviewfingerprint( vn->userdata );
vn->sel = FALSE;
}
vn = next;
}
ogreLVRefresh( ogw, IGID_LV );
isediting = -1;
}
break;
}
}
ogreIMReply( ogw, im );
}
if( Done == 2 )
{
struct ogrevn *vn;
struct keymem *km;
pushhomedir();
DeleteFile( "microdot.new_pgpkeys.bak" );
Rename( "microdot.new_pgpkeys", "microdot.new_pgpkeys.bak" );
f = OpenAsync( "microdot.new_pgpkeys", MODE_WRITE, 4096 );
if( f )
{
/* ▄brige Keys wieder abspeichern */
for( c = 0; ; c++ )
{
vn = ogreLVGetEntry( ogw, IGID_LV, c );
if( !vn )
break;
km = vn->userdata;
lm = MDKID;
WriteAsync( f, &lm, 4 );
lm = strlen( km->userid );
WriteAsync( f, &lm, 4 );
WriteAsync( f, km->userid, lm + 1 );
WriteAsync( f, &lm, 4 ); /* Dummy */
WriteAsync( f, &km->keysize, 4 );
WriteAsync( f, km->key, km->keysize );
WriteAsync( f, &lm, 4 ); /* Dummy */
}
CloseAsync( f );
}
if( !c )
DeleteFile( "microdot.new_pgpkeys" );
popdir();
}
ogreExitWindow( ogw );
LibDeletePool( keypool );
}
void pgp_showkeys( int verbose )
{
char exec[á64 ];
sprintf( exec, "-kv%s %s", verbose ? "v" : "", prefs.pgp_ring1 );
runpgp( exec, 0, 1 );
if( prefs.pgp_ring2[á0 ]á)
{
sprintf( exec, "-kv%s %s", verbose ? "v" : "", prefs.pgp_ring2 );
runpgp( exec, 0, 1 );
}
}
void pgp_checkkeys( void )
{
char exec[á64 ];
sprintf( exec, "-kc %s", prefs.pgp_ring1 );
runpgp( exec, 0, 1 );
if( prefs.pgp_ring2[á0 ]á)
{
sprintf( exec, "-kc %s", prefs.pgp_ring2 );
runpgp( exec, 0, 1 );
}
}
void pgp_changepassphrase( void )
{
char tmp[ 256 ];
sprintf( tmp, "-ke \"%s\"", prefs.pgp_userid );
runpgp( tmp, 2, 0 );
}
void pgp_rereadownkey( void )
{
pushhomedir();
DeleteFile( "microdot.pgpkey" );
popdir();
pgp_init();
}