Bug & warning fixes; pretty much what will become 0.5 later this week.

Submitted by:	Solar Designer <solar@openwall.com>
This commit is contained in:
Dag-Erling Smørgrav 2002-04-14 22:30:54 +00:00
parent 0b0ecb56f2
commit 402783abd1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/pam_modules/dist/; revision=94691
6 changed files with 88 additions and 72 deletions

View File

@ -11,8 +11,11 @@ module prompts for the old password, things should work either way.
FreeBSD.
Currently, FreeBSD doesn't use PAM for password changing. This means
you won't be able to use pam_passwdqc with FreeBSD.
As of this writing (April 2002), FreeBSD-current is moving to OpenPAM
which pam_passwdqc already includes support for. The next step would
be for FreeBSD to start actually using PAM from password changing.
Once that becomes a reality, you should be able to use pam_passwdqc
with FreeBSD.
Solaris.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000,2001 by Solar Designer. See LICENSE.
* Copyright (c) 2000-2002 by Solar Designer. See LICENSE.
*/
#define _XOPEN_SOURCE 500
@ -28,16 +28,17 @@
#define PAM_EXTERN extern
#endif
#if !defined(PAM_AUTHTOK_RECOVER_ERR) && defined(PAM_AUTHTOK_RECOVERY_ERR)
#define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
#if !defined(PAM_AUTHTOK_RECOVERY_ERR) && defined(PAM_AUTHTOK_RECOVER_ERR)
#define PAM_AUTHTOK_RECOVERY_ERR PAM_AUTHTOK_RECOVER_ERR
#endif
#if defined(__sun__) && !defined(LINUX_PAM)
#define linux_const /* Sun's PAM doesn't use const here */
#if defined(__sun__) && !defined(LINUX_PAM) && !defined(_OPENPAM)
/* Sun's PAM doesn't use const here */
#define lo_const
#else
#define linux_const const
#define lo_const const
#endif
typedef linux_const void *pam_item_t;
typedef lo_const void *pam_item_t;
#include "passwdqc.h"
@ -128,7 +129,7 @@ static params_t defaults = {
#define MESSAGE_RETRY \
"Try again."
static int converse(pam_handle_t *pamh, int style, char *text,
static int converse(pam_handle_t *pamh, int style, lo_const char *text,
struct pam_response **resp)
{
struct pam_conv *conv;
@ -144,7 +145,7 @@ static int converse(pam_handle_t *pamh, int style, char *text,
msg.msg = text;
*resp = NULL;
return conv->conv(1, (linux_const struct pam_message **)&pmsg, resp,
return conv->conv(1, (lo_const struct pam_message **)&pmsg, resp,
conv->appdata_ptr);
}
@ -163,7 +164,7 @@ static int say(pam_handle_t *pamh, int style, const char *format, ...)
needed = vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
if (needed > 0 && needed < sizeof(buffer)) {
if ((unsigned int)needed < sizeof(buffer)) {
status = converse(pamh, style, buffer, &resp);
_pam_overwrite(buffer);
} else {
@ -174,9 +175,9 @@ static int say(pam_handle_t *pamh, int style, const char *format, ...)
return status;
}
static int check_max(params_t *params, pam_handle_t *pamh, char *newpass)
static int check_max(params_t *params, pam_handle_t *pamh, const char *newpass)
{
if (strlen(newpass) > params->qc.max) {
if ((int)strlen(newpass) > params->qc.max) {
if (params->qc.max != 8) {
say(pamh, PAM_ERROR_MSG, MESSAGE_TOOLONG);
return -1;
@ -191,6 +192,7 @@ static int parse(params_t *params, pam_handle_t *pamh,
int argc, const char **argv)
{
const char *p;
char *e;
int i;
unsigned long v;
@ -201,28 +203,30 @@ static int parse(params_t *params, pam_handle_t *pamh,
if (!strncmp(p, "disabled", 8)) {
v = INT_MAX;
p += 8;
} else
v = strtoul(p, (char **)&p, 10);
} else {
v = strtoul(p, &e, 10);
p = e;
}
if (i < 4 && *p++ != ',') break;
if (v > INT_MAX) break;
if (i && v > params->qc.min[i - 1]) break;
if (i && (int)v > params->qc.min[i - 1]) break;
params->qc.min[i] = v;
}
if (*p) break;
} else
if (!strncmp(*argv, "max=", 4)) {
v = strtoul(*argv + 4, (char **)&p, 10);
if (*p || v < 8 || v > INT_MAX) break;
v = strtoul(*argv + 4, &e, 10);
if (*e || v < 8 || v > INT_MAX) break;
params->qc.max = v;
} else
if (!strncmp(*argv, "passphrase=", 11)) {
v = strtoul(*argv + 11, (char **)&p, 10);
if (*p || v > INT_MAX) break;
v = strtoul(*argv + 11, &e, 10);
if (*e || v > INT_MAX) break;
params->qc.passphrase_words = v;
} else
if (!strncmp(*argv, "match=", 6)) {
v = strtoul(*argv + 6, (char **)&p, 10);
if (*p || v > INT_MAX) break;
v = strtoul(*argv + 6, &e, 10);
if (*e || v > INT_MAX) break;
params->qc.match_length = v;
} else
if (!strncmp(*argv, "similar=", 8)) {
@ -235,12 +239,12 @@ static int parse(params_t *params, pam_handle_t *pamh,
break;
} else
if (!strncmp(*argv, "random=", 7)) {
v = strtoul(*argv + 7, (char **)&p, 10);
if (!strcmp(p, ",only")) {
p += 5;
v = strtoul(*argv + 7, &e, 10);
if (!strcmp(e, ",only")) {
e += 5;
params->qc.min[4] = INT_MAX;
}
if (*p || v > INT_MAX) break;
if (*e || v > INT_MAX) break;
params->qc.random_bits = v;
} else
if (!strncmp(*argv, "enforce=", 8)) {
@ -259,8 +263,8 @@ static int parse(params_t *params, pam_handle_t *pamh,
params->flags |= F_NON_UNIX;
} else
if (!strncmp(*argv, "retry=", 6)) {
v = strtoul(*argv + 6, (char **)&p, 10);
if (*p || v > INT_MAX) break;
v = strtoul(*argv + 6, &e, 10);
if (*e || v > INT_MAX) break;
params->retry = v;
} else
if (!strncmp(*argv, "ask_oldauthtok", 14)) {
@ -308,7 +312,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
struct spwd *spw;
#endif
char *user, *oldpass, *newpass, *randompass;
char *reason;
const char *reason;
int ask_oldauthtok;
int randomonly, enforce, retries_left, retry_wanted;
int status;
@ -339,7 +343,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
PAM_OLDAUTHTOK, resp->resp);
_pam_drop_reply(resp, 1);
} else
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
}
if (status != PAM_SUCCESS)
@ -406,12 +410,12 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (status != PAM_SUCCESS)
return status;
if (!newpass || (check_max(&params, pamh, newpass) && enforce))
return PAM_AUTHTOK_RECOVER_ERR;
return PAM_AUTHTOK_RECOVERY_ERR;
reason = _passwdqc_check(&params.qc, newpass, oldpass, pw);
if (reason) {
say(pamh, PAM_ERROR_MSG, MESSAGE_WEAKPASS, reason);
if (enforce)
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
}
return status;
}
@ -465,12 +469,12 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (randomonly) {
say(pamh, PAM_ERROR_MSG, getuid() != 0 ?
MESSAGE_MISCONFIGURED : MESSAGE_RANDOMFAILED);
return PAM_AUTHTOK_RECOVER_ERR;
return PAM_AUTHTOK_RECOVERY_ERR;
}
status = converse(pamh, PAM_PROMPT_ECHO_OFF, PROMPT_NEWPASS1, &resp);
if (status == PAM_SUCCESS && (!resp || !resp->resp))
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
if (status != PAM_SUCCESS) {
if (randompass) _pam_overwrite(randompass);
@ -483,11 +487,11 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (!newpass) {
if (randompass) _pam_overwrite(randompass);
return PAM_AUTHTOK_RECOVER_ERR;
return PAM_AUTHTOK_RECOVERY_ERR;
}
if (check_max(&params, pamh, newpass) && enforce) {
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
retry_wanted = 1;
}
@ -501,7 +505,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
else
say(pamh, PAM_ERROR_MSG, MESSAGE_WEAKPASS, reason);
if (enforce) {
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
retry_wanted = 1;
}
}
@ -515,13 +519,13 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
status = say(pamh,
PAM_ERROR_MSG, MESSAGE_MISTYPED);
if (status == PAM_SUCCESS) {
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
retry_wanted = 1;
}
}
_pam_drop_reply(resp, 1);
} else
status = PAM_AUTHTOK_RECOVER_ERR;
status = PAM_AUTHTOK_RECOVERY_ERR;
}
if (status == PAM_SUCCESS)
@ -540,7 +544,9 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
return status;
}
#ifdef PAM_STATIC
#ifdef PAM_MODULE_ENTRY
PAM_MODULE_ENTRY("pam_passwdqc");
#elif defined(PAM_STATIC)
struct pam_module _pam_passwdqc_modstruct = {
"pam_passwdqc",
NULL,

View File

@ -1,7 +1,9 @@
Summary: Pluggable password "quality check"
# $Id: pam_passwdqc.spec,v 1.9 2002/02/06 22:36:40 mci Exp $
Summary: Pluggable password "quality check".
Name: pam_passwdqc
Version: 0.4
Release: 1owl
Release: owl1
License: relaxed BSD and (L)GPL-compatible
Group: System Environment/Base
Source: pam_passwdqc-%version.tar.gz
@ -33,6 +35,9 @@ rm -rf $RPM_BUILD_ROOT
/lib/security/pam_passwdqc.so
%changelog
* Thu Feb 07 2002 Michail Litvak <mci@owl.openwall.com>
- Enforce our new spec file conventions.
* Sun Nov 04 2001 Solar Designer <solar@owl.openwall.com>
- Updated to 0.4:
- Added "ask_oldauthtok" and "check_oldauthtok" as needed for stacking with

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000,2001 by Solar Designer. See LICENSE.
* Copyright (c) 2000-2002 by Solar Designer. See LICENSE.
*/
#ifndef _PASSWDQC_H
@ -17,8 +17,8 @@ typedef struct {
extern char _passwdqc_wordset_4k[0x1000][6];
extern char *_passwdqc_check(passwdqc_params_t *params,
char *newpass, char *oldpass, struct passwd *pw);
extern const char *_passwdqc_check(passwdqc_params_t *params,
const char *newpass, const char *oldpass, struct passwd *pw);
extern char *_passwdqc_random(passwdqc_params_t *params);
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000,2001 by Solar Designer. See LICENSE.
* Copyright (c) 2000-2002 by Solar Designer. See LICENSE.
*/
#include <stdlib.h>
@ -60,7 +60,7 @@ static int expected_different(int charset, int length)
* contain enough different characters for its class, or doesn't contain
* enough words for a passphrase.
*/
static int is_simple(passwdqc_params_t *params, char *newpass)
static int is_simple(passwdqc_params_t *params, const char *newpass)
{
int length, classes, words, chars;
int digits, lowers, uppers, others, unknowns;
@ -140,10 +140,10 @@ static int is_simple(passwdqc_params_t *params, char *newpass)
return 1;
}
static char *unify(char *src)
static char *unify(const char *src)
{
char *dst;
char *sptr, *dptr;
const char *sptr;
char *dst, *dptr;
int c;
if (!(dst = malloc(strlen(src) + 1)))
@ -162,10 +162,10 @@ static char *unify(char *src)
return dst;
}
static char *reverse(char *src)
static char *reverse(const char *src)
{
char *dst;
char *sptr, *dptr;
const char *sptr;
char *dst, *dptr;
if (!(dst = malloc(strlen(src) + 1)))
return NULL;
@ -193,12 +193,12 @@ static void clean(char *dst)
* substring removed.
*/
static int is_based(passwdqc_params_t *params,
char *haystack, char *needle, char *original)
const char *haystack, const char *needle, const char *original)
{
char *scratch;
int length;
int i, j;
char *p;
const char *p;
int match;
if (!params->match_length) /* disabled */
@ -252,16 +252,16 @@ static int is_based(passwdqc_params_t *params,
* should still be added, even though this is now of little importance.
*/
static int is_word_based(passwdqc_params_t *params,
char *needle, char *original)
const char *needle, const char *original)
{
char word[7];
char *unified;
int index;
int i;
word[6] = '\0';
for (index = 0; index < 0x1000; index++) {
memcpy(word, _passwdqc_wordset_4k[index], 6);
if (strlen(word) < params->match_length) continue;
for (i = 0; i < 0x1000; i++) {
memcpy(word, _passwdqc_wordset_4k[i], 6);
if ((int)strlen(word) < params->match_length) continue;
unified = unify(word);
if (is_based(params, unified, needle, original)) {
clean(unified);
@ -273,14 +273,14 @@ static int is_word_based(passwdqc_params_t *params,
return 0;
}
char *_passwdqc_check(passwdqc_params_t *params,
char *newpass, char *oldpass, struct passwd *pw)
const char *_passwdqc_check(passwdqc_params_t *params,
const char *newpass, const char *oldpass, struct passwd *pw)
{
char truncated[9], *reversed;
char *u_newpass, *u_reversed;
char *u_oldpass;
char *u_name, *u_gecos;
char *reason;
const char *reason;
int length;
reversed = NULL;
@ -346,7 +346,7 @@ char *_passwdqc_check(passwdqc_params_t *params,
is_based(params, u_gecos, u_reversed, reversed)))
reason = REASON_PERSONAL;
if (!reason && strlen(newpass) < params->min[2] &&
if (!reason && (int)strlen(newpass) < params->min[2] &&
(is_word_based(params, u_newpass, newpass) ||
is_word_based(params, u_reversed, reversed)))
reason = REASON_WORD;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000,2001 by Solar Designer. See LICENSE.
* Copyright (c) 2000-2002 by Solar Designer. See LICENSE.
*/
#include <stdio.h>
@ -37,7 +37,8 @@ char *_passwdqc_random(passwdqc_params_t *params)
{
static char output[0x100];
int bits;
int use_separators, count, length, index;
int use_separators, count, i;
unsigned int length;
char *start, *end;
int fd;
unsigned char bytes[2];
@ -49,7 +50,8 @@ char *_passwdqc_random(passwdqc_params_t *params)
use_separators = ((bits + 11) / 12 != count);
length = count * 7 - 1;
if (length >= sizeof(output) || length > params->max) return NULL;
if (length >= sizeof(output) || (int)length > params->max)
return NULL;
if ((fd = open("/dev/urandom", O_RDONLY)) < 0) return NULL;
@ -60,8 +62,8 @@ char *_passwdqc_random(passwdqc_params_t *params)
return NULL;
}
index = (((int)bytes[1] & 0x0f) << 8) | (int)bytes[0];
start = _passwdqc_wordset_4k[index];
i = (((int)bytes[1] & 0x0f) << 8) | (int)bytes[0];
start = _passwdqc_wordset_4k[i];
end = memchr(start, '\0', 6);
if (!end) end = start + 6;
if (length + (end - start) >= sizeof(output) - 1) {
@ -73,8 +75,8 @@ char *_passwdqc_random(passwdqc_params_t *params)
bits -= 12;
if (use_separators && bits > 3) {
index = ((int)bytes[1] & 0x70) >> 4;
output[length++] = SEPARATORS[index];
i = ((int)bytes[1] & 0x70) >> 4;
output[length++] = SEPARATORS[i];
bits -= 3;
} else
if (bits > 0)