--- pgp/src/pgp.c 2018/04/24 16:42:41 1.1.1.7 +++ pgp/src/pgp.c 2018/04/24 16:43:55 1.1.1.8 @@ -1,104 +1,105 @@ -/* #define TEMP_VERSION / * if defined, temporary experimental version of PGP */ -/* pgp.c -- main module for PGP. - PGP: Pretty Good(tm) Privacy - public key cryptography for the masses. - - Synopsis: PGP uses public-key encryption to protect E-mail. - Communicate securely with people you've never met, with no secure - channels needed for prior exchange of keys. PGP is well featured and - fast, with sophisticated key management, digital signatures, data - compression, and good ergonomic design. - - The original PGP version 1.0 was written by Philip Zimmermann, of - Phil's Pretty Good(tm) Software. Many parts of later versions of - PGP were developed by an international collaborative effort, - involving a number of contributors, including major efforts by: - Branko Lankester - Hal Finney <74076.1041@compuserve.com> - Peter Gutmann - Other contributors who ported or translated or otherwise helped include: - Jean-loup Gailly in France - Hugh Kennedy in Germany - Lutz Frank in Germany - Cor Bosman in The Netherlands - Felipe Rodriquez Svensson in The Netherlands - Armando Ramos in Spain - Miguel Angel Gallardo Ortiz in Spain - Harry Bush and Maris Gabalins in Latvia - Zygimantas Cepaitis in Lithuania - Alexander Smishlajev - Peter Suchkow and Andrew Chernov in Russia - David Vincenzetti in Italy - ...and others. - - - (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved. - The author assumes no liability for damages resulting from the use - of this software, even if the damage results from defects in this - software. No warranty is expressed or implied. - - Note that while most PGP source modules bear Philip Zimmermann's - copyright notice, many of them have been revised or entirely written - by contributors who frequently failed to put their names in their - code. Code that has been incorporated into PGP from other authors - was either originally published in the public domain or is used with - permission from the various authors. - - PGP is available for free to the public under certain restrictions. - See the PGP User's Guide (included in the release package) for - important information about licensing, patent restrictions on - certain algorithms, trademarks, copyrights, and export controls. - - - Philip Zimmermann may be reached at: - Boulder Software Engineering - 3021 Eleventh Street - Boulder, Colorado 80304 USA - (303) 541-0140 (voice or FAX) - email: prz@acm.org - - - PGP will run on MSDOS, Sun Unix, VAX/VMS, Ultrix, Atari ST, - Commodore Amiga, and OS/2. Note: Don't try to do anything with - this source code without looking at the PGP User's Guide. - - PGP combines the convenience of the Rivest-Shamir-Adleman (RSA) - public key cryptosystem with the speed of fast conventional - cryptographic algorithms, fast message digest algorithms, data - compression, and sophisticated key management. And PGP performs - the RSA functions faster than most other software implementations. - PGP is RSA public key cryptography for the masses. - - Uses RSA Data Security, Inc. MD5 Message Digest Algorithm - as a hash for signatures. Uses the ZIP algorithm for compression. - Uses the ETH IPES/IDEA algorithm for conventional encryption. - - PGP generally zeroes its used stack and memory areas before exiting. - This avoids leaving sensitive information in RAM where other users - could find it later. The RSA library and keygen routines also - sanitize their own stack areas. This stack sanitizing has not been - checked out under all the error exit conditions, when routines exit - abnormally. Also, we must find a way to clear the C I/O library - file buffers, the disk buffers, and and cache buffers. - - Revisions: - Version 1.0 - 5 Jun 91 - Version 1.4 - 19 Jan 92 - Version 1.5 - 12 Feb 92 - Version 1.6 - 24 Feb 92 - Version 1.7 - 29 Mar 92 - Version 1.8 - 23 May 92 - Version 2.0 - 2 Sep 92 - Version 2.1 - 6 Dec 92 - Version 2.2 - 6 Mar 93 - Version 2.3 - 13 Jun 93 - Version 2.3a- 1 Jul 93 - Version 2.4 - 6 Nov 93 - Version 2.5 - 5 May 94 - Version 2.6 - 22 May 94 - - Modified: 12-Nov-92 HAJK - Add FDL stuff for VAX/VMS local mode. -*/ +/* #define TEMP_VERSION / * if defined, temporary experimental + version of PGP */ +/* pgp.c -- main module for PGP. + PGP: Pretty Good(tm) Privacy - public key cryptography for the masses. + + Synopsis: PGP uses public-key encryption to protect E-mail. + Communicate securely with people you've never met, with no secure + channels needed for prior exchange of keys. PGP is well featured and + fast, with sophisticated key management, digital signatures, data + compression, and good ergonomic design. + + The original PGP version 1.0 was written by Philip Zimmermann, of + Phil's Pretty Good(tm) Software. Many parts of later versions of + PGP were developed by an international collaborative effort, + involving a number of contributors, including major efforts by: + Branko Lankester + Hal Finney <74076.1041@compuserve.com> + Peter Gutmann + Other contributors who ported or translated or otherwise helped include: + Jean-loup Gailly in France + Hugh Kennedy in Germany + Lutz Frank in Germany + Cor Bosman in The Netherlands + Felipe Rodriquez Svensson in The Netherlands + Armando Ramos in Spain + Miguel Angel Gallardo Ortiz in Spain + Harry Bush and Maris Gabalins in Latvia + Zygimantas Cepaitis in Lithuania + Alexander Smishlajev + Peter Suchkow and Andrew Chernov in Russia + David Vincenzetti in Italy + ...and others. + + + (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved. + The author assumes no liability for damages resulting from the use + of this software, even if the damage results from defects in this + software. No warranty is expressed or implied. + + Note that while most PGP source modules bear Philip Zimmermann's + copyright notice, many of them have been revised or entirely written + by contributors who frequently failed to put their names in their + code. Code that has been incorporated into PGP from other authors + was either originally published in the public domain or is used with + permission from the various authors. + + PGP is available for free to the public under certain restrictions. + See the PGP User's Guide (included in the release package) for + important information about licensing, patent restrictions on + certain algorithms, trademarks, copyrights, and export controls. + + + Philip Zimmermann may be reached at: + Boulder Software Engineering + 3021 Eleventh Street + Boulder, Colorado 80304 USA + (303) 541-0140 (voice or FAX) + email: prz@acm.org + + + PGP will run on MSDOS, Sun Unix, VAX/VMS, Ultrix, Atari ST, + Commodore Amiga, and OS/2. Note: Don't try to do anything with + this source code without looking at the PGP User's Guide. + + PGP combines the convenience of the Rivest-Shamir-Adleman (RSA) + public key cryptosystem with the speed of fast conventional + cryptographic algorithms, fast message digest algorithms, data + compression, and sophisticated key management. And PGP performs + the RSA functions faster than most other software implementations. + PGP is RSA public key cryptography for the masses. + + Uses RSA Data Security, Inc. MD5 Message Digest Algorithm + as a hash for signatures. Uses the ZIP algorithm for compression. + Uses the ETH IPES/IDEA algorithm for conventional encryption. + + PGP generally zeroes its used stack and memory areas before exiting. + This avoids leaving sensitive information in RAM where other users + could find it later. The RSA library and keygen routines also + sanitize their own stack areas. This stack sanitizing has not been + checked out under all the error exit conditions, when routines exit + abnormally. Also, we must find a way to clear the C I/O library + file buffers, the disk buffers, and and cache buffers. + + Revisions: + Version 1.0 - 5 Jun 91 + Version 1.4 - 19 Jan 92 + Version 1.5 - 12 Feb 92 + Version 1.6 - 24 Feb 92 + Version 1.7 - 29 Mar 92 + Version 1.8 - 23 May 92 + Version 2.0 - 2 Sep 92 + Version 2.1 - 6 Dec 92 + Version 2.2 - 6 Mar 93 + Version 2.3 - 13 Jun 93 + Version 2.3a- 1 Jul 93 + Version 2.4 - 6 Nov 93 + Version 2.5 - 5 May 94 + Version 2.6 - 22 May 94 + + Modified: 12-Nov-92 HAJK + Add FDL stuff for VAX/VMS local mode. + */ #include @@ -108,6 +109,11 @@ #include #include #include + +#ifdef __QNX__ +#include +#endif + #include "system.h" #include "mpilib.h" #include "random.h" @@ -129,18 +135,18 @@ long time(); #endif #ifdef MSDOS -#ifdef __ZTC__ /* Extend stack for Zortech C */ -unsigned _stack_ = 24*1024; +#ifdef __ZTC__ /* Extend stack for Zortech C */ +unsigned _stack_ = 24 * 1024; #endif #ifdef __TURBOC__ -unsigned _stklen = 24*1024; +unsigned _stklen = 24 * 1024; #endif #endif #define STACK_WIPE 4096 /* Global filenames and system-wide file extensions... */ -char rel_version[] = _LANG("2.6"); /* release version */ -static char rel_date[] = "23 May 94"; /* release date */ +char rel_version[] = _LANG("2.6.1"); /* release version */ +static char rel_date[] = "29 Aug 94"; /* release date */ char PGP_EXTENSION[] = ".pgp"; char ASC_EXTENSION[] = ".asc"; char SIG_EXTENSION[] = ".sig"; @@ -157,7 +163,7 @@ char globalCommentString[128]; /* Flags which are global across the driver code files */ boolean verbose = FALSE; /* -l option: display maximum information */ -FILE *pgpout; /* Place for routine messages */ +FILE *pgpout; /* Place for routine messages */ static void usage(void); static void key_usage(void); @@ -168,49 +174,52 @@ static int do_decrypt(char *); static void do_armorfile(char *); -/* Various compression signatures: PKZIP, Zoo, GIF, Arj, and HPACK. - Lha(rc) is handled specially in the code; it is missing from the - compressSig structure intentionally. If more formats are added, - put them before lharc to keep the code consistent. -*/ -static char *compressSig[] = { "PK\03\04", "ZOO ", "GIF8", "\352\140", - "HPAK", "\037\213", "\037\235", "\032\013", "\032HP%" +/* Various compression signatures: PKZIP, Zoo, GIF, Arj, and HPACK. + Lha(rc) is handled specially in the code; it is missing from the + compressSig structure intentionally. If more formats are added, + put them before lharc to keep the code consistent. + */ +static char *compressSig[] = +{"PK\03\04", "ZOO ", "GIF8", "\352\140", + "HPAK", "\037\213", "\037\235", "\032\013", "\032HP%" /* lharc is special, must be last */ }; -static char *compressName[] = { "PKZIP", "Zoo", "GIF", "Arj", - "Hpack", "gzip", "compressed", "PAK", "Hyper", - "LHarc" }; -static char *compressExt[] = { ".zip", ".zoo", ".gif", ".arj", - ".hpk", ".z", ".Z", ".pak", ".hyp", - ".lzh" }; +static char *compressName[] = +{"PKZIP", "Zoo", "GIF", "Arj", + "Hpack", "gzip", "compressed", "PAK", "Hyper", + "LHarc"}; +static char *compressExt[] = +{".zip", ".zoo", ".gif", ".arj", + ".hpk", ".z", ".Z", ".pak", ".hyp", + ".lzh"}; /* "\032\0??", "ARC", ".arc" */ -int compressSignature(byte *header) /* Returns file signature type from a number of popular compression formats or -1 if no match */ +int compressSignature(byte * header) { - int i; + int i; - for (i=0; i= 0) - return FALSE; /* probably not compressible */ - return TRUE; /* possibly compressible */ -} /* compressible */ + byte header[8]; + get_header_info_from_file(filename, header, 8); + if (compressSignature(header) >= 0) + return FALSE; /* probably not compressible */ + return TRUE; /* possibly compressible */ +} /* compressible */ /* Possible error exit codes - not all of these are used. Note that we @@ -252,76 +261,84 @@ static boolean file_compressible(char *f #ifdef SIGINT -void breakHandler(int sig) + /* This function is called if a BREAK signal is sent to the program. In this case we zap the temporary files. -*/ + */ +void breakHandler(int sig) { #ifdef UNIX - if (sig == SIGPIPE) { - signal(SIGPIPE, SIG_IGN); - exitPGP(INTERRUPT); - } - if (sig != SIGINT) - fprintf(stderr, "\nreceived signal %d\n", sig); - else -#endif - fprintf(pgpout,LANG("\nStopped at user request\n")); + if (sig == SIGPIPE) { + signal(SIGPIPE, SIG_IGN); exitPGP(INTERRUPT); + } + if (sig != SIGINT) + fprintf(stderr, "\nreceived signal %d\n", sig); + else +#endif + fprintf(pgpout, LANG("\nStopped at user request\n")); + exitPGP(INTERRUPT); } #endif - +/* Clears screen and homes the cursor. */ static void clearscreen(void) -{ /* Clears screen and homes the cursor. */ - fprintf(pgpout,"\n\033[0;0H\033[J\r \r"); /* ANSI sequence. */ - fflush(pgpout); +{ + fprintf(pgpout, "\n\033[0;0H\033[J\r \r"); /* ANSI sequence. */ + fflush(pgpout); } +/* We had to process the config file first to possibly select the + foreign language to translate the sign-on line that follows... */ static void signon_msg(void) -{ /* We had to process the config file first to possibly select the - foreign language to translate the sign-on line that follows... */ - word32 tstamp; - /* display message only once to allow calling multiple times */ - static boolean printed = FALSE; - - if (quietmode || printed) - return; - printed = TRUE; - fprintf(stderr,LANG("Pretty Good Privacy(tm) %s - Public-key encryption for the masses.\n"), - rel_version); +{ + word32 tstamp; + /* display message only once to allow calling multiple times */ + static boolean printed = FALSE; + + if (quietmode || printed) + return; + printed = TRUE; + fprintf(stderr, +LANG("Pretty Good Privacy(tm) %s - Public-key encryption for the masses.\n"), + rel_version); #ifdef TEMP_VERSION - fputs("Internal development version only - not for general release.\n", stderr); + fputs( +"Internal development version only - not for general release.\n", stderr); #endif - fprintf(stderr, LANG("(c) 1990-1994 Philip Zimmermann, Phil's Pretty Good Software. %s\n"), - rel_date); - fputs(LANG (signon_legalese), stderr); - fputs(LANG("Export of this software may be restricted by the U.S. government.\n"),stderr); + fprintf(stderr, +LANG("(c) 1990-1994 Philip Zimmermann, Phil's Pretty Good Software. %s\n"), + rel_date); + fputs(LANG(signon_legalese), stderr); + fputs( +LANG("Export of this software may be restricted by the U.S. government.\n"), + stderr); - get_timestamp((byte *)&tstamp); /* timestamp points to tstamp */ - fprintf(pgpout,"Current time: %s\n",ctdate(&tstamp)); + get_timestamp((byte *) & tstamp); /* timestamp points to tstamp */ + fprintf(pgpout, "Current time: %s\n", ctdate(&tstamp)); } -#ifdef TEMP_VERSION /* temporary experimental version of PGP */ +#ifdef TEMP_VERSION /* temporary experimental version of PGP */ #include #define CREATION_DATE 0x2DC079A4ul - /* CREATION_DATE is Fri Apr 29 03:06:12 1994 UTC */ + /* CREATION_DATE is + Fri Apr 29 03:06:12 1994 UTC */ #define LIFESPAN ((unsigned long) 60L * (unsigned long) 86400L) - /* LIFESPAN is 60 days */ -void check_expiration_date(void) + /* LIFESPAN is 60 days */ + /* If this is an experimental version of PGP, cut its life short */ +void check_expiration_date(void) { - if (get_timestamp(NULL) > (CREATION_DATE + LIFESPAN)) { - fprintf(stderr,"\n\007This experimental version of PGP has expired.\n"); - exit(-1); /* error exit */ - } -} /* check_expiration_date */ -#else /* no expiration date */ -#define check_expiration_date() /* null statement */ -#endif /* TEMP_VERSION */ - - + if (get_timestamp(NULL) > (CREATION_DATE + LIFESPAN)) { + fprintf(stderr, + "\n\007This experimental version of PGP has expired.\n"); + exit(-1); /* error exit */ + } +} /* check_expiration_date */ +#else /* no expiration date */ +#define check_expiration_date() /* null statement */ +#endif /* TEMP_VERSION */ /* -f means act as a unix-style filter */ /* -i means internalize extended file attribute information, only supported @@ -336,7 +353,7 @@ void check_expiration_date(void) extern int optind; extern char *optarg; -boolean emit_radix_64 = FALSE; /* set by config file */ +boolean emit_radix_64 = FALSE; /* set by config file */ static boolean sign_flag = FALSE; boolean moreflag = FALSE; boolean filter_mode = FALSE; @@ -352,18 +369,22 @@ boolean batchmode = FALSE; /* if TRUE: d boolean quietmode = FALSE; boolean force_flag = FALSE; /* overwrite existing file without asking */ boolean pkcs_compat = 1; -#ifdef VMS /* kludge for those stupid VMS variable-length text records */ -char literal_mode = MODE_TEXT; /* MODE_TEXT or MODE_BINARY for literal packet */ -#else /* not VMS */ -char literal_mode = MODE_BINARY; /* MODE_TEXT or MODE_BINARY for literal packet */ -#endif /* not VMS */ +#ifdef VMS /* kludge for those stupid VMS variable-length + text records */ +char literal_mode = MODE_TEXT; /* MODE_TEXT or MODE_BINARY for literal + packet */ +#else /* not VMS */ +char literal_mode = MODE_BINARY; /* MODE_TEXT or MODE_BINARY for literal + packet */ +#endif /* not VMS */ /* my_name is substring of default userid for secret key to make signatures */ -char my_name[256] = "\0"; /* null my_name means take first userid in ring */ +char my_name[256] = "\0"; /* null my_name means take first userid + in ring */ boolean keepctx = FALSE; /* TRUE means keep .ctx file on decrypt */ /* Ask for each key separately if it should be added to the keyring */ boolean interactive_add = FALSE; -boolean compress_enabled = TRUE; /* attempt compression before encryption */ -long timeshift = 0L; /* seconds from GMT timezone */ +boolean compress_enabled = TRUE; /* attempt compression before encryption */ +long timeshift = 0L; /* seconds from GMT timezone */ boolean legal_kludge; int version_byte = VERSION_BYTE_OLD; boolean nomanual = 0; @@ -372,7 +393,7 @@ boolean nomanual = 0; static boolean attempt_compression; /* attempt compression before encryption */ static char *outputfile = NULL; static int errorLvl = EXIT_OK; -static char mcguffin[256]; /* userid search tag */ +static char mcguffin[256]; /* userid search tag */ boolean signature_checked = FALSE; char plainfile[MAX_PATH]; int myArgc = 2; @@ -382,670 +403,703 @@ static struct hashedpw **passwdstail = & int main(int argc, char *argv[]) { - int status, opt; - char *inputfile = NULL; - char **recipient = NULL; - char **mcguffins; - char *workfile, *tempf; - boolean nestflag = FALSE; - boolean decrypt_mode = FALSE; - boolean wipeflag = FALSE; - boolean armor_flag = FALSE; /* -a option */ - boolean separate_signature = FALSE; - boolean keyflag = FALSE; - boolean encrypt_flag = FALSE; - boolean conventional_flag = FALSE; - char *clearfile = NULL; - char *literal_file = NULL; - char literal_file_name[MAX_PATH]; - char cipherfile[MAX_PATH]; - char keychar = '\0'; + int status, opt; + char *inputfile = NULL; + char **recipient = NULL; + char **mcguffins; + char *workfile, *tempf; + boolean nestflag = FALSE; + boolean decrypt_mode = FALSE; + boolean wipeflag = FALSE; + boolean armor_flag = FALSE; /* -a option */ + boolean separate_signature = FALSE; + boolean keyflag = FALSE; + boolean encrypt_flag = FALSE; + boolean conventional_flag = FALSE; + char *clearfile = NULL; + char *literal_file = NULL; + char literal_file_name[MAX_PATH]; + char cipherfile[MAX_PATH]; + char keychar = '\0'; char *p; - byte ctb; - struct hashedpw *hpw; + byte ctb; + struct hashedpw *hpw; - /* Initial messages to stderr */ - pgpout = stderr; + /* Initial messages to stderr */ + pgpout = stderr; #ifdef DEBUG1 - verbose = TRUE; + verbose = TRUE; #endif - /* The various places one can get passwords from. - * We accumulate them all into two lists. One is - * to try on keys only, and is stored in no particular - * order, while the other is of unknown purpose so - * far (they may be used for conventional encryption - * or decryption as well), and are kept in a specific - * order. If any password in the general list is found - * to decode a key, it is moved to the key list. - * The general list is not grown after initialization, - * so the tail pointer is not used after this. - */ - - if ((p = getenv("PGPPASS")) != NULL) { - hpw = xmalloc(sizeof(struct hashedpw)); - hashpass(p, strlen(p), hpw->hash); - /* Add to linked list of key passwords */ - hpw->next = keypasswds; - keypasswds = hpw; - } - - /* The -z "password" option should be used instead of PGPPASS if - * the environment can be displayed with the ps command (eg. BSD). - * If the system does not allow overwriting of the command line - * argument list but if it has a "hidden" environment, PGPPASS - * should be used. - */ - for (opt = 1; opt < argc; ++opt) { - p = argv[opt]; - if (p[0] != '-' || p[1] != 'z') - continue; - /* Accept either "-zpassword" or "-z password" */ - p += 2; - if (!*p) - p = argv[++opt]; - /* p now points to password */ - if (!p) - break; /* End of arg list - ignore */ - hpw = xmalloc(sizeof(struct hashedpw)); - hashpass(p, strlen(p), hpw->hash); - /* Wipe password */ - while (*p) - *p++ = ' '; - /* Add to tail of linked list of passwords */ - hpw->next = 0; - *passwdstail = hpw; - passwdstail = &hpw->next; - } + /* The various places one can get passwords from. + * We accumulate them all into two lists. One is + * to try on keys only, and is stored in no particular + * order, while the other is of unknown purpose so + * far (they may be used for conventional encryption + * or decryption as well), and are kept in a specific + * order. If any password in the general list is found + * to decode a key, it is moved to the key list. + * The general list is not grown after initialization, + * so the tail pointer is not used after this. + */ + + if ((p = getenv("PGPPASS")) != NULL) { + hpw = xmalloc(sizeof(struct hashedpw)); + hashpass(p, strlen(p), hpw->hash); + /* Add to linked list of key passwords */ + hpw->next = keypasswds; + keypasswds = hpw; + } + /* The -z "password" option should be used instead of PGPPASS if + * the environment can be displayed with the ps command (eg. BSD). + * If the system does not allow overwriting of the command line + * argument list but if it has a "hidden" environment, PGPPASS + * should be used. + */ + for (opt = 1; opt < argc; ++opt) { + p = argv[opt]; + if (p[0] != '-' || p[1] != 'z') + continue; + /* Accept either "-zpassword" or "-z password" */ + p += 2; + if (!*p) + p = argv[++opt]; + /* p now points to password */ + if (!p) + break; /* End of arg list - ignore */ + hpw = xmalloc(sizeof(struct hashedpw)); + hashpass(p, strlen(p), hpw->hash); + /* Wipe password */ + while (*p) + *p++ = ' '; + /* Add to tail of linked list of passwords */ + hpw->next = 0; + *passwdstail = hpw; + passwdstail = &hpw->next; + } + /* + * If PGPPASSFD is set in the environment try to read the password + * from this file descriptor. If you set PGPPASSFD to 0 pgp will + * use the first line read from stdin as password. + */ + if ((p = getenv("PGPPASSFD")) != NULL) { + int passfd; + if (*p && (passfd = atoi(p)) >= 0) { + char pwbuf[256]; + p = pwbuf; + while (read(passfd, p, 1) == 1 && *p != '\n') + ++p; + hpw = xmalloc(sizeof(struct hashedpw)); + hashpass(pwbuf, p - pwbuf, hpw->hash); + memset(pwbuf, 0, p - pwbuf); + /* Add to tail of linked list of passwords */ + hpw->next = 0; + *passwdstail = hpw; + passwdstail = &hpw->next; + } + } + /* Process the config file. The following override each other: + - Hard-coded defualts + - The system config file + - Hard-coded defaults for security-critical things + - The user's config file + - Environment variables + - Command-line options. + */ + opt = 0; /* Number of config files read */ +#ifdef PGP_SYSTEM_DIR + strcpy(mcguffin, PGP_SYSTEM_DIR); + strcat(mcguffin, "config.txt"); + if (access(mcguffin, 0) == 0) { + opt++; /* - * If PGPPASSFD is set in the environment try to read the password - * from this file descriptor. If you set PGPPASSFD to 0 pgp will - * use the first line read from stdin as password. - */ - if ((p = getenv("PGPPASSFD")) != NULL) - { - int passfd; - if (*p && (passfd = atoi(p)) >= 0) - { - char pwbuf[256]; - p = pwbuf; - while (read(passfd, p, 1) == 1 && *p != '\n') - ++p; - hpw = xmalloc(sizeof(struct hashedpw)); - hashpass(pwbuf, p-pwbuf, hpw->hash); - memset(pwbuf, 0, p-pwbuf); - /* Add to tail of linked list of passwords */ - hpw->next = 0; - *passwdstail = hpw; - passwdstail = &hpw->next; - } - } - - /* Process the config file. The following override each other: - - Hard-coded defualts - - The system config file - - Hard-coded defaults for security-critical things - - The user's config file - - Environment variables - - Command-line options. + * Note: errors here are NOT fatal, so that people + * can use PGP with a corrputed system file. */ - opt = 0; /* Number of config files read */ -#ifdef PGP_SYSTEM_DIR - strcpy(mcguffin, PGP_SYSTEM_DIR); - strcat(mcguffin, "config.txt"); - if (access(mcguffin, 0) == 0) { - opt++; - /* - * Note: errors here are NOT fatal, so that people - * can use PGP with a corrputed system file. - */ - processConfigFile(mcguffin); - } + processConfigFile(mcguffin); + } #endif - /* - * These must be personal; the system config file may not - * influence them. - */ - buildfilename(globalPubringName, "pubring.pgp"); - buildfilename(globalSecringName, "secring.pgp"); - buildfilename(globalRandseedName, "randseed.bin"); - my_name[0] = '\0'; - - /* Process the config file first. Any command-line arguments will - override the config file settings */ - buildfilename( mcguffin, "config.txt" ); - if (access(mcguffin, 0) == 0) { - opt++; - if ( processConfigFile( mcguffin ) < 0 ) - exit(BAD_ARG_ERROR); - } - if (!opt) - fprintf(pgpout, LANG("\007No configuration file found.\n")); - - init_charset(); - -#ifdef MSDOS /* only on MSDOS systems */ - if ((p = getenv("TZ")) == NULL || *p == '\0') { - fprintf(pgpout,LANG("\007WARNING: Environmental variable TZ is not defined, so GMT timestamps\n\ + /* + * These must be personal; the system config file may not + * influence them. + */ + buildfilename(globalPubringName, "pubring.pgp"); + buildfilename(globalSecringName, "secring.pgp"); + buildfilename(globalRandseedName, "randseed.bin"); + my_name[0] = '\0'; + + /* Process the config file first. Any command-line arguments will + override the config file settings */ + buildfilename(mcguffin, "config.txt"); + if (access(mcguffin, 0) == 0) { + opt++; + if (processConfigFile(mcguffin) < 0) + exit(BAD_ARG_ERROR); + } + if (!opt) + fprintf(pgpout, LANG("\007No configuration file found.\n")); + + init_charset(); + +#ifdef MSDOS /* only on MSDOS systems */ + if ((p = getenv("TZ")) == NULL || *p == '\0') { + fprintf(pgpout,LANG("\007WARNING: Environmental variable TZ is not \ +defined, so GMT timestamps\n\ may be wrong. See the PGP User's Guide to properly define TZ\n\ in AUTOEXEC.BAT file.\n")); - } -#endif /* MSDOS */ + } +#endif /* MSDOS */ #ifdef VMS #define TEMP "SYS$SCRATCH" #else #define TEMP "TMP" -#endif /* VMS */ - if ((p = getenv(TEMP)) != NULL && *p != '\0') - settmpdir(p); - - /* Turn on incompatibility as of 1 September 1994 (GMT) */ - legal_kludge = (get_timestamp(NULL) >= 0x2e651980); - - if ((myArgv = (char **) malloc((argc + 2) * sizeof(char **))) == NULL) { - fprintf(stderr, LANG("\n\007Out of memory.\n")); - exitPGP(7); - } - myArgv[0] = NULL; - myArgv[1] = NULL; - - /* Process all the command-line option switches: */ - while (optind < argc) { - /* - * Allow random order of options and arguments (like GNU getopt) - * NOTE: this does not work with GNU getopt, use getopt.c from - * the PGP distribution. - */ - if ((opt = pgp_getopt(argc, argv, OPTIONS)) == EOF) { - if (optind == argc) /* -- at end */ - break; - myArgv[myArgc++] = argv[optind++]; - continue; - } - opt = to_lower(opt); - if (keyflag && (keychar == '\0' || (keychar == 'v' && opt == 'v'))) - { - if (keychar == 'v') - keychar = 'V'; - else - keychar = opt; - continue; - } - switch (opt) { - case 'a': armor_flag = TRUE; emit_radix_64 = 1; break; - case 'b': separate_signature = strip_sig_flag = TRUE; break; - case 'c': encrypt_flag = conventional_flag = TRUE; - c_flag = TRUE; break; - case 'd': decrypt_only_flag = TRUE; break; - case 'e': encrypt_flag = TRUE; break; - case 'f': filter_mode = TRUE; break; - case '?': - case 'h': usage(); break; +#endif /* VMS */ + if ((p = getenv(TEMP)) != NULL && *p != '\0') + settmpdir(p); + + /* Turn on incompatibility as of 1 September 1994 (GMT) */ + legal_kludge = (get_timestamp(NULL) >= 0x2e651980); + + if ((myArgv = (char **) malloc((argc + 2) * sizeof(char **))) == NULL) { + fprintf(stderr, LANG("\n\007Out of memory.\n")); + exitPGP(7); + } + myArgv[0] = NULL; + myArgv[1] = NULL; + + /* Process all the command-line option switches: */ + while (optind < argc) { + /* + * Allow random order of options and arguments (like GNU getopt) + * NOTE: this does not work with GNU getopt, use getopt.c from + * the PGP distribution. + */ + if ((opt = pgp_getopt(argc, argv, OPTIONS)) == EOF) { + if (optind == argc) /* -- at end */ + break; + myArgv[myArgc++] = argv[optind++]; + continue; + } + opt = to_lower(opt); + if (keyflag && (keychar == '\0' || (keychar == 'v' && opt == 'v'))) { + if (keychar == 'v') + keychar = 'V'; + else + keychar = opt; + continue; + } + switch (opt) { + case 'a': + armor_flag = TRUE; + emit_radix_64 = 1; + break; + case 'b': + separate_signature = strip_sig_flag = TRUE; + break; + case 'c': + encrypt_flag = conventional_flag = TRUE; + c_flag = TRUE; + break; + case 'd': + decrypt_only_flag = TRUE; + break; + case 'e': + encrypt_flag = TRUE; + break; + case 'f': + filter_mode = TRUE; + break; + case '?': + case 'h': + usage(); + break; #ifdef VMS - case 'i': literal_mode = MODE_LOCAL; break; -#endif /* VMS */ - case 'k': keyflag = TRUE; break; - case 'l': verbose = TRUE; break; - case 'm': moreflag = TRUE; break; - case 'p': preserve_filename = TRUE; break; - case 'o': outputfile = optarg; break; - case 's': sign_flag = TRUE; break; - case 't': literal_mode = MODE_TEXT; break; - case 'u': strncpy(my_name, optarg, sizeof(my_name)-1); - CONVERT_TO_CANONICAL_CHARSET(my_name); - break; - case 'w': wipeflag = TRUE; break; - case 'z': break; - /* '+' special option: does not require - */ - case '+': - if (processConfigLine(optarg) == 0) - break; - fprintf(stderr, "\n"); - /* fallthrough */ - default: - arg_error(); - } + case 'i': + literal_mode = MODE_LOCAL; + break; +#endif /* VMS */ + case 'k': + keyflag = TRUE; + break; + case 'l': + verbose = TRUE; + break; + case 'm': + moreflag = TRUE; + break; + case 'p': + preserve_filename = TRUE; + break; + case 'o': + outputfile = optarg; + break; + case 's': + sign_flag = TRUE; + break; + case 't': + literal_mode = MODE_TEXT; + break; + case 'u': + strncpy(my_name, optarg, sizeof(my_name) - 1); + CONVERT_TO_CANONICAL_CHARSET(my_name); + break; + case 'w': + wipeflag = TRUE; + break; + case 'z': + break; + /* '+' special option: does not require - */ + case '+': + if (processConfigLine(optarg) == 0) + break; + fprintf(stderr, "\n"); + /* fallthrough */ + default: + arg_error(); } - myArgv[myArgc] = NULL; /* Just to make it NULL terminated */ + } + myArgv[myArgc] = NULL; /* Just to make it NULL terminated */ - if (keyflag && keychar == '\0') - key_usage(); + if (keyflag && keychar == '\0') + key_usage(); - signon_msg(); - check_expiration_date(); /* hobble any experimental version */ + signon_msg(); + check_expiration_date(); /* hobble any experimental version */ - if (legal_kludge) - version_byte = VERSION_BYTE_KLUDGE; + if (legal_kludge) + version_byte = VERSION_BYTE_KLUDGE; #if 1 - /* At request of Peter Simons, use stderr always. Sounds reasonable. */ - /* JIS: Put this code back in... removing it broke too many things */ - if (!filter_mode && (outputfile == NULL || strcmp(outputfile, "-"))) - pgpout = stdout; + /* At request of Peter Simons, use stderr always. Sounds reasonable. */ + /* JIS: Put this code back in... removing it broke too many things */ + if (!filter_mode && (outputfile == NULL || strcmp(outputfile, "-"))) + pgpout = stdout; #endif #if 0 - /* Check for the existence of the manual */ - /* Commented out to make PGP less facist */ - if (manuals_missing()) { - fputs(LANG("\nWARNING: PGP User's Guide not found. PGP should not be\n\ + /* Check for the existence of the manual */ + /* Commented out to make PGP less facist */ + if (manuals_missing()) { + fputs( +LANG("\nWARNING: PGP User's Guide not found. PGP should not be\n\ distributed without the User's Guide.\n"), pgpout); - } + } #endif - + #if defined(UNIX) || defined(VMS) - umask(077); /* Make files default to private */ + umask(077); /* Make files default to private */ #endif - initsigs(); /* Catch signals */ - noise(); /* Start random number generation */ - - if (keyflag) { - status = do_keyopt(keychar); - if (status < 0) - user_error(); - exitPGP(status); - } + initsigs(); /* Catch signals */ + noise(); /* Start random number generation */ - /* -db means break off signature certificate into separate file */ - if (decrypt_only_flag && strip_sig_flag) - decrypt_only_flag = FALSE; - - if (decrypt_only_flag && armor_flag) - decrypt_mode = de_armor_only = TRUE; - - if (outputfile != NULL) - preserve_filename = FALSE; - - if (!sign_flag && !encrypt_flag && !conventional_flag && !armor_flag) - { - if (wipeflag) { /* wipe only */ - if (myArgc != 3) - arg_error(); /* need one argument */ - if (wipefile(myArgv[2]) == 0 && remove(myArgv[2]) == 0) - { - fprintf(pgpout,LANG("\nFile %s wiped and deleted. "),myArgv[2]); - fprintf(pgpout, "\n"); - exitPGP(EXIT_OK); - } - exitPGP(UNKNOWN_FILE_ERROR); - } - /* decrypt if none of the -s -e -c -a -w options are specified */ - decrypt_mode = TRUE; - } - - if (myArgc == 2) /* no arguments */ - { + if (keyflag) { + status = do_keyopt(keychar); + if (status < 0) + user_error(); + exitPGP(status); + } + /* -db means break off signature certificate into separate file */ + if (decrypt_only_flag && strip_sig_flag) + decrypt_only_flag = FALSE; + + if (decrypt_only_flag && armor_flag) + decrypt_mode = de_armor_only = TRUE; + + if (outputfile != NULL) + preserve_filename = FALSE; + + if (!sign_flag && !encrypt_flag && !conventional_flag && !armor_flag) { + if (wipeflag) { /* wipe only */ + if (myArgc != 3) + arg_error(); /* need one argument */ + if (wipefile(myArgv[2]) == 0 && remove(myArgv[2]) == 0) { + fprintf(pgpout, + LANG("\nFile %s wiped and deleted. "), myArgv[2]); + fprintf(pgpout, "\n"); + exitPGP(EXIT_OK); + } + exitPGP(UNKNOWN_FILE_ERROR); + } + /* decrypt if none of the -s -e -c -a -w options are specified */ + decrypt_mode = TRUE; + } + if (myArgc == 2) { /* no arguments */ #ifdef UNIX - if (!filter_mode && !isatty(fileno(stdin))) { - /* piping to pgp without arguments and no -f: - * switch to filter mode but don't write output to stdout - * if it's a tty, use the preserved filename */ - if (!moreflag) - pgpout = stderr; - filter_mode = TRUE; - if (isatty(fileno(stdout)) && !moreflag) - preserve_filename = TRUE; - } -#endif - if (!filter_mode) { - if (quietmode) { - quietmode = FALSE; - signon_msg(); - } - fprintf(pgpout,LANG("\nFor details on licensing and distribution, see the PGP User's Guide.\ + if (!filter_mode && !isatty(fileno(stdin))) { + /* piping to pgp without arguments and no -f: + * switch to filter mode but don't write output to stdout + * if it's a tty, use the preserved filename */ + if (!moreflag) + pgpout = stderr; + filter_mode = TRUE; + if (isatty(fileno(stdout)) && !moreflag) + preserve_filename = TRUE; + } +#endif + if (!filter_mode) { + if (quietmode) { + quietmode = FALSE; + signon_msg(); + } + fprintf(pgpout, +LANG("\nFor details on licensing and distribution, see the PGP User's Guide.\ \nFor other cryptography products and custom development services, contact:\ -\nPhilip Zimmermann, 3021 11th St, Boulder CO 80304 USA, phone +1 303 541-0140\n")); - if (strcmp((p = LANG("@translator@")), "@translator@")) - fprintf(pgpout, p); - fprintf(pgpout,LANG("\nFor a usage summary, type: pgp -h\n")); - exit(BAD_ARG_ERROR); /* error exit */ - } - } else { - if (filter_mode) { - recipient = &myArgv[2]; - } else { - inputfile = myArgv[2]; - recipient = &myArgv[3]; - } - } - - - if (filter_mode) { - inputfile = "stdin"; - } else { - if (decrypt_mode && no_extension(inputfile)) { - strcpy(cipherfile, inputfile); - force_extension( cipherfile, ASC_EXTENSION ); - if (file_exists (cipherfile)) { - inputfile = cipherfile; - } else { - force_extension( cipherfile, PGP_EXTENSION ); - if (file_exists (cipherfile)) { - inputfile = cipherfile; - } else { - force_extension( cipherfile, SIG_EXTENSION ); - if (file_exists (cipherfile)) - inputfile = cipherfile; - } - } - } - if (! file_exists( inputfile )) { - fprintf(pgpout, LANG("\007File [%s] does not exist.\n"), inputfile); - errorLvl = FILE_NOT_FOUND_ERROR; - user_error(); - } +\nPhilip Zimmermann, 3021 11th St, Boulder CO 80304 USA, \ +phone +1 303 541-0140\n")); + if (strcmp((p = LANG("@translator@")), "@translator@")) + fprintf(pgpout, p); + fprintf(pgpout, LANG("\nFor a usage summary, type: pgp -h\n")); + exit(BAD_ARG_ERROR); /* error exit */ } - - if (strlen(inputfile) >= (unsigned) MAX_PATH-4) { - fprintf(pgpout, LANG("\007Invalid filename: [%s] too long\n"), inputfile ); - errorLvl = INVALID_FILE_ERROR; - user_error(); - } - strcpy(plainfile, inputfile); - + } else { if (filter_mode) { - setoutdir(NULL); /* NULL means use tmpdir */ + recipient = &myArgv[2]; } else { - if (outputfile) - setoutdir(outputfile); - else - setoutdir(inputfile); + inputfile = myArgv[2]; + recipient = &myArgv[3]; } + } - if (filter_mode) { - workfile = tempfile(TMP_WIPE|TMP_TMPDIR); - readPhantomInput(workfile); - } else { - workfile = inputfile; - } - get_header_info_from_file( workfile, &ctb, 1 ); - if (decrypt_mode) { - strip_spaces = FALSE; - if (!is_ctb(ctb) && is_armor_file(workfile, 0L)) - do_armorfile(workfile); - else - if (do_decrypt(workfile) < 0) - user_error(); - if (batchmode && !signature_checked) - exitPGP(1); /* alternate success, file did not have sig. */ - else - exitPGP(EXIT_OK); - } + if (filter_mode) { + inputfile = "stdin"; + } else { + if (decrypt_mode && no_extension(inputfile)) { + strcpy(cipherfile, inputfile); + force_extension(cipherfile, ASC_EXTENSION); + if (file_exists(cipherfile)) { + inputfile = cipherfile; + } else { + force_extension(cipherfile, PGP_EXTENSION); + if (file_exists(cipherfile)) { + inputfile = cipherfile; + } else { + force_extension(cipherfile, SIG_EXTENSION); + if (file_exists(cipherfile)) + inputfile = cipherfile; + } + } + } + if (!file_exists(inputfile)) { + fprintf(pgpout, + LANG("\007File [%s] does not exist.\n"), inputfile); + errorLvl = FILE_NOT_FOUND_ERROR; + user_error(); + } + } + + if (strlen(inputfile) >= (unsigned) MAX_PATH - 4) { + fprintf(pgpout, + LANG("\007Invalid filename: [%s] too long\n"), inputfile); + errorLvl = INVALID_FILE_ERROR; + user_error(); + } + strcpy(plainfile, inputfile); - /* - * See if plaintext input file was actually created by PGP earlier-- - * If it was, maybe we should NOT encapsulate it in a literal packet. - * Otherwise, always encapsulate it. - */ - if (force_flag) /* for use with batchmode, force nesting */ - nestflag = legal_ctb(ctb); + if (filter_mode) { + setoutdir(NULL); /* NULL means use tmpdir */ + } else { + if (outputfile) + setoutdir(outputfile); else - nestflag = FALSE; /* First assume we will encapsulate it. */ + setoutdir(inputfile); + } - if (!batchmode && !filter_mode && legal_ctb(ctb)) { - /* Special case--may be a PGP-created packet, so - do we inhibit encapsulation in literal packet? */ - fprintf(pgpout, LANG("\n\007Input file '%s' looks like it may have been created by PGP. "), - inputfile ); - fprintf(pgpout, LANG("\nIs it safe to assume that it was created by PGP (y/N)? ")); - nestflag = getyesno('n'); - } /* Possible ciphertext input file */ - - if (moreflag) { /* special name to cause printout on decrypt */ - strcpy (literal_file_name, CONSOLE_FILENAME); - literal_mode = MODE_TEXT; /* will check for text file later */ - } else { - strcpy (literal_file_name, inputfile); + if (filter_mode) { + workfile = tempfile(TMP_WIPE | TMP_TMPDIR); + readPhantomInput(workfile); + } else { + workfile = inputfile; + } + + get_header_info_from_file(workfile, &ctb, 1); + if (decrypt_mode) { + strip_spaces = FALSE; + if (!is_ctb(ctb) && is_armor_file(workfile, 0L)) + do_armorfile(workfile); + else if (do_decrypt(workfile) < 0) + user_error(); + if (batchmode && !signature_checked) + exitPGP(1); /* alternate success, file did not have sig. */ + else + exitPGP(EXIT_OK); + } + /* + * See if plaintext input file was actually created by PGP earlier-- + * If it was, maybe we should NOT encapsulate it in a literal packet. + * Otherwise, always encapsulate it. + */ + if (force_flag) /* for use with batchmode, force nesting */ + nestflag = legal_ctb(ctb); + else + nestflag = FALSE; /* First assume we will encapsulate it. */ + + if (!batchmode && !filter_mode && legal_ctb(ctb)) { + /* Special case--may be a PGP-created packet, so + do we inhibit encapsulation in literal packet? */ + fprintf(pgpout, +LANG("\n\007Input file '%s' looks like it may have been created by PGP. "), + inputfile); + fprintf(pgpout, +LANG("\nIs it safe to assume that it was created by PGP (y/N)? ")); + nestflag = getyesno('n'); + } /* Possible ciphertext input file */ + if (moreflag) { /* special name to cause printout on decrypt */ + strcpy(literal_file_name, CONSOLE_FILENAME); + literal_mode = MODE_TEXT; /* will check for text file later */ + } else { + strcpy(literal_file_name, inputfile); #ifdef MSDOS - strlwr (literal_file_name); + strlwr(literal_file_name); #endif - } - literal_file = literal_file_name; - - /* Make sure non-text files are not accidentally converted - to canonical text. This precaution should only be followed - for US ASCII text files, since European text files may have - 8-bit character codes and still be legitimate text files - suitable for conversion to canonical (CR/LF-terminated) - text format. */ - if (literal_mode==MODE_TEXT && !is_text_file(workfile)) { - fprintf(pgpout, -LANG("\nNote: '%s' is not a pure text file.\nFile will be treated as binary data.\n"), - workfile); - literal_mode = MODE_BINARY; /* now expect straight binary */ - } - - if (moreflag && literal_mode==MODE_BINARY) { /* For eyes only? Can't display binary file. */ - fprintf(pgpout, - LANG("\n\007Error: Only text files may be sent as display-only.\n")); - errorLvl = INVALID_FILE_ERROR; - user_error(); - } - - - /* See if plainfile looks like it might be incompressible, - by examining its contents for compression headers for - commonly-used compressed file formats like PKZIP, etc. - Remember this information for later, when we are deciding - whether to attempt compression before encryption. - */ - attempt_compression = compress_enabled && file_compressible(plainfile); - + } + literal_file = literal_file_name; - if (sign_flag) { - if (!filter_mode && !quietmode) - fprintf(pgpout, LANG("\nA secret key is required to make a signature. ")); - if (!quietmode && my_name[0] == '\0') { - fprintf(pgpout, LANG("\nYou specified no user ID to select your secret key,\n\ + /* Make sure non-text files are not accidentally converted + to canonical text. This precaution should only be followed + for US ASCII text files, since European text files may have + 8-bit character codes and still be legitimate text files + suitable for conversion to canonical (CR/LF-terminated) + text format. */ + if (literal_mode == MODE_TEXT && !is_text_file(workfile)) { + fprintf(pgpout, +LANG("\nNote: '%s' is not a pure text file.\n\ +File will be treated as binary data.\n"), + workfile); + literal_mode = MODE_BINARY; /* now expect straight binary */ + } + if (moreflag && literal_mode == MODE_BINARY) { /* For eyes only? + Can't display + binary file. */ + fprintf(pgpout, +LANG("\n\007Error: Only text files may be sent as display-only.\n")); + errorLvl = INVALID_FILE_ERROR; + user_error(); + } + /* See if plainfile looks like it might be incompressible, + by examining its contents for compression headers for + commonly-used compressed file formats like PKZIP, etc. + Remember this information for later, when we are deciding + whether to attempt compression before encryption. + */ + attempt_compression = compress_enabled && file_compressible(plainfile); + + + if (sign_flag) { + if (!filter_mode && !quietmode) + fprintf(pgpout, +LANG("\nA secret key is required to make a signature. ")); + if (!quietmode && my_name[0] == '\0') { + fprintf(pgpout, +LANG("\nYou specified no user ID to select your secret key,\n\ so the default user ID and key will be the most recently\n\ added key on your secret keyring.\n")); - } - - strip_spaces = FALSE; - clearfile = NULL; - if (literal_mode==MODE_TEXT) { - /* Text mode requires becoming canonical */ - tempf = tempfile(TMP_WIPE|TMP_TMPDIR); - /* +clear means output file with signature in the clear, - only in combination with -t and -a, not with -e or -b */ - if (!encrypt_flag && !separate_signature && - emit_radix_64 && clear_signatures) { - clearfile = workfile; - strip_spaces = TRUE; - } - make_canonical( workfile, tempf ); - if (!clearfile) - rmtemp(workfile); - workfile = tempf; - } - if ((emit_radix_64 || encrypt_flag) && !separate_signature) - tempf = tempfile(TMP_WIPE|TMP_TMPDIR); - else - tempf = tempfile(TMP_WIPE); - /* for clear signatures we create a separate signature */ - status = signfile(nestflag, separate_signature || (clearfile != NULL), - my_name, workfile, tempf, literal_mode, literal_file ); - rmtemp(workfile); - workfile = tempf; - - if (status < 0) { /* signfile failed */ - fprintf(pgpout, LANG("\007Signature error\n") ); - errorLvl = SIGNATURE_ERROR; - user_error(); - } - /* - * We used to compress signed files only if they were also - * armored. Now that we have clear signatures it makes more - * sense to always compress signature files. - */ - if (attempt_compression && !separate_signature && !encrypt_flag - && !clearfile) - { - tempf = tempfile(TMP_WIPE|TMP_TMPDIR); - squish_file(workfile, tempf); - rmtemp(workfile); - workfile = tempf; - } - - } else if (!nestflag) { /* !sign_file */ - /* Prepend CTB_LITERAL byte to plaintext file. - --sure wish this pass could be optimized away. */ - tempf = tempfile(TMP_WIPE); - status = make_literal( workfile, tempf, literal_mode, literal_file ); - rmtemp(workfile); - workfile = tempf; } - - if (encrypt_flag) { - tempf = tempfile(TMP_WIPE); - if (!conventional_flag) { - if (!filter_mode && !quietmode) - fprintf(pgpout, LANG("\n\nRecipients' public key(s) will be used to encrypt. ")); - if (recipient == NULL || *recipient == NULL || **recipient == '\0') - { - /* no recipient specified on command line */ - fprintf(pgpout, LANG("\nA user ID is required to select the recipient's public key. ")); - fprintf(pgpout, LANG("\nEnter the recipient's user ID: ")); - getstring( mcguffin, 255, TRUE ); /* echo keyboard */ - if ((mcguffins = (char **) malloc (2 * sizeof(char *))) == NULL) { - fprintf(stderr, LANG("\n\007Out of memory.\n")); - exitPGP(7); - } - mcguffins[0] = mcguffin; - mcguffins[1] = ""; - } else { - /* recipient specified on command line */ - mcguffins = recipient; - } - for (recipient = mcguffins; *recipient != NULL && - **recipient != '\0'; recipient++) { - CONVERT_TO_CANONICAL_CHARSET(*recipient); - } - status = encryptfile( mcguffins, workfile, tempf, attempt_compression); - } else { - status = idea_encryptfile( workfile, tempf, attempt_compression); - } - + strip_spaces = FALSE; + clearfile = NULL; + if (literal_mode == MODE_TEXT) { + /* Text mode requires becoming canonical */ + tempf = tempfile(TMP_WIPE | TMP_TMPDIR); + /* +clear means output file with signature in the clear, + only in combination with -t and -a, not with -e or -b */ + if (!encrypt_flag && !separate_signature && + emit_radix_64 && clear_signatures) { + clearfile = workfile; + strip_spaces = TRUE; + } + make_canonical(workfile, tempf); + if (!clearfile) rmtemp(workfile); - workfile = tempf; - - if (status < 0) { - fprintf(pgpout, LANG("\007Encryption error\n") ); - errorLvl = (conventional_flag ? ENCR_ERROR : RSA_ENCR_ERROR); - user_error(); - } - } /* encrypt file */ + workfile = tempf; + } + if ((emit_radix_64 || encrypt_flag) && !separate_signature) + tempf = tempfile(TMP_WIPE | TMP_TMPDIR); + else + tempf = tempfile(TMP_WIPE); + /* for clear signatures we create a separate signature */ + status = signfile(nestflag, separate_signature || (clearfile != NULL), + my_name, workfile, tempf, literal_mode, literal_file); + rmtemp(workfile); + workfile = tempf; + + if (status < 0) { /* signfile failed */ + fprintf(pgpout, LANG("\007Signature error\n")); + errorLvl = SIGNATURE_ERROR; + user_error(); + } + /* + * We used to compress signed files only if they were also + * armored. Now that we have clear signatures it makes more + * sense to always compress signature files. + */ + if (attempt_compression && !separate_signature && !encrypt_flag + && !clearfile) { + tempf = tempfile(TMP_WIPE | TMP_TMPDIR); + squish_file(workfile, tempf); + rmtemp(workfile); + workfile = tempf; + } + } else if (!nestflag) { /* !sign_file */ + /* Prepend CTB_LITERAL byte to plaintext file. + --sure wish this pass could be optimized away. */ + tempf = tempfile(TMP_WIPE); + status = make_literal(workfile, tempf, literal_mode, literal_file); + rmtemp(workfile); + workfile = tempf; + } + if (encrypt_flag) { + tempf = tempfile(TMP_WIPE); + if (!conventional_flag) { + if (!filter_mode && !quietmode) + fprintf(pgpout, +LANG("\n\nRecipients' public key(s) will be used to encrypt. ")); + if (recipient == NULL || *recipient == NULL || + **recipient == '\0') { + /* no recipient specified on command line */ + fprintf(pgpout, +LANG("\nA user ID is required to select the recipient's public key. ")); + fprintf(pgpout, LANG("\nEnter the recipient's user ID: ")); + getstring(mcguffin, 255, TRUE); /* echo keyboard */ + if ((mcguffins = (char **) malloc(2 * sizeof(char *))) + == NULL) { + fprintf(stderr, LANG("\n\007Out of memory.\n")); + exitPGP(7); + } + mcguffins[0] = mcguffin; + mcguffins[1] = ""; + } else { + /* recipient specified on command line */ + mcguffins = recipient; + } + for (recipient = mcguffins; *recipient != NULL && + **recipient != '\0'; recipient++) { + CONVERT_TO_CANONICAL_CHARSET(*recipient); + } + status = encryptfile(mcguffins, workfile, tempf, + attempt_compression); + } else { + status = idea_encryptfile(workfile, tempf, attempt_compression); + } - if (outputfile) /* explicit output file overrides filter mode */ - filter_mode = (strcmp(outputfile, "-") == 0); + rmtemp(workfile); + workfile = tempf; - if (filter_mode) { - if (emit_radix_64) { - /* NULL for outputfile means write to stdout */ - if (armor_file(workfile, NULL, inputfile, clearfile) != 0) - { - errorLvl = UNKNOWN_FILE_ERROR; - user_error(); - } - if (clearfile) - rmtemp(clearfile); - } else { - if (writePhantomOutput(workfile) < 0) { - errorLvl = UNKNOWN_FILE_ERROR; - user_error(); - } - } - rmtemp(workfile); + if (status < 0) { + fprintf(pgpout, LANG("\007Encryption error\n")); + errorLvl = (conventional_flag ? ENCR_ERROR : RSA_ENCR_ERROR); + user_error(); + } + } /* encrypt file */ + if (outputfile) /* explicit output file overrides + filter mode */ + filter_mode = (strcmp(outputfile, "-") == 0); + + if (filter_mode) { + if (emit_radix_64) { + /* NULL for outputfile means write to stdout */ + if (armor_file(workfile, NULL, inputfile, clearfile) != 0) { + errorLvl = UNKNOWN_FILE_ERROR; + user_error(); + } + if (clearfile) + rmtemp(clearfile); } else { - char name[MAX_PATH]; - if (outputfile) { - strcpy(name, outputfile); - } else { - strcpy(name, inputfile); - drop_extension(name); - } - if (no_extension(name)) { - if (emit_radix_64) - force_extension(name, ASC_EXTENSION); - else if (sign_flag && separate_signature) - force_extension(name, SIG_EXTENSION); - else - force_extension(name, PGP_EXTENSION); - } - if (emit_radix_64) { - if (armor_file(workfile, name, inputfile, clearfile) != 0) - { - errorLvl = UNKNOWN_FILE_ERROR; - user_error(); - } - if (clearfile) - rmtemp(clearfile); - } else { - if ((outputfile = savetemp(workfile, name)) == NULL) { - errorLvl = UNKNOWN_FILE_ERROR; - user_error(); - } - if (!quietmode) { - if (encrypt_flag) - fprintf(pgpout, LANG("\nCiphertext file: %s\n"), outputfile); - else if (sign_flag) - fprintf(pgpout, LANG("\nSignature file: %s\n"), outputfile); - } - } + if (writePhantomOutput(workfile) < 0) { + errorLvl = UNKNOWN_FILE_ERROR; + user_error(); + } } - - if (wipeflag) { - /* destroy every trace of plaintext */ - if (wipefile(inputfile) == 0) { - remove(inputfile); - fprintf(pgpout,LANG("\nFile %s wiped and deleted. "),inputfile); - fprintf(pgpout, "\n"); - } + rmtemp(workfile); + } else { + char name[MAX_PATH]; + if (outputfile) { + strcpy(name, outputfile); + } else { + strcpy(name, inputfile); + drop_extension(name); } - - exitPGP(EXIT_OK); - return 0; /* to shut up lint and some compilers */ -} /* main */ + if (no_extension(name)) { + if (emit_radix_64) + force_extension(name, ASC_EXTENSION); + else if (sign_flag && separate_signature) + force_extension(name, SIG_EXTENSION); + else + force_extension(name, PGP_EXTENSION); + } + if (emit_radix_64) { + if (armor_file(workfile, name, inputfile, clearfile) != 0) { + errorLvl = UNKNOWN_FILE_ERROR; + user_error(); + } + if (clearfile) + rmtemp(clearfile); + } else { + if ((outputfile = savetemp(workfile, name)) == NULL) { + errorLvl = UNKNOWN_FILE_ERROR; + user_error(); + } + if (!quietmode) { + if (encrypt_flag) + fprintf(pgpout, + LANG("\nCiphertext file: %s\n"), outputfile); + else if (sign_flag) + fprintf(pgpout, + LANG("\nSignature file: %s\n"), outputfile); + } + } + } + + if (wipeflag) { + /* destroy every trace of plaintext */ + if (wipefile(inputfile) == 0) { + remove(inputfile); + fprintf(pgpout, LANG("\nFile %s wiped and deleted. "), inputfile); + fprintf(pgpout, "\n"); + } + } + exitPGP(EXIT_OK); + return 0; /* to shut up lint and some compilers */ +} /* main */ #ifdef MSDOS #include -static char *dos_errlst[] = { - "Write protect error", /* LANG ("Write protect error") */ - "Unknown unit", - "Drive not ready", /* LANG ("Drive not ready") */ - "3", "4", "5", "6", "7", "8", "9", - "Write error", /* LANG ("Write error") */ - "Read error", /* LANG ("Read error") */ - "General failure", +static char *dos_errlst[] = +{ + "Write protect error", /* LANG ("Write protect error") */ + "Unknown unit", + "Drive not ready", /* LANG ("Drive not ready") */ + "3", "4", "5", "6", "7", "8", "9", + "Write error", /* LANG ("Write error") */ + "Read error", /* LANG ("Read error") */ + "General failure", }; /* handler for msdos 'harderrors' */ #ifndef OS2 -#ifdef __TURBOC__ /* Turbo C 2.0 */ +#ifdef __TURBOC__ /* Turbo C 2.0 */ static int dostrap(int errval) #else static void dostrap(unsigned deverr, unsigned errval) #endif { - char errbuf[64]; - int i; - sprintf(errbuf, "\r\nDOS error: %s\r\n", dos_errlst[errval]); - i = 0; - do - bdos(2,(unsigned int)errbuf[i],0); - while (errbuf[++i]); + char errbuf[64]; + int i; + sprintf(errbuf, "\r\nDOS error: %s\r\n", dos_errlst[errval]); + i = 0; + do + bdos(2, (unsigned int) errbuf[i], 0); + while (errbuf[++i]); #ifdef __TURBOC__ - return 0; /* ignore (fopen will return NULL) */ + return 0; /* ignore (fopen will return NULL) */ #else - return; + return; #endif } -#endif /* MSDOS */ +#endif /* MSDOS */ #endif static void initsigs() @@ -1053,468 +1107,480 @@ static void initsigs() #ifdef MSDOS #ifndef OS2 #ifdef __TURBOC__ - harderr(dostrap); -#else /* MSC */ -#ifndef __GNUC__ /* DJGPP's not MSC */ - _harderr(dostrap); + harderr(dostrap); +#else /* MSC */ +#ifndef __GNUC__ /* DJGPP's not MSC */ + _harderr(dostrap); #endif #endif #endif -#endif /* MSDOS */ +#endif /* MSDOS */ #ifdef SIGINT #ifdef ATARI - signal(SIGINT,(sigfunc_t) breakHandler); + signal(SIGINT, (sigfunc_t) breakHandler); #else - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT,breakHandler); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, breakHandler); #if defined(UNIX) || defined(VMS) - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP,breakHandler); - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT,breakHandler); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, breakHandler); + if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) + signal(SIGQUIT, breakHandler); #ifdef UNIX - signal(SIGPIPE,breakHandler); + signal(SIGPIPE, breakHandler); #endif - signal(SIGTERM,breakHandler); + signal(SIGTERM, breakHandler); #ifndef DEBUG - signal(SIGTRAP,breakHandler); - signal(SIGSEGV,breakHandler); - signal(SIGILL,breakHandler); + signal(SIGTRAP, breakHandler); + signal(SIGSEGV, breakHandler); + signal(SIGILL, breakHandler); #ifdef SIGBUS - signal(SIGBUS,breakHandler); + signal(SIGBUS, breakHandler); #endif -#endif /* DEBUG */ -#endif /* UNIX */ -#endif /* not Atari */ -#endif /* SIGINT */ -} /* initsigs */ +#endif /* DEBUG */ +#endif /* UNIX */ +#endif /* not Atari */ +#endif /* SIGINT */ +} /* initsigs */ static void do_armorfile(char *armorfile) { - char *tempf; - char cipherfile[MAX_PATH]; - long linepos = 0; - int status; - int success = 0; - - for (;;) { - /* Handle transport armor stripping */ - tempf = tempfile(0); - strip_spaces = FALSE; /* de_armor_file() sets this for clear signature files */ - status = de_armor_file(armorfile,tempf,&linepos); - if (status) { - fprintf(pgpout,LANG("\n\007Error: Transport armor stripping failed for file %s\n"),armorfile); - errorLvl = INVALID_FILE_ERROR; - user_error(); /* Bad file */ - } - if (keepctx || de_armor_only) { - if (outputfile && de_armor_only) { - if (strcmp(outputfile, "-") == 0) { - writePhantomOutput(tempf); - rmtemp(tempf); - return; - } - strcpy(cipherfile, outputfile); - } else { - strcpy(cipherfile, file_tail(armorfile)); - force_extension(cipherfile, PGP_EXTENSION); - } - if ((tempf = savetemp(tempf, cipherfile)) == NULL) { - errorLvl = UNKNOWN_FILE_ERROR; - user_error(); - } - if (!quietmode) - fprintf(pgpout,LANG("Stripped transport armor from '%s', producing '%s'.\n"), - armorfile, tempf); - /* -da flag: don't decrypt */ - if (de_armor_only || do_decrypt(tempf) >= 0) - ++success; - } else { - if (do_decrypt(tempf) >= 0) - ++success; - rmtemp(tempf); - } - - if (!is_armor_file(armorfile, linepos)) { - if (!success) /* print error msg if we didn't decrypt anything */ - user_error(); - return; - } + char *tempf; + char cipherfile[MAX_PATH]; + long linepos = 0; + int status; + int success = 0; + + for (;;) { + /* Handle transport armor stripping */ + tempf = tempfile(0); + strip_spaces = FALSE; /* de_armor_file() sets + this for clear signature files */ + status = de_armor_file(armorfile, tempf, &linepos); + if (status) { + fprintf(pgpout, +LANG("\n\007Error: Transport armor stripping failed for file %s\n"), + armorfile); + errorLvl = INVALID_FILE_ERROR; + user_error(); /* Bad file */ + } + if (keepctx || de_armor_only) { + if (outputfile && de_armor_only) { + if (strcmp(outputfile, "-") == 0) { + writePhantomOutput(tempf); + rmtemp(tempf); + return; + } + strcpy(cipherfile, outputfile); + } else { + strcpy(cipherfile, file_tail(armorfile)); + force_extension(cipherfile, PGP_EXTENSION); + } + if ((tempf = savetemp(tempf, cipherfile)) == NULL) { + errorLvl = UNKNOWN_FILE_ERROR; + user_error(); + } + if (!quietmode) + fprintf(pgpout, +LANG("Stripped transport armor from '%s', producing '%s'.\n"), + armorfile, tempf); + /* -da flag: don't decrypt */ + if (de_armor_only || do_decrypt(tempf) >= 0) + ++success; + } else { + if (do_decrypt(tempf) >= 0) + ++success; + rmtemp(tempf); + } - fprintf (pgpout, LANG("\nLooking for next packet in '%s'...\n"), armorfile); + if (!is_armor_file(armorfile, linepos)) { + if (!success) /* print error msg if we didn't + decrypt anything */ + user_error(); + return; } -} /* do_armorfile */ + fprintf(pgpout, + LANG("\nLooking for next packet in '%s'...\n"), armorfile); + } +} /* do_armorfile */ static int do_decrypt(char *cipherfile) { - char *outfile = NULL; - int status, i; - boolean nested_info = FALSE; - char ringfile[MAX_PATH]; - byte ctb; - byte header[8]; /* used to classify file type at the end. */ - char preserved_name[MAX_PATH]; - char *newname; - - /* will be set to the original file name after processing a literal packet */ - preserved_name[0] = '\0'; - - do { /* while nested parsable info present */ - if (nested_info) { - rmtemp(cipherfile); /* never executed on first pass */ - cipherfile = outfile; - } - if (get_header_info_from_file( cipherfile, &ctb, 1) < 0) - { - fprintf(pgpout,LANG("\n\007Can't open ciphertext file '%s'\n"),cipherfile); - errorLvl = FILE_NOT_FOUND_ERROR; - return -1; - } + char *outfile = NULL; + int status, i; + boolean nested_info = FALSE; + char ringfile[MAX_PATH]; + byte ctb; + byte header[8]; /* used to classify file type at the end. */ + char preserved_name[MAX_PATH]; + char *newname; + + /* will be set to the original file name after processing a + literal packet */ + preserved_name[0] = '\0'; + + do { /* while nested parsable info present */ + if (nested_info) { + rmtemp(cipherfile); /* never executed on first pass */ + cipherfile = outfile; + } + if (get_header_info_from_file(cipherfile, &ctb, 1) < 0) { + fprintf(pgpout, +LANG("\n\007Can't open ciphertext file '%s'\n"), cipherfile); + errorLvl = FILE_NOT_FOUND_ERROR; + return -1; + } + if (!is_ctb(ctb)) /* not a real CTB -- complain */ + break; - if (!is_ctb(ctb)) /* not a real CTB -- complain */ - break; + if (moreflag) + outfile = tempfile(TMP_WIPE | TMP_TMPDIR); + else + outfile = tempfile(TMP_WIPE); - if (moreflag) - outfile = tempfile(TMP_WIPE|TMP_TMPDIR); - else - outfile = tempfile(TMP_WIPE); + /* PKE is Public Key Encryption */ + if (is_ctb_type(ctb, CTB_PKE_TYPE)) { - /* PKE is Public Key Encryption */ - if (is_ctb_type( ctb, CTB_PKE_TYPE )) { + if (!quietmode) + fprintf(pgpout, +LANG("\nFile is encrypted. Secret key is required to read it. ")); - if (!quietmode) - fprintf(pgpout,LANG("\nFile is encrypted. Secret key is required to read it. ")); + /* Decrypt to scratch file since we may have a LITERAL2 */ + status = decryptfile(cipherfile, outfile); - /* Decrypt to scratch file since we may have a LITERAL2 */ - status = decryptfile( cipherfile, outfile ); - - if (status < 0) { /* error return */ - errorLvl = RSA_DECR_ERROR; - return -1; - } - nested_info = (status > 0); - - } else if (is_ctb_type( ctb, CTB_SKE_TYPE )) { - - if (decrypt_only_flag) { - /* swap file names instead of just copying the file */ - rmtemp(outfile); - outfile = cipherfile; - cipherfile = NULL; - if (!quietmode) - fprintf(pgpout,LANG("\nThis file has a signature, which will be left in place.\n")); - break; /* Do no more */ - } - if (!quietmode) - fprintf(pgpout,LANG("\nFile has signature. Public key is required to check signature. ")); - - status = check_signaturefile( cipherfile, outfile, strip_sig_flag, preserved_name ); - - if (status < 0) { /* error return */ - errorLvl = SIGNATURE_CHECK_ERROR; - return -1; - } - nested_info = (status > 0); - - if (strcmp(preserved_name, "/dev/null") == 0) { - rmtemp(outfile); - fprintf(pgpout, "\n"); - return 0; - } - - } else if (is_ctb_type( ctb, CTB_CKE_TYPE )) { - - /* Conventional Key Encrypted ciphertext. */ - /* Tell user it's encrypted here, and prompt for password in subroutine. */ - if (!quietmode) - fprintf(pgpout,LANG("\nFile is conventionally encrypted. ")); - /* Decrypt to scratch file since it may be a LITERAL2 */ - status = idea_decryptfile( cipherfile, outfile ); - if (status < 0) /* error return */ - { errorLvl = DECR_ERROR; - return -1; /* error exit status */ - } - nested_info = (status > 0); - - } else if (is_ctb_type( ctb, CTB_COMPRESSED_TYPE )) { - - /* Compressed text. */ - status = decompress_file( cipherfile, outfile ); - if (status < 0) { /* error return */ - errorLvl = DECOMPRESS_ERROR; - return -1; - } - /* Always assume nested information... */ - nested_info = TRUE; - - } else if (is_ctb_type( ctb, CTB_LITERAL_TYPE ) || - is_ctb_type( ctb, CTB_LITERAL2_TYPE)) - { /* Raw plaintext. Just copy it. No more nesting. */ - - /* Strip off CTB_LITERAL prefix byte from file: */ - /* strip_literal may alter plainfile; will set mode */ - status = strip_literal( cipherfile, outfile, - preserved_name, &literal_mode); - if (status < 0) { /* error return */ - errorLvl = UNKNOWN_FILE_ERROR; - return -1; - } - nested_info = FALSE; - } else if (ctb==CTB_CERT_SECKEY || ctb==CTB_CERT_PUBKEY) { + if (status < 0) { /* error return */ + errorLvl = RSA_DECR_ERROR; + return -1; + } + nested_info = (status > 0); - rmtemp(outfile); - if (decrypt_only_flag) { - /* swap file names instead of just copying the file */ - outfile = cipherfile; - cipherfile = NULL; - break; /* no further processing */ - } - /* Key ring. View it. */ - fprintf(pgpout, LANG("\nFile contains key(s). Contents follow...") ); - if (view_keyring( NULL, cipherfile, TRUE, FALSE ) < 0) - { - errorLvl = KEYRING_VIEW_ERROR; - return -1; - } - /* filter mode explicit requested with -f */ - if (filter_mode && !preserve_filename) - return 0; /* No output file */ - if (batchmode) - return 0; - if (ctb == CTB_CERT_SECKEY) - strcpy(ringfile, globalSecringName); - else - strcpy(ringfile, globalPubringName); - /* Ask if it should be put on key ring */ - fprintf(pgpout, LANG("\nDo you want to add this keyfile to keyring '%s' (y/N)? "), ringfile); - if (!getyesno('n')) - return 0; - status = addto_keyring(cipherfile,ringfile); - if (status < 0) { - fprintf(pgpout, LANG("\007Keyring add error. ") ); - errorLvl = KEYRING_ADD_ERROR; - return -1; - } - return 0; /* No output file */ + } else if (is_ctb_type(ctb, CTB_SKE_TYPE)) { - } else { /* Unrecognized CTB */ - break; - } + if (decrypt_only_flag) { + /* swap file names instead of just copying the file */ + rmtemp(outfile); + outfile = cipherfile; + cipherfile = NULL; + if (!quietmode) + fprintf(pgpout, +LANG("\nThis file has a signature, which will be left in place.\n")); + nested_info = FALSE; + break; /* Do no more */ + } + if (!quietmode) + fprintf(pgpout, +LANG("\nFile has signature. Public key is required to check signature. ")); - } while (nested_info); - /* No more nested parsable information */ + status = check_signaturefile(cipherfile, outfile, + strip_sig_flag, preserved_name); - /* Stopped early due to error */ - if (nested_info) { - fprintf(pgpout, "\7\nERROR: Nested data has unexpected format. CTB=0x%02X\n", ctb); - if (outfile) - rmtemp(outfile); - if (cipherfile) - rmtemp(cipherfile); - errorLvl = UNKNOWN_FILE_ERROR; + if (status < 0) { /* error return */ + errorLvl = SIGNATURE_CHECK_ERROR; return -1; - } + } + nested_info = (status > 0); - if (outfile == NULL) { /* file was not encrypted */ - if (!filter_mode && !moreflag) { - fprintf(pgpout,LANG("\007\nError: '%s' is not a ciphertext, signature, or key file.\n"), - cipherfile); - errorLvl = UNKNOWN_FILE_ERROR; - return -1; - } - outfile = cipherfile; - } else { - if (cipherfile) - rmtemp(cipherfile); - } - - if (moreflag || (strcmp(preserved_name,CONSOLE_FILENAME) == 0)) { - /* blort to screen */ - if (strcmp(preserved_name,CONSOLE_FILENAME) == 0) { - fprintf(pgpout, - LANG("\n\nThis message is marked \"For your eyes only\". Display now (Y/n)? ")); - if (batchmode || !getyesno('y')) { - /* no -- abort display, and clean up */ - rmtemp(outfile); - return 0; - } - } - if (!quietmode) - fprintf(pgpout, LANG("\n\nPlaintext message follows...\n")); - else - putc('\n', pgpout); - fprintf(pgpout, "------------------------------\n"); - more_file(outfile); - /* Disallow saving to disk if outfile is console-only: */ - if (strcmp(preserved_name,CONSOLE_FILENAME) == 0) { - clearscreen(); /* remove all evidence */ - } else if (!quietmode && !batchmode) { - fprintf(pgpout, LANG("Save this file permanently (y/N)? ")); - if (getyesno('n')) { - char moreFilename[256]; - fprintf(pgpout,LANG("Enter filename to save file as: ")); - if (preserved_name[0]) - fprintf(pgpout, "[%s]: ", file_tail(preserved_name)); - getstring( moreFilename, 255, TRUE ); - if (*moreFilename == '\0') { - if (*preserved_name != '\0') - savetemp (outfile, file_tail(preserved_name)); - else - rmtemp(outfile); - } - else - savetemp (outfile, moreFilename); - return 0; - } - } + if (strcmp(preserved_name, "/dev/null") == 0) { rmtemp(outfile); + fprintf(pgpout, "\n"); return 0; - } /* blort to screen */ + } + } else if (is_ctb_type(ctb, CTB_CKE_TYPE)) { - if (outputfile) { - if (!strcmp(outputfile, "/dev/null")) { - rmtemp(outfile); - return 0; - } - filter_mode = (strcmp(outputfile, "-") == 0); - strcpy(plainfile, outputfile); - } else { -#ifdef VMS - /* VMS null extension has to be ".", not "" */ - force_extension(plainfile, "."); -#else /* not VMS */ - drop_extension(plainfile); -#endif /* not VMS */ + /* Conventional Key Encrypted ciphertext. */ + /* Tell user it's encrypted here, and prompt for + password in subroutine. */ + if (!quietmode) + fprintf(pgpout, LANG("\nFile is conventionally encrypted. ")); + /* Decrypt to scratch file since it may be a LITERAL2 */ + status = idea_decryptfile(cipherfile, outfile); + if (status < 0) { /* error return */ + errorLvl = DECR_ERROR; + return -1; /* error exit status */ + } + nested_info = (status > 0); + + } else if (is_ctb_type(ctb, CTB_COMPRESSED_TYPE)) { + + /* Compressed text. */ + status = decompress_file(cipherfile, outfile); + if (status < 0) { /* error return */ + errorLvl = DECOMPRESS_ERROR; + return -1; + } + /* Always assume nested information... */ + nested_info = TRUE; + + } else if (is_ctb_type(ctb, CTB_LITERAL_TYPE) || + is_ctb_type(ctb, CTB_LITERAL2_TYPE)) { /* Raw plaintext. + Just copy it. + No more nesting. + */ + + /* Strip off CTB_LITERAL prefix byte from file: */ + /* strip_literal may alter plainfile; will set mode */ + status = strip_literal(cipherfile, outfile, + preserved_name, &literal_mode); + if (status < 0) { /* error return */ + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } + nested_info = FALSE; + } else if (ctb == CTB_CERT_SECKEY || ctb == CTB_CERT_PUBKEY) { + + rmtemp(outfile); + if (decrypt_only_flag) { + /* swap file names instead of just copying the file */ + outfile = cipherfile; + cipherfile = NULL; + break; /* no further processing */ + } + /* Key ring. View it. */ + fprintf(pgpout, +LANG("\nFile contains key(s). Contents follow...")); + if (view_keyring(NULL, cipherfile, TRUE, FALSE) < 0) { + errorLvl = KEYRING_VIEW_ERROR; + return -1; + } + /* filter mode explicit requested with -f */ + if (filter_mode && !preserve_filename) + return 0; /* No output file */ + if (batchmode) + return 0; + if (ctb == CTB_CERT_SECKEY) + strcpy(ringfile, globalSecringName); + else + strcpy(ringfile, globalPubringName); + /* Ask if it should be put on key ring */ + fprintf(pgpout, +LANG("\nDo you want to add this keyfile to keyring '%s' (y/N)? "), ringfile); + if (!getyesno('n')) + return 0; + status = addto_keyring(cipherfile, ringfile); + if (status < 0) { + fprintf(pgpout, LANG("\007Keyring add error. ")); + errorLvl = KEYRING_ADD_ERROR; + return -1; + } + return 0; /* No output file */ + + } else { /* Unrecognized CTB */ + break; } - if (!preserve_filename && filter_mode) { - if (writePhantomOutput(outfile) < 0) { - errorLvl = UNKNOWN_FILE_ERROR; - return -1; - } + } while (nested_info); + /* No more nested parsable information */ + + /* Stopped early due to error */ + if (nested_info) { + fprintf(pgpout, +"\7\nERROR: Nested data has unexpected format. CTB=0x%02X\n", ctb); + if (outfile) + rmtemp(outfile); + if (cipherfile) + rmtemp(cipherfile); + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } + if (outfile == NULL) { /* file was not encrypted */ + if (!filter_mode && !moreflag) { + fprintf(pgpout, +LANG("\007\nError: '%s' is not a ciphertext, signature, or key file.\n"), + cipherfile); + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } + outfile = cipherfile; + } else { + if (cipherfile) + rmtemp(cipherfile); + } + + if (moreflag || (strcmp(preserved_name, CONSOLE_FILENAME) == 0)) { + /* blort to screen */ + if (strcmp(preserved_name, CONSOLE_FILENAME) == 0) { + fprintf(pgpout, +LANG("\n\nThis message is marked \"For your eyes only\". Display now \ +(Y/n)? ")); + if (batchmode || !getyesno('y')) { + /* no -- abort display, and clean up */ rmtemp(outfile); return 0; + } } - - if (preserve_filename && preserved_name[0] != '\0') - strcpy(plainfile, file_tail(preserved_name)); - - if (quietmode) { - if (savetemp(outfile, plainfile) == NULL) { - errorLvl = UNKNOWN_FILE_ERROR; - return -1; - } + if (!quietmode) + fprintf(pgpout, LANG("\n\nPlaintext message follows...\n")); + else + putc('\n', pgpout); + fprintf(pgpout, "------------------------------\n"); + more_file(outfile); + /* Disallow saving to disk if outfile is console-only: */ + if (strcmp(preserved_name, CONSOLE_FILENAME) == 0) { + clearscreen(); /* remove all evidence */ + } else if (!quietmode && !batchmode) { + fprintf(pgpout, LANG("Save this file permanently (y/N)? ")); + if (getyesno('n')) { + char moreFilename[256]; + fprintf(pgpout, LANG("Enter filename to save file as: ")); + if (preserved_name[0]) + fprintf(pgpout, "[%s]: ", file_tail(preserved_name)); + getstring(moreFilename, 255, TRUE); + if (*moreFilename == '\0') { + if (*preserved_name != '\0') + savetemp(outfile, file_tail(preserved_name)); + else + rmtemp(outfile); + } else + savetemp(outfile, moreFilename); return 0; + } } - if (!verbose) /* if other filename messages were suppressed */ - fprintf(pgpout,LANG("\nPlaintext filename: %s"), plainfile); - - - /*---------------------------------------------------------*/ - - /* One last thing-- let's attempt to classify some of the more - frequently occurring cases of plaintext output files, as an - aid to the user. - - For example, if output file is a public key, it should have - the right extension on the filename. - - Also, it will likely be common to encrypt files created by - various archivers, so they should be renamed with the archiver - extension. - */ - get_header_info_from_file( outfile, header, 8 ); - - newname = NULL; - if (header[0] == CTB_CERT_PUBKEY) { - /* Special case--may be public key, worth renaming */ - fprintf(pgpout, LANG("\nPlaintext file '%s' looks like it contains a public key."), - plainfile ); - newname = maybe_force_extension( plainfile, PGP_EXTENSION ); - } /* Possible public key output file */ - - else if ((i = compressSignature( header )) >= 0) { - /* Special case--may be an archived/compressed file, worth renaming */ - fprintf(pgpout, LANG("\nPlaintext file '%s' looks like a %s file."), - plainfile, compressName[i] ); - newname = maybe_force_extension( plainfile, compressExt[i] ); - } else if (is_ctb(header[0]) && - ( is_ctb_type (header[0], CTB_PKE_TYPE) - || is_ctb_type (header[0], CTB_SKE_TYPE) - || is_ctb_type (header[0], CTB_CKE_TYPE))) - { - /* Special case--may be another ciphertext file, worth renaming */ - fprintf(pgpout, LANG("\n\007Output file '%s' may contain more ciphertext or signature."), - plainfile ); - newname = maybe_force_extension( plainfile, PGP_EXTENSION ); - } /* Possible ciphertext output file */ - - if (savetemp(outfile, (newname ? newname : plainfile)) == NULL) { - errorLvl = UNKNOWN_FILE_ERROR; - return -1; + rmtemp(outfile); + return 0; + } /* blort to screen */ + if (outputfile) { + if (!strcmp(outputfile, "/dev/null")) { + rmtemp(outfile); + return 0; + } + filter_mode = (strcmp(outputfile, "-") == 0); + strcpy(plainfile, outputfile); + } else { +#ifdef VMS + /* VMS null extension has to be ".", not "" */ + force_extension(plainfile, "."); +#else /* not VMS */ + drop_extension(plainfile); +#endif /* not VMS */ + } + + if (!preserve_filename && filter_mode) { + if (writePhantomOutput(outfile) < 0) { + errorLvl = UNKNOWN_FILE_ERROR; + return -1; } - - fprintf (pgpout, "\n"); + rmtemp(outfile); return 0; -} /* do_decrypt */ - + } + if (preserve_filename && preserved_name[0] != '\0') + strcpy(plainfile, file_tail(preserved_name)); + + if (quietmode) { + if (savetemp(outfile, plainfile) == NULL) { + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } + return 0; + } + if (!verbose) /* if other filename messages were suppressed */ + fprintf(pgpout, LANG("\nPlaintext filename: %s"), plainfile); + + +/*---------------------------------------------------------*/ + + /* One last thing-- let's attempt to classify some of the more + frequently occurring cases of plaintext output files, as an + aid to the user. + + For example, if output file is a public key, it should have + the right extension on the filename. + + Also, it will likely be common to encrypt files created by + various archivers, so they should be renamed with the archiver + extension. + */ + get_header_info_from_file(outfile, header, 8); + + newname = NULL; + if (header[0] == CTB_CERT_PUBKEY) { + /* Special case--may be public key, worth renaming */ + fprintf(pgpout, +LANG("\nPlaintext file '%s' looks like it contains a public key."), + plainfile); + newname = maybe_force_extension(plainfile, PGP_EXTENSION); + } + /* Possible public key output file */ + else if ((i = compressSignature(header)) >= 0) { + /* Special case--may be an archived/compressed file, + worth renaming + */ + fprintf(pgpout, LANG("\nPlaintext file '%s' looks like a %s file."), + plainfile, compressName[i]); + newname = maybe_force_extension(plainfile, compressExt[i]); + } else if (is_ctb(header[0]) && + (is_ctb_type(header[0], CTB_PKE_TYPE) + || is_ctb_type(header[0], CTB_SKE_TYPE) + || is_ctb_type(header[0], CTB_CKE_TYPE))) { + /* Special case--may be another ciphertext file, worth renaming */ + fprintf(pgpout, +LANG("\n\007Output file '%s' may contain more ciphertext or signature."), + plainfile); + newname = maybe_force_extension(plainfile, PGP_EXTENSION); + } /* Possible ciphertext output file */ + if (savetemp(outfile, (newname ? newname : plainfile)) == NULL) { + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } + fprintf(pgpout, "\n"); + return 0; +} /* do_decrypt */ static int do_keyopt(char keychar) { - char keyfile[MAX_PATH]; - char ringfile[MAX_PATH]; - char *workfile; - int status; - - if ((filter_mode || batchmode) - && (keychar == 'g' || keychar == 'e' || keychar == 'd' - || (keychar == 'r' && sign_flag))) - { - errorLvl = NO_BATCH; - arg_error(); /* interactive process, no go in batch mode */ - } + char keyfile[MAX_PATH]; + char ringfile[MAX_PATH]; + char *workfile; + int status; + + if ((filter_mode || batchmode) + && (keychar == 'g' || keychar == 'e' || keychar == 'd' + || (keychar == 'r' && sign_flag))) { + errorLvl = NO_BATCH; + arg_error(); /* interactive process, no go in batch mode */ + } + /* + * If we're not doing anything that uses stdout, produce output there, + * in case user wants to redirect it. + */ + if (!filter_mode) + pgpout = stdout; + + switch (keychar) { + +/*-------------------------------------------------------*/ + case 'g': + { /* Key generation + Arguments: bitcount, bitcount + */ + char keybits[6], ebits[6]; + + /* + * Why all this code? + * + * Some dimwits have been distributing versions of + * PGP (especially on MS-DOS) without the manuals. + * This frustrates users (who call Philip Zimmermann + * at all hours of the day and night), and in + * addition to depriving them of instructions on how + * to operate the program, also deprives them of + * IMPORTANT legal notices. This is a Bad Thing, so + * we've gone to the trouble of being fascist and + * *forcing* the manuals to be there. The +nomanual + * flag (documented only in the manual) lets you + * overrride this if desired. + */ - /* - * If we're not doing anything that uses stdout, produce output there, - * in case user wants to redirect it. - */ - if (!filter_mode) - pgpout = stdout; - - switch (keychar) { - - /*-------------------------------------------------------*/ - case 'g': - { /* Key generation - Arguments: bitcount, bitcount - */ - char keybits[6], ebits[6]; - - /* - * Why all this code? - * - * Some dimwits have been distributing versions of PGP (especially on - * MS-DOS) without the manuals. This frustrates users (who call - * Philip Zimmermann at all hours of the day and night), and in - * addition to depriving them of instructions on how to operate the - * program, also deprives them of IMPORTANT legal notices. This is - * a Bad Thing, so we've gone to the trouble of being fascist and - * *forcing* the manuals to be there. - * - * The +nomanual flag (documented only in the manual) lets you - * overrride this if desired. - */ - - if (!nomanual && manuals_missing()) { - char const * const *dir; + if (!nomanual && manuals_missing()) { + char const *const *dir; - fputs(LANG("\a\nError: PGP User's Guide not found.\n\ + fputs(LANG("\a\nError: PGP User's Guide not found.\n\ PGP looked for it in the following directories:\n"), pgpout); - for (dir = manual_dirs; *dir; dir++) - fprintf(pgpout, "\t\"%s\"\n", *dir); - fputs(LANG("and the doc subdirectory of each of the above. Please put a copy of\n\ + for (dir = manual_dirs; *dir; dir++) + fprintf(pgpout, "\t\"%s\"\n", *dir); + fputs( +LANG("and the doc subdirectory of each of the above. Please put a copy of\n\ both volumes of the User's Guide in one of these directories.\n\ \n\ Under NO CIRCUMSTANCES should PGP ever be distributed without the PGP\n\ @@ -1525,513 +1591,526 @@ distributed further.\n\ \n\ PGP will not generate a key without finding the User's Guide.\n\ \n"), pgpout); - return KEYGEN_ERROR; - } - - if (myArgc > 2) - strncpy( keybits, myArgv[2], sizeof(keybits)-1 ); - else - keybits[0] = '\0'; - - if (myArgc > 3) - strncpy( ebits, myArgv[3], sizeof(ebits)-1 ); - else - ebits[0] = '\0'; - - /* dokeygen writes the keys out to the key rings... */ - status = dokeygen(keybits, ebits); - - if (status < 0) { - fprintf(pgpout, LANG("\007Keygen error. ") ); - errorLvl = KEYGEN_ERROR; - } - return status; - } /* Key generation */ - - /*-------------------------------------------------------*/ - case 'c': - { /* Key checking - Arguments: userid, ringfile - */ - - if (myArgc < 3) { /* Default to all user ID's */ - mcguffin[0] = '\0'; - } else { - strcpy ( mcguffin, myArgv[2] ); - if (strcmp( mcguffin, "*" ) == 0) - mcguffin[0] = '\0'; - } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); - - if (myArgc < 4) /* default key ring filename */ - strcpy(ringfile, globalPubringName); - else - strncpy( ringfile, myArgv[3], sizeof(ringfile)-1 ); - - if ((myArgc < 4 && myArgc > 2) /* Allow just key file as arg */ - && has_extension( myArgv[2], PGP_EXTENSION ) ) - { - strcpy( ringfile, myArgv[2] ); - mcguffin[0] = '\0'; - } - - status = dokeycheck( mcguffin, ringfile, CHECK_ALL ); - - if (status < 0) { - fprintf(pgpout, LANG("\007Keyring check error.\n") ); - errorLvl = KEYRING_CHECK_ERROR; - } - if (status >= 0 && mcguffin[0] != '\0') - return status; /* just checking a single user, dont do maintenance */ - - if ((status = maint_check(ringfile, 0)) < 0 && status != -7) { - fprintf(pgpout, LANG("\007Maintenance pass error. ") ); - errorLvl = KEYRING_CHECK_ERROR; - } - - return status == -7 ? 0 : status; - } /* Key check */ - - /*-------------------------------------------------------*/ - case 'm': - { /* Maintenance pass - Arguments: ringfile - */ - - if (myArgc < 3) /* default key ring filename */ - strcpy(ringfile, globalPubringName); - else - strcpy( ringfile, myArgv[2] ); + return KEYGEN_ERROR; + } + if (myArgc > 2) + strncpy(keybits, myArgv[2], sizeof(keybits) - 1); + else + keybits[0] = '\0'; + + if (myArgc > 3) + strncpy(ebits, myArgv[3], sizeof(ebits) - 1); + else + ebits[0] = '\0'; + + /* dokeygen writes the keys out to the key rings... */ + status = dokeygen(keybits, ebits); + + if (status < 0) { + fprintf(pgpout, LANG("\007Keygen error. ")); + errorLvl = KEYGEN_ERROR; + } + return status; + } /* Key generation */ + +/*-------------------------------------------------------*/ + case 'c': + { /* Key checking + Arguments: userid, ringfile + */ + + if (myArgc < 3) { /* Default to all user ID's */ + mcguffin[0] = '\0'; + } else { + strcpy(mcguffin, myArgv[2]); + if (strcmp(mcguffin, "*") == 0) + mcguffin[0] = '\0'; + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); + + if (myArgc < 4) /* default key ring filename */ + strcpy(ringfile, globalPubringName); + else + strncpy(ringfile, myArgv[3], sizeof(ringfile) - 1); + + if ((myArgc < 4 && myArgc > 2) /* Allow just key file as arg */ + &&has_extension(myArgv[2], PGP_EXTENSION)) { + strcpy(ringfile, myArgv[2]); + mcguffin[0] = '\0'; + } + status = dokeycheck(mcguffin, ringfile, CHECK_ALL); + + if (status < 0) { + fprintf(pgpout, LANG("\007Keyring check error.\n")); + errorLvl = KEYRING_CHECK_ERROR; + } + if (status >= 0 && mcguffin[0] != '\0') + return status; /* just checking a single user, + dont do maintenance */ + + if ((status = maint_check(ringfile, 0)) < 0 && status != -7) { + fprintf(pgpout, LANG("\007Maintenance pass error. ")); + errorLvl = KEYRING_CHECK_ERROR; + } + return status == -7 ? 0 : status; + } /* Key check */ + +/*-------------------------------------------------------*/ + case 'm': + { /* Maintenance pass + Arguments: ringfile + */ + + if (myArgc < 3) /* default key ring filename */ + strcpy(ringfile, globalPubringName); + else + strcpy(ringfile, myArgv[2]); #ifdef MSDOS - strlwr( ringfile ); + strlwr(ringfile); #endif - if (! file_exists( ringfile )) - default_extension( ringfile, PGP_EXTENSION ); - - if ((status = maint_check(ringfile, - MAINT_VERBOSE|(c_flag ? MAINT_CHECK : 0))) < 0) - { - if (status == -7) - fprintf(pgpout, LANG("File '%s' is not a public keyring\n"), ringfile); - fprintf(pgpout, LANG("\007Maintenance pass error. ") ); - errorLvl = KEYRING_CHECK_ERROR; - } - return status; - } /* Maintenance pass */ + if (!file_exists(ringfile)) + default_extension(ringfile, PGP_EXTENSION); - /*-------------------------------------------------------*/ - case 's': - { /* Key signing - Arguments: her_id, keyfile - */ - - if (myArgc >= 4) - strncpy( keyfile, myArgv[3], sizeof(keyfile)-1 ); - else - strcpy(keyfile, globalPubringName); - - if (myArgc >= 3) { - strcpy( mcguffin, myArgv[2] ); /* Userid to sign */ - } else { - fprintf(pgpout, LANG("\nA user ID is required to select the public key you want to sign. ")); - if (batchmode) /* not interactive, userid must be on command line */ - return -1; - fprintf(pgpout, LANG("\nEnter the public key's user ID: ")); - getstring( mcguffin, 255, TRUE ); /* echo keyboard */ - } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); - - if (my_name[0] == '\0') { - fprintf(pgpout, LANG("\nA secret key is required to make a signature. ")); - fprintf(pgpout, LANG("\nYou specified no user ID to select your secret key,\n\ + if ((status = maint_check(ringfile, + MAINT_VERBOSE | (c_flag ? MAINT_CHECK : 0))) < 0) { + if (status == -7) + fprintf(pgpout, + LANG("File '%s' is not a public keyring\n"), + ringfile); + fprintf(pgpout, LANG("\007Maintenance pass error. ")); + errorLvl = KEYRING_CHECK_ERROR; + } + return status; + } /* Maintenance pass */ + +/*-------------------------------------------------------*/ + case 's': + { /* Key signing + Arguments: her_id, keyfile + */ + + if (myArgc >= 4) + strncpy(keyfile, myArgv[3], sizeof(keyfile) - 1); + else + strcpy(keyfile, globalPubringName); + + if (myArgc >= 3) { + strcpy(mcguffin, myArgv[2]); /* Userid to sign */ + } else { + fprintf(pgpout, +LANG("\nA user ID is required to select the public key you want to sign. ")); + if (batchmode) /* not interactive, userid + must be on command line */ + return -1; + fprintf(pgpout, LANG("\nEnter the public key's user ID: ")); + getstring(mcguffin, 255, TRUE); /* echo keyboard */ + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); + + if (my_name[0] == '\0') { + fprintf(pgpout, +LANG("\nA secret key is required to make a signature. ")); + fprintf(pgpout, +LANG("\nYou specified no user ID to select your secret key,\n\ so the default user ID and key will be the most recently\n\ added key on your secret keyring.\n")); - } - - status = signkey ( mcguffin, my_name, keyfile ); - - if (status >= 0) { - status = maint_update(keyfile, 0); - if (status == -7) { /* ringfile is a keyfile or secret keyring */ - fprintf(pgpout, "Warning: '%s' is not a public keyring\n", keyfile); - return 0; - } - if (status < 0) - fprintf(pgpout, LANG("\007Maintenance pass error. ") ); - } - - if (status < 0) { - fprintf(pgpout, LANG("\007Key signature error. ") ); - errorLvl = KEY_SIGNATURE_ERROR; - } - return status; - } /* Key signing */ - - - /*-------------------------------------------------------*/ - case 'd': - { /* disable/revoke key - Arguments: userid, keyfile - */ - - if (myArgc >= 4) - strncpy( keyfile, myArgv[3], sizeof(keyfile)-1 ); - else - strcpy(keyfile, globalPubringName); - - if (myArgc >= 3) { - strcpy( mcguffin, myArgv[2] ); /* Userid to sign */ - } else { - fprintf(pgpout, LANG("\nA user ID is required to select the key you want to revoke or disable. ")); - fprintf(pgpout, LANG("\nEnter user ID: ")); - getstring( mcguffin, 255, TRUE ); /* echo keyboard */ - } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); - - status = disable_key ( mcguffin, keyfile ); + } + status = signkey(mcguffin, my_name, keyfile); - if (status >= 0) { - status = maint_update(keyfile, 0); - if (status == -7) { /* ringfile is a keyfile or secret keyring */ - fprintf(pgpout, "Warning: '%s' is not a public keyring\n", keyfile); - return 0; - } - if (status < 0) - fprintf(pgpout, LANG("\007Maintenance pass error. ") ); + if (status >= 0) { + status = maint_update(keyfile, 0); + if (status == -7) { /* ringfile is a keyfile or + secret keyring */ + fprintf(pgpout, + "Warning: '%s' is not a public keyring\n", + keyfile); + return 0; } - if (status < 0) - errorLvl = KEY_SIGNATURE_ERROR; - return status; - } /* Key compromise */ - - /*-------------------------------------------------------*/ - case 'e': - { /* Key editing - Arguments: userid, ringfile - */ - - if (myArgc >= 4) - strncpy( ringfile, myArgv[3], sizeof(ringfile)-1 ); - else /* default key ring filename */ - strcpy(ringfile, globalPubringName); - - if (myArgc >= 3) { - strcpy( mcguffin, myArgv[2] ); /* Userid to edit */ - } else { - fprintf(pgpout, LANG("\nA user ID is required to select the key you want to edit. ")); - fprintf(pgpout, LANG("\nEnter the key's user ID: ")); - getstring( mcguffin, 255, TRUE ); /* echo keyboard */ + fprintf(pgpout, LANG("\007Maintenance pass error. ")); + } + if (status < 0) { + fprintf(pgpout, LANG("\007Key signature error. ")); + errorLvl = KEY_SIGNATURE_ERROR; + } + return status; + } /* Key signing */ + + +/*-------------------------------------------------------*/ + case 'd': + { /* disable/revoke key + Arguments: userid, keyfile + */ + + if (myArgc >= 4) + strncpy(keyfile, myArgv[3], sizeof(keyfile) - 1); + else + strcpy(keyfile, globalPubringName); + + if (myArgc >= 3) { + strcpy(mcguffin, myArgv[2]); /* Userid to sign */ + } else { + fprintf(pgpout, +LANG("\nA user ID is required to select the key you want to revoke or \ +disable. ")); + fprintf(pgpout, LANG("\nEnter user ID: ")); + getstring(mcguffin, 255, TRUE); /* echo keyboard */ + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); + + status = disable_key(mcguffin, keyfile); + + if (status >= 0) { + status = maint_update(keyfile, 0); + if (status == -7) { /* ringfile is a keyfile or + secret keyring */ + fprintf(pgpout, "Warning: '%s' is not a public keyring\n", + keyfile); + return 0; } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); - - status = dokeyedit( mcguffin, ringfile ); + if (status < 0) + fprintf(pgpout, LANG("\007Maintenance pass error. ")); + } + if (status < 0) + errorLvl = KEY_SIGNATURE_ERROR; + return status; + } /* Key compromise */ + +/*-------------------------------------------------------*/ + case 'e': + { /* Key editing + Arguments: userid, ringfile + */ + + if (myArgc >= 4) + strncpy(ringfile, myArgv[3], sizeof(ringfile) - 1); + else /* default key ring filename */ + strcpy(ringfile, globalPubringName); + + if (myArgc >= 3) { + strcpy(mcguffin, myArgv[2]); /* Userid to edit */ + } else { + fprintf(pgpout, +LANG("\nA user ID is required to select the key you want to edit. ")); + fprintf(pgpout, LANG("\nEnter the key's user ID: ")); + getstring(mcguffin, 255, TRUE); /* echo keyboard */ + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); + + status = dokeyedit(mcguffin, ringfile); + + if (status >= 0) { + status = maint_update(ringfile, 0); + if (status == -7) + status = 0; /* ignore "not a public keyring" error */ + if (status < 0) + fprintf(pgpout, LANG("\007Maintenance pass error. ")); + } + if (status < 0) { + fprintf(pgpout, LANG("\007Keyring edit error. ")); + errorLvl = KEYRING_EDIT_ERROR; + } + return status; + } /* Key edit */ + +/*-------------------------------------------------------*/ + case 'a': + { /* Add key to key ring + Arguments: keyfile, ringfile + */ - if (status >= 0) { - status = maint_update(ringfile, 0); - if (status == -7) - status = 0; /* ignore "not a public keyring" error */ - if (status < 0) - fprintf(pgpout, LANG("\007Maintenance pass error. ") ); - } + if (myArgc < 3 && !filter_mode) + arg_error(); - if (status < 0) { - fprintf(pgpout, LANG("\007Keyring edit error. ") ); - errorLvl = KEYRING_EDIT_ERROR; - } - return status; - } /* Key edit */ + if (!filter_mode) { /* Get the keyfile from args */ + strncpy(keyfile, myArgv[2], sizeof(keyfile) - 1); - /*-------------------------------------------------------*/ - case 'a': - { /* Add key to key ring - Arguments: keyfile, ringfile - */ - - if (myArgc < 3 && !filter_mode) - arg_error(); - - if (!filter_mode) { /* Get the keyfile from args */ - strncpy( keyfile, myArgv[2], sizeof(keyfile)-1 ); - #ifdef MSDOS - strlwr( keyfile ); + strlwr(keyfile); #endif - if (! file_exists( keyfile )) - default_extension( keyfile, PGP_EXTENSION ); - - if (! file_exists( keyfile )) { - fprintf(pgpout, LANG("\n\007Key file '%s' does not exist.\n"), keyfile ); - errorLvl = NONEXIST_KEY_ERROR; - return -1; - } - - workfile = keyfile; + if (!file_exists(keyfile)) + default_extension(keyfile, PGP_EXTENSION); - } else { - workfile = tempfile(TMP_WIPE|TMP_TMPDIR); - readPhantomInput(workfile); + if (!file_exists(keyfile)) { + fprintf(pgpout, + LANG("\n\007Key file '%s' does not exist.\n"), + keyfile); + errorLvl = NONEXIST_KEY_ERROR; + return -1; } + workfile = keyfile; - if (myArgc < (filter_mode ? 3 : 4)) { /* default key ring filename */ - byte ctb; - get_header_info_from_file(workfile, &ctb, 1); - if (ctb == CTB_CERT_SECKEY) - strcpy(ringfile, globalSecringName); - else - strcpy(ringfile, globalPubringName); - } else { - strncpy( ringfile, myArgv[(filter_mode ? 2 : 3)], sizeof(ringfile)-1 ); - default_extension( ringfile, PGP_EXTENSION ); - } + } else { + workfile = tempfile(TMP_WIPE | TMP_TMPDIR); + readPhantomInput(workfile); + } + + if (myArgc < (filter_mode ? 3 : 4)) { /* default key ring + filename */ + byte ctb; + get_header_info_from_file(workfile, &ctb, 1); + if (ctb == CTB_CERT_SECKEY) + strcpy(ringfile, globalSecringName); + else + strcpy(ringfile, globalPubringName); + } else { + strncpy(ringfile, myArgv[(filter_mode ? 2 : 3)], + sizeof(ringfile) - 1); + default_extension(ringfile, PGP_EXTENSION); + } #ifdef MSDOS - strlwr( ringfile ); + strlwr(ringfile); #endif - status = addto_keyring( workfile, ringfile); + status = addto_keyring(workfile, ringfile); - if (filter_mode) - rmtemp(workfile); - - if (status < 0) { - fprintf(pgpout, LANG("\007Keyring add error. ") ); - errorLvl = KEYRING_ADD_ERROR; - } - return status; - } /* Add key to key ring */ - - /*-------------------------------------------------------*/ - case 'x': - { /* Extract key from key ring - Arguments: mcguffin, keyfile, ringfile - */ + if (filter_mode) + rmtemp(workfile); - if (myArgc >= (filter_mode ? 4 : 5)) /* default key ring filename */ - strncpy( ringfile, myArgv[(filter_mode ? 3 : 4)], sizeof(ringfile)-1 ); + if (status < 0) { + fprintf(pgpout, LANG("\007Keyring add error. ")); + errorLvl = KEYRING_ADD_ERROR; + } + return status; + } /* Add key to key ring */ + +/*-------------------------------------------------------*/ + case 'x': + { /* Extract key from key ring + Arguments: mcguffin, keyfile, ringfile + */ + + if (myArgc >= (filter_mode ? 4 : 5)) /* default key ring + filename */ + strncpy(ringfile, myArgv[(filter_mode ? 3 : 4)], + sizeof(ringfile) - 1); + else + strcpy(ringfile, globalPubringName); + + if (myArgc >= (filter_mode ? 2 : 3)) { + if (myArgv[2]) + /* Userid to extract */ + strcpy(mcguffin, myArgv[2]); else - strcpy(ringfile, globalPubringName); + strcpy(mcguffin, ""); + } else { + fprintf(pgpout, +LANG("\nA user ID is required to select the key you want to extract. ")); + if (batchmode) /* not interactive, userid + must be on command line */ + return -1; + fprintf(pgpout, LANG("\nEnter the key's user ID: ")); + getstring(mcguffin, 255, TRUE); /* echo keyboard */ + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); - if (myArgc >= (filter_mode ? 2 : 3)) { - if (myArgv[2]) - /* Userid to extract */ - strcpy( mcguffin, myArgv[2] ); - else - strcpy( mcguffin, "" ); - } else { - fprintf(pgpout, LANG("\nA user ID is required to select the key you want to extract. ")); - if (batchmode) /* not interactive, userid must be on command line */ - return -1; - fprintf(pgpout, LANG("\nEnter the key's user ID: ")); - getstring( mcguffin, 255, TRUE ); /* echo keyboard */ - } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); - - if (!filter_mode) { - if (myArgc >= 4) - strncpy(keyfile, myArgv[3], sizeof(keyfile)-1); - else - keyfile[0] = '\0'; + if (!filter_mode) { + if (myArgc >= 4) + strncpy(keyfile, myArgv[3], sizeof(keyfile) - 1); + else + keyfile[0] = '\0'; - workfile = keyfile; - } else { - workfile = tempfile(TMP_WIPE|TMP_TMPDIR); - } + workfile = keyfile; + } else { + workfile = tempfile(TMP_WIPE | TMP_TMPDIR); + } #ifdef MSDOS - strlwr( workfile ); - strlwr( ringfile ); + strlwr(workfile); + strlwr(ringfile); #endif - default_extension( ringfile, PGP_EXTENSION ); - - status = extract_from_keyring( mcguffin, workfile, - ringfile, (filter_mode ? FALSE : - emit_radix_64) ); - - if (status < 0) { - fprintf(pgpout, LANG("\007Keyring extract error. ") ); - errorLvl = KEYRING_EXTRACT_ERROR; - if (filter_mode) - rmtemp(workfile); - return status; - } + default_extension(ringfile, PGP_EXTENSION); + status = extract_from_keyring(mcguffin, workfile, + ringfile, (filter_mode ? FALSE : + emit_radix_64)); - if (filter_mode && !status) { - if (emit_radix_64) { - /* NULL for outputfile means write to stdout */ - if (armor_file(workfile, NULL, NULL, NULL) != 0) - { - errorLvl = UNKNOWN_FILE_ERROR; - return -1; - } - } else { - if (writePhantomOutput(workfile) < 0) { - errorLvl = UNKNOWN_FILE_ERROR; - return -1; - } - } - rmtemp(workfile); + if (status < 0) { + fprintf(pgpout, LANG("\007Keyring extract error. ")); + errorLvl = KEYRING_EXTRACT_ERROR; + if (filter_mode) + rmtemp(workfile); + return status; + } + if (filter_mode && !status) { + if (emit_radix_64) { + /* NULL for outputfile means write to stdout */ + if (armor_file(workfile, NULL, NULL, NULL) != 0) { + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } + } else { + if (writePhantomOutput(workfile) < 0) { + errorLvl = UNKNOWN_FILE_ERROR; + return -1; + } } - - return 0; - } /* Extract key from key ring */ - - /*-------------------------------------------------------*/ - case 'r': - { /* Remove keys or selected key signatures from userid keys + rmtemp(workfile); + } + return 0; + } /* Extract key from key ring */ + +/*-------------------------------------------------------*/ + case 'r': + { /* Remove keys or selected key signatures from userid keys Arguments: userid, ringfile - */ - - if (myArgc >= 4) - strcpy( ringfile, myArgv[3] ); - else /* default key ring filename */ - strcpy(ringfile, globalPubringName); + */ - if (myArgc >= 3) { - strcpy( mcguffin, myArgv[2] ); /* Userid to work on */ - } else { - if (sign_flag) { - fprintf(pgpout, LANG("\nA user ID is required to select the public key you want to\n\ + if (myArgc >= 4) + strcpy(ringfile, myArgv[3]); + else /* default key ring filename */ + strcpy(ringfile, globalPubringName); + + if (myArgc >= 3) { + strcpy(mcguffin, myArgv[2]); /* Userid to work on */ + } else { + if (sign_flag) { + fprintf(pgpout, +LANG("\nA user ID is required to select the public key you want to\n\ remove certifying signatures from. ")); - } else { - fprintf(pgpout, LANG("\nA user ID is required to select the key you want to remove. ")); - } - if (batchmode) /* not interactive, userid must be on command line */ - return -1; - fprintf(pgpout, LANG("\nEnter the key's user ID: ")); - getstring( mcguffin, 255, TRUE ); /* echo keyboard */ + } else { + fprintf(pgpout, +LANG("\nA user ID is required to select the key you want to remove. ")); } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); + if (batchmode) /* not interactive, userid must be on + command line */ + return -1; + fprintf(pgpout, LANG("\nEnter the key's user ID: ")); + getstring(mcguffin, 255, TRUE); /* echo keyboard */ + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); #ifdef MSDOS - strlwr( ringfile ); + strlwr(ringfile); #endif - if (! file_exists( ringfile )) - default_extension( ringfile, PGP_EXTENSION ); + if (!file_exists(ringfile)) + default_extension(ringfile, PGP_EXTENSION); - if (sign_flag) { /* Remove signatures */ - if (remove_sigs( mcguffin, ringfile ) < 0) { - fprintf(pgpout, LANG("\007Key signature remove error. ") ); - errorLvl = KEYSIG_REMOVE_ERROR; - return -1; - } - } else { /* Remove keyring */ - if (remove_from_keyring( NULL, mcguffin, ringfile, (boolean) (myArgc < 4) ) < 0) - { - fprintf(pgpout, LANG("\007Keyring remove error. ") ); - errorLvl = KEYRING_REMOVE_ERROR; - return -1; - } - } - return 0; - } /* remove key signatures from userid */ - - /*-------------------------------------------------------*/ - case 'v': - case 'V': /* -kvv */ - { /* View or remove key ring entries, with userid match - Arguments: userid, ringfile - */ - - if (myArgc < 4) /* default key ring filename */ - strcpy(ringfile, globalPubringName); - else - strcpy( ringfile, myArgv[3] ); - - if (myArgc > 2) { - strcpy( mcguffin, myArgv[2] ); - if (strcmp( mcguffin, "*" ) == 0) - mcguffin[0] = '\0'; - } else { - *mcguffin = '\0'; - } - - if ((myArgc == 3) && has_extension( myArgv[2], PGP_EXTENSION )) - { - strcpy( ringfile, myArgv[2] ); - mcguffin[0] = '\0'; - } - CONVERT_TO_CANONICAL_CHARSET(mcguffin); + if (sign_flag) { /* Remove signatures */ + if (remove_sigs(mcguffin, ringfile) < 0) { + fprintf(pgpout, LANG("\007Key signature remove error. ")); + errorLvl = KEYSIG_REMOVE_ERROR; + return -1; + } + } else { /* Remove keyring */ + if (remove_from_keyring(NULL, mcguffin, ringfile, + (boolean) (myArgc < 4)) < 0) { + fprintf(pgpout, LANG("\007Keyring remove error. ")); + errorLvl = KEYRING_REMOVE_ERROR; + return -1; + } + } + return 0; + } /* remove key signatures from userid */ + +/*-------------------------------------------------------*/ + case 'v': + case 'V': /* -kvv */ + { /* View or remove key ring entries, + with userid match + Arguments: userid, ringfile + */ + + if (myArgc < 4) /* default key ring filename */ + strcpy(ringfile, globalPubringName); + else + strcpy(ringfile, myArgv[3]); + + if (myArgc > 2) { + strcpy(mcguffin, myArgv[2]); + if (strcmp(mcguffin, "*") == 0) + mcguffin[0] = '\0'; + } else { + *mcguffin = '\0'; + } + + if ((myArgc == 3) && has_extension(myArgv[2], PGP_EXTENSION)) { + strcpy(ringfile, myArgv[2]); + mcguffin[0] = '\0'; + } + CONVERT_TO_CANONICAL_CHARSET(mcguffin); #ifdef MSDOS - strlwr( ringfile ); + strlwr(ringfile); #endif - if (! file_exists( ringfile )) - default_extension( ringfile, PGP_EXTENSION ); - - /* If a second 'v' (keychar = V), show signatures too */ - status = view_keyring(mcguffin, ringfile, (boolean) (keychar == 'V'), c_flag); - if (status < 0) { - fprintf(pgpout, LANG("\007Keyring view error. ") ); - errorLvl = KEYRING_VIEW_ERROR; - } - return status; - } /* view key ring entries, with userid match */ + if (!file_exists(ringfile)) + default_extension(ringfile, PGP_EXTENSION); - default: - arg_error(); - } - return 0; -} /* do_keyopt */ + /* If a second 'v' (keychar = V), show signatures too */ + status = view_keyring(mcguffin, ringfile, + (boolean) (keychar == 'V'), c_flag); + if (status < 0) { + fprintf(pgpout, LANG("\007Keyring view error. ")); + errorLvl = KEYRING_VIEW_ERROR; + } + return status; + } /* view key ring entries, with userid match */ + + default: + arg_error(); + } + return 0; +} /* do_keyopt */ - - -void user_error() /* comes here if user made a boo-boo. */ +/* comes here if user made a boo-boo. */ +void user_error() { - fprintf(pgpout,LANG("\nFor a usage summary, type: pgp -h\n")); - fprintf(pgpout,LANG("For more detailed help, consult the PGP User's Guide.\n")); - exitPGP(errorLvl ? errorLvl : 127); /* error exit */ + fprintf(pgpout, LANG("\nFor a usage summary, type: pgp -h\n")); + fprintf(pgpout, + LANG("For more detailed help, consult the PGP User's Guide.\n")); + exitPGP(errorLvl ? errorLvl : 127); /* error exit */ } #if defined(DEBUG) && defined(linux) #include #endif + /* * exitPGP: wipes and removes temporary files, also tries to wipe * the stack. */ void exitPGP(int returnval) { - char buf[STACK_WIPE]; - struct hashedpw *hpw; + char buf[STACK_WIPE]; + struct hashedpw *hpw; - if (verbose) - fprintf(pgpout, "exitPGP: exitcode = %d\n", returnval); - for (hpw = passwds; hpw; hpw = hpw->next) - memset(hpw->hash, 0, sizeof(hpw->hash)); - for (hpw = keypasswds; hpw; hpw = hpw->next) - memset(hpw->hash, 0, sizeof(hpw->hash)); - cleanup_tmpf(); + if (verbose) + fprintf(pgpout, "exitPGP: exitcode = %d\n", returnval); + for (hpw = passwds; hpw; hpw = hpw->next) + memset(hpw->hash, 0, sizeof(hpw->hash)); + for (hpw = keypasswds; hpw; hpw = hpw->next) + memset(hpw->hash, 0, sizeof(hpw->hash)); + cleanup_tmpf(); #if defined(DEBUG) && defined(linux) - if (verbose) { - struct mstats mstat; - mstat = mstats(); - printf("%d chunks used (%d bytes) %d bytes total\n", - mstat.chunks_used, mstat.bytes_used, mstat.bytes_total); - } + if (verbose) { + struct mstats mstat; + mstat = mstats(); + printf("%d chunks used (%d bytes) %d bytes total\n", + mstat.chunks_used, mstat.bytes_used, mstat.bytes_total); + } #endif - memset(buf, 0, sizeof(buf)); /* wipe stack */ + memset(buf, 0, sizeof(buf)); /* wipe stack */ #ifdef VMS /* * Fake VMS style error returns with severity in bottom 3 bits */ - if (returnval) - returnval = (returnval << 3) | 0x10000002; - else - returnval = 0x10000001; -#endif /* VMS */ - exit(returnval); + if (returnval) + returnval = (returnval << 3) | 0x10000002; + else + returnval = 0x10000001; +#endif /* VMS */ + exit(returnval); } - static void arg_error() { - signon_msg(); - fprintf(pgpout,LANG("\nInvalid arguments.\n")); - errorLvl = BAD_ARG_ERROR; - user_error(); + signon_msg(); + fprintf(pgpout, LANG("\nInvalid arguments.\n")); + errorLvl = BAD_ARG_ERROR; + user_error(); } /* @@ -2041,60 +2120,58 @@ static void arg_error() * * System-wide copies currently only exist on Unix. */ -static void -build_helpfile(char *helpfile, char const *extra) +static void build_helpfile(char *helpfile, char const *extra) { - if (strcmp(language, "en")) { - buildfilename(helpfile, language); - strcat(helpfile, extra); - force_extension(helpfile, HLP_EXTENSION); - if (file_exists(helpfile)) - return; -#ifdef PGP_SYSTEM_DIR - strcpy(helpfile, PGP_SYSTEM_DIR); - strcat(helpfile, language); - strcat(helpfile, extra); - force_extension(helpfile, HLP_EXTENSION); - if (file_exists(helpfile)) - return; -#endif - } - buildfilename(helpfile, "pgp"); + if (strcmp(language, "en")) { + buildfilename(helpfile, language); strcat(helpfile, extra); force_extension(helpfile, HLP_EXTENSION); -#ifdef PGP_SYSTEM_DIR if (file_exists(helpfile)) - return; + return; +#ifdef PGP_SYSTEM_DIR strcpy(helpfile, PGP_SYSTEM_DIR); - strcat(helpfile, "pgp"); + strcat(helpfile, language); strcat(helpfile, extra); force_extension(helpfile, HLP_EXTENSION); + if (file_exists(helpfile)) + return; +#endif + } + buildfilename(helpfile, "pgp"); + strcat(helpfile, extra); + force_extension(helpfile, HLP_EXTENSION); +#ifdef PGP_SYSTEM_DIR + if (file_exists(helpfile)) + return; + strcpy(helpfile, PGP_SYSTEM_DIR); + strcat(helpfile, "pgp"); + strcat(helpfile, extra); + force_extension(helpfile, HLP_EXTENSION); #endif } static void usage() { - char helpfile[MAX_PATH]; - char *tmphelp = helpfile; - extern unsigned char *ext_c_ptr; - - signon_msg(); - build_helpfile(helpfile, ""); - - if (ext_c_ptr) { - /* conversion to external format necessary */ - tmphelp = tempfile(TMP_TMPDIR); - CONVERSION = EXT_CONV; - if (copyfiles_by_name(helpfile, tmphelp) < 0) { - rmtemp(tmphelp); - tmphelp = helpfile; - } - CONVERSION = NO_CONV; - } - - /* built-in help if pgp.hlp is not available */ - if (more_file(tmphelp) < 0) - fprintf(pgpout,LANG("\nUsage summary:\ + char helpfile[MAX_PATH]; + char *tmphelp = helpfile; + extern unsigned char *ext_c_ptr; + + signon_msg(); + build_helpfile(helpfile, ""); + + if (ext_c_ptr) { + /* conversion to external format necessary */ + tmphelp = tempfile(TMP_TMPDIR); + CONVERSION = EXT_CONV; + if (copyfiles_by_name(helpfile, tmphelp) < 0) { + rmtemp(tmphelp); + tmphelp = helpfile; + } + CONVERSION = NO_CONV; + } + /* built-in help if pgp.hlp is not available */ + if (more_file(tmphelp) < 0) + fprintf(pgpout, LANG("\nUsage summary:\ \nTo encrypt a plaintext file with recipent's public key, type:\ \n pgp -e textfile her_userid [other userids] (produces textfile.pgp)\ \nTo sign a plaintext file with your secret key:\ @@ -2109,36 +2186,34 @@ static void usage() \nTo produce output in ASCII for email, add the -a option to other options.\ \nTo generate your own unique public/secret key pair: pgp -kg\ \nFor help on other key management functions, type: pgp -k\n")); - if (ext_c_ptr) - rmtemp(tmphelp); - exit(BAD_ARG_ERROR); /* error exit */ + if (ext_c_ptr) + rmtemp(tmphelp); + exit(BAD_ARG_ERROR); /* error exit */ } - static void key_usage() { - char helpfile[MAX_PATH]; - char *tmphelp = helpfile; - extern unsigned char *ext_c_ptr; - - signon_msg(); - build_helpfile(helpfile, "key"); - - if (ext_c_ptr) { - /* conversion to external format necessary */ - tmphelp = tempfile(TMP_TMPDIR); - CONVERSION = EXT_CONV; - if (copyfiles_by_name(helpfile, tmphelp) < 0) { - rmtemp(tmphelp); - tmphelp = helpfile; - } - CONVERSION = NO_CONV; - } - - /* built-in help if pgp.hlp is not available */ - if (more_file(tmphelp) < 0) - /* only use built-in help if there is no helpfile */ - fprintf(pgpout,LANG("\nKey management functions:\ + char helpfile[MAX_PATH]; + char *tmphelp = helpfile; + extern unsigned char *ext_c_ptr; + + signon_msg(); + build_helpfile(helpfile, "key"); + + if (ext_c_ptr) { + /* conversion to external format necessary */ + tmphelp = tempfile(TMP_TMPDIR); + CONVERSION = EXT_CONV; + if (copyfiles_by_name(helpfile, tmphelp) < 0) { + rmtemp(tmphelp); + tmphelp = helpfile; + } + CONVERSION = NO_CONV; + } + /* built-in help if pgp.hlp is not available */ + if (more_file(tmphelp) < 0) + /* only use built-in help if there is no helpfile */ + fprintf(pgpout, LANG("\nKey management functions:\ \nTo generate your own unique public/secret key pair:\ \n pgp -kg\ \nTo add a key file's contents to your public or secret key ring:\ @@ -2158,6 +2233,6 @@ static void key_usage() \nTo remove selected signatures from a userid on a keyring:\ \n pgp -krs userid [keyring]\ \n")); - - exit(BAD_ARG_ERROR); /* error exit */ + + exit(BAD_ARG_ERROR); /* error exit */ }