diff -r -C3 mixmaster-3.0/Src/crypto.c mixmaster-3.0-mymods2/Src/crypto.c *** mixmaster-3.0/Src/crypto.c 2006-06-24 14:40:39.000000000 +0100 --- mixmaster-3.0-mymods2/Src/crypto.c 2013-10-11 18:41:55.128007032 +0100 *************** *** 285,291 **** return (ret); } ! int v2createkey(void) { RSA *k; BUFFER *b, *ek, *iv; --- 285,291 ---- return (ret); } ! int v2createkey(long int lifeindays) { RSA *k; BUFFER *b, *ek, *iv; *************** *** 310,317 **** gt = gmtime(&now); strftime(line, LINELEN, "%Y-%m-%d", gt); fprintf(f, "%s\nCreated: %s\n", begin_key, line); if (KEYLIFETIME) { ! now += KEYLIFETIME; gt = gmtime(&now); strftime(line, LINELEN, "%Y-%m-%d", gt); fprintf(f, "Expires: %s\n", line); --- 310,322 ---- gt = gmtime(&now); strftime(line, LINELEN, "%Y-%m-%d", gt); fprintf(f, "%s\nCreated: %s\n", begin_key, line); + /* lifeindays comes from the command line and may override + the default of KEYLIFETIME (in seconds). */ if (KEYLIFETIME) { ! if ((lifeindays>0) && (lifeindays*86400 time(NULL))) || ! ((expires != 0) && (expires < time(NULL)))) { ! /* Key already is expired or has creation date in the future */ continue; } id_decode(line, k1); --- 327,339 ---- } while ( res != NULL && strchr(line, ':') != NULL ); if (res == NULL) break; ! if ((created != 0) && (created > time(NULL))) { ! /* Key has creation date in the future */ ! continue; ! } ! if ((expires != 0) && (expires < time(NULL))) { ! /* Key already is expired.*/ ! need2delete=1; continue; } id_decode(line, k1); *************** *** 351,356 **** --- 357,363 ---- buf_crypt(b, pass, iv, DECRYPT); buf_clear(pk); if (seckeytopub(pk, b, k1) == 0) { + long pos; /* file position */ found = 1; if (expires == 0 || (expires - KEYOVERLAPPERIOD >= time(NULL))) foundnonexpiring = 1; *************** *** 361,374 **** expires_found = expires; created_found = created; } } } } fclose(keyring); } if (!foundnonexpiring || (force == 2)) { ! v2createkey(); foundnonexpiring = 1; force = 1; } else --- 368,390 ---- expires_found = expires; created_found = created; } + /* write all the pub keys */ + pk_temp = buf_new(); + buf_clear(pk_temp); + buf_cat(pk_temp, pk); + pos=ftell(keyring); + write_pubkey_file(keyring,all_pub,pk_temp,k1,created,expires); + fseek(keyring,pos,SEEK_SET); + buf_free(pk_temp); } } } fclose(keyring); + fclose(all_pub); } if (!foundnonexpiring || (force == 2)) { ! v2createkey(lifeindays); foundnonexpiring = 1; force = 1; } else *************** *** 377,405 **** if (found) { if ((f = mix_openfile(KEYFILE, "w")) != NULL) { ! id_encode(k1_found, line); ! fprintf(f, "%s %s %s %s:%s %s%s", SHORTNAME, ! REMAILERADDR, line, mixmaster_protocol, VERSION, ! MIDDLEMAN ? "M" : "", ! NEWS[0] == '\0' ? "C" : (strchr(NEWS, '@') ? "CNm" : "CNp")); ! if (created_found) { ! struct tm *gt; ! gt = gmtime(&created_found); ! strftime(line, LINELEN, "%Y-%m-%d", gt); ! fprintf(f, " %s", line); ! if (expires_found) { ! struct tm *gt; ! gt = gmtime(&expires_found); ! strftime(line, LINELEN, "%Y-%m-%d", gt); ! fprintf(f, " %s", line); ! } ! } ! fprintf(f, "\n\n%s\n", begin_key); ! id_encode(k1_found, line); ! fprintf(f, "%s\n258\n", line); ! encode(pk_found, 40); ! buf_write(pk_found, f); ! fprintf(f, "%s\n\n", end_key); fclose(f); } } else --- 393,399 ---- if (found) { if ((f = mix_openfile(KEYFILE, "w")) != NULL) { ! write_pubkey_file(keyring,f,pk_found,k1_found,created_found,expires_found); fclose(f); } } else *************** *** 412,421 **** buf_free(pk); buf_free(pk_found); return (err); } ! int keymgt(int force) { /* force = 0: write key file if there is none force = 1: update key file --- 406,418 ---- buf_free(pk); buf_free(pk_found); + if (need2delete) + fprintf(stderr, "key deletion returns %d\n", deleteoldkeys()); + return (err); } ! int keymgt(int force,long int lifeindays) { /* force = 0: write key file if there is none force = 1: update key file *************** *** 423,429 **** int err = 0; if (REMAIL || force == 2) { ! if (MIX && (err = v2keymgt(force)) == -1) err = -1; #ifdef USE_PGP if (PGP && (err = pgp_keymgt(force)) == -1) --- 420,426 ---- int err = 0; if (REMAIL || force == 2) { ! if (MIX && (err = v2keymgt(force,lifeindays)) == -1) err = -1; #ifdef USE_PGP if (PGP && (err = pgp_keymgt(force)) == -1) *************** *** 432,434 **** --- 429,543 ---- } return (err); } + + int deleteoldkeys(void) + { + FILE *keyring, *newsecring; + int show=1; + int linecount=0; + int expires; + char line[LINELEN]; + BUFFER *header; + char *res=line; + + keyring = mix_openfile(SECRING, "r"); + if (!keyring) + return -1; + newsecring = mix_openfile("secring.mix.new", "w"); + if (!newsecring) + return -1; + + while (res) { + linecount++; + if (fgets(line, sizeof(line), keyring) == NULL) + break; + if (strleft(line, begin_key)) { + expires = 0; + header = buf_new(); + buf_clear(header); + show = 0; /* store text but do not show it yet */ + buf_append(header, line, strlen(line)); + do { + linecount++; + res = fgets(line, sizeof(line), keyring); + switch (show) { + case 0: + buf_append(header, line, strlen(line)); + break; + case 1: + fprintf(newsecring, "%s", line); + break; + default: + /* no action */ + break; + } + if (strileft(line, "expires:")) { + expires = parse_yearmonthday(strchr(line, ':')+1); + if (expires == -1) + expires = 0; + if (expires < time(NULL)) { + show=2; /* do not show this key */ + } else { + show=1; /* show this key */ + } + if (1==show) buf_write(header, newsecring); + buf_free(header); + } + /* Fetch lines until end key or eof */ + if (res == NULL) + break; /* quit from two loops */ + } while ( !strileft(line,end_key) ); + fprintf(newsecring, "\n"); + } + } + + if (fclose(keyring)) return -11; + if (fclose(newsecring)) return -12; + /* replace the file and wipe the old one */ + keyring = mix_openfile(SECRING, "r+"); + { + /* rename the "secring.mix.new" in the MIXDIR not CWD */ + char path1[PATHMAX], path2[PATHMAX]; + mixfile(path1, "secring.mix.new"); + mixfile(path2, SECRING); + if (rename(path1, path2)) return -14; + } + sync(); + if (!keyring) return -15; + memset(line,'\n',LINELEN-1); + line[LINELEN-1]='\0'; + for (;linecount>0;linecount--) + fprintf(keyring,"%s",line); + fclose(keyring); + return 0; + } + + int write_pubkey_file(FILE *in, FILE *out, BUFFER *pk_found, byte *k1_found, time_t created_found, time_t expires_found) + { + char line[LINELEN]; + + id_encode(k1_found, line); + fprintf(out, "%s %s %s %s:%s %s%s", SHORTNAME, + REMAILERADDR, line, mixmaster_protocol, VERSION, + MIDDLEMAN ? "M" : "", + NEWS[0] == '\0' ? "C" : (strchr(NEWS, '@') ? "CNm" : "CNp")); + if (created_found) { + struct tm *gt; + gt = gmtime(&created_found); + strftime(line, LINELEN, "%Y-%m-%d", gt); + fprintf(out, " %s", line); + if (expires_found) { + struct tm *gt; + gt = gmtime(&expires_found); + strftime(line, LINELEN, "%Y-%m-%d", gt); + fprintf(out, " %s", line); + } + } + fprintf(out, "\n\n%s\n", begin_key); + id_encode(k1_found, line); + fprintf(out, "%s\n258\n", line); + encode(pk_found, 40); + buf_write(pk_found, out); + fprintf(out, "%s\n\n", end_key); + return 0; + } diff -r -C3 mixmaster-3.0/Src/main.c mixmaster-3.0-mymods2/Src/main.c *** mixmaster-3.0/Src/main.c 2006-06-24 16:52:20.000000000 +0100 --- mixmaster-3.0-mymods2/Src/main.c 2013-10-11 18:41:55.128007032 +0100 *************** *** 45,50 **** --- 45,51 ---- int daemon = 0, type_list = 0, nodetach = 0; int update_stats = 0, update_pingerlist = 0; int never_ask_for_passphrase = 0; + long int lifeindays=0; #ifdef USE_SOCK int pop3 = 0; *************** *** 153,158 **** --- 154,163 ---- deflt = 0; fprintf(stderr, "%s: No current stats source --%s\n", argv[0], p); } + } else if (strleft(p, "lifetime") && p[strlen("lifetime")] == '=') { + lifeindays=strtol(p + strlen("lifetime") + 1,NULL,10); + if (lifeindays<0) + lifeindays=0; } else if (strleft(p, "update-stats") && p[strlen("update-stats")] == '=') { buf_clear(statssrc); buf_appendf(statssrc, "%s", (p + strlen("update-stats") + 1)); *************** *** 682,688 **** if (keygen) { check_get_pass(0, never_ask_for_passphrase); ! keymgt(keygen); } if (sendpool) mix_send(); --- 687,693 ---- if (keygen) { check_get_pass(0, never_ask_for_passphrase); ! keymgt(keygen,lifeindays); } if (sendpool) mix_send(); diff -r -C3 mixmaster-3.0/Src/mix3.h mixmaster-3.0-mymods2/Src/mix3.h *** mixmaster-3.0/Src/mix3.h 2006-06-24 14:40:39.000000000 +0100 --- mixmaster-3.0-mymods2/Src/mix3.h 2013-10-11 18:41:55.131007041 +0100 *************** *** 210,216 **** int digest_rmd160(BUFFER *b, BUFFER *md); #define KEY_ID_LEN 32 ! int keymgt(int force); int key(BUFFER *b); int adminkey(BUFFER *b); --- 210,216 ---- int digest_rmd160(BUFFER *b, BUFFER *md); #define KEY_ID_LEN 32 ! int keymgt(int force,long int lifeindays); int key(BUFFER *b); int adminkey(BUFFER *b); *************** *** 234,240 **** int pk_encrypt(BUFFER *plaintext, BUFFER *privkey); int check_seckey(BUFFER *buf, const byte id[]); int check_pubkey(BUFFER *buf, const byte id[]); ! int v2createkey(void); int getv2seckey(byte keyid[], BUFFER *key); int seckeytopub(BUFFER *pub, BUFFER *sec, byte keyid[]); --- 234,240 ---- int pk_encrypt(BUFFER *plaintext, BUFFER *privkey); int check_seckey(BUFFER *buf, const byte id[]); int check_pubkey(BUFFER *buf, const byte id[]); ! int v2createkey(long int lifeindays); int getv2seckey(byte keyid[], BUFFER *key); int seckeytopub(BUFFER *pub, BUFFER *sec, byte keyid[]); *************** *** 370,375 **** --- 370,376 ---- int v2_merge(BUFFER *mid); int mix_armor(BUFFER *in); int mix_dearmor(BUFFER *armored, BUFFER *bin); + int deleteoldkeys(void); /* type 1 */ #define HDRMARK "::" diff -r -C3 mixmaster-3.0/Src/mix.c mixmaster-3.0-mymods2/Src/mix.c *** mixmaster-3.0/Src/mix.c 2007-11-19 13:42:41.000000000 +0000 --- mixmaster-3.0-mymods2/Src/mix.c 2013-10-11 18:41:55.133007047 +0100 *************** *** 1022,1028 **** pgpmaxexp(); pool_packetexp(); stats(NULL); ! keymgt(0); return (0); } --- 1022,1028 ---- pgpmaxexp(); pool_packetexp(); stats(NULL); ! keymgt(0,0); return (0); }