master xplshn/aruu / cmd / xsi / mkpasswd.c
 1/* see LICENSE file for copyright and license details */
 2#include "passwd.h"
 3#include "util.h"
 4
 5#include <crypt.h>
 6#include <stdio.h>
 7#include <stdlib.h>
 8#include <string.h>
 9#include <termios.h>
10#include <unistd.h>
11
12static void
13usage(void)
14{
15  eprintf("usage: %s [password]\n", argv0);
16}
17
18// ?man mkpasswd: generate a crypt(3) password hash
19// ?man arguments: [password]
20// ?man hash a password for use in /etc/passwd or /etc/shadow. reads
21// ?man the password from the command line, or prompts for it if not given
22int
23main(int argc, char *argv[])
24{
25  static char    buf[128];
26  struct termios old, raw;
27  char           salt[PW_SALT_MAX];
28  char          *pass, *hash;
29  int            have_old;
30  size_t         n;
31
32  ARGBEGIN
33  {
34    default:
35      usage();
36  }
37  ARGEND
38
39  if (argc > 0) {
40    pass = argv[0];
41  } else {
42    fputs("Password: ", stdout);
43    fflush(stdout);
44
45    have_old = tcgetattr(STDIN_FILENO, &old) == 0;
46    if (have_old) {
47      raw = old;
48      raw.c_lflag &= ~ECHO;
49      tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
50    }
51
52    if (!fgets(buf, sizeof(buf), stdin)) {
53      if (have_old)
54        tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
55      exit(1);
56    }
57
58    if (have_old) {
59      tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
60      fputc('\n', stdout);
61    }
62
63    n = strlen(buf);
64    if (n && buf[n - 1] == '\n')
65      buf[--n] = '\0';
66    pass = buf;
67  }
68
69  pw_init();
70  if (pw_gensalt(salt, sizeof(salt)) < 0)
71    eprintf("mkpasswd: cannot generate salt\n");
72
73  hash = crypt(pass, salt);
74  if (!hash)
75    eprintf("mkpasswd: crypt:");
76
77  printf("%s\n", hash);
78  return 0;
79}