xref: /aosp_15_r20/external/toybox/toys/other/mkpasswd.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1 /* mkpasswd.c - encrypt the given passwd using salt
2  *
3  * Copyright 2013 Ashwini Kumar <[email protected]>
4  * Copyright 2013 Kyungwan Han <[email protected]>
5  *
6  * No Standard
7 
8 USE_MKPASSWD(NEWTOY(mkpasswd, ">2S:m:P#=0<0", TOYFLAG_USR|TOYFLAG_BIN))
9 
10 config MKPASSWD
11   bool "mkpasswd"
12   default y
13   depends on !TOYBOX_ON_ANDROID
14   help
15     usage: mkpasswd [-P FD] [-m TYPE] [-S SALT] [PASSWORD] [SALT]
16 
17     Encrypt PASSWORD using crypt(3), with either random or provided SALT.
18 
19     -P FD	Read password from file descriptor FD
20     -m TYPE	Encryption method (des, md5, sha256, or sha512; default is des)
21 */
22 
23 #define FOR_mkpasswd
24 #include "toys.h"
25 
26 GLOBALS(
27   long P;
28   char *m, *S;
29 )
30 
mkpasswd_main(void)31 void mkpasswd_main(void)
32 {
33   char salt[32] = {0,};
34   int ii, jj, kk;
35 
36   if (toys.optc == 2) {
37     if (TT.S) error_exit("duplicate salt");
38     TT.S = toys.optargs[1];
39   }
40 
41   if (-1 == get_salt(salt, TT.m ? : "des", !TT.S)) error_exit("bad -m");
42   if (TT.S) {
43     char *mirv = strrchr(salt, '$'), *s = TT.S;
44 
45     if (mirv) mirv++;
46     else mirv = salt;
47     ii = strlen(mirv);
48 
49     // In C locale, isalnum() means [a-zA-Z0-9]
50     while (isalnum(*s) || *s == '.' || *s == '/') s++;
51     jj = s-TT.S;
52     kk = ii==16 ? 8 : ii;
53     if (*s || jj>ii || jj<kk)
54       error_exit("bad SALT (need [a-zA-Z0-9] len %d-%d)", ii, kk);
55     strcpy(mirv, TT.S);
56   }
57 
58   // Because read_password() doesn't have an fd argument
59   if (TT.P) {
60     if (dup2(TT.P, 0) == -1) perror_exit("fd");
61     close(TT.P);
62   }
63 
64   // If we haven't got a password on the command line, read it from tty or FD
65   if (!*toys.optargs) {
66     // Prompt and read interactively?
67     if (isatty(0)) {
68       if (read_password(toybuf, sizeof(toybuf), "Password: "))
69         perror_exit("password read failed");
70     } else {
71       for (ii = 0; ii<sizeof(toybuf)-1; ii++) {
72         if (!xread(0, toybuf+ii, 1)) break;
73         if (toybuf[ii] == '\n' || toybuf[ii] == '\r') break;
74       }
75       toybuf[ii] = 0;
76     }
77   }
78 
79   // encrypt & print the password
80   xprintf("%s\n", crypt(*toys.optargs ? *toys.optargs : toybuf, salt));
81 }
82