diff options
Diffstat (limited to 'loginutils/cryptpw.c')
-rw-r--r-- | loginutils/cryptpw.c | 144 |
1 files changed, 90 insertions, 54 deletions
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 0c1a9a0db..c179e35cf 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
@@ -3,75 +3,111 @@ | |||
3 | * cryptpw.c | 3 | * cryptpw.c |
4 | * | 4 | * |
5 | * Cooked from passwd.c by Thomas Lundquist <thomasez@zelow.no> | 5 | * Cooked from passwd.c by Thomas Lundquist <thomasez@zelow.no> |
6 | * mkpasswd compatible options added by Bernhard Reutner-Fischer | ||
6 | */ | 7 | */ |
7 | 8 | ||
8 | #include "libbb.h" | 9 | #include "libbb.h" |
9 | 10 | ||
10 | #define TESTING 0 | 11 | /* Debian has 'mkpasswd' utility, manpage says: |
11 | 12 | ||
12 | /* | 13 | NAME |
13 | set TESTING to 1 and pipe some file through this script | 14 | mkpasswd - Overfeatured front end to crypt(3) |
14 | if you played with bbox's crypt implementation. | 15 | SYNOPSIS |
16 | mkpasswd PASSWORD SALT | ||
17 | ... | ||
18 | OPTIONS | ||
19 | -S, --salt=STRING | ||
20 | Use the STRING as salt. It must not contain prefixes such as | ||
21 | $1$. | ||
22 | -R, --rounds=NUMBER | ||
23 | Use NUMBER rounds. This argument is ignored if the method | ||
24 | choosen does not support variable rounds. For the OpenBSD Blowfish | ||
25 | method this is the logarithm of the number of rounds. | ||
26 | -m, --method=TYPE | ||
27 | Compute the password using the TYPE method. If TYPE is 'help' | ||
28 | then the available methods are printed. | ||
29 | -P, --password-fd=NUM | ||
30 | Read the password from file descriptor NUM instead of using getpass(3). | ||
31 | If the file descriptor is not connected to a tty then | ||
32 | no other message than the hashed password is printed on stdout. | ||
33 | -s, --stdin | ||
34 | Like --password-fd=0. | ||
35 | ENVIRONMENT | ||
36 | $MKPASSWD_OPTIONS | ||
37 | A list of options which will be evaluated before the ones | ||
38 | specified on the command line. | ||
39 | BUGS | ||
40 | This programs suffers of a bad case of featuritis. | ||
41 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
15 | 42 | ||
16 | while read line; do | 43 | Very true... |
17 | n=`./busybox cryptpw -a des -- "$line"` | 44 | |
18 | o=`./busybox_org cryptpw -a des -- "$line"` | 45 | cryptpw was in bbox before this gem, so we retain it, and alias mkpasswd |
19 | test "$n" != "$o" && { | 46 | to cryptpw. -a option (alias for -m) came from cryptpw. |
20 | echo n="$n" | 47 | */ |
21 | echo o="$o" | ||
22 | exit | ||
23 | } | ||
24 | n=`./busybox cryptpw -- "$line"` | ||
25 | o=`./busybox_org cryptpw -- "$line"` | ||
26 | test "$n" != "$o" && { | ||
27 | echo n="$n" | ||
28 | echo o="$o" | ||
29 | exit | ||
30 | } | ||
31 | done | ||
32 | */ | ||
33 | 48 | ||
34 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 49 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
35 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) | 50 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) |
36 | { | 51 | { |
37 | char salt[sizeof("$N$") + 16 + TESTING*100]; | 52 | /* $N$ + sha_salt_16_bytes + NUL */ |
38 | char *opt_a; | 53 | char salt[3 + 16 + 1]; |
39 | int opts; | 54 | char *salt_ptr; |
40 | 55 | const char *opt_m, *opt_S; | |
41 | opts = getopt32(argv, "a:", &opt_a); | 56 | int len; |
57 | int fd; | ||
42 | 58 | ||
43 | if (opts && opt_a[0] == 'd') { | 59 | #if ENABLE_GETOPT_LONG |
44 | crypt_make_salt(salt, 2/2, 0); /* des */ | 60 | static const char mkpasswd_longopts[] ALIGN1 = |
45 | #if TESTING | 61 | "stdin\0" No_argument "s" |
46 | strcpy(salt, "a."); | 62 | "password-fd\0" Required_argument "P" |
63 | "salt\0" Required_argument "S" | ||
64 | "method\0" Required_argument "m" | ||
65 | ; | ||
66 | applet_long_options = mkpasswd_longopts; | ||
47 | #endif | 67 | #endif |
48 | } else { | 68 | fd = STDIN_FILENO; |
49 | salt[0] = '$'; | 69 | opt_m = "d"; |
50 | salt[1] = '1'; | 70 | opt_S = NULL; |
51 | salt[2] = '$'; | 71 | /* at most two non-option arguments; -P NUM */ |
72 | opt_complementary = "?2:P+"; | ||
73 | getopt32(argv, "sP:S:m:a:", &fd, &opt_S, &opt_m, &opt_m); | ||
74 | argv += optind; | ||
75 | |||
76 | /* have no idea how to handle -s... */ | ||
77 | |||
78 | if (argv[0] && !opt_S) | ||
79 | opt_S = argv[1]; | ||
80 | |||
81 | len = 2/2; | ||
82 | salt_ptr = salt; | ||
83 | if (opt_m[0] != 'd') { /* not des */ | ||
84 | len = 8/2; /* so far assuming md5 */ | ||
85 | *salt_ptr++ = '$'; | ||
86 | *salt_ptr++ = '1'; | ||
87 | *salt_ptr++ = '$'; | ||
52 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA | 88 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA |
53 | if (opts && opt_a[0] == 's') { | 89 | if (opt_m[0] == 's') { /* sha */ |
54 | salt[1] = '5' + (strcmp(opt_a, "sha512") == 0); | 90 | salt[1] = '5' + (strcmp(opt_m, "sha512") == 0); |
55 | crypt_make_salt(salt + 3, 16/2, 0); /* sha */ | 91 | len = 16/2; |
56 | #if TESTING | ||
57 | strcpy(salt, "$5$rounds=5000$toolongsaltstring"); | ||
58 | // with "This is just a test" as password, should produce: | ||
59 | // "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8mGRcvxa5" | ||
60 | strcpy(salt, "$6$rounds=5000$toolongsaltstring"); | ||
61 | // with "This is just a test" as password, should produce: | ||
62 | // "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQzQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" | ||
63 | #endif | ||
64 | } else | ||
65 | #endif | ||
66 | { | ||
67 | crypt_make_salt(salt + 3, 8/2, 0); /* md5 */ | ||
68 | #if TESTING | ||
69 | strcpy(salt + 3, "ajg./bcf"); | ||
70 | #endif | ||
71 | } | 92 | } |
93 | #endif | ||
72 | } | 94 | } |
95 | if (opt_S) | ||
96 | safe_strncpy(salt_ptr, opt_S, sizeof(salt) - 3); | ||
97 | else | ||
98 | crypt_make_salt(salt_ptr, len, 0); | ||
99 | |||
100 | xmove_fd(fd, STDIN_FILENO); | ||
73 | 101 | ||
74 | puts(pw_encrypt(argv[optind] ? argv[optind] : xmalloc_fgetline(stdin), salt, 1)); | 102 | puts(pw_encrypt( |
103 | argv[0] ? argv[0] : ( | ||
104 | /* Only mkpasswd, and only from tty, prompts. | ||
105 | * Otherwise it is a plain read. */ | ||
106 | (isatty(0) && applet_name[0] == 'm') | ||
107 | ? bb_ask(STDIN_FILENO, 0, "Password: ") | ||
108 | : xmalloc_fgetline(stdin) | ||
109 | ), | ||
110 | salt, 1)); | ||
75 | 111 | ||
76 | return 0; | 112 | return EXIT_SUCCESS; |
77 | } | 113 | } |