rev |
line source |
pascal@536
|
1 Check system passwords
|
pascal@536
|
2 --- busybox-1.19.0/networking/httpd.c
|
pascal@536
|
3 +++ busybox-1.19.0/networking/httpd.c
|
pascal@536
|
4 @@ -54,6 +54,7 @@
|
pascal@536
|
5 * /cgi-bin:foo:bar # Require user foo, pwd bar on urls starting with /cgi-bin/
|
pascal@536
|
6 * /adm:admin:setup # Require user admin, pwd setup on urls starting with /adm/
|
pascal@536
|
7 * /adm:toor:PaSsWd # or user toor, pwd PaSsWd on urls starting with /adm/
|
pascal@536
|
8 + * /adm:root:* # or user root, pwd from /etc/passwd on urls starting with /adm/
|
pascal@536
|
9 * .au:audio/basic # additional mime type for audio.au files
|
pascal@536
|
10 * *.php:/path/php # run xxx.php through an interpreter
|
pascal@536
|
11 *
|
pascal@536
|
12 @@ -1745,7 +1746,7 @@
|
pascal@536
|
13 const char *prev = NULL;
|
pascal@536
|
14
|
pascal@536
|
15 for (cur = g_auth; cur; cur = cur->next) {
|
pascal@536
|
16 - const char *dir_prefix;
|
pascal@536
|
17 + const char *dir_prefix, *passwd;
|
pascal@536
|
18 size_t len;
|
pascal@536
|
19
|
pascal@536
|
20 dir_prefix = cur->before_colon;
|
pascal@538
|
21 @@ -1770,18 +1771,53 @@
|
pascal@536
|
22 /* Path match found */
|
pascal@536
|
23 prev = dir_prefix;
|
pascal@536
|
24
|
pascal@536
|
25 + remoteuser = xstrndup(user_and_passwd,
|
pascal@536
|
26 + strchrnul(user_and_passwd, ':') - user_and_passwd);
|
pascal@536
|
27 + passwd = strchr(cur->after_colon, ':');
|
pascal@536
|
28 +
|
pascal@536
|
29 + if (passwd && passwd[1] == '*' && passwd[2] == 0) {
|
pascal@537
|
30 + struct passwd *pw = getpwnam(remoteuser);
|
pascal@538
|
31 + if (pw) {
|
pascal@538
|
32 +#if ENABLE_FEATURE_SHADOWPASSWDS
|
pascal@538
|
33 + /* Using _r function to avoid pulling in static buffers */
|
pascal@538
|
34 + struct spwd spw;
|
pascal@538
|
35 + char buffer[256];
|
pascal@538
|
36 +#endif
|
pascal@538
|
37 + const char *correct = pw->pw_passwd;
|
pascal@538
|
38 + char *unencrypted = strchr(user_and_passwd, ':');
|
pascal@538
|
39 + int r;
|
pascal@538
|
40 +
|
pascal@538
|
41 + /* Don't check the password if password entry is empty (!) */
|
pascal@538
|
42 + if (!correct[0])
|
pascal@538
|
43 + return 1; /* Ok */
|
pascal@538
|
44 +#if ENABLE_FEATURE_SHADOWPASSWDS
|
pascal@538
|
45 + if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) {
|
pascal@538
|
46 + /* getspnam_r may return 0 yet set result to NULL.
|
pascal@538
|
47 + * At least glibc 2.4 does this. Be extra paranoid here. */
|
pascal@538
|
48 + struct spwd *result = NULL;
|
pascal@538
|
49 + r = getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result);
|
pascal@538
|
50 + correct = (r || !result) ? "aa" : result->sp_pwdp;
|
pascal@538
|
51 + }
|
pascal@538
|
52 +#endif
|
pascal@538
|
53 + if (correct[0] != '!' && correct[0] != '*') {
|
pascal@538
|
54 + char *encrypted = pw_encrypt(unencrypted, correct, 1);
|
pascal@538
|
55 + r = (strcmp(encrypted, correct) == 0);
|
pascal@538
|
56 + free(encrypted);
|
pascal@538
|
57 + if (r)
|
pascal@538
|
58 + return 1; /* Ok */
|
pascal@538
|
59 + }
|
pascal@536
|
60 + free(remoteuser);
|
pascal@536
|
61 + continue;
|
pascal@536
|
62 + }
|
pascal@536
|
63 if (ENABLE_FEATURE_HTTPD_AUTH_MD5) {
|
pascal@536
|
64 - char *md5_passwd;
|
pascal@536
|
65 -
|
pascal@536
|
66 - md5_passwd = strchr(cur->after_colon, ':');
|
pascal@536
|
67 - if (md5_passwd && md5_passwd[1] == '$' && md5_passwd[2] == '1'
|
pascal@536
|
68 - && md5_passwd[3] == '$' && md5_passwd[4]
|
pascal@536
|
69 + if (passwd && passwd[1] == '$' && passwd[2] == '1'
|
pascal@536
|
70 + && passwd[3] == '$' && passwd[4]
|
pascal@536
|
71 ) {
|
pascal@536
|
72 char *encrypted;
|
pascal@536
|
73 int r, user_len_p1;
|
pascal@536
|
74
|
pascal@536
|
75 - md5_passwd++;
|
pascal@536
|
76 - user_len_p1 = md5_passwd - cur->after_colon;
|
pascal@536
|
77 + passwd++;
|
pascal@536
|
78 + user_len_p1 = passwd - cur->after_colon;
|
pascal@536
|
79 /* comparing "user:" */
|
pascal@536
|
80 if (strncmp(cur->after_colon, user_and_passwd, user_len_p1) != 0) {
|
pascal@536
|
81 continue;
|
pascal@538
|
82 @@ -1789,22 +1825,20 @@
|
pascal@536
|
83
|
pascal@536
|
84 encrypted = pw_encrypt(
|
pascal@536
|
85 user_and_passwd + user_len_p1 /* cleartext pwd from user */,
|
pascal@536
|
86 - md5_passwd /*salt */, 1 /* cleanup */);
|
pascal@536
|
87 - r = strcmp(encrypted, md5_passwd);
|
pascal@536
|
88 + passwd /*salt */, 1 /* cleanup */);
|
pascal@536
|
89 + r = strcmp(encrypted, passwd);
|
pascal@536
|
90 free(encrypted);
|
pascal@536
|
91 if (r == 0)
|
pascal@536
|
92 - goto set_remoteuser_var; /* Ok */
|
pascal@536
|
93 + return 1; /* Ok */
|
pascal@536
|
94 continue;
|
pascal@536
|
95 }
|
pascal@536
|
96 }
|
pascal@536
|
97
|
pascal@536
|
98 /* Comparing plaintext "user:pass" in one go */
|
pascal@536
|
99 - if (strcmp(cur->after_colon, user_and_passwd) == 0) {
|
pascal@536
|
100 - set_remoteuser_var:
|
pascal@536
|
101 - remoteuser = xstrndup(user_and_passwd,
|
pascal@536
|
102 - strchrnul(user_and_passwd, ':') - user_and_passwd);
|
pascal@536
|
103 + if (strcmp(cur->after_colon, user_and_passwd) == 0)
|
pascal@536
|
104 return 1; /* Ok */
|
pascal@536
|
105 - }
|
pascal@536
|
106 + free(remoteuser);
|
pascal@536
|
107 + remoteuser = NULL;
|
pascal@536
|
108 } /* for */
|
pascal@536
|
109
|
pascal@536
|
110 /* 0(bad) if prev is set: matches were found but passwd was wrong */
|