aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2018-06-29 18:27:59 -0500
committerRob Landley <rob@landley.net>2018-06-29 18:27:59 -0500
commitde365c8a091ac758f83de68d8986a54959063067 (patch)
tree7eedcf1de6c30703fd25b86c3f74902fb61555a7
parent753f2faa0b38af2d69d91a4a52a71b15a1d72306 (diff)
downloadtoybox-de365c8a091ac758f83de68d8986a54959063067.tar.gz
Cleanup pass on passwd, needs more testing.
-rw-r--r--toys/lsb/passwd.c181
1 files changed, 53 insertions, 128 deletions
diff --git a/toys/lsb/passwd.c b/toys/lsb/passwd.c
index 687d4c09..e23de1c6 100644
--- a/toys/lsb/passwd.c
+++ b/toys/lsb/passwd.c
@@ -26,10 +26,10 @@ config PASSWD_SAD
default n
depends on PASSWD
help
- Password changes are checked to make sure they don't include the entire
- username (but not a subset of it), and the entire previous password
- (but changing password1, password2, password3 is fine). This heuristic
- accepts "aaaaaa" as a password.
+ Password changes are checked to make sure they're at least 6 chars long,
+ don't include the entire username (but not a subset of it), or the entire
+ previous password (but changing password1, password2, password3 is fine).
+ This heuristic accepts "aaaaaa" and "123456".
*/
#define FOR_passwd
@@ -39,153 +39,78 @@ GLOBALS(
char *algo;
)
-static int str_check(char *s, char *p)
+// Sad advisory heuristic, won't find password1 password2 password3...
+static void weak_check(char *new, char *old, char *user)
{
- if (strnstr(s, p) || strnstr(p, s)) return 1;
- return 0;
-}
-
-// Insane heuristic won't find password1 password2 password3...?
-static void strength_check(char *newp, char *oldp, char *user)
-{
- char *msg = NULL;
-
- if (strlen(newp) < 6) { //Min passwd len
- msg = "too short";
- xprintf("BAD PASSWORD: %s\n",msg);
- }
- if (!newp[0]) return; //passwd is empty
-
- if (str_check(newp, user)) {
- msg = "user based password";
- xprintf("BAD PASSWORD: %s\n",msg);
- }
-
- if (oldp[0] && str_check(newp, oldp)) {
- msg = "based on old passwd";
- xprintf("BAD PASSWORD: %s\n",msg);
- }
-}
-
-static int verify_passwd(char * pwd)
-{
- char * pass;
-
- if (!pwd) return 1;
- if (pwd[0] == '!' || pwd[0] == '*') return 1;
-
- pass = crypt(toybuf, pwd);
- if (pass && !strcmp(pass, pwd)) return 0;
-
- return 1;
-}
+ char *msg = 0;
-static char *new_password(char *oldp, char *user)
-{
- char *newp = NULL;
-
- if (read_password(toybuf, sizeof(toybuf), "New password:"))
- return NULL; //may be due to Ctrl-C
-
- newp = xstrdup(toybuf);
- if (CFG_PASSWD_SAD) strength_check(newp, oldp, user);
- if (read_password(toybuf, sizeof(toybuf), "Retype password:")) {
- free(newp);
- return NULL; //may be due to Ctrl-C
+ if (strlen(new) < 6) msg = "too short";
+ if (*new) {
+ if (strnstr(new, user) || strnstr(user, new)) msg = "user";
+ if (*old && (strnstr(new, old) || strnstr(old, new))) msg = "old";
}
-
- if (!strcmp(newp, toybuf)) return newp;
- else error_msg("Passwords do not match.\n");
- // Failure Case
- free(newp);
- return NULL;
+ if (msg) xprintf("BAD PASSWORD: %s\n",msg);
}
void passwd_main(void)
{
uid_t myuid;
- struct passwd *pw;
+ struct passwd *pw = 0;
struct spwd *sp;
- char *name = NULL, *pass = NULL, *encrypted = NULL, *newp = NULL,
- *orig = (char *)"", salt[MAX_SALT_LEN];
+ char *pass, *name, *encrypted = 0, salt[MAX_SALT_LEN];
int ret = -1;
- myuid = getuid();
- if (myuid && (toys.optflags & (FLAG_l | FLAG_u | FLAG_d)))
- error_exit("Not root");
-
- pw = xgetpwuid(myuid);
-
- if (*toys.optargs) name = toys.optargs[0];
- else name = xstrdup(pw->pw_name);
-
- pw = xgetpwnam(name);
-
- if (myuid && (myuid != pw->pw_uid)) error_exit("Not root");
-
- pass = pw->pw_passwd;
- if (pw->pw_passwd[0] == 'x') {
- //get shadow passwd
- sp = getspnam(name);
- if (sp) pass = sp->sp_pwdp;
+ // If we're root or not -lud, load specified user. Exit if not allowed.
+ if (!(myuid = getuid()) || !(toys.optflags&(FLAG_l|FLAG_u|FLAG_d))) {
+ if (*toys.optargs) pw = xgetpwnam(*toys.optargs);
+ else pw = xgetpwuid(myuid);
}
+ if (!pw || (myuid && (myuid != pw->pw_uid))) error_exit("Not root");
+ // Get password from /etc/passwd or /etc/shadow
+ // TODO: why still support non-shadow passwords...?
+ name = pw->pw_name;
+ if (*(pass = pw->pw_passwd)=='x' && (sp = getspnam(name))) pass = sp->sp_pwdp;
- if (!(toys.optflags & (FLAG_l | FLAG_u | FLAG_d))) {
-
- if (!(toys.optflags & FLAG_a)) TT.algo = "des";
- if (get_salt(salt, TT.algo) == -1)
- error_exit("Error: Unkown encryption algorithm\n");
+ if (toys.optflags & FLAG_l) {
+ if (*pass=='!') error_exit("already locked");
+ printf("Locking '%s'\n", name);
+ encrypted = xmprintf("!%s", pass);
+ } else if (toys.optflags & FLAG_u) {
+ if (*pass!='!') error_exit("already unlocked");
+ printf("Unlocking '%s'\n", name);
+ encrypted = pass+1;
+ } else if (toys.optflags & FLAG_d) {
+ printf("Deleting password for '%s'\n", name);
+ encrypted = "";
+ } else {
+ if (get_salt(salt, TT.algo ? TT.algo : "des")<0)
+ error_exit("bad -a '%s'", TT.algo);
- printf("Changing password for %s\n",name);
- if (myuid && pass[0] == '!')
- error_exit("Can't change, password is locked for %s",name);
+ printf("Changing password for %s\n", name);
if (myuid) {
- //Validate user
-
- if (read_password(toybuf, sizeof(toybuf), "Origial password:")) {
- if (!toys.optargs[0]) free(name);
- return;
- }
- orig = toybuf;
- if (verify_passwd(pass)) error_exit("Authentication failed\n");
- }
+ if (*pass=='!') error_exit("'%s' locked", name);
- orig = xstrdup(orig);
-
- // Get new password
- newp = new_password(orig, name);
- if (!newp) {
- free(orig);
- if (!toys.optargs[0]) free(name);
- return; //new password is not set well.
+ if (read_password(toybuf+2048, 2048, "Old password:")) return;
+ pass = crypt(toybuf+2048, pw->pw_passwd);
+ if (!pass || strcmp(pass, pw->pw_passwd)) error_exit("No");
}
- encrypted = crypt(newp, salt);
- free(newp);
- free(orig);
- } else if (toys.optflags & FLAG_l) {
- if (pass[0] == '!') error_exit("password is already locked for %s",name);
- printf("Locking password for %s\n",name);
- encrypted = xmprintf("!%s",pass);
- } else if (toys.optflags & FLAG_u) {
- if (pass[0] != '!') error_exit("password is already unlocked for %s",name);
+ if (read_password(toybuf, 2048, "New password:")) return;
- printf("Unlocking password for %s\n",name);
- encrypted = xstrdup(&pass[1]);
- } else if (toys.optflags & FLAG_d) {
- printf("Deleting password for %s\n",name);
- encrypted = xstrdup(""); //1 = "", 2 = '\0'
+ if (CFG_PASSWD_SAD) weak_check(toybuf, toybuf+2048, name);
+ if (read_password(toybuf+2048, 2048, "Retype password:")) return;
+ if (strcmp(toybuf, toybuf+2048)) error_exit("Passwords do not match.");
+
+ encrypted = crypt(toybuf, salt);
}
// Update the passwd
- if (pw->pw_passwd[0] == 'x')
- ret = update_password("/etc/shadow", name, encrypted);
- else ret = update_password("/etc/passwd", name, encrypted);
+ ret = update_password(*pw->pw_passwd=='x' ? "/etc/shadow" : "/etc/passwd",
+ name, encrypted);
- if ((toys.optflags & (FLAG_l | FLAG_u | FLAG_d))) free(encrypted);
+ if (ret) error_msg("Failure");
+ else fprintf(stderr, "Success\n");
- if (!toys.optargs[0]) free(name);
- if (!ret) error_msg("Success");
- else error_msg("Failure");
+ if (CFG_TOYBOX_FREE && (toys.optflags & FLAG_l)) free(encrypted);
}