/* * Password / Login checker. Developed on Linux, might work elsewhere. * Supports /etc/passwd and /etc/shadow. * * Reads login:password (in plain text) from standard input, and prints * "true" on standard input if authentication is successful, "false" or * nothing otherwise. * * Should be pretty secure. * * (c) Frank Pilhofer 1999, fp@fpx.de. */ #include #include #include #include #include #include #include char login[64], password[64]; void sighdlr (int sig) { memset (login, 0, 64); memset (password, 0, 64); printf ("false\n"); exit (1); } int main (int argc, char *argv[]) { struct passwd * pwdata; struct spwd * spwdata; char *pwd, *ptr; int i, c; umask (0777); chdir ("/"); signal (SIGINT, sighdlr); signal (SIGQUIT, sighdlr); signal (SIGALRM, sighdlr); signal (SIGPIPE, sighdlr); for (i=0; ipw_passwd) == 0 && !password[0]) { goto true; } /* * Shadow Password ? */ if (strlen (pwdata->pw_passwd) == 13) { pwd = pwdata->pw_passwd; } else { if ((spwdata = getspnam (login)) == NULL) { goto false; } /* * Empty password */ if (strlen (spwdata->sp_pwdp) == 0 && !password[0]) { goto true; } if (strlen (spwdata->sp_pwdp) != 13) { goto false; } pwd = spwdata->sp_pwdp; } /* * Encrypt user's password and compare */ if ((ptr = crypt (password, pwd)) == NULL) { goto false; } if (strncmp (ptr, pwd, 13) == 0) { goto true; } false: memset (login, 0, 64); memset (password, 0, 64); printf ("false\n"); exit (1); true: memset (login, 0, 64); memset (password, 0, 64); printf ("true\n"); exit (0); }