Date: Mon, 21 Jan 2002 01:02:56 +0300 From: "Andrey A. Chernov" <ache@nagual.pp.ru> To: markm@freebsd.org, des@freebsd.org, current@freebsd.org Subject: Step5, pam_opie OPIE auth fix for review Message-ID: <20020120220254.GA25886@nagual.pp.ru>
next in thread | raw e-mail | index | archive | help
Bug: pam_opie module _always_ allows Unix (plaintext) password, even in the cases which are disabled by OPIE auth procedure. Description: How non-PAM standalone OPIE works: 1) If OPIE user exists, its remote host checked against /etc/opieaccess via opieaccessfile() 2) If remote host is found there, user home dir checked for ~/.opiealways file via opiealways() 3) If no such file, it is assumed than OPIE user is allowed to authenticate with plaintext (Unix) password additionly to OPIE exchange. In all other cases OPIE user is not allowed to authenticate with plaintext (Unix) password. How PAM OPIE works: OPIE user can _always_ authenticate with plaintext (Unix) password which is is security lowering and violates OPIE way of things. Fix: It can't be fixed in current 2-state pam_opie return codes model, we need 3 codes: 1) For OPIE exchange success 2) For OPIE exchange failure, but Unix (plaintext) passwords allowed 3) For OPIE exchange failure, but Unix (plaintext) passwords disabled 1) and 2) works exact as in old 2-state model, so 1) is PAM_SUCCESS and 2) is PAM_AUTH_ERR. I choose PAM_CRED_INSUFFICIENT for case 3) which means that pam_opie module deside that all additionally possible auth will be insufficient and returns immediately from modules chain with this code. --- pam_opie.c.old Sun Jan 20 23:56:47 2002 +++ pam_opie.c Mon Jan 21 00:24:51 2002 @@ -66,13 +66,14 @@ struct opie opie; struct options options; struct passwd *pwd; - int retval, i; + int retval, i, pwok; char *(promptstr[]) = { "%s\nPassword: ", "%s\nPassword [echo on]: "}; char challenge[OPIE_CHALLENGE_MAX]; char prompt[OPIE_CHALLENGE_MAX+22]; char resp[OPIE_SECRET_MAX]; const char *user; const char *response; + const char *rhost; pam_std_option(&options, other_options, argc, argv); @@ -97,6 +98,8 @@ retval = pam_get_user(pamh, (const char **)&user, NULL); if (retval != PAM_SUCCESS) PAM_RETURN(retval); + if ((pwd = getpwnam(user)) == NULL) + PAM_RETURN(PAM_AUTH_ERR); } PAM_LOG("Got user: %s", user); @@ -107,7 +110,14 @@ */ opiedisableaeh(); - opiechallenge(&opie, (char *)user, challenge); + if (opiechallenge(&opie, (char *)user, challenge) == 0) { + rhost = NULL; + (void) pam_get_item(pamh, PAM_RHOST, (const void **)&rhost); + pwok = (rhost != NULL) && (*rhost != '\0') && + opieaccessfile((char *)rhost) && + opiealways(pwd->pw_dir); + } else + pwok = 1; for (i = 0; i < 2; i++) { snprintf(prompt, sizeof prompt, promptstr[i], challenge); retval = pam_get_pass(pamh, &response, prompt, &options); @@ -134,7 +144,10 @@ * it expects. Thus we can't log an error and can only check for * success or lack thereof. */ - retval = opieverify(&opie, resp) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR; + if (opieverify(&opie, resp) != 0) + retval = pwok ? PAM_AUTH_ERR : PAM_CRED_INSUFFICIENT; + else + retval = PAM_SUCCESS; PAM_RETURN(retval); } --- ftpd.c.bak Sat Jan 19 21:29:50 2002 +++ ftpd.c Mon Jan 21 00:30:03 2002 @@ -1190,6 +1190,7 @@ break; case PAM_AUTH_ERR: + case PAM_CRED_INSUFFICIENT: case PAM_USER_UNKNOWN: case PAM_MAXTRIES: rval = 1; --- login.c.bak Sat Jan 19 21:05:16 2002 +++ login.c Mon Jan 21 00:31:45 2002 @@ -802,6 +802,7 @@ break; case PAM_AUTH_ERR: + case PAM_CRED_INSUFFICIENT: case PAM_USER_UNKNOWN: case PAM_MAXTRIES: rval = 1; --- su.bak Sat Jan 19 21:29:49 2002 +++ su Mon Jan 21 00:39:04 2002 @@ -9,7 +9,7 @@ auth requisite pam_wheel.so no_warn auth_as_self noroot_ok #auth sufficient pam_kerberosIV.so no_warn #auth sufficient pam_krb5.so no_warn try_first_pass auth_as_self -#auth required pam_opie.so no_warn +#auth [defalt=ignore success=done cred_insufficient=die] pam_opie.so no_warn #auth required pam_ssh.so no_warn try_first_pass auth required pam_unix.so no_warn try_first_pass nullok #auth sufficient pam_rootok.so no_warn --- login.bak Sat Jan 19 21:29:49 2002 +++ login Mon Jan 21 00:39:04 2002 @@ -6,7 +6,7 @@ # auth auth required pam_nologin.so no_warn -#auth sufficient pam_opie.so no_warn +#auth [defalt=ignore success=done cred_insufficient=die] pam_opie.so no_warn #auth sufficient pam_kerberosIV.so no_warn try_first_pass #auth sufficient pam_krb5.so no_warn try_first_pass #auth required pam_ssh.so no_warn try_first_pass --- ftpd.bak Sat Jan 19 21:29:49 2002 +++ ftpd Mon Jan 21 00:39:04 2002 @@ -9,10 +9,8 @@ #auth sufficient pam_kerberosIV.so no_warn #auth sufficient pam_krb5.so no_warn #auth sufficient pam_ssh.so no_warn try_first_pass -# Uncomment either pam_opie or pam_unix, but not both of them. -# pam_unix can't be simple chained with pam_opie, ftpd provides proper fallback -auth required pam_opie.so no_warn -#auth required pam_unix.so no_warn try_first_pass +#auth [defalt=ignore success=done cred_insufficient=die] pam_opie.so no_warn +auth required pam_unix.so no_warn try_first_pass # account #account required pam_kerberosIV.so -- Andrey A. Chernov http://ache.pp.ru/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020120220254.GA25886>