keygen.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "platform.h"
  2. #include <sys/types.h>
  3. #include <sys/file.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <stdint.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <termios.h>
  11. #include <unistd.h>
  12. #include "crypto.h"
  13. #include "getopt.h"
  14. #include "humansize.h"
  15. #include "keyfile.h"
  16. #include "keygen.h"
  17. #include "readpass.h"
  18. #include "sysendian.h"
  19. #include "tarsnap_opt.h"
  20. #include "tsnetwork.h"
  21. #include "warnp.h"
  22. static void usage(void);
  23. /* Be noisy about network errors while registering a machine. */
  24. int tarsnap_opt_noisy_warnings = 1;
  25. static void
  26. usage(void)
  27. {
  28. fprintf(stderr, "usage: tarsnap-keygen %s %s %s %s %s %s\n",
  29. "--keyfile key-file", "--user user-name",
  30. "--machine machine-name",
  31. "[--passphrased]", "[--passphrase-mem maxmem]",
  32. "[--passphrase-time maxtime]");
  33. fprintf(stderr, " tarsnap-keygen --version\n");
  34. exit(1);
  35. /* NOTREACHED */
  36. }
  37. int
  38. main(int argc, char **argv)
  39. {
  40. struct register_internal C;
  41. const char * keyfilename;
  42. int passphrased;
  43. uint64_t maxmem;
  44. double maxtime;
  45. const char * ch;
  46. WARNP_INIT;
  47. /* We have no username, machine name, or key filename yet. */
  48. C.user = C.name = NULL;
  49. keyfilename = NULL;
  50. /*
  51. * So far we're not using a passphrase, have unlimited RAM, and allow
  52. * up to 1 second of CPU time.
  53. */
  54. passphrased = 0;
  55. maxmem = 0;
  56. maxtime = 1.0;
  57. /* Parse arguments. */
  58. while ((ch = GETOPT(argc, argv)) != NULL) {
  59. GETOPT_SWITCH(ch) {
  60. GETOPT_OPTARG("--user"):
  61. if (C.user != NULL)
  62. usage();
  63. C.user = optarg;
  64. break;
  65. GETOPT_OPTARG("--machine"):
  66. if (C.name != NULL)
  67. usage();
  68. C.name = optarg;
  69. break;
  70. GETOPT_OPTARG("--keyfile"):
  71. if (keyfilename != NULL)
  72. usage();
  73. keyfilename = optarg;
  74. break;
  75. GETOPT_OPTARG("--passphrase-mem"):
  76. if (maxmem != 0)
  77. usage();
  78. if (humansize_parse(optarg, &maxmem)) {
  79. warnp("Cannot parse --passphrase-mem"
  80. " argument: %s", optarg);
  81. exit(1);
  82. }
  83. break;
  84. GETOPT_OPTARG("--passphrase-time"):
  85. if (maxtime != 1.0)
  86. usage();
  87. maxtime = strtod(optarg, NULL);
  88. if ((maxtime < 0.05) || (maxtime > 86400)) {
  89. warn0("Invalid --passphrase-time argument: %s",
  90. optarg);
  91. exit(1);
  92. }
  93. break;
  94. GETOPT_OPT("--passphrased"):
  95. if (passphrased != 0)
  96. usage();
  97. passphrased = 1;
  98. break;
  99. GETOPT_OPT("--version"):
  100. fprintf(stderr, "tarsnap-keygen %s\n",
  101. PACKAGE_VERSION);
  102. exit(0);
  103. GETOPT_MISSING_ARG:
  104. warn0("Missing argument to %s", ch);
  105. /* FALLTHROUGH */
  106. GETOPT_DEFAULT:
  107. usage();
  108. }
  109. }
  110. argc -= optind;
  111. argv += optind;
  112. /* We should have processed all the arguments. */
  113. if (argc != 0)
  114. usage();
  115. (void)argv; /* argv is not used beyond this point. */
  116. /* We must have a user name, machine name, and key file specified. */
  117. if ((C.user == NULL) || (C.name == NULL) || (keyfilename == NULL))
  118. usage();
  119. /*
  120. * It doesn't make sense to specify --passphrase-mem or
  121. * --passphrase-time if we're not using a passphrase.
  122. */
  123. if (((maxmem != 0) || (maxtime != 1.0)) && (passphrased == 0))
  124. usage();
  125. /*
  126. * Use shared code between keygen and keyregen for the actual
  127. * processing. The NULL parameter is the oldkeyfilename (used for
  128. * keyregen)
  129. */
  130. if (keygen_actual(&C, keyfilename, passphrased, maxmem, maxtime,
  131. NULL) != 0)
  132. goto err0;
  133. /* Success! */
  134. return (0);
  135. err0:
  136. /* Failure! */
  137. return (1);
  138. }