summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Mraz <tmraz@redhat.com>2011-09-21 11:39:19 +0200
committerTomas Mraz <tmraz@redhat.com>2011-09-21 11:39:19 +0200
commit4df3d90fec8fc92881a47eebcbc71af5bfadcb21 (patch)
tree3ce15c164ab46f87e8b1b85fd5ff333b67ed2747 /src
parentf2704b82f30f1cf83307f9015f61aaef38f1d125 (diff)
downloadlibpwquality-4df3d90fec8fc92881a47eebcbc71af5bfadcb21.tar.gz
Incorporate better error message handling.
Diffstat (limited to 'src')
-rw-r--r--src/check.c59
-rw-r--r--src/error.c63
-rw-r--r--src/generate.c2
-rw-r--r--src/libpwquality.map1
-rw-r--r--src/pam_pwquality.c50
-rw-r--r--src/pwmake.c31
-rw-r--r--src/pwquality.h50
-rw-r--r--src/pwscore.c67
-rw-r--r--src/settings.c40
9 files changed, 190 insertions, 173 deletions
diff --git a/src/check.c b/src/check.c
index c02d1b4..1b65409 100644
--- a/src/check.c
+++ b/src/check.c
@@ -191,7 +191,7 @@ numclass(pwquality_settings_t *pwq,
* present in the password
*/
static int
-simple(pwquality_settings_t *pwq, const char *new)
+simple(pwquality_settings_t *pwq, const char *new, void **auxerror)
{
int digits = 0;
int uppers = 0;
@@ -227,27 +227,42 @@ simple(pwquality_settings_t *pwq, const char *new)
if (pwq->dig_credit >= 0)
size -= digits;
- else if (digits < pwq->dig_credit * -1)
+ else if (digits < -pwq->dig_credit) {
+ if (auxerror)
+ *auxerror = (void *)(long)-pwq->dig_credit;
return PWQ_ERROR_MIN_DIGITS;
+ }
if (pwq->up_credit >= 0)
size -= uppers;
- else if (uppers < pwq->up_credit * -1)
+ else if (uppers < -pwq->up_credit) {
+ if (auxerror)
+ *auxerror = (void *)(long)-pwq->up_credit;
return PWQ_ERROR_MIN_UPPERS;
+ }
if (pwq->low_credit >= 0)
size -= lowers;
- else if (lowers < pwq->low_credit * -1)
+ else if (lowers < -pwq->low_credit) {
+ if (auxerror)
+ *auxerror = (void *)(long)-pwq->low_credit;
return PWQ_ERROR_MIN_LOWERS;
+ }
if (pwq->oth_credit >= 0)
size -= others;
- else if (others < pwq->oth_credit * -1)
+ else if (others < -pwq->oth_credit) {
+ if (auxerror)
+ *auxerror = (void *)(long)-pwq->oth_credit;
return PWQ_ERROR_MIN_OTHERS;
+ }
if (size <= i)
return 0;
+ if (auxerror)
+ *auxerror = (void *)(long)size;
+
return PWQ_ERROR_MIN_LENGTH;
}
@@ -256,7 +271,7 @@ simple(pwquality_settings_t *pwq, const char *new)
*/
static int
-consecutive(pwquality_settings_t *pwq, const char *new)
+consecutive(pwquality_settings_t *pwq, const char *new, void **auxerror)
{
char c;
int i;
@@ -268,8 +283,11 @@ consecutive(pwquality_settings_t *pwq, const char *new)
for (i = 0; new[i]; i++) {
if (i > 0 && new[i] == c) {
++same;
- if (same > pwq->max_repeat)
+ if (same > pwq->max_repeat) {
+ if (auxerror)
+ *auxerror = (void *)(long)pwq->max_repeat;
return 1;
+ }
} else {
c = new[i];
same = 1;
@@ -301,7 +319,7 @@ x_strdup(const char *string)
static int
password_check(pwquality_settings_t *pwq,
- const char *new, const char *old)
+ const char *new, const char *old, void **auxerror)
{
int rv = 0;
char *oldmono = NULL, *newmono, *wrapped = NULL;
@@ -332,15 +350,19 @@ password_check(pwquality_settings_t *pwq,
rv = similar(pwq, oldmono, newmono);
if (!rv)
- rv = simple(pwq, new);
+ rv = simple(pwq, new, auxerror);
if (!rv && wrapped && strstr(wrapped, newmono))
rv = PWQ_ERROR_ROTATED;
- if (!rv && numclass(pwq, new) < pwq->min_class)
+ if (!rv && numclass(pwq, new) < pwq->min_class) {
rv = PWQ_ERROR_MIN_CLASSES;
+ if (auxerror) {
+ *auxerror = (void *)(long)pwq->min_class;
+ }
+ }
- if (!rv && consecutive(pwq, new))
+ if (!rv && consecutive(pwq, new, auxerror))
rv = PWQ_ERROR_MAX_CONSECUTIVE;
if (newmono) {
@@ -417,17 +439,18 @@ password_score(pwquality_settings_t *pwq, const char *password)
}
/* check the password according to the settings
- * it returns either score <0-100>, negative error number,
- * and in case of PWQ_ERROR_CRACKLIB also auxiliary
- * error message returned from cracklib;
+ * it returns either score <0-100> or negative error number;
* the old password is optional */
int
pwquality_check(pwquality_settings_t *pwq, const char *password,
- const char *oldpassword, const char **error)
+ const char *oldpassword, void **auxerror)
{
const char *msg;
int score;
+ if (auxerror)
+ *auxerror = NULL;
+
if (password == NULL || *password == '\0') {
return PWQ_ERROR_EMPTY_PASSWORD;
}
@@ -438,12 +461,12 @@ pwquality_check(pwquality_settings_t *pwq, const char *password,
msg = FascistCheck(password, pwq->dict_path);
if (msg) {
- if (error)
- *error = msg;
+ if (auxerror)
+ *auxerror = (void *)msg;
return PWQ_ERROR_CRACKLIB_CHECK;
}
- score = password_check(pwq, password, oldpassword);
+ score = password_check(pwq, password, oldpassword, auxerror);
if (score == 0) {
score = password_score(pwq, password);
}
diff --git a/src/error.c b/src/error.c
index c1f6e26..790dbed 100644
--- a/src/error.c
+++ b/src/error.c
@@ -7,16 +7,16 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "pwquality.h"
#include "pwqprivate.h"
/* Create an error message, the auxerror is generated by the library call
* and so it can be an arbitrary thing - it does not have to be a pointer
- * to string. Also in future it might be a string that will have to be
- * deallocated inside this function. */
-char *
-pwquality_strerror(char *buf, size_t len, int rv, char *auxerror)
+ * to string. */
+const char *
+pwquality_strerror(char *buf, size_t len, int rv, void *auxerror)
{
static char intbuf[PWQ_MAX_ERROR_MESSAGE_LEN];
@@ -27,6 +27,11 @@ pwquality_strerror(char *buf, size_t len, int rv, char *auxerror)
switch(rv) {
case PWQ_ERROR_MEM_ALLOC:
+ if (auxerror) {
+ snprintf(buf, len, "%s - %s", _("Memory allocation error when setting"), (const char *)auxerror);
+ free(auxerror);
+ return buf;
+ }
return _("Memory allocation error");
case PWQ_ERROR_SAME_PASSWORD:
return _("The password is the same as the old one");
@@ -38,31 +43,31 @@ pwquality_strerror(char *buf, size_t len, int rv, char *auxerror)
return _("The password is too similar to the old one");
case PWQ_ERROR_MIN_DIGITS:
if (auxerror) {
- snprintf(buf, len, _("The password contains less than %d digits"), (int)auxerror);
+ snprintf(buf, len, _("The password contains less than %ld digits"), (long)auxerror);
return buf;
}
return _("The password contains too few digits");
case PWQ_ERROR_MIN_UPPERS:
if (auxerror) {
- snprintf(buf, len, _("The password contains less than %d uppercase letters"), (int)auxerror);
+ snprintf(buf, len, _("The password contains less than %ld uppercase letters"), (long)auxerror);
return buf;
}
return _("The password contains too few uppercase letters");
case PWQ_ERROR_MIN_LOWERS:
if (auxerror) {
- snprintf(buf, len, _("The password contains less than %d lowercase letters"), (int)auxerror);
+ snprintf(buf, len, _("The password contains less than %ld lowercase letters"), (long)auxerror);
return buf;
}
return _("The password contains too few lowercase letters");
case PWQ_ERROR_MIN_OTHERS:
if (auxerror) {
- snprintf(buf, len, _("The password contains less than %d non-alphanumeric characters"), (int)auxerror);
+ snprintf(buf, len, _("The password contains less than %ld non-alphanumeric characters"), (long)auxerror);
return buf;
}
return _("The password contains too few non-alphanumeric characters");
case PWQ_ERROR_MIN_LENGTH:
if (auxerror) {
- snprintf(buf, len, _("The password is shorter than %d characters"), (int)auxerror);
+ snprintf(buf, len, _("The password is shorter than %ld characters"), (long)auxerror);
return buf;
}
return _("The password is too short");
@@ -70,13 +75,13 @@ pwquality_strerror(char *buf, size_t len, int rv, char *auxerror)
return _("The password is just rotated old one");
case PWQ_ERROR_MIN_CLASSES:
if (auxerror) {
- snprintf(buf, len, _("The password contains less than %d character classes"), (int)auxerror);
+ snprintf(buf, len, _("The password contains less than %ld character classes"), (long)auxerror);
return buf;
}
return _("The password does not contain enough character classes");
case PWQ_ERROR_MAX_CONSECUTIVE:
if (auxerror) {
- snprintf(buf, len, _("The password contains more than %d same characters consecutively"), (int)auxerror);
+ snprintf(buf, len, _("The password contains more than %ld same characters consecutively"), (long)auxerror);
return buf;
}
return _("The password contains too many same characters consecutively");
@@ -88,10 +93,44 @@ pwquality_strerror(char *buf, size_t len, int rv, char *auxerror)
return _("Password generation failed - required entropy too low for settings");
case PWQ_ERROR_CRACKLIB_CHECK:
if (auxerror) {
- snprintf(buf, len, "%s - %s", _("The password fails the dictionary check"), auxerror);
+ snprintf(buf, len, "%s - %s", _("The password fails the dictionary check"), (const char *)auxerror);
return buf;
}
return _("The password fails the dictionary check");
+ case PWQ_ERROR_UNKNOWN_SETTING:
+ if (auxerror) {
+ snprintf(buf, len, "%s - %s", _("Unknown setting"), (const char *)auxerror);
+ free(auxerror);
+ return buf;
+ }
+ return _("Unknown setting");
+ case PWQ_ERROR_INTEGER:
+ if (auxerror) {
+ snprintf(buf, len, "%s - %s", _("Bad integer value of setting"), (const char *)auxerror);
+ free(auxerror);
+ return buf;
+ }
+ return _("Bad integer value");
+ case PWQ_ERROR_NON_INT_SETTING:
+ if (auxerror) {
+ snprintf(buf, len, _("Setting %s is not of integer type"), (const char *)auxerror);
+ free(auxerror);
+ return buf;
+ }
+ return _("Setting is not of integer type");
+ case PWQ_ERROR_NON_STR_SETTING:
+ if (auxerror) {
+ snprintf(buf, len, _("Setting %s is not of string type"), (const char *)auxerror);
+ free(auxerror);
+ return buf;
+ }
+ return _("Setting is not of string type");
+ case PWQ_ERROR_CFGFILE_OPEN:
+ return _("Opening the configuration file failed");
+ case PWQ_ERROR_CFGFILE_MALFORMED:
+ return _("The configuration file is malformed");
+ case PWQ_ERROR_FATAL_FAILURE:
+ return _("Fatal failure");
default:
return _("Unknown error");
}
diff --git a/src/generate.c b/src/generate.c
index 24c158b..193e27b 100644
--- a/src/generate.c
+++ b/src/generate.c
@@ -118,7 +118,7 @@ pwquality_generate(pwquality_settings_t *pwq, int entropy_bits, char **password)
tmp = malloc(maxlen);
if (tmp == NULL) {
- return PWQ_ERROR_FATAL_FAILURE;
+ return PWQ_ERROR_MEM_ALLOC;
}
do {
diff --git a/src/libpwquality.map b/src/libpwquality.map
index 231dd02..f49ef96 100644
--- a/src/libpwquality.map
+++ b/src/libpwquality.map
@@ -10,6 +10,7 @@ LIBPWQUALITY_1.0 {
pwquality_get_str_value;
pwquality_generate;
pwquality_check;
+ pwquality_strerror;
local:
*;
};
diff --git a/src/pam_pwquality.c b/src/pam_pwquality.c
index e3cd522..8c9e164 100644
--- a/src/pam_pwquality.c
+++ b/src/pam_pwquality.c
@@ -52,16 +52,20 @@ _pam_parse (pam_handle_t *pamh, struct module_options *opt,
int argc, const char **argv)
{
int ctrl = 0;
+ int rv;
pwquality_settings_t *pwq;
+ void *auxerror;
+ char buf[PWQ_MAX_ERROR_MESSAGE_LEN];
pwq = pwquality_default_settings();
if (pwq == NULL)
return -1;
/* just log error here */
- if (pwquality_read_config(pwq, NULL))
+ if ((rv=pwquality_read_config(pwq, NULL, &auxerror)) != 0)
pam_syslog(pamh, LOG_ERR,
- "Reading pwquality configuration file failed: %m");
+ "Reading pwquality configuration file failed: %s",
+ pwquality_strerror(buf, sizeof(buf), rv, auxerror));
/* step through arguments */
for (ctrl = 0; argc-- > 0; ++argv) {
@@ -96,41 +100,6 @@ _pam_parse (pam_handle_t *pamh, struct module_options *opt,
return ctrl;
}
-static const char *
-make_error_message(int rv, const char *crack_msg)
-{
- switch(rv) {
- case PWQ_ERROR_MEM_ALLOC:
- return _("memory allocation error");
- case PWQ_ERROR_SAME_PASSWORD:
- return _("is the same as the old one");
- case PWQ_ERROR_PALINDROME:
- return _("is a palindrome");
- case PWQ_ERROR_CASE_CHANGES_ONLY:
- return _("case changes only");
- case PWQ_ERROR_TOO_SIMILAR:
- return _("is too similar to the old one");
- case PWQ_ERROR_MIN_DIGITS:
- case PWQ_ERROR_MIN_UPPERS:
- case PWQ_ERROR_MIN_LOWERS:
- case PWQ_ERROR_MIN_OTHERS:
- case PWQ_ERROR_MIN_LENGTH:
- return _("is too simple");
- case PWQ_ERROR_ROTATED:
- return _("is rotated");
- case PWQ_ERROR_MIN_CLASSES:
- return _("not enough character classes");
- case PWQ_ERROR_MAX_CONSECUTIVE:
- return _("contains too many same characters consecutively");
- case PWQ_ERROR_EMPTY_PASSWORD:
- return _("No password supplied");
- case PWQ_ERROR_CRACKLIB_CHECK:
- return crack_msg;
- default:
- return _("Error in service module");
- }
-}
-
PAM_EXTERN int
pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char **argv)
@@ -165,7 +134,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
tries = 0;
while (tries < options.retry_times) {
- const char *crack_msg;
+ void *auxerror;
const char *newtoken = NULL;
tries++;
@@ -188,11 +157,12 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
/* now test this passwd against libpwquality */
- retval = pwquality_check(options.pwq, newtoken, oldtoken, &crack_msg);
+ retval = pwquality_check(options.pwq, newtoken, oldtoken, &auxerror);
if (retval < 0) {
const char *msg;
- msg = make_error_message(retval, crack_msg);
+ char buf[PWQ_MAX_ERROR_MESSAGE_LEN];
+ msg = pwquality_strerror(buf, sizeof(buf), retval, auxerror);
if (ctrl & PAM_DEBUG_ARG)
pam_syslog(pamh, LOG_DEBUG, "bad password: %s", msg);
pam_error(pamh, _("BAD PASSWORD: %s"), msg);
diff --git a/src/pwmake.c b/src/pwmake.c
index 876ef1c..6c4c84e 100644
--- a/src/pwmake.c
+++ b/src/pwmake.c
@@ -12,6 +12,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#include <libgen.h>
#include "pwquality.h"
@@ -20,20 +21,6 @@ usage(const char *progname) {
fprintf(stderr, _("Usage: %s <entropy-bits>\n"), progname);
}
-static const char *
-make_error_message(int rv)
-{
- switch(rv) {
- case PWQ_ERROR_MEM_ALLOC:
- return _("Memory allocation error");
- case PWQ_ERROR_RNG:
- return _("Cannot obtain random numbers from the RNG device");
- case PWQ_ERROR_GENERATION_FAILED:
- return _("Password generation failed - required entropy too low for settings");
- default:
- return _("Unknown error");
- }
-}
/* score a password */
int
@@ -43,9 +30,14 @@ main(int argc, char *argv[])
char *password;
int rv;
int bits;
+ void *auxerror;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain("libpwquality", "/usr/share/locale");
+ textdomain("libpwquality");
if (argc != 2) {
- usage(argv[0]);
+ usage(basename(argv[0]));
exit(3);
}
@@ -53,16 +45,19 @@ main(int argc, char *argv[])
pwq = pwquality_default_settings();
if (pwq == NULL) {
- fprintf(stderr, "Error: %s\n", _("Error: Memory allocation error"));
+ fprintf(stderr, "Error: %s\n", pwquality_strerror(NULL, 0, PWQ_ERROR_MEM_ALLOC, NULL));
exit(2);
}
- pwquality_read_config(pwq, NULL);
+ if ((rv = pwquality_read_config(pwq, NULL, &auxerror)) != 0) {
+ fprintf(stderr, "Error: %s\n", pwquality_strerror(NULL, 0, rv, auxerror));
+ exit(3);
+ }
rv = pwquality_generate(pwq, bits, &password);
if (rv != 0) {
- fprintf(stderr, "Error: %s\n", make_error_message(rv));
+ fprintf(stderr, "Error: %s\n", pwquality_strerror(NULL, 0, rv, NULL));
exit(1);
}
diff --git a/src/pwquality.h b/src/pwquality.h
index 5e7105b..e6de079 100644
--- a/src/pwquality.h
+++ b/src/pwquality.h
@@ -24,6 +24,8 @@
#define PWQ_MAX_ENTROPY_BITS 256
#define PWQ_MIN_ENTROPY_BITS 56
+#define PWQ_MAX_ERROR_MESSAGE_LEN 256
+
#define PWQ_ERROR_SUCCESS 0 /* implicit, not used in the library code */
#define PWQ_ERROR_FATAL_FAILURE -1
#define PWQ_ERROR_INTEGER -2
@@ -52,56 +54,70 @@
typedef struct pwquality_settings pwquality_settings_t;
-/* returns default pwquality settings to be used in other library calls */
+/* Return default pwquality settings to be used in other library calls. */
pwquality_settings_t *
pwquality_default_settings(void);
-/* frees pwquality settings data */
+/* Free pwquality settings data. */
void
pwquality_free_settings(pwquality_settings_t *pwq);
-/* parse the configuration file (if NULL then the default one) */
+/* Parse the configuration file (if cfgfile is NULL then the default one).
+ * If auxerror is not NULL it also possibly returns auxiliary error information
+ * that must be passed into pwquality_strerror() function. */
int
-pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile);
+pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile,
+ void **auxerror);
-/* useful for setting the options as configured on a pam module
+/* Useful for setting the options as configured on a pam module
* command line in form of <opt>=<val> */
int
pwquality_set_option(pwquality_settings_t *pwq, const char *option);
-/* set value of an integer setting */
+/* Set value of an integer setting. */
int
pwquality_set_int_value(pwquality_settings_t *pwq, int setting, int value);
-/* set value of a string setting */
+/* Set value of a string setting. */
int
pwquality_set_str_value(pwquality_settings_t *pwq, int setting,
const char *value);
-/* get value of an integer setting, or -1 if setting unknown */
+/* Get value of an integer setting. */
int
-pwquality_get_int_value(pwquality_settings_t *pwq, int setting);
+pwquality_get_int_value(pwquality_settings_t *pwq, int setting, int *value);
-/* get value of a string setting, or NULL if setting unknown */
+/* Get value of a string setting, or NULL if setting unknown. */
const char *
pwquality_get_str_value(pwquality_settings_t *pwq, int setting);
-/* generate a random password of entropy_bits entropy and check it according to
- * the settings */
+/* Generate a random password of entropy_bits entropy and check it according to
+ * the settings. */
int
pwquality_generate(pwquality_settings_t *pwq, int entropy_bits,
char **password);
-/* check the password according to the settings
- * it returns either score <0-100>, negative error number,
- * and in case of PWQ_ERROR_CRACKLIB also auxiliary
- * error message returned from cracklib
+/* Check the password according to the settings.
+ * It returns either score <0-100>, negative error number,
+ * and possibly also auxiliary error information that must be
+ * passed into pwquality_strerror() function.
* The old password is optional and can be NULL.
+ * The auxerror can be NULL - in that case the auxiliary error information
+ * is not returned.
+ * Not passing the *auxerror into pwquality_strerror() can lead to memory leaks.
* The score depends on PWQ_SETTING_MIN_LENGTH. If it is set higher,
* the score for the same passwords will be lower. */
int
pwquality_check(pwquality_settings_t *pwq, const char *password,
- const char *oldpassword, const char **error);
+ const char *oldpassword, void **auxerror);
+
+/* Translate the error code and auxiliary message into a localized
+ * text message.
+ * If buf is NULL it uses an internal static buffer which
+ * makes the function non-reentrant in that case.
+ * The returned pointer is not guaranteed to point to the buf. */
+const char *
+pwquality_strerror(char *buf, size_t len, int errcode, void *auxerror);
#endif /* PWQUALITY_H */
diff --git a/src/pwscore.c b/src/pwscore.c
index 9046bbb..c9db396 100644
--- a/src/pwscore.c
+++ b/src/pwscore.c
@@ -12,6 +12,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#include <libgen.h>
#include "pwquality.h"
@@ -21,66 +22,27 @@ usage(const char *progname) {
fprintf(stderr, _(" The command reads the password to be scored from the standard input.\n"));
}
-static const char *
-make_error_message(int rv, const char *crack_msg)
-{
- static char buf[200];
-
- switch(rv) {
- case PWQ_ERROR_MEM_ALLOC:
- return _("Memory allocation error");
- case PWQ_ERROR_SAME_PASSWORD:
- return _("The password is the same as the old one");
- case PWQ_ERROR_PALINDROME:
- return _("The password is a palindrome");
- case PWQ_ERROR_CASE_CHANGES_ONLY:
- return _("The password differs with case changes only");
- case PWQ_ERROR_TOO_SIMILAR:
- return _("The password is too similar to the old one");
- case PWQ_ERROR_MIN_DIGITS:
- return _("The password contains too few digits");
- case PWQ_ERROR_MIN_UPPERS:
- return _("The password contains too few uppercase letters");
- case PWQ_ERROR_MIN_LOWERS:
- return _("The password contains too few lowercase letters");
- case PWQ_ERROR_MIN_OTHERS:
- return _("The password contains too few non-alphanumeric characters");
- case PWQ_ERROR_MIN_LENGTH:
- return _("The password is too short");
- case PWQ_ERROR_ROTATED:
- return _("The password is just rotated old one");
- case PWQ_ERROR_MIN_CLASSES:
- return _("The password does not contain enough character classes");
- case PWQ_ERROR_MAX_CONSECUTIVE:
- return _("The password contains too many same characters consecutively");
- case PWQ_ERROR_EMPTY_PASSWORD:
- return _("No password supplied");
- case PWQ_ERROR_CRACKLIB_CHECK:
- snprintf(buf, sizeof(buf), _("The password fails the dictionary check - %s"), crack_msg);
- return buf;
- default:
- return _("Unknown error");
- }
-}
-
-
/* score a password */
int
main(int argc, char *argv[])
{
pwquality_settings_t *pwq;
int rv;
- const char *crack_msg;
+ void *auxerror;
char buf[1024];
size_t len;
+ setlocale(LC_ALL, "");
+ bindtextdomain("libpwquality", "/usr/share/locale");
+ textdomain("libpwquality");
+
if (argc != 1) {
- usage(argv[0]);
+ usage(basename(argv[0]));
exit(3);
}
if (fgets(buf, sizeof(buf), stdin) == NULL || (len = strlen(buf)) == 0) {
- fprintf(stderr, "Error: Could not obtain the password to be scored\n");
+ fprintf(stderr, _("Error: %s\n"), _("Could not obtain the password to be scored"));
exit(4);
}
if (buf[len - 1] == '\n')
@@ -88,17 +50,20 @@ main(int argc, char *argv[])
pwq = pwquality_default_settings();
if (pwq == NULL) {
- fprintf(stderr, _("Error: %s\n"), make_error_message(PWQ_ERROR_MEM_ALLOC, NULL));
+ fprintf(stderr, _("Error: %s\n"), pwquality_strerror(NULL, 0, PWQ_ERROR_MEM_ALLOC, NULL));
exit(2);
}
- pwquality_read_config(pwq, NULL);
+ if ((rv=pwquality_read_config(pwq, NULL, &auxerror)) != 0) {
+ fprintf(stderr, _("Error: %s\n"), pwquality_strerror(NULL, 0, rv, auxerror));
+ exit(3);
+ }
- rv = pwquality_check(pwq, buf, NULL, &crack_msg);
+ rv = pwquality_check(pwq, buf, NULL, &auxerror);
if (rv < 0) {
- fprintf(stderr, _("Password quality check failed: %s\n"),
- make_error_message(rv, crack_msg));
+ fprintf(stderr, _("Password quality check failed:\n %s\n"),
+ pwquality_strerror(NULL, 0, rv, auxerror));
exit(1);
}
diff --git a/src/settings.c b/src/settings.c
index 70c0c2e..329e3d1 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -98,18 +98,24 @@ set_name_value(pwquality_settings_t *pwq, const char *name, const char *value)
/* parse the configuration file (if NULL then the default one) */
int
-pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile)
+pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile, void **auxerror)
{
FILE *f;
char linebuf[PWQSETTINGS_MAX_LINELEN+1];
int rv = 0;
+ if (auxerror)
+ *auxerror = NULL;
if (cfgfile == NULL)
cfgfile = PWQUALITY_DEFAULT_CFGFILE;
f = fopen(cfgfile, "r");
- if (f == NULL)
+ if (f == NULL) {
+ /* ignore non-existent default config file */
+ if (errno == ENOENT && strcmp(cfgfile, PWQUALITY_DEFAULT_CFGFILE) == 0)
+ return 0;
return PWQ_ERROR_CFGFILE_OPEN;
+ }
while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
size_t len;
@@ -159,6 +165,8 @@ pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile)
}
if ((rv=set_name_value(pwq, name, ptr)) != 0) {
+ if (auxerror)
+ *auxerror = strdup(name);
break;
}
}
@@ -262,41 +270,42 @@ pwquality_set_str_value(pwquality_settings_t *pwq, int setting,
return 0;
}
-/* get value of an integer setting, or -1 if setting unknown */
+/* get value of an integer setting */
int
-pwquality_get_int_value(pwquality_settings_t *pwq, int setting)
+pwquality_get_int_value(pwquality_settings_t *pwq, int setting, int *value)
{
switch(setting) {
case PWQ_SETTING_DIFF_OK:
- return pwq->diff_ok;
+ *value = pwq->diff_ok;
break;
case PWQ_SETTING_DIFF_IGNORE:
- return pwq->diff_ignore;
+ *value = pwq->diff_ignore;
break;
case PWQ_SETTING_MIN_LENGTH:
- return pwq->min_length;
+ *value = pwq->min_length;
break;
case PWQ_SETTING_DIG_CREDIT:
- return pwq->dig_credit;
+ *value = pwq->dig_credit;
break;
case PWQ_SETTING_UP_CREDIT:
- return pwq->up_credit;
+ *value = pwq->up_credit;
break;
case PWQ_SETTING_LOW_CREDIT:
- return pwq->low_credit;
+ *value = pwq->low_credit;
break;
case PWQ_SETTING_OTH_CREDIT:
- return pwq->oth_credit;
+ *value = pwq->oth_credit;
break;
case PWQ_SETTING_MIN_CLASS:
- return pwq->min_class;
+ *value = pwq->min_class;
break;
case PWQ_SETTING_MAX_REPEAT:
- return pwq->max_repeat;
+ *value = pwq->max_repeat;
break;
default:
- return -1;
- }
+ return PWQ_ERROR_NON_INT_SETTING;
+ }
+ return 0;
}
/* get value of a string setting, or NULL if setting unknown */
@@ -306,7 +315,6 @@ pwquality_get_str_value(pwquality_settings_t *pwq, int setting)
switch(setting) {
case PWQ_SETTING_DICT_PATH:
return pwq->dict_path;
- break;
default:
return NULL;
}