wok-undigest annotate busybox/stuff/busybox-1.19-httpd.u @ rev 538

busybox/httpd: check system passwords (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Nov 05 15:13:15 2011 +0100 (2011-11-05)
parents e3d45fb903d5
children 693eba8cf9a0
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 */