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:
parent
0b0ecb56f2
commit
402783abd1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/pam_modules/dist/; revision=94691
@ -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.
|
||||
|
@ -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(¶ms, pamh, newpass) && enforce))
|
||||
return PAM_AUTHTOK_RECOVER_ERR;
|
||||
return PAM_AUTHTOK_RECOVERY_ERR;
|
||||
reason = _passwdqc_check(¶ms.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(¶ms, 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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user