aboutsummaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_cracklib/pam_cracklib.c
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 12:48:14 -0800
committerSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 12:48:14 -0800
commitd5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c (patch)
treeba5654cffacfd2002eefc5bc3764a7971afff1dc /Linux-PAM/modules/pam_cracklib/pam_cracklib.c
parent4c51da22e068907adb7857d50f5109a467c94d7c (diff)
parent7cbfa335c57d068d59508c844f3957165cccfb9b (diff)
downloadpam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.tar.gz
pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.tar.bz2
pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.zip
New upstream version 0.99.7.1
Diffstat (limited to 'Linux-PAM/modules/pam_cracklib/pam_cracklib.c')
-rw-r--r--Linux-PAM/modules/pam_cracklib/pam_cracklib.c316
1 files changed, 108 insertions, 208 deletions
diff --git a/Linux-PAM/modules/pam_cracklib/pam_cracklib.c b/Linux-PAM/modules/pam_cracklib/pam_cracklib.c
index 8f3e4c42..9b496202 100644
--- a/Linux-PAM/modules/pam_cracklib/pam_cracklib.c
+++ b/Linux-PAM/modules/pam_cracklib/pam_cracklib.c
@@ -1,6 +1,5 @@
/*
* pam_cracklib module
- * $Id: pam_cracklib.c,v 1.9 2004/09/15 12:06:17 kukuk Exp $
*/
/*
@@ -35,7 +34,7 @@
* S.A.G. in the section on the cracklib module.
*/
-#include <security/_pam_aconf.h>
+#include "config.h"
#include <stdio.h>
#ifdef HAVE_CRYPT_H
@@ -49,16 +48,19 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
+#include <limits.h>
+#ifdef HAVE_CRACK_H
+#include <crack.h>
+#else
extern char *FascistCheck(char *pw, const char *dictpath);
-
-#ifndef CRACKLIB_DICTPATH
-#define CRACKLIB_DICTPATH "/usr/share/dict/cracklib_dict"
#endif
-#define PROMPT1 "New %s%spassword: "
-#define PROMPT2 "Retype new %s%spassword: "
-#define MISTYPED_PASS "Sorry, passwords do not match"
+/* For Translators: "%s%s" could be replaced with "<service> " or "". */
+#define PROMPT1 _("New %s%spassword: ")
+/* For Translators: "%s%s" could be replaced with "<service> " or "". */
+#define PROMPT2 _("Retype new %s%spassword: ")
+#define MISTYPED_PASS _("Sorry, passwords do not match.")
#ifdef MIN
#undef MIN
@@ -76,23 +78,7 @@ extern char *FascistCheck(char *pw, const char *dictpath);
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
-
-#ifndef LINUX_PAM
-#include <security/pam_appl.h>
-#endif /* LINUX_PAM */
-
-/* some syslogging */
-
-static void _pam_log(int err, const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- openlog("PAM-Cracklib", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
- va_end(args);
- closelog();
-}
+#include <security/pam_ext.h>
/* argument parsing */
#define PAM_DEBUG_ARG 0x0001
@@ -108,6 +94,7 @@ struct cracklib_options {
int oth_credit;
int use_authtok;
char prompt_type[BUFSIZ];
+ char cracklib_dictpath[PATH_MAX];
};
#define CO_RETRY_TIMES 1
@@ -121,7 +108,9 @@ struct cracklib_options {
#define CO_OTH_CREDIT 1
#define CO_USE_AUTHTOK 0
-static int _pam_parse(struct cracklib_options *opt, int argc, const char **argv)
+static int
+_pam_parse (pam_handle_t *pamh, struct cracklib_options *opt,
+ int argc, const char **argv)
{
int ctrl=0;
@@ -169,63 +158,21 @@ static int _pam_parse(struct cracklib_options *opt, int argc, const char **argv)
opt->oth_credit = 0;
} else if (!strncmp(*argv,"use_authtok",11)) {
opt->use_authtok = 1;
+ } else if (!strncmp(*argv,"dictpath=",9)) {
+ strncpy(opt->cracklib_dictpath, *argv+9,
+ sizeof(opt->cracklib_dictpath) - 1);
} else {
- _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
+ pam_syslog(pamh,LOG_ERR,"pam_parse: unknown option; %s",*argv);
}
}
opt->prompt_type[sizeof(opt->prompt_type) - 1] = '\0';
+ opt->cracklib_dictpath[sizeof(opt->cracklib_dictpath) - 1] = '\0';
return ctrl;
}
/* Helper functions */
-/* this is a front-end for module-application conversations */
-static int converse(pam_handle_t *pamh, int ctrl, int nargs,
- struct pam_message **message,
- struct pam_response **response)
-{
- int retval;
- struct pam_conv *conv = NULL;
-
- retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
-
- if ( retval == PAM_SUCCESS && conv ) {
- retval = conv->conv(nargs, (const struct pam_message **)message,
- response, conv->appdata_ptr);
- if (retval != PAM_SUCCESS && (ctrl && PAM_DEBUG_ARG)) {
- _pam_log(LOG_DEBUG, "conversation failure [%s]",
- pam_strerror(pamh, retval));
- }
- } else {
- _pam_log(LOG_ERR, "couldn't obtain coversation function [%s]",
- pam_strerror(pamh, retval));
- if ( retval == PAM_SUCCESS )
- retval = PAM_BAD_ITEM; /* conv was NULL */
- }
-
- return retval; /* propagate error status */
-}
-
-static int make_remark(pam_handle_t *pamh, unsigned int ctrl,
- int type, const char *text)
-{
- struct pam_message *pmsg[1], msg[1];
- struct pam_response *resp;
- int retval;
-
- pmsg[0] = &msg[0];
- msg[0].msg = text;
- msg[0].msg_style = type;
- resp = NULL;
-
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (retval == PAM_SUCCESS)
- _pam_drop_reply(resp, 1);
-
- return retval;
-}
-
/* use this to free strings. ESPECIALLY password strings */
static char *_pam_delete(register char *xx)
{
@@ -237,7 +184,7 @@ static char *_pam_delete(register char *xx)
/*
* can't be a palindrome - like `R A D A R' or `M A D A M'
*/
-static int palindrome(const char *old, const char *new)
+static int palindrome(const char *new)
{
int i, j;
@@ -256,7 +203,8 @@ static int palindrome(const char *old, const char *new)
* the other
*/
-static int distdifferent(const char *old, const char *new, int i, int j)
+static int distdifferent(const char *old, const char *new,
+ size_t i, size_t j)
{
char c, d;
@@ -274,7 +222,7 @@ static int distdifferent(const char *old, const char *new, int i, int j)
}
static int distcalculate(int **distances, const char *old, const char *new,
- int i, int j)
+ size_t i, size_t j)
{
int tmp = 0;
@@ -295,7 +243,7 @@ static int distcalculate(int **distances, const char *old, const char *new,
static int distance(const char *old, const char *new)
{
int **distances = NULL;
- int m, n, i, j, r;
+ size_t m, n, i, j, r;
m = strlen(old);
n = strlen(new);
@@ -344,8 +292,7 @@ static int similar(struct cracklib_options *opt,
/*
* a nice mix of characters.
*/
-static int simple(struct cracklib_options *opt,
- const char *old, const char *new)
+static int simple(struct cracklib_options *opt, const char *new)
{
int digits = 0;
int uppers = 0;
@@ -428,7 +375,7 @@ static const char * password_check(struct cracklib_options *opt, const char *old
char *oldmono, *newmono, *wrapped;
if (strcmp(new, old) == 0) {
- msg = "is the same as the old one";
+ msg = _("is the same as the old one");
return msg;
}
@@ -438,20 +385,20 @@ static const char * password_check(struct cracklib_options *opt, const char *old
strcpy (wrapped, oldmono);
strcat (wrapped, oldmono);
- if (palindrome(oldmono, newmono))
- msg = "is a palindrome";
+ if (palindrome(newmono))
+ msg = _("is a palindrome");
if (!msg && strcmp(oldmono, newmono) == 0)
- msg = "case changes only";
+ msg = _("case changes only");
if (!msg && similar(opt, oldmono, newmono))
- msg = "is too similar to the old one";
+ msg = _("is too similar to the old one");
- if (!msg && simple(opt, old, new))
- msg = "is too simple";
+ if (!msg && simple(opt, new))
+ msg = _("is too simple");
if (!msg && strstr(wrapped, newmono))
- msg = "is rotated";
+ msg = _("is rotated");
memset(newmono, 0, strlen(newmono));
memset(oldmono, 0, strlen(oldmono));
@@ -486,7 +433,7 @@ static const char * check_old_password(const char *forwho, const char *newpass)
s_pas = strtok(NULL, ":,");
while (s_pas != NULL) {
if (!strcmp(crypt(newpass, s_pas), s_pas)) {
- msg = "has been already used";
+ msg = _("has been already used");
break;
}
s_pas = strtok(NULL, ":,");
@@ -507,15 +454,14 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh,
const char *pass_new)
{
const char *msg = NULL;
- const char *user;
+ const void *user;
int retval;
if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) {
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_DEBUG, "bad authentication token");
- make_remark(pamh, ctrl, PAM_ERROR_MSG,
- pass_new == NULL ?
- "No password supplied":"Password unchanged" );
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "bad authentication token");
+ pam_error(pamh, "%s", pass_new == NULL ?
+ _("No password supplied"):_("Password unchanged"));
return PAM_AUTHTOK_ERR;
}
@@ -525,25 +471,20 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh,
*/
msg = password_check(opt, pass_old,pass_new);
if (!msg) {
- retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
+ retval = pam_get_item(pamh, PAM_USER, &user);
if (retval != PAM_SUCCESS || user == NULL) {
- if (ctrl & PAM_DEBUG_ARG) {
- _pam_log(LOG_ERR,"Can not get username");
- return PAM_AUTHTOK_ERR;
- }
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh,LOG_ERR,"Can not get username");
+ return PAM_AUTHTOK_ERR;
}
msg = check_old_password(user, pass_new);
}
if (msg) {
- char remark[BUFSIZ];
-
- memset(remark,0,sizeof(remark));
- snprintf(remark,sizeof(remark),"BAD PASSWORD: %s",msg);
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_NOTICE, "new passwd fails strength check: %s",
- msg);
- make_remark(pamh, ctrl, PAM_ERROR_MSG, remark);
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_NOTICE,
+ "new passwd fails strength check: %s", msg);
+ pam_error(pamh, _("BAD PASSWORD: %s"), msg);
return PAM_AUTHTOK_ERR;
};
return PAM_SUCCESS;
@@ -573,45 +514,26 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
options.use_authtok = CO_USE_AUTHTOK;
memset(options.prompt_type, 0, BUFSIZ);
strcpy(options.prompt_type,"UNIX");
+ memset(options.cracklib_dictpath, 0,
+ sizeof (options.cracklib_dictpath));
- ctrl = _pam_parse(&options, argc, argv);
+ ctrl = _pam_parse(pamh, &options, argc, argv);
if (flags & PAM_PRELIM_CHECK) {
/* Check for passwd dictionary */
- struct stat st;
- char buf[sizeof(CRACKLIB_DICTPATH)+10];
-
- D(("prelim check"));
-
- memset(buf,0,sizeof(buf)); /* zero the buffer */
- snprintf(buf,sizeof(buf),"%s.pwd",CRACKLIB_DICTPATH);
-
- if (!stat(buf,&st) && st.st_size)
- return PAM_SUCCESS;
- else {
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_NOTICE,"dict path '%s'[.pwd] is invalid",
- CRACKLIB_DICTPATH);
- return PAM_ABORT;
- }
-
- /* Not reached */
- return PAM_SERVICE_ERR;
-
+ /* We cannot do that, since the original path is compiled
+ into the cracklib library and we don't know it. */
+ return PAM_SUCCESS;
} else if (flags & PAM_UPDATE_AUTHTOK) {
int retval;
- char *token1, *token2, *oldtoken;
- struct pam_message msg[1],*pmsg[1];
- struct pam_response *resp;
- const char *cracklib_dictpath = CRACKLIB_DICTPATH;
- char prompt[BUFSIZ];
+ char *token1, *token2, *resp;
+ const void *oldtoken;
D(("do update"));
- retval = pam_get_item(pamh, PAM_OLDAUTHTOK,
- (const void **)&oldtoken);
+ retval = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldtoken);
if (retval != PAM_SUCCESS) {
if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_ERR,"Can not get old passwd");
+ pam_syslog(pamh,LOG_ERR,"Can not get old passwd");
oldtoken=NULL;
retval = PAM_SUCCESS;
}
@@ -637,71 +559,60 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
*/
if (options.use_authtok == 1) {
- const char *item = NULL;
+ const void *item = NULL;
- retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &item);
+ retval = pam_get_item(pamh, PAM_AUTHTOK, &item);
if (retval != PAM_SUCCESS) {
/* very strange. */
- _pam_log(LOG_ALERT
- ,"pam_get_item returned error to pam_cracklib"
- );
+ pam_syslog(pamh, LOG_ALERT,
+ "pam_get_item returned error to pam_cracklib");
} else if (item != NULL) { /* we have a password! */
token1 = x_strdup(item);
item = NULL;
} else {
- retval = PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
+ retval = PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */
}
} else {
/* Prepare to ask the user for the first time */
- memset(prompt,0,sizeof(prompt));
- snprintf(prompt,sizeof(prompt),PROMPT1,
- options.prompt_type, options.prompt_type[0]?" ":"");
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = prompt;
-
resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (resp != NULL) {
- /* interpret the response */
- if (retval == PAM_SUCCESS) { /* a good conversation */
- token1 = x_strdup(resp[0].resp);
- if (token1 == NULL) {
- _pam_log(LOG_NOTICE,
- "could not recover authentication token 1");
- retval = PAM_AUTHTOK_RECOVER_ERR;
- }
- }
+ retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
+ PROMPT1, options.prompt_type,
+ options.prompt_type[0]?" ":"");
+
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token1 = x_strdup(resp);
+ if (token1 == NULL) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "could not recover authentication token 1");
+ retval = PAM_AUTHTOK_RECOVERY_ERR;
+ }
/*
* tidy up the conversation (resp_retcode) is ignored
*/
- _pam_drop_reply(resp, 1);
+ _pam_drop(resp);
} else {
retval = (retval == PAM_SUCCESS) ?
- PAM_AUTHTOK_RECOVER_ERR:retval ;
+ PAM_AUTHTOK_RECOVERY_ERR:retval ;
}
}
if (retval != PAM_SUCCESS) {
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"unable to obtain a password");
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh,LOG_DEBUG,"unable to obtain a password");
continue;
}
D(("testing password, retval = %s", pam_strerror(pamh, retval)));
/* now test this passwd against cracklib */
{
- char *crack_msg;
- char remark[BUFSIZ];
+ const char *crack_msg;
- bzero(remark,sizeof(remark));
D(("against cracklib"));
- if ((crack_msg = FascistCheck(token1, cracklib_dictpath))) {
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_DEBUG,"bad password: %s",crack_msg);
- snprintf(remark,sizeof(remark),"BAD PASSWORD: %s", crack_msg);
- make_remark(pamh, ctrl, PAM_ERROR_MSG, remark);
+ if ((crack_msg = FascistCheck(token1,options.cracklib_dictpath[0] == '\0'?NULL:options.cracklib_dictpath))) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh,LOG_DEBUG,"bad password: %s",crack_msg);
+ pam_error(pamh, _("BAD PASSWORD: %s"), crack_msg);
if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
retval = PAM_AUTHTOK_ERR;
else
@@ -735,51 +646,41 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* Now we have a good passwd. Ask for it once again */
if (options.use_authtok == 0) {
- bzero(prompt,sizeof(prompt));
- snprintf(prompt,sizeof(prompt),PROMPT2,
- options.prompt_type, options.prompt_type[0]?" ":"");
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = prompt;
-
resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (resp != NULL) {
- /* interpret the response */
- if (retval == PAM_SUCCESS) { /* a good conversation */
- token2 = x_strdup(resp[0].resp);
- if (token2 == NULL) {
- _pam_log(LOG_NOTICE,
- "could not recover authentication token 2");
- retval = PAM_AUTHTOK_RECOVER_ERR;
- }
- }
+ retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
+ PROMPT2, options.prompt_type,
+ options.prompt_type[0]?" ":"");
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token2 = x_strdup(resp);
+ if (token2 == NULL) {
+ pam_syslog(pamh,LOG_NOTICE,
+ "could not recover authentication token 2");
+ retval = PAM_AUTHTOK_RECOVERY_ERR;
+ }
/*
* tidy up the conversation (resp_retcode) is ignored
*/
- _pam_drop_reply(resp, 1);
- } else {
- retval = (retval == PAM_SUCCESS) ?
- PAM_AUTHTOK_RECOVER_ERR:retval ;
+ _pam_drop(resp);
}
- if (retval != PAM_SUCCESS) {
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_DEBUG
- ,"unable to obtain the password a second time");
- continue;
- }
+ /* No else, the a retval == PAM_SUCCESS path can change retval
+ to a failure code. */
+ if (retval != PAM_SUCCESS) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh,LOG_DEBUG,"unable to obtain retyped password");
+ continue;
+ }
/* Hopefully now token1 and token2 the same password ... */
if (strcmp(token1,token2) != 0) {
/* tell the user */
- make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS);
+ pam_error(pamh, "%s", MISTYPED_PASS);
token1 = _pam_delete(token1);
token2 = _pam_delete(token2);
pam_set_item(pamh, PAM_AUTHTOK, NULL);
if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_NOTICE,"Password mistyped");
- retval = PAM_AUTHTOK_RECOVER_ERR;
+ pam_syslog(pamh,LOG_NOTICE,"Password mistyped");
+ retval = PAM_AUTHTOK_RECOVERY_ERR;
continue;
}
@@ -788,7 +689,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
*/
{
- const char *item = NULL;
+ const void *item = NULL;
retval = pam_set_item(pamh, PAM_AUTHTOK, token1);
@@ -797,10 +698,9 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
token2 = _pam_delete(token2);
if ( (retval != PAM_SUCCESS) ||
- ((retval = pam_get_item(pamh, PAM_AUTHTOK,
- (const void **)&item)
+ ((retval = pam_get_item(pamh, PAM_AUTHTOK, &item)
) != PAM_SUCCESS) ) {
- _pam_log(LOG_CRIT, "error manipulating password");
+ pam_syslog(pamh, LOG_CRIT, "error manipulating password");
continue;
}
item = NULL; /* break link to password */
@@ -812,7 +712,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
} else {
if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_NOTICE, "UNKNOWN flags setting %02X",flags);
+ pam_syslog(pamh, LOG_NOTICE, "UNKNOWN flags setting %02X",flags);
return PAM_SERVICE_ERR;
}