Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/libbb/correct_password.c

    r3232 r3621  
    3131#include "libbb.h"
    3232
    33 /* Ask the user for a password.
    34  * Return 1 if the user gives the correct password for entry PW,
    35  * 0 if not.  Return 1 without asking if PW has an empty password.
    36  *
    37  * NULL pw means "just fake it for login with bad username" */
     33#define SHADOW_BUFSIZE 256
    3834
    39 int FAST_FUNC correct_password(const struct passwd *pw)
     35/* Retrieve encrypted password string for pw.
     36 * If pw == NULL, return a string which fails password check against any
     37 * password.
     38 */
     39#if !ENABLE_FEATURE_SHADOWPASSWDS
     40#define get_passwd(pw, buffer) get_passwd(pw)
     41#endif
     42static const char *get_passwd(const struct passwd *pw, char buffer[SHADOW_BUFSIZE])
    4043{
    41     char *unencrypted, *encrypted;
    42     const char *correct;
    43     int r;
    44     /* fake salt. crypt() can choke otherwise. */
    45     correct = "aa";
    46     if (!pw) {
    47         /* "aa" will never match */
    48         goto fake_it;
    49     }
    50     correct = pw->pw_passwd;
     44    const char *pass;
     45
     46    if (!pw)
     47        return "aa"; /* "aa" will never match */
     48
     49    pass = pw->pw_passwd;
    5150#if ENABLE_FEATURE_SHADOWPASSWDS
    5251    /* Using _r function to avoid pulling in static buffers */
    53     if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) {
     52    if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) {
    5453        struct spwd spw;
    55         char buffer[256];
     54        int r;
    5655        /* getspnam_r may return 0 yet set result to NULL.
    5756         * At least glibc 2.4 does this. Be extra paranoid here. */
    5857        struct spwd *result = NULL;
    59         r = getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result);
    60         correct = (r || !result) ? "aa" : result->sp_pwdp;
     58        r = getspnam_r(pw->pw_name, &spw, buffer, SHADOW_BUFSIZE, &result);
     59        pass = (r || !result) ? "aa" : result->sp_pwdp;
    6160    }
    6261#endif
     62    return pass;
     63}
    6364
    64     if (!correct[0]) /* empty password field? */
     65/*
     66 * Return 1 if PW has an empty password.
     67 * Return 1 if the user gives the correct password for entry PW,
     68 * 0 if not.
     69 * NULL pw means "just fake it for login with bad username"
     70 */
     71int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext)
     72{
     73    IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];)
     74    char *encrypted;
     75    const char *pw_pass;
     76    int r;
     77
     78    pw_pass = get_passwd(pw, buffer);
     79    if (!pw_pass[0]) { /* empty password field? */
     80        return 1;
     81    }
     82
     83    encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1);
     84    r = (strcmp(encrypted, pw_pass) == 0);
     85    free(encrypted);
     86    return r;
     87}
     88
     89
     90/* Ask the user for a password.
     91 * Return 1 without asking if PW has an empty password.
     92 * Return -1 on EOF, error while reading input, or timeout.
     93 * Return 1 if the user gives the correct password for entry PW,
     94 * 0 if not.
     95 *
     96 * NULL pw means "just fake it for login with bad username"
     97 */
     98int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw,
     99        int timeout, const char *prompt)
     100{
     101    IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];)
     102    char *plaintext;
     103    const char *pw_pass;
     104    int r;
     105
     106    pw_pass = get_passwd(pw, buffer);
     107    if (!pw_pass[0]) /* empty password field? */
    65108        return 1;
    66109
    67  fake_it:
    68     unencrypted = bb_ask_stdin("Password: ");
    69     if (!unencrypted) {
    70         return 0;
     110    plaintext = bb_ask(STDIN_FILENO, timeout, prompt);
     111    if (!plaintext) {
     112        /* EOF (such as ^D) or error (such as ^C) or timeout */
     113        return -1;
    71114    }
    72     encrypted = pw_encrypt(unencrypted, correct, 1);
    73     r = (strcmp(encrypted, correct) == 0);
    74     free(encrypted);
    75     memset(unencrypted, 0, strlen(unencrypted));
     115
     116    r = check_password(pw, plaintext);
     117    nuke_str(plaintext);
    76118    return r;
    77119}
     120
     121int FAST_FUNC ask_and_check_password(const struct passwd *pw)
     122{
     123    return ask_and_check_password_extended(pw, 0, "Password: ");
     124}
Note: See TracChangeset for help on using the changeset viewer.