*** /tmp/,RCSt1a02013 Thu Sep 22 16:40:07 1994 --- config.c Wed Sep 7 16:00:58 1994 *************** *** 103,109 **** ARMORLINES, COMPLETES_NEEDED, MARGINALS_NEEDED, PAGER, CERT_DEPTH, CHARSET, CLEAR, SELF_ENCRYPT, INTERACTIVE, PKCS_COMPAT, PUBRING, SECRING, RANDSEED, ! COMMENT, /* options below this line can only be used as command line * "long" options */ #define CONFIG_INTRINSICS BATCHMODE --- 103,109 ---- ARMORLINES, COMPLETES_NEEDED, MARGINALS_NEEDED, PAGER, CERT_DEPTH, CHARSET, CLEAR, SELF_ENCRYPT, INTERACTIVE, PKCS_COMPAT, PUBRING, SECRING, RANDSEED, ! COMMENT, EXCLUDE, /* options below this line can only be used as command line * "long" options */ #define CONFIG_INTRINSICS BATCHMODE *************** *** 116,122 **** "ARMORLINES", "COMPLETES_NEEDED", "MARGINALS_NEEDED", "PAGER", "CERT_DEPTH", "CHARSET", "CLEARSIG", "ENCRYPTTOSELF", "INTERACTIVE", "PKCS_COMPAT", "PUBRING", "SECRING", "RANDSEED", ! "COMMENT", /* command line only */ "BATCHMODE", "FORCE", "LEGAL_KLUDGE", "NOMANUAL" }; --- 116,122 ---- "ARMORLINES", "COMPLETES_NEEDED", "MARGINALS_NEEDED", "PAGER", "CERT_DEPTH", "CHARSET", "CLEARSIG", "ENCRYPTTOSELF", "INTERACTIVE", "PKCS_COMPAT", "PUBRING", "SECRING", "RANDSEED", ! "COMMENT", "EXCLUDE", /* command line only */ "BATCHMODE", "FORCE", "LEGAL_KLUDGE", "NOMANUAL" }; *************** *** 127,133 **** NUMERIC, NUMERIC, NUMERIC, STRING, NUMERIC, STRING, BOOL, BOOL, BOOL, NUMERIC, STRING, STRING, STRING, ! STRING, /* command line only */ BOOL, BOOL, BOOL, BOOL }; --- 127,133 ---- NUMERIC, NUMERIC, NUMERIC, STRING, NUMERIC, STRING, BOOL, BOOL, BOOL, NUMERIC, STRING, STRING, STRING, ! STRING, STRING, /* command line only */ BOOL, BOOL, BOOL, BOOL }; *************** *** 443,448 **** --- 443,452 ---- case RANDSEED: strcpy(globalRandseedName, str); + break; + + case EXCLUDE: + strcpy(globalExcludeName, str); break; case COMMENT: *** /tmp/,RCSt1a02013 Thu Sep 22 16:40:10 1994 --- keyadd.c Wed Sep 7 16:04:39 1994 *************** *** 559,564 **** --- 559,569 ---- } copying = FALSE; } else if (status == -1) { /* key NOT in keyring */ + if (is_excluded_keyid(keyID)) { + fprintf(pgpout, + LANG("\n\007KeyID %s is on the exlude list and will not be added.\n"), + keyIDstring(keyID)); + } else { ++newkeys; if (interactive_add) { if (!show_key(f, file_position, SHOW_ALL)) { *************** *** 584,589 **** --- 589,595 ---- nkey->next = nkeys; nkeys = nkey; } + } } else { /* unknown version or bad key */ copying = FALSE; *** /tmp/,RCSt1a02013 Thu Sep 22 16:40:11 1994 --- keymgmt.c Thu Sep 22 16:38:32 1994 *************** *** 111,116 **** --- 111,312 ---- return FALSE; } + static int excluded_count = 0; + static char *excluded_list = NULL; + + /* + * Used internally to add an entry to the excluded list + */ + void _add_exclude_memory(char *exclude_keyID) + { + excluded_count++; + if (excluded_count == 1) + excluded_list = (char *)malloc((KEYFRAGSIZE * 2) + 1); + else + excluded_list = (char *)realloc(excluded_list, + excluded_count * ((KEYFRAGSIZE * 2 + 1))); + + if (excluded_list == NULL) { + fprintf(pgpout, LANG("Cannot allocate memory for excluded list!\n")); + exitPGP(7); /* OUT_OF_MEM */ + } + + /* remember the key */ + strcpy(excluded_list + (excluded_count - 1) * (KEYFRAGSIZE * 2 + 1), + exclude_keyID); + } + + void read_exclude_file() + { + FILE *efile; /* the file itself */ + static char keyIDbuf[1024]; /* bigger than needed, but... */ + int i; + + if (excluded_count) + return; + + efile = fopen(globalExcludeName, FOPRTXT); + if (efile == NULL) + return; /* no excluded file, assume no excluded keys */ + + while (fgets(keyIDbuf, sizeof(keyIDbuf), efile)) { + + /* comments are allowed I suppose */ + if ((keyIDbuf[0] == '\0') || (keyIDbuf[0] == '#')) + break; + + /* nuke the newline fgets leaves in the string */ + keyIDbuf[strlen(keyIDbuf) - 1] = '\0'; + + if (strlen(keyIDbuf) != (KEYFRAGSIZE * 2)) { + fprintf(pgpout, LANG("Bad line in exclude file, %s\n"), keyIDbuf); + break; /* bad entry in the file, bitch about it */ + } + + _add_exclude_memory(keyIDbuf); + } + + fclose(efile); + } + + /* + * write the in-memory list to the file + */ + void write_exclude_file() { + int i; + FILE *efile; + + /* if there are no entries, there's little to do... */ + if (!excluded_count) + return; + + efile = fopen(globalExcludeName, FOPWTXT); + if (efile == NULL) { + fprintf(pgpout, LANG("\n\007Cannot open %s for writing!\n"), + globalExcludeName); + return; /* no excluded file, assume no excluded keys */ + } + + for (i = 0 ; i < excluded_count; i++) + fprintf(efile, "%s\n", excluded_list + i * (KEYFRAGSIZE * 2 + 1)); + + fclose(efile); + } + + /* + * List the contents of the in-memory exclude list + */ + void exclude_list() { + int i; + + read_exclude_file(); + + if (!excluded_count) + return; + + fprintf(pgpout, + LANG("\nThese are all 64-bit values. This is more than what is usually\n")); + fprintf(pgpout, + LANG("displayed, but PGP uses these internally. To get the PGP-displayed\n")); + fprintf(pgpout, + LANG("KeyID, use the rightmost digits.\n\n")); + for (i = 0 ; i < excluded_count; i++) + fprintf(pgpout, "Excluded\t%s\n", excluded_list + i * (KEYFRAGSIZE * 2 + 1)); + } + + int exclude_add(char *keyguffin, char *keyfile) + { + byte keyctrl; + byte keyID[KEYFRAGSIZE]; + byte userid[256]; + unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION]; + long fp; + int pktlen; + short i; + char *bufptr; /* ptr to Key ID string */ + static char keyIDbuf[1024]; /* bigger than needed, but... */ + + read_exclude_file(); + + strcpy((char *)userid, keyguffin); + if (getpublickey(GPK_SHOW | GPK_DISABLED, keyfile, &fp, &pktlen, NULL, + NULL, userid, n, e) < 0) + return -1; + extract_keyID(keyID, n); + + if (is_excluded_keyid(keyID)) { + fprintf(pgpout, LANG("\nThis key is already excluded.\n")); + return -1; + } + + if (!batchmode) { + fprintf(pgpout, + LANG("\nExcluding this key will prevent it from ever appearing on your\n")); + fprintf(pgpout, + LANG("keyring again. Do you wish to do this? [y/N] ")); + } + if (batchmode || getyesno('n')) { + + bufptr = keyIDbuf; + for (i = KEYFRAGSIZE - 1; i >= 0; i--) { + #ifdef XLOWFIRST + sprintf(bufptr, "%02X", keyID[i]); + #else + sprintf(bufptr, "%02X", keyID[KEYFRAGSIZE - i - 1]); + #endif + bufptr += 2; + } + *bufptr = '\0'; + + _add_exclude_memory(keyIDbuf); + write_exclude_file(); + return (0); + } + return -1; + } + + int exclude_remove(char *name, char *keyfile) + { + return -1; /* indicate error for now */ + } + + /* + * Scan through the excluded key list for matching keyID. Returns 0 if it is + * not excluded or non-zero if it is. + */ + int is_excluded_keyid(byte *keyID) + { + short i; + char *bufptr; /* ptr to Key ID string */ + static char keyIDbuf[1024]; /* bigger than needed, but... */ + + read_exclude_file(); + + /* if there are no entries, there's little to check for... */ + if (!excluded_count) + return(0); + + bufptr = keyIDbuf; + for (i = KEYFRAGSIZE - 1; i >= 0; i--) { + #ifdef XLOWFIRST + sprintf(bufptr, "%02X", keyID[i]); + #else + sprintf(bufptr, "%02X", keyID[KEYFRAGSIZE - i - 1]); + #endif + bufptr += 2; + } + *bufptr = '\0'; + + for (i = 0 ; i < excluded_count; i++) { + bufptr = excluded_list + (i * (KEYFRAGSIZE * 2 + 1)); + if (!strcmp(bufptr, keyIDbuf)) + return(1); /* found it! */ + } + + /* if we got here, the key is OK */ + return(0); + } + int is_key_ctb(byte ctb) { return ctb == CTB_CERT_PUBKEY || ctb == CTB_CERT_SECKEY; *************** *** 1932,1938 **** return -1; } } ! } else if (!force_flag) { /* only one user ID */ fprintf(pgpout, LANG("\nAre you sure you want this key removed (y/N)? ")); if (!getyesno('n')) { --- 2129,2135 ---- return -1; } } ! } else if (!force_flag && !batchmode) { /* only one user ID */ fprintf(pgpout, LANG("\nAre you sure you want this key removed (y/N)? ")); if (!getyesno('n')) { *************** *** 2055,2063 **** } if (!keyfile || strlen(keyfile) == 0) { - fprintf(pgpout, LANG("\nExtract the above key into which file? ")); if (batchmode) return -1; getstring(fname, sizeof(fname) - 4, TRUE); if (*fname == '\0') return -1; --- 2252,2260 ---- } if (!keyfile || strlen(keyfile) == 0) { if (batchmode) return -1; + fprintf(pgpout, LANG("\nExtract the above key into which file? ")); getstring(fname, sizeof(fname) - 4, TRUE); if (*fname == '\0') return -1; *************** *** 2396,2402 **** /* key is in secret keyring but buckstop is not set */ fprintf(pgpout, LANG("\nUse this key as an ultimately-trusted introducer (y/N)? "), userid); ! if (getyesno('n')) { fseek(f, trust_pos, SEEK_SET); keyctrl = KC_OWNERTRUST_ULTIMATE | KC_BUCKSTOP; write_trust(f, keyctrl); --- 2593,2599 ---- /* key is in secret keyring but buckstop is not set */ fprintf(pgpout, LANG("\nUse this key as an ultimately-trusted introducer (y/N)? "), userid); ! if (batchmode || getyesno('n')) { fseek(f, trust_pos, SEEK_SET); keyctrl = KC_OWNERTRUST_ULTIMATE | KC_BUCKSTOP; write_trust(f, keyctrl); *** /tmp/,RCSt1a02013 Thu Sep 22 16:40:18 1994 --- pgp.c Thu Sep 22 16:39:49 1994 *************** *** 159,164 **** --- 159,165 ---- char globalPubringName[MAX_PATH]; char globalSecringName[MAX_PATH]; char globalRandseedName[MAX_PATH]; + char globalExcludeName[MAX_PATH]; char globalCommentString[128]; /* Flags which are global across the driver code files */ *************** *** 189,195 **** "LHarc"}; static char *compressExt[] = {".zip", ".zoo", ".gif", ".arj", ! ".hpk", ".z", ".Z", ".pak", ".hyp", ".lzh"}; /* "\032\0??", "ARC", ".arc" */ --- 190,196 ---- "LHarc"}; static char *compressExt[] = {".zip", ".zoo", ".gif", ".arj", ! ".hpk", ".gz", ".Z", ".pak", ".hyp", ".lzh"}; /* "\032\0??", "ARC", ".arc" */ *************** *** 364,369 **** --- 365,372 ---- boolean clear_signatures = TRUE; boolean strip_spaces; static boolean c_flag = FALSE; + static boolean a_flag = FALSE; + static boolean r_flag = FALSE; boolean encrypt_to_self = FALSE; /* should I encrypt messages to myself? */ boolean batchmode = FALSE; /* if TRUE: don't ask questions */ boolean quietmode = FALSE; *************** *** 527,532 **** --- 530,536 ---- buildfilename(globalPubringName, "pubring.pgp"); buildfilename(globalSecringName, "secring.pgp"); buildfilename(globalRandseedName, "randseed.bin"); + buildfilename(globalExcludeName, "excluded.txt"); my_name[0] = '\0'; /* Process the config file first. Any command-line arguments will *************** *** 594,599 **** --- 598,604 ---- case 'a': armor_flag = TRUE; emit_radix_64 = 1; + a_flag = TRUE; break; case 'b': separate_signature = strip_sig_flag = TRUE; *************** *** 632,637 **** --- 637,645 ---- case 'p': preserve_filename = TRUE; break; + case 'r': + r_flag = TRUE; + break; case 'o': outputfile = optarg; break; *************** *** 2005,2010 **** --- 2013,2081 ---- } return 0; } /* remove key signatures from userid */ + + + /*-------------------------------------------------------*/ + case 'l': + { + /* + * List/add/remove 64-bit keyid's -- for the exclude file stuff + * Arguments: userid, ringfile + */ + + if (myArgc >= 4) + strcpy( ringfile, myArgv[3] ); + else /* default key ring filename */ + strcpy(ringfile, globalPubringName); + + if (a_flag || r_flag) { + if (myArgc >= 3) { + strcpy( mcguffin, myArgv[2] ); /* Userid to work on */ + } else { + fprintf(pgpout, + LANG("\nA user ID is required to select the key you want to exclude. ")); + 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 ); + #endif + if (! file_exists( ringfile )) + default_extension( ringfile, PGP_EXTENSION ); + + if (a_flag) { + /* lookup a key, add to the exclude list, and remove that key */ + if (exclude_add(mcguffin, ringfile)) { + fprintf(pgpout, LANG("\007Error adding key to exclude list.")); + errorLvl = KEYRING_REMOVE_ERROR; + return -1; + } + if (remove_from_keyring( NULL, mcguffin, ringfile, + (boolean) (myArgc < 4) ) < 0) { + fprintf(pgpout, LANG("\007Keyring remove error. ") ); + errorLvl = KEYRING_REMOVE_ERROR; + return -1; + } + } else if (r_flag) { + /* remove from the exclude list */ + if (exclude_remove(mcguffin, ringfile)) { + fprintf(pgpout, LANG("\007Error removing key from exclude list.")); + errorLvl = KEYRING_REMOVE_ERROR; + return -1; + } + } else { + /* list the exclude ring */ + exclude_list(); + } + + return 0; + } /* exclude file stuff */ /*-------------------------------------------------------*/ case 'v': *** /tmp/,RCSt1a02013 Thu Sep 22 16:40:20 1994 --- pgp.h Wed Sep 7 16:16:56 1994 *************** *** 202,207 **** --- 202,208 ---- extern char globalPubringName[MAX_PATH]; extern char globalSecringName[MAX_PATH]; extern char globalRandseedName[MAX_PATH]; + extern char globalExcludeName[MAX_PATH]; extern char globalCommentString[128]; /* Variables which are global across the driver code */