Disable old RSA keys when generating new ones.
[tinc] / src / tincd.c
index b6a24da..c2660fa 100644 (file)
@@ -1,7 +1,7 @@
 /*
     tincd.c -- the main file for tincd
     Copyright (C) 1998-2005 Ivo Timmermans
-                  2000-2006 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2008 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -292,6 +292,13 @@ static bool keygen(int bits)
        char *name = NULL;
        char *filename;
 
+       get_config_string(lookup_config(config_tree, "Name"), &name);
+
+       if(name && !check_id(name)) {
+               fprintf(stderr, _("Invalid name for myself!\n"));
+               return false;
+       }
+
        fprintf(stderr, _("Generating %d bits keys:\n"), bits);
        rsa_key = RSA_generate_key(bits, 0x10001, indicator, NULL);
 
@@ -302,41 +309,41 @@ static bool keygen(int bits)
                fprintf(stderr, _("Done.\n"));
 
        asprintf(&filename, "%s/rsa_key.priv", confbase);
-       f = ask_and_open(filename, _("private RSA key"), "a");
+       f = ask_and_open(filename, _("private RSA key"));
 
        if(!f)
                return false;
+
+       if(disable_old_keys(f))
+               fprintf(stderr, _("Warning: old key(s) found and disabled.\n"));
   
 #ifdef HAVE_FCHMOD
        /* Make it unreadable for others. */
        fchmod(fileno(f), 0600);
 #endif
                
-       if(ftell(f))
-               fprintf(stderr, _("Appending key to existing contents.\nMake sure only one key is stored in the file.\n"));
-
        PEM_write_RSAPrivateKey(f, rsa_key, NULL, NULL, 0, NULL, NULL);
        fclose(f);
        free(filename);
 
-       get_config_string(lookup_config(config_tree, "Name"), &name);
-
        if(name)
                asprintf(&filename, "%s/hosts/%s", confbase, name);
        else
                asprintf(&filename, "%s/rsa_key.pub", confbase);
 
-       f = ask_and_open(filename, _("public RSA key"), "a");
+       f = ask_and_open(filename, _("public RSA key"));
 
        if(!f)
                return false;
 
-       if(ftell(f))
-               fprintf(stderr, _("Appending key to existing contents.\nMake sure only one key is stored in the file.\n"));
+       if(disable_old_keys(f))
+               fprintf(stderr, _("Warning: old key(s) found and disabled.\n"));
 
        PEM_write_RSAPublicKey(f, rsa_key);
        fclose(f);
        free(filename);
+       if(name)
+               free(name);
 
        return true;
 }
@@ -392,6 +399,14 @@ static void make_names(void)
        }
 }
 
+static void free_names() {
+       if (identname) free(identname);
+       if (netname) free(netname);
+       if (pidfilename) free(pidfilename);
+       if (logfilename) free(logfilename);
+       if (confbase) free(confbase);
+}
+
 int main(int argc, char **argv)
 {
        program_name = argv[0];
@@ -408,7 +423,7 @@ int main(int argc, char **argv)
        if(show_version) {
                printf(_("%s version %s (built %s %s, protocol %d)\n"), PACKAGE,
                           VERSION, __DATE__, __TIME__, PROT_CURRENT);
-               printf(_("Copyright (C) 1998-2006 Ivo Timmermans, Guus Sliepen and others.\n"
+               printf(_("Copyright (C) 1998-2008 Ivo Timmermans, Guus Sliepen and others.\n"
                                "See the AUTHORS file for a complete list.\n\n"
                                "tinc comes with ABSOLUTELY NO WARRANTY.  This is free software,\n"
                                "and you are welcome to redistribute it under certain conditions;\n"
@@ -498,11 +513,11 @@ int main2(int argc, char **argv)
 
        /* Shutdown properly. */
 
-       close_network_connections();
-
        ifdebug(CONNECTIONS)
                dump_device_stats();
 
+       close_network_connections();
+
 end:
        logger(LOG_NOTICE, _("Terminating"));
 
@@ -511,6 +526,13 @@ end:
 #endif
 
        EVP_cleanup();
+       ENGINE_cleanup();
+       CRYPTO_cleanup_all_ex_data();
+       ERR_remove_state(0);
+       ERR_free_strings();
+
+       exit_configuration(&config_tree);
+       free_names();
        
        return status;
 }